對python3 Serial 串口助手的接收讀取數(shù)據(jù)方法詳解
其實(shí)網(wǎng)上已經(jīng)有許多python語言書寫的串口,但大部分都是python2寫的,沒有找到一個合適的python編寫的串口助手,只能自己來寫一個串口助手,由于我只需要串口能夠接收讀取數(shù)據(jù)就可以了,故而這個串口助手只實(shí)現(xiàn)了數(shù)據(jù)的接收讀取。
創(chuàng)建串口助手首先需要創(chuàng)建一個類,重構(gòu)類的實(shí)現(xiàn)過程如下:
#coding=gb18030 import threading import time import serial class ComThread: def __init__(self, Port='COM3'): #構(gòu)造串口的屬性 self.l_serial = None self.alive = False self.waitEnd = None self.port = Port self.ID = None self.data = None #定義串口等待的函數(shù) def waiting(self): if not self.waitEnd is None: self.waitEnd.wait() def SetStopEvent(self): if not self.waitEnd is None: self.waitEnd.set() self.alive = False self.stop() #啟動串口的函數(shù) def start(self): self.l_serial = serial.Serial() self.l_serial.port = self.port self.l_serial.baudrate = 115200 #設(shè)置等待時間,若超出這停止等待 self.l_serial.timeout = 2 self.l_serial.open() #判斷串口是否已經(jīng)打開 if self.l_serial.isOpen(): self.waitEnd = threading.Event() self.alive = True self.thread_read = None self.thread_read = threading.Thread(target=self.FirstReader) self.thread_read.setDaemon(1) self.thread_read.start() return True else: return False
創(chuàng)建好類后,就要實(shí)現(xiàn)串口讀取的功能,其讀取數(shù)據(jù)的函數(shù)如下:
首先要創(chuàng)建一個字符串來存放接收到的數(shù)據(jù):
data = ''
data = data.encode('utf-8')#由于串口使用的是字節(jié),故而要進(jìn)行轉(zhuǎn)碼,否則串口會不識別
在創(chuàng)建好變量來接收數(shù)據(jù)后就要開始接收數(shù)據(jù):
n = self.l_serial.inWaiting()#獲取接收到的數(shù)據(jù)長度
if n:
#讀取數(shù)據(jù)并將數(shù)據(jù)存入data
data = data + self.l_serial.read(n)
#輸出接收到的數(shù)據(jù)
print('get data from serial port:', data)
#顯示data的類型,便于如果出錯時檢查錯誤
print(type(data))
將數(shù)據(jù)接收完后,就要對接收到的數(shù)據(jù)進(jìn)行處理,提取出有用信息,由于下位機(jī)使用的協(xié)議不一樣,因此處理的方法也不一樣,我使用的協(xié)議是**+ID+*Data+*,因此我的提取方法如下:
#獲取還沒接收到的數(shù)據(jù)長度
n = self.l_serial.inWaiting()
#判斷是否已經(jīng)將下位機(jī)傳輸過來的數(shù)據(jù)全部提取完畢,防止之前沒有獲取全部數(shù)據(jù)
if len(data)>0 and n==0:
try:
#將數(shù)據(jù)轉(zhuǎn)換為字符型
temp = data.decode('gb18030')
#輸出temp類型,看轉(zhuǎn)碼是否成功
print(type(temp))
#輸出接收到的數(shù)據(jù)
print(temp)
將數(shù)據(jù)按換行分割并輸出
car,temp = str(temp).split("\n",1)
print(car,temp)
#將temp按':'分割,并獲取第二個數(shù)據(jù)
string = str(temp).strip().split(":")[1]
#由于前面分割后的數(shù)據(jù)類型是列表,因此需要轉(zhuǎn)換成字符串,而后按照'*'分割,得到的也就是我們需要的Id和data
str_ID,str_data = str(string).split("*",1)
print(str_ID)
print(str_data)
print(type(str_ID),type(str_data))
#判斷data最后一位是否是'*',若是則退出,若不是則輸出異常
if str_data[-1]== '*':
break
else:
print(str_data[-1])
print('str_data[-1]!=*')
except:
print("讀卡錯誤,請重試!\n")
其輸出結(jié)果為:
get data from serial port:b'ID:4A622E29\n\xbf\xa8\xd6\xd0\xbf\xe924\xca\xfd\xbe\xdd\xce\xaa:1*80*\r\n' <class 'bytes'> <class 'str'> ID:4A622E29 卡中塊24數(shù)據(jù)為:1*80* ID:4A622E29 卡中塊24數(shù)據(jù)為:1*80* 80* <class 'str'> <class 'str'>
串口助手完整代碼如下:
#coding=gb18030
import threading
import time
import serial
class ComThread:
def __init__(self, Port='COM3'):
self.l_serial = None
self.alive = False
self.waitEnd = None
self.port = Port
self.ID = None
self.data = None
def waiting(self):
if not self.waitEnd is None:
self.waitEnd.wait()
def SetStopEvent(self):
if not self.waitEnd is None:
self.waitEnd.set()
self.alive = False
self.stop()
def start(self):
self.l_serial = serial.Serial()
self.l_serial.port = self.port
self.l_serial.baudrate = 115200
self.l_serial.timeout = 2
self.l_serial.open()
if self.l_serial.isOpen():
self.waitEnd = threading.Event()
self.alive = True
self.thread_read = None
self.thread_read = threading.Thread(target=self.FirstReader)
self.thread_read.setDaemon(1)
self.thread_read.start()
return True
else:
return False
def SendDate(self,i_msg,send):
lmsg = ''
isOK = False
if isinstance(i_msg):
lmsg = i_msg.encode('gb18030')
else:
lmsg = i_msg
try:
# 發(fā)送數(shù)據(jù)到相應(yīng)的處理組件
self.l_serial.write(send)
except Exception as ex:
pass;
return isOK
def FirstReader(self):
while self.alive:
time.sleep(0.1)
data = ''
data = data.encode('utf-8')
n = self.l_serial.inWaiting()
if n:
data = data + self.l_serial.read(n)
print('get data from serial port:', data)
print(type(data))
n = self.l_serial.inWaiting()
if len(data)>0 and n==0:
try:
temp = data.decode('gb18030')
print(type(temp))
print(temp)
car,temp = str(temp).split("\n",1)
print(car,temp)
string = str(temp).strip().split(":")[1]
str_ID,str_data = str(string).split("*",1)
print(str_ID)
print(str_data)
print(type(str_ID),type(str_data))
if str_data[-1]== '*':
break
else:
print(str_data[-1])
print('str_data[-1]!=*')
except:
print("讀卡錯誤,請重試!\n")
self.ID = str_ID
self.data = str_data[0:-1]
self.waitEnd.set()
self.alive = False
def stop(self):
self.alive = False
self.thread_read.join()
if self.l_serial.isOpen():
self.l_serial.close()
#調(diào)用串口,測試串口
def main():
rt = ComThread()
rt.sendport = '**1*80*'
try:
if rt.start():
print(rt.l_serial.name)
rt.waiting()
print("The data is:%s,The Id is:%s"%(rt.data,rt.ID))
rt.stop()
else:
pass
except Exception as se:
print(str(se))
if rt.alive:
rt.stop()
print('')
print ('End OK .')
temp_ID=rt.ID
temp_data=rt.data
del rt
return temp_ID,temp_data
if __name__ == '__main__':
#設(shè)置一個主函數(shù),用來運(yùn)行窗口,便于若其他地方下需要調(diào)用串口是可以直接調(diào)用main函數(shù)
ID,data = main()
print("******")
print(ID,data)
以上這篇對python3 Serial 串口助手的接收讀取數(shù)據(jù)方法詳解就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
python實(shí)現(xiàn)分析apache和nginx日志文件并輸出訪客ip列表的方法
這篇文章主要介紹了python實(shí)現(xiàn)分析apache和nginx日志文件并輸出訪客ip列表的方法,涉及Python操作日志文件的技巧,非常具有實(shí)用價值,需要的朋友可以參考下2015-04-04
PyTorch一小時掌握之a(chǎn)utograd機(jī)制篇
這篇文章主要介紹了PyTorch一小時掌握之a(chǎn)utograd機(jī)制篇,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-09-09
Python數(shù)據(jù)可視化繪圖實(shí)例詳解
數(shù)據(jù)可視化是指用圖形或表格的方式來呈現(xiàn)數(shù)據(jù)。圖表能夠清楚地呈現(xiàn)數(shù)據(jù)性質(zhì), 以及數(shù)據(jù)間或?qū)傩蚤g的關(guān)系。本文為大家分享了幾個Python數(shù)據(jù)可視化繪圖的實(shí)例,感興趣的可以了解一下2022-05-05
python實(shí)現(xiàn)自動解數(shù)獨(dú)小程序
這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)自動解數(shù)獨(dú)小程序,具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-01-01
python實(shí)現(xiàn)Flappy Bird源碼
這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)Flappy Bird源碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-12-12

