日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > python >内容正文

python

android 串口一直打开_实例 | 使用Python串口实时显示数据并绘图

發(fā)布時(shí)間:2023/12/19 python 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 android 串口一直打开_实例 | 使用Python串口实时显示数据并绘图 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

今天為大家分享一篇使用Python串口實(shí)時(shí)顯示數(shù)據(jù)并繪圖的例子,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。

一、安裝pyserial以及基本用法

使用pyserial進(jìn)行串口傳輸,在cmd下輸入命令pip install pyserial

注:升級(jí)pip后會(huì)出現(xiàn) "‘E:\Anaconda3\Scripts\pip-script.py' is not present."錯(cuò)誤

使用 easy_install pip命令就能解決,換一條重新能執(zhí)行安裝的命令。

常用方法:

ser = serial.Serial(0) 是打開第一個(gè)串口

print ser.portstr 能看到第一個(gè)串口的標(biāo)識(shí),windows下是COM1

ser.write(“hello") 就是往串口里面寫數(shù)據(jù)

ser.close() 就是關(guān)閉ser表示的串口

ser.open() 會(huì)打開這個(gè)串口

ser = serial.Serial(‘COM1', 115200) 來(lái)設(shè)置波特率,當(dāng)然還有專門的函數(shù)

data = ser.read()可以讀一個(gè)字符

data = ser.read(20) 是讀20個(gè)字符

data = ser.readline() 是讀一行,以/n結(jié)束,要是沒有/n就一直讀,阻塞。

data = ser.readlines()和ser.xreadlines()都需要設(shè)置超時(shí)時(shí)間

ser.baudrate = 9600 設(shè)置波特率

ser 來(lái)查看當(dāng)前串口的狀態(tài)

ser.isOpen() 看看這個(gè)串口是否已經(jīng)被打開

串行口的屬性:

name:設(shè)備名字 portstr:已廢棄,用name代替 port:讀或者寫端口 baudrate:波特率

bytesize:字節(jié)大小 parity:校驗(yàn)位 stopbits:停止位 timeout:讀超時(shí)設(shè)置

writeTimeout:寫超時(shí) xonxoff:軟件流控 rtscts:硬件流控 dsrdtr:硬件流控

interCharTimeout:字符間隔超時(shí)

二、最基本的串口代碼

import serialportx="COM5"bps=9600timex=5#串口執(zhí)行到這已經(jīng)打開 再用open命令會(huì)報(bào)錯(cuò)ser = serial.Serial(portx, int(bps), timeout=1, parity=serial.PARITY_NONE,stopbits=1)if (ser.isOpen()):print("open success")# 向端口些數(shù)據(jù) 字符串必須譯碼ser.write("hello".encode())while (True):line = ser.readline()if(line):print(line)line=0else:print("open failed")ser.close()#關(guān)閉端口)

三、pyqtgraph的使用

pip install pyqtgraph#顯示波形的界面

pip install PyQt5#界面要Qt的支持

pyqtgraph是Python平臺(tái)上一種功能強(qiáng)大的2D/3D繪圖庫(kù),相對(duì)于matplotlib庫(kù),由于內(nèi)部實(shí)現(xiàn)方式上,使用了高速計(jì)算的numpy信號(hào)處理庫(kù)以及Qt的GraphicsView框架。

因此,它在大數(shù)據(jù)量的數(shù)字處理和快速顯示方面有著巨大的優(yōu)勢(shì),它適合于需要快速繪圖更新、視頻或?qū)崟r(shí)交互性的操作場(chǎng)合。

另外,它不僅為各種數(shù)據(jù)提供了快速可交互式的圖形顯示,同時(shí)也提供了用于快速開發(fā)應(yīng)用程序的各種小工具,如屬性樹、流程圖等小部件,在數(shù)學(xué)、科學(xué)和工程領(lǐng)域都有著廣泛的應(yīng)用。

import pyqtgraph as pgimport numpy as npimport array app = pg.mkQApp()#建立appwin = pg.GraphicsWindow()#建立窗口win.setWindowTitle(u'pyqtgraph逐點(diǎn)畫波形圖')win.resize(800, 500)#小窗口大小 data = array.array('d') #可動(dòng)態(tài)改變數(shù)組的大小,double型數(shù)組historyLength = 100#橫坐標(biāo)長(zhǎng)度p = win.addPlot()#把圖p加入到窗口中p.showGrid(x=True, y=True)#把X和Y的表格打開p.setRange(xRange=[0,historyLength], yRange=[-1.2, 1.2], padding=0)p.setLabel(axis='left', text='y / V')#靠左p.setLabel(axis='bottom', text='x / point')p.setTitle('y = sin(x)')#表格的名字curve = p.plot()#繪制一個(gè)圖形idx = 0def plotData():global idx#內(nèi)部作用域想改變外部域變量tmp = np.sin(np.pi / 50 * idx)if len(data)data.append(tmp)else:data[:-1] = data[1:]#前移data[-1] = tmpcurve.setData(data)idx += 1 timer = pg.QtCore.QTimer()timer.timeout.connect(plotData)#定時(shí)調(diào)用plotData函數(shù)timer.start(50)#多少ms調(diào)用一次 app.exec_()

四、通過多線程實(shí)現(xiàn)串口數(shù)據(jù)的實(shí)時(shí)繪圖import pyqtgraph as pg

這里主要開了一個(gè)線程去處理串口,剩下的和上面內(nèi)容一樣。

代碼:

import arrayimport serialimport threadingimport numpy as npimport time i = 0def Serial():while(True):n = mSerial.inWaiting()if(n):if data!=" ":dat = int.from_bytes(mSerial.readline(1),byteorder='little') # 格式轉(zhuǎn)換n=0global i;if i < historyLength:data[i] = dati = i+1else:data[:-1] = data[1:]data[i-1] = dat def plotData():curve.setData(data) if __name__ == "__main__":app = pg.mkQApp() # 建立appwin = pg.GraphicsWindow() # 建立窗口win.setWindowTitle(u'pyqtgraph逐點(diǎn)畫波形圖')win.resize(800, 500) # 小窗口大小data = array.array('i') # 可動(dòng)態(tài)改變數(shù)組的大小,double型數(shù)組historyLength = 200 # 橫坐標(biāo)長(zhǎng)度a = 0data=np.zeros(historyLength).__array__('d')#把數(shù)組長(zhǎng)度定下來(lái)p = win.addPlot() # 把圖p加入到窗口中p.showGrid(x=True, y=True) # 把X和Y的表格打開p.setRange(xRange=[0, historyLength], yRange=[0, 255], padding=0)p.setLabel(axis='left', text='y / V') # 靠左p.setLabel(axis='bottom', text='x / point')p.setTitle('semg') # 表格的名字curve = p.plot() # 繪制一個(gè)圖形curve.setData(data)portx = 'COM24'bps = 19200# 串口執(zhí)行到這已經(jīng)打開 再用open命令會(huì)報(bào)錯(cuò)mSerial = serial.Serial(portx, int(bps))if (mSerial.isOpen()):print("open success")mSerial.write("hello".encode()) # 向端口些數(shù)據(jù) 字符串必須譯碼mSerial.flushInput() # 清空緩沖區(qū)else:print("open failed")serial.close() # 關(guān)閉端口th1 = threading.Thread(target=Serial)#目標(biāo)函數(shù)一定不能帶()被這個(gè)BUG搞了好久th1.start()timer = pg.QtCore.QTimer()timer.timeout.connect(plotData) # 定時(shí)刷新數(shù)據(jù)顯示timer.start(50) # 多少ms調(diào)用一次app.exec_()

效果如圖:

五、與下位機(jī)通訊實(shí)現(xiàn)波形實(shí)時(shí)監(jiān)測(cè)

在這里與第四階段基本相同,需要注意的是,如果收數(shù)據(jù)直接畫圖的話,波形會(huì)出現(xiàn)問題。所以串口傳輸數(shù)據(jù)時(shí)使用循環(huán)隊(duì)列(先進(jìn)先出),數(shù)據(jù)來(lái)之后先進(jìn)隊(duì)列,之后再定時(shí)器調(diào)用函數(shù),出隊(duì)列,更新圖。

理論上刷新數(shù)據(jù)的時(shí)間需要大于下位機(jī)發(fā)送數(shù)據(jù)的間隔時(shí)間,否則隊(duì)列會(huì)越來(lái)越大,而且圖的刷新不連貫。再就是有一個(gè)小問題,因?yàn)檎也ㄓ胸?fù)值,我又沒找到很好的把Byte轉(zhuǎn)為char的方法,所以只能手動(dòng)代碼處理,先轉(zhuǎn)成int類型,再把第八位(符號(hào)位)清零,得到絕對(duì)值。然后再取負(fù),得到我們需要的數(shù)據(jù)。

