目的:
ラズベリーパイの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 件のコメント:
コメントを投稿