I am very new to programming and micro controllers. As part of my degree I would like to track buffalo. Due to the cost of commercially available gps tracking units I decided to attempt building my own. To start with I have an Arduino Uno R3 with a Adafruit Ultimate GPS shield.
I would like to log one gps location every hour, save it to the sd card, and power everything down to conserve as much power as possible. My power source will be 2 parallel AA NiMD (6 in series giving 9v at a stated 2700mAh). I can change batteries every 70 days.
I have found the following code (see below). The code seems to have been written for a previous version of the gps shield. It compiles and loads to the Arduino Uno R3 and then only gives the following in the serial monitor GPSlogger, Writing to GPSLOG12.TXT, Ready!, and does not continue with obtaining gps sentences or the sleep procedure.
I would really appreciate it someone could have a look at the code for me to tell me where I am going wrong. I have spent days trying to find a solution, but my programming knowledge is preventing me from finding a solution.
Thanks a lot.
Code: Select all
// Ladyada's logger modified by Bill Greiman to use the SdFat library
// this is a generic logger that does checksum testing so the data written should be always good
// Assumes a sirf III chipset logger attached to pin 2 and 3
#include <SD.h>
#include <avr/sleep.h>
#include "GPSconfig.h"
#include <SPI.h>
#include <Adafruit_GPS.h>
#include <SoftwareSerial.h>
// If using Arduino IDE prior to 1.0,
// make sure to install newsoftserial from Mikal Hart
// http://arduiniana.org/libraries/NewSoftSerial/
#if ARDUINO >= 100
#include <SoftwareSerial.h>
#else
#include <NewSoftSerial.h>
#endif
// power saving modes
#define SLEEPDELAY 10
#define TURNOFFGPS 1
#define LOG_RMC_FIXONLY 1
// what to log
#define LOG_RMC 1 // RMC-Recommended Minimum Specific GNSS Data, message 103,04
#define LOG_GGA 0 // GGA-Global Positioning System Fixed Data, message 103,00
#define LOG_GLL 0 // GLL-Geographic Position-Latitude/Longitude, message 103,01
#define LOG_GSA 0 // GSA-GNSS DOP and Active Satellites, message 103,02
#define LOG_GSV 0 // GSV-GNSS Satellites in View, message 103,03
#define LOG_VTG 0 // VTG-Course Over Ground and Ground Speed, message 103,05
// //Set GPS Echo
// #define GOSECHO true
// //Set log only if gps fix
// #define LOG_FIXONLY true
// Use pins 8 and 7 to talk to the GPS. 8 is the TX pin, 7 is the RX pin
SoftwareSerial gpsSerial = SoftwareSerial(8, 7);
#define GPSRATE 115200 //115200 works
// Set the pins used
#define powerPin 4
//#define led1Pin 5
//#define led2Pin 6
#define ledPin 13
#define chipSelect 10
#define BUFFSIZE 90
char buffer[BUFFSIZE];
uint8_t bufferidx = 0;
bool fix = false; // current fix data
bool gotGPRMC; //true if current data is a GPRMC strinng
uint8_t i;
File logfile;
// read a Hex value and return the decimal equivalent
uint8_t parseHex(char c) {
if (c < '0')
return 0;
if (c <= '9')
return c - '0';
if (c < 'A')
return 0;
if (c <= 'F')
return (c - 'A')+10;
}
// blink out an error code
void error(uint8_t errno) {
/*
if (SD.errorCode()) {
putstring("SD error: ");
Serial.print(card.errorCode(), HEX);
Serial.print(',');
Serial.println(card.errorData(), HEX);
}
*/
while(1) {
for (i=0; i<errno; i++) {
digitalWrite(ledPin, HIGH);
//digitalWrite(led2Pin, HIGH);
delay(100);
digitalWrite(ledPin, LOW);
//digitalWrite(led2Pin, LOW);
delay(100);
}
for (; i<10; i++) {
delay(200);
}
}
}
void setup() {
WDTCSR |= (1 << WDCE) | (1 << WDE);
WDTCSR = 0;
Serial.begin(115200);
Serial.println("\r\nGPSlogger");
pinMode(ledPin, OUTPUT);
//pinMode(led2Pin, OUTPUT);
pinMode(powerPin, OUTPUT);
digitalWrite(powerPin, LOW);
// make sure that the default chip select pin is set to
// output, even if you don't use it:
pinMode(10, OUTPUT);
// see if the card is present and can be initialized:
if (!SD.begin(chipSelect)) {
Serial.println("Card init. failed!");
error(1);
}
strcpy(buffer, "GPSLOG00.TXT");
for (i = 0; i < 100; i++) {
buffer[6] = '0' + i/10;
buffer[7] = '0' + i%10;
// create if does not exist, do not open existing, write, sync after write
if (! SD.exists(buffer)) {
break;
}
}
logfile = SD.open(buffer, FILE_WRITE);
if( ! logfile ) {
Serial.print("Couldnt create "); Serial.println(buffer);
error(3);
}
Serial.print("Writing to "); Serial.println(buffer);
// connect to the GPS at the desired rate
gpsSerial.begin(GPSRATE);
Serial.println("Ready!");
gpsSerial.print(SERIAL_SET);
delay(250);
#if (LOG_DDM == 1)
gpsSerial.print(DDM_ON);
#else
gpsSerial.print(DDM_OFF);
#endif
delay(250);
#if (LOG_GGA == 1)
gpsSerial.print(GGA_ON);
#else
gpsSerial.print(GGA_OFF);
#endif
delay(250);
#if (LOG_GLL == 1)
gpsSerial.print(GLL_ON);
#else
gpsSerial.print(GLL_OFF);
#endif
delay(250);
#if (LOG_GSA == 1)
gpsSerial.print(GSA_ON);
#else
gpsSerial.print(GSA_OFF);
#endif
delay(250);
#if (LOG_GSV == 1)
gpsSerial.print(GSV_ON);
#else
gpsSerial.print(GSV_OFF);
#endif
delay(250);
#if (LOG_RMC == 1)
gpsSerial.print(RMC_ON);
#else
gpsSerial.print(RMC_OFF);
#endif
delay(250);
#if (LOG_VTG == 1)
gpsSerial.print(VTG_ON);
#else
gpsSerial.print(VTG_OFF);
#endif
delay(250);
#if (USE_WAAS == 1)
gpsSerial.print(WAAS_ON);
#else
gpsSerial.print(WAAS_OFF);
#endif
}
void loop() {
//Serial.println(Serial.available(), DEC);
char c;
uint8_t sum;
// read one 'line'
if (gpsSerial.available()) {
c = gpsSerial.read();
#if ARDUINO >= 100
Serial.write(c);
#else
Serial.print(c, BYTE);
#endif
if (bufferidx == 0) {
while (c != '$')
c = gpsSerial.read(); // wait till we get a $
}
buffer[bufferidx] = c;
#if ARDUINO >= 100
Serial.write(c);
#else
Serial.print(c, BYTE);
#endif
if (c == '\n') {
//putstring_nl("EOL");
//Serial.print(buffer);
buffer[bufferidx+1] = 0; // terminate it
if (buffer[bufferidx-4] != '*') {
// no checksum?
Serial.print('*');
bufferidx = 0;
return;
}
// get checksum
sum = parseHex(buffer[bufferidx-3]) * 16;
sum += parseHex(buffer[bufferidx-2]);
// check checksum
for (i=1; i < (bufferidx-4); i++) {
sum ^= buffer[i];
}
if (sum != 0) {
//putstring_nl("Cxsum mismatch");
Serial.print('~');
bufferidx = 0;
return;
}
// got good data!
gotGPRMC = strstr(buffer, "GPRMC");
if (gotGPRMC) {
// find out if we got a fix
char *p = buffer;
p = strchr(p, ',')+1;
p = strchr(p, ',')+1; // skip to 3rd item
if (p[0] == 'V') {
digitalWrite(ledPin, LOW);
fix = false;
} else {
digitalWrite(ledPin, HIGH);
fix = true;
}
}
if (LOG_RMC_FIXONLY) {
if (!fix) {
Serial.print('_');
bufferidx = 0;
return;
}
}
// rad. lets log it!
Serial.print(buffer); //first, write it to the serial monitor
Serial.print('#');
if (gotGPRMC) //If we have a GPRMC string
{
// Bill Greiman - need to write bufferidx + 1 bytes to getCR/LF
bufferidx++;
digitalWrite(ledPin, HIGH); // Turn on LED 2 (indicates write to SD)
logfile.write((uint8_t *) buffer, bufferidx); //write the string to the SD file
logfile.flush();
/*
if( != bufferidx) {
putstring_nl("can't write!");
error(4);
}
*/
digitalWrite(ledPin, LOW); //turn off LED2
bufferidx = 0; //reset buffer pointer
if ((fix) && (TURNOFFGPS)) { // turn off GPS module? (don't turn off if thre's no fix)
digitalWrite(powerPin, HIGH); //turn off GPS
delay(100); //wait for serial write to finish
sleep_sec(SLEEPDELAY); //turn off CPU
digitalWrite(powerPin, LOW); //turn on GPS
} //if ((fix) && (TURNOFFGPS))
return;
}//if (gotGPRMC)
}
bufferidx++;
if (bufferidx == BUFFSIZE-1) {
Serial.print('!');
bufferidx = 0;
}
} else {
}
}
void sleep_sec(uint8_t x) {
while (x--) {
// set the WDT to wake us up!
WDTCSR |= (1 << WDCE) | (1 << WDE); // enable watchdog & enable changing it
WDTCSR = (1<< WDE) | (1 <<WDP2) | (1 << WDP1);
WDTCSR |= (1<< WDIE);
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
// sleep_enable();
sleep_mode();
// sleep_disable();
}
}
SIGNAL(WDT_vect) {
WDTCSR |= (1 << WDCE) | (1 << WDE);
WDTCSR = 0;
}
/* End code */