LoPy LoraWAN OTAA Deepsleep Example



  • Is there a working example how to send LoraWAN packets with OTAA in a deepsleep loop?

    1. join loraWAN
    2. send data
    3. deepsleep for minutes
    4. send data
    5. 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.



  • @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

    https://forum.pycom.io/topic/1668/has-anyone-successfully-used-lora-nvram_save-and-restore



  • @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:

    nvram_restore()
    send your data
    nvram_save()
    deepsleep



  • @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)?



Pycom on Twitter