Shahariar
Published © LGPL

Hiking Tracker

Tracks compass heading, altitude, temperature, pressure, humidity, time, travel distance and GPS location during a hike.

BeginnerFull instructions provided2 hours15,192
Hiking Tracker

Things used in this project

Hardware components

Arduino 101 & Genuino 101
Arduino 101 & Genuino 101
×1
AA Batteries
AA Batteries
×1
4xAA battery holder
4xAA battery holder
×1
Accessory Shiled
×1
Adafruit BMP180 Pressure Sensor
×1
Adafruit Ultimate GPS Breakout
Adafruit Ultimate GPS Breakout
×1
Adafruit - 3 Axis Magnetic
×1
Adafruit AM2320 Humidity Sensor
×1
Adafruit Coin Cell CR2012
×2
Resistor 10k ohm
Resistor 10k ohm
×1
Resistor 3.9 k
×1

Software apps and online services

Arduino IDE
Arduino IDE

Hand tools and fabrication machines

Hot glue gun (generic)
Hot glue gun (generic)
Soldering iron (generic)
Soldering iron (generic)

Story

Read more

Schematics

Hiking Tracker

Code

Hiking_Tracker.ino

C/C++
main.c
/*/////////// NOTE //////////
D2 allows soft reset assertable from code
D3,D9,D10 are available through 
12,13,16 of xbee interface
D4, D13 are not accessable
///////////////////////////*/

//// HEADER FILES FOR LIBRARY /////
#include <math.h>
#include <inttypes.h>

#include <Wire.h>
#include <lm75.h>
#include <ADXL345.h>
#include <ChainableLED.h>
#include "U8glib.h"
#include "ds3231.h"

#include "Adafruit_Sensor.h"
#include "Adafruit_AM2320.h"
#include <Adafruit_BMP085_U.h>
#include <Adafruit_HMC5883_U.h>
#include <Adafruit_GPS.h>


///////////////////////RTC Variables///////////////////
uint8_t time[8];
struct ts t;
int s;
int m;
int h;
int dy;
int mo;
int yr;

///////////////// Accelerometer Variables/////////////
float X=0.0;
float Y=0.0;
float Z=0.0;
float Gravity = 0.0;
///////////////// Accelerometer Variables/////////////
float Xm=0.0;
float Ym=0.0;
float Zm=0.0;
 

/////////////////////// RGB LED Variables///////////////
const int rgb_pwr = 12;                                     
const int clk_pin = 6;                                    
const int data_pin = 5;                                    
float hue = 0.0;
boolean up = true;

////////////////////// potentiometer///////////////////
int pot=0;  
//////////////////// Batt/Supply Vin /////////////////
float Vbatt =0.0;
//////////////////////Thermometer////////////////////
float temp = 0.0;
///////////////////// Humidity///////////////////////
float humid = 0.0;
////////////////////Air pressure////////////////////
double prsr = 0.0;
////////////////////Altitude ////////////////////
float alt = 0.0;
/////////////////// Lat, Long////////////////////
float lat = 0.0; float lon = 0.0;
//////////////////Compass Heading/////////////////
float heading =0.0;
///////////////////// Ohter Variables ///////////////

int mstime =0;
int sensor_selector = 1;
//////////// ENUM //I2C Device type Object /////////////////

U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE|U8G_I2C_OPT_DEV_0);   // I2C OLED  Display
TempI2C_LM75 termo = TempI2C_LM75(0x48,TempI2C_LM75::nine_bits); // I2C Temp  Sensor
ADXL345 accelerometer;                                           // I2C Acce  Sensor
ChainableLED leds(clk_pin, data_pin, rgb_pwr, 1);                // I2C RGB   LED
Adafruit_AM2320 am2320 = Adafruit_AM2320();                      // I2C Humid Sensor
Adafruit_BMP085_Unified bmp180 = Adafruit_BMP085_Unified(10085); // I2C Press Sensor
Adafruit_HMC5883_Unified mag = Adafruit_HMC5883_Unified(12345);  // I2C Compa Sensor

// uncomment the following 2 lines to enable GPS
// Serial Debugging won't be availabel

//HardwareSerial mySerial = Serial;
//Adafruit_GPS GPS(&mySerial);
 



