Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 10 of 10

Thread: Snooze_TinyGPSPlus_Teensy 3.2 - problem reading gps on wake

  1. #1
    Junior Member
    Join Date
    Feb 2019
    Posts
    12

    Snooze_TinyGPSPlus_Teensy 3.2 - problem reading gps on wake

    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. 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();
          }
        }
      }

  2. #2
    Senior Member duff's Avatar
    Join Date
    Jan 2013
    Location
    Las Vegas
    Posts
    970
    Can you try this:
    Code:
    SnoozeBlock config(usb, digital);

  3. #3
    Junior Member
    Join Date
    Feb 2019
    Posts
    12

    Snooze_TinyGPSPlus_Teensy 3.2 - problem reading gps on wake

    Quote Originally Posted by duff View Post
    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? I am pretty suremy laptop is accurate..same as iPhone and iPad. Any other suggestions..thanks

  4. #4
    Senior Member duff's Avatar
    Join Date
    Jan 2013
    Location
    Las Vegas
    Posts
    970
    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.

  5. #5
    Junior Member
    Join Date
    Feb 2019
    Posts
    12
    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.

  6. #6
    Senior Member duff's Avatar
    Join Date
    Jan 2013
    Location
    Las Vegas
    Posts
    970
    That time is from the gps module as far as I can see: "gps.time.minute()"

  7. #7
    Junior Member
    Join Date
    Feb 2019
    Posts
    12
    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 by AndyUK; 06-01-2019 at 09:25 PM. Reason: putting code in braces

  8. #8
    Junior Member
    Join Date
    Feb 2019
    Posts
    12
    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();
          }
        }
      }

  9. #9
    Senior Member duff's Avatar
    Join Date
    Jan 2013
    Location
    Las Vegas
    Posts
    970
    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?

  10. #10
    Junior Member
    Join Date
    Feb 2019
    Posts
    12
    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);
    }

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •