Python3 实现串口同时读写:多线程日志记录与退出机制

小石头
小石头
发布时间:2026-10-12| 3人浏览过
原创

本文介绍如何使用 Python3 的 threading 模块实现串口的同时读写功能。通过创建独立的接收和发送线程,程序能够实时记录收发数据到日志文件,并在接收到特定字符(如 'q')时安全退出。代码示例展示了串口初始化、线程管理及异常处理的具体实现。

实现思路与核心逻辑

在串口通信应用中,通常需要同时进行数据的发送与接收。Python 提供了 threading 模块,允许我们创建多个线程来并行处理这些任务。本方案的核心在于:

  • 使用两个独立的线程分别负责读取和发送数据。
  • 将发送和接收的数据分别记录到不同的日志文件中,便于后续分析。
  • 通过检测特定字符(如 'q')来触发程序的正常退出。

代码实现详解

以下代码展示了如何实现上述功能。代码中定义了一个 SerThread 类,封装了串口的初始化和线程管理逻辑。

import threading,time
import serial
import string
 
 
class SerThread:
  def __init__(self, Port=0):
    #初始化串口、blog文件名称
    self.my_serial = serial.Serial()
    self.my_serial.port=Port
    self.my_serial.baudrate = 9600
    self.my_serial.timeout = 1    
    self.alive = False
    self.waitEnd = None
    fname=time.strftime("%Y%m%d")#blog名称为当前时间
    self.rfname='r'+fname #接收blog名称
    self.sfname='s'+fname #发送blog名称
    self.thread_read= None
    self.thread_send=None   
       
  def waiting(self):
    # 等待event停止标志
    if not self.waitEnd is None:
      self.waitEnd.wait()
  
  def start(self):
    #开串口以及blog文件 
    self.rfile=open(self.rfname,'w')
    self.sfile=open(self.sfname,'w')
    self.my_serial.open()
       
    if self.my_serial.isOpen():
      self.waitEnd = threading.Event()
      self.alive = True
      
      self.thread_read = threading.Thread(target=self.Reader)
      self.thread_read.setDaemon(True)
      
      self.thread_send=threading.Thread(target=self.Sender)
      self.thread_send.setDaemon(True)
      
      self.thread_read.start()
      self.thread_send.start()
      return True
    else:
      return False
  
  def Reader(self):
    while self.alive:
      try:
        n=self.my_serial.inWaiting()
        data=''
        if n:
          data= self.my_serial.read(n).decode('utf-8')       
          print ('recv'+' '+time.strftime("%Y-%m-%d %X")+' '+data.strip())
          print (time.strftime("%Y-%m-%d %X:")+data.strip(),file=self.rfile)
          if len(data)==1 and ord(data[len(data)-1])==113: #收到字母q,程序退出
            break
      except Exception as ex:
        print (ex)
        
    self.waitEnd.set()
    self.alive = False
  
  def Sender(self):
    while self.alive:
      try:
        snddata=input("input data:\n")
        self.my_serial.write(snddata.encode('utf-8'))
        print ('sent'+' '+ time.strftime("%Y-%m-%d %X"))
        print (snddata,file=self.sfile) 
        
      except Exception as ex:
        print (ex)
    
    self.waitEnd.set()
    self.alive = False          
        
  def stop(self):
    self.alive = False
    #self.thread_read.join()
    #self.thread_send.join()
    if self.my_serial.isOpen():
      self.my_serial.close()
    self.rfile.close()
    self.sfile.close()
      
if __name__ == '__main__':  
  
  ser = SerThread('com4')
  try:
    if ser.start():
      ser.waiting()
      ser.stop()
    else:
      pass;      
  except Exception as ex:
    print (ex)
  
  if ser.alive:
    ser.stop()
  
  print ('End OK .');
  del ser; 

关键步骤说明

  1. 初始化串口:在 __init__ 方法中,设置串口号、波特率和超时时间。
  2. 创建线程:在 start 方法中,创建接收和发送线程,并设置为守护线程。
  3. 数据记录:接收和发送的数据分别写入以日期命名的日志文件中。
  4. 退出机制:当接收到字符 'q' 时,触发退出标志,程序安全退出。

注意事项

  • 确保串口未被其他程序占用。
  • 日志文件路径需有写入权限。
  • 处理异常时,记录错误信息有助于调试。

以上就是 Python3 实现串口同时读写:多线程收发与日志记录的详细内容,更多关于 Python 串口通信的资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。