亿迅智能制造网
工业4.0先进制造技术信息网站!
首页 | 制造技术 | 制造设备 | 工业物联网 | 工业材料 | 设备保养维修 | 工业编程 |
home  MfgRobots >> 亿迅智能制造网 >  >> Manufacturing Technology >> 制造工艺

Arduino 进阶徒步追踪器:GPS、多传感器与电池组

元器件与材料

所需工具

软件与在线服务

项目简介

什么是徒步追踪器?

徒步追踪器用于感知徒步者周围环境变化:温度、气压、湿度、海拔、位置、方向等,为户外探索提供数据洞察。高海拔空气稀薄干燥,许多人呼吸困难、皮肤干燥;本设备帮助了解自身极限。探索沼泽、沙漠、森林等不同环境时,实时监测环境参数能更好理解自然。

Arduino 进阶徒步追踪器:GPS、多传感器与电池组

硬件分配

Accessory Shield 内置 I2C 传感器:

Arduino 101 扩展:

硬件改装与连接

Arduino 101 用螺柱+热熔胶固定在 4×AA 电池盒上。

Arduino 进阶徒步追踪器:GPS、多传感器与电池组
Arduino 进阶徒步追踪器:GPS、多传感器与电池组

安装 4×AA 电池与 CR1220 (RTC)。

Arduino 进阶徒步追踪器:GPS、多传感器与电池组

电池盒与主板间隙塞入气压、湿度、磁力计、GPS 模块。

Arduino 进阶徒步追踪器:GPS、多传感器与电池组

I2C 传感器焊在万能板上置于该间隙,从底部引线连接 Arduino。

Arduino 进阶徒步追踪器:GPS、多传感器与电池组
Arduino 进阶徒步追踪器:GPS、多传感器与电池组

分压电路测电池电压,接 ADC A1。扩展板摇杆占用 A1,故拆除摇杆。

Arduino 进阶徒步追踪器:GPS、多传感器与电池组
Arduino 进阶徒步追踪器:GPS、多传感器与电池组

通过焊桥引出 D2(软复位)、D3、D9、D10 到 XBee 接口备用。

Arduino 进阶徒步追踪器:GPS、多传感器与电池组

分层堆叠:顶层扩展板、中层传感器+GPS、底层电池盒。连接示意见原理图。

Arduino 进阶徒步追踪器:GPS、多传感器与电池组

软件开发

Arduino IDE 1.8.5,通过库管理器安装所需库:

Arduino 进阶徒步追踪器:GPS、多传感器与电池组
Arduino 进阶徒步追踪器:GPS、多传感器与电池组

Accessory Shield 专用库通过 ZIP 安装。参考各传感器示例代码整合 API。

头文件清单

math.h, inttypes.h, Wire.h, lm75.h, ADXL345.h,
ChainableLED.h, U8glib.h, ds3231.h,
Adafruit_Sensor.h, Adafruit_AM2320.h,
Adafruit_BMP085_U.h, Adafruit_HMC5883_U.h,
Adafruit_GPS.h

多次编译调试 (含排查松动接线,如 BMP180 无 VCC 仍工作,疑为 I2C 泄漏供电) 后代码定型。

已知局限

改进方向

固件: 参数定期存 EEPROM、海拔/位置里程碑蜂鸣提醒、喝水/休息提醒、低电压/低温/低湿报警、罗盘软件倾斜补偿、GPS+物联网自动获取磁偏角。
硬件: 用户按键设置时间/磁偏角、3D 打印外壳、改用可充电 LiPo、单板紧凑 PCB 设计。

结语

徒步旅行很酷,随时掌握环境变化更有趣。海拔、湿度、气压、温度随行程变化,本设备让你知道多高会高反、多干皮肤会不适。虽电路布局和代码仍有改进空间,但作为野外探索小工具已很实用!

外部资源

Accessory Shield 文档:waveshare.com

推荐更好版本的硬件

Rapid Prototyping Kit

代码

Hiking_Tracker.ino (主程序)

/* 注意:
 * D2 可软复位,D3/D9/D10 经 XBee 接口引出
 * D4/D13 不可用
 */
#include 
#include 
#include 
#include 
#include 
#include 
#include "U8glib.h"
#include "ds3231.h"
#include "Adafruit_Sensor.h"
#include "Adafruit_AM2320.h"
#include 
#include 
#include 

