徒步追踪器
组件和用品
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 2 | ||||
| × | 1 | ||||
| × | 1 |
必要的工具和机器
| ||||
|
应用和在线服务
|
关于这个项目
什么是徒步追踪器?
徒步追踪器是一种在徒步过程中感知徒步者周围环境变化的设备。
这个想法是观察温度、压力、湿度、高度、位置、方向等的变化。它提供了一些徒步旅行的有趣见解。
与低地相比,在寒冷、干燥、低密度空气的山区,许多人发现呼吸困难。有些人会出现皮肤干燥刺激。这个设备让有兴趣徒步旅行的人知道他们的极限。还有去高海拔地方的乐趣。能够知道海拔是一件有趣的事情!
不仅是山脉,还可以探索沼泽、沙漠、森林——每一个都有其独特的环境特征,能够在旅途中监测环境是了解自然的更好方式。
视频演示
第 1 步:硬件,用于什么?
这个项目有很多感觉
附件屏蔽板带有一些板上的 I2C 设备:
- LM 75B 温度传感器,用于检测环境温度
- ADXL345 3 轴加速度计用于感应倾斜和重力
- DS3231 高精度 RTC 感应时间
- HMC5883 3 轴磁传感器,用于感应罗盘航向
- AM2320 湿度传感器,用于感测空气的 % RH
- BMP180 压力传感器,用于感应大气压力和海拔
- MTK3339 GPS 传感器,用于感应位置和步行距离
在 Arduino Uno 上:
- 3.9k + 22k 分压器,用于 传感 4 AA 电池电压
- 1306 OLED 用于查看数据
- 蜂鸣器发出警报声
- 此项目不需要 RGB LED
- 没有使用XBee接口,但是Arduino D2、D3、D9、D10可以从这个接口中带出来用于其他项目,D2连接到reset,可以从代码中重置Arduino!
- 未使用 5 向操纵杆
- 未使用 101 锅
第 2 步:修改和连接硬件
对 Arduino Uno 进行了很少的修改。它安装在带有螺丝支架和热胶的 4 AA 电池座上。
图>4 AA 和 CR1220(用于 RTC)安装在电池座上。
图>电池座和Arduino Uno板之间有一个空间,可以放置压力、湿度、磁性和GPS传感器。
图>I2C传感器焊接在一块预制板上并放置在这个空间中
图>这些传感器从底部连接到 Arduino Uno :
增加分压器测量4节AA电池电压。
AA 电池组电压检测线连接到 ADC A1 :
屏蔽的操纵杆映射到 ACD 引脚 A1 到引脚 A5。这就是为什么要拆焊并移除操纵杆。P>
通过将 Accessory Shield 上的一些焊盘(原理图见参考)与焊桥 D2(用于软复位)连接,Arduino 的 D3、D9、D10 引脚可在 Xbee 接口上使用。
图>组件堆栈如下:
- 顶层:Arduino 上的附件扩展板
- 中间层:其他传感器和 GPS 将位于 Uno 和电池盒之间
- 底层:4 AA 电池座,带电池
连接看起来像这样:
第 3 步:对设备进行编程
Arduino IDEBuild 1.8.5
用于对设备进行编程。首先使用库管理器包含或下载以下所有库。
在库管理器的搜索框中输入传感器的名称,就会出现相应的库。
一些 Accessory Shield 库(见参考)是通过 zip.file 选项添加的
添加必要的库后,查看每个传感器的示例代码,以找出相关传感器的 API。
接下来,所有库头文件都包含在一个空的 Arduino 草图中。
头文件列表
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 引脚的漏电)并上传 - 最终代码准备就绪。
注意事项
- 高度计算基于气压降,仅适用于正常天气条件。
- 指南针代码未在软件中进行倾斜补偿,设备必须保持在水平平面上。有一个固定的罗盘圆,其中有另一个可变半径的圆。当设备倾斜时,内圆会增加。当它处于水平位置时(即加速度的 x 和 y 分量几乎为 0 ),内圆将减少到一个点。这是指南针航向更准确的时候。
- 罗盘指针的偏角取决于地球磁场的位置和变化。这可能会受到太阳风暴的影响。如果不包括偏角,罗盘航向将偏离几度。
查找您所在地区的磁偏角:http://www.magnetic-declination.com
- 罗盘航向容易受到附近磁性物体的影响,例如山上存在强磁性矿物。
- 设备的最低工作电压约为 4.5 伏。此时应更换 AA 电池。
- 时间和日期是通过代码编程的,如果需要时间来更换纽扣电池,必须拔掉再插上。代码中带有新时间的新程序上传将更改时间。
- 在开发期间 GPS 模块不可用。因此,演示坐标放置在 Lat-Long 中。如果有人希望复制此项目,则需要包含 GPS 库和相关代码。
- 加速度计和磁力计的 XY 平面取决于 PCB 上的放置位置。代码需要做相应的调整。
- 加速度计读数精度容易出现振动。建议在静止状态下使用设备。
改进范围
可以从固件方面进行改进以获得更多功能:
- 在 EEPROM 上定期记录参数
- 到达高度/位置里程碑时蜂鸣器发出蜂鸣声
- 喝水提醒
- 休息提醒
- 低电量警报
- 低温、湿度警报
- 用于倾斜补偿的罗盘软件校准(很多三角学东西)
- 通过网关应用使用 GPS 和物联网连接自动获取赤纬
至于硬件部分的改进:
- 用于设置时间、偏角等的用户输入开关
- 设备的自定义 3D 外壳
- 使用可充电锂电池
- 单板紧凑型 PCB 设计,便于携带
结论
Traveling &Hiking 很酷,当你可以检查周围环境的变化时,它会让事情变得更有趣。特别是,在徒步旅行的几个小时内检查海拔、湿度、压力和温度的变化。这个设备让你知道在什么高度你会感到高原反应,什么湿度水平会让你的皮肤干燥——诸如此类。尽管电路布局和代码都有改进的空间来处理这些警告,但在进入荒野时拥有这样的小工具仍然很酷!
外部资源
https://www.waveshare.com/wiki/Accessory_Shield
本项目更好版本的推荐硬件
快速原型制作套件
代码
- Hiking_Tracker.ino
- 图书馆
Hiking_Tracker.inoC/C++
main.c/*///////// 注意 ///////// D2 允许从代码 D3、D9、D10 可断言的软复位可通过 12、13、16 xbee interfaceD4、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;int m; int h;int dy;int mo;int yr;//////////////// 加速度计变量////////////float X=0.0;float Y=0.0;float Z=0.0;float Gravity =0.0;//////////////// 加速度计变量//////////float Xm=0.0;float Ym=0.0;float Zm=0.0; ///////////////////// RGB LED 变量///////////////const int rgb_pwr =12; const int clk_pin =6; const int data_pin =5;浮动色调 =0.0;布尔向上 =真;////////////////////// 电位器//////////////// //int锅=0; ////////////////// 电池/供应Vin /////////////////浮动Vbatt =0.0;//// /////////////////温度计////////////////////浮动温度=0.0;////// /////////////// 湿度///////////////////////浮动湿度=0.0;////// /////////////气压////////////////////双prsr =0.0;////////// ///////////海拔////////////////////float alt =0.0;///////////// ////// 经纬度////////////////////浮动纬度=0.0; float lon =0.0;//////////////////罗盘方向////////////////浮动方向=0.0;//// //////////////// 其他变量//////////////int mstime =0;int sensor_selector =1;////// /////// ENUM //I2C 设备类型对象 ///////////////U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE|U8G_I2C_OPT_DEV_0); // I2C OLED DisplayTempI2C_LM75 termo =TempI2C_LM75(0x48,TempI2C_LM75::nine_bits); // I2C 温度传感器ADXL345 加速度计; // I2C Acce SensorChainableLED LEDs(clk_pin, data_pin, rgb_pwr, 1); // I2C RGB LEDAdafruit_AM2320 am2320 =Adafruit_AM2320(); // I2C 湿度传感器Adafruit_BMP085_Unified bmp180 =Adafruit_BMP085_Unified(10085); // I2C 按 SensorAdafruit_HMC5883_Unified mag =Adafruit_HMC5883_Unified(12345); // I2C Compa Sensor//取消注释以下2行以启用GPS//串行调试将不可用//HardwareSerial mySerial =Serial;//Adafruit_GPS GPS(&mySerial); void setup(void) {// 1.1V 内部模拟参考 //analogReference(INTERNAL);///////////// 附件屏蔽上 OLED 的信号 /////////// //// D2、D3、D9、D10所需的屏蔽上的焊接桥接// pinMode(2,1); // 自复位 D2 到 RST pinMode(3,1); // xbee int 12, pinMode(9,1); // xbee int 13 pinMode(10,1) 输出;// xbee int 16 输出// digitalWrite(2,HIGH);数字写入(3,高);数字写入(9,低);数字写入(10,高); pinMode(7,1); pinMode(8,1);数字写入(7,高);数字写入(8,低); // A0 上的 10k POT // A1 上的 Vin Batt/供应 (3.91k/21.76k)/////////////////////////// ///////////////////// 用于调试的串行通信(可选)////////// Serial.begin(9600);// /////////// 加速初始化等待 ///////// if (!accelerometer.begin()) { delay(50); }////////////// RTC中断使能////////DS3231_init(DS3231_INTCN); ////////////// 蜂鸣器初始化//////////////pinMode(11,1);digitalWrite(11,LOW); }void loop(void) { // 图片循环 u8g.firstPage();做{画(); } while( u8g.nextPage() );// I2C传感器之间切换 sensor_selector++; if (sensor_selector>=3) {sensor_selector=0;}//////温度获取API ////// temp=termo.getTemp(); delay(5);// "C//////// 压力获取 API ////////if(sensor_selector ==0){ ///////////// 压力传感器Init ///////// if(!bmp180.begin()) delay(11);sensors_event_t event;bmp180.getEvent(&event);if(event.pressure){prsr =event.pressure/10;/ /hP to kP delay(50); } }//////////// GPS Init //////////GPS.begin(9600);//// /// 海拔获取 API ////////if(sensor_selector ==0){ sensors_event_t event; bmp180.getEvent(&event); alt =bmp180.pressureToAltitude(1013.25,event.pressure); delay(50); // bmp180.end();}// 在仪表中 //////////// 湿度传感器初始化 ///////if(sensor_selector ==1){ am2320.begin(); delay(50);////// Humidity Fetch API ///////// humd=am2320.readHumidity(); delay(50);// am2320.end(); // in % of RH}// in kPa////// Acceleration Fetch API ////// Vector norm =accelerometer.readNormalize(); X =norm.XAxis; Y =norm.YAxis; Z =norm.ZAxis; Gravity =sqrt(X*X + Y*Y+ Z*Z)-(0.3);// 偏移量// 以米/秒^2///// 时间获取API /////// DS3231_get(&t); s=t.sec;m=t.min;h=t。小时; dy=t.mday; mo=t.mon;年=t.年; ///// 罐头位置获取 /////// pot=analogRead(A0)*5/(10*3); delay(2);///// VBatt/Supply Fetch /////// // 1.1 就是这个芯片的 1.08 Vbatt=(1.08*analogRead(A1)/1023)/3.91*((3.91+21.76) ); delay(2);///////// 罗盘方向////////if(sensor_selector ==2){ if(!mag.begin()) { while(1); } // 延迟(70); sensor_t sensor2; mag.getSensor(&sensor2);延迟(70); // 偏角取决于地理位置 // 使用 GPS 中的纬度经度计算sensors_event_t event2; mag.getEvent(&event2); // Xm =event2.magnetic.x; // Ym =event2.magnetic.y;延迟(70);浮动偏角 =0.0;标题 =atan2(event2.magnetic.y, event2.magnetic.x);航向 +=偏角; // 符号修正 if(heading <0) Heading +=2*PI; if(heading> 2*PI) 标题 -=2*PI; // 将弧度转换为度数以提高可读性。标题 =标题 * 180/M_PI; // mag.end();} ///// 蜂鸣器控制 ///////// 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);如果(向上)色调+=0.025;否则色调-=0.025; if (hue>=1.0 &&up) up =false;否则 if (hue<=0.0 &&!up) up =true; }///////////////////////////////////////// 自我重置//// /////// // digitalWrite(2,LOW);///////////////////////////////// } ///////// 空循环到此结束 /////////////////////// Oled Picture Loop Draw Fn///////// //////////void draw(void) { 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.setFont(u8g_font_7x13);// u8g.setPrintPos(40, 25); u8g.print(round(temp));u8g.drawStr(55,25, "'C");// u8g.print(round(temp)); u8g.setFont(u8g_font_5x8);// u8g.drawStr( 5,40, "x "); u8g.setPrintPos(15, 40); u8g.print(round(X));// u8g.drawStr(50,40,"y"); u8g.setPrintPos(60, 40); u8g.print(round(Y));// u8g.drawStr(90,40,"z"); u8g.setPrintPos(100, 40); u8g.print(round(Z));// u8g.drawStr(68,22,"BATT:"); u8g.setPrintPos(95, 22); u8g.print(Vbatt);u8g.drawStr(123,22,"V"); u8g.drawVLine(37, 18, 36); u8g.drawStr(39,24,"空气温度:"); u8g.setPrintPos(85, 24); u8g.print(temp);u8g.drawStr(118,24,"C"); u8g.drawStr(39,34,“湿度:”); u8g.setPrintPos(85, 34); u8g.print(潮湿);u8g.drawStr(118,34,“%”); u8g.drawStr(39,44,“压力:”); u8g.setPrintPos(85, 44); u8g.print(prsr);u8g.drawStr(118,44,"hP"); u8g.drawStr(39,54,“海拔:”); 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); // Demo,当GPS添加时替换为LAT u8g.drawStr(69,64,"LONG:");u8g.setPrintPos(94, 64); u8g.print(90.36);// 演示,添加 GPS 时替换为 LON // u8g.setPrintPos(40, 25); u8g.print(round(temp));u8g.drawStr(55,25,"'C"); int r =round(sqrt(X*X + Y*Y)); // float tid =atan(Y/X)*180/3.1415;// 数学问题 // int radius =round(tid); u8g.drawStr(0,22,"标题"); u8g.drawCircle(18, 34,r, U8G_DRAW_ALL);// 内平圆 u8g.drawCircle(18, 34,10, U8G_DRAW_ALL);// 外固定圆 // 内圆在 x 和y 轴 // 这是罗盘航向更准确的时候 //u8g.drawLine(18, 34,(18+round(Y*2)),(34+round(X*2))); //放大 2 倍 u8g.setPrintPos(0, 53); u8g.print(标题); // 0 或 360 是 N // 90 是 E // 180 是 S // 270 是 W // u8g.setFont(u8g_font_5x8); if ((heading>315)|(heading<=45)) {u8g.drawLine(18,34,8,34); }if ((heading>45)&(heading<=135)){u8g.drawLine(18,34,18,24);}if ((heading>135)&(heading<=225)){u8g.drawLine (18,34,28,34);}if ((heading>225)&(heading<315)){u8g.drawLine(18,34,18,44);}// u8g.drawLine(18, 34, (18+轮(Y*2)),(34+轮(X*2))); //基于加速度计放大 2 倍 // 循环到此结束 }
库C/C++
解压缩并将单个库 zip 添加到 Arduino 库管理器无预览(仅下载)。
示意图
制造工艺