[FR] Idle sleep mode
Issue in-home use opens up the possibility that SS2K will be left plugged in for extended periods of time, broadcasting its availability over Bluetooth and maintaining connectivity.
Describe the solution you'd like timeout that disables wifi and bluetooth until the device is woken up by button press on the shifters... maybe the same approach that's used for reconnecting (ie, hold both buttons for 3s)
Describe alternatives you've considered pull the darn plug
Good idea, we can send ESP32 into Hibernation mode and wake up when a shifter is pressed. How should we calculate the timeout? Is it possible to detect that now data from Power Meter / Zwift / HR Belt are received? If this is possible adding a "LastReceiveTimestamp" to BLE Client / BLE Server and checking this timestamp in the main loop should work. If timeout expires, all task are killed and ESP32 is sent to hibernation mode. If possible step driver could also getting disabled.
After shifter interrupt, all getting enabled. https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/sleep_modes.html
Need to check if shifter interrupt is able to wake up ESP32 from hibernation.
I believe hardware interrupts are the preferred method for wakeups actually.
I'd say if no clients or servers are connected and no shifter has been pressed for 30 minutes, hibernate. We can already check clients with: https://github.com/doudar/SmartSpin2k/blob/d0d6a524ddd10927f569f89a7e77cc8793693ce7/src/BLE_Server.cpp#L548-L555
You could also check connected servers by implementing the following function:
int connectedServerCount() {
int _serverCount = 0;
for (i = 0; i < BLEDevice::getClientListSize; i++) {
if (BLEDevice::getClientByID(i)) { //nullptr check
if (BLEDevice::getClientByID(i)->isConnected()) {
_serverCount++;
}
}
}
return _serverCount();
}
On wakeup, I think it's probably best to run all of setup, but maybe it's not needed :man_shrugging:
Is this something you're interested in implementing Markus? I'm super busy with work for the next month.
Something to consider... I don't think heart rate monitors go to sleep on their own. At least, I think mine stays on until it times out due to lack of heart rate. The power meter and spin bike usually power down after inactivity though
Something to consider... I don't think heart rate monitors go to sleep on their own. At least, I think mine stays on until it times out due to lack of heart rate. The power meter and spin bike usually power down after inactivity though
Wouldn't that be considered inactivity on the part of either device though? (lack of heart rate == inactivity)
Good point! I fell into the whatabout trap of "what if the user leaves the HRM on for an extended period post-ride"
I've tested hibernation mode and got it working. But wake up is only working if a RTC Pin is used. RTC GPIOs are highligted in light orange in the picture below.
For the shifter Pin 18 + 19 is used. These pins are no RTC Pins.
Now we have to options:
- use RTC Pins for shifters
- use extra button for wake up

If you like to test it by your own:
- I've created a new branch "hibernation_mode-#331"
see main.cpp https://github.com/doudar/SmartSpin2k/blob/ff1c02d92f93bc81c9d6fe285fe907faa03f8e2b/src/Main.cpp#L419-L430
and index.html

