Python中串口操作的實現(xiàn)示例
介紹
基于Python的串口通信功能主要通過使用pyserial庫來實現(xiàn)。pyserial是一個跨平臺的Python庫,它提供了對串行端口(如RS232、USB轉(zhuǎn)串口等)進行讀寫操作的支持。下面將詳細介紹如何使用pyserial來進行串口通信。
安裝PySerial
首先需要安裝pyserial庫,可以通過pip工具輕松完成:
pip install pyserial
基本概念
波特率(Baud Rate):表示每秒傳輸?shù)臄?shù)據(jù)位數(shù),是串行通信中的一個重要參數(shù),必須確保發(fā)送端和接收端設置相同的波特率。
數(shù)據(jù)位(Data Bits):通常為7或8位,指每次傳輸?shù)臄?shù)據(jù)量大小。
停止位(Stop Bits):用于標識一個字節(jié)結(jié)束的數(shù)量,默認情況下為1個停止位。
校驗位(Parity Bit):可選參數(shù),用來檢測傳輸錯誤,有無校驗、奇校驗和偶校驗三種選擇。
流控制(Flow Control):硬件流控(RTS/CTS, DTR/DSR)或軟件流控(XON/XOFF),用于管理數(shù)據(jù)流動。
使用PySerial的基本步驟
導入模塊
import serialfrom serial.tools import list_ports
查找可用的串口
- 可以使用
list_ports.comports()函數(shù)列出系統(tǒng)中所有可用的串口設備。
- 可以使用
打開串口連接
- 使用
serial.Serial()創(chuàng)建一個串口對象,并指定相應的參數(shù)(如端口號、波特率等)。
- 使用
配置串口參數(shù)
- 在創(chuàng)建串口對象時可以傳遞額外的關鍵字參數(shù)來設置波特率、數(shù)據(jù)位、停止位、校驗位等。
讀取與寫入數(shù)據(jù)
- 通過調(diào)用串口對象的
read()、write()方法來進行數(shù)據(jù)的讀取和發(fā)送。
- 通過調(diào)用串口對象的
關閉串口連接
- 當不再需要使用串口時,應該調(diào)用
close()方法來釋放資源。
- 當不再需要使用串口時,應該調(diào)用
串行通信服務實現(xiàn)
這段代碼展示了如何使用 pyserial 庫來管理和操作串行端口,包括列出可用的串行端口、打開和關閉端口、發(fā)送和接收數(shù)據(jù)。以下是詳細的功能解析:
環(huán)境準備
確保安裝了 pyserial 庫,以便能夠訪問和管理串行端口。
pip install pyserial
列出所有串行端口
list_ports 函數(shù)用于掃描系統(tǒng)中的所有串行端口,并返回一個包含這些端口名稱的列表。它還記錄每個端口的描述信息和硬件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串行通信服務類 (CommService)
定義了一個用于串行通信的服務類CommService,以及一個列出所有可用串行端口的函數(shù)list_ports。它使用了Python的serial庫來處理串行通信,并且引入了一些輔助模塊來增強功能
導入模塊
深色版本
import serial import binascii import serial.tools.list_ports from utils.const_util import AppConst
serial:提供了對串行端口(如RS232、USB轉(zhuǎn)串等)的訪問。binascii:包含將二進制數(shù)據(jù)轉(zhuǎn)換為ASCII字符串的函數(shù)。serial.tools.list_ports:提供工具函數(shù)來枚舉系統(tǒng)上的串行端口。utils.const_util.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_nameslist_ports函數(shù):遍歷所有可用的串行端口,并打印每個端口的名稱、描述和硬件ID。- 返回一個包含所有端口名稱的列表,可用于選擇具體的通信端口。
串行通信服務類
深色版本
class CommService:
def __init__(self, comm_port):
self.comm_port = comm_port
self.ser_comm = None- 構(gòu)造方法
__init__:初始化時設置串行端口名稱,并將實際的串行連接對象初始化為None。
設置串行端口
def set_comm_port(self, comm_port):
self.comm_port = comm_portset_comm_port方法:允許動態(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_commopen_comm方法:嘗試打開指定的串行端口,并配置波特率、字節(jié)大小、校驗位、停止位等參數(shù)。- 如果打開失敗(例如端口不存在或已被占用),捕獲異常并返回
None;否則返回打開的串行連接對象。
關閉串行連接
def close_comm(self):
if self.is_opened:
self.ser_comm.close()
self.ser_comm = Noneclose_comm方法:檢查串行連接是否打開,如果是,則關閉連接并重置連接對象為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, msgsend_comm方法:如果串行連接是打開狀態(tài),嘗試發(fā)送十六進制格式的數(shù)據(jù)。- 使用
bytearray.fromhex()將十六進制字符串轉(zhuǎn)換為字節(jié)數(shù)組后發(fā)送。 - 捕獲可能發(fā)生的超時異常,并返回相應的錯誤信息。
- 成功發(fā)送后返回
True及空消息,發(fā)送失敗則返回False及錯誤消息。
讀取數(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 Noneread_comm方法:如果串行連接是打開狀態(tài)并且有數(shù)據(jù)待讀取,嘗試讀取一行數(shù)據(jù)。- 使用
binascii.hexlify()將讀取到的數(shù)據(jù)轉(zhuǎn)換為十六進制表示形式,并解碼為ASCII字符串。 - 如果發(fā)生異?;蛘邲]有數(shù)據(jù)可讀,則返回
None。
檢查連接狀態(tài)
def is_opened(self):
return self.ser_comm is not None and self.ser_comm.is_openis_opened方法:檢查當前是否有有效的串行連接對象,并且該連接是否處于打開狀態(tài)。
總結(jié)
CommService類封裝了與串行設備通信所需的所有基本操作,包括打開/關閉連接、發(fā)送/接收數(shù)據(jù)以及檢查連接狀態(tài)。它還提供了一個靜態(tài)方法list_ports來列出系統(tǒng)上所有的串行端口,這在需要用戶選擇具體端口進行通信時非常有用。此外,通過使用try-except語句,代碼實現(xiàn)了簡單的錯誤處理邏輯,確保即使在出現(xiàn)問題的情況下也能維持程序的基本運行。最后,利用AppConst中的常量,使得錯誤消息可以集中管理,便于維護和國際化支持。
完整代碼
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
使用示例
下面是一個簡單的使用示例,假設已經(jīng)有一個實例化好的 CommService 對象 comm_service:
# 列出所有可用的串行端口
available_ports = list_ports()
# 假設選擇了第一個可用端口進行通信
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}")
# 關閉串行端口
comm_service.close_comm()
else:
print("No available serial ports found.")通過這種方式,您可以輕松地與連接到計算機的任何串行設備進行交互,無論是讀取傳感器數(shù)據(jù)還是控制外部硬件。
到此這篇關于Python中串口操作的實現(xiàn)示例的文章就介紹到這了,更多相關Python 串口操作內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
- Python中串口通信庫pyserial基礎知識
- Python讀取串口數(shù)據(jù)的實現(xiàn)方法
- python讀取串口數(shù)據(jù)有幾種方法
- python serial串口通信示例詳解
- 玩轉(zhuǎn)串口通信:利用pyserial庫,Python打開無限可能
- Python通過串口實現(xiàn)收發(fā)文件
- Python串口通信的接收與發(fā)送的實現(xiàn)
- python實現(xiàn)串口通信的示例代碼
- Python?Serial串口的簡單數(shù)據(jù)收發(fā)方式
- 使用Python玩轉(zhuǎn)串口(基于pySerial問題)
- python串口讀取數(shù)據(jù)的實例
- 使用 Python 列出串口的實現(xiàn)方法
相關文章
Python使用whisper實現(xiàn)語音識別(ASR)的示例代碼
Whisper是OpenAI的一個強大的語音識別庫,支持離線的語音識別,本文主要介紹了Python使用whisper實現(xiàn)語音識別(ASR)的示例代碼,具有一定的參考價值,感興趣的可以了解一下2024-03-03
使用pandas實現(xiàn)連續(xù)數(shù)據(jù)的離散化處理方式(分箱操作)
今天小編就為大家分享一篇使用pandas實現(xiàn)連續(xù)數(shù)據(jù)的離散化處理方式(分箱操作),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-11-11

