Welcome to the Pycom forum Forum
    • \[\[global:header.categories\]\]
    • \[\[global:header.recent\]\]
    • \[\[global:header.tags\]\]
    • \[\[global:header.popular\]\]
    • Login

    Explore Pybytes | Official Documentation | Report a Firmware Bug/Issue | GitHub

    lora.join does not attempt every 15 seconds in background

    Scheduled Pinned Locked Moved Firmware
    loralopybug
    12 Posts 4 Posters 1.6k Views 4 Watching
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • G Offline
      Graham
      last edited by Graham

      If lora.join fails on the first attempt, it does not attempt again every 15 seconds as suggested in Pycom docs.

      Example code:

      lora.join(activation=LoRa.OTAA, auth=(app_eui, app_key),timeout=0)
      # wait for a connection to be established
      while not lora.has_joined():
          pass
      

      Which will hang forever if the first join fails (which happens to us often enough during educational workshops with LoPy4).

      The docs say Internally the stack will automatically retry every 15 seconds until a Join Accept message is received. - which implies no wizardry is needed for the 15s intervals to join.

      If I am overlooking something. any tips are welcomed!

      G robert-hhR 2 Replies Last reply Reply Quote 0
      • G Offline
        Graham @Graham
        last edited by

        Fyi, here's my os.uname() on the LoPy4:

        sysname='LoPy4', nodename='LoPy4', release='1.18.1.r1', version='v1.8.6-849-b0520f1 on 2018-08-29', machine='LoPy4 with ESP32', lorawan='1.0.2', sigfox='1.0.1'
        
        1 Reply Last reply Reply Quote 0
        • robert-hhR Offline
          robert-hh @Graham
          last edited by

          @graham I do not agree. If I look at the traffic from a node, e.g. in the TTN console or at the gateway, you'll see join messages every 15 seconds. Which gateway are you using?

          G 1 Reply Last reply Reply Quote 0
          • G Offline
            Graham @robert-hh
            last edited by Graham

            It happens on different gateways, so I'm not leaning in that direction yet. I can very reliably trigger the fault by powering up 5x LoPy4's all at the same time. At least one or two of the last-to-be-powered devices will hang.

            The only semi-reliable method we have for educational workshops (where 10+ devices are being powered on/off at the same time) is this:

            print("Device EUI: " + binascii.hexlify(lora.mac()).upper().decode('utf-8'))
            
            while not lora.has_joined():
                # if no connection in a few seconds, then reboot
                if utime.time() > 15:
                    print("possible timeout")
                    machine.reset()
                pass
            

            Although it looks and feels like a dity workaround for something that is breaking somewhere at the OS-level.

            Anyone with 5+ LoPy4's to test could replicate the issue easily and reliably. This failure state triggers all-the-time, it doesn't seem to be dependant on the Gateway model.

            If this happened to a device in the field, without our workaround, it would remain in a hung state indefinitely. That, erm, concerns me a little.

            robert-hhR 1 Reply Last reply Reply Quote 0
            • robert-hhR Offline
              robert-hh @Graham
              last edited by robert-hh

              @graham It looks for me as if two devices try to join at the same time over and over again, and then the join messages get lost due to collision. An indirect proof for that would be, if every device joins when started by itself. So the reset you used as workaround would then force the devices out of their malicious sync.

              1 Reply Last reply Reply Quote 0
              • H Offline
                Harald
                last edited by

                What do you experience if you power up your gateway after the first join attempt? I seem to have the same issue. Only one join attempt

                1 Reply Last reply Reply Quote 0
                • E Offline
                  Emmanuel Florent
                  last edited by

                  The firmware does repeat the join request.
                  Uplink join frequency (in Mhz) depends of each regional specification same for retry frequency (in seconds)
                  Depending on your setup (region in particular) you have to make a particular setup so what regional specification do you target ?
                  Example for US_915 subband 1 you would OTAA join on channel 64 and then that would be:

                      lora.add_channel(int(upstream.get('chan')), frequency=int(upstream.get('fq')), dr_min=0, dr_max=int(data_rate))  
                      for index in range(0, 71):
                          if index != upstream.get('chan'):
                              lora.remove_channel(index)
                  
                  
                          # create an OTA authentication params
                          dev_eui = binascii.unhexlify(self.config["lora"]["otaa"]['dev_eui'])
                          app_key = binascii.unhexlify(self.config["lora"]["otaa"]['app_key'])
                          nwk_key = binascii.unhexlify(self.config["lora"]["otaa"]['nwk_key'])
                  
                          start_join_time = time.time()
                  
                          # lora.nvram_restore()
                  
                          if not lora.has_joined():
                              if self.config["lora"]["region"] == "US915":
                                  lora.join(activation=LoRa.OTAA, auth=(dev_eui, app_key, nwk_key), timeout=0, dr=0)
                              else:
                                  lora.join(activation=LoRa.OTAA, auth=(dev_eui, app_key, nwk_key), timeout=0, dr=int(self.config["lora"]["data_rate"]))
                  
                  
                          # wait until the module has joined the network
                          while not lora.has_joined():
                              time.sleep(1)
                              pycom.rgbled(0x000000)
                              print('.', end='')
                              time.sleep(1)
                              pycom.rgbled(0x0000ff)
                  
                          lora.nvram_save()
                  
                  
                  
                      for i in range(0, 8):
                          fq = 902300000 + (i * 200000)
                          self.lora.add_channel(i, frequency=fq, dr_min=0, dr_max=self.config["lora"]["data_rate"])
                  1 Reply Last reply Reply Quote 0
                  • G Offline
                    Graham
                    last edited by Graham

                    @harald The Gateway (more specifically, TTN console data logs) show a single join event. No additional join events occur in TTN console after this issue is invoked (which suggests the LoPy4 is the issue).

                    @emmanuel-florent I've omitted the region settings to just show the minimal code. We're heavy-users of LoPy hardware; everything upstream of the join event is fine.

                    @robert-hh I agree there is a collision, though it's not attempting every 15 seconds. A failed connection never recovers, even if other failed devices are turned off (leaving 1 failed device "on" to attempt its own recovery).

                    It does appear more-and-more that there's an issue in the stack for this scenario. With REPL connected, sending a CTRL+C during a failure condition

                    Left as is, this bug could be viewed as a DDoS layer for Pycom LoPy4. Devices that attempt to connect on power-up could find themselves in this situation and never "connect" using any of the recommended examples in Pycom Docs. I doubt many people have experienced the issue as they are not holding educational workshops that invoke more-than-normal LoRaWAN events over a short time.

                    robert-hhR E 2 Replies Last reply Reply Quote 0
                    • robert-hhR Offline
                      robert-hh @Graham
                      last edited by

                      @graham I have never seen that behavior. Did you check that the various board you are using have a different dev-eui, when manually set?

                      About Ctrl-C: The Lora stack/device is not fully reset on Ctrl-C. You have to push hard reset (button) or call machine.reset().

                      1 Reply Last reply Reply Quote 0
                      • E Offline
                        Emmanuel Florent @Graham
                        last edited by

                        @graham please let me look the code for the workshop you can write me at emmanuel at pycom dot io.

                        G 1 Reply Last reply Reply Quote 0
                        • G Offline
                          Graham @Emmanuel Florent
                          last edited by

                          @emmanuel-florent here's the code. I've tested this many times with 4x LoPy4's before posting; pressing the reset button at the same time on them all. Almost always, one or two devices will not connect and do not recover.

                          Gateway logs show 1 join request from the failed device(s), I watched the logs for two minutes each time awaiting any signs of life (there were none).

                          from network import LoRa
                          import pycom
                          import binascii
                          import socket
                          
                          lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.AS923)
                          app_eui = binascii.unhexlify('XXXXXXXXXXXXXX')
                          app_key = binascii.unhexlify('XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX')
                          
                          lora.join(activation=LoRa.OTAA, auth=(app_eui, app_key), timeout=0)
                          
                          print('Waiting for LoRaWAN network connection...')
                          while not lora.has_joined():
                              pass
                          
                          print('Network joined!')
                          
                          while True:
                              pass
                          
                          robert-hhR 1 Reply Last reply Reply Quote 0
                          • robert-hhR Offline
                            robert-hh @Graham
                            last edited by

                            @graham said in lora.join does not attempt every 15 seconds in background:

                            while not lora.has_joined():
                            pass

                            I would add something like sleep(1) into the loop, giving the background tasks more time.

                            1 Reply Last reply Reply Quote 0

                            Hello! It looks like you're interested in this conversation, but you don't have an account yet.

                            Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.

                            With your input, this post could be even better 💗

                            Register Login
                            • 1 / 1
                            • First post
                              Last post

                            Pycom on Twitter

                            Pycom