**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) << 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 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')
@Andrea-Filippini You are welcome :-)
@daniel Wow... I never noticed that difference D:
You saved my day thanks! =)
Because on that example one node uses
tx_iq=Trueand 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)?
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)
lora = LoRa(mode=LoRa.LORA)
Otherwise you need to invert the rx_iq on the other side for it to work...