loading

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.

<p>Been having some fun testing this device. Haven't yet put it on scout, but it works quite well walking around the property. I changed the code to put out more Google Earth friendly data. </p><p>void execute_command_export()<br>{<br> int itemsCount = 0;<br> read_int(0, itemsCount);<br> Serial.print(&quot;read itemsCount=&quot;); Serial.println(itemsCount);<br> Serial.print(&quot;Latitude,Longitude,LineStringColor,Icon,IconColor,IconHeading&quot;);<br><br> struct LocationItem loc;<br> for (int index = 0; index &lt; itemsCount; index++)<br> {<br> read_location_item(index, loc);<br> print_location_item(loc);<br> } <br>}</p><p>void print_location_item(const struct LocationItem &amp;v)<br>{<br> Serial.print(v.lat, 6); Serial.print(&quot;,&quot;);<br> Serial.print(v.lng, 6); Serial.print(&quot;,cyan,none,yellow,line-180&quot;); // See the ExcellTo Kml website to explain this.<br>// Serial.print(v.time.hour); Serial.print(&quot;:&quot;);<br>// Serial.print(v.time.minute); Serial.print(&quot;:&quot;);<br>// Serial.print(v.time.second);<br> Serial.println(); <br>}</p><p>If you copy the data and save it to a .csv file (Excel comma delimited text) then use the web site:</p><p><a href="https://www.earthpoint.us/ExcelToKml.aspx#GpsTrack" rel="nofollow">https://www.earthpoint.us/ExcelToKml.aspx#GpsTrack...</a> to convert it and load it into Google Earth you get a nice track line.</p><p>I've also been playing around with the read interval. One or Three seconds is too much detail. 30 seconds may be too long. I'll know more when I can get it mounted on Scout. I'd like to be able to leave it on for 8 hours or more in case he decides to pull an all nighter. </p>
<p>Thanks for the code update, you are welcome to create a PR in github if you fells like it :)</p><p>About the need to run it for 8 hours, there are two main factors to consider: battery and memory.</p><p>I aim for 2 hours max so the battrey was not an issue, even though I didn't do any real testing of how long battaries will last. I was more concerned with having enough memory to keep the locations.</p><p>If you aim for 8 hours then batteries do become an issue and that's outside my knowledge but I do know you should put both the Arduino and the GPS module in some kind of sleep mode, from what I read there are multiple modes of sleep.</p><p>Than again, if you put 4 AA battaries it might be just enough as it is.</p><p>Thank you again for sharing the updates.</p>
I meant to ask you about that storage issue. Do you have any idea how many records can be saved? And if you don't save the time value, does that get you more records. I really haven't tried to look into this myself yet. I do have a nice case to hold the device and a way to mount it on the harness so I'll be trying it on Scout soon.
<p>In the code I've published each record is 10 bytes (SERIALIZED_LENGTH) made up of long-lat-time. I'm &quot;squizing&quot; time into 2 bytes, you can see write_time function.</p><p>The memory is 32k byte which means we have 3276 / 10 = 3,276 entries.</p><p>You can calcualte the time by 3276 * interval_in_seconds / 60 / 60 = hours-to-run - in my code 3276 * 3 / 60 / 60 = 2.73 hours.</p><p>One relatively easy way to extend this is to check the last two entries and update the last entries (instead of adding new one) if the diff between the one before last and the current location does not exceed say 5 meters.</p><p>Also, remove the time field will of course leave more room for entries.</p>
<p>Yes, that confirms what I thought. I removed the time two bytes and set the record time for 15 second interval. That seems to give me 4000 records in 8 hours. 4 batteries should last that long. Thanks again for this fun and educational project.</p>
<p>I think I see the problem. Your BOM calls for a 2 AA battery box. That's only 3vdc. In your wiring list all the VCC inputs are 5vdc. I rewired it to use a 4 AA box and took the 3v from the Nano to run the GPS. The data looks good now. </p>
<p>Hi,</p><p>Thanks for the picture and also for the fix to use 4 battaries!</p><p>I also notice that when the battaries low the GPS doesn't always works.</p><p>You should have a blinking LED on the GPS module when the GPS has good connection and is able to read the location, if the LED on the GPS does not blink it will not record locations.</p>
<p>Completed the breadboard. Everything sees to work. Not real impressed with the accuracy so far. How to know when it's actually recording? I turned it on and went to the store with it. Got back and had no data at all. It looks like it's not recording on battery, only on USB power.</p>
<p>Fun Project. I was looking for this because our dog Scout just hates being confined to the 45 fenced acres and prefers to roam the thousands of forest acres around us. Occasionally he's gone over night and we want to see where he goes and exactly where he gets out of the fence. So far I've got the Nano and the GPS talking and waiting for the EEPROM to get here from China, this week I hope. </p><p>Looking forward to trying the real-time version. Thanks.</p>
<p>I'm happy to see the project helps you.</p><p>I have some set back with the online version :\ but I do hope to get around to it.</p>
<p>Awesome idea! </p>

About This Instructable

917views

27favorites

More by Ido Ran:Finding Lychee - Dog GPS Offline Tracker 
Add instructable to: