Last week, I moved from New York to San Francisco to start a new job. You can read all about it in my last blog post. I used the PODs shipping service to send all my stuff across the country. PODs drops off a shipping container at your starting point, gives you as much time as you need to pack it, then they pick it up and deliver it to your end destination on the date you specify. The evening before my POD was set to be picked up, I decided that it would be cool to track my POD’s location across the country in real-time. In just a few hours, I threw together a real-time GPS tracker system. I even drove around with it for an hour to confirm that it would work and record data to my website. Needless to say, it didn’t continue to work for the entire cross country trip. In this post, I’ll explain exactly how the system worked, I’ll share all the source code (as is) and I’ll provide the parts list. Then, I’ll do a quick postmortem to try to figure out why it died just one day into the journey. This post serves as an important reminder that projects often don’t work the way you intended on the first time around; it’s really important to analyze both your successes and failures so that you can figure out the best way to prevent similar problems from happening in the future.
How it was Supposed to Work
The flowchart above should give you a good idea of how the system is set up. Inside the POD, I used an Arduino Uno, a Cooking-Hacks 3G/GPS Shield (actually overkill since I sent data via SMS), a SIM card set up for 30 days of pay-as-you unlimited texting, and a beefy battery pack (the same one I used for my Control-my-Cap Project). The photo below shows the complete setup. When installed in the pod, the tracker unit was taped to a ceiling beam, and the GPS antenna was aimed straight up (and taped in place).
The arduino runs a relatively simple loop, with a bunch of code based on the excellent tutorials provided by cooking-hacks.com. I threw in the narcoleptic library at the last minute in an attempt to conserve some power without spending a lot of time on power consumption analysis. The unit first attempts to get a GPS lock. If it fails repeatedly, then it is probably somewhere out of satellite range, and it goes to sleep for several minutes before searching for a signal again. Once it does find a signal, it grabs the raw data, puts it in the body of a text message, and sends it to my Twilio cloud phone number. If it doesn’t have cell coverage, it will keep retying until it gets a cellular signal (this is probably the program’s main failure point). It then sleeps for 10 minutes before trying to send another update. When the Twilio server receives the text message, it uses an HTTP POST webhook to send it over to a parsing PHP script on my server. This script confirms that the message came from my Twilio account, then it decodes the message into latitude, longitude, time, altitude, and speed. It saves the new data into the next line of a simple text file. When a user visits the mapping site (pod.jeremyblum.com), the text file is parsed, and the Google Maps API is used to plot the points on a full-screen map. The map zooms to the most recent datapoint, datapoints can be clicked for more detailed information, and the last datapoint bounces up and down.
All the software (both the web interface/parser and the Arduino code) is available from my GitHub account. The GitHub page also includes more detailed instructions regarding how to setup the system for your own experiments. This project is licensed via a Creative Commons Attribution-ShareAlike 3.0 Unported License. Please Attribute and Share-Alike.
How it Actually Worked
Given that I only thought of doing this the night before the POD was set to be picked up, I wasn’t particularly surprised that it didn’t make it through the whole journey. After I finished a rudimentary first-pass at the system, I set it up in my car, and drove around my neighborhood for an hour. As I drove, I used my laptop to download updated code as I fixed bugs that I identified. In the time I had, I did the best I could to iron out problems, but I certainly didn’t have time to account for every potential problem. Once the pod was picked up, I excitedly watched its journey from my home, along a few highways, and across the Hudson River. The screenshot below shows the datapoints with a red overlay (added afterwards) showing the route that I assume was taken given the available datapoints:
I was thrilled to see that I was actually collecting data! Then, it stopped, just a few miles west of the Hudson. After some digging, I determined that PODs has a storage facility very close to the last beacon I received (indicated by the blue dot on the map above). Since I gave PODs 12 days to get it across the country, but the trip only takes 9, I figured they were keeping the POD in local storage for a day or two before sending it on its way. If the storage facility was in a building, then it also stood to reason that a GPS fix would be lost, and I wouldn’t get data for a few days. Unfortunately, a few days passed, and by the time it should have been on the road again, I was not receiving any more data. I didn’t have any time to do a power analysis before sending the unit on its way, so the odds are good that the battery just died trying to get a GPS or cellular fix. Even with the sleep cycles that I had put into the code, the unit wasn’t really designed to sip power. Unfortunately, I’ll never really know what caused the failure, since I also didn’t have time to setup any kind of debug logging (though the shield I used did have an SD card that would have made that fairly easy).
Though I did get a few exciting datapoints, this project obviously didn’t work out the way I had hoped. Frankly, I would have been extremely surprised if it actually made it all the way to California without breaking. However, I don’t consider this project to be failure; consider everything I learned in just the few hours that it took me to build it: I learned how to use Twilio, I learned how to send SMS messages with an Arduino, I learned how to use the Google Maps API to build a fullscreen interface, and I learned the importance of planning one-shot projects much farther in advance. I’m sure I’ll move again at some point in the future. And, when that time comes, I’ll be ready with a seriously awesome GPS tracker (that hopefully won’t fail an hour into the journey).