// RTC 变量
uint8_t time[8]; struct ts t; int s,m,h,dy,mo,yr;
// 加速度计
float X=0,Y=0,Z=0,Gravity=0;
// 磁力计
float Xm=0,Ym=0,Zm=0;
// RGB LED
const int rgb_pwr=12, clk_pin=6, data_pin=5;
float hue=0; boolean up=true;
// 电位器
int pot=0;
// 电池电压
float Vbatt=0;
// 温湿度气压海拔
float temp=0, humid=0, prsr=0, alt=0;
// GPS 坐标
float lat=0, lon=0;
// 罗盘
float heading=0;
// 其他
int mstime=0, sensor_selector=1;

// I2C 设备对象
U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE|U8G_I2C_OPT_DEV_0);
TempI2C_LM75 termo(0x48, TempI2C_LM75::nine_bits);
ADXL345 accelerometer;
ChainableLED leds(clk_pin, data_pin, rgb_pwr, 1);
Adafruit_AM2320 am2320;
Adafruit_BMP085_Unified bmp180(10085);
Adafruit_HMC5883_Unified mag(12345);
// GPS 串口冲突调试时取消注释
// HardwareSerial mySerial = Serial;
// Adafruit_GPS GPS(&mySerial);

void setup() {
  // analogReference(INTERNAL); // 1.1V 内部基准
  // OLED 信号引出需扩展板焊桥
  pinMode(2,1); pinMode(3,1); pinMode(9,1); pinMode(10,1);
  digitalWrite(2,HIGH); digitalWrite(3,HIGH); digitalWrite(9,LOW); digitalWrite(10,HIGH);
  pinMode(7,1); pinMode(8,1); digitalWrite(7,HIGH); digitalWrite(8,LOW);
  // A0: 10k电位器, A1: 电池分压 (3.91k/21.76k)

  // Serial.begin(9600); // 调试用

  if (!accelerometer.begin()) delay(50);
  DS3231_init(DS3231_INTCN);
  pinMode(11,1); digitalWrite(11,LOW); // 蜂鸣器
}

void loop() {
  // OLED 画面循环
  u8g.firstPage();
  do { draw(); } while(u8g.nextPage());

  sensor_selector++; if (sensor_selector>=3) sensor_selector=0;

  // 温度
  temp = termo.getTemp(); delay(5);

  // 气压/海拔 (sensor_selector==0)
  if (sensor_selector==0) {
    if(!bmp180.begin()) delay(11);
    sensors_event_t event;
    bmp180.getEvent(&event);
    if (event.pressure) { prsr = event.pressure/10; delay(50); } // hPa->kPa
    sensors_event_t event2;
    bmp180.getEvent(&event2);
    alt = bmp180.pressureToAltitude(1013.25, event2.pressure); delay(50);
  }

  // 湿度 (sensor_selector==1)
  if (sensor_selector==1) {
    am2320.begin(); delay(50);
    humid = am2320.readHumidity(); delay(50);
  }

  // 加速度
  Vector norm = accelerometer.readNormalize();
  X = norm.XAxis; Y = norm.YAxis; Z = norm.ZAxis;
  Gravity = sqrt(X*X+Y*Y+Z*Z) - 0.3;

  // RTC 时间
  DS3231_get(&t);
  s=t.sec; m=t.min; h=t.hour; dy=t.mday; mo=t.mon; yr=t.year;

  // 电位器 (0-5V 映射)
  pot = analogRead(A0)*5/(10*3); delay(2);

  // 电池电压 (1.1V 内部基准实测 1.08V)
  Vbatt = (1.08*analogRead(A1)/1023)/3.91*((3.91+21.76)); delay(2);

  // 罗盘 (sensor_selector==2)
  if (sensor_selector==2) {
    if(!mag.begin()) while(1);
    delay(70);
    sensor_t sensor2; mag.getSensor(&sensor2); delay(70);
    sensors_event_t event2; mag.getEvent(&event2); delay(70);
    float declination = 0; // 需按 GPS 坐标查表填入
    heading = atan2(event2.magnetic.y, event2.magnetic.x);
    heading += declination;
    if (heading < 0) heading += 2*PI;
    if (heading > 2*PI) heading -= 2*PI;
    heading = heading * 180 / M_PI;
  }

  // 蜂鸣器阈值
  if (pot > 80) digitalWrite(11,1); else digitalWrite(11,0);

  // RGB LED 呼吸灯
  if (pot > 40) {
    leds.pwr_set(PWR_ENABLE);
    for (byte i=0; i<1; i++) leds.setColorHSB(i, hue, 1.0, 0.5);
    if (up) hue+=0.025; else hue-=0.025;
    if (hue>=1.0 && up) up=false;
    else if (hue<=0.0 && !up) up=true;
  }

  // 软复位示例
  // digitalWrite(2,LOW);
}

