Instructables

Geo Data Logger: Arduino+GPS+SD+Accelerometer to log, time-stamp, and geo-tag sensor data

Featured

Step 5: THE ARDUINO PROGRAM THAT PULLS IT ALL TOGETHER

Picture of THE ARDUINO PROGRAM THAT PULLS IT ALL TOGETHER
This program reads the LS20031 GPS receiver and saves the NMEA sentences generated by the receiver as-is to the SD card.  The program also reads the X, Y, Z pins of the ADXL335 accelerometer and saves them with each NMEA line saved.

The Arduino program I developed for this prototype uses the SD library. I am not using TinyGPS to interact with the GPS receiver or SoftwareSerial.  I did not need TinyGPS for this project since I am saving raw NMEA messages to the SD card. As for the SoftwareSerial library, after I ran into a few issues which were time consuming to resolve I decided to stick to the default Arduino serial library. 

The downside of not using SoftwareSerial in this project is that the GPS Receiver will be using the Arduino's RX/TX pins to read configuration commands and to send GPS data to the Arduino.  This means we don't have the Arduino Serial Monitor available for debugging.

More importantly, we will have to disconnect the Arduino Uno's PIN0 (RX) from the GPS receiver's TX pin before uploading an Arduino program. If we don't disconnect Arduino's PIN0 (RX) from the GPS receiver, it will most likely fail to upload the Arduino program from the PC to the Arduino because of serial conflict. I found this to be a small price for the gains in coding compactness and shortened development cycle.


The data saved by this program to the SD will look like the list below. Theoretically, five lines of GPS and sensor data will be generated per second. This log can be imported as a comma-delimited file into a host of applications such as spreadsheets or databases for scrubbing, analysis, and charting:

  • 446,425,542,GPRMC,093116.200,A,3158.0155,N,03551.5032,E,18.78,291.56,111112,,,A*54
  • 443,442,542,GPRMC,093116.400,A,3158.0159,N,03551.5020,E,18.78,291.79,111112,,,A*50
  • 444,435,523,GPRMC,093116.600,A,3158.0163,N,03551.5009,E,18.77,292.32,111112,,,A*53
  • 444,432,525,PRMC,093116.800,A,3158.0167,N,03551.4998,E,18.75,292.88,111112,,,A*5A

// ====================== START PROGRAM ==========================
/*

PROJECT: Bump-O-Meter (Geo Data Logger for Sensors )

DEVELOPER:  Hazim Bitar (techbitar at gmail dot com)

DESCRIPTION:  This program reads the ADXL335 accelerometer sensor data (X,Y,Z)  or any
sensor data then saves   this data to an SD card along with geo-location and a date/time stamp
generated by the LS20031 GPS receiver

LICENSE:      I am placing this code in the public domain

DATE:         NOV 16, 2012

*/

#include
#define LED 8           // status LED for SD operations
#define BUFF_MAX 100   // size of GPS & SD buffers

File GPSlog;

void setup()
{
  Serial.begin(4800); // The LS20031 GPS receiver must be set to 4800 for program to work

  // You can use the statements below to send configuration commands to the LS20031 GPS.
  // But for this to work, the baud rate must be set on the LS20031 GPS receiver to 4800.
  // You can use the MiniGPS 1.4 utility to configure or query the LS20031 GPS receiver.
  //
  // LS20031 COMMANDS:
  // Serial.print("$PMTK251,4800*27\r\n");  // Set GPS baud rate
  // Serial.print("$PMTK314,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*2C\r\n"); // Set RMC to 5 fixes/second. 
  // Serial.print("$PMTK220,200*2C\r\n");  // GPS update rate at 5Hz
 
  pinMode(10, OUTPUT);   // Per SD library notes, pin 10 must be set to output
  pinMode(LED, OUTPUT);

  if (!SD.begin(4)) {        // SD card detected?
    digitalWrite(LED,LOW);   // turn off status LED if SD detection fails
    return;
  }
  else   digitalWrite(LED, HIGH); // turn on LED if SD detection is OK

  GPSlog = SD.open("GPS.log", O_CREAT | O_WRITE);  // open/append to a file GPS.log
  if (!GPSlog) {               // test if file can be opened
    digitalWrite(LED,LOW);     // turn off status LED if file open fails
    return;
  }
  else digitalWrite(LED, HIGH);  // turn on status LED if file open is OK
}

