What LMIC state must be preserved during sleep mode?

Is this solution still state-of-the-art, using it with MCCI LMIC? Or is there a better piece of code for the task of storing/restoring LMIC state while sleeping on ESP32?

/cc @grazy

In V3 OTAA is the preferred method to join LoRaWAN network.
It is now a good opportunity to switch my devices from ABP to OTAA.
That’s why I would like to know what is required to restore a session after power down the device.
In the end, was there a solution for MCCI LMIC and, for example, an ATmega328P?

MCCI LMIC (and the older classic) show the keys returned when a join request is completed, those need preserving along with the frame count.

It is quite rare for anyone to power down their nodes - particularly on the lightweight AVRs which don’t consume much current at all in sleep mode - so I’m not aware of any implementations but it’s easy enough to code using the built-in flash.

You only need to store the keys each time you get a join accept event - but the frame counter will need storing before power down.

You need to store a bit more, channel definitions provided in the join accept come to mind, RX1 offset, ADR results (power and data rate), DevNonces used for join. There is probably more

It would be easier to just use a incrementing DevNonce and only save that value and rejoin on reset. Be aware that limits the number of resets to just 65535 times before you need to re-add the device in TTN to generate a fresh set of ‘credentials’.

Thanks for the answers but it is hard to follow the best practices guidelines which says, for example:

“A device should keep the result of an activation in permanent storage
if the device is expected to be power-cycled during its lifetime.”

when the required information is not available or difficult to obtain to implement them.
For a “normal” user, this makes creating a device a trial and error process.
There should be a simple guide where it is described what to save, as always it doesn’t seem easy.

I agree that good and complete documentation with clear steps and practical guidance for this is still missing.

If that would be available with clear working examples (if even in pseudo code) it would be much easier to create fully compliant devices.

Why isn’t something like that still not available after many years? Conlicting commercial interests?

“Normal” users seem to enjoy that sort of thing.

The consensus is that a small device is going to be on all the time, even if it’s in deep sleep, so the code to save the settings is of academic interest. The ESP32 does have code for that because it’s version of deep sleep doesn’t include power to memory.

The only time someone wants to turn off the element that has the settings in is when they have something else that is controlling time - which again is a bit redundant given the very low current levels of many of the appropriate MCU’s in deep sleep mode. In fact it’s got to a point where you can tell if you have succeeded because either your multimeter shows some current draw or it appears to be off - as 0.7”A is usually a bit too low for the average meter to accurately measure.

Even if the device is always switched on, the battery has to be replaced.
After inserting new batteries, the device have lost its settings and start a new session.
This is probably how most otaa devices work.

The idea was a sketch that works with adjustments for all of my devices.
For example there could be a button that force the device to save its
settings and after the batteries have been replaced the old session will continue.

It is complete expected that there will be rejoins if you do a battery change.

It’s not acceptable and has technical issues if you rejoin too frequently.

What is the expected battery life of your devices - if it’s daily, then you have other problems, if it’s a few months or more, concentrate on other aspects of your project.

As I said above, there is a reason you can’t find clear information on saving session info with LMIC, that’s because most people using it have devices that run for months or years, so don’t consider saving session data worth the effort.

You are right, keep the code simple is still the best way.

@bluejedi

MCUs like ESP8266 and ESP32 do not preserve RAM in sleep mode
Waking up from sleep on these MCUs is similar to a reboot.

ESP32 RTCRam , preserved during deepsleep, is located in SRAM , not in Flash like NVS or emulated EEPROM.
Waking from sleep is a special boot with preserved data available in 8kB RTCRa.
cf Data Sheet 3.1.2
So RTCRam is good for what you wnat to do

Useful suggestion as alternative for storing in non-volatile storage like flash.
However, the LMIC library keeps its state in normal RAM so the state still needs to be saved to RTCRAM before deepsleep and restored after wakeup.

According to (recent) LoRaWAN specs certain parameters (e.g. devnonce) should even be stored in NV storage that can survive power cycles.

I found a useful and working code snippet for this here. Although i did not yet analyze which parameters of LMIC need to be stored (volatile or non-volatile), i can state that the approach to save and reload the whole LMIC struct between sleep cycles seems to work stable.

On esp32 arduino framework i still did not find a solution to advance the time base millis() after deep sleep of esp32, while this should be done for the LMIC stack, as far as i understand it. It seems to work without, but i am not sure if this can cause side effects, esp. after longer sleep times (days, months, 
).

5 Likes