How to adjust or cancel the LMIC libraries duty cycle check?

I looked at loramac-node, the code is almost impenetrable, clearly written for experts only.

I found this thread in here;

https://www.thethingsnetwork.org/forum/t/deep-sleep-and-otaa-m328p-lmic/27199/12

But code example does not exist anymore.

The function mentioned in MCCI_LMIC is;

LMIC_getSessionKeys() which is this;

LMIC_getSessionKeys(&netid, &devaddr, nwkKey, artKey);

The LMIC version I have used so far has access to these, printed out at join;

LMIC.netid
LMIC.devaddr
LMIC.artKey
LMIC.nwkKey

Presumably stored in RAM, so you might think its not too difficult to save them to FRAM and read back, I have done a library that read\writes the various variable types and arrays to a FRAM.

However, I suspect that storing the above in FRAM is only a part of the problem, the library may well have status flags and other counters that need to be saved ?

1 Like

This looks intersting;

"After an OTAA Join has finished, your node has the very same details youā€™d have for an ABP device. So: store the DevAddr and the secret session keys NwkSKey and AppSKey, and keep track of both frame counters. After deep sleep, configure your node as an ABP node using LMIC_setSession(ā€¦), and set the frame counters to their last stored values, using LMIC.seqnoUp = ā€¦ and LMIC.seqnoDn = ā€¦

For LMiC, these session details have different names (which originate from the early days where LoRaWAN was still called LoRaMAC). The documentation shows:

2.5.4 void LMIC_setSession (u4_t netid, devaddr_t devaddr, u1_t nwkKey, u1_t* artKey)*

Set static session parameters. Instead of dynamically establishing a session by joining the network, precomputed session parameters can be provided. To resume a session with precomputed parameters, the frame sequence counters (LMIC.seqnoUp and LMIC.seqnoDn) must be restored to their latest values."

Does that sound feasible ?

Cheeky but trueā€¦.I can craft great solutions and systems/architectures and ideasā€¦ā€¦ I just leave it to/need people like you to actually code them - my days or writing microcode (yep!), registry settings, assembly language or maybe the odd C, Basic, or Fortran! programme seems along time agoā€¦.Ok might still copy/edit/pasta a bit of C, C+ or even Python or play with Arduino stuffā€¦. But hard core softie skills? This dogs too old :wink:

Anyone can write impenetrable code, it takes an expert to write understandable & maintainable code.

By the power of GitHub commits:

Looking at the repro history it seems that @bertrik, like me, just went with a new join on restart of device which is why the code appears to have been removed, because it was.

There are some other commits that look quite tasty along the way - like saving the ADR value. May be worth picking through it all: Commits Ā· bertrik/LoraWanPmSensor Ā· GitHub

It does, it certainly resonates with prior discussions.

Very much so. You need to store the frequencies being used as MAC commands can change them, the transmission power and data rate, the frame counters (up- and downlink) and a whole lot more. Loramac-node has a couple of structures with all the information that requires saving and if I recall correctly that amounts to hundreds of bytes being saved.

If you are using a supported MCU and radio combination the actual code you need to change is relatively small. However even then it takes some time to get you head around it.

So does the pseudo ABP approach sound feasible ?

I understand that if the processor does not retain memory during deep sleep, such as with an ESP32, then a lot of stuff needs to be recovered at each wakeup.

But that is not the situation here, a watchdog recovery should not need to be used that often, its a just in case. The intention is not for a watchdog to be used to cover up a problem elsewhere.

I suspect that some OTAA nodes may already be powered on\off perhaps more often than is ideal, and they dont recover keys, does that cause significant issues ?

You suspect correctly. The main downside to a rebooting node is that the join accept has to be transmitted. So if the watch dog reboots a device once in a blue moon, thatā€™s not a big deal. Bit hard to say where the cut-off point would be for it to become problematic - technically under the FUP that would be 10 times a day ā€¦

Too often/too many times and you start to run out of Dev Nonce countā€¦. May take time to join depending on spec/mechanism the more they get used, also when Dev Nonce pool exhausted only solution is delete device and re register to start new poolā€¦.

OK, so if you have FRAM you could store it on first join and then recover it from FRAM on a watchdog reset ?

Yes, if you have any form of memory backup, you can restore the join accept credentials plus the various counters and carry on from where it was before the crash.

FWIW, the LoRa-E5 module running the LoRaMac-node STM32 Cube WL 1.2 with NVM can be run as AT commands, so it will do it all for you.

I have tried a coupleof the E5s, and whilst I dont recall the exact details of how it happened both are bricked and I cannot recover them.

I can imagine, Rising HF chose not to put the BOOT0 pin on to the outside so we canā€™t get to the ST boot loader for de-bricking via that route. Iā€™ve got in a pickle a couple of times and had to use many fingers & STM32CubeProgrammer to retrieve a module - but not often enough to end up with notes.

The LoRa-E5 does look attractive, from the spec sheets, but the device is not what is seems. Make an error in programming and you might well be stuffed. Perhaps the manufacturer should post warnings about it, as in be careful how you program this device, you might implement a self destruct mechanism.

Well, I have managed to save the OTAA session state to FRAM, and a sketch that imposes what is saved in FRAM as a session after reset does appear to work, the credentails are accepted ant the node keeps transmitting payloads.

However, the original sketch starts out at SF12 and the ADP quickly brings that down to SF8, then SF7, in about 3 transmissions. But with the sketch that recovers the session details from FRAM, whilst the re-newed transmissions start at SF12, the node does not appear to accept from the Gateway the downlinks to change down SF as you would expect with ADP.

The node does carry on transmitting at SF12 and the FUP code increases the sleep period appropriatly. I realise I could save the session SF in use and recover it, but why does ADP not appear to be working ?

I havenā€™t done this YET - and as I have a few hundred as one of the only realistic items available in the supply chain, Iā€™ll be careful - they are a bugg3r to get off once they are on a board.

And to add to not having Boot0 actually available, although Seeed have labeled an input as Boot0 (itā€™s for getting in to their updater as it comes from them), there isnā€™t a switch between LP & HP antenna outputs so itā€™s always on HP so in the EU we burn about 30-40mA more than we need on a Tx. Thatā€™s relatively inconsequential over the lifecycle of the battery - but it probably makes the difference between 3/4 years and 4/5 years.

RAK did the same with their STM32WL module but Iā€™m told they have resolved it for their SIP.

Saving & restoring the current value should help:

That change does not appear to work, LMIC.dn2Dr starts anew at 3 = SF9BW125, and just stays there.

The change to save the OTAA session stuff to FRAM works well enough and at least when ā€˜testingā€™ you dont have to re-join every time you re-program the node.

On reset and recovery of the OTAA session, the node starts up at SF12 and the Gateway does send downlinks, but either the node is ignoring them or not acting on them.

Easy enough to set the SF to the last used on recovery of the session, but not good that the node appears to be ignoring the downlinks.

Do you save the downlink counter? If not your node will be ignoring the downlinks.

LMIC.seqnoUp and LMIC.seqnoDn are saved and restored.

Forcing the reset node to SF7 does stop the downlinks.

On a node reset, I can force the data rate to what ADR had set, SF7125, but still the Gateway sends downlinks.

Looking at the node up times, a transmission straight after join has an up time of around 7800mS. After a node reset and session recovery the node up time is around 3500mS.

So is it likley that the downlinks are being ignored because the node is not listening for them ?