bsb036 2024-02-27 18:32 采纳率: 43.8%
浏览 5
已结题

串口通信传输字符的质量控制

利用ChatGPT设计了两个通过串口收发信息的程序,接收端在收到信息后,将信息拆解再插入数据库,目前在串口通信时,一条100余字节的信息,第一次发送时只会接收到信息的1/3,第二次发送时,接收到第一次发送信息的后2/3和第二次的1/3组合,第三次又是第二次的2/3和第三次的1/3组合,以此类推。
实际使用中会发送至少100-200字符的信息,请教如何做到接收信息的完整。以下为发送端的部分代码:

def send_data(self):
        try:
            # 获取勾选项状态
            selected_options = [option for option, var in self.options.items() if var.get() == 1]
        
            # 获取单选项内容
            alert_type = self.alert_type_var.get()
        
            # 获取填写项内容
            author = self.author_var.get()
        
            # 获取当前时间
            current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")[:-3]
        
            # 获取文本编辑框内容
            message = self.text_box.get("1.0", tk.END)
        
            # 构建数据字符串
            data_to_send = f"Tables: {', '.join(selected_options)} | EventKind: {alert_type} | Event: {message} | team: 清风班组 | Writer: {author} | DT: {current_time} | subKind: 其他 | MSG_From: QX2 | ENDHERE"
    
            # 调用串口通信实例的 send_data 方法发送数据
            self.serial_communicator.send_data(data_to_send)
            
            print("Sending data:", data_to_send)

        except Exception as e:
            print(f"Error sending data: {e}")

接收端的代码:

    def receive_data(self):
        while True:
            try:
                if self.serial_communicator and self.serial_communicator.is_open:
                    # 清空队列中的旧数据
                    with self.receive_queue.mutex:
                        self.receive_queue.queue.clear()
                    # 从串口读取数据
                    received_data = self.serial_communicator.readline().decode('utf-8')
                    # 判断是否包含结束符号
                    if 'ENDHERE' in received_data:
                        # 找到结束符号时,截取到结束符号之前的部分
                        received_data = received_data.split('ENDHERE')[0]                    
                    print(received_data)
    
                    # 将接收到的数据放入队列
                    self.receive_queue.put(received_data)
    
                    # 立即处理接收到的数据
                    self.process_received_data()
    
            except Exception as e:
                print(f"Error receiving data: {e}")

  • 写回答

13条回答 默认 最新

  • 专家-郭老师 Java领域新星创作者 2024-02-27 18:33
    关注

    🌈🌈🌈参考通义千问和郭老师的小迷弟雅思莫了-编写提供🌈🌈🌈
    您可以参考如下,如果回答的不正确,及时评论区回复我,我会根据你错误描述追加回复,直到您满意为止。

    看起来你的程序在处理接收到的数据时存在问题,你提到数据被“拆片”接收,这个现象非常像是使用串行通讯时的一种常见问题,那就是数据分块。当发送方连续快速发送大量数据时,接收方可能会在任何字节间隔接收到这些数据,这是由于物理层异步串行通信的特性决定的。为了解决这个问题,通常我们需要在应用层做一些处理。
    这里有一个可能的解决方案,可以尝试调整你的接收代码如下:

        def receive_data(self):
            received_data = ""  // 初始化接收数据的字符串
            while True:
                try:
                    if self.serial_communicator and self.serial_communicator.is_open:
                        # 从串口读取一行数据
                        received_data += self.serial_communicator.readline().decode('utf-8')
                        # 判断是否包含结束符号
                        if 'ENDHERE' in received_data:
                            # 找到结束符号时,截取到结束符号之前的部分,并清空接收数据字符串
                            data_to_process = received_data.split('ENDHERE')[0]
                            received_data = ""
                            print(data_to_process)
    
                            # 将接收到的数据放入队列
                            self.receive_queue.put(data_to_process)
    
                            # 立即处理接收到的数据
                            self.process_received_data()
    
                except Exception as e:
                    print(f"Error receiving data: {e}")
    
    
    

    在这个修正版本的receive_data方法中,received_data被改为一个持久变量,它不会在每次循环开始时被重置。每次从串口收到数据时,数据都会被添加到received_data变量中,而不是替换它。如果在received_data中找到了ENDHERE字符串,那么数据被拆分,一部分数据被取出来处理,剩余的数据留在received_data中,等待接收进一步的数据。这样,即使你的数据在多次readline()调用中被分割,你的程序也能正确地处理这些数据。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(12条)

报告相同问题?

问题事件

  • 系统已结题 3月9日
  • 已采纳回答 3月1日
  • 创建了问题 2月27日

悬赏问题

  • ¥15 c#里的静态变量为什么是错误的?
  • ¥15 服务器安装php5.6版本
  • ¥15 我想用51单片机和数码管做一个从0开始的计数表 我写了一串代码 但是放到单片机里面数码管只闪烁一下然后熄灭
  • ¥20 系统工程中,状态空间模型中状态方程的应用。请猛男来完整讲一下下面所有问题
  • ¥15 我想在WPF的Model Code中获取ViewModel Code中的一个参数
  • ¥15 arcgis处理土地利用道路 建筑 林地分类
  • ¥20 使用visual studio 工具用C++语音,调用openslsx库读取excel文件的sheet问题
  • ¥100 寻会做云闪付tn转h5支付链接的技术
  • ¥15 DockerSwarm跨节点无法访问问题
  • ¥15 使用dify通过OpenAI 的API keys添加OpenAI模型时报了“Connection Error”错误