我和我的星星都醉了 2023-07-18 16:40 采纳率: 60%
浏览 74
已结题

关于#python#的问题:模拟串口通讯时,使用自定义的帧协议,并在PC电脑上实现数据的打包发出与解析接收,但代码在接收数据的时候跑不通,加了try后显示一直都是等待数据超时

模拟串口通讯时,使用自定义的帧协议,并在PC电脑上实现数据的打包发出与解析接收,但代码在接收数据的时候跑不通,直接卡死了,加了try后显示一直都是等待数据超时。各位请看看是什么情况

import time
import queue
from threading import Thread

# 定义帧协议格式
FRAME_LENGTH = 15
FRAME_HEADER = bytes.fromhex('AA55')
FRAME_RESERVE = bytes.fromhex('00000000000000')

def pack_data(raw_data):
    # 将原始数据转换成符合帧协议的数据
    # 在这个例子中,假设原始数据为 3 个整数
    data = list(raw_data)
    cs = sum(data) % 256
    frame = FRAME_HEADER + bytes([0x01] + data) + FRAME_RESERVE + bytes([cs])
    return frame

def unpack_data(frame):
    # 解析帧协议格式的数据,返回原始数据
    if len(frame) != FRAME_LENGTH or frame[:2] != FRAME_HEADER:
        return None
    data = tuple(frame[3:6])
    return data

class Serial:
    def __init__(self, port, baudrate, timeout):
        self.port = port
        self.baudrate = baudrate
        self.timeout = timeout
        self.buffer = b''
    
    def write(self, data):
        # 模拟串口发送数据
        print('[发送数据]', data.hex())
        time.sleep(1)  # 模拟发送数据需要的时间
    
    def read(self, size):
        # 模拟串口接收数据
        while len(self.buffer) < size:
            time.sleep(0.1)  # 模拟接收数据需要的时间
        data = self.buffer[:size]
        self.buffer = self.buffer[size:]
        print('[接收数据]', data.hex())
        return data
    
    def receive(self, data):
        # 模拟串口接收数据
        self.buffer += data

def receive_data(ser, queue):
    while True:
        raw_frame = ser.read(FRAME_LENGTH)
        if raw_frame:
            # 解析接收到的数据,并输出原始数据
            data = unpack_data(raw_frame)
            if data:
                queue.put(data)

# 创建串口对象
ser = Serial(port='/dev/ttyUSB0', baudrate=9600, timeout=1)
# 创建队列对象
data_queue = queue.Queue()

# 启动线程,用于接收数据
thread = Thread(target=receive_data, args=(ser, data_queue))
thread.daemon = True
thread.start()

while True:
    # 读取原始数据
    raw_data = input('请输入原始数据(3 个整数,以空格分隔):')
    try:
        # 将原始数据转换成帧协议格式的数据,并发送
        frame = pack_data(map(int, raw_data.split()))
        ser.write(frame)
        # 等待接收数据
        try:
            data = data_queue.get(block=True, timeout=10)
            print('已接收数据:', data)
        except queue.Empty:
            print('等待数据超时。')
    except ValueError:
        print('输入的数据不是 3 个整数,请重新输入。')
    except Exception as e:
        print('串口通信异常:', e)
    print('------------------------')

img

  • 写回答

7条回答 默认 最新

  • bobhuang 2023-07-18 17:18
    关注

    这个程序有两个线程。主线程接收键盘输入,然后用print模拟串口发数据。receive_data线程,调用Serial对象的read接口,模拟串口收数据。现在缺少一个线程调用Serial对象的receive接口,给串口模拟对象喂数据。所以receive_data始终收不到数据。因为Queue.get会阻塞等待,所以一直超时。

    解决方式:建议增加一个线程,给Serial对象喂数据。

    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 7月25日
  • 赞助了问题酬金15元 7月18日
  • 修改了问题 7月18日
  • 创建了问题 7月18日

悬赏问题

  • ¥30 STM32 INMP441无法读取数据
  • ¥100 求汇川机器人IRCB300控制器和示教器同版本升级固件文件升级包
  • ¥15 用visualstudio2022创建vue项目后无法启动
  • ¥15 x趋于0时tanx-sinx极限可以拆开算吗
  • ¥500 把面具戴到人脸上,请大家贡献智慧
  • ¥15 任意一个散点图自己下载其js脚本文件并做成独立的案例页面,不要作在线的,要离线状态。
  • ¥15 各位 帮我看看如何写代码,打出来的图形要和如下图呈现的一样,急
  • ¥30 c#打开word开启修订并实时显示批注
  • ¥15 如何解决ldsc的这条报错/index error
  • ¥15 VS2022+WDK驱动开发环境