Python模拟串口通信的示例详解

Written by

in

文章目录
  • 下载: sourceforge.net/projects/com0com/files/latest/download 下载安装完成后,会在设备管理器中新增两个com。 这两个串口是互相接通的,一个com 可以当作上位机,一个com可以当作下位机。创建的一对虚拟串口。 或者利用虚拟串口的软件创建,VSPD(Virtual Serial Port Driver)
  • pyserial模块封装了python对串口的访问,为多平台的使用提供了统一的接口。 import serial import serial.tools.list_ports # 获取所有串口设备实例。 port_list = list(serial.tools.list_ports.comports()) def show_all_com(): # 如果找到串口设备,则依次输出每个设备对应的串口号和描述信息。 port_list_name = [] if len(port_list) <= 0: print(“the serial port can’t find!”) else: for itms in port_list: print(list(itms)[0], list(itms)[1]) port_list_name.append(itms.device) return port_list_name 运行结果 COM1 通信端口 (COM1)COM3 com0com – serial port emulator (COM3)COM4 com0com – serial port emulator (COM4)['COM1', 'COM3', 'COM4']
  • import serial # 打开 COM3,将波特率配置为115200,数据位为7,停止位为2,无校验位,读超时时间为0.5秒。 ser = serial.Serial(port=”COM3″, baudrate=115200, bytesize=serial.SEVENBITS, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_TWO, timeout=0.5) 常用的参数如下: port – 串口设备名或 None。 baudrate – 波特率,可以是50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400, 460800, 500000, 576000, 921600, 1000000, 1152000, 1500000, 2000000, 2500000, 3000000, 3500000, 4000000。 bytesize – 数据位,可取值为:FIVEBITS, SIXBITS, SEVENBITS, EIGHTBITS。 parity – 校验位,可取值为:PARITY_NONE, PARITY_EVEN, PARITY_ODD, PARITY_MARK, PARITY_SPACE。 stopbits – 停止位,可取值为:STOPBITS_ONE, STOPBITS_ONE_POINT_FIVE, STOPBITS_TOW。 xonxoff – 软件流控,可取值为 True, False。 rtscts – 硬件(RTS/CTS)流控,可取值为 True, False。 dsr/dtr – 硬件(DSR/DTR)流控,可取值为 True, False。 timeout – 读超时时间,可取值为 None, 0 或者其他具体数值(支持小数)。当设置为 None 时,表示阻塞式读取,一直读到期望的所有数据才返回;当设置为 0 时,表示非阻塞式读取,无论读取到多少数据都立即返回;当设置为其他数值时,表示设置具体的超时时间(以秒为单位),如果在该时间内没有读取到所有数据,则直接返回。 write_timeout: 写超时时间,可取值为 None, 0 或者其他具体数值(支持小数)。参数值起到的效果参考 timeout 参数。
  • python 实现向一个串口内写数据(发送端),另一个串口内接受数据(接收端) 1.串口类工具 串口类功能函数组成:打开、关闭、发送数据、接受数据、解析保存数据功能 import serial from time import sleep import queue import time from datetime import datetime q = queue.Queue() class SerialPort: def __init__(self, port, buand): self.port = serial.Serial(port, buand) self.port.close() if not self.port.isOpen(): self.port.open() def port_open(self): if not self.port.isOpen(): self.port.open() def port_close(self): self.port.close() #发送数据 def send_data(self): “”” #write() 方法只能发送 bytes 类型的数据,所以需要对字符串进行 encode 编码。 # write() 方法执行完成后,会将发送的字节数作为返回值。 “”” while True: # 循环发送数据 date = datetime.now().strftime(‘%H:%M:%S.%f’)[:-3] print(“send:”, date) self.port.write(date.encode()) time.sleep(1) # 读取数据 def read_data(self): “”” # read()方法默认一次读取一个字节,可以通过传入参数指定每次读取的字节数; read() 方法会将读取的内容作为返回值,类型为 bytes。 “”” while True: count = self.port.inWaiting() if count != 0: recv = self.port.read(count) self.port.flushInput() q.put(recv.decode()) print(“receive:”,recv.decode()) sleep(0.5) #解析保存数据 def save_json(self): while True: if q.empty(): pass else: print(“队列长度”,q.qsize()) data = q.get() print(data) sleep(0.1) 2.发送端 开启一个线程定时发送数据 from tools.LoRaSerial import SerialPort import threading from time import sleep if __name__==’__main__’: baunRate = 115200 serialPort_w = “COM3” mSerial_w = SerialPort(serialPort_w, baunRate) t1 = threading.Thread(target=mSerial_w.send_data) t1.daemon = True t1.start() while True: sleep(10) 3.接收端 ****接收端开启两个线程接收数据:读取数据和解析存储数据。 from tools.LoRaSerial import SerialPort import threading from time import sleep if __name__==’__main__’: threads=[] baunRate = 115200 serialPort_r = “COM4” mSerial_r = SerialPort(serialPort_r, baunRate) t2 = threading.Thread(target=mSerial_r.read_data) threads.append(t2) t3 = threading.Thread(target=mSerial_r.save_json) threads.append(t3) for t in threads: t.start() while True: sleep(10)
  • 从一个线程向另一个线程发送数据最安全的方式可能就是使用 queue 库中的队列了。创建一个被多个线程共享的 Queue 对象,这些线程通过使用put() 和 get() 操作来向队列中添加或者删除元素。 **当终端发送数据量较大时,其数据解析也是比较耗时,可以用消息队列缓存接收到的发送端数据,当接收线程进行IO监听时,负责解析线程去消息队列取消息并解析。如下图,将解析过程时间延迟由0.1至2s。** 为了方便模拟传递数据变化效果,这里用时间函数代替的,实际上设备传递具体消息可解析为具体的json数据格式**** 消息类别 Ori_ID****发送端设备ID des_ID****接收端设备ID CMD****消息类别 VALUE****数组 消息方向 上线消息 1 123 Online [] 终端—网关 心跳消息 1 123 Heart [{“battery”:”60”}] 终端—网关 环境信息 1 123 Env [{“temp”:”35”},{“hum”:”66”}] 终端—网关 控制指令 1 123 Alarm [{“light”:”on”},{“pump”:”Stop”}] 网关—终端 报警消息 123 1 Control [] 终端—网关 备注: 1、 上线消息——-终端启动时给网关发送上线的消息,网关返回该终端的各种数据及运行状态 2、 心跳消息——–终端定期发送心跳消息给网关 3、 环境信息——–终端定期上报各种环境参数 4、 控制指令——-网关发送指令给终端,实现对终端的控制,如开灯、关灯等 5、 报警消息——-设备监测到报警信息,发送报警信息给网关 以上就是Python模拟串口通信的示例详解的详细内容,更多关于Python串口通信的资料请关注风君子博客其它相关文章! 您可能感兴趣的文章: Python应用开发之实现串口通信 使用python pyserial模块串口通信方式 python实现串口通信的示例代码 Python串口通信的接收与发送的实现 玩转串口通信:利用pyserial库,Python打开无限可能 python serial串口通信示例详解 python实现与arduino的串口通信的示例代码 Python中串口通信库pyserial基础知识
  • 目录
    • 1.win 下载虚拟串口
    • 2、确定串口号
    • 3、配置串口
    • 4、串口通信示例
    • 5.运行结果

    本次分享利用Python模拟串口通信案例。当前编程环境,并没有办法接好下位机平台,需要模拟出一个串口,不断发送、接收信息的过程。

    串行通信端口(cluster communication port ),简称串口,即COM口。

    pySerial 是 Python 中用于操作串口的第三方模块,它支持 Windows、Linux、OSX、BSD等多个平台。

    下载: sourceforge.net/projects/com0com/files/latest/download

    下载安装完成后,会在设备管理器中新增两个com。

    这两个串口是互相接通的,一个com 可以当作上位机,一个com可以当作下位机。创建的一对虚拟串口。

    或者利用虚拟串口的软件创建,VSPD(Virtual Serial Port Driver)

    pyserial模块封装了python对串口的访问,为多平台的使用提供了统一的接口。

    import serial
    import serial.tools.list_ports
     
    # 获取所有串口设备实例。
    
    port_list = list(serial.tools.list_ports.comports())
    def show_all_com():
        # 如果找到串口设备,则依次输出每个设备对应的串口号和描述信息。
        port_list_name = []
        if len(port_list) <= 0:
            print("the serial port can't find!")
        else:
            for itms in port_list:
                print(list(itms)[0], list(itms)[1])
                port_list_name.append(itms.device)
    
        return port_list_name
    

    运行结果

    COM1 通信端口 (COM1)
    COM3 com0com – serial port emulator (COM3)
    COM4 com0com – serial port emulator (COM4)
    ['COM1', 'COM3', 'COM4']

    import serial
     
    # 打开 COM3,将波特率配置为115200,数据位为7,停止位为2,无校验位,读超时时间为0.5秒。
    ser = serial.Serial(port="COM3",
                        baudrate=115200,
                        bytesize=serial.SEVENBITS,
                        parity=serial.PARITY_NONE,
                        stopbits=serial.STOPBITS_TWO,
                        timeout=0.5) 
    

    常用的参数如下:

    port – 串口设备名或 None。

    baudrate – 波特率,可以是50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400, 460800, 500000, 576000, 921600, 1000000, 1152000, 1500000, 2000000, 2500000, 3000000, 3500000, 4000000。

    bytesize – 数据位,可取值为:FIVEBITS, SIXBITS, SEVENBITS, EIGHTBITS。

    parity – 校验位,可取值为:PARITY_NONE, PARITY_EVEN, PARITY_ODD, PARITY_MARK, PARITY_SPACE。

    stopbits – 停止位,可取值为:STOPBITS_ONE, STOPBITS_ONE_POINT_FIVE, STOPBITS_TOW。

    xonxoff – 软件流控,可取值为 True, False。

    rtscts – 硬件(RTS/CTS)流控,可取值为 True, False。

    dsr/dtr – 硬件(DSR/DTR)流控,可取值为 True, False。

    timeout – 读超时时间,可取值为 None, 0 或者其他具体数值(支持小数)。当设置为 None 时,表示阻塞式读取,一直读到期望的所有数据才返回;当设置为 0 时,表示非阻塞式读取,无论读取到多少数据都立即返回;当设置为其他数值时,表示设置具体的超时时间(以秒为单位),如果在该时间内没有读取到所有数据,则直接返回。

    write_timeout: 写超时时间,可取值为 None, 0 或者其他具体数值(支持小数)。参数值起到的效果参考 timeout 参数。

    python 实现向一个串口内写数据(发送端),另一个串口内接受数据(接收端)

    1.串口类工具

    串口类功能函数组成:打开、关闭、发送数据、接受数据、解析保存数据功能

    import serial
    from time import sleep
    import queue
    import time
    from datetime import datetime
    
    q = queue.Queue()
    
    class SerialPort:
        def __init__(self, port, buand):
            self.port = serial.Serial(port, buand)
            self.port.close()
            if not self.port.isOpen():
                self.port.open()
    
        def port_open(self):
            if not self.port.isOpen():
                self.port.open()
    
        def port_close(self):
            self.port.close()
    
        #发送数据
        def send_data(self):
            """
            #write() 方法只能发送 bytes 类型的数据,所以需要对字符串进行 encode 编码。
            # write() 方法执行完成后,会将发送的字节数作为返回值。
            """
            while True:   # 循环发送数据
                date = datetime.now().strftime('%H:%M:%S.%f')[:-3]
                print("send:", date)
                self.port.write(date.encode())
                time.sleep(1)
    
        # 读取数据
        def read_data(self):
            """
            #  read()方法默认一次读取一个字节,可以通过传入参数指定每次读取的字节数;
            read() 方法会将读取的内容作为返回值,类型为 bytes。
            """
            while True:
                count = self.port.inWaiting()
                if count != 0:
                    recv = self.port.read(count)
                    self.port.flushInput()
                    q.put(recv.decode())
                    print("receive:",recv.decode())
                sleep(0.5)
    
        #解析保存数据
        def save_json(self):
            while True:
                if q.empty():
                    pass
                else:
                    print("队列长度",q.qsize())
                    data = q.get()
                    print(data)
                sleep(0.1)
    

    2.发送端

    开启一个线程定时发送数据

    from tools.LoRaSerial import SerialPort
    import threading
    from time import sleep
    
    if __name__=='__main__':
        baunRate = 115200
        serialPort_w = "COM3"
        mSerial_w = SerialPort(serialPort_w, baunRate)
        t1 = threading.Thread(target=mSerial_w.send_data)
        t1.daemon = True
        t1.start()
    
        while True:
            sleep(10)
    

    3.接收端

    ****接收端开启两个线程接收数据:读取数据和解析存储数据。

    from tools.LoRaSerial import SerialPort
    import threading
    from time import sleep
    
    if __name__=='__main__':
        threads=[]
        baunRate = 115200
    
        serialPort_r = "COM4"
        mSerial_r = SerialPort(serialPort_r, baunRate)
    
        t2 = threading.Thread(target=mSerial_r.read_data)
        threads.append(t2)
    
        t3 = threading.Thread(target=mSerial_r.save_json)
        threads.append(t3)
    
        for t in threads:
            t.start()
    
        while True:
            sleep(10)
    

    从一个线程向另一个线程发送数据最安全的方式可能就是使用 queue 库中的队列了。创建一个被多个线程共享的 Queue 对象,这些线程通过使用put() 和 get() 操作来向队列中添加或者删除元素。

    **当终端发送数据量较大时,其数据解析也是比较耗时,可以用消息队列缓存接收到的发送端数据,当接收线程进行IO监听时,负责解析线程去消息队列取消息并解析。如下图,将解析过程时间延迟由0.1至2s。
    **

    为了方便模拟传递数据变化效果,这里用时间函数代替的,实际上设备传递具体消息可解析为具体的json数据格式****

    消息类别 Ori_ID****发送端设备ID des_ID****接收端设备ID CMD****消息类别 VALUE****数组 消息方向
    上线消息 1 123 Online [] 终端—网关
    心跳消息 1 123 Heart [{“battery”:”60”}] 终端—网关
    环境信息 1 123 Env [{“temp”:”35”},{“hum”:”66”}] 终端—网关
    控制指令 1 123 Alarm [{“light”:”on”},{“pump”:”Stop”}] 网关—终端
    报警消息 123 1 Control [] 终端—网关

    备注:

    1、 上线消息——-终端启动时给网关发送上线的消息,网关返回该终端的各种数据及运行状态

    2、 心跳消息——–终端定期发送心跳消息给网关

    3、 环境信息——–终端定期上报各种环境参数

    4、 控制指令——-网关发送指令给终端,实现对终端的控制,如开灯、关灯等

    5、 报警消息——-设备监测到报警信息,发送报警信息给网关

    以上就是Python模拟串口通信的示例详解的详细内容,更多关于Python串口通信的资料请关注风君子博客其它相关文章!

    您可能感兴趣的文章:

    • Python应用开发之实现串口通信
    • 使用python pyserial模块串口通信方式
    • python实现串口通信的示例代码
    • Python串口通信的接收与发送的实现
    • 玩转串口通信:利用pyserial库,Python打开无限可能
    • python serial串口通信示例详解
    • python实现与arduino的串口通信的示例代码
    • Python中串口通信库pyserial基础知识

    站内搜索