]> git.piffa.net Git - arduino/blob - books/pdummies/APFD_Chapter13_GPS_Datalogger/APFD_Chapter13_GPS_Datalogger.ino
first commit
[arduino] / books / pdummies / APFD_Chapter13_GPS_Datalogger / APFD_Chapter13_GPS_Datalogger.ino
1 /* Arduino Projects for Dummies
2  * by Brock Craft 
3  *
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
7  *
8  * Requires:
9  * Adafruit_GPS library
10  * SD library
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
14  *
15  * v0.1 30.04.2013
16 */
17
18
19 #include <Adafruit_GPS.h>
20 #include <SoftwareSerial.h>
21 #include <SD.h>
22 #include <avr/sleep.h>
23 #include "GPSconfig.h"
24
25 SoftwareSerial mySerial(8, 7);
26 Adafruit_GPS GPS(&mySerial);
27
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
30 #define GPSECHO  true
31 /* set to true to only log to SD when GPS has a fix, for debugging, keep it false */
32 #define LOG_FIXONLY false  
33
34 // Set the pins used
35 #define chipSelect 10
36 #define ledPin 13
37
38 File logfile;
39
40 // read a Hex value and return the decimal equivalent
41 uint8_t parseHex(char c) {
42   if (c < '0')
43     return 0;
44   if (c <= '9')
45     return c - '0';
46   if (c < 'A')
47     return 0;
48   if (c <= 'F')
49     return (c - 'A')+10;
50 }
51
52 // blink out an error code
53 void error(uint8_t errno) {
54 /*
55   if (SD.errorCode()) {
56     putstring("SD error: ");
57     Serial.print(card.errorCode(), HEX);
58     Serial.print(',');
59     Serial.println(card.errorData(), HEX);
60   }
61   */
62   while(1) {
63     uint8_t i;
64     for (i=0; i<errno; i++) {
65       digitalWrite(ledPin, HIGH);
66       delay(100);
67       digitalWrite(ledPin, LOW);
68       delay(100);
69     }
70     for (i=errno; i<10; i++) {
71       delay(200);
72     }
73   }
74 }
75
76 void setup() {
77   // for Leonardos, if you want to debug SD issues, uncomment this line
78   // to see serial output
79   //while (!Serial);
80   
81   // connect at 115200 so we can read the GPS fast enough and echo without dropping chars
82   // also spit it out
83   Serial.begin(115200);
84   Serial.println("\r\nUltimate GPSlogger Shield");
85   pinMode(ledPin, OUTPUT);
86
87   // make sure that the default chip select pin is set to
88   // output, even if you don't use it:
89   pinMode(10, OUTPUT);
90   
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!");
95     error(2);
96   }
97   char filename[15];
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)) {
104       break;
105     }
106   }
107
108   logfile = SD.open(filename, FILE_WRITE);
109   if( ! logfile ) {
110     Serial.print("Couldnt create "); Serial.println(filename);
111     error(3);
112   }
113   Serial.print("Writing to "); Serial.println(filename);
114   
115   // connect to the GPS at the desired rate
116   GPS.begin(9600);
117
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
126
127   // Turn off updates on antenna status, if the firmware permits it
128   GPS.sendCommand(PGCMD_NOANTENNA);
129   
130   Serial.println("Ready!");
131 }
132
133 void loop() {
134   char c = GPS.read();
135   if (GPSECHO)
136      if (c)   Serial.print(c);
137
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
144         
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
147     
148     // Sentence parsed! 
149     Serial.println("OK");
150     if (LOG_FIXONLY && !GPS.fix) {
151         Serial.print("No Fix");
152         return;
153     }
154
155     // Rad. lets log it!
156     Serial.println("Log");
157       Serial.print("Location: ");
158       Serial.print(GPS.latitude, 4); Serial.print(GPS.lat);
159       Serial.print(", "); 
160       Serial.print(GPS.longitude, 4); Serial.println(GPS.lon);
161       
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
169       error(4);
170     if (strstr(stringptr, "RMC"))   logfile.flush();
171     Serial.println();
172   }
173 }
174
175
176 /* End code */