Hello, I'm using an adafruit ultimate GPS logger shield with the Arduino Uno. I'm in the process of modifying an example sketch (shield_sdlog) to fit my exact purpose. I just want to log latitude and longitude to a log file in a format that I can control. Originally, I was trying to parse through the default NMEA sentences for the latitude and longitude, but then I realized that it's easier if I just access them directly, so I switched the code to do that. However, then I began to wonder if the commands in the setup code to tell the GPS to send out specific sentences were unnecessary, if I was accessing the data directly, and not through these sentences, so I tried commenting out this section and one other section in the loop that parsed each sentence. However, now whenever I run the code I get no fix from the GPS no matter where I am (including places that had a fix before I commented out this code). So I assume that this code is important to what I want to do somehow, but I don't understand how. I was wondering if anyone could explain how it was related, and/or what the built in "interrupt" option does, and whether or not I want it. (I'm going to be pushing the memory capacity for this project, so I want to remove anything that's unnecessary)
Here is the code of the modified sketch:
// This code shows how to listen to the GPS module in an interrupt
// which allows the program to have more 'freedom' - just parse
// when a new NMEA sentence is available! Then access data when
// desired.
#include <SPI.h>
#include <Adafruit_GPS.h>
#include <SoftwareSerial.h>
#include <SD.h>
#include <avr/sleep.h>
SoftwareSerial mySerial(8, 7);
Adafruit_GPS GPS(&mySerial);
// Set GPSECHO to 'false' to turn off echoing the GPS data to the Serial console
// Set to 'true' if you want to debug and listen to the raw GPS sentences
#define GPSECHO true
/* set to true to only log to SD when GPS has a fix, for debugging, keep it false */
#define LOG_FIXONLY false
// this keeps track of whether we're using the interrupt
// off by default!
boolean usingInterrupt = false;
void useInterrupt(boolean); // Func prototype keeps Arduino 0023 happy
//pins
//adafruit GPS shield uses pins 8, 10-13
//pin 8 is for serial communication, 10 is the chip select pin (whatever that means), and 11-13 are for the SPI bus
//not sure why we only have to declare 8, 10, and 13, but this is how it was originally in the tutorial and it works
//apparently the GPS uses pin 9 also because I realized it was glitching when I didn't connect it
#define chipSelect 10
#define ledPin 13
File logFile;
//maybe use a different class for these functions if I ever get MSVCPP and visual micro working with Arduino
// 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)
{
while(1)
{
uint8_t i;
for (i=0; i<errno; i++)
{
digitalWrite(ledPin, HIGH);
delay(100);
digitalWrite(ledPin, LOW);
delay(100);
}
for (i=errno; i<10; i++)
{
delay(200);
}
}
}
void setup()
{
// connect at 115200 so we can read the GPS fast enough and echo without dropping chars
// also spit it out
Serial.begin(115200);
Serial.println("\r\nUltimate GPSlogger Shield");
//initialize switch pins
pinMode(laneUpPin, INPUT);
pinMode(laneDownPin, INPUT);
pinMode(leftShoulderPin, INPUT);
pinMode(rightShoulderPin, INPUT);
pinMode(onRampPin, INPUT);
pinMode(offRampPin, INPUT);
//initialize LCD pins
//pinMode(greenPin, OUTPUT);
//pinMode(bluePin, OUTPUT);
pinMode(ledPin, OUTPUT);
// 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(2);
}
//increment name by adding a number if there are already GPS logs on the SD card
char filename[15];
strcpy(filename, "GPSLOG00.TXT");
for (uint8_t i = 0; i < 100; i++)
{
filename[6] = '0' + i/10;
filename[7] = '0' + i%10;
// create if does not exist, do not open existing, write, sync after write
if (! SD.exists(filename))
{
break;
}
}
logFile = SD.open(filename, FILE_WRITE);
if( ! logFile )
{
Serial.print("Couldnt create ");
Serial.println(filename);
error(3);
}
Serial.print("Writing to ");
Serial.println(filename);
// connect to the GPS at the desired rate
GPS.begin(9600);
//this is the first section I want to be able to comment out but apparently can't
/*
//for logging data, we don't suggest using anything but either RMC only or RMC+GGA to keep the log files at a reasonable size
//the other two possible NMEA sentences I might want to include: GPHDT/GPHDG (heading), and PGRME (estimated position error)
//RMC (recommended minimum) and GGA (fix data) including altitude
GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
// uncomment this line to turn on only the "minimum recommended" data
//GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCONLY);
// Set the update rate
GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ); // 100 millihertz (once every 10 seconds), 1Hz or 5Hz update rate
// Turn off updates on antenna status, if the firmware permits it
GPS.sendCommand(PGCMD_NOANTENNA);
// the nice thing about this code is you can have a timer0 interrupt go off
// every 1 millisecond, and read data from the GPS for you. that makes the
// loop code a heck of a lot easier!
useInterrupt(true);
*/
}
// Interrupt is called once a millisecond, looks for any new GPS data, and stores it
SIGNAL(TIMER0_COMPA_vect)
{
char c = GPS.read();
// if you want to debug, this is a good time to do it!
#ifdef UDR0
if (GPSECHO)
if (c) UDR0 = c;
// writing direct to UDR0 is much much faster than Serial.print
// but only one character can be written at a time.
#endif
}
void useInterrupt(boolean v)
{
if (v)
{
// Timer0 is already used for millis() - we'll just interrupt somewhere
// in the middle and call the "Compare A" function above
OCR0A = 0xAF;
TIMSK0 |= _BV(OCIE0A);
usingInterrupt = true;
}
else
{
// do not call the interrupt function COMPA anymore
TIMSK0 &= ~_BV(OCIE0A);
usingInterrupt = false;
}
}
void loop()
{
if (! usingInterrupt)
{
// read data from the GPS in the 'main loop'
char c = GPS.read();
// if you want to debug, this is a good time to do it!
if (GPSECHO)
if (c) Serial.print(c);
}
if (GPS.newNMEAreceived())
{
//get GPS location
//this is the second section
/*
// a tricky thing here is if we print the NMEA sentence, or data
// we end up not listening and catching other sentences!
// so be very wary if using OUTPUT_ALLDATA and trying to print out data
// Don't call lastNMEA more than once between parse calls! Calling lastNMEA
// will clear the received flag and can cause very subtle race conditions if
// new data comes in before parse is called again.
char *stringptr = GPS.lastNMEA();
if (!GPS.parse(stringptr)) // this also sets the newNMEAreceived() flag to false
return; // we can fail to parse a sentence in which case we should just wait for another
*/
//log NMEA sentence along with highway state variables to SD card
if (GPS.fix)
{
//logFile.print("Fix: ");
} else
{
logFile.print("no fix: ");
}
logFile.print(GPS.month); logFile.print("/"); logFile.print(GPS.day); logFile.print("/"); logFile.print(GPS.year); logFile.print(";");
logFile.print(GPS.hour); logFile.print(":"); logFile.print(GPS.minute); logFile.print(":"); logFile.print(GPS.seconds); logFile.print(";");
logFile.print(GPS.lat); logFile.print(";"); //N or S to represent a positive or negative sign for the latitude
logFile.print(GPS.latitude); logFile.print(";");
logFile.print(GPS.lon); logFile.print(";"); //E or W to represent a positive or negative sign for the longitude
logFile.print(GPS.longitude); logFile.print(";");
logFile.println();
logFile.flush(); //need this to make sure that each individual line is actually saved to the file without closing it officially
}
}
Thanks