2022年 11月 4日

python 的串口通信

串口通信是指外设和计算机间,通过数据信号线 、地线、控制线等,按位进行传输数据的一种通讯方式。这种通信方式使用的数据线少,在远距离通信中可以节约通信成本,但其传输速度比并行传输低。串口是计算机上一种非常通用的设备通信协议。pyserial模块封装了python对串口的访问,为多平台的使用提供了统一的接口。

安装

 pip3 install pyserial

测试:

两个 串口转usp线对接后接入到PC USB口上,通过Python进行数据交互:

简单串口程序实现:

  1. import serial #导入模块
  2. try:
  3. #端口,GNU / Linux上的/ dev / ttyUSB0 等 或 Windows上的 COM3 等
  4. portx="COM3"
  5. #波特率,标准值之一:50,75,110,134,150,200,300,600,1200,1800,2400,4800,9600,19200,38400,57600,115200
  6. bps=115200
  7. #超时设置,None:永远等待操作,0为立即返回请求结果,其他值为等待超时时间(单位为秒)
  8. timex=5
  9. # 打开串口,并得到串口对象
  10. ser=serial.Serial(portx,bps,timeout=timex)
  11. # 写数据
  12. result=ser.write("我是东小东".encode("gbk"))
  13. print("写总字节数:",result)
  14. ser.close()#关闭串口
  15. except Exception as e:
  16. print("---异常---:",e)

  获取可用串口列表:

  1. import serial #导入模块
  2. import serial.tools.list_ports
  3. port_list = list(serial.tools.list_ports.comports())
  4. print(port_list)
  5. if len(port_list) == 0:
  6. print('无可用串口')
  7. else:
  8. for i in range(0,len(port_list)):
  9. print(port_list[i])

 十六进制处理:

  1. import serial #导入模块
  2. try:
  3. portx="COM3"
  4. bps=115200
  5. #超时设置,None:永远等待操作,0为立即返回请求结果,其他值为等待超时时间(单位为秒)
  6. timex=None
  7. ser=serial.Serial(portx,bps,timeout=timex)
  8. print("串口详情参数:", ser)
  9. #十六进制的发送
  10. result=ser.write(chr(0x06).encode("utf-8"))#写数据
  11. print("写总字节数:",result)
  12. #十六进制的读取
  13. print(ser.read().hex())#读一个字节
  14. print("---------------")
  15. ser.close()#关闭串口
  16. except Exception as e:
  17. print("---异常---:",e)

其他细节补充:

  1. import serial #导入模块
  2. try:
  3. #端口,GNU / Linux上的/ dev / ttyUSB0 等 或 Windows上的 COM3 等
  4. portx="COM3"
  5. #波特率,标准值之一:50,75,110,134,150,200,300,600,1200,1800,2400,4800,9600,19200,38400,57600,115200
  6. bps=115200
  7. #超时设置,None:永远等待操作,0为立即返回请求结果,其他值为等待超时时间(单位为秒)
  8. timex=5
  9. # 打开串口,并得到串口对象
  10. ser=serial.Serial(portx,bps,timeout=timex)
  11. print("串口详情参数:", ser)
  12. print(ser.port)#获取到当前打开的串口名
  13. print(ser.baudrate)#获取波特率
  14. result=ser.write("我是东小东".encode("gbk"))#写数据
  15. print("写总字节数:",result)
  16. #print(ser.read())#读一个字节
  17. # print(ser.read(10).decode("gbk"))#读十个字节
  18. #print(ser.readline().decode("gbk"))#读一行
  19. #print(ser.readlines())#读取多行,返回列表,必须匹配超时(timeout)使用
  20. #print(ser.in_waiting)#获取输入缓冲区的剩余字节数
  21. #print(ser.out_waiting)#获取输出缓冲区的字节数
  22. #循环接收数据,此为死循环,可用线程实现
  23. while True:
  24. if ser.in_waiting:
  25. str=ser.read(ser.in_waiting ).decode("gbk")
  26. if(str=="exit"):#退出标志
  27. break
  28. else:
  29. print("收到数据:",str)
  30. print("---------------")
  31. ser.close()#关闭串口
  32. except Exception as e:
  33. print("---异常---:",e)

部分封装:

其中读数据的封装方法并不是很好用,使用的话又得循环接收,这样反而更加复杂了

  1. import serial #导入模块
  2. import threading
  3. STRGLO="" #读取的数据
  4. BOOL=True #读取标志位
  5. #读数代码本体实现
  6. def ReadData(ser):
  7. global STRGLO,BOOL
  8. # 循环接收数据,此为死循环,可用线程实现
  9. while BOOL:
  10. if ser.in_waiting:
  11. STRGLO = ser.read(ser.in_waiting).decode("gbk")
  12. print(STRGLO)
  13. #打开串口
  14. # 端口,GNU / Linux上的/ dev / ttyUSB0 等 或 Windows上的 COM3 等
  15. # 波特率,标准值之一:50,75,110,134,150,200,300,600,1200,1800,2400,4800,9600,19200,38400,57600,115200
  16. # 超时设置,None:永远等待操作,0为立即返回请求结果,其他值为等待超时时间(单位为秒)
  17. def DOpenPort(portx,bps,timeout):
  18. ret=False
  19. try:
  20. # 打开串口,并得到串口对象
  21. ser = serial.Serial(portx, bps, timeout=timeout)
  22. #判断是否打开成功
  23. if(ser.is_open):
  24. ret=True
  25. threading.Thread(target=ReadData, args=(ser,)).start()
  26. except Exception as e:
  27. print("---异常---:", e)
  28. return ser,ret
  29. #关闭串口
  30. def DColsePort(ser):
  31. global BOOL
  32. BOOL=False
  33. ser.close()
  34. #写数据
  35. def DWritePort(ser,text):
  36. result = ser.write(text.encode("gbk")) # 写数据
  37. return result
  38. #读数据
  39. def DReadPort():
  40. global STRGLO
  41. str=STRGLO
  42. STRGLO=""#清空当次读取
  43. return str
  44. if __name__=="__main__":
  45. ser,ret=DOpenPort("COM6",115200,None)
  46. if(ret==True):#判断串口是否成功打开
  47. count=DWritePort(ser,"我是东小东,哈哈")
  48. print("写入字节数:",count)
  49. #DReadPort() #读串口数据
  50. #DColsePort(ser) #关闭串口