void setup(void) {

// 1.1V Internal Analog Ref //
analogReference(INTERNAL);

///////////// Signals for OLED on Accessory Shield /////////////
// solder bridged on shield needed for D2,D3,D9,D10
// pinMode(2,1); // self reset D2 to RST
   pinMode(3,1); // outs at xbee int 12, 
   pinMode(9,1); // outs at xbee int 13
   pinMode(10,1);// outs at xbee int 16
// digitalWrite(2,HIGH);  
   digitalWrite(3,HIGH); 
   digitalWrite(9,LOW);  
   digitalWrite(10,HIGH); 

 pinMode(7,1);
 pinMode(8,1);
 digitalWrite(7,HIGH);  
 digitalWrite(8,LOW);
 // 10k POT on A0
 // Vin Batt/Supply on A1 (3.91k/21.76k)
////////////////////////////////////////////
///////// Serial Comm for Debuging (optional)////////
// Serial.begin(9600);

////////////// Accel Init Waiting /////////
  if (!accelerometer.begin())
  {
    delay(50);
  }

/////////////// RTC Interrupt enabling /////////
DS3231_init(DS3231_INTCN);                                          
//////////////// Buzzer Init ////////////////
pinMode(11,1);
digitalWrite(11,LOW);  

 }


void loop(void) 
{
  
  // picture loop
  u8g.firstPage();  
  do {
    draw();
  } while( u8g.nextPage() );

// switch between I2C sensors
 sensor_selector++;
 if (sensor_selector >= 3)
 {sensor_selector=0;}

////// Temperature Fetch API  //////
  temp=termo.getTemp(); 
  delay(5);
// "C
/////// Pressure Fetch API ////////
if(sensor_selector == 0)
{
  ///////////// Pressure Sensor 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);


/////// Altitude Fetch API ////////
if(sensor_selector == 0)
{
    sensors_event_t event;
  bmp180.getEvent(&event);

  alt = bmp180.pressureToAltitude(1013.25,event.pressure);
  delay(50);
//  bmp180.end();
}
// in meter
  ////////////// Humidity Sensor Init ///////
if(sensor_selector == 1)
{
  am2320.begin();
  delay(50);
////// Humidity Fetch API /////////
  humid= 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);// offset
// in m/s^2
///// Time Fetch API ////////
  
  DS3231_get(&t);
  s=t.sec; m=t.min; h=t.hour;
  dy=t.mday; mo=t.mon; yr=t.year;
 
///// Pot Position Fetch ///////
  
  pot=analogRead(A0)*5/(10*3);
  delay(2);

///// VBatt/Supply Fetch ///////

  // 1.1 is 1.08 for this chip 
  Vbatt=(1.08*analogRead(A1)/1023)/3.91*((3.91+21.76));
  delay(2);
///////// Compass Heading ////////
if(sensor_selector == 2)
{
  if(!mag.begin())
  {    while(1);
  }
 // delay(70);
  sensor_t sensor2;
  mag.getSensor(&sensor2);
  delay(70);
    // declination angle depends on Geo Location
  // use Lat Long from GPS to calculate
  sensors_event_t event2; 
  mag.getEvent(&event2);
 // Xm = event2.magnetic.x;
 // Ym = event2.magnetic.y;
  delay(70);
  float declination = 0.0; 
  heading = atan2(event2.magnetic.y, event2.magnetic.x);
  heading += declination; 
  //  sign correction
  if(heading < 0)
    heading += 2*PI;
  if(heading > 2*PI)
    heading -= 2*PI;
  // Convert radians to degrees for readability.
    heading = heading * 180/M_PI; 
//    mag.end();
} 
  
///// Buzzer Control //////////

  if (pot>80)
    {digitalWrite(11,1);}
   else 
    {digitalWrite(11,0);}

///// RGB Addressable LED Control /////////////
   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;
  }

/////////////////////////////////
////////// Self Reset ///////////
  //  digitalWrite(2,LOW);
/////////////////////////////////  
 
}///////// Void Loop ends Here ///



//////////////////// 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,"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); // Demo, replace with LAT when GPS added
  u8g.drawStr( 69,64,"LONG:");u8g.setPrintPos(94, 64); u8g.print(90.36);// demo, replace with LON when GPS added
  
//  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;// mathematical issues here
 // int radius = round(tid);
  
  u8g.drawStr( 0,22,"heading");
  u8g.drawCircle(18, 34,r,  U8G_DRAW_ALL);//  inner leveling circle
  u8g.drawCircle(18, 34,10,  U8G_DRAW_ALL);// outer fixed circle

  // inner circle will become a point when no tilt in x and y axis
  // this is when the compass heading is more accurate
  //u8g.drawLine(18, 34,(18+round(Y*2)),(34+round(X*2))); //scaled up 2x
  u8g.setPrintPos(0, 53); u8g.print(heading);
 // 0 or 360 is N
 //       90 is E
 //      180 is S
 //      270 is 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+round(Y*2)),(34+round(X*2))); //scaled up 2x BASED ON ACCELAROMETER
 
  
// loop ends here  
}

Libraries

C/C++
Unzip it and add the individual library zips to Arduino Library Manager
No preview (download only).

Credits

Shahariar

Shahariar

48 projects • 158 followers
"What Kills a 'Great life' is a 'Good Life', which is Living a Life Inside While Loop"
Thanks to Adafruit & Lady Ada.

Comments