Not at all, I suspect they are just formatted in a way that LMIC does it’s best with but between it & the LNS they don’t quite make it.
I regularly end up with nodes that are fully configured & tweaked yet still get downlink commands. I’m slowly working towards additions to LMIC to fully explain what it is hearing and what it is doing about it to try to debug this. But it can happen with LoRaMAC-node as well, so I think the LNS is as much a culprit as the device.
I don’t profess to understand it either but it has been an ongoing irritation since the move to v3.
So much so that I diverted from the planned tasks of the morning to resurrect the test code base that I’d worked on earlier in the year so that I can dip in & out of running tests to accumulate info & learn more about decoding MAC commands.
It’s not just LMIC that suffers, I use LoRaMac-node on Murata ABZ and STM32WL modules a lot and see similar issues that seem to just appear out of no where - or start on join (like setting the Rx1 window) and never ever go away.
Well, if you think about it, after the first join and ADR has settled, there must be some configuration\status stored in variables that is governing how the node subsequently behaves, listens for downlinks and for how long etc.
Now my code at such a low level is not that good, but I note the library code has not used private: to hide variables so one might assume that all the variables the library code is using are accessible from an external sketch, so you might then assume that in principal, you could save and restore the whole lot.
Whats needed to debug, is to be able to print stuff out within the library code, that does not appear to be possible with the SAMD21, Serial. is not recognised, but notes in the code suggest the use of Serial. is possible with an AVR processor.
Think I have solved the problem of the ADR being ignored.
The basics of saving the session keys and status to FRAM and the recovery are working, but when the RecoveredState starts up in SF12, ADR does not adjust back down to SF7. The Gateway is sending downlinks but the node either does not listen for them or is ignoring them. In the case of the node with in RecoveredState mode its awake for some 4000ms less than the node in FreshJoined mode.
I added a large pile of LMIC.****** variable prints, about 60 of them to see what was going on.
Comparing the FreshJoined prints with the RecoveredState prints, LMIC.rxDelay is 5 for FreshJoined mode and 1 for RecoveredState. Now if rxDelay is how long the software says the node should listen for an RX and it is in seconds, it would explain the 4000mS difference in awake time between FreshJoined mode and RecoveredState. So I change the sketch and impose an rxDelay of 5 after the RecoveredState code restores the session state from FRAM.
Now ADR on the RecoveredState node works, the ADR is not as fast as the new OTAA join, but it changes from SF12 down to SF7 in about 4 transmissions, and then stays at SF7. There are still downlinks, about 1 in 5 similar to what @DavidTaylor_DPI reported I believe. Not sure if that number of downlinks is something to worry about.
Whilst the node code is primarily intended for a Seeeduino XIAO, the combination of Low Power Sleep, BME280 sensor, FRAM, Cayenne payload and the recovery of the OTAA session from FRAM, will fit on an Atmega328P, aka Arduino Pro Mini. Tight on Flash, but a significant pruning of the Serial debug messages should cure that.
May-be you should check what the initial join accept provides as parameters and save all of them, not rely on RX1 being 5 seconds. There are other parameters like the additional frequencies (apart from the 868.1/3/5MHz used by join) you need to recover (and not use at join time) as well.
LoRaWAN spec 1.0.3, ‘6.2.5 Join-accept message’ lists an optional channel list. Regional parameter spec 1.0.3 (2.4.4 EU863-870 Join-Accept CFList) for EU868 states it is optional but if used the channels shall replace all existing channels apart from the three mandatory channels.
So to make sure a node is standards compliant it should process (and save) the list if present in a join request,
Could well be. I haven’t used LMIC for ages. My code is loramac-node based these days, that allows a 1.0.4 pre certification test without failures, I don’t know how LMIC would fare…
The same for a LoRaWAN compliant device. MAC commands to modify the channel list will be used in ABP mode to make sure the device has the same channel plan as used by the NS. ADR will be active as well. So there isn’t much, if anything, to gain by switching to ABP.
After testing the recover of the LMIC_low_power from a sketch using data stored in FRAM, and finding it reliable enough, with no apparent untoward effects when compared with a MCCI_LoRaWAN_LMIC sketch, I wondered if sleep mode could be used with that more upto date library.
Since the LMIC_setSession () works well enough following a reset, I modified the basic MCCI_LoRaWAN_LMIC otaa sketch to go into deep sleep after a transmission and then do a LMIC_setSession () and restore of counters when awake.
This seems to work, and by forcing transmissions to SF12 (only for a short while!) it would appear that LMIC_setSession () puts the duty cycle checking back to zero. Sleep periods were still mostly 7-8 seconds with maybe 1 : 10 being 12 seconds, which is acceptable. LMIC_setSession () can recover data either from RAM (when preserved in deep sleep) so this would be a workable solution for boards without FRAM or EEPROM.
A TPL5010, a 6 pin SOT device, as a Watchdog works well. Hook up the done pin to the LoRa device NSS and if there is no activity for a time determined by a single resistor, (mS to 2 hours), the SAMD21 gets a reset and the session is recovered where it last left off from FRAM. TPL5010s are around £1.
On watchdog reset the node sets to SF12 and 60 second interval but that ADRs in about 3 transmissions to SF7. After 5 transmissions the FUP adjuster comes in and sets the interval to 158 seconds. Easy enough to overide the FUP adjuster and set the interval to one hour though.