Snooze_TinyGPSPlus_Teensy 3.2 - problem reading gps on wake

Status
Not open for further replies.

AndyUK

Member
Hi I am working on a project that includes a Teensy 3.2 and GPS unit as part of a LIPO battery powered project. There are other components but they don't have an impact on my problem.
To save power I am using the excellent Snooze library and waking using a digital input button.:)
The GPS unit works fine when not using the Snooze function.
My problem is,when I try and use Snooze the Teensy goes to sleep fine but on waking I can't read the current GPS location...it appears to be serial printing the location at the time the Teensy went to sleep and not the one upon waking up.:confused: I will be using the latitude and longitude values after waking up to make various distance calculations to multiple known coordinates from whatever the current location is. I am hoping there is a simple answer..hope someone can assist me.
I have attached the code which I have tried to modify...it works to a fashion but does give the required current location.

Code:
#include <Snooze.h>//teensy snooze library

//load snooze drivers
SnoozeDigital digital;
SnoozeUSBSerial   usb;

//install drivers to SnoozeBlock
SnoozeBlock config(digital);

#include <TinyGPS++.h>

/* This sample code demonstrates the normal use of a TinyGPSPlus object. */

TinyGPSPlus gps;

/* On Teensy, the UART (real serial port) is always best to use. */
/* Unlike Arduino, there's no need to use NewSoftSerial because */
/* the "Serial" object uses the USB port, leaving the UART free. */
HardwareSerial Uart = HardwareSerial();

//void gpsdump(TinyGPSPlus &gps);
//void printFloat(double f, int digits = 2);

const int findholeWake = 16; //pin 16 connected to a button which is held high..low when pressed

void setup()
{
  Serial.begin(115200);
  Uart.begin(9600);  
  delay(1000);
  Serial.println("by Mikal Hart");
  Serial.println();
  Serial.print("Sizeof(gpsobject) = "); Serial.println(sizeof(TinyGPSPlus));
  Serial.println();
  
  //pin, mode, type
digital.pinMode(findholeWake, INPUT_PULLUP, FALLING);
}
// end of set up

void loop()
{   
  bool newdata = false;
  unsigned long start = millis();

  // Every 5 seconds we print an update
  while (millis() - start <350) {
    if (Uart.available()) {
      char c = Uart.read();
       //Serial.print(c);  // uncomment to see raw GPS data
      if (gps.encode(c)) {
        newdata = true;
        // break;  // uncomment to print new data immediately!
      }
    }
  }
    
  if (newdata) { 
    
        int who;      
       //go to sleep and wake up using digital pin 16 
         who = Snooze.deepSleep(config);          
      // following code will allow serial mointor to work when button/timer wakes Teensy
        elapsedMillis time = 0;
        while (!Serial && time < 1000) {
        Serial.write(0x00);// print out a bunch of NULLS to serial monitor
        digitalWriteFast(LED_BUILTIN, HIGH);
        delay(30);
        digitalWriteFast(LED_BUILTIN, LOW);
        delay(30);
    }
    // normal delay for Arduino Serial Monitor
    delay(500);//200...500 seems to work back to front
    // print who woke the teensy up, i.e. timer || digital
    Serial.print("Timer Driver number indicator: ");
    Serial.println(who);
     //delay(200);
    
    if (who == 16) {// pin wakeup source is its pin value
       // following code will allow serial mointor to work when button/timer wakes Teensy
      delay(400);
      Serial.println(gps.time.minute()); 
      Serial.println("Acquired Data");
      Serial.println("-------------");
      //gpsdump(gps);
      Serial.println(gps.location.lat(),6);
      Serial.println(gps.location.lng(),6);
      Serial.println("-------------");
      Serial.println();
      }
    }
  }
 
Can you try this:
Code:
SnoozeBlock config(usb, digital);

Thanks Duff for your quick reply:)...yep sorry I missed that. The Serial.print data now displays as expected. However, I am not sure that it has fixed the problem of the data being old and not current on waking up.
For example.. if I allow the time in mins to move from say 30 to 31 on my laptop and I press the button after 31 mins I get serial data printed with a time of 30 mins and not 31. Not sure if there is another explanation for the time not being current on waking up?:confused: I am pretty suremy laptop is accurate..same as iPhone and iPad. Any other suggestions..thanks
 
Not sure why you are getting stale data, is this data coming from the GPS or from millis on the Teensy? Is this stale data what you are printing after waking, i.e.
Code:
if (who == 16) {// pin wakeup source is its pin value
       // following code will allow serial mointor to work when button/timer wakes Teensy
      delay(400);
      Serial.println(gps.time.minute()); 
      Serial.println("Acquired Data");
      Serial.println("-------------");
      //gpsdump(gps);
      Serial.println(gps.location.lat(),6);
      Serial.println(gps.location.lng(),6);
      Serial.println("-------------");
      Serial.println();
}
Snooze just puts the teensy to sleep so any external modules should not be effected.
 
