-
Notifications
You must be signed in to change notification settings - Fork 514
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Electron resumes session after sleep #845
Conversation
@m-mcgowan just a heads up that I added the 0.5.x milestone to this PR. Very important for sleepy code with low data usage on resume. |
How about we remove the conditional compilation and instead wire this through to a flag, so that the behavior is controllable by the caller. We could have a new flag This could also be used on the deep sleep mode too. So the sleep API turns off the radio by default (keeping consistency with other platforms) and allows the user to optionally maintain the network connection. Currently deep sleep already doesn't turn off the radio - I believe this is an oversight. I feel it's best to make the APIs consistent (so that 0.5.0 does turn off the radio by default) since that's the least surprising outcome. The SLEEP_NETWORK_UP flag is there for those cases where the caller wants to maintain the cellular connection. |
In a meeting with me, @technobly and @avtolstoy, we decided that there would be an additional optional flag as the last parameter to deep sleep, and stop sleep modes. The flags are:
e.g.
The default is SLEEP_NETWORK_OFF so that sleep shuts down the network as part of sleep. The flags will be strongly typed to remove the chance of confusion in mixing with other integer-typed parameters. This is intended as a stop-gap solution. The sleep mode API will be overhauled for a 1.0 release. |
4c388c8
to
6b0f9fe
Compare
@technobly - please review these changes when you get chance. (I've not tested them - going to have a bout of coding then will test.) Any thoughts how we can automate tests for this new functionality? |
@m-mcgowan we should start with simply automating existing sleep tests. One way to test sleep mode reliably is to use a serial to usb adapter on Serial1 for debugging output. This way the serial stream will stay open as the device goes to sleep and/or resets after waking from sleep. Typically the USB serial will disconnect on sleep Stop and Standby. A simple GPIO could work for this as well, but not nearly as accurate as sending and parsing a message that says "GOING TO SLEEP", "WAKING UP" ... and after several iterations "FINISHED" ... or even "S", "W" and "F" from the test device. Then timing from the test rig to ensure these messages are occurring at predefined times. One step further would be to command the test device to sleep at different times, 5, 10, 20, 30 seconds and with different sleep APIs and log / measure all appropriate responses. Beyond that we need to put a CI on the interrupts that wake Sleep stop mode as well. Then to test the new API -> NETWORK_STANDBY, for the Electron we would expect low data usage in sleep Stop and fast connection times, both fairly straight forward to measure. We could monitor current usage as well when asleep, as we'd expect the modem to be on. |
@technobly Please review and merge. |
@@ -106,8 +118,11 @@ void system_sleep(Spark_Sleep_TypeDef sleepMode, long seconds, uint32_t param, v | |||
|
|||
void system_sleep_pin(uint16_t wakeUpPin, uint16_t edgeTriggerMode, long seconds, uint32_t param, void* reserved) | |||
{ | |||
network_suspend(); | |||
bool network_sleep = (param & 1)==0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this just use network_sleep_flag(param)
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, I had planned to do this as part of the refactoring while writing the code - seems that fell through the cracks. Good catch!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll push that change.
* after System.sleep(pin, trigger, seconds) or System.sleep(pin, trigger) electron will enter STOP mode, modem will remain on and powered in this mode (Photon/P1 will still have the Wi-Fi module powered off). The reason for this is to maintain an active PDP context to keep our current DTLS session happy. Upon waking, the system will immediately be able to Particle.publish() with the bare minimum amount of data transferred (TX/RX). Current consumption in this mode is ~4mA for the most of the idle time with small peaks when the modem is maintaining a cellular network connection. Current consumption should be further reduced when Low Power mode is enabled.
0f87b4e
to
5220382
Compare
I reviewed the code. The changes look good. I rebased to the latest develop so it's mergeable but I don't have enough background info on what behaviour this should have to test it. I'm assigning it back to you @technobly. |
Electron resumes session after sleep
oops..trigger finger |
Tested these 6 cases successfully on the Electron: Only one sleep type will not require a full handshake. Two others will require a full handshake and then restore and resume sessions thereafter. Deep sleep always requires full handshake even though it seems like it should be able to restore and resume as well. In deep sleep, D7 LED is off spinWait(6000); is required for this PR, will not be required for future use. #include "application.h"
SYSTEM_MODE(SEMI_AUTOMATIC);
// ALL_LEVEL, TRACE_LEVEL, DEBUG_LEVEL, INFO_LEVEL, WARN_LEVEL, ERROR_LEVEL, PANIC_LEVEL, NO_LOG_LEVEL
Serial1DebugOutput debugOutput(9600, ALL_LEVEL);
retained int count = 0;
STARTUP(System.enableFeature(FEATURE_RETAINED_MEMORY));
void spinWait(uint32_t timeout) {
uint32_t start = millis();
while (millis() - start < timeout) Particle.process();
}
void setup() {
pinMode(D1, INPUT_PULLDOWN);
pinMode(D7, OUTPUT);
Particle.connect();
DEBUG_D("\r\n[ Particle.connect ]\r\n\r\n");
waitUntil(Particle.connected);
DEBUG_D("\r\n[ Particle.connected ]\r\n\r\n");
}
void loop() {
digitalWrite(D7, LOW);
DEBUG_D("\r\n[ Waking up and publishing once! ]\r\n\r\n");
Particle.publish("b", String(++count));
spinWait(6000);
DEBUG_D("\r\n[ Going to sleep ]\r\n\r\n");
digitalWrite(D7, HIGH);
// These all will restore and resume sessions after the first full handshake (fairly low data usage)
//
// System.sleep(D1, RISING, 30); // SLEEP_NETWORK_OFF is default
// System.sleep(D1, RISING, 30, SLEEP_NETWORK_OFF); // Turns off network
// These all require a full handshake (higher data usage)
//
// System.sleep(SLEEP_MODE_DEEP, 30); // SLEEP_NETWORK_OFF is default
// System.sleep(SLEEP_MODE_DEEP, 30, SLEEP_NETWORK_STANDBY); // Does not turn off network
// System.sleep(SLEEP_MODE_DEEP, 30, SLEEP_NETWORK_OFF); // Turns off network
// This is the only one that doesn't require another
// session resume or handshake upon waking (lowest data usage)
//
System.sleep(D1, RISING, 30, SLEEP_NETWORK_STANDBY); // Does not turn off network
} |
After System.sleep(pin, trigger, seconds) or System.sleep(pin, trigger) electron will enter STOP mode, modem will remain on and powered in this mode (Photon/P1 will still have the Wi-Fi module powered off). The reason for this is to maintain an active PDP context to keep our current DTLS session happy. Upon waking, the system will immediately be able to Particle.publish() with the bare minimum amount of data transferred (TX/RX). Current consumption in this mode is ~4mA for the most of the idle time with small peaks when the modem is maintaining a cellular network connection. Current consumption should be further reduced when Low Power mode is enabled. (NOTE: Please measure and test these current readings yourself before deploying a product based on them, this is preliminary info)
Simple change, big impact :)