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

    Print(recv_ack) and Print(recv_pkg)

    Scheduled Pinned Locked Moved Comments & Feedback
    loralopygateway
    9 Posts 2 Posters 2.7k Views 2 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.
    • T Offline
      timeb
      last edited by timeb

      Hello, I am trying to understand about the lora socket and I came across something I did not really get. So, it would be nice to get an explanation.

      while (True):
      recv_pkg = lora_sock.recv(512)
      print(recv_pkg)
      if (len(recv_pkg) > 2):
      recv_pkg_len = recv_pkg[1]

      So, when I tried to print(recv_pkg) I get b' ' . Why is it empty?

      1 Reply Last reply Reply Quote 0
      • PiAirP Offline
        PiAir
        last edited by

        Did you find that code here?
        Basically, it is waiting for packets to be received via lora (recv_pkg = lora_sock.recv(512))
        Did you make sure there actually was a node that was transmitting data? Because without such a node, it makes sense that recv_pkg is empty. You can use the node-code that is on that same page to test it.

        T 1 Reply Last reply Reply Quote 0
        • T Offline
          timeb @PiAir
          last edited by

          @PiAir I actually tried it with the LoRa Nano-Gateway found in the docs.

          PiAirP 1 Reply Last reply Reply Quote 0
          • PiAirP Offline
            PiAir @timeb
            last edited by

            @timeb What do you mean "tried it with" ? The code you post "listens", so that a Gateway. Before either of them can "hear" something, you need a node to send packets via LoRa. Take a look at the code on the page that I linked: it has code for a gateway and for a node. Neither of them can do much without the other.

            T 1 Reply Last reply Reply Quote 0
            • T Offline
              timeb @PiAir
              last edited by

              @PiAir yes that is what I used. My question is after the Sending node sends out a message and waits for an acknowledgment. So, I tried to do print(recv_ack) but I just see b ' ' . The thing is that it says it has received Ack. But why can't I see what that ack pkg is?

              PiAirP 1 Reply Last reply Reply Quote 0
              • PiAirP Offline
                PiAir @timeb
                last edited by PiAir

                @timeb You lost me (must be me), let my try this once more.

                You've got the code for the gateway:

                import socket
                import struct
                from network import LoRa
                
                # A basic package header, B: 1 byte for the deviceId, B: 1 byte for the pkg size, %ds: Formated string for string
                _LORA_PKG_FORMAT = "!BB%ds"
                # A basic ack package, B: 1 byte for the deviceId, B: 1 bytes for the pkg size, B: 1 byte for the Ok (200) or error messages
                _LORA_PKG_ACK_FORMAT = "BBB"
                
                # Open a LoRa Socket, use rx_iq to avoid listening to our own messages
                lora = LoRa(mode=LoRa.LORA, rx_iq=True)
                lora_sock = socket.socket(socket.AF_LORA, socket.SOCK_RAW)
                lora_sock.setblocking(False)
                
                while (True):
                    recv_pkg = lora_sock.recv(512)
                    if (len(recv_pkg) > 2):
                        recv_pkg_len = recv_pkg[1]
                
                        device_id, pkg_len, msg = struct.unpack(_LORA_PKG_FORMAT % recv_pkg_len, recv_pkg)
                
                # If the uart = machine.UART(0, 115200) and os.dupterm(uart) are set in the boot.py this print should appear in the serial port
                        print('Device: %d - Pkg:  %s' % (device_id, msg))
                
                        ack_pkg = struct.pack(_LORA_PKG_ACK_FORMAT, device_id, 1, 200)
                        lora_sock.send(ack_pkg)
                

                and the code for the node:

                import os
                import socket
                import time
                import struct
                from network import LoRa
                
                # A basic package header, B: 1 byte for the deviceId, B: 1 bytes for the pkg size
                _LORA_PKG_FORMAT = "BB%ds"
                _LORA_PKG_ACK_FORMAT = "BBB"
                DEVICE_ID = 0x01
                
                
                # Open a Lora Socket, use tx_iq to avoid listening to our own messages
                lora = LoRa(mode=LoRa.LORA, tx_iq=True)
                lora_sock = socket.socket(socket.AF_LORA, socket.SOCK_RAW)
                lora_sock.setblocking(False)
                
                while(True):
                    # Package send containing a simple string
                    msg = "Device 1 Here"
                    pkg = struct.pack(_LORA_PKG_FORMAT % len(msg), DEVICE_ID, len(msg), msg)
                    lora_sock.send(pkg)
                
                    # Wait for the response from the gateway. NOTE: For this demo the device does an infinite loop for while waiting the response. Introduce a max_time_waiting for you application
                    waiting_ack = True
                    while(waiting_ack):
                        recv_ack = lora_sock.recv(256)
                
                        if (len(recv_ack) > 0):
                            device_id, pkg_len, ack = struct.unpack(_LORA_PKG_ACK_FORMAT, recv_ack)
                            if (device_id == DEVICE_ID):
                                if (ack == 200):
                                    waiting_ack = False
                                    # If the uart = machine.UART(0, 115200) and os.dupterm(uart) are set in the boot.py this print should appear in the serial port
                                    print("ACK")
                                else:
                                    waiting_ack = False
                                    # If the uart = machine.UART(0, 115200) and os.dupterm(uart) are set in the boot.py this print should appear in the serial port
                                    print("Message Failed")
                
                    time.sleep(5)`
                

                We start at the node:

                while(True):
                    # Package send containing a simple string
                    msg = "Device 1 Here"
                    pkg = struct.pack(_LORA_PKG_FORMAT % len(msg), DEVICE_ID, len(msg), msg)
                    lora_sock.send(pkg)
                
                    # Wait for the response from the gateway. NOTE: For this demo the device does an infinite loop for while waiting the response. Introduce a max_time_waiting for you application
                    waiting_ack = True
                    while(waiting_ack):
                        recv_ack = lora_sock.recv(256)
                        if (len(recv_ack) > 0):
                

                The first while(True) starts an infinite loop.
                The message (msg) sent by the node is always the same: "Device 1 Here"
                That message is packaged into pkg and then send using lora_sock.send(pkg)
                The node start another while loop where it waits for a message back from the/any gateway. It does that by listening to data coming in via the lora socket (recv_ack = lora_sock.recv(256))

                Ok, let's go to the Gateway side. The Gateway is always listening:

                while (True):
                    recv_pkg = lora_sock.recv(512)
                    if (len(recv_pkg) > 2):
                        recv_pkg_len = recv_pkg[1]
                

                if it received (enough) data, it unpacks it into device_id, pakage length and the actual message:

                        device_id, pkg_len, msg = struct.unpack(_LORA_PKG_FORMAT % recv_pkg_len, recv_pkg)
                
                # If the uart = machine.UART(0, 115200) and os.dupterm(uart) are set in the boot.py this print should appear in the serial port
                        print('Device: %d - Pkg:  %s' % (device_id, msg))
                

                The code then prints that info. So if you would have a serial connection open to the gateway, it would print "Device: 0x01 - Pkg: Device 1 Here" as soon as it receives the package from the node. And it would do that over and over again, because the node is in a infinite loop that keeps on sending that same text.
                After printing the data, the gateway send the value "200" back to the node:

                        ack_pkg = struct.pack(_LORA_PKG_ACK_FORMAT, device_id, 1, 200)
                        lora_sock.send(ack_pkg)
                

                Which is exactly what the node was waiting for. Switching back to the code on the node. As you remember, the node was listening to data coming in via the lora socket (recv_ack = lora_sock.recv(256)). If it received data on the socket, it unpacks it into device_id, package length and the message, it then checks to see if the package was intended of the node (if (device_id == DEVICE_ID):) and if the message is "200" (if (ack == 200):) it prints "ACK".

                if (len(recv_ack) > 0):
                            device_id, pkg_len, ack = struct.unpack(_LORA_PKG_ACK_FORMAT, recv_ack)
                            if (device_id == DEVICE_ID):
                                if (ack == 200):
                                    waiting_ack = False
                                    # If the uart = machine.UART(0, 115200) and os.dupterm(uart) are set in the boot.py this print should appear in the serial port
                                    print("ACK")
                

                if it does receive a message, but it is not "200", it assumes the transfer to the gateway has failed:

                                else:
                                    waiting_ack = False
                                    # If the uart = machine.UART(0, 115200) and os.dupterm(uart) are set in the boot.py this print should appear in the serial port
                                    print("Message Failed")
                

                The node then sleeps for 5 seconds:

                time.sleep(5)
                

                And it all starts over again.

                T 1 Reply Last reply Reply Quote 0
                • T Offline
                  timeb @PiAir
                  last edited by

                  @PiAir I totally understand. But what exactly is the purpose of the tx_iq and rx_iq? Let's say we have a receiving node which is meant to receive a message from the sending node through the gateway. The situation is like the following: The sending node wants to send a message to the receiving node and doesn't want to do it directly. So, let's say it sends it to the gateway and the gateway unpacks and checks if it is meant for it. If it is it sends back an ack to the sending node otherwise it packs the message again and forwards it to the receiving node. So, should gateway have both tx_iq and rx_iq True?

                  PiAirP 1 Reply Last reply Reply Quote 0
                  • PiAirP Offline
                    PiAir @timeb
                    last edited by

                    @timeb No, as far as I understand that part, the gateway should have:

                    lora = LoRa(mode=LoRa.LORA, rx_iq=True)
                    

                    and then both nodes should have:

                    lora = LoRa(mode=LoRa.LORA, tx_iq=True)
                    
                    T 1 Reply Last reply Reply Quote 0
                    • T Offline
                      timeb @PiAir
                      last edited by

                      @PiAir Thanks.

                      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