also update HTTP_Server_Basic.cpp and added an Endpoint for hibernation request.
I think moving these pins is something we should target in the new pcb.
I propose adding another section to the platformIO.ini for pcb2 and then compiler if statements in settings.h for the pin labeling and hibernation modes.
We will probably do this anyway because there's a fair chance pcb 2.0 will incorporate a larger psram esp32.
Let me know what you're thinking for pin mapping so we can draw up a plan.
Tagging @alexquilty on the conversation as well.
Conditional compile is a good idea. Hibernation has also benefits for "old" boards only wake up is not working and you have to re power the board, but suspend mode will work if you forget to plug out the board.
For pin mapping I have no preferences any RTC Pin will work. If you like, I can implement hibernation mode now (including BLE traffic check) and the wake up function comes then with the new pcb.
Conditional compile is a good idea.
Hibernation has also benefits for "old" boards only wake up is not working and you have to re power the board, but suspend mode will work if you forget to plug out the board.
For pin mapping I have no preferences any RTC Pin will work.
If you like, I can implement hibernation mode now (including BLE traffic check) and the wake up function comes then with the new pcb.
Any chance you could do a periodic wakeup to scan for BLE and if one of the selected devices is available, do a full setup, if not sleep again?
If WiFi stays powered down, power consumption is very minimal.
I've added light sleep mode. In light sleep any gpio is able to wake up 😉.
BLE, ERG and HTTP is stopped while sleep mode is enabled.
https://github.com/doudar/SmartSpin2k/blob/042fa5a2f47ddad88acacc008de028da5b32baa2/src/Main.cpp#L425-L446 After wake up the whole setup and loop logic is called.
Also added new field in rtConfig. https://github.com/doudar/SmartSpin2k/blob/042fa5a2f47ddad88acacc008de028da5b32baa2/include/SmartSpin_parameters.h#L94-L95
to hold the last BLE connection timestamp. With every new BLE Client message, lastBLEPackateTimestamp is getting updated. Hope this is the right place to check for BLE messages 😐. https://github.com/doudar/SmartSpin2k/blob/042fa5a2f47ddad88acacc008de028da5b32baa2/src/BLE_Client.cpp#L40-L48
In the main loop, a check is made and if last BLE message is older then 30 Minutes, sleep mode is entered (L179-180). https://github.com/doudar/SmartSpin2k/blob/042fa5a2f47ddad88acacc008de028da5b32baa2/src/Main.cpp#L173-L182
Looks good!
@MarkusSchneider , do you think we should still move the shifter pins to an RTC pin in PCB version 2.0?
One of my concerns is the shifters are currently on the JTAG pins, so even if we don't use deep sleep, maybe we still should move them?
I've added light sleep mode. In light sleep any gpio is able to wake up 😉.
BLE, ERG and HTTP is stopped while sleep mode is enabled.
https://github.com/doudar/SmartSpin2k/blob/042fa5a2f47ddad88acacc008de028da5b32baa2/src/Main.cpp#L425-L446
After wake up the whole setup and loop logic is called. Also added new field in rtConfig.
https://github.com/doudar/SmartSpin2k/blob/042fa5a2f47ddad88acacc008de028da5b32baa2/include/SmartSpin_parameters.h#L94-L95
to hold the last BLE connection timestamp. With every new BLE Client message, lastBLEPackateTimestamp is getting updated. Hope this is the right place to check for BLE messages 😐.
https://github.com/doudar/SmartSpin2k/blob/042fa5a2f47ddad88acacc008de028da5b32baa2/src/BLE_Client.cpp#L40-L48
In the main loop, a check is made and if last BLE message is older then 30 Minutes, sleep mode is entered (L179-180).
https://github.com/doudar/SmartSpin2k/blob/042fa5a2f47ddad88acacc008de028da5b32baa2/src/Main.cpp#L173-L182
Your current tests only check for a remote server connected to our client. We have use cases where only a remote client is going to be connected to our server and those should be checked.
You should add a test for this by using this function:
https://github.com/doudar/SmartSpin2k/blob/d0d6a524ddd10927f569f89a7e77cc8793693ce7/src/BLE_Server.cpp#L548-L555
or by putting your existing rtconfig time stamps on
https://github.com/doudar/SmartSpin2k/blob/1f8d20299e34dc9c27d6b98c2bcb9d22a16e3918/src/BLE_Server.cpp#L621 and https://github.com/doudar/SmartSpin2k/blob/1f8d20299e34dc9c27d6b98c2bcb9d22a16e3918/src/BLE_Server.cpp#L354
Ok thx for point this out, I'll add the update of the timestamp also to the BLE-Server.
Yes, leaving JTAG Pins free will allow to use a JTAG Debugger for development. I tried it in the past and had to move the shifter GPIOs. With PCB 2.0 we can go with deep sleep and RTC GPIOs (to consume less power) for the old version light sleep will be ok I think. Main benefit is that BLE is disabled and advertising is stopped. I'll do a test tomorrow if all works well, I create a pull request 👍
Ok thx for point this out, I'll add the update of the timestamp also to the BLE-Server.
Yes, leaving JTAG Pins free will allow to use a JTAG Debugger for development. I tried it in the past and had to move the shifter GPIOs. With PCB 2.0 we can go with deep sleep and RTC GPIOs (to consume less power) for the old version light sleep will be ok I think. Main benefit is that BLE is disabled and advertising is stopped. I'll do a test tomorrow if all works well, I create a pull request 👍
Awesome!
I have a meeting in person tomorrow with the Purdue senior design project EE's that are going to be working on the PCB, so if you can think of anything else that should be done on the new PCB, please let me know. I'll also be sure to get you one of the new PCB's once we have working prototypes.
@MarkusSchneider , I'm just going through old issues and wonder if this is one we can tidy up and merge into develop?