GPS Data Logger with SD File system. Logger can save RMC & GGA data from GPS and five channels of analog data. Based on http://mbed.org/users/prf/ "GPS_Logger_01" by Peter Forden

Dependencies:   mbed

main.cpp

Committer:
kenjiArai
Date:
2010-04-17
Revision:
0:dc3be3264d2d

File content as of revision 0:dc3be3264d2d:

//-------------------------------------------------------------------------------------------------
// GPS DATA LOGGER Ver.1
//      (c)2010  Kenji Arai / JH1PJL 
//      http://www.page.sannet.ne.jp/kenjia/index.html
//      http://mbed.org/users/kenjiArai/   
//          April 17th,2010  Started
//          April 17th,2010
//-------------------------------------------------------------------------------------------------
// Reference ----- GPS_logger_01 by Peter Foden ------
//  http://mbed.org/users/prf/
//  http://mbed.org/users/prf/programs/GPS_Logger_01/f5c2b003ae38423640de0fc5e0727190/
//-------------------------------------------------------------------------------------------------
// Function
//      GPS data and five channeles ADC data records into a file which is located in SD-Card
// Connection
//      GPS receiver    PIN 8,9
//      Analog input    PIN 15,16,17,19,20
//      SD Card I/F     PIN 11,12,13,14
//      LCD             PIN 5,6,7,21,22,23
//       -> CAUTION!! pin assignment is different
//          with " http://mbed.org/projects/cookbook/wiki/TextLCD "
//      RTC             PIN 3 needs to connect 3V Battery
//       -> Please refer my program " RTC_w_COM" for time adjustment
//          at " http://mbed.org/users/kenjiArai/programs/RTC_w_COM/5yi9a/ "
//-------------------------------------------------------------------------------------------------
#include "mbed.h"
#include "TextLCD.h"
#include "SDFileSystem.h"

// Data logging configration
//      Save RMC any condition
#define CONFG_ANA   1   // 1= Save Analog data  
#define DEBUG       1   // 1= Shows progress on PC via USB ( virtual COM line)
#define USE_LCD     1   // 1= Display the data on LCD

// Commands for GPS to turn on or off data strings
#define RMC_ON   "$PSRF103,4,0,1,1*21\r\n"
#define RMC_OFF  "$PSRF103,4,0,0,1*20\r\n"
#define GGA_ON   "$PSRF103,0,0,1,1*25\r\n"
#define GGA_OFF  "$PSRF103,0,0,0,1*24\r\n"
#define GSA_ON   "$PSRF103,2,0,1,1*27\r\n"
#define GSA_OFF  "$PSRF103,2,0,0,1*26\r\n"
#define GSV_ON   "$PSRF103,3,0,1,1*26\r\n"
#define GSV_OFF  "$PSRF103,3,0,0,1*27\r\n"
#define WAAS_ON  "$PSRF151,1*3F\r\n"
#define WAAS_OFF "$PSRF151,0*3E\r\n"

// kind of GPS data
#define NONE    0
#define RMC     1
#define GGA     2
#define GSA     3
#define GSV     4

// SD Recording status
#define IDLE    0
#define RECD    1
#define SD_FAIL 0xff

// Buffer size
#define BSIZ    256

//-------------------------------------------------------------------------------------------------
// Set up hardware
//      MBED USB port used for console debug messages
//      SZP950T GPS unit connects to UART
//      LED & Switch
//      40chr x 2 line Text LCD
//      SD card interface
//      Analog input
//          G-sensor data, Baterry volt, Temperature sensor data
#if DEBUG
Serial pc(USBTX, USBRX);   // tx, rx - Default 9600 baud
#endif
Serial gps(p9, p10);       // tx, rx - 4800 baud required
DigitalOut RCV_GPS(LED1);  // Receive GPS data
DigitalOut GPS_LOCK(LED2); // GPS got valid data
DigitalOut ON_REC(LED4);   // Data sent LED
DigitalIn  SW_REC(p26);    // Data recode switch
#if USE_LCD
TextLCD lcd(p22, p23, p21, p8, p7, p6, p5, 40, 2); // rs,rw,e,d0,d1,d2,d3,40char's x 2 lines
#endif
SDFileSystem sd(p11, p12, p13, p14, "sd");  // do,di,clk,cs
#if CONFG_ANA
AnalogIn ain_G_X(p15);      // G Sensor
AnalogIn ain_G_Y(p16);      // G Sensor
AnalogIn ain_G_Z(p17);      // G Sensor
AnalogIn ain_BAT(p19);      // Battery Volt
AnalogIn ain_TEMP(p20);     // Temperature Sensor
#endif

//-------------------------------------------------------------------------------------------------
// Data rea
char msg[BSIZ];             //GPS data buffer
char MsgBuf_RMC[BSIZ];      // GPS/GGA data
char MsgBuf_GGA[BSIZ];      // GPS/RMC data
#if CONFG_ANA
char MsgBuf_ANA[128];       // Analog data buffer
float x,y,z,b,t;            // Analog data
#endif
char gps_dat;               // Kind of GPS data
char recode_status;
FILE *fp;                   // File pointer
char buf[40];               // data buffer for text
time_t seconds;             // RTC data based on seconds

//-------------------------------------------------------------------------------------------------
// --------------- CONTROL PROGRAM --------------------
   
// Select GPS data
void setgps() {
    gps.printf(RMC_ON);     // use RMC
    gps.printf(GGA_ON);     // use GGA
    gps.printf(GSA_OFF);
    gps.printf(GSV_OFF);
    gps.printf(WAAS_OFF);
    return;
}

// Get line of data from GPS
void getline() {
    while (gps.getc() != '$');  // Wait for start of line
    msg[0] = '$';
#if DEBUG
    pc.putc('$');
#endif
    for (int i=1; i<512; i++) {
        msg[i] = gps.getc();
    #if DEBUG
        pc.putc(msg[i]);
    #endif
        if (msg[i] == '\r' || msg[i] == '\n') {
            msg[i] = '\r';
            msg[i+1] = '\n';
            msg[i+2] = 0;
        #if DEBUG
            pc.printf("\r\n");
        #endif
            return;
        }
    }
}

int main(void) {
    gps.baud(4800);         // baud rate 4800
#if DEBUG
    pc.printf("\r\n\r\nGPS logger on mbed by K.Arai/JH1PJL (c)2010\r\n");
#endif
#if USE_LCD
    lcd.cls();
    lcd.locate(0, 0);
    //          1234567890123456789012345678901234567890 
    lcd.printf("GPS Logger Running! ....               ");
#endif
    setgps();
    while (1) {
        RCV_GPS = 1;
        getline();          // Get GPS data from UART
        if (strncmp(msg, "$GPRMC",6) == 0) {
            for (int i=0; i<BSIZ ; MsgBuf_RMC[i++]=0);  // Clear buffer
            for (int i=0; msg[i] != 0; i++) {           // Copy msg to RMC buffer
                MsgBuf_RMC[i] = msg[i];
            }
            gps_dat = RMC;
            // Get analog data from each port
        #if CONFG_ANA
            x=ain_G_X.read();
            y=ain_G_Y.read();
            z=ain_G_Z.read();
            b=ain_BAT.read();
            t=ain_TEMP.read();
            sprintf(MsgBuf_ANA, "$ANA,%f,%f,%f,%f,%f,,*00\r\n", x, y, z, b, t);
          #if DEBUG
            pc.printf(MsgBuf_ANA);
          #endif
        #endif
        } else if (strncmp(msg, "$GPGGA",6) == 0) {
            for (int i=0; i<BSIZ ; MsgBuf_GGA[i++]=0);  // Clear buffer
            for (int i=0; msg[i] != 0; i++) {           // Copy msg to GGA buffer
                MsgBuf_GGA[i] = msg[i];
            }
            gps_dat = GGA;
        } else {
            gps_dat = NONE;
        }
        RCV_GPS = 0;
        if (SW_REC){
            if (recode_status == RECD){
                // Recording -> on going
                ON_REC = 1;             // LED ON for recording indication
                switch(gps_dat){
                    case RMC: {
                        fprintf(fp,MsgBuf_RMC); // save data
                #if CONFG_ANA
                        fprintf(fp,MsgBuf_ANA); // save data
                #endif  
                        break;
                    }
                    case GGA: {
                        fprintf(fp,MsgBuf_GGA); // save data
                        break;
                    }
                    default: {;}           
                }
            } else if (recode_status == IDLE){
                // Start recoding -> File open
                seconds = time(NULL);
                seconds %= 100000000;               // Adjust 8 charcters file name
                sprintf(buf,"/sd/%d.txt",seconds);  // File name based on time from 1970/1/1   
                fp = fopen(buf, "w");               // File open 
            #if DEBUG
                pc.printf("\r\n %s \r\n", buf);     // File name on the screen
            #endif
                if(fp == NULL) {
                    // Try again
                    fp = fopen(buf, "w");
                    if(fp == NULL) {
                        // File not open then give up
                    #if USE_LCD
                        lcd.locate(0, 0);
                        //          1234567890123456789012345678901234567890 
                        lcd.printf("  Could not open file for write         ");
                    #endif
                    #if DEBUG
                        pc.printf( "\r\n Could not open file for write\r\n");
                    #endif
                        recode_status = SD_FAIL;
                    }
                }
                if (fp){
                    // File open successful
                    fprintf(fp, "GPS logger on mbed by K.Arai/JH1PJL (c)2010\r\n");
                #if USE_LCD
                    lcd.locate(0, 0);
                    //          1234567890123456789012345678901234567890  
                    lcd.printf(" Start recording                        ");
                #endif
                #if DEBUG
                    pc.printf(  "GPS logger on mbed by K.Arai/JH1PJL (c)2010");
                    pc.printf("\r\nStart recording\r\n");
                #endif
                    recode_status = RECD;
                }    
            }
        } else {
            if (recode_status == RECD){
                // File close
                fclose(fp);
                recode_status = IDLE;       // back to idle state
            #if USE_LCD
                lcd.locate(0, 0);
                //          1234567890123456789012345678901234567890 
                lcd.printf("Finish data save                        ");
            #endif
            #if DEBUG
                pc.printf( "\r\n Finish data save\r\n");
            #endif
            } else if (recode_status == SD_FAIL){
                // When file access failed
                recode_status = IDLE;       // back to idle state
            #if USE_LCD
                lcd.locate(0, 0);
                //          1234567890123456789012345678901234567890  
                lcd.printf("Could not save the data                 ");
            #endif
            #if DEBUG
                pc.printf( "\r\n Could not save the data\r\n");
            #endif               
            }
            ON_REC = 0;         // LED off for IDLE
        }
    }
}