loading

Step 5: 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(" , ");
<p>Hi im just wondering whether it will able to track the location like within a room because i want to implement this in a lego track for detecting faulty track.</p><p>Can you assist me with this?</p>
<p>Can anyone help please? I am new <br>to this, and been trying to put together the project. So far I have everything <br>assembled as instructed. However, as soon as I try to verify the code, I get <br>this error:</p><p>Arduino: 1.6.5 (Windows 7), Board: &quot;Arduino/Genuino <br>Uno&quot;</p><p>C:\Program Files <br>(x86)\Arduino\libraries\SD\src\utility\Sd2Card.cpp:26:17: fatal error: SPI.h: <br>No such file or directory</p><p>#include <br>&lt;SPI.h&gt;</p><p>^</p><p>compilation terminated.</p><p>Error compiling.</p><p>What do I need to do to fix this?</p>
<p>Newer versions of Arduino IDE can't find the SPI library, so you need to add them by adding the following line at the start of sketch:<br>#include &lt;SPI.h&gt;<br></p>
<p>I'm no expert but had this same problem on another project. All of the files (including the additional libraries) need to be in the right folder. The Arduino IDE seems to be a bit picky about this (on Linux at least).</p>
<p>can i have the code for storing Accelerometer ADXL335 data into SD card with time staps (say every 5 min interbal)</p><p>and how can name the stored file as a YYYYMMDDHHSS format </p>
<p>could not get code to compile</p>
<p>I made an equivalent tool in python that print real time data from ADXL345 accelerometer.</p>
<p>like</p>
<p>I made an equivalent tool in python that print real time data from ADXL345 accelerometer.</p><p><a href="https://github.com/mba7/SerialPort-RealTime-Data-Plotter" rel="nofollow">https://github.com/mba7/SerialPort-RealTime-Data-P...</a></p><p>may be it will be helpful for someone</p>
<p>I made an equivalent tool in python that print real time data from ADXL345 accelerometer.</p><p><a href="https://github.com/mba7/SerialPort-RealTime-Data-Plotter" rel="nofollow">https://github.com/mba7/SerialPort-RealTime-Data-P...</a></p><p>may be it will be helpful for someone</p>
<p>I need create a file GPS.log in SD card before do this work ? Or the file GPS.log will be created by code?</p>
<p>You can read the accelerometer more often than the GPS, so there should be no need to interpolate the accelerometer reading.</p>
<p>great</p>
<p>good</p>
<p>super</p>
<p>super</p>
<p>In this tutorial I find what I need to start interfacing the gps sensor with an Arduino. And because I want to help many more hobbyists to start building robots, I share this tutorial on my post http://www.intorobotics.com/gps-sensors-tutorials-resources/. Thank you!</p>
<p>Hello techbitar - I'm thinking of building an adaption of your project but am considering changing the SD card adapter to the microSD card shield from Sparkfun: https://www.sparkfun.com/products/9802</p>
True but not all sensors (temperature, humid, etc.) possibly used by others will be as fast as the accelerometer I am using in my project.
Hello techbitar, <br> <br>I just ordered all the hardware for this project, and I should be beginning it some time next week. I just had a question. Obviously all of these components would need to be powered up whilst in car data collecting while driving, so would one of these do the job: http://www.radioshack.com/product/index.jsp?productId=3802146 . Also, I got this for the 'in-home' programming and construction of the actual project: https://www.sparkfun.com/products/9442? ..... Do you think that'll be good as well? I would assume so.
The Arduino Uno specs are as follows: <br>Input Voltage (recommended) 7-12V <br>Input Voltage (limits) 6-20V <br> <br>As for current, I have tested my Bump-O-Meter with a USB connection which provides 5V and up to 0.5A. I did not run into any issues but I did not perform any exhaustive tests. <br> <br>While driving around in my car, I powered the Arduino Uno via the DC plug using a battery brick made of 6 X 1.2V (NiMh) = 7.2V @ 2A. That voltage is close to the minimum recommended voltage. It worked but of course the moment the battery dropped to 6V and below I am sure I would have ran into all sorts of issues. <br> <br>If I go production with this, I would use a 3S LiPo for a cool 11.1 Volts and 1.5A or 2A current for safety margin in case I need to add additional power hungry gizmos to the bump-o-meter. <br> <br>Check you choices of power supplies against the min/max voltage specs and add a comfortable margin to the current with an eye on your future plans. then decide what fits your requirements best.
I was riding my bike recently and remarked to another rider that it would be useful to quantify just how bad our roads are. My thinking is to first breadboard components as you have laid them out, and then substitute an Arduino Micro and micro SD card reader for compactness. While I like LiOn batteries, a 3S 11.1V 2 amp battery is fairly large (and heavy and needs a requisite charger). Do you have an idea for a compact battery with a 3-hour runtime?
Hello techbitar - I'm thinking of building an adaption of your project but am considering changing the SD card adapter to the microSD card shield from Sparkfun: https://www.sparkfun.com/products/9802 <br> <br>Do you see any obvious problems with this change, and would it break the code you've written? Cheers
I have not tried it but if it Sparkfun's SD adapter does not work out of the box you may need to tweak my circuit and/or code.
You can read the accelerometer more often than the GPS, so there should be no need to interpolate the accelerometer reading.
True but not all sensors (temperature, humid, etc.) possibly used by others will be as fast as the accelerometer I am using in my project.
awesome and super useful..
SUPER Tutorial and explanation!! Thanks.
Does anyone know why I am getting this: http://imgur.com/AeUVEwj , and not what the instructable shows? Any help would be much appreciated, especially seeing how far I've gotten.
&quot;We have to level-shift the Arduino's 5V signals to 3.3V before we can connect them to the SD card.&quot; &nbsp;<strong>Why?</strong><br> <br> Can I <strong>power the SD</strong> card via a <strong>3.3V output of the SN74AHC125?</strong> I just have the SD socket and have got all components except the LM1117 to build a circuit like the LC STUDIO.
Wikipedia says &quot;The power consumption of microSD cards varies by manufacturer, but is in the range of 66&ndash;330 mW (20&ndash;100 mA)&quot;
&quot;Just because this SD card socket can be powered with 5V or 3.3V, we still can't connect 5V Arduino pins to the SD card socket's pins&quot;. <br> <br>Also ask why? If the arduino's 5V socket can hold 500mA shouldn't I be able to connect this socket to the shield's 5V socket directly?
Hw to make this data logger into real time to upload the SD card contents after formatting into any GPS visulaizing website automatically !! <br>Can any one help me !!!
everything is well
does the GPS data logger always have to be connected to the internet or all it needs is a power source? i need an urgent reply coz im about to start making it please help me hehe tnx in advanced
there's no need to connect the gadget to the internet.
oh i get it thank you very much<br>
You can read the accelerometer more often than the GPS, so there should be no need to interpolate the accelerometer reading. Either you would interpolate the position reading (write 10 accelerometer readings for every GPS reading and do the interpolation in post processing,) or characterize the 10 accelerometer readings (likely take RMS or peak) and record once per GPS reading.
actually this is my 2nd time to use the arduino and im a student, most of the materials that you use is available in the Philippines but they differ on the look and sizes but the function remain the same <br> <br>SN74AHCT1G32DCKR 2 input OR Gate tsop-5 &lt;--- is this IC are allowed to use? i find it hard to find the IC SN74AHC125 as level shifter from 5V to 3.3V <br>or do you have any alternatives?
Google it and see if others have used it and what are their impressions. then check the datasheet and see if the specs meet your requirements
ok tnx for the reply
awesome and super useful....keep going :)
this is a LOT better than your previous version, i am planning to build it, i am from the Philippines, is it okay if i present it to my school? anyway i hope you can help me out if i encounter trouble in making this prototype :D <br>GOD bless thank you :)
Hi tolstoyan, by all means you can do whatever you want with the design. But if this is your first Arduino project, may I suggest that you start with something more basic (so many nice Arduino projects on instructbales.com) before you start with the geo data logger. I have provided point to point wiring diagrams both visually and textually so you can implement this with little need for intervention from anyone. if you use the same parts and wire them according to my instructions, the accompanying software will also work as-is. I would love to see some videos of your final project. Best of luck and keep me posted please.
Hello, this looks pretty awesome. I am learning to fly a Powered Paraglider and would live to have some type of instrumentation that gives similar results to what you have here. Just a simple GPS or Variometer seems like minimal information. Thanks for the post ill keep up with you to see how things progress. If you ever need an aviation instrument tester let me know!
Thanks, Scubamatt. I am not sure I will be flying things with my gadget any time soon :) but I think the nice folks at DIYDRONES.com have great guides and tools for what you have in mind. Check this out: http://diydrones.com/profiles/blogs/a-newbies-guide-to-uavs <br>
Air quality depends a lot on time of day. This seems like a good way to measure that variation on a local level over many, many trips through the same area at different times of day.
good point.
I would like to use something like this to log mileage driven in my informal two-household car-sharing program, for the purpose of sharing expenses. We determined that we don't need to know where the car has been, but would like to know just the amount of time it is driven + time it is away from the garage, for each user. So I think it's three sensor inputs needed to log three pieces of info: <br>1. am i away from the garage? <br>2. if so, am i moving? <br>3. if moving, who is driving me? <br>And the rest can be worked out offline. Any ideas?
my first impression is that you will have write a program to analyze the data generated by the geo logger. we already capture location, speed, and date/time. Since know your garage's latitude/longitude you can analyze logged data ranges that start and end with your garage's location.this signifies a completed round trip. then you calculate difference of time/date when you left the garage vs when you returned. that's the duration of your journey. then you scan the previous data for in between locations to look for periods where location does not change much which should mean the car is stationary. subtract the time for the stationary locations from total round trip time to determine for how much time the car was moving. this is very preliminary approach but you get my drift. the solution will be mostly programmatic.

About This Instructable

166,166views

521favorites

License:

Bio: Did I unplug the solder iron?
More by techbitar:IR Remote Control Station for Android - TURN THE TV DOWN SensoDuino: Turn Your Android Phone into a Wireless Sensors Hub for Arduino Modify The HC-05 Bluetooth Module Defaults Using AT Commands 
Add instructable to: