You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Python多线程实现LoRaWAN双向通信及故障排查

Elastel EG500 双向LoRa+RS232通信线程异常排查与修复

问题背景

  • 硬件:两台Elastel EG500(类Raspberry Pi 4)设备
  • 单向通信正常:发送端接收RS232雷达数据→闪灯→发送LoRa包;接收端接收LoRa包→闪灯
  • 双向通信异常:设备可接收RS232数据并触发LoRa发送,但对方无法接收该LoRa包,疑似线程资源冲突问题

核心排查方向

  • LoRa收发线程资源抢占:双向模式下,同一设备同时监听LoRa和RS232,可能存在UART串口或GPIO资源被线程占用,导致LoRa包发送不完整或未发出
  • 线程同步缺失:RS232接收线程与LoRa监听线程未做同步处理,可能导致LoRa发送时模块处于接收阻塞状态,无法切换到发送模式
  • LoRa模块配置错误:双向模式下误将模块设置为单向收发模式,未保留收发切换的兼容性
  • GPIO操作干扰:闪灯的GPIO操作未做线程安全处理,可能阻塞LoRa发送的时序逻辑

修复方案与代码示例

1. 给LoRa串口操作添加互斥锁

确保同一时间只有一个线程访问LoRa模块的串口,避免收发操作冲突:

import threading
from serial import Serial

# 初始化LoRa串口与互斥锁
lora_serial = Serial("/dev/ttyS0", 9600, timeout=0.1)
lora_lock = threading.Lock()

def send_lora_data(data):
    with lora_lock:
        # 发送前切换到发送模式(根据模块AT指令调整)
        lora_serial.write(b"AT+MODE=TX\r\n")
        lora_serial.readline()  # 读取指令响应
        lora_serial.write(data + b"\r\n")
        # 发送完成后切回接收模式
        lora_serial.write(b"AT+MODE=RX\r\n")
        lora_serial.readline()

def listen_lora():
    while True:
        with lora_lock:
            if lora_serial.in_waiting > 0:
                recv_data = lora_serial.readline().strip()
                if recv_data:
                    # 执行闪灯逻辑
                    print(f"Received LoRa data: {recv_data}")
        threading.sleep(0.01)  # 释放CPU资源,避免空循环占用

2. 线程化RS232接收逻辑

将RS232数据接收与LoRa发送封装为独立线程,避免阻塞LoRa监听线程:

def listen_rs232():
    rs232_serial = Serial("/dev/ttyS1", 9600, timeout=0.1)
    while True:
        if rs232_serial.in_waiting > 0:
            radar_data = rs232_serial.readline().strip()
            if radar_data:
                # 执行闪灯逻辑
                print(f"Received radar data: {radar_data}")
                send_lora_data(radar_data)
        threading.sleep(0.01)

# 启动后台线程
threading.Thread(target=listen_lora, daemon=True).start()
threading.Thread(target=listen_rs232, daemon=True).start()

# 主进程保持运行
while True:
    threading.sleep(1)

3. 调整线程优先级(Linux环境)

给LoRa收发线程设置较高优先级,避免被RS232线程长时间抢占(需root权限):

import os

def set_high_priority():
    os.nice(-10)  # 降低nice值,提升线程优先级

# 启动LoRa线程后设置优先级
lora_thread = threading.Thread(target=listen_lora, daemon=True)
lora_thread.start()
set_high_priority()

4. 硬件资源排查

  • 确认RS232与LoRa模块使用的UART端口无冲突(可通过ls /dev/ttyS*查看设备节点)
  • 检查闪灯GPIO引脚是否与LoRa模块的控制引脚(如MODE、RESET)复用,若冲突需调整引脚

内容的提问来源于stack exchange,提问作者shafeen Ahmed

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 18:44:54