Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

initial commit. making it easier to use (only 328)

  • Loading branch information...
commit 26b94bfb7ad12d44fd6c864a2b37b6cd1cf04ea3 0 parents
@ladyada ladyada authored
Showing with 340 additions and 0 deletions.
  1. +340 −0 SD_GPSLogger.pde
340 SD_GPSLogger.pde
@@ -0,0 +1,340 @@
+// Ladyada's logger modified by Bill Greiman to use the SdFat library
+
+// this is a generic logger that does checksum testing so the data written should be always good
+// Assumes a sirf III chipset logger attached to pin 0 and 1
+
+#include <SdFat.h>
+#include <SdFatUtil.h>
+#include <avr/sleep.h>
+
+// macros to use PSTR
+#define putstring(str) SerialPrint_P(PSTR(str))
+#define putstring_nl(str) SerialPrintln_P(PSTR(str))
+
+// power saving modes
+#define SLEEPDELAY 0
+#define TURNOFFGPS 0
+#define LOG_RMC_FIXONLY 1
+
+Sd2Card card;
+SdVolume volume;
+SdFile root;
+SdFile f;
+
+#define led1Pin 4
+#define led2Pin 3
+#define powerPin 2
+
+#define BUFFSIZE 75
+char buffer[BUFFSIZE];
+uint8_t bufferidx = 0;
+uint8_t fix = 0; // current fix data
+uint8_t i;
+
+/* EXAMPLE
+
+$PSRF103,<msg>,<mode>,<rate>,<cksumEnable>*CKSUM<CR><LF>
+
+<msg> 00=GGA,01=GLL,02=GSA,03=GSV,04=RMC,05=VTG
+<mode> 00=SetRate,01=Query
+<rate> Output every <rate>seconds, off=00,max=255
+<cksumEnable> 00=disable Checksum,01=Enable checksum for specified message
+Note: checksum is required
+
+Example 1: Query the GGA message with checksum enabled
+$PSRF103,00,01,00,01*25
+
+Example 2: Enable VTG message for a 1Hz constant output with checksum enabled
+$PSRF103,05,00,01,01*20
+
+Example 3: Disable VTG message
+$PSRF103,05,00,00,01*21
+
+*/
+
+#define SERIAL_SET "$PSRF100,01,4800,08,01,00*0E\r\n"
+
+// GGA-Global Positioning System Fixed Data, message 103,00
+#define LOG_GGA 0
+#define GGA_ON "$PSRF103,00,00,01,01*25\r\n"
+#define GGA_OFF "$PSRF103,00,00,00,01*24\r\n"
+
+// GLL-Geographic Position-Latitude/Longitude, message 103,01
+#define LOG_GLL 0
+#define GLL_ON "$PSRF103,01,00,01,01*26\r\n"
+#define GLL_OFF "$PSRF103,01,00,00,01*27\r\n"
+
+// GSA-GNSS DOP and Active Satellites, message 103,02
+#define LOG_GSA 0
+#define GSA_ON "$PSRF103,02,00,01,01*27\r\n"
+#define GSA_OFF "$PSRF103,02,00,00,01*26\r\n"
+
+// GSV-GNSS Satellites in View, message 103,03
+#define LOG_GSV 0
+#define GSV_ON "$PSRF103,03,00,01,01*26\r\n"
+#define GSV_OFF "$PSRF103,03,00,00,01*27\r\n"
+
+// RMC-Recommended Minimum Specific GNSS Data, message 103,04
+#define LOG_RMC 1
+#define RMC_ON "$PSRF103,04,00,01,01*21\r\n"
+#define RMC_OFF "$PSRF103,04,00,00,01*20\r\n"
+
+// VTG-Course Over Ground and Ground Speed, message 103,05
+#define LOG_VTG 0
+#define VTG_ON "$PSRF103,05,00,01,01*20\r\n"
+#define VTG_OFF "$PSRF103,05,00,00,01*21\r\n"
+
+// Switch Development Data Messages On/Off, message 105
+#define LOG_DDM 1
+#define DDM_ON "$PSRF105,01*3E\r\n"
+#define DDM_OFF "$PSRF105,00*3F\r\n"
+
+#define USE_WAAS 0 // useful in US, but slower fix
+#define WAAS_ON "$PSRF151,01*3F\r\n" // the command for turning on WAAS
+#define WAAS_OFF "$PSRF151,00*3E\r\n" // the command for turning off WAAS
+
+// read a Hex value and return the decimal equivalent
+uint8_t parseHex(char c) {
+ if (c < '0')
+ return 0;
+ if (c <= '9')
+ return c - '0';
+ if (c < 'A')
+ return 0;
+ if (c <= 'F')
+ return (c - 'A')+10;
+}
+
+// blink out an error code
+void error(uint8_t errno) {
+ if (card.errorCode()) {
+ putstring("SD error: ");
+ Serial.print(card.errorCode(), HEX);
+ Serial.print(',');
+ Serial.println(card.errorData(), HEX);
+ }
+ while(1) {
+ for (i=0; i<errno; i++) {
+ digitalWrite(led1Pin, HIGH);
+ digitalWrite(led2Pin, HIGH);
+ delay(100);
+ digitalWrite(led1Pin, LOW);
+ digitalWrite(led2Pin, LOW);
+ delay(100);
+ }
+ for (; i<10; i++) {
+ delay(200);
+ }
+ }
+}
+
+void setup() {
+ WDTCSR |= (1 << WDCE) | (1 << WDE);
+ WDTCSR = 0;
+ Serial.begin(4800);
+ putstring_nl("\r\nGPSlogger");
+ pinMode(led1Pin, OUTPUT);
+ pinMode(led2Pin, OUTPUT);
+ pinMode(powerPin, OUTPUT);
+ digitalWrite(powerPin, LOW);
+
+ // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with
+ // breadboards. use SPI_FULL_SPEED for better performance.
+ if (!card.init(SPI_HALF_SPEED)) {
+ putstring_nl("Card init. failed!");
+ error(1);
+ }
+ if (!volume.init(&card)) {
+ putstring_nl("No partition!");
+ error(2);
+ }
+ if(!root.openRoot(&volume)) {
+ putstring_nl("Can't! open root dir");
+ error(3);
+ }
+ strcpy(buffer, "GPSLOG00.TXT");
+ for (i = 0; i < 100; i++) {
+ buffer[6] = '0' + i/10;
+ buffer[7] = '0' + i%10;
+ // create if does not exist, do not open existing, write, sync after write
+ if (f.open(&root, buffer, O_CREAT | O_EXCL | O_WRITE | O_SYNC)) break;
+ }
+
+ if(!f.isOpen()) {
+ putstring("couldnt create "); Serial.println(buffer);
+ error(3);
+ }
+ putstring("writing to "); Serial.println(buffer);
+ putstring_nl("ready!");
+
+ putstring(SERIAL_SET);
+ delay(250);
+
+ if (LOG_DDM)
+ putstring(DDM_ON);
+ else
+ putstring(DDM_OFF);
+ delay(250);
+
+ if (LOG_GGA)
+ putstring(GGA_ON);
+ else
+ putstring(GGA_OFF);
+ delay(250);
+
+ if (LOG_GLL)
+ putstring(GLL_ON);
+ else
+ putstring(GLL_OFF);
+ delay(250);
+
+ if (LOG_GSA)
+ putstring(GSA_ON);
+ else
+ putstring(GSA_OFF);
+ delay(250);
+
+ if (LOG_GSV)
+ putstring(GSV_ON);
+ else
+ putstring(GSV_OFF);
+ delay(250);
+
+ if (LOG_RMC)
+ putstring(RMC_ON);
+ else
+ putstring(RMC_OFF);
+ delay(250);
+
+ if (LOG_VTG)
+ putstring(VTG_ON);
+ else
+ putstring(VTG_OFF);
+ delay(250);
+
+ if (USE_WAAS)
+ putstring(WAAS_ON);
+ else
+ putstring(WAAS_OFF);
+}
+
+void loop() {
+ //Serial.println(Serial.available(), DEC);
+ char c;
+ uint8_t sum;
+
+ // read one 'line'
+ if (Serial.available()) {
+ c = Serial.read();
+ //Serial.print(c, BYTE);
+ if (bufferidx == 0) {
+ while (c != '$')
+ c = Serial.read(); // wait till we get a $
+ }
+ buffer[bufferidx] = c;
+
+ //Serial.print(c, BYTE);
+ if (c == '\n') {
+ //putstring_nl("EOL");
+ //Serial.print(buffer);
+ buffer[bufferidx+1] = 0; // terminate it
+
+ if (buffer[bufferidx-4] != '*') {
+ // no checksum?
+ Serial.print('*', BYTE);
+ bufferidx = 0;
+ return;
+ }
+ // get checksum
+ sum = parseHex(buffer[bufferidx-3]) * 16;
+ sum += parseHex(buffer[bufferidx-2]);
+
+ // check checksum
+ for (i=1; i < (bufferidx-4); i++) {
+ sum ^= buffer[i];
+ }
+ if (sum != 0) {
+ //putstring_nl("Cxsum mismatch");
+ Serial.print('~', BYTE);
+ bufferidx = 0;
+ return;
+ }
+ // got good data!
+
+ if (strstr(buffer, "GPRMC")) {
+ // find out if we got a fix
+ char *p = buffer;
+ p = strchr(p, ',')+1;
+ p = strchr(p, ',')+1; // skip to 3rd item
+
+ if (p[0] == 'V') {
+ digitalWrite(led1Pin, LOW);
+ fix = 0;
+ } else {
+ digitalWrite(led1Pin, HIGH);
+ fix = 1;
+ }
+ }
+ if (LOG_RMC_FIXONLY) {
+ if (!fix) {
+ Serial.print('_', BYTE);
+ bufferidx = 0;
+ return;
+ }
+ }
+ // rad. lets log it!
+ Serial.print(buffer);
+ Serial.print('#', BYTE);
+ digitalWrite(led2Pin, HIGH); // sets the digital pin as output
+
+ // Bill Greiman - need to write bufferidx + 1 bytes to getCR/LF
+ bufferidx++;
+
+ if(f.write((uint8_t *) buffer, bufferidx) != bufferidx) {
+ putstring_nl("can't write!");
+ error(4);
+ }
+
+ digitalWrite(led2Pin, LOW);
+
+ bufferidx = 0;
+
+ // turn off GPS module?
+ if (TURNOFFGPS) {
+ digitalWrite(powerPin, HIGH);
+ }
+
+ sleep_sec(SLEEPDELAY);
+ digitalWrite(powerPin, LOW);
+ return;
+ }
+ bufferidx++;
+ if (bufferidx == BUFFSIZE-1) {
+ Serial.print('!', BYTE);
+ bufferidx = 0;
+ }
+ } else {
+
+ }
+
+}
+
+void sleep_sec(uint8_t x) {
+ while (x--) {
+ // set the WDT to wake us up!
+ WDTCSR |= (1 << WDCE) | (1 << WDE); // enable watchdog & enable changing it
+ WDTCSR = (1<< WDE) | (1 <<WDP2) | (1 << WDP1);
+ WDTCSR |= (1<< WDIE);
+ set_sleep_mode(SLEEP_MODE_PWR_DOWN);
+ sleep_enable();
+ sleep_mode();
+ sleep_disable();
+ }
+}
+
+SIGNAL(WDT_vect) {
+ WDTCSR |= (1 << WDCE) | (1 << WDE);
+ WDTCSR = 0;
+}
+
+/* End code */

0 comments on commit 26b94bf

Please sign in to comment.
Something went wrong with that request. Please try again.