Hey yall,
This is my first post here. I am very new to the arduino community, and development in general. My first project is a GPS Clock that alternates between Time and Date. And also toggles a letter in the corner from A to V, depending on the validity of the fix, and outputs serial data to a SerLCD. My problem is when the GPS has a valid lock the date changes from the correct date 9/8/10 to 0/0/7 or 0/0/5 or something like that. Once it looses its fix the date goes back to normal. I think it has to do with how I am parsing the NMEA statement. I got the bulk of the code from a ladyada project on her site. I cut out all the Long Lat statements.
Here is the code im using…
// A simple sketch to read GPS data and parse the $GPRMC string
// see for more info
#include <NewSoftSerial.h>
NewSoftSerial mySerial = NewSoftSerial(2, 3);
#define powerpin 4
int LedPin = 13;
#define GPSRATE 4800
//#define GPSRATE 38400
// GPS parser for 406a
#define BUFFSIZ 90 // plenty big
char buffer[BUFFSIZ];
char *parseptr;
char buffidx;
uint8_t hour, minute, second, year, month, date;
uint32_t latitude, longitude;
char latdir, longdir;
char status;
long previousMillis = 0;
long interval = 6000;
void setup()
{
pinMode(LedPin, OUTPUT);
if (powerpin) {
pinMode(powerpin, OUTPUT);
}
pinMode(13, OUTPUT);
Serial.begin(9600);
mySerial.begin(GPSRATE);
// prints title with ending line break
Serial.print(0x7C, BYTE);
Serial.print(157, BYTE);
delay(500);
Serial.print(0xFE, BYTE);
Serial.print(0x01, BYTE);
Serial.print(0xFE, BYTE);
Serial.print(128, BYTE);
Serial.print("GPS parser");
Serial.print(0xFE, BYTE);
Serial.print(191, BYTE);
Serial.print("By: Burns");
delay(1000);
digitalWrite(powerpin, LOW); // pull low to turn on!
}
void loop()
{
uint32_t tmp;
//Serial.print("\n\rread: ");
readline();
// check if $GPRMC (global positioning fixed data)
if (strncmp(buffer, "$GPRMC",6) == 0) {
// hhmmss time data
parseptr = buffer+7;
tmp = parsedecimal(parseptr);
hour = tmp / 10000;
minute = (tmp / 100) % 100;
second = tmp % 100;
//fix data
parseptr = strchr(parseptr, ',') + 1;
status = parseptr[0];
parseptr += 2;
// date
parseptr = strchr(parseptr, ',')+7;
tmp = parsedecimal(parseptr);
date = tmp / 10000;
month = (tmp / 100) % 100;
year = tmp % 100;
if (millis() - previousMillis > interval)
{
previousMillis = millis();
Serial.print(0xFE, BYTE);
Serial.print(0x01, BYTE);
Serial.print("DATE");
Serial.print(0xFE, BYTE);
Serial.print(191, BYTE);
Serial.print(date, DEC);
Serial.print('/');
Serial.print(month, DEC);
Serial.print('/');
Serial.print(year, DEC);
Serial.print(0xFE, BYTE);
Serial.print(143, BYTE);
Serial.print(status);
delay(2000);
}
else{
Serial.print(0xFE, BYTE);
Serial.print(0x01, BYTE);
Serial.print("TIME -ZULU-");
Serial.print(0xFE, BYTE);
Serial.print(191, BYTE);
Serial.print(hour, DEC); Serial.print(':');
Serial.print(minute, DEC); Serial.print(':');
Serial.print(second, DEC);
Serial.print(0xFE, BYTE);
Serial.print(143, BYTE);
Serial.print(status);
}
if
(status == 'A')
digitalWrite(LedPin, HIGH);
}
else{
digitalWrite(LedPin, LOW);
}
}
//Serial.println(buffer);
}
uint32_t parsedecimal(char *str) {
uint32_t d = 0;
while (str[0] != 0) {
if ((str[0] > '9') || (str[0] < '0'))
return d;
d *= 10;
d += str[0] - '0';
str++;
}
return d;
}
void readline(void) {
char c;
buffidx = 0; // start at begninning
while (1) {
c=mySerial.read();
if (c == -1)
continue;
//Serial.print(c);
if (c == '\n')
continue;
if ((buffidx == BUFFSIZ-1) || (c == '\r')) {
buffer[buffidx] = 0;
return;
}
buffer[buffidx++]= c;
}
}
Thanks guys,
Steven