Print(recv_ack) and Print(recv_pkg)



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



  • @PiAir Thanks.



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


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



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



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



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



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



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


Log in to reply
 

Pycom on Twitter