Introduction: Finding Lychee - Dog GPS Offline Tracker

I have a dog name Lychee that like to go to walks alone and when she comes back I always want to know where she has been.

Using Arduino Nano + NEO-6M GPS module + AT24C256 EEPROM - I was able to build a device that will capture the GPS locations every 3 seconds and when she comes back I copy the data to a map to see the path.

Using the GPS module was surprisingly easy, both wiring and coding thanks to open-source library name TinyGPS++.

Using the EEPROM however was more evolve than I imaging. To be fair I'm a developer with desktop and web-applications background, so moving from GB of storage to 32 KB that required a shift in thinking.

The source code can be found in Github

Step 1: Hardware

The BOM required for this project

  1. Arduino Nano - I bought it on eBay for about 4$ (You can use Arduino Uno - it's just a bit bigger).
  2. U-blox NEO-6M GPS module - I bought it on eBay for about 10$
  3. AT24C256 Serial EEPROM I2C Interface - I bought it on eBay for about 2$ for 2 pieces
  4. 2 AA Battery Holder Box - I bought it on eBay for about 1$
  5. Small breadboards
  6. Jumper wires

Total cost is about 17$ + wires

Wiring was straight forward

NEO-6M GPS

Module - Arduino

VCC - V5

GND - GND

RX - D4

TX - D3

AT24C256 EEPROM

VCC - V5

GND - GND

SCL - A5

SCD - A4

Arduino (Power)

Black - GND

Red - V5

Step 2: Software - GPS

The purpose of the application is to read the GPS module every 3 seconds and write the location to the EEPROM. After Lychee will return we'll take the device and connect the Arduino to a computer using the USB cable and will export the data from the EEPROM to the serial monitor and then paste it to web-site that show the path on a map. You can use several sites, I use darrinward.com.

Reading location from the GPS

That was actually surprisingly simple to do. First you need to download TinyGPS++ library and add it to your Arduino IDE by selecting Sketch -> Include Library -> Add .ZIP Library and select the zip file you just downloaded.

That will add two things:

Under Sketch -> Include Library -> TinyGPSPlus-0.94b you can add the library to your sketch.

Under File -> Examples -> TinyGPSPlus-0.94b you have several examples, the interesting two are DeviceExample and FullExample.

DeviceExample show the minimum code for talking with GPS module such as NEO-6M and print location and date-time information. Try to run it and open the Serial Monitor, if you see No GPS detected: check wiring. it means something is not working with the GPS module. Try the following to fix it:

  • Make sure all the wires are connected well and correctly
  • Flip the RX and TX - better flip the values in the code than the actual wires
  • Change the const name GPSBaud to 9600 (the example comes with 4800)

The first time you'll use the GPS module it takes longer (I've read that it can take up-to 15 minutes) to find satellites, also you'll probably be indoors which makes it even harder to find them so my suggestion is to either work outside if you can or sit close to a window and put the GPS antenna in clear line to the sky.

The main part of the code is

while (ss.available() > 0)
<p>  if (gps.encode(ss.read()))</p><p>    displayInfo();</p>

It uses SoftSerial to read characters from the serial communication with the GPS module and fed it into the TinyGPS++ library which decode the data and provide simple API to get long, lat, date and time information.

smartDelay

This function allow the code to delay while still "feeding" the GPS library so when we'll read the location it will be up-to-date.

Step 3: Software - EEPROM

Working with the EEPROM turn out to be harder than I anticipated. The AT24C256 chip has 256 Kbit of memory which is 32 Kbyte.

I use the code in Arduino Playground for I2C EEPROM which include 2 ways to work with the memory: one-byte at a time or one page a time. The have small warning of WARNING: address is a page address, 6-bit end will wrap around - which means that due to the physical structure of this chip write operation has to be done inside a single page, if you go over a single page the write will wrap around to the beginning of that page. You can read all the details and how to solve it in this post but I've decide to simply work with one byte at a time.

The data structures I work with in this app are as follows

struct Time<br>{
  byte hour;
  byte minute;
  byte second;
};
struct LocationItem
{
  float lat;
  float lng;
  Time time;
};

float is 4 bytes so I need to write 1 byte at a time and for that I wrote write_float function and read_float.

Time structure is made up of 3 bytes but I've manage to push it into 2 bytes by limit the hour to be only 12 hours instead of 24 (since the recording can be done for about 2.7 hours there is no point in 24 hours clock). The numbers 0-11 require 4 bits. The minute and seconds are 0-59 values which require 6 bits each together 4+6+6=16 bits which is exactly 2 bytes. You can see write_timewrite_time and read_time for the bit manipulation to serialize and deserialize Time structure to bits and back.

The only thing left is manage the list of recorded locations. For that I keep an int (2 bytes) at position 0 of the EEPROM and that int is the number of locations we recorded until now. Every time we record a new location we read this value which allow us to calculate the location to write the new location and then we increment the records number and write it back to location 0. Look at add_location_item for the code.

Step 4: Software - Serial Command Line

In order to export the data recorded by the device and to be able to reset the memory I've create a very simple serial command line. To active it connect the Arduino to your computer using a USB cable, open Arduino IDE and click on the Serial Monitor button. If you get an error message make sure to select Tools -> Board -> Arudino Nano and Tool -> Port -> [Your Port] and Your Port is depond on your computer and OS.

The command line support only single digit commands input in the Serial Monitor interface

0 - show help

1 - export data to the serial interface

2 - reset the record counter (it first export the data just to be safe).

See process_serial_command to read the digit from the Serial interface and execute_command to actually call the specific command.

Step 5: Mount the GPS on Lychee

The last hard part of this project was to find a way to mount the GPS on Lychee with minimal discomfort.

I've used a pill-bottle to push the whole electronics into to keep it safe. I've used the soldering iron to remove the bottom of the bottle, I've cover the electronics with isolierband to reduce the chance of things touching each other and I use hot-glue to make sure the jumper-wire will not jump.

I've made a way for the GPS antenna wire and using a hook-and-loop to glue it to the top of the bottle.

Then I've use a lot of hook-and-loop to make sure the bottle with the electronics and the batteries will remain connected to a dog harness.

I'm sure there are better ways of doing this :)

Those are the materials I have and it seem that Lychee did not complain to much.

Step 6: Conclusion and the Future

It was a lot of fun building this project. Most of the time I spent learning and playing with the EEPROM module and harness the GPS on my dog.

Few things I've learn along the way:

  1. Even when the Arduino seem to be on according to the LED indicator it does not mean the whole circut is working, I've notice that when the batteries are week the GPS does not work and currently it's hard to notice the GPS LED is not blinking when the electronics is inside the bottle.
  2. Packing the electronics is harder then it first seem, especially since I've used the breadboard and not costum circut.
  3. Testing, testing, testing. I've took the GPS with me in my car for test drive, literally, and it help me see how it works.
  4. Mount is electornics on my dog was not something I though about at the beginning and assume I'll find a way. I did but maybe thinking about it earlier could make things easier.

The evolution of this project is to add a RF transmitter that will send the location data in real-time to a base-station that will show the data on a map. I plan to use 433Mhz HC-12 SI4463 Wireless Serial Port Modulewhich according to the amazing Instructables about it should work to a distance of up-to 1.8 Km in clear line-of-sight so I really hope it will work to about 1Km of real terrain with trees and houses.