**SOLVED** Method not working if moved



  • I'm interested in implementing this kind of LoRa protocol in my application https://forum.pycom.io/topic/526/lopy-nano-gateway-extended-timeout-and-retry
    So I download the files, load them on my LoPys and succesfully tested them. Now I want to make some changes and include the code in my script but the code only works sometimes (very rare BTW). What could be the problem?

    Here's my code. Power up one LoPy and let it run the "client" part from the above tutorial, then run my code on another LoPy and see nothing is being received (if you run the "gateway" part from the tutorial it works!).

    note that i'd like to include both the gateway and client methods in this module; the client part seems to work flawlessly, but inside the receive_loop function, when I do "lora_sock.recv" it always reads nothing:

    import socket
    import struct
    import time
    
    import machine
    
    from uos import urandom
    from network import LoRa
    from machine import Timer
    
    
    # A basic package header
    # B: 1 byte for the deviceId
    # B: 1 byte for the pkg size
    # B: 1 byte for the messageId
    # %ds: Formated string for string
    _LORA_PKG_FORMAT = "!BBB%ds"
    
    # A basic ack package
    # B: 1 byte for the deviceId
    # B: 1 byte for the pkg size
    # B: 1 byte for the messageId
    # B: 1 byte for the Ok (200) or error messages
    _LORA_PKG_ACK_FORMAT = "BBBB"
    
    _DEVICE_ID = 0x01
    _MAX_ACK_TIME = 5000
    _RETRY_COUNT = 3
    
    try:
        lora_sock.close()
        print(lora_sock)
    except:
        pass
    lora = LoRa(mode=LoRa.LORA, tx_iq=True)
    lora_sock = socket.socket(socket.AF_LORA, socket.SOCK_RAW)
    lora_sock.setblocking(False)
    
    msg_id = 0
    
    # Method to increase message id and keep in between 1 and 255
    def increase_msg_id():
        global msg_id
        msg_id = (msg_id + 1) & 0xFF
    
    # Method for acknoledge waiting time keep
    def check_ack_time(from_time):
        current_time = time.ticks_ms()
        return (current_time - from_time > _MAX_ACK_TIME)
    # Method to increase message id and keep in between 1 and 255
    def increase_msg_id():
        global msg_id
        msg_id = (msg_id + 1) & 0xFF
    
    # Method for acknoledge waiting time keep
    def check_ack_time(from_time):
        current_time = time.ticks_ms()
        return (current_time - from_time > _MAX_ACK_TIME)
    
    # Method to send messages
    def send_to_gateway(msg):
        global msg_id
        retry = _RETRY_COUNT
        while (retry > 0 and not retry == -1):
            retry -= 1
            pkg = struct.pack(_LORA_PKG_FORMAT % len(msg), _DEVICE_ID, len(msg), msg_id, msg)
            print('send', pkg)
            lora_sock.send(pkg)
    
            # Wait for the response from the server.
            start_time = time.ticks_ms()
    
            while(not check_ack_time(start_time)):
                recv_ack = lora_sock.recv(256)
                # If a message of the size of the acknoledge message is received
                if (len(recv_ack) == 4):
                    device_id, pkg_len, recv_msg_id, status = struct.unpack(_LORA_PKG_ACK_FORMAT, recv_ack)
                    if (device_id == _DEVICE_ID and recv_msg_id == msg_id):
                        if (status == 200):
                            # Do some code if your message arrived at the central
                            return True
                        else:
                            return False
            time.sleep_ms(urandom(1)[0] << 2)
        return False
    
    
    def receive_loop():
        while (True):
            # Since the maximum body size in the protocol is 255 the request is limited to 512 bytes
            recv_pkg = lora_sock.recv(512)
    
            # If at least a message with the header is received process it
            if (len(recv_pkg) > 3):
                recv_pkg_len = recv_pkg[1]
                print(recv_pkg)
    
                # If message is corrupted should not continue processing
                if (not len(recv_pkg) == recv_pkg_len + 3):
                    continue
    
                # Unpack the message based on the protocol definition
                device_id, pkg_len, msg_id, msg = struct.unpack(_LORA_PKG_FORMAT % recv_pkg_len, recv_pkg)
    
                # Respond to the device with an acknoledge package
                # time.sleep(0.15)
                ack_pkg = struct.pack(_LORA_PKG_ACK_FORMAT, device_id, 1, msg_id, 200)
    
                lora_sock.send(ack_pkg)
    
                # Do any xtra processing required for the package. Keep in mind it should be as fast as posible
                # to make sure that the other clients are not waiting too long for their messages to be acknoleged
    
    receive_loop()
    
    

    my device info: (sysname='LoPy', nodename='LoPy', release='1.6.13.b1', version='v1.8.6-607-g9c8a0e9e on 2017-05-01', machine='LoPy with  ESP32', lorawan='1.0.0')


  • administrators

    @Andrea-Filippini You are welcome :-)



  • @daniel Wow... I never noticed that difference D:
    You saved my day thanks! =)


  • administrators

    Because on that example one node uses tx_iq=True and the other rx_iq=True, which is what makes it work.



  • @daniel Thank you, it seems to work. But can you explain why this exaple https://forum.pycom.io/topic/526/lopy-nano-gateway-extended-timeout-and-retry works with lora = LoRa(mode=LoRa.LORA, tx_iq=True)?


  • administrators

    Hello @Andrea-Filippini,

    Are you suing exactly the same code for both LoRa end-points (Gateway and Node)? If that's the case then change this line:

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

    to:

    lora = LoRa(mode=LoRa.LORA)

    Otherwise you need to invert the rx_iq on the other side for it to work...

    Cheers,
    Daniel


Log in to reply
 

Looks like your connection to Pycom Forum was lost, please wait while we try to reconnect.