序列槽通訊
平常與裝置通訊的方式都是序列槽通訊,常用的協定包括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)