Preliminary 0.9.0 Boron LTE current consumption in sleep modes measurements


Hard to tell without knowing what your code looks like.


Link to my code is here.
Before we had sleep, it ran reliably for weeks using 10-min delays. Since upgrading to 0.9.0 and implementing sleep, data uploads are very sporadic. Sometimes it will run fine for hours, or even a day or two, while only missing odd transmits. Eventually it just fails to wake up until manually reset.
Any help appreciated!


I should mention that I’m using the particle sim for now, but plan to port to a 3rd-party sim soon. Some functions (e.g. the SMS function) are for the 3rd party sim.


After looking at your code I’m slightly surprised that your code works at all
AFAICT this issue is still open

Hence your code should actually need a Cellular.on() (and for safe measures also Cellular.connect()) call in setup(). Even if that issue doesn’t apply to Boron or was already fixed it never hurts to call the intermediate connection steps.

However, even if that issue was fixed, since you are calling before System.sleep(A4, RISING, 300); you need to reestablish the connection after you wake. Unlike System.sleep(SLEEP_MODE_DEEP, 300); your sleep command won’t cause the device to reset and re-run setup() after waking up.

You should also setup your Particle.variable() list before or at least immediately after the Particle.connect() call. Doing it after this

    uint32_t ms = millis();
    while(millis()-ms < 2000) Particle.process(); // checks the cloud for incoming messages for 2 sec
    if (System.updatesPending()) //if there is an update waiting
        ms = millis();
        while(millis()-ms < 60000) Particle.process(); //allow 60 sec to perform the firmware update
        Serial.println("Firmware has been updated!");

may not successfully register the variables with the cloud.


Thanks Scruffr, that’s GOLD! I’ll be implementing those changes today! Appreciate your time on this.


I can’t get it to send any data now. I think I’m missing something from my updated code.
The Boron seems to wake up at the right intervals and within 20s or so breaths cyan (indicating connected to the cloud), but when I look in my Events log, nothing is posted. No data is received in ThingSpeak either. Could I please get some more help?
Debugging isn’t helped by the fact that I’m having trouble finding a suitable serial monitor. Particle Dev (which I used for the Electron) doesn’t support the Boron, Arduino serial monitor doesn’t work for me, Realterm does work, but only sometimes. Can anyone suggest a good serial monitor for mesh devices?


You can use particle serial monitor --follow which will automatically reconnect when the device comes back online.

Since you have this part in your loop()

        keepAlive_set = true;

you may want to reset keepAlive_set to false after your call before sleep.

You should also guard your Particle.publish() calls with a if (Particle.connected()) check and depending on your needs prevent going to sleep if the publishes didn’t happen.

But most importantly I have to repeat myself …

… since your updated code still doesn’t.
With System.sleep(A4, RISING, 300); your code will just start running the next instruction after the sleep call (=re-run loop() but not setup()).


Aahh…thanks for putting me straight on this. Indeed, I can see now that I have a serial monitor (thanks!) that the program only runs from the top of loop after wake-up, not from the top of set-up. Clearly I didn’t get that. Thanks for your patience and help!


Not quite. As I said, it continues after the System.sleep() call. In your case it appears to be the same, but it isn’t. For example if you had some instructions following the System.sleep() call these would be executed which, when starting from “top of loop” wouldn’t be the case.
Also since there are some actions between iterations of loop() which you may not be aware of, they are also executed before returning to the top of loop()

Update: The follwoing only works with Gen1&2 devices - Gen3 has no timed wake from deep sleep
If you want a sleep mode that also “re-runs” setup() then you could use System.sleep(SLEEP_MODE_DEEP, 300) but would need to use WKP/A7 as wake-pin.


Gotcha, thanks for clarifying. Out of interest, are the cellular and particle connection steps (Cellular.on(), Cellular.connect() and Particle.connect()) blocking calls? If not, should I use delays after each?
Also, to be clear, if you want to run setup on a regular basis (e.g. to check for OTA firmware updates), you need an external device to toggle WKP/A7 or the EN pin? There is no way of doing this by code on the Boron?


I could be wrong, but it’s my understanding that this depends on your combination of System Mode and System Threading.

You could call a new function directly after your System.sleep(A4, RISING, 300), since that’s where the Boron will be in the Code when it wakes up after 300 seconds.
It wont be Setup(), but it could perform similar duties I suppose.


This works great, but why? There is nothing else referencing A4 in my code AND nothing externally interacting with the pin.


I don’t quite get this question

Why what? You have got that command in your code, so what’s the confusion?

If you don’t need a wake pin you can pass PIN_INVALID (currently only defined for Gen3 devices - no idea why tho’ :flushed:) or -1 instead of A4 (or a bit more obscure System.sleep({}, {}, 300)).


There’s nothing raising A4, so I guess the statement as coded means “wake on A4 rising OR when the timer pops”. By contrast I tested SLEEP_MODE_DEEP which really does wake on rising D8.


re: serial monitor: I like TeraTerm (Windows only). It persists through resets just like the CLI one, and unlike the CLI one it’s bidirectional so you can send keystrokes to the device.


Good suggestion! And I and use the CLI for uploads without having to change to serial monitor mode.


I’m seeing 1,220 µA (1.22 mA) @ 4.01V with System.sleep( {}, {}, 30); for Boron LTE on 0.9.0, when I need to wake up from a timer, Verses a pin as required by SLEEP_MODE_DEEP

The only connection to the boron is the Li-Po @ 4.01 V.
Current measured w/ µCurrent GOLD inline on negative Li-Po conductor.

My Boron LTE Sleeping Results, 0.9.0, Li-Po only, as of 03-14-2019:

4.9 mW if you need to wake after elapsed time (not a pin), System.sleep( {}, {}, 30)
2.9 mW if you can wake from WKP/A7 Pin [Edit: D8 Pin ] , System.sleep(SLEEP_MODE_DEEP)
0.3 mW if you Shutdown Boron with EN Pin, requires external circuit such as TPL5111

And for the folks that prefer mA for a 3.7V “Nominal” Rated Li-Po :

1.32 mA avg if you need to wake after elapsed time (not a pin), System.sleep( {}, {}, 30)
0.78 mA avg if you can wake from WKP/A7 Pin [Edit: D8 Pin ]  , System.sleep(SLEEP_MODE_DEEP)
0.08 mA avg if you Shutdown Boron with EN Pin, requires external circuit such as TPL5111

(converted using mW & the Average Voltage of 3.7 V over the Li-Po discharge cycle)


May I suggest that folks post their test code and hardware configurations so that testing conditions can be duplicated by others. :smiley:


@Rftop Thanks for the awesome work! I am a little confused though. Boron doesn’t have a WKP/A7 Pin so which pin are you using?
Does anyone have access to a scope? I would be interested to know the wakeup times between all three sleep modes. timed vs pin wakeup vs EN pin.

I’m trying to build a datalogger myself and need years of battery so every squeaky joule counts!


Good Catch…its D8

Per the Boron docs:
The Gen 3 devices (Argon, Boron, Xenon) can only wake from SLEEP_MODE_DEEP by rising D8. 
It's not possible to exit SLEEP_MODE_DEEP based on time because the clock does not run in 
standby sleep mode on the nRF52.