void loop()
{
  char inBuffer[BUFF_MAX];    // buffer used to read NMEA lines from GPS
  byte outBuffer[BUFF_MAX];   // buffer used to write NMEA lines to SD card
  int sizeBuffer = 0;        // counter of how many chars per line

// HERE WE DECLARE MORE OR LESS ANALOG SENSOR VARIABLES
  char an0[4], an1[4], an2[4];  // char variables to store analog pin values. Total 6 pins from 0-5

  while (Serial.available()>0)  // if serial data available from GPS
  {         
    sizeBuffer = Serial.readBytesUntil('\n', inBuffer, BUFF_MAX);  // read one NMEA line from GPS until end of line

//  THIS IS WHERE WE READ SENSOR VALUES
    itoa (analogRead(A0),  an0, 10);    // X read and convert numeric analog pin to char
    itoa (analogRead(A1),  an1, 10);    // Y  ..
    itoa (analogRead(A2),  an2, 10);    // Z  ..
    for (int i = 0; i < BUFF_MAX; i++) outBuffer[i] = inBuffer[i];   // create CSV file on SD 
    int j = 0;

    // THIS IS WHERE WE WRITE SENSOR DATA TO THE SD FILE
    if (GPSlog) {
      GPSlog.print(an0);    // write ANALOG0 (X) to SD
      GPSlog.print(" , ");      
      GPSlog.print(an1);    // write ANALOG1 (Y) to SD     
      GPSlog.print(" , ");      
      GPSlog.print(an2);    // write ANALOG2 (Z) to SD
      GPSlog.print(" , ");     
      // If you only want NMEA output logged, comment out all above GPSlog.print statements
      GPSlog.write(outBuffer, sizeBuffer);  // write GPS NMEA output to SD
      GPSlog.print("\r\n");     
      GPSlog.flush();
      digitalWrite(LED, HIGH);  // Keep LED on so long as SD logging is working.
    }
    else {
      // if the file didn't open, turn LED off
      digitalWrite(LED, LOW);  // turn LED off if writing to file fails
    }
  }
}
// ================ END PROGRAM =====================



HOW TO ADD/REMOVE SENSORS TO THE GEO DATA LOGGER

This program will read up to 6 analog sensors and save their values to the SD card. There are two places in the program where you need to make changes to suit your needs:

1. DECLARING SENSOR VARIABLES

In the declaration section, we create text variables that will hold the converted numeric values of the sensors before we write them to the SD card.  Here, we are declaring for a maximum of 6 analog sensors. Reduce as needed. 

char an0[4], an1[4], an2[4]; an3[4]; an4[4]; an5[4];

2. READING SENSORS

In this part of the program, we convert the numeric sensor readings to text before we write them to the SD card. Change the next code segment in the program to add/remove sensors as needed. You can have up to 6 analog sensors read in this program:

    itoa (analogRead(A0),  an0, 10);   
    itoa (analogRead(A1),  an1, 10);  
    itoa (analogRead(A2),  an2, 10); 
    itoa (analogRead(A3),  an0, 10);  
    itoa (analogRead(A4),  an1, 10); 
    itoa (analogRead(A5),  an2, 10);

3. WRITING SENSORS VALUES TO THE SD CARD

After we read the sensor(s) above, we write their text values to the SD card. In the code segment below, we are adding a comma between each sensor value written to the SD card so we can separate them. This makes it easier to import them into a spreadsheet program as comma-delimited  text:

      GPSlog.print(an0);    // write ANALOG0 to SD card
      GPSlog.print(" , ");    
      GPSlog.print(an1);    // write ANALOG1 to SD card
      GPSlog.print(" , ");    
      GPSlog.print(an2);    // write ANALOG2 to SD card
      GPSlog.print(" , ");
      GPSlog.print(an0);    // write ANALOG3 to SD card
      GPSlog.print(" , ");   
      GPSlog.print(an1);    // write ANALOG4 to SD card
      GPSlog.print(" , ");   
      GPSlog.print(an2);    // write ANALOG5 to SD card
      GPSlog.print(" , ");
 
Remove these adsRemove these ads by Signing Up