欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python中串口操作的實(shí)現(xiàn)示例

 更新時(shí)間:2025年01月07日 09:51:13   作者:道友老李  
本文主要介紹了使用Python的pyserial庫進(jìn)行串口通信,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

介紹

基于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ā)送。
  • 關(guān)閉串口連接

    • 當(dāng)不再需要使用串口時(shí),應(yīng)該調(diào)用close()方法來釋放資源。

串行通信服務(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)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論