Python中pyserial 實(shí)現(xiàn)模擬串口通信的示例詳解
在嵌入式系統(tǒng)開(kāi)發(fā)、工業(yè)自動(dòng)化和物聯(lián)網(wǎng)(IoT)設(shè)備調(diào)試中,串口通信是一種基礎(chǔ)且重要的技術(shù)。Python通過(guò) pyserial
庫(kù)提供了強(qiáng)大的串口通信支持,使得開(kāi)發(fā)者能夠快速實(shí)現(xiàn)串口數(shù)據(jù)的發(fā)送與接收。本文將詳細(xì)介紹如何使用 Python 模擬串口通信,并通過(guò)實(shí)際代碼示例演示其核心功能和應(yīng)用場(chǎng)景。
一、串口通信的基本概念
1.1 什么是串口通信?
串口通信(Serial Communication)是一種通過(guò)串行接口傳輸數(shù)據(jù)的通信方式。它通過(guò)一根數(shù)據(jù)線(xiàn)逐位傳輸數(shù)據(jù),常用于設(shè)備間的點(diǎn)對(duì)點(diǎn)通信。常見(jiàn)的應(yīng)用場(chǎng)景包括:
- 與嵌入式設(shè)備(如 STM32、Arduino)交互。
- 工業(yè)設(shè)備的調(diào)試與監(jiān)控。
- GPS 模塊、傳感器等外設(shè)的數(shù)據(jù)采集。
1.2 串口通信的關(guān)鍵參數(shù)
- 波特率(Baud Rate):數(shù)據(jù)傳輸速率,單位為 bit/s。常見(jiàn)值如 9600、115200。
- 數(shù)據(jù)位(Data Bits):每幀數(shù)據(jù)的位數(shù),通常為 7 或 8 位。
- 停止位(Stop Bits):每幀數(shù)據(jù)的結(jié)束標(biāo)志,通常為 1 或 2 位。
- 校驗(yàn)位(Parity):用于錯(cuò)誤檢測(cè),可選無(wú)校驗(yàn)(None)、奇校驗(yàn)(Odd)、偶校驗(yàn)(Even)等。
- 超時(shí)時(shí)間(Timeout):讀取數(shù)據(jù)時(shí)等待的最長(zhǎng)時(shí)間。
二、Python 串口通信的核心庫(kù):pyserial
2.1 安裝 pyserial
使用 pip
安裝 pyserial
庫(kù):
pip install pyserial
2.2 核心功能
- 打開(kāi)/關(guān)閉串口:通過(guò)
Serial
類(lèi)管理串口連接。 - 數(shù)據(jù)發(fā)送:使用
write()
方法發(fā)送字節(jié)數(shù)據(jù)。 - 數(shù)據(jù)接收:使用
read()
、readline()
等方法接收數(shù)據(jù)。 - 串口參數(shù)配置:靈活設(shè)置波特率、數(shù)據(jù)位、校驗(yàn)位等。
三、Python 模擬串口通信的完整示例
3.1 列出可用的串口設(shè)備
在開(kāi)始通信前,可以先查詢(xún)系統(tǒng)中可用的串口設(shè)備:
import serial.tools.list_ports ports = list(serial.tools.list_ports.comports()) for port in ports: print(f"設(shè)備名: {port.device}, 描述: {port.description}")
運(yùn)行結(jié)果(以 Windows 為例):
設(shè)備名: COM1, 描述: 通信端口 (COM1)
設(shè)備名: COM3, 描述: com0com - serial port emulator (COM3)
設(shè)備名: COM4, 描述: com0com - serial port emulator (COM4)
3.2 配置并打開(kāi)串口
以下代碼演示如何配置串口參數(shù)并打開(kāi)串口:
import serial # 配置串口參數(shù) ser = serial.Serial( port="COM3", # 串口號(hào)(需根據(jù)實(shí)際設(shè)備修改) baudrate=115200, # 波特率 bytesize=serial.EIGHTBITS, # 數(shù)據(jù)位:8 位 parity=serial.PARITY_NONE, # 校驗(yàn)位:無(wú)校驗(yàn) stopbits=serial.STOPBITS_ONE, # 停止位:1 位 timeout=0.5 # 讀取超時(shí)時(shí)間(秒) ) # 檢查串口是否成功打開(kāi) if ser.is_open: print(f"串口 {ser.port} 已成功打開(kāi)") else: print(f"無(wú)法打開(kāi)串口 {ser.port}")
3.3 發(fā)送數(shù)據(jù)到串口
通過(guò) write()
方法向串口發(fā)送數(shù)據(jù)。注意,發(fā)送的數(shù)據(jù)必須是字節(jié)格式(bytes
):
def send_data(ser, data): if ser.is_open: ser.write(data.encode('utf-8')) # 將字符串編碼為字節(jié) print(f"發(fā)送數(shù)據(jù): {data}") else: print("串口未打開(kāi),無(wú)法發(fā)送數(shù)據(jù)") # 示例:發(fā)送 "Hello, Serial!" 到串口 send_data(ser, "Hello, Serial!")
3.4 從串口接收數(shù)據(jù)
接收數(shù)據(jù)的方式有多種,以下是常見(jiàn)的兩種方法:
方法一:讀取指定字節(jié)數(shù)
def read_fixed_bytes(ser, num_bytes): if ser.in_waiting >= num_bytes: # 檢查緩沖區(qū)是否有足夠數(shù)據(jù) data = ser.read(num_bytes) # 讀取指定字節(jié)數(shù) print(f"接收到數(shù)據(jù)({len(data)} 字節(jié)): {data.decode('utf-8')}") else: print("緩沖區(qū)數(shù)據(jù)不足,未讀取到完整數(shù)據(jù)") # 示例:讀取 10 字節(jié)數(shù)據(jù) read_fixed_bytes(ser, 10)
方法二:讀取一行數(shù)據(jù)(直到換行符)
def read_line(ser): if ser.in_waiting > 0: # 檢查是否有數(shù)據(jù)可讀 line = ser.readline() # 讀取一行數(shù)據(jù) print(f"接收到一行數(shù)據(jù): {line.decode('utf-8').strip()}") else: print("未接收到數(shù)據(jù)") # 示例:讀取一行數(shù)據(jù) read_line(ser)
3.5 完整的收發(fā)示例
以下代碼演示了一個(gè)完整的串口通信流程,包括發(fā)送數(shù)據(jù)和循環(huán)接收響應(yīng):
import serial import time # 配置串口 ser = serial.Serial( port="COM3", baudrate=9600, timeout=1 ) # 發(fā)送數(shù)據(jù)并接收響應(yīng) def communicate(): if not ser.is_open: print("串口未打開(kāi),無(wú)法通信") return while True: # 發(fā)送數(shù)據(jù) command = input("請(qǐng)輸入要發(fā)送的數(shù)據(jù)(輸入 'exit' 退出): ") if command.lower() == 'exit': break ser.write(command.encode('utf-8')) # 接收響應(yīng) time.sleep(0.5) # 等待設(shè)備響應(yīng) if ser.in_waiting > 0: response = ser.readline().decode('utf-8').strip() print(f"設(shè)備響應(yīng): {response}") else: print("未收到設(shè)備響應(yīng)") # 關(guān)閉串口 ser.close() print("串口已關(guān)閉") if __name__ == "__main__": communicate()
四、常見(jiàn)問(wèn)題與解決方案
4.1 串口未找到或無(wú)法打開(kāi)
- 原因:串口號(hào)錯(cuò)誤或設(shè)備未連接。
- 解決方法:使用
serial.tools.list_ports
查詢(xún)可用串口,確認(rèn)設(shè)備是否正常連接。
4.2 數(shù)據(jù)接收不完整
- 原因:波特率設(shè)置不一致,或讀取操作未等待足夠時(shí)間。
- 解決方法:確保發(fā)送端和接收端的波特率一致,并適當(dāng)增加
timeout
或time.sleep()
的等待時(shí)間。
4.3 編碼錯(cuò)誤
- 原因:數(shù)據(jù)解碼時(shí)使用的字符集與實(shí)際數(shù)據(jù)不匹配。
- 解決方法:嘗試使用
utf-8
、latin-1
等不同編碼方式,或直接處理字節(jié)數(shù)據(jù)(bytes
)。
五、實(shí)際應(yīng)用場(chǎng)景示例
5.1 與 STM32 通信
假設(shè) STM32 通過(guò)串口返回溫度傳感器數(shù)據(jù),Python 可以實(shí)時(shí)讀取并顯示:
while True: if ser.in_waiting > 0: data = ser.readline().decode('utf-8').strip() print(f"當(dāng)前溫度: {data} ℃") time.sleep(0.1)
5.2 模擬設(shè)備調(diào)試
通過(guò) pyserial
模擬設(shè)備響應(yīng),無(wú)需真實(shí)硬件即可測(cè)試上位機(jī)邏輯:
# 模擬設(shè)備響應(yīng) if command == "GET_STATUS": ser.write(b"Status: OK\r\n") elif command == "GET_VERSION": ser.write(b"Version: 1.0.0\r\n")
六、總結(jié)
通過(guò) pyserial
庫(kù),Python 能夠高效地實(shí)現(xiàn)串口通信,適用于調(diào)試硬件設(shè)備、開(kāi)發(fā)上位機(jī)程序等多種場(chǎng)景。本文通過(guò)詳細(xì)代碼示例,演示了串口的配置、數(shù)據(jù)發(fā)送與接收的核心操作,并提供了常見(jiàn)問(wèn)題的解決方案。掌握這些技能后,開(kāi)發(fā)者可以更輕松地與嵌入式設(shè)備、傳感器或其他串口設(shè)備進(jìn)行交互,提升開(kāi)發(fā)效率和調(diào)試能力。
擴(kuò)展學(xué)習(xí):
- 探索
pyserial
的高級(jí)功能,如異步通信(asyncio
集成)。 - 結(jié)合 GUI 框架(如 PyQt)開(kāi)發(fā)串口調(diào)試工具。
- 使用
pySerial-asyncio
實(shí)現(xiàn)非阻塞串口通信。
到此這篇關(guān)于Python中pyserial 實(shí)現(xiàn)模擬串口通信的示例詳解的文章就介紹到這了,更多相關(guān)Python 模擬串口通信內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Flask數(shù)據(jù)庫(kù)遷移簡(jiǎn)單介紹
這篇文章主要為大家詳細(xì)介紹了Flask數(shù)據(jù)庫(kù)遷移簡(jiǎn)單工作,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-10-10Pycharm主題切換(禁用)導(dǎo)致UI界面顯示異常的解決方案
這篇文章主要介紹了Pycharm主題切換(禁用)導(dǎo)致UI界面顯示異常的原因分析和解決方案,文中通過(guò)圖文結(jié)合的方式給大家介紹的非常詳細(xì),需要的朋友可以參考下2024-06-06python print輸出延時(shí),讓其立刻輸出的方法
今天小編就為大家分享一篇python print輸出延時(shí),讓其立刻輸出的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-01-01python filecmp.dircmp實(shí)現(xiàn)遞歸比對(duì)兩個(gè)目錄的方法
這篇文章主要介紹了python filecmp.dircmp實(shí)現(xiàn)遞歸比對(duì)兩個(gè)目錄的方法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-05-05Django的性能優(yōu)化實(shí)現(xiàn)解析
這篇文章主要介紹了Django的性能優(yōu)化實(shí)現(xiàn)解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-07-07