Raspberry PI 4のスターターキットを購入して組み立てましたが、CPUファンの音が気になるようになりました。説明書に書いてある通りに5vのピンに接続しているため、常に全力でファンが回転しているようです。
一時しのぎの対応として、今は3.3vのピンに接続して消音化しています。今は大した使い方をしていないので温度があまり上がらないため問題ないと思いますが、今後、CPUに負荷がかかってくると問題化しそうです。
ラズパイでCPU温度を確認する方法
GPIOピンでトランジスタを制御してCPU温度に合わせて回転数を調整する手法があるようですので、調べていきたいと思います。
まずは、温度制御までの道のりの第1歩として、CPU温度の把握をしなくてはなりませんので今回はこれを調べていきたいと思います。
LXTerminalを使用して温度を確認する方法
この方法は簡単でGoogle検索でもすぐに見つけることができます。CPU温度を取得するコマンドは記載の2種類あるようです。
- $ cat /sys/class/thermal/thermal_zone0/temp
- $ vcgencmd measure_temp
実際に実行してみた結果、「$ cat /sys/class/thermal/thermal_zone0/temp」を使用すると、1000倍された温度(今回は37485)が表示されてしまい、「$ vcgencmd measure_temp」を使用すると、親切に符合(℃)までつけて表示(今回はtemp=37.4℃)してくれるようです。
Pythonを使用してCPUの温度取得
CPU温度を取得する方法はわかりましたが、最終目標は「取得した温度をCPUファンの回転数制御に使用」することですので、プログラム言語を使用しての温度取得方法について調べました。
Pythonの開発環境について
ラズベリーパイ(OSは普通のRaspberry Pi OS)に最初から「Thonny Python IDE」がインストールされていますのでこれを使いたいのですが、うまく日本語入力を行うことができませんでしたので、「Spider3」というアプリも併用して作業をすすめます。
作成したプログラム
温度取得方法は2種類ありましたが、このうち「$ cat /sys/class/thermal/thermal_zone0/temp」を使用してプログラムを作成していきます。理由はCPU温度取得が目的のため、「temp=」や「℃」が付いていると扱いにくいと感じたからです。
import subprocess import time cut = 0 while cut < 86400: #Ends after 24 hours args = ['cat','/sys/class/thermal/thermal_zone0/temp'] temp = subprocess.run(args,stdout=subprocess.PIPE,encoding='utf8') temp = round(int(temp.stdout)/1000,1) print (temp) cut = cut + 1 time.sleep(1) #Wait for 1 second else: print ("24 hours have passed")
作成したプログラムの解説
温度取得のみを目的とした単純プログラムのため、比較的簡単にプログラムを作成することができました。それでも、迷ったことは多々ありましたので、説明していきたいと思います。
1~2行目
import subprocess import time
「subprocess」「time」のライブラリをインポートします。
- subprocess : ラズパイのコマンドを実行
- time : 時間の使用
Pythonで、ラズパイのコマンドを実行する方法として「commands」と「subprocess」というライブラリを見つけました。使い方は「commands」のほうが簡単そうだったのですが、Pythonの公式的なサイトで「Python3で削除されました」と記載されていましたので「subprocess」を使用することしています。
4~6行目
cut = 0 while cut < 86400: #Ends after 24 hours
4行目で変数「cut」を宣言し「0」を入力しています。そのあと6行目で「while」文を使用してループさせています。変数cutが86400を超えるとループから抜けるようにしています。
8~12行目
args = ['cat','/sys/class/thermal/thermal_zone0/temp'] temp = subprocess.run(args,stdout=subprocess.PIPE,encoding='utf8') temp = round(int(temp.stdout)/1000,1) print (temp)
8行目については「args」の中にコマンドを記入しています。「cut」などをシングルコーテーション「’」で囲い記述します。subprocess.runの引数に「shell=True」を記述すると、LXTerminalと同じように記述できるようですが、公式にはセキュリティ上お勧めしないとのことですので、shell=Trueを使用せず、このような記述にしました。
9行目で「subprocess.run」を使用ラズパイコマンドを実行します。引数は「args」で8行目のコマンドを実行、「stdout=subprocess.PIPE」はコマンドの実行結果をPythonに渡す(PIPE)するたの記述、「encoding=’utf8’」で文字コードを指定しています。
10行目では、取得した文字列を数値に変換して、さらに1000で割り戻し、四捨五入を行っています。
14~15行目
cut = cut + 1 time.sleep(1) #Wait for 1 second
14行目は変数「cut」に「1」を足し算しています。
15行目は「time.sleep(1) 」で1秒間待機させています。この記述によって、CPU温度の取得を1秒間に1回行うことができます。
17~18行目
else: print ("24 hours have passed")
「white」文のループを抜けた後「24 hours have passed」とプリントする記述です。今回は1秒間に1回処理し、86,400回繰り返し(24時間経過後)たら終了としています。
プログラムの実行
プログラムを「Thonny Python IDE」で実行すると、1秒に1回温度を取得してプリントしてくれています。
さいごに
今回はラズベリーパイ(Raspberry PI 4B)の温度取得を行うPythonプログラミングに挑戦しました。もう少しプログラムを発展させて、最終的にはCPU温度監視による、CPUファンの回転制御をしていきたいと思います。