Does lora.nvram_restore() clear (delete) the saved lora context?
Since nvram usually has a limited lifespan (maybe some 100000 writes) we designed our code to only do lora.nvram_save() once (i.e. the first time the device joins the network) and the idea was that for all subsequent wakeups from deep sleep we only read the saved lora session using lora.nvram_restore(). The problem is that we are observing the following pattern (detected by monitoring the traffic on the gateway):
- The device issues a join request and after some retries the device joins the network and sends a lora packet using the assigned dev_addr. After the send the device goes into deep sleep (for a periode of time)
- The next time the device wakes up it restores the join session (using lora.nvram_restore()) and sends a lora packet using the same dev_addr as in 1)
- The next time thereafter the device issues a new join request (after lora_nvram.restore()) indicating that the restore did not retrieve a stored session.
This rises the question, does a lora_nvram.restore() also delete the previously saved lora session from nvram? If yes, is this by design or a bug?
@jcaron Just to clarify something from our use case: In our experience using the same frame counter is not a problem with our private instance of a TTN server. How we do it now is that we restore from nvram and save it immediately after. This is so we don't need to think about it again. I understand ADR will not work for us here, but it is still a lot easier and spares us from some logic with exception handling and still keeping the session and avoiding a new join. We also do not need to receive responses. We are basically using it as a makeshift abp connection, as our setup and back-end does not support abp. Having a function that restores the session without erasing it would actually be quite nice for our case. This, as far as I understand it from TTN, does also work for the public TTN network, but I have not confirmed this. Is there some way of getting all connection details down in a file so we could save it to an SD card instead? This would actually allow us to quite efficiently create devises and manage the things for our system.
robert-hh last edited by
@chumelnicu it's not on the board. But to support other means of storage, a lora.nvram_read() and lora.nvram_write() pair could be useful. That could also be used to change individual parameters.
@arneme Why did not use a i2C FRAM Memory for storing Lora parameters ?
FRAM Mem have milions of write cycles
@arneme Unless you have a very large battery, or you have an alternative power source (e.g. solar cells), at the moment it remains difficult to have a LoPy run on battery for extended periods of time with frequent wake-ups.
Remember that when you wake up, the LoPy will stay active and draw > 50 mA for several seconds.
If you have a (rather large) 2500 mAh battery, that's 2500 * 3600 = 9 000 000 mAs. At 50 mA, that means it can stay up 180 000 seconds. If the LoPy is awake for 3 seconds, that means a maximum of 60000 wake-ups. If the LoPy is awake longer (because the network has a long RXDelay, or you use confirmed uplinks and you have packet loss, or whatever other reason), this can do down dramatically.
And this is not even counting the current draw while the LoPy is sleeping or what whatever sensors you have connected draw. On a full charge in ideal conditions you won't be able to wake up more than a few tens of thousands of times. Unless you are planning to change batteries very often, that means the number of cycles over the lifetime of the LoPy is probably not going to exceed the low 100Ks, which should be well within what you can expect from the nvram routines.
Things may change dramatically if and when the LoPy are able to light-sleep while awake, but at that point I would except the nvram routines to be able to use the actual NVRAM rather than wear-levelled flash.
Of course, you may have a very different use case...
@jcaron OK, noted. I am however not entirely sure that I agree on your reflections related to battery powered devices: It depends on the use case how often you want/will send and changing or recharging batteries is always an option :-)
@arneme Yes, the information is cleared.
But even if it wasn't, you scheme wouldn't work: you would send frames with the same frame counter (so they would be ignored), you would not answer MAC commands, you would not handle ADR or channel changes, etc.
You need to restore and save on each cycle, there's no way around it.
Note that the nvram lib does wear levelling, so the number of writes that can be performed is much higher than the lifespan of flash. And even if it was only 100 000 writes, if you need deep sleep that means you run on battery, if you run on battery that means you can't wake up that often, so 100 000 deep sleep cycles is probably many years.