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 Cellular.off()
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()
{
Particle.keepAlive(5*60);
keepAlive_set = true;
}
you may want to reset keepAlive_set
to false
after your Cellular.off()
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' ) 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.
@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.