Yes, the stale data is from the code you have highlighted. I am not sure how to check whether this is from the GPS or from millis on the Teensy. Any further help appreciated.
 
hi, just removed snooze and could see that the serial data on te monitor matched laptop time...so still not there yet:)

Code:
//#include <Snooze.h>//teensy snooze library

//load snooze drivers
//SnoozeDigital digital;
//SnoozeUSBSerial   usb;

//install drivers to SnoozeBlock
//SnoozeBlock config(usb, digital);

#include <TinyGPS++.h>

/* This sample code demonstrates the normal use of a TinyGPSPlus object. */

TinyGPSPlus gps;

/* On Teensy, the UART (real serial port) is always best to use. */
/* Unlike Arduino, there's no need to use NewSoftSerial because */
/* the "Serial" object uses the USB port, leaving the UART free. */
HardwareSerial Uart = HardwareSerial();

//void gpsdump(TinyGPSPlus &gps);
//void printFloat(double f, int digits = 2);

//const int findholeWake = 16; //pin 16 connected to a button which is held high..low when pressed

void setup()
{
  Serial.begin(115200);
  Uart.begin(9600);  
  delay(1000);
  Serial.println("by Mikal Hart");
  Serial.println();
  Serial.print("Sizeof(gpsobject) = "); Serial.println(sizeof(TinyGPSPlus));
  Serial.println();
  
  //pin, mode, type
//digital.pinMode(findholeWake, INPUT_PULLUP, FALLING);
}
// end of set up

void loop()
{   
  bool newdata = false;
  unsigned long start = millis();

  // Every 5 seconds we print an update
  while (millis() - start <350) {
    if (Uart.available()) {
      char c = Uart.read();
       //Serial.print(c);  // uncomment to see raw GPS data
      if (gps.encode(c)) {
        newdata = true;
        // break;  // uncomment to print new data immediately!
      }
    }
  }
    
  if (newdata) { 
    /*
        int who;      
       //go to sleep and wake up using digital pin 16 
         who = Snooze.deepSleep(config);          
      // following code will allow serial mointor to work when button/timer wakes Teensy
        elapsedMillis time = 0;
        while (!Serial && time < 1000) {
        Serial.write(0x00);// print out a bunch of NULLS to serial monitor
        digitalWriteFast(LED_BUILTIN, HIGH);
        delay(30);
        digitalWriteFast(LED_BUILTIN, LOW);
        delay(30);
    }
    // normal delay for Arduino Serial Monitor
    delay(500);//200...500 seems to work back to front
    // print who woke the teensy up, i.e. timer || digital
    Serial.print("Timer Driver number indicator: ");
    Serial.println(who);
     //delay(200);
    
    if (who == 16) {// pin wakeup source is its pin value
       // following code will allow serial mointor to work when button/timer wakes Teensy
      delay(400);
      */
      Serial.println(gps.time.minute()); 
      Serial.println("Acquired Data");
      Serial.println("-------------");
      //gpsdump(gps);
      Serial.println(gps.location.lat(),6);
      Serial.println(gps.location.lng(),6);
      Serial.println("-------------");
      Serial.println();
      //}
    }
  }
 
Last edited:
Hi, just removed the millis element in the code and put snooze back in...unfortunately still same problem of stale data
Code:
#include <Snooze.h>//teensy snooze library

//load snooze drivers
SnoozeDigital digital;
SnoozeUSBSerial   usb;

//install drivers to SnoozeBlock
SnoozeBlock config(usb, digital);

#include <TinyGPS++.h>

/* This sample code demonstrates the normal use of a TinyGPSPlus object. */

TinyGPSPlus gps;

/* On Teensy, the UART (real serial port) is always best to use. */
/* Unlike Arduino, there's no need to use NewSoftSerial because */
/* the "Serial" object uses the USB port, leaving the UART free. */
HardwareSerial Uart = HardwareSerial();


const int findholeWake = 16; //pin 16 connected to a button which is held high..low when pressed

void setup()
{
  Serial.begin(115200);
  Uart.begin(9600);  
  delay(1000);
  Serial.println("by Mikal Hart");
  Serial.println();
  Serial.print("Sizeof(gpsobject) = "); Serial.println(sizeof(TinyGPSPlus));
  Serial.println();
  
  //pin, mode, type
digital.pinMode(findholeWake, INPUT_PULLUP, FALLING);
}
// end of set up