// OLED 绘制函数
void draw() {
  u8g.setFont(u8g_font_7x13);
  u8g.drawHLine(37,0,62);
  u8g.setPrintPos(41,12); if(h<10) u8g.print(0); u8g.print(h); u8g.drawStr(54,12,":");
  u8g.setPrintPos(62,12); if(m<10) u8g.print(0); u8g.print(m); u8g.drawStr(75,12,":");
  u8g.setPrintPos(83,12); if(s<10) u8g.print(0); u8g.print(s);
  u8g.drawHLine(37,14,62);
  u8g.setFont(u8g_font_5x8);
  u8g.drawVLine(37,0,14);
  u8g.setPrintPos(0,7); if(dy<10) u8g.print(0); u8g.print(dy); u8g.drawStr(11,7,"/");
  u8g.setPrintPos(17,7); if(mo<10) u8g.print(0); u8g.print(mo); u8g.drawStr(0,16,"/");
  u8g.setPrintPos(6,16); u8g.print(yr);
  u8g.drawVLine(99,0,14);
  u8g.drawStr(104,7,"BATT"); u8g.setPrintPos(102,15); u8g.print(Vbatt); u8g.drawStr(123,15,"V");

  u8g.print(round(temp)); u8g.drawStr(55,25,"'C");
  u8g.setFont(u8g_font_5x8);
  u8g.setPrintPos(15,40); u8g.print(round(X));
  u8g.setPrintPos(60,40); u8g.print(round(Y));
  u8g.setPrintPos(100,40); u8g.print(round(Z));
  u8g.setPrintPos(95,22); u8g.print(Vbatt); u8g.drawStr(123,22,"V");
  u8g.drawVLine(37,18,36);
  u8g.drawStr(39,24,"AIR TEMP: "); u8g.setPrintPos(85,24); u8g.print(temp); u8g.drawStr(118,24,"C");
  u8g.drawStr(39,34,"HUMIDITY: "); u8g.setPrintPos(85,34); u8g.print(humid); u8g.drawStr(118,34,"%");
  u8g.drawStr(39,44,"PRESSURE: "); u8g.setPrintPos(85,44); u8g.print(prsr); u8g.drawStr(118,44,"hP");
  u8g.drawStr(39,54,"ALTITUDE: "); u8g.setPrintPos(85,54); u8g.print(round(alt)); u8g.drawStr(118,54,"m");
  u8g.drawHLine(0,56,128);
  u8g.drawStr(19,64,"LAT:"); u8g.setPrintPos(39,64); u8g.print(23.57); // 演示坐标
  u8g.drawStr(69,64,"LONG:"); u8g.setPrintPos(94,64); u8g.print(90.36);

  int r = round(sqrt(X*X+Y*Y));
  u8g.drawStr(0,22,"heading");
  u8g.drawCircle(18,34,r,U8G_DRAW_ALL); // 内圈随倾斜变化
  u8g.drawCircle(18,34,10,U8G_DRAW_ALL); // 外圈固定
  u8g.setPrintPos(0,53); u8g.print(heading); // 0/360=N, 90=E, 180=S, 270=W
  if ((heading>315)||(heading<=45)) u8g.drawLine(18,34,8,34); // N
  if ((heading>45)&&(heading<=135)) u8g.drawLine(18,34,18,24); // E
  if ((heading>135)&&(heading<=225)) u8g.drawLine(18,34,28,34); // S
  if ((heading>225)&&(heading<315)) u8g.drawLine(18,34,18,44); // W
}

依赖库

需解压后逐个通过 Arduino 库管理器“添加 ZIP 库”安装,详见原项目附件。

原理图

Arduino 进阶徒步追踪器:GPS、多传感器与电池组

制造工艺

  1. 树莓派 PIR 运动传感器控制 LED 实战指南
  2. 树莓派低成本土壤湿度传感器:智能灌溉 DIY 指南
  3. 树莓派仓鼠健身追踪器:激光断束传感器记录每日运动量
  4. 树莓派 DS18B20 温度传感器测试与 HC-SR04 超声波测距实战
  5. 树莓派 + MCP9808 + InfluxDB + Grafana:家庭温度监测系统
  6. Walabot 驱动的马桶卫生监测器
  7. 低成本情绪传感器与 EEG:实时情绪检测硬件方案
  8. 树莓派 2 (Windows 10 IoT Core) 采集 Adafruit 10DOF IMU 数据上传 Azure Event Hubs
  9. UnifiedWater v1 — 基于 Arduino MKR GSM 1400 的完整水质监测套件
  10. MyRiver:基于 Arduino MKR FOX 1200 的河流水质远程监测系统
  11. 氧传感器 (O2) 详解:作用、位置与故障征兆
  12. 国际空间站传感器精准WiFi RSSI定位追踪