adafruit/Adafruit_GPS

Calling power states over I2C

Opened this issue · 7 comments

Using this library with the Adafruit Mini GPS PA1010D Module over I2C I found it as not possible to pull it out of Stanby. After reading the data sheet I realised a byte needs to be sent to the serial port nothing is said about I2C.
A suggested addition would be to add the " AlwaysLocate Mode(Advance Power Periodic Mode)" - $PMTK225,823 to the library. This is much simpler than pulling it in and out of Standby. Another suggestion would be the "Periodic mode".
Then it is possible to send the "Full Power Continuous Mode" -$PMTK225,0
2B to get it back to normal.

Hope this info is of use.

thanks - where is this text to update?

It's not clear if there is an actual issue here or if this is just a feature request / suggestion?

Using this library with the Adafruit Mini GPS PA1010D Module over I2C I found it as not possible to pull it out of Stanby.

This sounds like an issue. More details about how to reproduce the issue would help.

After reading the data sheet I realised a byte needs to be sent to the serial port nothing is said about I2C.

And this sounds like it was a solution? Is there code missing from the current library that needs to send extra configuration to the GPS module?

I think there's still an issue with waking a GPS unit on I2C. I'm using the Adafruit Mini GPS PA1010D with an Arduino Nano RP2040 Connect. When I call GPS.wakeup() the call hangs and never returns.

The test I'm using is based on the GPS_I2C_Parsing example code and adding the following at the top:

unsigned long on_off_timer;
bool gps_off = false;

And at the beginning of loop():

  unsigned long uptime = millis();

  if (uptime - on_off_timer > 10000) {
    on_off_timer = uptime;
    gps_off = !gps_off;

    if (gps_off) {
      Serial.print("\nTurning gps off... ");
      GPS.standby();
      Serial.println("done");
    }
    else {
      Serial.print("\nTurning gps on... ");
      GPS.wakeup();
      Serial.println("done");
    }
  }

The GPS unit runs fine to start and stops sending NEMA messages after the GPS.standby(), but when GPS.wakeup() is called, it never returns and never gets to the "done" output. On rebooting the board, the GPS unit is still non-responsive - a full power-cycle is required to reset the GPS unit.

I have the exact same issue using I2C the Wake Up call as you say just hangs and never returns. Is this an issue ?

Asking the GPS module manufacturer for clarification. The datasheet says this in section 1.9.2.1:

The host can then wake up the module from Standby mode to Full Power mode by sending any
byte to the serial port.

But it's not clear if "serial port" means only UART.

Recreated behavior using a QT PY M0 with GPS module attached via STEMMA connector.

Test Sketch:

#include <Adafruit_GPS.h>

Adafruit_GPS GPS(&Wire);

void setup() {
  Serial.begin(115200);
  while (!Serial);
  Serial.println("Adafruit I2C GPS library power mode test");

  GPS.begin(0x10);

  delay(500);

  Serial.println("Entering standby mode.");
  GPS.standby();
  
  delay(500);

  Serial.println("Waking up from standby.");
  GPS.wakeup();

  Serial.println("Done.");
}

void loop() {
}

Serial Monitor Output:

Adafruit I2C GPS library power mode test
Entering standby mode.
Waking up from standby.

(never prints "Done.")

Scope Traces
Zoomed out view:
image
first activity is device discovery when initing the i2cdevice, second activity is sending standyby command, last activity is stuck in a loop sending wake up command.

Zooming in on wake up command attempts:
image

The GPS module is NAKing right away, which is preventing the waitForSentence loop from exiting:

bool Adafruit_GPS::waitForSentence(const char *wait4me, uint8_t max,
bool usingInterrupts) {
uint8_t i = 0;
while (i < max) {
if (!usingInterrupts)
read();
if (newNMEAreceived()) {
char *nmea = lastNMEA();
i++;
if (strStartsWith(nmea, wait4me))
return true;
}
}
return false;
}

(it never increments i due to NAK)