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

I am currently testing the LMIC_low_power code. It may not be the most modern LMIC, but is seems to do the basics OK, although I dont intend to test the downlink stuff.

I have seen a problem with the BME280, that has at least once gone off line, so I added some code to re-initialize it.

You can start the node up in SF12 at an interval of 60 seconds and it then quickly adjusts down to SF7 and imposes an interval that keeps to the FUP.

In a few days when I am happy with the LMIC_low_power code version, I will give yours a go. It does take a fair bit more program sapce than the LMIC_low_power version, but thats not an issue on the XIAO.

Running the code now. The debug info sent to Serial is very good, you can sure see what is happening and when, due to the sketch picking up the current time.

Currently monitoring it for a while on a local serial port connected to a laptop and if it runs OK I will leave it running with an openlog connected to the XIAO serial port.

I have had your code running for 12 hours on a 240 seconds interval (within FUP!) and all I see is uplinks.

This is what a working TTN BME280 temperature node using the XIAO can look like (LoRa module is on the back of PCB);

min_build_node2

Deep sleep current 4.5uA, enforces the TTN fair useage policy.

You could use pin headers for the connections, but the soldered wires are a fair bit easier and no crimp tool or crimps needed.

4 Likes

On your code, I have seen something similar.

Not all the time but I noticed this evening that for about 4 of the every 240 secs transmissions, there was a standard payload uplink and then 6 seconds later another, but with no payload. I downloaded and saved the java stuff from the applications screen for these uplinks, but its all voodoo to me.

I have written up my efforts so far, to make an easy build TTN node here;

3 Likes

I thought that was happening with my code about once a day (with my uplinks at a different frequency to yours) and that it was TTN sending some config commands to the node, and the node responding about whether it had applied them.

But what config commands could they be ?

Nodes are transmitting well within duty cycle and are using SF7 at minimum power. Signals are strong, so nowhere to go ADR wise.

Clever idea to only advance the LMIC clock enough to skip the duty cycle check.

I am using the network time request and RTC to try and get our nodes reporting in a reasonably synchronised manner so we can compare the readings from each node without having those readings too far apart. For example, the current wind direction over nodes at an orchard is more interesting if those 10 measurements were made at the same time.

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 ?