LoPy LoraWAN OTAA Deepsleep Example
Is there a working example how to send LoraWAN packets with OTAA in a deepsleep loop?
- join loraWAN
- send data
- deepsleep for minutes
- send data
- goto 3
so far i'm only able todo this loop with joining lora after each deepsleep cycle, but thas quite a bit of aditional airtime which i would like to avoid beside that packet count always is 1.
papasmurph last edited by
@roadfox Late response, but this doesn't look like a correct approach, as the join (and send) might have failed. Next time it will detect that it comes out of deepsleep and assume that it has joined, which it hasn't, so "if boot" must be replaced by something like "if successfully joined and not boot".
Try these two to see if it changes things for you:
- make sure the socket is blocking
- add a
time.sleep(2)after sending, before saving and going to deep sleep.
I had the same problem and I only could solve it using confirmed messages.
@roadfox I also have the same problem, I do not know if they have already found a solution. it seems that the frame counter is not stored
@jcaron i'm using the default machine.deepslep, it's not for current it's to see if it all will work whenever i get a deepsleep shield. my understanding is that the lopy boots no matter what kind of deepsleep i'm using
thats how i detect the boot and send the data
n = LORA() # Setup network & sensors if machine.reset_cause() == machine.DEEPSLEEP_RESET: print('woke from a deep sleep') else: print('power on or hard reset') # Join LoRaWAN with OTAA n.connect(app_eui, app_key) # Send packet response = n.send(data) print("Received data:", response) # put the device to sleep machine.deepsleep(sleep_time*1000)
What kind of deep sleep are you using? Deep Sleep Shield? Pysense? Pytrack?
How do you detect whether you're coming from deep sleep or some other form of startup?
@jcaron ok thats what i have now:
def connect(self, app_eui, app_key): """ Connect device to LoRa. Set the socket and lora instances. """ app_eui = unhexlify(app_eui) app_key = unhexlify(app_key) # Disable blue blinking and turn LED off LED.heartbeat(False) LED.off() # Initialize LoRa in LORAWAN mode self.lora = LoRa(mode = LoRa.LORAWAN) # Join a network using OTAA (Over the Air Activation) self.lora.join(activation = LoRa.OTAA, auth = (app_eui, app_key), timeout = 0) #login for TheThingsNetwork see here: https://www.thethingsnetwork.org/forum/t/lopy-otaa-example/4471 # Wait until the module has joined the network count = 1 while not self.lora.has_joined(): LED.blink(1, 2.5, 0xff0000) print("Trying to join LoraWAN with OTAA: " , count) count = count + 1 sleep(2.5) print ("LoraWAN joined! ") # save the LoRaWAN connection state self.lora.nvram_save() def send(self, data): """ Send data over the network. """ # Initialize LoRa in LORAWAN mode self.lora = LoRa(mode = LoRa.LORAWAN) # restore the LoRaWAN connection state self.lora.nvram_restore() # Create a LoRa socket print("Create LoRaWAN socket") self.s = socket.socket(socket.AF_LORA, socket.SOCK_RAW) # Set the LoRaWAN data rate self.s.setsockopt(socket.SOL_LORA, socket.SO_DR, 5) # Make the socket non-blocking self.s.setblocking(False) try: self.s.send(data) LED.blink(2, 0.1, 0x00ff00) print("Sending data:") print(data) # save the LoRaWAN connection state self.lora.nvram_save() except OSError as e: if e.errno == 11: print("Caught exception while sending") print("errno: ", e.errno)
i call connect after a hard reset or boot, otherwise i just call send
so far everything is working beside the fact that LoRaWAN frame counter is always at 1 and the packets are dropped in TTN unless i disable frame counter checks.
should nvram_save/restore not also save the framecounter?
You only need to join once, so you may do that manually at the same time you upload the code. Once you've done that, it's as simple as:
send your data
@jcaron i was reading about nvram_save and restore and i also found a code snippet,how to detect if the system is booting or coming from deepsleep but its all puzzle pieces and new to me, so i was hopimg for a bit more complete example
If boot lorawan join else nvram_restore send data nvram_save deepslep 2min
Is this approach correct?
Are you using the most recent firmware? Are you using
nvram_save(before going to sleep) and
nvram_restore(after coming back from sleep)?