void loop()
{   
  bool newdata = false;
  unsigned long start = millis();

  // Every 5 seconds we print an update
  //while (millis() - start <350) {
    if (Uart.available()) {
      char c = Uart.read();
       //Serial.print(c);  // uncomment to see raw GPS data
      if (gps.encode(c)) {
        newdata = true;
        // break;  // uncomment to print new data immediately!
      }
    //}
  }
    
  if (newdata) { 
    
        int who;      
       //go to sleep and wake up using digital pin 16 
         who = Snooze.deepSleep(config);          
      // following code will allow serial mointor to work when button/timer wakes Teensy
        elapsedMillis time = 0;
        while (!Serial && time < 1000) {
        Serial.write(0x00);// print out a bunch of NULLS to serial monitor
        digitalWriteFast(LED_BUILTIN, HIGH);
        delay(30);
        digitalWriteFast(LED_BUILTIN, LOW);
        delay(30);
    }
    // normal delay for Arduino Serial Monitor
    delay(500);//200...500 seems to work back to front
    // print who woke the teensy up, i.e. timer || digital
    Serial.print("Timer Driver number indicator: ");
    Serial.println(who);
     //delay(200);
    
    if (who == 16) {// pin wakeup source is its pin value
       // following code will allow serial mointor to work when button/timer wakes Teensy
      delay(400);
      
      Serial.println(gps.time.minute()); 
      Serial.println("Acquired Data");
      Serial.println("-------------");
      Serial.println(gps.location.lat(),6);
      Serial.println(gps.location.lng(),6);
      Serial.println("-------------");
      Serial.println();
      }
    }
  }
 
I've never used a gps module but it seems that you are reading the gps data then going to sleep, shouldn't you read the gps receiver after waking? Does this module toggle a pin when new data has arrived? If so then read it after waking?
 
Hi, so I seem to have something that now works...although the gps encode function seems to be very sensitive to minor code changes. So, there may be a health warning....good enough for me though hopefully:)
Code attached. Am now reading gps data after waking up and getting current data... not stale.
Many thanks for your tips Duff. Am using Snooze for a number of other functions in the same project, so very happy to now have the gps part under control.
Code:
#include <Snooze.h>//teensy snooze library

//load snooze drivers
SnoozeDigital digital;
SnoozeUSBSerial   usb;

//install drivers to SnoozeBlock
SnoozeBlock config(usb, digital);

#include <TinyGPS++.h>

/* This sample code demonstrates the normal use of a TinyGPSPlus object. */

TinyGPSPlus gps;

/* On Teensy, the UART (real serial port) is always best to use. */
/* Unlike Arduino, there's no need to use NewSoftSerial because */
/* the "Serial" object uses the USB port, leaving the UART free. */
HardwareSerial Uart = HardwareSerial();


const int findholeWake = 16; //pin 16 connected to a button which is held high..low when pressed

void setup()
{
  Serial.begin(115200);
  Uart.begin(9600);  
  delay(1000);
  Serial.println("by Mikal Hart");
  Serial.println();
  Serial.print("Sizeof(gpsobject) = "); Serial.println(sizeof(TinyGPSPlus));
  Serial.println();
  
  //pin, mode, type
digital.pinMode(findholeWake, INPUT_PULLUP, FALLING);
delay(200);
}

// end of set up

void loop()
{   
   int who;      
       //go to sleep and wake up using digital pin 16 
         who = Snooze.deepSleep(config);          
      // following code will allow serial mointor to work when button/timer wakes Teensy
        elapsedMillis time = 0;
        while (!Serial && time < 1000) {
        Serial.write(0x00);// print out a bunch of NULLS to serial monitor
        digitalWriteFast(LED_BUILTIN, HIGH);
        delay(30);
        digitalWriteFast(LED_BUILTIN, LOW);
        delay(30);
    }
    // normal delay for Arduino Serial Monitor
    delay(200);//200
    // print who woke the teensy up, i.e. timer || digital
    Serial.print("Timer Driver number indicator: ");
    Serial.println(who);
    
    if (who == 16) {// pin wakeup source is its pin value
      delay(400);//200 not enough time for teensy to wake up... 400 seems to be enough before starting to read and encode gps data 
    }
    
  for(int i=0; i<2; i++){// need to loop through the Uart read and encode cycle a couple of times to allow enough raw gps data to get full sets to encoded data
      unsigned long start = millis();
  // Every 5 seconds we print an update
  while (millis() - start < 500) {// need to include the millis loop or no data encoded 
    if (Uart.available()) {
      char c = Uart.read();
       //Serial.print(c);  // uncomment to see raw GPS data
     // /*
      if (gps.encode(c)) {
       Serial.println(gps.satellites.value());
       Serial.println(gps.time.minute());
       Serial.println(gps.location.lat(),6);
       Serial.println(gps.location.lng(),6);
       Serial.println(gps.location.age());
        // break;  // uncomment to print new data immediately!
        }
       // else{
          //Serial.println("gps.encode failed");// cant use this else function to check....it causes encode to fail!!!!!
       // }
        //*/
      }
    }
  }
  Serial.println(gps.satellites.value()); // check that serial.print shows the last encoded data
  Serial.println(gps.time.minute());  // check that serial.print shows the last encoded data
  delay(200);
}
 
Status
Not open for further replies.
Back
Top