その5-1.冷却ファンを接続してPWMでCPU温度に応じた回転数制御を行う(そして失敗した話)
Raspberry Pi 4は熱い!
界隈が熱い(らしい?)のは昔からの話。そうじゃないんです。Raspberry Pi、物理的に熱いのです。一応CPU冷却用に小型ファンを購入しましたが、常時フル稼働では騒音(実はそんなにしませんけど)が気になりますし、常時稼働を前提としたドラレコと考えた場合、ある程度の出力制御を行って電力消費を少しでも抑えたい所。
なので今回はPWMを使ってファンの制御を行う事にします。
まずは配線
以下のサイトさんを参考に配線します。
Raspberry Pi でPWM信号を使って5Vファンを制御する - Qiita
ただ今回はpigpioを使ったソフトウェア制御を行います。なのでピンはどこを利用しても良いので、今回は空く予定のGPIO4へ接続。
制御プログラムのコーディング
早速コーディングを開始。今回はpigpioのIFではなく、pigpiodのIFを使ってコーディングします。
CPUの温度取得方法は2通りありますが、今回は文字列操作の必要のない方法を使います。(やってもいいしポインタ使って脳汁出るソース書いたりして楽しかったですけど、処理の軽さも重視していくので大人しくわかりやすい方法で)
コマンド実行結果の標準出力を用いるので、C++のpopen関数を利用します。
#include <stdio.h> #include <cstring> #include <stdlib.h> #include <unistd.h> #include <pigpiod_if2.h> #define FAN_GPIO 4 // FANコントロールGPIO番号 #define FAN_PWM_DUTY_MIN 20 // PWM Duty最小値 #define FAN_PWM_DUTY_MAX 100 // PWM Duty最大値 #define FAN_PWM_FREQUENCY 10 // PWM周波数値 #define CPU_THERMAL_MIN 40 // ファン稼働CPU最低温度 #define CPU_THERMAL_MAX 80 // ファン稼働CPU最高温度 int main() { // pigpioへ接続 int pi = pigpio_start(NULL, NULL); if (pi < 1) { printf("%d\n", pi); return 1; } // GPIO設定 set_mode(pi, FAN_GPIO, PI_OUTPUT); set_PWM_range(pi, FAN_GPIO, FAN_PWM_DUTY_MAX); set_PWM_frequency(pi, FAN_GPIO, FAN_PWM_FREQUENCY); // CPU温度取得用変数 const char* cmd = "cat /sys/class/thermal/thermal_zone0/temp"; FILE* fp; char buf[1024]; memset(buf, 0, sizeof(buf)); // duty算出用設定値 int pwm_duty_range = FAN_PWM_DUTY_MAX - FAN_PWM_DUTY_MIN; int cpu_thermal_range = CPU_THERMAL_MAX - CPU_THERMAL_MIN; while(1) { // CPU温度取得 int thermal = 0; fp = popen(cmd,"r"); if (fp != NULL) { fgets(buf, sizeof(buf), fp); thermal = atoi(buf) / 1000; pclose(fp); // Duty値算出 int duty = 0; if (thermal > CPU_THERMAL_MAX) { // MAX以上なら100固定 duty = FAN_PWM_DUTY_MAX; } else if (thermal > CPU_THERMAL_MIN) { // MINより上なら温度とduty値を比例させる duty = (CPU_THERMAL_MAX - thermal) / cpu_thermal_range * pwm_duty_range + FAN_PWM_DUTY_MIN; } // Duty値に変更があれば変更 if (get_PWM_dutycycle(pi, FAN_GPIO) != duty) { set_PWM_dutycycle(pi, FAN_GPIO, duty); } } // 次のループ開始まで1秒待機 time_sleep(1); } // pigpioへの接続終了 pigpio_stop(pi); return 0; }
これで動くはず…がなぜかpigpio_startで0が返ってきました。なぜ…
明日は不具合の原因究明と、バックグラウンド実行の設定を…行えたらいいですね。ちょっとこれは問題が面倒な気配…