但發(fā)現(xiàn)Python無(wú)法進(jìn)行移位操作,python是int類型是無(wú)精度類型,不會(huì)發(fā)生溢出而進(jìn)行截取的情況,所以只能先轉(zhuǎn)為二進(jìn)制在移位,太麻煩,這里直接通過減去一個(gè)數(shù)的方法來(lái)實(shí)現(xiàn)了。

代碼:

import pyqtgraph as pgimport arrayimport serialimport threadingimport numpy as npfrom queue import Queueimport time i = 0q = Queue(maxsize=0)def Serial():global i;global q;while(True):n = mSerial.inWaiting()if(n):dat = int.from_bytes(mSerial.readline(1),byteorder='little') # 格式轉(zhuǎn)換if(dat>>7):dat =256-datdat =0-datq.put(dat) def plotData():global i;if i < historyLength:data[i] = q.get()i = i+1else:data[:-1] = data[1:]data[i-1] = q.get()curve.setData(data) if __name__ == "__main__":app = pg.mkQApp() # 建立appwin = pg.GraphicsWindow() # 建立窗口win.setWindowTitle(u'pyqtgraph逐點(diǎn)畫波形圖')win.resize(800, 500) # 小窗口大小data = array.array('i') # 可動(dòng)態(tài)改變數(shù)組的大小,double型數(shù)組historyLength = 100 # 橫坐標(biāo)長(zhǎng)度a = 0data=np.zeros(historyLength).__array__('d')#把數(shù)組長(zhǎng)度定下來(lái)p = win.addPlot() # 把圖p加入到窗口中p.showGrid(x=True, y=True) # 把X和Y的表格打開p.setRange(xRange=[0, historyLength], yRange=[-50, 50], padding=0)p.setLabel(axis='left', text='y / V') # 靠左p.setLabel(axis='bottom', text='x / point')p.setTitle('semg') # 表格的名字curve = p.plot() # 繪制一個(gè)圖形curve.setData(data)portx = 'COM25'bps = 19200# 串口執(zhí)行到這已經(jīng)打開 再用open命令會(huì)報(bào)錯(cuò)mSerial = serial.Serial(portx, int(bps))if (mSerial.isOpen()):dat = 0xff;dat >> 2;print("open success")# 向端口些數(shù)據(jù) 字符串必須譯碼mSerial.write("hello".encode())mSerial.flushInput() # 清空緩沖區(qū)else:print("open failed")serial.close() # 關(guān)閉端口th1 = threading.Thread(target=Serial)th1.start()timer = pg.QtCore.QTimer()timer.timeout.connect(plotData) # 定時(shí)刷新數(shù)據(jù)顯示timer.start(1) # 多少ms調(diào)用一次app.exec_()

以上這篇使用Python串口實(shí)時(shí)顯示數(shù)據(jù)并繪圖的例子就是分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考。

- END -

往期精彩

◆ ?從重刑犯到硅谷碼農(nóng),是什么改變了他?

◆ ?27?個(gè)為什么,幫助你更好的理解Python

◆ ?出現(xiàn)這 10 種癥狀,說明你不適合干程序員

總結(jié)

以上是生活随笔為你收集整理的android 串口一直打开_实例 | 使用Python串口实时显示数据并绘图的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。