做一个基于python的树莓派MCU性能-温度监控仪表盘
前段時間,需要比較樹莓派MCU發熱情況,因為沒有找到合適工具,故使用python在畫一個曲線圖,完成圖如下:
這個圖完全由樹莓派的Raspbian操作系統自帶的python完成,現在我和大家一步步來介紹這個代碼如何完成吧。
一、準備工作
1、文本編輯器
文本編輯可以用Raspbian自帶的nano,其操作和windows的記事本基本類似,鍵盤用于代碼的輸入,快捷鍵ctrl+s保存,ctrl+x退出。
2、python環境
Raspbian的2019-09-26版本上分別裝有Python2.7.16和Python3.7.3,考慮到Python2已經EOL,所以我們選擇Python3作為代碼執行的工具,python代碼不需要編譯,可以直接使用命令行“python3 源文件名”執行。
3、MCU負載增加
可以自由選取你希望增加負載的軟件,這里我選擇的是stress-ng,是一個用來拷機的專業工具,執行過程中會讓MCU利用率達到100%。
二、預備知識
1、pillow庫
PIL(Python Image Library)是python的第三方圖像處理庫,支持圖像的歸檔(Archives)、展示(Display)和處理(Processing)功能。其應用非常廣泛,在Raspbian自帶的Python3中已經安裝和配置好了,我們可以直接使用。
2、正則表達式
正則表達式(Regular Expression)可以用于通過匹配字符串的方式來提取文本中符合規則的某個字段,在本文中用到的匹配規則有:
\d匹配數字
例如:
就是將字符串c2中第一個浮點數取出來,且只保留一位小數。
3、Linux下查看MCU當前頻率、溫度和利用率的命令
sudo cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freqcat /sys/class/thermal/thermal_zone0/temptop命令執行效果如下圖所示
在圖中,顯示出的頻率600000是MCU降頻為600MHz,如果工作時應該會自動升為1.5GHz;溫度36476是實際值的1000倍,因此可以認為大概是36.5攝氏度;而top命令執行后得到的數據較多,而且會隨時間不斷發生變化,還需要重新處理,在不少資料中都建議使用命令
直接獲取cpu利用率,但根據實際測試的情況看來,由于執行過程中會出現異常數據污染,其效果并不好。我們使用命令
top -n1 |grep %Cpu\(s\)得到MCU利用率這一整行的數據后再通過正則表達式處理數據。
三、畫圖
在Python3中調用pillow庫需要先導入:
import PIL或者我們僅導入需要使用的庫中命令:
from PIL import Image,ImageDraw上述兩種方法在Python中都可以使用,需要注意大小寫的區別。
調用pillow庫是用來畫圖的,因此我們新建一張大小為555*220的圖片img,并且在圖片上建立一個“畫圖板”draw,對圖片的各項操作都在“畫圖板”上實現。
這時,這個圖片僅僅在系統內存中存在,我們在“畫圖板”上寫寫畫畫之后,再保存到文件中。
img.save("test.png")畫出坐標系
for i in range(30,90,10):draw.text((24, 275-i*3), str(i),(225,225,225)) draw.line((40,280-i*3,490,280-i*3),(120,120,120))for i in range(1,5):draw.text((i*30+38,195), str(i*2),(225,225,225)) for i in range(5,16):draw.text((i*30+35,195), str(i*2),(225,225,225)) for i in range(1,16):draw.line((i*30+40,40,i*30+40,190),(120,120,120))draw.line((40,20,40,190),(225,225,225))draw.line((40,190,510,190),(225,225,225))draw.text((503,190), "t(min)",(225,225,225)) draw.text((12,12), "T( C)",(225,225,225))draw.text((24,7), ".",(225,225,225))draw.line((490,20,490,190),(225,225,225))for i in range (5):draw.text((493,35+i*30), "%d%%"%(100-i*20),(225,225,225))draw.text((493,18), "CPU Usage",(225,225,225))需要注意的是,在“畫圖板”中,左上角的位置是(0,0),右下角的位置是(555,220),而我們通常習慣的坐標系是向右和向上延伸的有所不同。考慮到樹莓派MCU可能具有的溫度范圍,我們選擇從30~80℃,cpu利用率為0~100%,分別在縱軸標準,橫軸為時間線,我們考慮測試時間為半小時,即30分鐘。
在python循環中可以通過in命令實現循環,循環體通過縮進決定的,因此文本格式非常重要。
接下來我們根據時間獲取數據并開始正式畫曲線圖。
使用代碼:
其中a1是溫度值,m1是MCU利用率。調用系統命令的方法是
os.popen('命令行').read()使用前同樣需要導入os庫
import os由于認為樹莓派上MCU的溫度和MCU是否有使用和其利用率是密切相關的,因此我們在同一坐標系內分別畫出這兩根曲線。另外,我們主要關注的是MCU溫度的高低,因此在顏色上可以用漸變的彩色表示,而MCU的利用率高或者低我們僅作為參考,使用青色和藍色表示(樹莓派運行的時候有時候會自動降頻,我們使用藍色表示全速主頻,青色表示主頻降低為600MHz的)。我們不斷獲取上述數值,并根據其值來畫曲線,例如:
for i in range(900):a2=(int(os.popen('cat /sys/class/thermal/thermal_zone0/temp').read()))/1000a=int((a1+a2-75)*4)draw.line((i*0.5+40,280-a1*3,i*0.5+40.5,280-a2*3),(a,255-a,0))a1=a2其中,a是用來表示溫度的顏色參量,a值越大,越偏紅色,反之則偏近綠色。同時規范a值門限,高于255就讓a=255,低于0就讓a=0。
同時,我們還希望畫圖循環過程中,不斷有提示告訴我們程序執行的進度,因此在命令中給出打印:
表示在進度每行進1/60(在這段代碼中是30秒),都會給出進度提示。
之前提到,我們希望在某個時刻增加MCU的負載,因此使用
其中nohup表示讓stress-ng在后臺運行,-t 1200是命令stress-ng的參數,表示這個負載運行20分鐘。
循環體中,我們無論是獲取樹莓派MCU溫度還是畫圖都不是一個連續的過程,每執行一次都需要等待一段時間,我們使用:
讓循環過程中,每次執行一次后等待1.4秒,與之前相同,使用time庫需提前導入。
編寫完整代碼,執行完成后,會打印出本次測試過程中的最高溫度。
四、關于這個畫圖程序的幾個說明
1、循環等待時間間隔是怎么確定的?
我們希望在2秒實現一次循環(30分鐘共循環900次),我們知道python的效率不太高的,而且執行Linux的命令例如:
top -n1命令讀取需要較多時間,至于等待1.4秒,是根據多次嘗試實驗出來的,在樹莓派3b上大約等待1.2秒。
2、為什么運行負載的起始點定在i=59?
i=59表示運行到第60個點,也就是120秒之后開始增加負載。
3、在畫圖時候,橫坐標只有450,但我們取樣了900個時間點的數據,合適嗎?
因為在畫圖時,坐標必須是整數,我們之所以取900個測試點,是因為發現讀取硬件數據并不穩定,因此,在2秒取一個點,相對精度較高,畫圖后顯示會比較吻合實際。至于取點數量為坐標寬度值的兩倍,畫圖時將在同一個時間坐標畫出兩個點,這并不影響實際畫圖效果。
4、
print("Process:[{}->{}]{:.2f}%\r".format('*'*(i//15),'-'*(60-i//15),i*1.0/9))中雙斜線表示什么意思?為什么需要i*1.0/9,而不是直接用i/9?
雙斜線“//”表示整除,在這里,因為i已經是15的倍數了,所以可以認為i//15=i/15。
使用i1.0/9是希望將這個數字使用浮點形式表示出來,可以用i1.0,將整形數i變成浮點數。如果直接使用i/9,那么當i=15時,打印出來的不會是1.67,而直接是1.00了,當然也可以用i/9.0實現采用浮點數表示結果。
你點的每個贊,我都當成喜歡
總結
以上是生活随笔為你收集整理的做一个基于python的树莓派MCU性能-温度监控仪表盘的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【任务脚本】0523更新京东618叠蛋糕
- 下一篇: 200528更新arduino开发ESP