0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Raspberry Pi 4のファンをCPU温度に応じてPWMで速度調整する方法

Posted at

背景

Raspberry PiにPWM制御可能なファンを取り付けている場合、PythonでGPIOピンをPWM制御する方法などが検索にヒットするが、OSに組み込まれている仕組みを使って簡単に実現できることがわかった。

ファンの例(Amazon)

本記事の内容は、ほぼ以下ページに記載がある。

環境

  • Raspberry Pi 4B
  • Raspberry Pi OS (Bookworm)
    • Linux rpi4b 6.6.28+rpt-rpi-v8 #1 SMP PREEMPT Debian 1:6.6.28-1+rpt1 (2024-04-22) aarch64 GNU/Linux

手順

ソースの取得と変更

上記ページ内の pwm-fan-overlay.dts を取得し、Raspberry Piにコピーする

上記ページ内のpwm-fan-overlay.dts
/*
 * Overlay for a Raspberry Pi PWM Fan
 * References: 
 *
 * Optional parameters:
 *
 * pwm-fan-overlay.dts
 */
/dts-v1/;
/plugin/;

#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/thermal/thermal.h>
#include <dt-bindings/pinctrl/bcm2835.h>

/ {
	compatible = "brcm,bcm2835";

	fragment@0 {
		target = <&gpio>;
		__overlay__ {
			pwm_pins: pwm_pins {
				brcm,pins = <18>;
				brcm,function = <BCM2835_FSEL_ALT5>;
				brcm,pull = <0>;
			};
		};
	};

	fragment@1 {
		target = <&pwm>;
		frag1: __overlay__ {
			pinctrl-names = "default";
			pinctrl-0 = <&pwm_pins>;
			/* in Hz */
			assigned-clock-rates = <100000000>;
			status = "okay";
		};
	};

	fragment@2 {
		target-path = "/";
		__overlay__ {
			fan: pwm-fan {
				compatible = "pwm-fan";
				#cooling-cells = <2>;
				/* in ns */
				pwms = <&pwm 0 20000000 0>;
				cooling-min-state = <0>;
				cooling-max-state = <4>;	
				/* PWM duty cycle values in a range from 0 to 255
				 * which correspond to thermal cooling states
				 */
				cooling-levels = <0 75 125 175 250>;
			};
		};
	};

	fragment@3 {
		target = <&cpu_thermal>;
		__overlay__ {
			polling-delay = <2000>; /* milliseconds */
		};
	};

	fragment@4 {
		target = <&thermal_trips>;
		__overlay__ {
			trip0: trip0 {
				temperature = <40000>;
				hysteresis = <2000>;
				type = "active";
			};
			trip1: trip1 {
				temperature = <45000>;
				hysteresis = <2000>;
				type = "active";
			};
			trip2: trip2 {
				temperature = <50000>;
				hysteresis = <2000>;
				type = "active";
			};
			trip3: trip3 {
				temperature = <55000>;
				hysteresis = <5000>;
				type = "active";
			};
		};
	};

	fragment@5 {
		target = <&cooling_maps>;
		__overlay__ {
			map0 {
				trip = <&trip0>;
				cooling-device = <&fan 0 1>;
			};
			map1 {
				trip = <&trip1>;
				cooling-device = <&fan 1 2>;
			};
			map2 {
				trip = <&trip2>;
				cooling-device = <&fan 2 3>;
			};
			map3 {
				trip = <&trip3>;
				cooling-device = <&fan 3 4>;
			};
		};
	};

	__overrides__ {
			fan_temp0 = <&trip0>,"temperature:0";
			fan_temp0_hyst = <&trip0>,"hysteresis:0";
			fan_temp0_speed = <&fan>, "cooling-levels:4";
			fan_temp1 = <&trip1>,"temperature:0";
			fan_temp1_hyst = <&trip1>,"hysteresis:0";
			fan_temp1_speed = <&fan>, "cooling-levels:8";
			fan_temp2 = <&trip2>,"temperature:0";
			fan_temp2_hyst = <&trip2>,"hysteresis:0";
			fan_temp2_speed = <&fan>, "cooling-levels:12";
			fan_temp3 = <&trip3>,"temperature:0";
			fan_temp3_hyst = <&trip3>,"hysteresis:0";
			fan_temp3_speed = <&fan>, "cooling-levels:16";
		};
};

必要に応じて編集する場所

ピン番号

brcm,pins = <18>; の部分がPWM制御をするピン番号。
18はGPIO18(=12番ピン)を表す。

ここを変更した場合は、brcm,function = <BCM2835_FSEL_ALT5>; も変更する必要があると考えられる。(未確認)

PWM周波数

fragment@2内のpwms = <&pwm 0 20000000 0>;の部分のうち、20000000がPWMの周期(ns)なので、ファンからノイズが聞こえる場合などは変更する。
20000000は 50Hz であり、私のファンではノイズがあったので 40000 (=25000Hz)に変更した。

コンパイル

プリプロセッサを通す

#includeとなっている部分はcppを使って事前に処理を行う。

$ cpp -nostdinc -undef -x assembler-with-cpp -I /usr/src/linux-headers-6.6.28+rpt-common-rpi/include/ -o pwm-fan-overlay.tmp.dts pwm-fan-overlay.dts

※ヘッダーファイルの位置は各自の環境に合わせて変更する

コンパイル

dtcコマンドを使用する

$ dtc -O dtb -o pwm-fan.dtbo pwm-fan-overlay.tmp.dts

インストール

ファイルを配置

$ sudo mv pwm-fan.dtbo /boot/firmware/overlays/

※警告が出るが無視して問題なかった

設定

/boot/firmware/config.txt で pwm-fan を読み込むように変更

...
dtoverlay=pwm-fan

設定変更

config.txt内で、以下の記法でパラメータを変更できる。

dtoverlay=pwm-fan
dtparam=fan_temp0=55000
dtparam=fan_temp0_hyst=5000
dtparam=fan_temp0_speed=75
dtparam=fan_temp1=62500
dtparam=fan_temp1_hyst=5000
dtparam=fan_temp1_speed=128
dtparam=fan_temp2=70000
dtparam=fan_temp2_hyst=5000
dtparam=fan_temp2_speed=192
dtparam=fan_temp3=77500
dtparam=fan_temp3_hyst=5000
dtparam=fan_temp3_speed=255

再起動

$ sudo reboot
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?