Conserving power with remote sleep / wakeup

I’m using the Electron with Asset Tracker v2, and am currently having a lot of success with the AssetTrackerRK library. I am broadcasting GPS coordinates at a regular interval in an environment with water, so the device is screwed into the waterproof case while in use. I would like to use POST functions from a web app to facilitate power saving functions when the operator is not actively using the GPS broadcast throughout the day (i.e.: let the operator tell the device when to broadcast, and save power when it’s not needed). The battery would be recharged at the end of the day. Based on other forum topics, I understand that none of the sleep modes will work because the device is not awake to listen for a function call.

Here are the ideas I’ve come up with after reading lots of forum posts:

  1. Use a function to start/stop publishing events (will this save power?)
  2. Turn on/off the GPS module only (will this save power?)
  3. An Idle mode is referenced in @rickkas7’s article on sleep modes, but can’t find documentation on it…
  4. Use sleep mode with a wakeup interval (say… 10 minutes), if a POST function call has not set a variable in the meantime then go back to sleep (and set operator expectations that there could be up to a 10 minute lag for the device to wake up)

Is there a smarter way to accomplish this?

For the GPS, there are two things you can do:

  1. You can actually turn the GPS off. Within a day and still powered by the Electron LiPo it will do a warm start but it will still take a few seconds to get a fix.
  2. You can use a GPS sleep mode to reduce power consumption. The AssetTracker and AssetTrackerRK libraries do not support this, but the u-blox M8 does.

However, by far the largest user of power the the STM32F205 processor, at least when you're not actively transmitting cellular data.

You can use stop mode sleep (pin + time) along SLEEP_NETWORK_STANDBY so the cellular modem is still on, with the Wake on RI feature, and the processor will wake up on a Particle function call from the cloud.

This only works on the Electron and E Series (Gen 2) on 2G/3G devices. It does not work on Gen 2 LTE devices. It does not currently work on Gen 3 devices (Argon/Boron/Xenon) though it probably could with a change within Device OS.

2 Likes

This was exactly what I needed and it worked on the first try. I am powering off the GPS and using SLEEP_NETWORK_STANDBY for sleep mode, then using a function call to wake and turning the GPS back on. I plan to incorporate another function to change the sleep time from the UI. I really struggled to wrap my head around this and it turned out to be pretty simple, so here’s all the components of my code in case it helps anyone else.

Setup (using AssetTrackerRK) and my savePower function

void setup() {

    Particle.connect();
    Particle.function("savePower", savePower);
    
    Serial.begin();
    pinMode(D6, OUTPUT);
    digitalWrite(D6, LOW);

    t.gpsOn();
    t.startThreadedMode();
    startFix = millis();
    gettingFix = true;
    t.antennaExternal();
}
int savePower(String command) { 
    
    if (command == "sleep") {
        digitalWrite(D6, HIGH);
        Cellular.command("AT+URING=1\r\n");
        delay(1000);
        System.sleep(RI_UC, RISING, 120, SLEEP_NETWORK_STANDBY);
    }
    else if (command == "wake") {
        digitalWrite(D6, LOW);
        startFix = millis();
        gettingFix = true;
        Cellular.command("AT+URING=0\r\n");
    }
    else {
        return 0;
    }
    return 1;
}

My javascript being called from the web UI thanks to the awesome tutorial from @bko

function savePower(command) {
  var requestURL = "https://api.spark.io/v1/devices/" + deviceID + "/savePower/";
  $.post( requestURL, { params: command, access_token: accessToken });
}

Thank you @rickkas7, you’re a lifesaver!

1 Like