Python的串口通信(pyserial)


串口通信是指外設和計算機間,通過數據信號線 、地線、控制線等,按位進行傳輸數據的一種通訊方式。這種通信方式使用的數據線少,在遠距離通信中可以節約通信成本,但其傳輸速度比並行傳輸低。串口是計算機上一種非常通用的設備通信協議。pyserial模塊封裝了python對串口的訪問,為多平台的使用提供了統一的接口。

 安裝:

pip3 install pyserial

 測試:

兩個CH340 (TTL轉串口模塊)接入到PC串口上,通過Python進行數據交互:

 簡單串口程序實現:

import serial #導入模塊
try:
  #端口,GNU / Linux上的/ dev / ttyUSB0 等 或 Windows上的 COM3 等
  portx="COM3"
  #波特率,標准值之一:50,75,110,134,150,200,300,600,1200,1800,2400,4800,9600,19200,38400,57600,115200
  bps=115200
  #超時設置,None:永遠等待操作,0為立即返回請求結果,其他值為等待超時時間(單位為秒)
  timex=5
  # 打開串口,並得到串口對象
  ser=serial.Serial(portx,bps,timeout=timex)

  # 寫數據
  result=ser.write("我是東小東".encode("gbk"))
  print("寫總字節數:",result)

  ser.close()#關閉串口

except Exception as e:
    print("---異常---:",e)

 

 

 獲取可用串口列表:

import serial #導入模塊

import serial.tools.list_ports
port_list = list(serial.tools.list_ports.comports())
print(port_list)
if len(port_list) == 0:
   print('無可用串口')
else:
    for i in range(0,len(port_list)):
        print(port_list[i])

 

十六進制處理:

import serial #導入模塊
try:
  portx="COM3"
  bps=115200
  #超時設置,None:永遠等待操作,0為立即返回請求結果,其他值為等待超時時間(單位為秒)
  timex=None
  ser=serial.Serial(portx,bps,timeout=timex)
  print("串口詳情參數:", ser)

  #十六進制的發送
  result=ser.write(chr(0x06).encode("utf-8"))#寫數據
  print("寫總字節數:",result)

  #十六進制的讀取
  print(ser.read().hex())#讀一個字節

  print("---------------")
  ser.close()#關閉串口

except Exception as e:
    print("---異常---:",e)

 

 其他細節補充:

import serial #導入模塊
try:

  #端口,GNU / Linux上的/ dev / ttyUSB0 等 或 Windows上的 COM3 等
  portx="COM3"
  #波特率,標准值之一:50,75,110,134,150,200,300,600,1200,1800,2400,4800,9600,19200,38400,57600,115200
  bps=115200
  #超時設置,None:永遠等待操作,0為立即返回請求結果,其他值為等待超時時間(單位為秒)
  timex=5
  # 打開串口,並得到串口對象
  ser=serial.Serial(portx,bps,timeout=timex)
  print("串口詳情參數:", ser)



  print(ser.port)#獲取到當前打開的串口名
  print(ser.baudrate)#獲取波特率

  result=ser.write("我是東小東".encode("gbk"))#寫數據
  print("寫總字節數:",result)


  #print(ser.read())#讀一個字節
  # print(ser.read(10).decode("gbk"))#讀十個字節
  #print(ser.readline().decode("gbk"))#讀一行
  #print(ser.readlines())#讀取多行,返回列表,必須匹配超時(timeout)使用
  #print(ser.in_waiting)#獲取輸入緩沖區的剩余字節數
  #print(ser.out_waiting)#獲取輸出緩沖區的字節數

  #循環接收數據,此為死循環,可用線程實現
  while True:
         if ser.in_waiting:
             str=ser.read(ser.in_waiting ).decode("gbk")
             if(str=="exit"):#退出標志
                 break
             else:
               print("收到數據:",str)

  print("---------------")
  ser.close()#關閉串口


except Exception as e:
    print("---異常---:",e)

 

部分封裝:

其中讀數據的封裝方法並不是很好用,使用的話又得循環接收,這樣反而更加復雜了

import serial #導入模塊
import threading
STRGLO="" #讀取的數據
BOOL=True  #讀取標志位

#讀數代碼本體實現
def ReadData(ser):
    global STRGLO,BOOL
    # 循環接收數據,此為死循環,可用線程實現
    while BOOL:
        if ser.in_waiting:
            STRGLO = ser.read(ser.in_waiting).decode("gbk")
            print(STRGLO)


#打開串口
# 端口,GNU / Linux上的/ dev / ttyUSB0 等 或 Windows上的 COM3 等
# 波特率,標准值之一:50,75,110,134,150,200,300,600,1200,1800,2400,4800,9600,19200,38400,57600,115200
# 超時設置,None:永遠等待操作,0為立即返回請求結果,其他值為等待超時時間(單位為秒)
def DOpenPort(portx,bps,timeout):
    ret=False
    try:
        # 打開串口,並得到串口對象
        ser = serial.Serial(portx, bps, timeout=timeout)
        #判斷是否打開成功
        if(ser.is_open):
           ret=True
           threading.Thread(target=ReadData, args=(ser,)).start()
    except Exception as e:
        print("---異常---:", e)
    return ser,ret



#關閉串口
def DColsePort(ser):
    global BOOL
    BOOL=False
    ser.close()



#寫數據
def DWritePort(ser,text):
    result = ser.write(text.encode("gbk"))  # 寫數據
    return result




#讀數據
def DReadPort():
    global STRGLO
    str=STRGLO
    STRGLO=""#清空當次讀取
    return str



if __name__=="__main__":
    ser,ret=DOpenPort("COM6",115200,None)
    if(ret==True):#判斷串口是否成功打開
         count=DWritePort(ser,"我是東小東,哈哈")
         print("寫入字節數:",count)
         #DReadPort() #讀串口數據
         #DColsePort(ser)  #關閉串口

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM