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
Diff: main.cpp
- Revision:
- 0:dc3be3264d2d
diff -r 000000000000 -r dc3be3264d2d main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Sat Apr 17 13:27:34 2010 +0000 @@ -0,0 +1,274 @@ +//------------------------------------------------------------------------------------------------- +// 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 + } + } +} +