目的:
ラズベリーパイのFAN (PWM制御対応のFAN> を PWM 制御 する。
背景:
ラズベリーパイのケースについているFAN から音が出るようになった。
(5V ファン を 3.3V 駆動 )
この為、PWM制御対応の5V FAN を購入し、説明書通り、/boot/config.txt に
この為、PWM制御 (回転数制御) できるようにする。
(5V ファン を 3.3V 駆動 )
この為、PWM制御対応の5V FAN を購入し、説明書通り、/boot/config.txt に
dtoverlay=gpio-fan,gpiopin=18,temp=55000
を追加したところ、
指定温度 (55℃) 以上 で ON, 未満で OFF となり、FAN が 定期的に 全力回転 していた。(PWM制御ではなく、 ON/OFF 制御 )この為、PWM制御 (回転数制御) できるようにする。
概要
PWM制御については、「C言語で LED 調光 (pigpio を使用した PWM 制御) 」を参照。
pigpiod(デーモン)を使用した hardware_PWM (ユーザ権限で実行可能) を使用し、指定温度範囲で 段階的に FAN回転数 を変える様にする。
尚、コード作成は C言語 で行う。
pigpiod(デーモン)を使用した hardware_PWM (ユーザ権限で実行可能) を使用し、指定温度範囲で 段階的に FAN回転数 を変える様にする。
尚、コード作成は C言語 で行う。
構成
raspberry pi
:
raspberry pi 4
FAN : PWM制御端子付き の 5V FAN
使用 GPIO : 18 pin
FAN : PWM制御端子付き の 5V FAN
使用 GPIO : 18 pin
PWM FAN 制御用コード
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <pigpiod_if2.h> int get_temp(void) { static int tmp = 0; FILE *fp; char rdt[16]; fp = fopen("/sys/devices/virtual/thermal/thermal_zone0/temp","r") ; if (fp != NULL ) { fgets(rdt,16,fp) ; fclose(fp); tmp = atoi(rdt) / 1000 ; } return tmp ; } void usage(void) { printf("Usage: pigpio_pwnfan [option]\n"); printf("\n"); printf(" option\n (default)") ; printf(" -l n ... Low temperature (50) 'C\n"); printf(" -h n ... hi temperature (60) 'C\n"); printf(" -p n ... PWM output pin (18) 12/18(ch0) or 13/19(ch1)\n"); printf(" -f n ... PWM Frequency (10000) Hz\n"); printf("\n"); } int main(int argc, char **argv) { int gpio_pin = 18; // hardware PWM Pin int pwm_freq = 10000; // hardware PWM frequency int pwm_duty = 0 ; // hardware PWM duty int tmp_low = 50; // cold temperature int tmp_hi = 60; // hot temperature int temp = 0 ; // detect twmperature int pi = 0 ; int opt = 0 ; // command line option while ((opt = getopt(argc, argv, "l:h:p:f:")) != -1) { switch (opt) { case 'l': tmp_low = atoi(optarg); break; case 'h': tmp_hi = atoi(optarg); break; case 'p': switch((gpio_pin = atoi(optarg))) { case 12: case 13: case 18: case 19: break; default: usage(); exit(1); } break; case 'f': pwm_freq = atoi(optarg); break; default: printf("\n"); usage(); exit(1); } } if (tmp_low >= tmp_hi) { usage(); exit(1); } // pigpio start pi = pigpio_start(0,0) ; if (pi<0) { printf ("pigpio start error !!") ; exit(1) ; } // PWM control while (1) { temp = get_temp(); if (temp <= tmp_low) { pwm_duty = 0; } else if(temp >= tmp_hi) { pwm_duty = 1000000 ; // 100% }else { pwm_duty = ((temp - tmp_low) * 1000000) / (tmp_hi - tmp_low) ; } hardware_PWM(pi,gpio_pin, pwm_freq, pwm_duty) ; sleep(10); } return 0; }
コード概要
- get_temp(void)
raspberry pi のCPU温度を取得する。
温度の取得は /sys/devices/virtual/thermal/thermal_zone0/temp を読み込む事で行う。 - usage(void)
オプション不正時の書式の表示を行う。 - main(int argc,char **argv)
PWM FAN 制御 本体。
- command line option 解析部分
getopt を して オプションの解析を行う。
unistd.h をインクルードする必要がある。
-l : 下限温度。この温度より下は FAN停止。(省力時 50℃) -h : 上限温度。この温度より上は FAN全速。(省略時 60℃) -p : GPIO PIN番号。12/18(ch0) 又は 13/19(ch1) (省略時 18) -f : PWM 周波数 (省略時 10000 (10KHz) )
- command line option 解析部分
getopt を して オプションの解析を行う。
- pigpio start pigpio_start(0,9) (pigpio の 初期化) を実行。 戻り値が負の場合、異常終了。
- PWM control PWM 制御 本体。 設定温度の間、検出温度の応じてデューティを 0~100% の間で変化させる。 無限ループで、 温度の取得, PWM 設定 を行った後、10秒間 スリープする。 ( 10秒間隔で PWM制御 )
コンパイル
gcc -Wall -pthread -o pigpio_pwmfan pigpio_pwmfan.c -lpigpiod_if2 -lrt
実行
pigpiod 開始
sudo systemctl enable pigpiod.service
sudo systemctl start pigpiod.service
sudo systemctl start pigpiod.service
実行 (動作確認)
pigpio_pwmfan&
で実行し、FAN がPWM制御されていること(全速でないこと)を確認する。
停止
作成した FAN制御プログラムは サービスとして実行するため、動作確認で実行したプロセスを以下で終了させる。
ps
で pigpio_pwmfan の PIDを確認し、
kill [PID]
で pigpio_pwmfan を終了させる。
サービスへの登録
再起動時等、自動で開始するようにサービスに登録する。
ユニット定義ファイルの作成
/etc/systemd/system に ユニット定義ファイルを作成する。
ユニット定義ファイル例
ユニット定義ファイル例
[Unit] # サービスの説明。内容は任意 Description=PWM FAN Control # このUnitより先に起動するべきUnitを設定 After=local-fs.target [Service] # 実行するコマンドやスクリプトを記述 ExecStart=/usr/local/bin/pigpio_pwmfan # サービス停止時の Kill する単位を設定 KillMode=process # プロセスの起動方法を指定 Type=simple # サービス停止時の再起動条件 (no は再起動しない) Restart=always [Install] # 該当ユニットへの弱い依存関係を設定 WantedBy=multi-user.target
FAN制御プログラムの サービス登録、実行
sudo systemctl enable pigpiod.service
sudo systemctl start pigpiod.service
sudo systemctl start pigpiod.service
0 件のコメント:
コメントを投稿