Hi fellow Arduinoers
I have a GPS that works great, but when I try to include the watchdog timer, I find that it isn't working as it should. Basically, I would like my GPS to print the time 10 times, and then go to sleep for 8 seconds. Instead, it just keeps printing continuously (without the 8sec delay) the following output:
Setting up...
Adafruit GPS library basic test!
Stopping now.
Going to sleep now
Hello World 1 Time: 3:59:47.0
Stopping now.
Going to sleep now
Stopping now.
Going to sleep now
Hello World 1 Time: 3:59:51.0
Stopping now.
Going to sleep now
Stopping now.
etc etc etc
Below is my code. Does anyone have any thoughts on what might be going on?
#include <avr/sleep.h>
#include <avr/wdt.h>
#include <Adafruit_GPS.h>
#include <SoftwareSerial.h>
SoftwareSerial mySerial(3, 2);
Adafruit_GPS GPS(&mySerial);
#define GPSECHO 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
int lines = 10;
int sleeping_cycles = 1; // 1 = 8sec
// watchdog interrupt
ISR (WDT_vect)
{
wdt_disable(); // disable watchdog
} // end of WDT_vect
void setup () {
Serial.begin(9600);
Serial.println("Setting up...");
Serial.begin(9600);
Serial.println("Adafruit GPS library basic test!");
GPS.begin(9600);
GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ); // 1 Hz update rate
GPS.sendCommand(PGCMD_ANTENNA);
// 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);
delay(1000);
}
// 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;
}
}
uint32_t timer = millis();
void loop ()
{
get_values ();
// Now, run the watchdog...
// disable ADC
ADCSRA = 0;
// clear various "reset" flags
MCUSR = 0;
// allow changes, disable reset
WDTCSR = bit (WDCE) | bit (WDE);
// set interrupt mode and an interval
WDTCSR = bit (WDIE) | bit (WDP3) | bit (WDP0); // set WDIE, and 8 seconds delay
wdt_reset(); // pat the dog
set_sleep_mode (SLEEP_MODE_PWR_DOWN);
sleep_enable();
// turn off brown-out enable in software
MCUCR = bit (BODS) | bit (BODSE);
MCUCR = bit (BODS);
sleep_cpu ();
// cancel sleep as a precaution
sleep_disable();
} // end of loop
void get_values ()
{
int counter = 0;
for (int testloop= 0; testloop < lines; testloop++)
{
counter = counter + 1;
// in case you are not using the interrupt above, you'll
// need to 'hand query' the GPS, not suggested :(
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 a sentence is received, we can check the checksum, parse it...
if (GPS.newNMEAreceived()) {
if (!GPS.parse(GPS.lastNMEA())) // 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
}
if (timer > millis()) timer = millis();
if (millis() - timer > 2000) {
timer = millis(); // reset the timer
if (GPS.fix) {
Serial.print("Hello World ");
Serial.print(counter);
delay(100);
Serial.print("\tTime: ");
Serial.print(GPS.hour, DEC);
Serial.print(':');
Serial.print(GPS.minute, DEC);
Serial.print(':');
Serial.print(GPS.seconds, DEC);
Serial.print('.');
Serial.println(GPS.milliseconds);
delay(100);
}
}
}
Serial.println("Stopping now.");
Serial.println("Going to sleep now");
delay(1000);
} // end of loop