Python 串口通訊操作實現

串口通訊

平常與設備通訊的方式都是串口通訊,常用的協議包括RS-232、RS-422和RS-485。

RS-232

RS-232只限於PC串口和設備間點對點的通信。RS-232串口通信最遠距離是50英尺。
RS-232的接頭是DB-9,但是通常使用最多3個針腳:TXD(2pin)、RXD(3pin)和 GND(5pin)。
注意如果設備只提供接線柱的話,記得TX與設備的RX連接,RX和設備的TX連接。

RS-422

RS-422使用差分信號,RS-232使用非平衡參考地的信號。差分傳輸使用兩根線發送和接收信號,對比RS-232,它能更好的抗噪聲和有更遠的傳輸距離。在工業環境中更好的抗噪性和更遠的傳輸距離是一個很大的優點。

RS-485

有多個設備有通訊能力,你可以使用一個單個RS-485口建立設備網絡。
RS-485是RS-422的超集,因此所有的RS-422設備可以被RS-485控制。RS-485可以用超過4000英尺的線進行串行通行。
RS-485的DB-9接頭定義一般也最多使用到3個引腳:T+(1pin)、T-(2pin)、GND(5pin)
RS-485的通訊由於可以多個設備連接,所以可以通過監聽來獲得上位機和設備的對話。

代碼實現

需要 pyserial庫支持。

每次發送數據的時候需要轉成字節數組後再往COM口發送,否則會數據發送失敗。
python 2.x 和 python 3.x的字節數組轉換有些不一樣
python 2.x 是 data = bytearray.fromhex(value.encode('hex'))
python 3.x 是 data = bytes().fromhex(value)
讀取數據如果需要十六進制 則進行轉換,如果是ascii 則可以直接 打印

以下代碼是python2.x實現

import serial
import serial.tools.list_ports
import time

class myserial:

    COMM = None
    delay = 0.08

    def __init__(self):
        pass
        
    
    def list_ports(self,OS = 0):
        # OS is 0 mean os is windows,OS is 1 mean os is linux 
        # return now search comm port name
        list_p = list(serial.tools.list_ports.comports())
        if OS:
            list_ports_name = [str(i.name) for i in list_p]
        else:
            list_ports_name = [str(i.device) for i in list_p]
        return list_ports_name
    
    def open_serial(self,port=None, baudrate=9600, bytesize=serial.EIGHTBITS, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, 
                    timeout=None, xonxoff=False, rtscts=False, write_timeout=None,
                    dsrdtr=False, inter_byte_timeout=None, exclusive=None):
        # open serial
        self.COMM = serial.Serial(port,baudrate,bytesize,parity,stopbits,timeout,xonxoff,rtscts,write_timeout,dsrdtr,inter_byte_timeout,exclusive)
        return self.COMM 

    def write_ascii(self,value):
        # wtite cmd to serial
        write_data = bytearray.fromhex(value.encode('hex'))
        try:
            self.COMM.write(write_data)
            return True
        except BaseException as e:
            print(e)
            return False

    def read_ascii(self):
        # read data from serail
        try:
            data = self.COMM.read(self.COMM.in_waiting)
            return data
        except BaseException as e:
            print(e)
            return None

    def query_ascii(self,value):
        # query mechine
        write_data = bytearray.fromhex(value.encode('hex'))
        try:
            self.COMM.write(write_data)
            time.sleep(self.delay)
            data = self.COMM.read(self.COMM.in_waiting)
            return data
        except BaseException as e:
            print(e)
            return None

    def write_hex(self,value):
        # wtite cmd to serial
        write_data = value.decode('hex')
        try:
            self.COMM.write(write_data)
            return True
        except BaseException as e:
            print(e)
            return False

    def read_hex(self):
        # read data from serail
        try:
            data = self.COMM.read(self.COMM.in_waiting).encode('hex')
            return data
        except BaseException as e:
            print(e)
            return None

    def query_hex(self,value):
        # query mechine
        write_data = value.decode('hex')
        try:
            self.COMM.write(write_data)
            time.sleep(self.delay)
            data = self.COMM.read(self.COMM.in_waiting).encode('hex')
            return data
        except BaseException as e:
            print(e)
            return None
        

    def close(self):
        self.COMM.close()




if __name__ == "__main__":
    s = myserial()
    a = s.list_ports()
    print(a)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章