-
Notifications
You must be signed in to change notification settings - Fork 389
To support PowerSaving for all ESP32-based repeaters and NRF52-based repeaters. #1353
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
base: dev
Are you sure you want to change the base?
To support PowerSaving for all ESP32-based repeaters and NRF52-based repeaters. #1353
Conversation
…es DIO0 to wakeup MCU instead of DIO1
fschrempf
left a comment
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.
@IoTThinks Thanks for your work! As I have already posted a solution for the sleep implementation for NRF52 in #1238 before, would you mind rebasing your work onto the latest version of this PR?
|
To fix the memory leaking for SoftwareTimer, to perform internal testing and to let the community to do beta test for NRF52-based repeaters. |
I've already done that work in #1238. There is no reason to reimplement my suggestions. Please, just use my branch and add your commits on top. |
|
Let me and some friends in busy-traffic areas test to use a simpler but more robust implementation without SuspendLoop, ResumeLoop and not touching setFlag for NRF52 repeaters. |
|
I have pushed the change to implement power saving for NRF52 to use System-Idle On instead. |
fschrempf
left a comment
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.
As you are somehow seeking to provide an alternative solution for #1238, can you at least mention in the description how your solution works and what benefits it has over the one in my PR? Thanks!
Also, can you please try to separate your changes logically into multiple commits and not chronologically stack each improvement as new commit on top of the previous one? As I mentioned before this is what git rebase --interactive and git push --force are made for.
I know that a lot of people do it like this, but this is not how git is intended to be used and it makes it impossible to have useful history in the end. And it leads you to copy code from my branch discarding the authorship (which can be seen as somewhat disrespectful among developers) instead of just doing git cherry-pick from my branch.
This is also something I wish the maintainers would take more into account when reviewing/merging PRs.
7b0546a to
c8e7727
Compare
c8e7727 to
67a4398
Compare
|
I have put in changes to implement light sleep for ESP32 without changing setFlag at all. |
To put back missing code board->onAfterTransmit();
9879bd4 to
f988eb3
Compare
fschrempf
left a comment
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 see you did a force-push, but the commits are still not separated properly. If you need help doing it, feel free to ask.
One more thing: You always begin your comments end commit subjects with "To ...". This doesn't really makes sense. Just leave out the "to" and state your changes in an imperative way.
| -D WIFI_DEBUG_LOGGING=1 | ||
| -D WIFI_SSID='"myssid"' | ||
| -D WIFI_PWD='"mypwd"' | ||
| -D OFFLINE_QUEUE_SIZE=256 |
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.
This shouldn't be removed, right?
| -D WIFI_SSID='"ssid"' | ||
| -D WIFI_PWD='"password"' | ||
| -D WIFI_DEBUG_LOGGING=1 | ||
| -D OFFLINE_QUEUE_SIZE=256 |
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.
This shouldn't be removed, right?
| } | ||
| // To configure GPIO wakeup | ||
| esp_sleep_enable_gpio_wakeup(); | ||
| gpio_wakeup_enable((gpio_num_t) wakeupPin, GPIO_INTR_HIGH_LEVEL); // To wake up when receiving a LoRa packet |
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.
Remove the gpio_num_t cast. It's not needed.
| #if defined(ESP32) && defined(RADIO_SX1276) && defined(P_LORA_DIO_0) // SX1276 | ||
| gpio_set_intr_type((gpio_num_t)P_LORA_DIO_0, GPIO_INTR_POSEDGE); | ||
| #elif defined(ESP32) && defined(P_LORA_DIO_1) // SX1262 | ||
| gpio_set_intr_type((gpio_num_t)P_LORA_DIO_1, GPIO_INTR_POSEDGE); | ||
| #endif |
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.
This whole block can be replaced with a single line
| #if defined(ESP32) && defined(RADIO_SX1276) && defined(P_LORA_DIO_0) // SX1276 | |
| gpio_set_intr_type((gpio_num_t)P_LORA_DIO_0, GPIO_INTR_POSEDGE); | |
| #elif defined(ESP32) && defined(P_LORA_DIO_1) // SX1262 | |
| gpio_set_intr_type((gpio_num_t)P_LORA_DIO_1, GPIO_INTR_POSEDGE); | |
| #endif | |
| gpio_set_intr_type(wakeupPin, GPIO_INTR_POSEDGE); |
| gpio_set_intr_type((gpio_num_t)P_LORA_DIO_1, GPIO_INTR_POSEDGE); | ||
| #endif | ||
|
|
||
| // To disable CPU interrupt servicing |
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.
| // To disable CPU interrupt servicing | |
| // To enable CPU interrupt servicing |
| #if defined(NRF52_PLATFORM) | ||
| #include "NRF52Board.h" | ||
|
|
||
| #include "nrf_sdm.h" |
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 don't think we need this, do we?
| uint32_t startTime = millis(); | ||
|
|
||
| // To wake up when a LoRa packet comes or sleep timeout. Safe to 49-day overflow | ||
| while (digitalRead(P_LORA_DIO_1) == LOW && (millis() - startTime < secs*1000)) { |
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.
What about the boards with DIO0 interrupt instead of DIO1? The digitalRead(P_LORA_DIO_1) would be incorrect in this case, right?
As mentioned above we could use a getIrqPin() function to retrieve the correct pin.
I did force-push to fix some simple missing codes. And clean PRs are usually approved faster. :D
Well, if you don't like then I will not include the "To..." |
I know, thanks. If FOSS developers work on the same topic and take over work from each other they usually credit by taking the commits with the original authorship.
Ok, good idea. I think we can do it like this. |
Ok, maybe. To me it sounds awkward and I've never seen this style elsewhere. But maybe that's just me... |
Ok, do as you like. |
|
@fschrempf Thanks a lot for your comprehensive reviews. Since, the code for lightsleep for esp32 and NRF52 have changed. Then I will make a final clean push. |
|
@IoTThinks , thanks for the work here :) I'll test this out on my RAK repeater. I was thinking if it would be good to show how much the repeater has slept on the repeater stats to get some insight. Could very well be added in some other PR of course. |

Hi all,
This PR is to add PowerSaving for all ESP32-based repeaters and NRF52-based repeaters including 4 boards with old SX1276.
Credits:
(12 Jan 2026) In latest approach, I use hardware and software events instead of SuspendLoop and ResumeLoop to avoid deadlock issue.
SuspendLoopandResumeLoopfrom Mr. Fschrempf and the check of HIGH-level DIO1 to prevent deadlock from Mr. 4np at NRF52 Repeater Powersaving. Thanks a lot.Known issue:
Testing:
I have tested the change with main branch and achieve 10mA for ESP32-based repeaters and 6mA for NRF52-based repeaters.
Some kind friends have tested boards with SX1276 working.
After the merge to dev, I have compiled 29 boards and confirm no compilation error. I have tested the merged code and it worked for Heltec v3, v4 and RAK4631.
Heltec v3 and RAK 4631 in PowerSaving mode

This is a RAK4631 repeater with PowerSaving in action: Sleep at 6mA, wakeup when a LoRa packet comes, process it, wake up for 5s and go to sleep again.
Power.Saving.for.RAK4631.in.action.mp4