GPS causes hanging on wake from SLEEP_MODE_DEEP

I’m trying to configure my Electron Asset Tracker 3G v2 to report its location at regular intervals and enter SLEEP_MODE_DEEP otherwise.

This works for the first few intervals, but soon the device hangs on wake: it’s unresponsive over serial, the LED is solid white, the GPS module stays on with blinking SAT FIX LED indicating a fix, and the device never goes back to sleep. Pushing the reset button breaks it out of this state, but it eventually happens again.

The problem happens with both the internal antenna and an active external one, but it occurs much faster with an external antenna (after 10-20 minutes vs. 8 hours). When I leave the GPS off, everything is fine: the device is always able to wake up, connect to the cell network, publish an event, and go back to sleep.

Here’s a simplified example that still causes the problem. I’m using AssetTrackerRK, but it happens with the official AssetTracker library as well. I’ve also tried adding delays in various places, which didn’t work.

#include <AssetTrackerRK.h>

SYSTEM_MODE(SEMI_AUTOMATIC);

AssetTracker t;
FuelGauge fuel;

void setup() {
    t.gpsOn();
    Particle.connect();
}

void loop() {
    t.updateGPS();

    if (t.gpsFix() || millis() > 120 * 1000) {
        if (t.gpsFix()) {
            Particle.publish("g", t.readLatLon(), PRIVATE, NO_ACK);
        }
        Particle.publish("b", String::format("%.0f", fuel.getSoC()), PRIVATE, NO_ACK);
        Particle.process();
        System.sleep(SLEEP_MODE_DEEP, 5 * 60);
    }

Has anyone seen this before or have suggestions for debugging? Thanks!

Hello,

Let me ping someone that might be able to help, @tylercpeacock are you able to assist?

Kyle

I think I have finally figured this out! I believe it’s a brownout caused by a current spike to the u-blox GPS receiver during signal acquisition. No one else has reported this, so the vulnerability to current spikes could be a hardware defect specific to my Electron.

Luckily, the u-blox receiver offers an option to limit peak current. Enabling this option seems to fix the problem.

There were three clues that led me to this explanation:

  1. During the hanging, the u-blox receiver stayed on as indicated by the SAT FIX LED. This meant the problem was occurring after I had turned on the receiver from application code, not during wake.
  2. I noticed the problem would occur less frequently when the Electron was plugged in to USB power (once every few days rather than every few hours). This suggested a power draw issue.
  3. The problem turned out to occur regardless of which sleep mode I used, and in fact even if the microcontroller never went to sleep at all.

The fix is to ask the u-blox receiver to limit peak current using the limitPeakCurr flag within the UBX-CFG-PM2 command (see the u-blox M8 Receiver Description, page 190). I use a UBX protocol library to send this command, but it should also work to use the following code after turning the receiver on:

uint8_t limitPeakCurr[] = {0xB5,0x62,0x06,0x3B,0x30,0x00,0x02,0x00,0x00,0x00,0x00,0x11,0x02,0x00,0xE8,0x03,0x00,0x00,0x10,0x27,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xA8,0x32};
Serial1.write(limitPeakCurr, sizeof(limitPeakCurr));

With this fix, my device has been running successfully for three days so far. I’ll post an update if the problem recurs.

4 Likes