1 /* Arduino Projects for Dummies
4 * Chapter 13: Building a GPS Data Logger
5 * Uses Adafruit Industries Ultimate logger shield
6 * to capture GPS data and record it to an SD card
11 * This code is from http://www.adafruit.com and is slightly modified to
12 * run on an Arduino Uno by default.
13 * Ladyada's logger modified by Bill Greiman to use the SdFat library
19 #include <Adafruit_GPS.h>
20 #include <SoftwareSerial.h>
22 #include <avr/sleep.h>
23 #include "GPSconfig.h"
25 SoftwareSerial mySerial(8, 7);
26 Adafruit_GPS GPS(&mySerial);
28 // Set GPSECHO to 'false' to turn off echoing the GPS data to the Serial console
29 // Set to 'true' if you want to debug and listen to the raw GPS sentences
31 /* set to true to only log to SD when GPS has a fix, for debugging, keep it false */
32 #define LOG_FIXONLY false
40 // read a Hex value and return the decimal equivalent
41 uint8_t parseHex(char c) {
52 // blink out an error code
53 void error(uint8_t errno) {
56 putstring("SD error: ");
57 Serial.print(card.errorCode(), HEX);
59 Serial.println(card.errorData(), HEX);
64 for (i=0; i<errno; i++) {
65 digitalWrite(ledPin, HIGH);
67 digitalWrite(ledPin, LOW);
70 for (i=errno; i<10; i++) {
77 // for Leonardos, if you want to debug SD issues, uncomment this line
78 // to see serial output
81 // connect at 115200 so we can read the GPS fast enough and echo without dropping chars
84 Serial.println("\r\nUltimate GPSlogger Shield");
85 pinMode(ledPin, OUTPUT);
87 // make sure that the default chip select pin is set to
88 // output, even if you don't use it:
91 // see if the card is present and can be initialized:
92 //if (!SD.begin(chipSelect, 11, 12, 13)) {
93 if (!SD.begin(chipSelect)) { // if you're using an UNO, you can use this line instead
94 Serial.println("Card init. failed!");
98 strcpy(filename, "GPSLOG00.TXT");
99 for (uint8_t i = 0; i < 100; i++) {
100 filename[6] = '0' + i/10;
101 filename[7] = '0' + i%10;
102 // create if does not exist, do not open existing, write, sync after write
103 if (! SD.exists(filename)) {
108 logfile = SD.open(filename, FILE_WRITE);
110 Serial.print("Couldnt create "); Serial.println(filename);
113 Serial.print("Writing to "); Serial.println(filename);
115 // connect to the GPS at the desired rate
118 // uncomment this line to turn on RMC (recommended minimum) and GGA (fix data) including altitude
119 GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
120 // uncomment this line to turn on only the "minimum recommended" data
121 //GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCONLY);
122 // For logging data, we don't suggest using anything but either RMC only or RMC+GGA
123 // to keep the log files at a reasonable size
124 // Set the update rate
125 GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ); // 1 or 5 Hz update rate
127 // Turn off updates on antenna status, if the firmware permits it
128 GPS.sendCommand(PGCMD_NOANTENNA);
130 Serial.println("Ready!");
136 if (c) Serial.print(c);
138 // if a sentence is received, we can check the checksum, parse it...
139 if (GPS.newNMEAreceived()) {
140 // a tricky thing here is if we print the NMEA sentence, or data
141 // we end up not listening and catching other sentences!
142 // so be very wary if using OUTPUT_ALLDATA and trying to print out data
143 //Serial.println(GPS.lastNMEA()); // this also sets the newNMEAreceived() flag to false
145 if (!GPS.parse(GPS.lastNMEA())) // this also sets the newNMEAreceived() flag to false
146 return; // we can fail to parse a sentence in which case we should just wait for another
149 Serial.println("OK");
150 if (LOG_FIXONLY && !GPS.fix) {
151 Serial.print("No Fix");
156 Serial.println("Log");
157 Serial.print("Location: ");
158 Serial.print(GPS.latitude, 4); Serial.print(GPS.lat);
160 Serial.print(GPS.longitude, 4); Serial.println(GPS.lon);
162 Serial.print("Speed (knots): "); Serial.println(GPS.speed);
163 Serial.print("Angle: "); Serial.println(GPS.angle);
164 Serial.print("Altitude: "); Serial.println(GPS.altitude);
165 Serial.print("Satellites: "); Serial.println((int)GPS.satellites);
166 char *stringptr = GPS.lastNMEA();
167 uint8_t stringsize = strlen(stringptr);
168 if (stringsize != logfile.write((uint8_t *)stringptr, stringsize)) //write the string to the SD file
170 if (strstr(stringptr, "RMC")) logfile.flush();