Feeling so close yet so far. As the data comes in I am parsing it, pulling the latitude and longitude data out and converting it to a decimal format before printing it out to the serial port. Eventually it will be written to an sd card (as 1000's have done before me I'm sure). The problem is, as long as the data coming in is invalid, the program behaves as expected. As soon as the GPS spits out some valid data, the program processes it and then stops reading any additional data from the GPS. I know that the GPS is still transmitting because if I reset the micro controller I get one valid line of data before it freezes up again. I threw in a line of code at the top of my looping function just to see if the controller was freezing up completely and it doesn't, i.e. it still prints out the string at the top of the loop even though it isn't processing any more of the incoming data from the GPS. Can someone spot my problem because I am at a loss? My program is below:
#include <SoftwareSerial.h>
SoftwareSerial softSerial(4,5); //receive on pin 4 and transmit on pin 5
byte START_CMD[] = {
0xA0,
0xA2,
0x00,
0x18};
byte NMEA_SET[] = {
0x81,
0x02,
0x01, //GGA
0x01, //check sum
0x00, //GLL
0x00, //check sum
0x00, //GSA
0x00, //check sum
0x00, //GSV
0x00, //check sum
0x01, //RMC
0x01, //check sum
0x00, //VTG
0x00, //check sum
0x00, //MSS
0x00, //check sum
0x00, //EPE
0x00, //check sum
0x00, //ZDA
0x00, //check sum
0x00, //unused
0x00, //unused
0x12, //baud in hex high byte
0xC0}; //baud in hex low byte
volatile int state = 0;
boolean sentenceBegins = false;
char buffer[90];
int index = 0;
const byte wakePin = 3;
const byte Control = 2;
const byte On_Off = 7;
char messageID[6];
char time[11];
char latit1[5];
char latit2[5];
char NS[2];
char longit1[6];
char longit2[5];
char EW[2];
char fixindicator[2];
char satsUsed[3];
char HDOP[4];
char MSLalt[10];
char Units[2];
char Geoid[6];
char GeoUnits[2];
char GPSstatus[2];
char GPSspeed[8];
char GPScourse[7];
char Date[7];
char Dummy[12];
boolean sdfileOK = false;
void setup()
{
Serial.begin(115200);
softSerial.begin(4800);
pinMode(wakePin,INPUT); //GPS Wakeup Pin
pinMode(Control,INPUT); //Control Button
pinMode(On_Off,OUTPUT); //GPS ON/OFF Pin
digitalWrite(On_Off,LOW);
digitalWrite(Control,HIGH);
ADCSRA = 0; //disable ADC as we don't need it
//configure GPS to transmit GGA and RMC data only
Serial.println("Waking GPS");
//wake up GPS unless it is already awake
while(!GPSisAwake())
{
digitalWrite(On_Off, HIGH);
delay(200);
digitalWrite(On_Off, LOW);
}
Serial.println("GPS is awake!");
Serial.println("Switching to Binary");
//set to binary mode
softSerial.println("$PSRF100,0,4800,8,1,0*0F");
delay(100);
//set back to NMEA mode with GGA and RMC messages active
Serial.println("Switching to NMEA");
for(int x=0; x<4; x++)
{
softSerial.write(START_CMD[x]);
}
for(int x = 0; x<24; x++)
{
softSerial.write(NMEA_SET[x]);
}
softSerial.write(highByte(calc_check()));
softSerial.write(lowByte(calc_check()));
softSerial.write(0xB0);
softSerial.write(0xB3);
}
void loop()
{
if(checkforSentence())
{
//Serial.println("Sentence Found");
//Serial.println(buffer);
Process_message();
}
}
boolean GPSisAwake()
{
//check to see if GPS is already awake by purging serial data and then
//checking to see if Serial data is still coming in
while(softSerial.available()) softSerial.read();
delay(1200);
if(softSerial.available()) return true;
return false;
}
boolean checkforSentence()
{
char c;
while(softSerial.available())
{
c = softSerial.read();
if(sentenceBegins && c == '\r') //we have a full sentence
{
sentenceBegins = false;
return true;
}
if(sentenceBegins) //store characters to buffer
{
buffer[index] = c;
index++;
buffer[index] = '\0';
}
if(c == '
and this is what the output looks like:
Waking GPS
GPS is awake!
Switching to Binary
Switching to NMEA
0.000000,0.000000
0.000000,0.000000
0.000000,0.000000
0.000000,0.000000
0.000000,0.000000
0.000000,0.000000
0.000000,0.000000
...lots more lines of 0.00000 here deleted for space
0.000000,0.000000
0.000000,0.000000
0.000000,0.000000
40.689670,-74.115737
Waking GPS //This is where I tried a few resets with no luck
GPS is awake!
Switching to Binary
Switching to NMEA
40.689731,-74.115287
Waking GPS
GPS is awake!
Switching to Binary
Switching to NMEA
40.689811,-74.115303
Waking GPS
GPS is awake!
Switching to Binary
Switching to NMEA
40.689834,-74.115661
Waking GPS
GPS is awake!
Switching to Binary
Switching to NMEA
40.689792,-74.115745
) //beginning of sentence...start saving to buffer
{
sentenceBegins = true;
index = 0;
}
}
return false;
}
int calc_check()
{
byte msglen = sizeof(NMEA_SET);
byte index = 0;
int checksum = 0;
while(index<msglen)
{
checksum+=NMEA_SET[index++];
checksum&=(0x7FFF);
}
return checksum;
}
const char* mytok(char* pDst, const char* pSrc, char sep = ',')
{
while ( *pSrc )
{
if ( sep == *pSrc )
{
*pDst = '\0';
return ++pSrc;
}
*pDst++ = *pSrc++;
}
*pDst = '\0';
return NULL;
}
void Process_message()
{
const char* ptr;
//check message ID to see what kind of message we got
ptr = mytok(messageID, buffer);
//if it is GGA, read in the data and write to SDCard if
//the data is valid and an SD file has been created
if(strcmp(messageID, "GPGGA") == 0)
{
ptr = mytok(time, ptr);
ptr = mytok(latit1, ptr, '.'); //get the first half of latitude
ptr = mytok(latit2, ptr); //get the second half of latitude
ptr = mytok(NS, ptr);
ptr = mytok(longit1, ptr, '.');
ptr = mytok(longit2, ptr);
ptr = mytok(EW, ptr);
ptr = mytok(fixindicator, ptr);
ptr = mytok(satsUsed, ptr);
ptr = mytok(HDOP, ptr);
ptr = mytok(MSLalt, ptr);
ptr = mytok(Geoid, ptr);
ptr = mytok(GeoUnits, ptr);
float f, GPSdegrees, fminutes, fseconds, latdecCoords, longdecCoords;
//convert latitude to GPS Decimal format
f = atof(latit1);
f /= 100.00;
GPSdegrees = (int)f; //isolate degrees
fminutes = (f - (int)f) * 100;
//float fminutes = (int)(temp); //isolate minutes
fseconds = atof(latit2)/100.00; //isolate seconds
latdecCoords = GPSdegrees + (((fminutes * (60.0)) + fseconds)/3600.0);
if(NS[0] == 'S') latdecCoords *= -1.0;
//cconvert longitude to GPS decimal format
f = atof(longit1);
f /= 100.00;
GPSdegrees = (int)f; //isolate degrees
fminutes = (f - (int)f) * 100;
fseconds = atof(longit2)/100.00; //isolate seconds
longdecCoords = GPSdegrees + (((fminutes * (60.0)) + fseconds)/3600.0);
if(EW[0] == 'W') longdecCoords *= -1.0;
Serial.print(latdecCoords, 6);
Serial.print(",");
Serial.println(longdecCoords,6);
}
}
and this is what the output looks like:
§DISCOURSE_HOISTED_CODE_1§