Solar Powered GPS Hiking Logger

by spyclub in Circuits > Arduino

7616 Views, 153 Favorites, 0 Comments

Solar Powered GPS Hiking Logger

IMG_4928.JPG
IMG_4913.JPG

The concept here is simple, I want to be able to log where I go on my walks so that after my walk I can see where I have been. In the past I have used GPS on my phone, but when going on an all day (8 hour) hike, by the end of the day my phone is flat and I cannot even make phone calls.

I have been given a neat 5W 5V (so 1A) solar panels, so I was thinking that I could power a little Arduino with a standard GPS module.

The Arduino and Code

IMG_4918.JPG

I have a CAN-BUS shield (from when my car was having engine problems and I tried to do my own diagnostics) and noticed it has a EM-406 socket to plug in a standard GPS module. I ordered a GPS module from ebay (all GPS modules EM-406 socket seem to be the same) and plugged in a micro SD card into the SD socket on the shield.

To make the GPS logging easy I found a most excellent library called TinyGPS++ which means I don't need to spend my time understanding the packets sent from the GPS module!

Using linux tools such as GPS babel or online tools such as GPS Visualizer the data can be converted between most standard formats, so I thought I would stick with CSV so that I could open it up excel or matlab, but can still easy convert to kml to view in Google Earth.

I have included the source code I used below, I have left the serial dumping stuff in for debugging purposes (so you can see your location from your laptop immediately).

The LED's built into the shield are used to indicate when the board is logging, and the other for when the GPS is locked.

#include <SPI.h>
#include <SD.h>
#include <TinyGPS++.h>
#include <SoftwareSerial.h>

const int LED1 = 7;
const int LED2 = 8;
const int chipSelect = 9;

const int RXPin = 4;
const int TXPin = 5;
int GPSBaud = 4800;
TinyGPSPlus gps;

SoftwareSerial gpsSerial(RXPin, TXPin);

void setup()
{
  Serial.begin(9600);
  gpsSerial.begin(GPSBaud);
  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
  pinMode(chipSelect, OUTPUT);

  if (!SD.begin(chipSelect)) digitalWrite(LED1, LOW);
  else
  {
    Serial.println("SD Card Setup");
    digitalWrite(LED1, HIGH);
  }
}

void loop()
{
  while (gpsSerial.available() > 0)
  {
    if (gps.encode(gpsSerial.read()))
    {
      if (gps.location.isValid() && gps.time.isValid() && gps.date.isValid()) digitalWrite(LED2, HIGH);
      else digitalWrite(LED2, LOW);

      logInfo();
      displayInfo();
    }
  }
}

void logInfo()
{
  if (gps.location.isValid() &&
      gps.time.isValid() &&
      gps.date.isValid())
  {
    File dataFile = SD.open("gpslog.txt", FILE_WRITE);
    if (dataFile)
    {
      digitalWrite(LED1, HIGH);
      
      dataFile.print(gps.date.day());
      dataFile.print(F("/"));
      dataFile.print(gps.date.month());
      dataFile.print(F("/"));
      dataFile.print(gps.date.year());
      dataFile.print(F(","));

      if (gps.time.hour() < 10) dataFile.print(F("0"));
      dataFile.print(gps.time.hour());
      dataFile.print(F(":"));
      if (gps.time.minute() < 10) dataFile.print(F("0"));
      dataFile.print(gps.time.minute());
      dataFile.print(F(":"));
      if (gps.time.second() < 10) dataFile.print(F("0"));
      dataFile.print(gps.time.second());
      dataFile.print(F("."));
      if (gps.time.centisecond() < 10) dataFile.print(F("0"));
      dataFile.print(gps.time.centisecond());
      dataFile.print(F(","));

      dataFile.print(gps.location.lat(), 6);
      dataFile.print(F(","));
      dataFile.print(gps.location.lng(), 6);
      
      dataFile.println();
      dataFile.close();
    }
    // if the file isn't open, pop up an error:
    else
    {
      digitalWrite(LED1, HIGH);
      Serial.println("error opening datalog.txt");
    }
  }
}

void displayInfo()
{
  Serial.print(F("Location: "));
  if (gps.location.isValid())
  {
    Serial.print(gps.location.lat(), 6);
    Serial.print(F(","));
    Serial.print(gps.location.lng(), 6);
  }
  else
  {
    Serial.print(F("INVALID"));
  }

  Serial.print(F("  Date/Time: "));
  if (gps.date.isValid())
  {
    Serial.print(gps.date.day());
    Serial.print(F("/"));
    Serial.print(gps.date.month());
    Serial.print(F("/"));
    Serial.print(gps.date.year());
  }
  else
  {
    Serial.print(F("INVALID"));
  }

  Serial.print(F(" "));
  if (gps.time.isValid())
  {
    if (gps.time.hour() < 10) Serial.print(F("0"));
    Serial.print(gps.time.hour());
    Serial.print(F(":"));
    if (gps.time.minute() < 10) Serial.print(F("0"));
    Serial.print(gps.time.minute());
    Serial.print(F(":"));
    if (gps.time.second() < 10) Serial.print(F("0"));
    Serial.print(gps.time.second());
    Serial.print(F("."));
    if (gps.time.centisecond() < 10) Serial.print(F("0"));
    Serial.print(gps.time.centisecond());
  }
  else
  {
    Serial.print(F("INVALID"));
  }

  Serial.println();
}

Testing

IMG_4916.JPG
IMG_4917.JPG

Now, because I am a bit of a night owl, there is not much daylight in my hackspace, so for testing I connected the solar panel up using a standard USB connector and held a light over the panel so that I can at least power up the Arduino. It just about worked but would probably be best during daylight hours.

Mounting to the Bag

IMG_4920.JPG
IMG_4921.JPG
IMG_4922.JPG
IMG_4924.JPG

I have a 5.11 tactical Rush 24 rucksack that I use typically when I am going on my hikes, and fortunately it has a mounting standard called MOLLE for attaching their pouches. Essentially this means the backpack is covered in 1 inch loops which you can thread things through without damaging the bag. So, to attach the solar panel I used some cable ties which means they are semi permanently attached without damaging my bag.

Hiding the Electronics

IMG_4926.JPG
IMG_4925.JPG

The bag has a camera pouch as the top next to the handle, which has a nice felt lining to protect the camera, so it would work well to protect the Arduino electronics. I mounted the USB connector towards the top of the bag so that the cable run was very short and neat (no cables to tidy away).

The Finished Bag

IMG_4927.JPG

So, here it is, only a small blue USB cable which can be plugged in and unplugged whenever it is needed or not needed. The panel is very secure, and I have even tweeked it some more with a set of reusable/resealable cable ties so that I can take the whole panel on/off when I don't need to log.