GPS Logger using SD Card

Dependencies:   SDFileSystem mbed

Tested with a Haicom HI-203E serial GPS mouse and an adafruit MicroSD card breakout board+. The GPS is powered from the "VU" pin and the serial lines are connected via a MAX232 level shifter.

Revision:
0:6a32515035ec
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sun Feb 03 16:38:23 2013 +0000
@@ -0,0 +1,132 @@
+/* mbed GPS Logger using SD Card
+ * 
+ * Copyright (c) 2013 m.prinke, MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software 
+ * and associated documentation files (the "Software"), to deal in the Software without restriction, 
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute, 
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or 
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * @file          main.cpp 
+ * @purpose       GPS Logger using SD Card
+ * @version       0.1
+ * @date          Feb 2013
+ * @author        M. Prinke 
+ */
+/**   
+ * Writes any serial data received from a GPS receiver to an logfile on an SD Card.
+ * Logging is started/stopped using a toggle button.
+ * Everytime logging is started, a new file with the filename pattern /sd/gpslog<nnnn>.txt
+ * is created, where <nnnn> is decimal number in the range 0000 to 9999 which is incremented.
+ * Searching for a new unique filename is started from zero. 
+ */
+
+#include "mbed.h"
+#include "SDFileSystem.h"
+
+#define GPS_BAUDRATE 4800
+#define DEBUG
+ 
+SDFileSystem sd(p5, p6, p7, p8, "sd"); // mosi, miso, sclk, cs
+
+Serial pc(USBTX, USBRX);    // tx, rx
+Serial gps(p28, p27);       // tx, rx
+DigitalIn button(p21);      // button connects pin to GND
+DigitalOut led_log(LED1);   // logging active
+
+
+/**
+ * Function to create a unique filename
+ *
+ * @param fn pointer to a filename buffer
+ * @return 0 on success, -1 if no unused filename could be created.
+ */
+int get_filename(char *fn)
+{
+    FILE *fp;
+    
+    for (int n=0; n < 9999; n++) {
+        sprintf(fn, "/sd/gpslog%04d.txt", n);
+        if ((fp = fopen(fn, "r")) == NULL) {
+            // file does not exist yet
+            return 0;
+        } else {
+            fclose(fp);
+        }
+    }
+    
+    // filename pattern exhausted
+    return -1;
+}
+
+
+int main() {
+    char ch;
+    char filename[30];
+    
+    button.mode(PullUp);
+    gps.baud(GPS_BAUDRATE);
+    
+    while (1) {
+        led_log = 0;
+        
+        #if defined(DEBUG)
+        pc.printf("\n--------------------------------------------\n");
+        pc.printf("GPS logging stopped, press button to start.\n");
+        pc.printf("--------------------------------------------\n");
+        #endif
+        
+        while (button);     // wait until button pressed
+        wait_ms(50);        // button debounce
+        while (!button);    // wait until button released
+        if (get_filename(filename) != 0) {
+            error("Could not create file with unique name\n");
+        }
+        
+        #if defined(DEBUG)
+        pc.printf("\n--------------------------------------------\n");
+        pc.printf("GPS logging started, press button to stop.\n");
+        pc.printf("Current logfile: %s\n", filename);
+        pc.printf("--------------------------------------------\n");
+        #endif
+        
+        led_log = 1;
+        
+        // open file for writing
+        FILE *fp = fopen(filename, "w");
+        if(fp == NULL) {
+            error("Could not open file for write\n");
+        }
+        
+        /*
+         * Write GPS data to file until button is pressed or
+         * a write error occurs.
+         */
+        int rv = 0;
+        do {
+            if(gps.readable()) {
+                ch = gps.getc();
+                #if defined(DEBUG)
+                pc.putc(ch);
+                #endif
+                rv = fputc(ch, fp);
+            }
+        } while ((rv != EOF) && button);
+        
+        // close file
+        fclose(fp);
+        
+        wait_ms(50);        // button debounce
+        while (!button);    // wait until button released
+    }
+}