OK finally we get to the part thats interesting, where you can log GPS data (and possibly other sensor data as well) to a memory card.
Please note that GPS logging to an SD card is kind of at the edge of the ATmega168's abilities in terms of RAM and flash storage. It works great but make sure to test any modifications and watch RAM usage in particular. Try to reuse the buffer created to store NMEA strings, and use putstring() and putstring_nl() instead of Serial.print() to display debugging data strings.
- If you have a '168 you'll need to start by reducing the Arduino library RAM footprint. Follow the instructions here, and set the RX buffer to 32.
- You should also download an older version of the IDE (later versions generate 'chunkier' code) such as v11
- You'll have to use the older AF_SDLog library, which is not supported anymore (we are only going to be using the SD library built into the Arduino IDE).
- This means you'll have to format your card in FAT16 (FAT32 isnt supported)
and other annoyances. We really suggest upgrading your chip.
Hooray! If you have '328 then this is all a heck of a lot easier because there is plenty of space. In fact we strongly recommend upgrading to a '328 chip if you don't have one. You will save a lot of time and struggle!
You'll need a SD card formatted in FAT16, most SD cards are formatted correctly 'out of the box'. You can see the formatting tutorial over at the Wave Shield page
Unplug the Arduino, remove the GPS module (for now) and insert the SD card into the holder on the underside of the shield.
Next you'll need to install the AF_SDLog library. Uncompress it and install it. If you have the Wave Shield library installed, you may have to uninstall it (remove it from the library folder) since it will conflict.
Next download the GPSLogger sketch. If your GPS module talks at something other than 4800, change the sketch with the new baud rate. Upload it to the Arduino and open up the Serial Monitor at 4800 baud (or whatever you changed it to)
You should see the above. The logger starts up, initializes the SD card and creates a new file called GPSLOG00.TXT. That file will be empty because there is no GPS data, so dont worry about that. The next time it starts the file will be called GPSLOG01.TXT, etc. If the SD card doesnt initialize, check that it is formatted FAT16, try another card, etc.
Once you have the SD card working, unplug the Arduino.
We need to rewire the shield one more time. Since '168s have pretty much no RAM left over after including the SD_Log library we can't use the NewSoftSerial library. Instead we will wire up the GPS so it shares the Serial connection with the USB-serial chip. That means that every time the Arduino does a print() it is going to the USB connection as well as the GPS module. Thats OK though, because GPS modules only pay attention to very specific GPS commands and we won't confuse it.
Connect TX to pin 0, RX to pin 1,. PWR to pin 2, L2 to pin 3, and L1 to pin 4.
Connect up the Arduino again and watch the Serial Monitor. This time you will see notification that GPS strings were received and properly written to the card You will need to have a lock from the GPS to get proper location data so stick the Arduino+GPS outside for a bit.
the $PSRF data is GPS customization data sent from the Arduino to the GPS module. In this case it tells the GPS module what NMEA data we'd like it to transmit. Then we see a bunch of #'s. This is feedback from the Arduino saying that a NMEA string was received, passed the checksum and properly written.
Here are all the characters the logger will print as feedback:
- # - NMEA string received, checksummed and written
- * - NMEA string received, but there was no checksum
- ~ - NMEA string received with checksum, but the checksum didnt match
- ! - NMEA string received but the data was too big for our buffer
- _ - NMEA string received, but the Arduino is programmed to only save data when there is an active fix so it was ignored.
The LEDs will also give indication to whats going on. If the green LED (LED1) is lit, that means that we have a location fix. If the red LED (LED2) is lit, that means data is being written to the SD card.
Since the GPS module is talking to the Arduino on the same data pin as the USB chip, you wont be able to upload new sketches while the GPS is running. For that reason, the shield has a TX jumper. Remove this jumper and the GPS will be disconnected from the Arduino.
Once you see the multitudes of LEDs blinking away for a bit and you feel like its time to stop, here is the safest way to turn off the Arduino. Just like you wouldnt want to turn off your computer while its in the middle of writing a document, you shouldnt cut the power to the logger while its writing to the SD card as there is a risk of data corruption. Simply remove the TX jumper when you want to stop logging. Wait till the red LED is not lit and then you can safely remove power.
Now that you have turned off the logger and removed the SD card, place it in your computer's SD card reader and open it with a text file reader (such as WordPad or TextEdit). You will see those familiar NMEA sentences staring back at you!
You can now import this data into programs like Google Earth. Some programs require special formatted data (which is quite annoying) and since this is such a problem, there is a website devoted just to solving this problem calle GPSvisualizer. Lets go thru how to convert NMEA data to Google Earth since thats very popular. (You can also convert to other formats.)
The defaults are pretty good. I like uncompressed kml data but it doesnt really matter.
Under Upload your GPS data here you should Browse... and select the GPSLOGxx.TXT you'd like to convert,
Click Create KML File and then you can download the KML file directly into Google Earth for viewing
There's a few small things you can do to customize the GPS logger. You can turn on and off specific NMEA sentences. For example
#define LOG_GSA 0 // satelite data
indicates that we do not want the GPS to emit satelite data. This saves memory card space and reduces power consumption. To turn on $GPGSA data, simply set it to 1:
#define LOG_GSA 1 // satelite data
You can also set it to only log data when we have a location fix (0 means log eveything, 1 means only log during fix)
#define LOG_RMC_FIXONLY 0 // log only when we get RMC's with fix?
You can turn WAAS on or off. This is an addition to North America where GPS can use ground stations to get up to 3 meter radius precision. Set it to 0 to turn off.
#define USE_WAAS 1 // useful in US, but slower fix
You can also save a bunch of power by putting the Arduino (and even the GPS module) to sleep. This doesnt make much sense if you need to log data once a second, which is the default. But if, say, you dont mind only grabbing data once every 10 seconds or minute, it can reduce power consumption a lot!
The SLEEPDELAY constant says how long the Arduino should sleep (do nothing, using no power) between reads. Setting this to 0 means it never goes to sleep. 10 means sleep for 10 seconds. You can use any # up to 255 seconds (4 1/4 minutes) If you have the LOG_RMC_FIXONLY variable set, it will not go to sleep -until- there is a valid fix sentence.
#define SLEEPDELAY 0 // how long to sleep before reading another NMEA sentence
If you want to really reduce power consumption, you can ask the Arduino to turn off the GPS module while it sleeps. You pretty much have to use LOG_RMC_FIXONLY with this option because the first 5 seconds after the GPS turns on is 'warm start' and you'll get about 5 no-fix data points before a fix is acquired. Its an advanced power saving feature and may require some experimentation.
#define TURNOFFGPS 1 // probably only want to do this if the sleep delay > 60 or so
One other annoying thing about NMEA is that theres no real standard for embedding sensor information into the data. So I wrote another sketch that will log RMC sentences, split them up into nice comma-seperated-values (CSV) and also log analog inputs 0, 1 and 2 values. Theres pretty much no more space for doing funky sensor processing on the Arduino but with the raw data, you can easily manipulate it on a computer by opening it up in a spreadsheet or data analysis program.