RFM95W sleep() directly after send() often doesn't sleep radio
I've built a battery powered RFM95W LoRa sensor node which I intend to wake up every 4 hours or so and I modified a 3.3v Arduino Pro Mini by removing the LED and voltage regulator. Monitoring the sleep current draw I identified that the Arduino would always drop into the μA range, but the radio chip would often keep drawing around 5mA after calling
After swapping out hardware (no success) I tested out some different code variation and found that when calling
send()immediately followed by
sleep()the radio was often not going to sleep. I added a 1ms
wait()statement and now I'm getting consistent μA low power sleep.
I know this now, after a lot of head scratching, investigation, and sleeping on it. Yay. I wanted to at least post this here so that others could find it in a search and maybe find my workaround hack. Maybe someone with more experience than I have has a cleaner workaround or knows of a good way to fix this. I'd still need to do a lot of learning and maybe get an oscilloscope to really dig into the code and start debugging the actual communication between the radio chip and the Arduino to see whether the sleep command actually makes it to the radio chip.
send(voltageMsg.set(volts, 2)); // apparently after the send there needs to be a delay else the RFM95W can't go into µA sleep mode // and will draw 5mA in sleep. When working it draws 1.0µA. wait(1); sleep(SLEEP_DURATION_MILLIS);
lood29 last edited by
You may also play with the MY_SLEEP_TRANSPORT_RECONNECT_TIMEOUT_MS directive if your RFM95 modem setting are too slow/long air time/repeater parent...
OldSurferDude last edited by
@prawnpie This does not surprise me. I was losing data doing multiple sends in a row (node has multiple sensors). Putting a 500mS wait after each send() allowed the data to get through.
Also, 5mA for 1mS is not a significant draw on any battery (5mA * 1mS = 0.000002 mAh).
You could experiment with shorter wait times with
for (unsigned n = 1000;n>0;n--);
then keep lowering n until you find the threshold
And finally, assuming that the radio does have a flag to indicate that it is not ready to be put to sleep, it would be a real effort to put that into the libraries of all radios and the sleep command.
Waiting a milliSecond is actually the best solution and I am duly impressed you found it!
@lood29 Thanks for the idea. I'll play around with
MY_SLEEP_TRANSPORT_RECONNECT_TIMEOUT_MSand plan to report back whether it makes any difference.
@OldSurferDude I've run into a similar issue where I was sending data from the controller to an actuator node with mutliple relays and having commands get dropped when sent in rapid succession.
I agree that an extra millisecond of wake time every 4 hours will make a negligible difference on total power draw and I'm OK adding a wait now that I know that I need to do it.
I agree that it might not make sense to build this support in to MySensors unless we find the optimized time with your method and then... I don't know... add a hacky/naive solution of having the RFM95W sleep implementation block before sending the sleep command,... I don't know the MySensors architecture whether that's even feasible without breaking some rules.
My secondary point of posting was definitely just to add to the knowledge base in this forum so someone else trying to put a Lora radio to sleep would find this and save some time.