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

Possibly true but having many nodes time synched for sending messages is generally bad practice! - Collisions!

Better to have node take a reading at same time then randomly delay for some period before sending or take readings and send immediately but on a random basis…or atleast dithered timings…perhaps add a byte/nibble to payload for a timing offset count (seconds? even 0.1sec per message helps prevent clashes)…and does it really need to be hard realtime across the area of interest? Will the wind be swirling (tornado alley by any chance :rofl: ) or is it not safe/reasonanle to assume that as wind blows across a second or two later the next section generally same and so on as a gust or steady blow traverses the area such that the transition time delta isnt so huge c/w the update rate of the nodes - how often are you sending per node? I think a 16kmph/10mph gust will transit a 300m wide area in just over 1 minute and if you are sending every 20 mins or even 5 mins any transient data at opposite end nodes would potentially miss the gust event?

I’m just the plumber and firmware guy, not the scientist, but I think some nodes are out in the open and others are under covered rows and we want to see what effect the covering has on how much wind the fruit experiences - wind causing fruit to rub is a problem. It is pretty windy there, it’s on the side of what we jokingly call a mountain in Australia, getting that volcanic soil going.

I’ve added up to 5 seconds jitter because we were getting what I assume are collisions. I’m not worrying about the slight offset in uplink time because we’re also recording the readings to SD card at the actual time they’re taken with a timestamp which will probably be used for the real data analysis. The uplinks are a convenient way to let us know they’re still alive and lets us get a quick visualisation without visiting the orchard.

We are missing gust events at present. I’ve figured out how to count pulses while the SAMD21 is in standby using the event system, but I haven’t figured out how to get the time between the pulses to get the minimum without waking up every pulse. I know the TCC can be fed from the event system too, but as explained below, am not following this up.

Given the trouble we’re having with the things locking up we’ve pretty well given up on them and are now working on an ESP32 based node where we can use the ULP to get both counts and minimum time between pulses if we want.

I might put a sketch together over the summer break that only wakes and sleeps and does no comms, not even linking LMIC in. I don’t think LMIC is the problem in any case but if the thing still locks up doing nothing but that I don’t think they’re worth persevering with given there are so many other options out there.

Well time will tell as they say. I have had your code and the simpler LMIC_low_power code running on a couple of XIAOs in normal sensor mode for around 3 days now, they both put out around 350 uplinks a day. No lockups on either, so far.

Although the board I did is very simple, it probably makes sense to make it just a little bit bigger and add an edge SMA (for easy board mounting in a box) an I2C FRAM and a watchdog.

Not sure the SAMD21 internal watchdog is the answer, although I might give it a go. But for that to work the FRAM would be needed to store stuff, cannot have the node creating a new DevAddr every time there is a crash. My preferance would be an external watchdog such as the TPL5010, which could reset the node completly independantly of the SAMD21.

A question for the forum;

Are there known examples of using EEPROM\FRAM for saving the node status\config and having a graceful restart from a reset ?

For that you probably need to look at loramac-node. That saves state on every transmission.

Wow, check out the non-softie!

If the nodes are getting time sync’d and doing the readings at the same time, you could make the jitter much bigger - as you know that batch of readings were all taken at the same time or include the lower two bytes of the RTC epoc value.

There are a few random discussions but I’m not aware of any definitive conclusions or an actual library. Maybe @terrillmoore can say where LMIC is at with save & restore of credentials.

As for LMn, there is a recent firmware for the LoRa-E5 that does the saving.

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.