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

    I lose many packages in Lora

    Scheduled Pinned Locked Moved LoPy
    5 Posts 3 Posters 46 Views 3 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.
    • M Offline
      M m
      last edited by

      Hello! I'm having some troubles with LoRa uplinks and I'm not sure if it's my fault (probably) or what's happening.

      Basically the problem is that I send some data, and always the lora.event() says "Lora packet sent", but sometimes (to much times) the packet never arrive to my server (I'm not using TTN).

      It's weird because if the packets never arrived, I would understand that it is my code or maybe the antenna. But in this case sometimes yes, sometimes no ...

      Some idea?

      My code is made based on the own examples offered by Pycom.

      class myLoRa:
      
          def __init__(self):
              # LoRa device parameters
              self.dev_eui = config.dev_eui
              self.app_eui = config.app_eui
              self.app_key = config.app_key
      
              #
              self.frequency = config.LORA_FREQUENCY
              self.dr = config.LORA_NODE_DR
              self.region =  config.lora_region
              self.lora_class = config.lora_class
              self.lora_sf = config.lora_sf
      
              # Initialize LoRa in LORAWAN mode.
              self.lora = LoRa(
                  mode=LoRa.LORAWAN, region=self.region,
                  device_class=self.lora_class,
                  tx_retries = 3,
                  adr=False, sf=self.lora_sf)
      
              # Understand the events during LoRa comunication
              self.lora.callback(trigger=(LoRa.RX_PACKET_EVENT | LoRa.TX_PACKET_EVENT | LoRa.TX_FAILED_EVENT), handler=self.lora_events)
      
          def LoRa_join(self):        
              # set the 3 default channels to the same frequency (must be before sending the OTAA join request)
              self.lora.add_channel(0, frequency=self.frequency, dr_min=0, dr_max=5)
              self.lora.add_channel(1, frequency=self.frequency, dr_min=0, dr_max=5)
              self.lora.add_channel(2, frequency=self.frequency, dr_min=0, dr_max=5)
      
              # join a network using OTAA
              self.lora.join(
                  activation=LoRa.OTAA,
                  auth=(self.dev_eui, self.app_eui,self.app_key),
                  timeout=0,
                  dr=self.dr)
              
              # wait until the module has joined the network
              cnt = 0
              while not self.lora.has_joined():
                  time.sleep(2.5)
                  if config.debug:
                      print('\t\t· Trying to join...', str(cnt))
                  if (cnt < 30):
                      cnt += 1
                  else:
                      machine.reset()
      
              # remove all the non-default channels
              for i in range(3, 16):
                  self.lora.remove_channel(i)
      
          def LoRa_socket(self):
              # create a LoRa socket
              self.lora_socket = socket.socket(socket.AF_LORA, socket.SOCK_RAW)
              # set the LoRaWAN data rate
              self.lora_socket.setsockopt(socket.SOL_LORA, socket.SO_DR, self.dr)
              # make the socket non-blocking
              self.lora_socket.setblocking(False)
      
          def LoRa_send(self, payload):
              self.lora_socket.send(payload)
      
          def lora_events(self, lora):
              events = self.lora.events()
              if events & LoRa.RX_PACKET_EVENT:
                  if config.debug:
                      print('\t\t· Lora packet RECEIVED')
                  self.lora_socket.setblocking(False)
                  value = self.lora_socket.recv(64)
                  self.lora_socket.setblocking(True)
                  self.LoRa_downlink_handler(value)
      
              if events & LoRa.TX_PACKET_EVENT:
                  if config.debug:
                      print('\t\t· Lora packet sent')
      
              if events & LoRa.TX_FAILED_EVENT:
                  if config.debug:
                      print('\t\t· Lora packet sent FAIL')
      

      I will appreciate any comments, because losing data is not an option and the server api does not allow knowing if the data has arrived or not, thank you very much!

      J 1 Reply Last reply Reply Quote 0
      • G Offline
        Gijs
        last edited by

        Of course, we can assume LoRa is not 100% reliable, but Im not sure about the packet loss you are describing.
        It could be the case that other devices are also using the ISM band simultaneously, causing interference. There can be many causes for a packet to be sent out, but never received. Also, make sure to attached the correct antenna to the correct port.

        I assume you are using a local gateway to receiver the packets. Do you have any view on the RSSI / SNR of the packets that do get received, and compare that to the distance to the gateway so we can make a logical assumption there.

        1 Reply Last reply Reply Quote 0
        • J Offline
          jcaron @M m
          last edited by jcaron

          @M-m what region are you in and what gateway and network server are you using?

          If your use a another LoPy as a nano-gateway then you have to send all traffic on a single channel. That means removing all existing channels then adding the 3 default channels with the same frequency (the one the gateway is listening on). The network must also send correct channel information (or you need to set the channels again before each send).

          If you are using a “real” gateway but are in a region where there are more than 9 channels (e.g. US915, AU915...) then you need to do find out the channels the gateway/network are listening on (usually a set of 8 or 9 channels), and remove all channels not in the set. The network must likewise send the correct info to the device, or you may need to set the channels again.

          You’ll need to tell us the region, the gateway, the gateway settings (if you are operating it yourself), the network server and its settings (ditto) or the network you use and its frequency plan otherwise.

          Note that if losing packets is not an option then LoRa is probably not the best solution. It is really a best-effort network. You can set packets to be “confirmed” but there are in many regions strict limits on their use which make them often unusable.

          Also, how often are you sending, how much data, and at what data rate? Also, what’s your observed packet loss rate?

          1 Reply Last reply Reply Quote 0
          • M Offline
            M m
            last edited by

            I'm not sure to understand the solution but I have modified the lora configuration and now seems works better.

            The changes are:

            • Remove the channels config.
            • Modify the socket.
            class myLoRa:
            
                def __init__(self):
                    # LoRa device parameters
                    self.dev_eui = config.dev_eui
                    self.app_eui = config.app_eui
                    self.app_key = config.app_key
            
                    #
                    self.frequency = config.LORA_FREQUENCY
                    self.dr = config.LORA_NODE_DR
                    self.region =  config.lora_region
                    self.lora_class = config.lora_class
                    self.lora_sf = config.lora_sf
            
                    # Initialize LoRa in LORAWAN mode.
                    self.lora = LoRa(
                        mode=LoRa.LORAWAN, region=self.region,
                        device_class=self.lora_class,
                        tx_retries = 3,
                        adr=False, sf=self.lora_sf)
            
                    # Understand the events during LoRa comunication
                    self.lora.callback(trigger=(LoRa.RX_PACKET_EVENT | LoRa.TX_PACKET_EVENT | LoRa.TX_FAILED_EVENT), handler=self.lora_events)
            
                def LoRa_join(self):        
                    # set the 3 default channels to the same frequency (must be before sending the OTAA join request)
                    """self.lora.add_channel(0, frequency=self.frequency, dr_min=0, dr_max=5)
                    self.lora.add_channel(1, frequency=self.frequency, dr_min=0, dr_max=5)
                    self.lora.add_channel(2, frequency=self.frequency, dr_min=0, dr_max=5)"""
            
                    # join a network using OTAA
                    self.lora.join(
                        activation=LoRa.OTAA,
                        auth=(self.dev_eui, self.app_eui,self.app_key),
                        timeout=0,
                        dr=self.dr)
                    
                    # wait until the module has joined the network
                    cnt = 0
                    while not self.lora.has_joined():
                        time.sleep(2.5)
                        if config.debug:
                            print('\t\t· Trying to join...', str(cnt))
                        if (cnt < 30):
                            cnt += 1
                        else:
                            machine.reset()
            
                    # remove all the non-default channels
                    """for i in range(3, 16):
                        self.lora.remove_channel(i)"""
            
                def LoRa_socket(self):
                    """self.lora_socket = socket.socket(socket.AF_LORA, socket.SOCK_RAW)
                    self.lora_socket.setsockopt(socket.SOL_LORA, socket.SO_DR, self.dr)
                    self.lora_socket.setblocking(False)"""
                    self.lora_socket = socket.socket(socket.AF_LORA, socket.SOCK_RAW)
                    self.lora_socket.setsockopt(socket.SOL_LORA,socket.SO_CONFIRMED,True)
                    self.lora_socket.setblocking(True)
            
                def LoRa_send(self, payload):
                    self.lora_socket.send(payload)
            
                def lora_events(self, lora):
                    events = self.lora.events()
                    if events & LoRa.RX_PACKET_EVENT:
                        if config.debug:
                            print('\t\t· Lora packet RECEIVED')
                        self.lora_socket.setblocking(False)
                        value = self.lora_socket.recv(64)
                        self.lora_socket.setblocking(True)
                        self.LoRa_downlink_handler(value)
            
                    if events & LoRa.TX_PACKET_EVENT:
                        if config.debug:
                            print('\t\t· Lora packet sent')
            
                    if events & LoRa.TX_FAILED_EVENT:
                        if config.debug:
                            print('\t\t· Lora packet sent FAIL')
            

            As I said I really don't know why this works better, but I'll leave it here in case someone has similar problems and needs it in the future.

            And if somebody can explain me the difference between my first code and this one, I'll be glad. Because I hate doing things without understanding.

            Thanks for the answers!!!

            J 1 Reply Last reply Reply Quote 0
            • J Offline
              jcaron @M m
              last edited by

              @M-m unless you tell us what region you are in and the settings of your network+gateway (and the packet loss you observed, ideally with logs showing channels used), I think it’s going to be very difficult to know what your configuration should be and why those changes help (or if another configuration would help even more).

              1 Reply Last reply Reply Quote 1

              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