As you may or may not already know, the IMA organizes an artist residency each summer on Andrea Zittel’s Indy Island within 100 Acres. This year, the park will be inhabited by A. Bitterman and the project is called Indigenous. As part of the project, Mr. Bitterman wants to provide spectators an opportunity to track the artist.

To accomplish this, we first looked into commercial GPS solutions that would allow us to send realtime GPS data over the web that could then be plotted on a map. The closest thing we found is the Garmin Communicator API that works with select devices. Unfortunately this came with limitations on how often data could be polled, so it turned out to be less then a desirable solution.

Enter Arduino.

What is this strange word and what does it have to do with tracking artists? Arduino is an open source microcontroller for scientists, engineers, programmers, and hobbyists. Stopping short of my personal opinion that this little device will revolutionize hardware like Linux revolutionized software, I will say it was exactly what we needed.

Most any store that sells an Arduino also sells what are called “shields.” These shields allow you to attach different electronic circuits to the Arduino so that you can program your software to control and utilize them. For our application, we needed a GPS shield to track our artist and a cellular GSM shield to transmit the data back to us over the cellphone network.

All of the data aquired is plotted on a map using a hex binning algorithm

WARNING: the following contents are about to get very technical and nerdy. If you aren’t interested in the technical bits and just want to see where the artist is, you can jump straight to the website to “track the artist.”

Overview

This device utilizes the Arduino Uno R3, the sm5100b GSM/GPRS cellular shield and the EM406 GPS shield. The design was based off the work done by Jayesh and tronixstuff. When the system is provided with power, it will first initialize the GPRS network. Once the network has been initialized it will attempt to acquire GPS data and proceed to send the data back to a server running a Python script on port 81. The Python script will receive the data and store the result into a MySQL database. All of the source code for this project is available at github. So fork it and try it out!

Assembly

Because the shields come pre-assembled, this step is relatively straight forward. Along with your shields, you will need two sets of 6 and 8 pin headers per shield. Solder these on and simply stack the GSM shield onto your Arduino, with the GPS shield on top of that. If you would like to utilize the diagnostic LEDS, connect a green LED and 220 ohm resistor in series from pin 13 to ground, and a red LED and 220 ohm resistor in series from pin 12 to ground. On the GPS shield, flip the switch from DLINE to UART.

Optional: When the time came to test the device on battery power, I had an issue that prevented the sm5100b from initializing on power up. This chip requires a fair amount of current when it is first powered on (up to 2amps). The issue only occured for me when the GPS shield was powered on, as well. To avoid this, I removed the 3.3v, 5v, and vIn pins from bottom side of the headers on the GPS shield. After removing those, I ran a jumper from digital pin 9 to the 5v pin on the header. More about this in the code break down.

Programming the Arduino

I will only cover the import sections of the source code in this article. If you would like the full source, see the link at the bottom of this article. Before you begin, you will need to download the PString and TinyGPS libraries from Arduiniana.

First, we define some constants for error handling, We will provide handling on a few different errors that, when triggered, will flash the red LED, much like the diagnostic codes that cars provide. Our error handling function can then be called anywhere in the code by passing one of the predefined constants to trigger an error. The switch statement will then tell us how many times to flash the error LED, and it will stay in an infinite loop repeating the diagnostic message until the Arduino is powered down or reset.

Here we define the pins, The GPS shield transmits on pins 1 and 2, which means it will also be sharing the serial line with our Arduino. The sm5100b will utilize pins 2 and 3 and we will use the SoftwareSerial library to interface with. We also define our diagnostic LED pins as 12 and 13. Lastly, our GPS relay is defined on pin 9. This is only necessary if you have issues initializing the sm5100b on battery power.

Then we create a new TinyGPS instance and initialize a SoftwareSerial instance for the sm5100b. In the setup() function, our LED pins and GPS relay pins are set as output. Because the GPS shield is sharing its serial line with the Arduino, we don’t need to setup a software serial instance for it. We simple call Serial.begin(4800), which will establish a serial line at 4800 baud, the speed that the GPS chip communicates. We also need to begin the software serial instance at 9600 baud by calling cell.begin(9600);

NOTE: The sm5100b module should come preconfigured at 9600 baud. In my case, it was configured at 152800 baud. If this happens, you will need to connect a jumper from pin 1 to 4, and pins 2 to 3. Create a sketch that defines an empty setup() and loop function and upload that to your Arduino. Then from the serial monitor, send the command AT+IPR=9600. This will configure the sm5100b to communicate at 9600 baud.

First we check if firstTimeInLoop is true. If it is, we know we need to wait for the sm5100b to initialize before we can start acquiring data from the GPS. Once our cellular connection is established, we poll the GPS shield to get the data and then proceed to send that data back to the server. Once that is complete, we will pause for ten seconds and then the loop will be repeated.

Talking to the sm5100b consists of three primary function. ReadATString() creates a buffer that will read any responses character by character from the serial line. Once a line break is received, the function returns with the variable at_buffer containing the contents of our response. Once the buffer is filled, ProcessATString() is called and will compare the response to a few expected outcomes.

When the sm5100b initializes it will return the string +SIND: 1. This is where the previous hack I mentioned with the GPS occurs. As previously noted, we remove all pins that provide power to the GPS. This will prevent the chip from powering up when the Arduino is powered on. Once we receive the +SIND: 1 command telling us that the sm5100b is powered on and has detected the SIM card, we pull pin 9 high with will supply 5v to the GPS, thus powering it on. Once we receive +SIND: 11 and +SIND 4, the cellular connection has been established and we can proceed to send AT commands.

Here we acquire the data via our instance of the TinyGPS class and build the AT command that will send the data to the server via the PString instance we created. We are going to log latitude, longitude, cardinal direction, and speed.

Now that we have our AT command ready to send, we will have to send all of the required commands to establish our GPRS connection. Once the connection has been established, we will connect to the host and send the data. Once the data has been sent we close the connection. MyStr.begin() is called to clear the PString buffer and successLED() is called to blink the status LED, just so there is some type of visual indicator that the transmission has been sent.

This is just a small breakdown of the functionality of the Arduino sketch. If you would like to see the full source code go here.

Server side

For the server side, we are going to use Python and leverage the open source socket library Twisted. The examples sited at the beginning of this article use Python’s built in sockets class to aquire data. I decided to use Twisted as it already has built in support for multiple connections, which is useful if for any reason our client does not successfully close the connection. Those connections can gracefully time-out without impeding any new attempts to connect to the server. Twisted can also handle exemptions without killing the process, which also proves useful.

This code is fairly straightforward. When a connection is made, we will print to the console, and when data is received, we will attempt to issue a MySQL query that will insert the data into the database.

Conclusion

In the process of building this, I found many forum posts, articles, etc. of people having problems getting the sm5100b shield working. Hopefully this post will provide assistance to others trying to work with this module. Overall, I found the sm5100b to not be the most reliable chip in the world. For mission critical apps, I would not recommend this set-up. The code could be altered to more reliably handle network failures, but in this example it simply ignores them and moves on.

Hopefully you found this article helpful. Feel free to post a comment and provide some feedback.

This entry was posted on Tuesday, June 26th, 2012 at 2:26 pm and is filed under Art and Nature Park, Technology.
You can follow any responses to this entry through the RSS 2.0 feed.
Both comments and pings are currently closed.

4 Responses to “Tracking the Island Resident with Arduino”

Kris – I can run this on AT&T OK, when I change to t-mobile apn and use my t-mobile chip(works on another sketches) there is no connecting to the TCP Server. The only difference on the code is the APN and chip. Do you know why ?