如何将UDP端口接收的数据发送至LoRa传感器节点?
问题原因与代码修复方案
核心错误点
- 你当前代码直接把
struct.unpack返回的浮点型数据传给LoRa发送接口,rak811的send方法不支持直接发送数值类型,需要转换为字节类型 - 发送间隔设置为
sleep(0)等于无间隔,LoRa模块处理发送需要时间,且LoRaWAN规范对发包频率有严格限制,过频发送会直接被模块拒绝甚至掉线 - 全局异常捕获直接
pass,所有报错都被吞掉,你完全不知道具体是解包失败、LoRa发送失败还是网络掉线 struct.unpack('dddddddddd', data)要求UDP收到的包固定是80字节(10个double,每个占8字节),如果Simulink发送的包长度不对会直接触发错误,被异常捕获吞掉后程序直接退出循环走清理流程
修复后完整代码
from sys import exit from time import sleep from rak811.rak811 import Mode, Rak811 from ttn_secrets import APP_EUI, APP_KEY import socket import struct lora = Rak811() print('LoRa模块初始化中') lora.hard_reset() lora.mode = Mode.LoRaWan lora.band = 'AS923' lora.set_config(app_eui=APP_EUI, app_key=APP_KEY) print('正在接入LoRaWAN网络') lora.join_otaa() lora.dr = 5 # UDP配置 IP = "0.0.0.0" PORT = 50000 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.bind((IP, PORT)) print(f"UDP服务启动,监听端口{PORT}") try: while True: data, addr = sock.recvfrom(1024) # 先校验包长度是否符合要求 if len(data) != 80: print(f"收到无效长度包:{len(data)}字节,跳过") continue # 解包 unpack_data = struct.unpack('dddddddddd', data) send_val = unpack_data[0] print(f"收到数据x1:{send_val}") # 将浮点数转换为4字节单精度浮点字节(如果需要双精度就把f改为d,占8字节) send_bytes = struct.pack('f', send_val) # 发送字节数据 lora.send(send_bytes) print("LoRa发送成功") # 发送间隔至少1秒,可根据你的LoRa频段要求调整,避免违规被网关拒包 sleep(1) # 分类捕获异常,方便排查问题 except KeyboardInterrupt: print("收到终止指令,退出程序") except Exception as e: print(f"运行出错:{e}") finally: print('正在清理资源') sock.close() lora.close() exit(0)
关键修改说明
- 把UDP监听IP改为明确的
0.0.0.0,确保所有网卡的UDP包都能被接收 - 新增包长度校验逻辑,避免长度不对的包导致解包失败
- 新增浮点数据转字节的逻辑,符合LoRa发送接口的参数要求
- 把发送间隔改为1秒,适配LoRa模块处理速度和LoRaWAN规范要求
- 替换全局异常捕获为分类捕获,会打印具体错误信息,方便你排查问题
- 新增UDP socket的释放逻辑,避免端口被占用
内容的提问来源于stack exchange,提问作者Redblast
相关产品推荐
相关产品推荐

