Python中串口操作的實(shí)現(xiàn)示例
介紹
基于Python的串口通信功能主要通過使用pyserial
庫來實(shí)現(xiàn)。pyserial
是一個(gè)跨平臺(tái)的Python庫,它提供了對(duì)串行端口(如RS232、USB轉(zhuǎn)串口等)進(jìn)行讀寫操作的支持。下面將詳細(xì)介紹如何使用pyserial
來進(jìn)行串口通信。
安裝PySerial
首先需要安裝pyserial
庫,可以通過pip工具輕松完成:
pip install pyserial
基本概念
波特率(Baud Rate):表示每秒傳輸?shù)臄?shù)據(jù)位數(shù),是串行通信中的一個(gè)重要參數(shù),必須確保發(fā)送端和接收端設(shè)置相同的波特率。
數(shù)據(jù)位(Data Bits):通常為7或8位,指每次傳輸?shù)臄?shù)據(jù)量大小。
停止位(Stop Bits):用于標(biāo)識(shí)一個(gè)字節(jié)結(jié)束的數(shù)量,默認(rèn)情況下為1個(gè)停止位。
校驗(yàn)位(Parity Bit):可選參數(shù),用來檢測(cè)傳輸錯(cuò)誤,有無校驗(yàn)、奇校驗(yàn)和偶校驗(yàn)三種選擇。
流控制(Flow Control):硬件流控(RTS/CTS, DTR/DSR)或軟件流控(XON/XOFF),用于管理數(shù)據(jù)流動(dòng)。
使用PySerial的基本步驟
導(dǎo)入模塊
import serial
from serial.tools import list_ports
查找可用的串口
- 可以使用
list_ports.comports()
函數(shù)列出系統(tǒng)中所有可用的串口設(shè)備。
- 可以使用
打開串口連接
- 使用
serial.Serial()
創(chuàng)建一個(gè)串口對(duì)象,并指定相應(yīng)的參數(shù)(如端口號(hào)、波特率等)。
- 使用
配置串口參數(shù)
- 在創(chuàng)建串口對(duì)象時(shí)可以傳遞額外的關(guān)鍵字參數(shù)來設(shè)置波特率、數(shù)據(jù)位、停止位、校驗(yàn)位等。
讀取與寫入數(shù)據(jù)
- 通過調(diào)用串口對(duì)象的
read()
、write()
方法來進(jìn)行數(shù)據(jù)的讀取和發(fā)送。
- 通過調(diào)用串口對(duì)象的
關(guān)閉串口連接
- 當(dāng)不再需要使用串口時(shí),應(yīng)該調(diào)用
close()
方法來釋放資源。
- 當(dāng)不再需要使用串口時(shí),應(yīng)該調(diào)用
串行通信服務(wù)實(shí)現(xiàn)
這段代碼展示了如何使用 pyserial
庫來管理和操作串行端口,包括列出可用的串行端口、打開和關(guān)閉端口、發(fā)送和接收數(shù)據(jù)。以下是詳細(xì)的功能解析:
環(huán)境準(zhǔn)備
確保安裝了 pyserial
庫,以便能夠訪問和管理串行端口。
pip install pyserial
列出所有串行端口
list_ports
函數(shù)用于掃描系統(tǒng)中的所有串行端口,并返回一個(gè)包含這些端口名稱的列表。它還記錄每個(gè)端口的描述信息和硬件ID,方便調(diào)試或用戶選擇正確的端口。
def list_ports(): port_names = [] ports = serial.tools.list_ports.comports() for port, desc, hwid in ports: log_message(f"Port: {port}, Description: {desc}, HWID: {hwid}") port_names.append(port) return port_names
串行通信服務(wù)類 (CommService)
定義了一個(gè)用于串行通信的服務(wù)類CommService
,以及一個(gè)列出所有可用串行端口的函數(shù)list_ports
。它使用了Python的serial
庫來處理串行通信,并且引入了一些輔助模塊來增強(qiáng)功能
導(dǎo)入模塊
深色版本
import serial import binascii import serial.tools.list_ports from utils.const_util import AppConst
serial
:提供了對(duì)串行端口(如RS232、USB轉(zhuǎn)串等)的訪問。binascii
:包含將二進(jìn)制數(shù)據(jù)轉(zhuǎn)換為ASCII字符串的函數(shù)。serial.tools.list_ports
:提供工具函數(shù)來枚舉系統(tǒng)上的串行端口。utils.const_util.AppConst
:自定義模塊中定義的應(yīng)用常量。
列出所有可用串行端口
深色版本
def list_ports(): port_names = [] ports = serial.tools.list_ports.comports() for port, desc, hwid in ports: print(f"Port: {port}, Description: {desc}, HWID: {hwid}") port_names.append(port) return port_names
list_ports
函數(shù):遍歷所有可用的串行端口,并打印每個(gè)端口的名稱、描述和硬件ID。- 返回一個(gè)包含所有端口名稱的列表,可用于選擇具體的通信端口。
串行通信服務(wù)類
深色版本
class CommService: def __init__(self, comm_port): self.comm_port = comm_port self.ser_comm = None
- 構(gòu)造方法
__init__
:初始化時(shí)設(shè)置串行端口名稱,并將實(shí)際的串行連接對(duì)象初始化為None
。
設(shè)置串行端口
def set_comm_port(self, comm_port): self.comm_port = comm_port
set_comm_port
方法:允許動(dòng)態(tài)更改串行端口名稱。
打開串行連接
def open_comm(self): try: self.ser_comm = serial.Serial(self.comm_port, 9600, bytesize=serial.EIGHTBITS, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, timeout=1, xonxoff=False, rtscts=False, dsrdtr=False) except: return None return self.ser_comm
open_comm
方法:嘗試打開指定的串行端口,并配置波特率、字節(jié)大小、校驗(yàn)位、停止位等參數(shù)。- 如果打開失?。ɡ缍丝诓淮嬖诨蛞驯徽加茫?,捕獲異常并返回
None
;否則返回打開的串行連接對(duì)象。
關(guān)閉串行連接
def close_comm(self): if self.is_opened: self.ser_comm.close() self.ser_comm = None
close_comm
方法:檢查串行連接是否打開,如果是,則關(guān)閉連接并重置連接對(duì)象為None
。
發(fā)送數(shù)據(jù)
def send_comm(self, data): if self.is_opened: try: self.ser_comm.write(bytearray.fromhex(data.replace(' ', ''))) except serial.serialutil.SerialTimeoutException: msg = AppConst.COMM_SEND_OVER return False, msg return True, '' else: msg = AppConst.COMM_SEND_FAILED return False, msg
send_comm
方法:如果串行連接是打開狀態(tài),嘗試發(fā)送十六進(jìn)制格式的數(shù)據(jù)。- 使用
bytearray.fromhex()
將十六進(jìn)制字符串轉(zhuǎn)換為字節(jié)數(shù)組后發(fā)送。 - 捕獲可能發(fā)生的超時(shí)異常,并返回相應(yīng)的錯(cuò)誤信息。
- 成功發(fā)送后返回
True
及空消息,發(fā)送失敗則返回False
及錯(cuò)誤消息。
讀取數(shù)據(jù)
def read_comm(self): if self.is_opened: if self.ser_comm.in_waiting > 0: try: data = self.ser_comm.readline() except: return None return binascii.hexlify(data).decode('ascii') return None else: return None
read_comm
方法:如果串行連接是打開狀態(tài)并且有數(shù)據(jù)待讀取,嘗試讀取一行數(shù)據(jù)。- 使用
binascii.hexlify()
將讀取到的數(shù)據(jù)轉(zhuǎn)換為十六進(jìn)制表示形式,并解碼為ASCII字符串。 - 如果發(fā)生異常或者沒有數(shù)據(jù)可讀,則返回
None
。
檢查連接狀態(tài)
def is_opened(self): return self.ser_comm is not None and self.ser_comm.is_open
is_opened
方法:檢查當(dāng)前是否有有效的串行連接對(duì)象,并且該連接是否處于打開狀態(tài)。
總結(jié)
CommService
類封裝了與串行設(shè)備通信所需的所有基本操作,包括打開/關(guān)閉連接、發(fā)送/接收數(shù)據(jù)以及檢查連接狀態(tài)。它還提供了一個(gè)靜態(tài)方法list_ports
來列出系統(tǒng)上所有的串行端口,這在需要用戶選擇具體端口進(jìn)行通信時(shí)非常有用。此外,通過使用try-except
語句,代碼實(shí)現(xiàn)了簡單的錯(cuò)誤處理邏輯,確保即使在出現(xiàn)問題的情況下也能維持程序的基本運(yùn)行。最后,利用AppConst
中的常量,使得錯(cuò)誤消息可以集中管理,便于維護(hù)和國際化支持。
完整代碼
import serial import binascii import serial.tools.list_ports from utils.const_util import AppConst def list_ports(): port_names = [] ports = serial.tools.list_ports.comports() for port, desc, hwid in ports: print(f"Port: {port}, Description: {desc}, HWID: {hwid}") port_names.append(port) return port_names class CommService: def __init__(self, comm_port): self.comm_port = comm_port self.ser_comm = None def set_comm_port(self, comm_port): self.comm_port = comm_port def open_comm(self): try: self.ser_comm = serial.Serial(self.comm_port, 9600, bytesize=serial.EIGHTBITS, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, timeout=1, xonxoff=False, rtscts=False, dsrdtr=False) except: return None return self.ser_comm def close_comm(self): if self.is_opened: self.ser_comm.close() self.ser_comm = None def send_comm(self, data): if self.is_opened: try: self.ser_comm.write(bytearray.fromhex(data.replace(' ', ''))) except serial.serialutil.SerialTimeoutException: msg = AppConst.COMM_SEND_OVER return False, msg return True, '' else: msg = AppConst.COMM_SEND_FAILED return False, msg def read_comm(self): if self.is_opened: if self.ser_comm.in_waiting > 0: try: data = self.ser_comm.readline() except: return None return binascii.hexlify(data).decode('ascii') return None else: return None def is_opened(self): return self.ser_comm is not None and self.ser_comm.is_open
使用示例
下面是一個(gè)簡單的使用示例,假設(shè)已經(jīng)有一個(gè)實(shí)例化好的 CommService
對(duì)象 comm_service
:
# 列出所有可用的串行端口 available_ports = list_ports() # 假設(shè)選擇了第一個(gè)可用端口進(jìn)行通信 if available_ports: comm_service.set_comm_port(available_ports[0]) ser = comm_service.open_comm() if ser: # 發(fā)送一些數(shù)據(jù)到串行端口 success, msg = comm_service.send_comm("55 AA 01 02 03") if success: print("Data sent successfully.") else: print(f"Failed to send data: {msg}") # 嘗試讀取來自串行端口的數(shù)據(jù) received_data = comm_service.read_comm() if received_data: print(f"Received data: {received_data}") # 關(guān)閉串行端口 comm_service.close_comm() else: print("No available serial ports found.")
通過這種方式,您可以輕松地與連接到計(jì)算機(jī)的任何串行設(shè)備進(jìn)行交互,無論是讀取傳感器數(shù)據(jù)還是控制外部硬件。
到此這篇關(guān)于Python中串口操作的實(shí)現(xiàn)示例的文章就介紹到這了,更多相關(guān)Python 串口操作內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Python中串口通信庫pyserial基礎(chǔ)知識(shí)
- Python讀取串口數(shù)據(jù)的實(shí)現(xiàn)方法
- python讀取串口數(shù)據(jù)有幾種方法
- python serial串口通信示例詳解
- 玩轉(zhuǎn)串口通信:利用pyserial庫,Python打開無限可能
- Python通過串口實(shí)現(xiàn)收發(fā)文件
- Python串口通信的接收與發(fā)送的實(shí)現(xiàn)
- python實(shí)現(xiàn)串口通信的示例代碼
- Python?Serial串口的簡單數(shù)據(jù)收發(fā)方式
- 使用Python玩轉(zhuǎn)串口(基于pySerial問題)
- python串口讀取數(shù)據(jù)的實(shí)例
- 使用 Python 列出串口的實(shí)現(xiàn)方法
相關(guān)文章
10個(gè)有用的Python字符串函數(shù)小結(jié)
本文主要介紹了10個(gè)有用的Python字符串函數(shù)小結(jié),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-08-08python實(shí)現(xiàn)圖像隨機(jī)裁剪的示例代碼
這篇文章主要介紹了python實(shí)現(xiàn)圖像隨機(jī)裁剪的示例代碼,幫助大家更好的理解和使用python處理圖片,感興趣的朋友可以了解下2020-12-12Python使用whisper實(shí)現(xiàn)語音識(shí)別(ASR)的示例代碼
Whisper是OpenAI的一個(gè)強(qiáng)大的語音識(shí)別庫,支持離線的語音識(shí)別,本文主要介紹了Python使用whisper實(shí)現(xiàn)語音識(shí)別(ASR)的示例代碼,具有一定的參考價(jià)值,感興趣的可以了解一下2024-03-03Python機(jī)器學(xué)習(xí)之AdaBoost算法
今天帶大家來學(xué)習(xí)Python機(jī)器學(xué)習(xí),文中對(duì)AdaBoost算法介紹的很詳細(xì),有非常多的代碼示例,對(duì)正在學(xué)習(xí)python的小伙伴們有很好地幫助,需要的朋友可以參考下2021-05-05Python實(shí)現(xiàn)的多線程同步與互斥鎖功能示例
這篇文章主要介紹了Python實(shí)現(xiàn)的多線程同步與互斥鎖功能,涉及Python多線程及鎖機(jī)制相關(guān)操作技巧,需要的朋友可以參考下2017-11-11使用Python實(shí)現(xiàn)博客上進(jìn)行自動(dòng)翻頁
這篇文章主要介紹了使用Python實(shí)現(xiàn)博客上進(jìn)行自動(dòng)翻頁,需要的朋友可以參考下2017-08-08使用pandas實(shí)現(xiàn)連續(xù)數(shù)據(jù)的離散化處理方式(分箱操作)
今天小編就為大家分享一篇使用pandas實(shí)現(xiàn)連續(xù)數(shù)據(jù)的離散化處理方式(分箱操作),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-11-11