Raspberry Pi OSに搭載されたファン制御機能が怪しいので実験してみた1

![DSC_2913t.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308714/1f515c5a-58a5-efb2-7c99-23cfd98afd70.jpeg)
# はじめに
　この記事を書いている時点では、この機能(以降、この機能と表記します)は(日本語の)ネット情報が少なくてファン制御の仕様がよくわかりません。ソース解析すればわかるかもですが怪しい仕様を実験で確認してみました。

- 実験１：ファンはいつ回って、いつ止まるのか？
- [実験２：オン/オフ制御なのか？ PWM制御なのか？](https://qiita.com/nekokurono7/items/c947e781fae85855d280)

### ■ 実験環境
~~~
$ cat /proc/device-tree/model
Raspberry Pi 4 Model B Rev 1.4
$ uname -a
Linux raspberrypi 5.10.17-v7l+ #1414 SMP Fri Apr 30 13:20:47 BST 2021 armv7l GNU/Linux
$ lsb_release -a
No LSB modules are available.
Distributor ID: Raspbian
Description:    Raspbian GNU/Linux 10 (buster)
Release:        10
Codename:       buster
~~~

# 実験１：ファンはいつ回って、いつ止まるのか？
**結論：設定した温度になるとファンが回って、設定した温度からおおよそ10度下がると止まります。**
ソース解析した結果ではないので間違っていたらごめんなさい。以下、実験の過程です。

### ■ ファン制御の設定
　ファンを回す温度(閾値)とファンを制御するGPIOピンを設定します。raspi-configコマンドで設定するか/boot/config.txtに直書きして再起動します。今回は60度、GPIO14(BCM)ピンに設定しています。

~~~
# tail /boot/config.txt 
[all]
dtoverlay=gpio-fan,gpiopin=14,temp=60000
~~~

　起動したてでまだSoCが温まっていない状態でのGPIOピンの状態は以下です。GPIO14はOUTPUTモードで0になっていました。(▶の行をクリックすると内容が表示されます)

<details><summary>GPIOピンの状態</summary><div>

~~~
# gpio readall
 +-----+-----+---------+------+---+---Pi 4B--+---+------+---------+-----+-----+
 | BCM | wPi |   Name  | Mode | V | Physical | V | Mode | Name    | wPi | BCM |
 +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
 |     |     |    3.3v |      |   |  1 || 2  |   |      | 5v      |     |     |
 |   2 |   8 |   SDA.1 |   IN | 1 |  3 || 4  |   |      | 5v      |     |     |
 |   3 |   9 |   SCL.1 |   IN | 1 |  5 || 6  |   |      | 0v      |     |     |
 |   4 |   7 | GPIO. 7 |   IN | 1 |  7 || 8  | 0 | OUT  | TxD     | 15  | 14  |
 |     |     |      0v |      |   |  9 || 10 | 1 | IN   | RxD     | 16  | 15  |
 |  17 |   0 | GPIO. 0 |   IN | 0 | 11 || 12 | 0 | IN   | GPIO. 1 | 1   | 18  |
 |  27 |   2 | GPIO. 2 |   IN | 0 | 13 || 14 |   |      | 0v      |     |     |
 |  22 |   3 | GPIO. 3 |   IN | 0 | 15 || 16 | 0 | IN   | GPIO. 4 | 4   | 23  |
 |     |     |    3.3v |      |   | 17 || 18 | 0 | IN   | GPIO. 5 | 5   | 24  |
 |  10 |  12 |    MOSI |   IN | 0 | 19 || 20 |   |      | 0v      |     |     |
 |   9 |  13 |    MISO |   IN | 0 | 21 || 22 | 0 | IN   | GPIO. 6 | 6   | 25  |
 |  11 |  14 |    SCLK |   IN | 0 | 23 || 24 | 1 | IN   | CE0     | 10  | 8   |
 |     |     |      0v |      |   | 25 || 26 | 1 | IN   | CE1     | 11  | 7   |
 |   0 |  30 |   SDA.0 |   IN | 1 | 27 || 28 | 1 | IN   | SCL.0   | 31  | 1   |
 |   5 |  21 | GPIO.21 |   IN | 1 | 29 || 30 |   |      | 0v      |     |     |
 |   6 |  22 | GPIO.22 |   IN | 1 | 31 || 32 | 0 | IN   | GPIO.26 | 26  | 12  |
 |  13 |  23 | GPIO.23 |   IN | 0 | 33 || 34 |   |      | 0v      |     |     |
 |  19 |  24 | GPIO.24 |   IN | 0 | 35 || 36 | 0 | IN   | GPIO.27 | 27  | 16  |
 |  26 |  25 | GPIO.25 |   IN | 0 | 37 || 38 | 0 | IN   | GPIO.28 | 28  | 20  |
 |     |     |      0v |      |   | 39 || 40 | 0 | IN   | GPIO.29 | 29  | 21  |
 +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
 | BCM | wPi |   Name  | Mode | V | Physical | V | Mode | Name    | wPi | BCM |
 +-----+-----+---------+------+---+---Pi 4B--+---+------+---------+-----+-----+
~~~
</div></details>

### ■ SoCの温度を上げてみる
#### 実験方法
　ファンの風がSoCに当たらないようにしておき、温度とピンの状態を5秒置きに表示させながら裏でstressコマンドで負荷をかけます。ファンが回ったら別の強いファンでSoCを強制的に冷やします。

<details><summary>温度とGPIO14ピンの変化</summary><div>

~~~
# while : ; do echo `vcgencmd measure_temp` `gpio -g read 14`; sleep 5; done
temp=38.4'C 0
temp=38.4'C 0
＜途中略＞
temp=59.4'C 0
temp=59.4'C 0
temp=61.3'C 1　→ ファンが回りだす
temp=61.3'C 1　← 負荷停止、強制冷却開始
temp=60.3'C 1
temp=61.8'C 1
temp=56.9'C 1　→ 設定温度を下回る
temp=56.0'C 1
temp=56.4'C 1
temp=54.5'C 1
temp=53.5'C 1
temp=52.5'C 1
temp=51.6'C 1
temp=49.1'C 0　→ 約35秒後にファン停止
temp=49.1'C 0
~~~
</div></details>
※ 5秒間隔で表示しているので、GPIO14ピンが1や0になったときの実際の温度ではありません。短い間隔で表示させても誤差はあります。

#### 結果
　閾値設定した**60度を超えてGPIO14ピンが1(ファン回転)になりました**。強制冷却を始めるとぐんぐん温度が下がり、約35秒でGPIO14ピンが0(ファン停止)しました。設定温度を下回ったら30秒位でファンが止まる仕様なのか？


### ■ ファンが止まる条件は？
#### 実験方法
　時間でファンが止まるのか？ 一定温度まで下がったら止まるのか？ 前と同じ様に負荷をかけて温度を上げ、今回は自然冷却にまかせてじわじわ温度を下げてGPIO14ピンの変化を観察します。閾値の温度設定は変わらず60度です。

<details><summary>自然冷却した場合の変化</summary><div>

~~~
# while : ; do echo `vcgencmd measure_temp` `gpio -g read 14`; sleep 5; done
temp=38.4'C 0
temp=39.4'C 0
＜途中略＞
temp=60.3'C 0
temp=59.4'C 0
temp=61.3'C 1　→ ファンが回りだす
temp=59.9'C 1
temp=60.3'C 1
temp=61.8'C 1
temp=62.3'C 1
temp=62.3'C 1
temp=62.8'C 1
temp=62.8'C 1
temp=63.3'C 1
temp=62.3'C 1　← 負荷停止、送風なし自然冷却
temp=58.4'C 1　→ 60度を下回る
temp=57.4'C 1
temp=57.4'C 1
temp=56.4'C 1
temp=56.4'C 1
temp=56.0'C 1
temp=55.0'C 1
temp=54.5'C 1　→ 温度が下がっていたが
temp=55.0'C 1　→ 温度がちょっと上がる
temp=54.0'C 1　→ 60度を下回ってから30秒以上経ってもファンは止まらない
temp=55.0'C 1
temp=54.5'C 1
temp=54.0'C 1
＜15回分略＞　→ 上がったり下がったりが続いている
temp=53.0'C 1
temp=54.5'C 1
temp=53.0'C 1
temp=52.5'C 1　← 強制冷却開始
temp=51.6'C 1
temp=51.1'C 1
temp=49.6'C 1
temp=47.7'C 0　→ ファンが止まる
temp=48.7'C 0
~~~
</div></details>

#### 結果
　負荷を止めて自然冷却に任せると温度が微妙に上下しながらじわじわと下がっていますが、**30秒以上経ってもファンは止まりません。**
　強制冷却を始めると20秒程度でファンが止まりました。温度が下がり続けないとファンは止まらない？ 一定温度まで下がると止まる？

### ■ 設定温度を変えてみる
#### 実験方法
　前の2回の実験でファンが止まったのは50度を下回ってからでした。一定温度まで下がるとファンが止まるという仮説をたて、閾値の温度設定を60度から**65度に変更**してファンが止まる温度を観察してみます。55度位でファンが止まれば仮説が裏付けされます。

<details><summary>閾値65度の場合</summary><div>

~~~
temp=59.9'C 0
temp=60.3'C 0
temp=60.8'C 0
temp=61.8'C 0
temp=62.3'C 0
temp=62.8'C 0
temp=62.3'C 0
temp=63.3'C 0
temp=63.7'C 0
temp=62.8'C 0
temp=63.7'C 0
temp=64.2'C 1
temp=64.7'C 1　← 負荷停止、強制冷却開始
temp=63.7'C 1
temp=65.2'C 1
temp=64.7'C 1
temp=65.7'C 1
temp=65.7'C 1
temp=66.2'C 1
temp=67.2'C 1
temp=65.2'C 1
temp=59.9'C 1
temp=56.0'C 1
temp=53.5'C 0　→ ファンが止まる(手前の5秒前が56.0度なのでその間に55度になったと考えられる)
temp=53.0'C 0
temp=51.6'C 0
temp=50.1'C 0
temp=49.1'C 0

~~~
</div></details>
#### 結果
　表示値64.7度でファンが回って、56.0度から53.5度になってファンが止まりました。始めの実験では51.6度から49.1度に下がってファンが止まっていました(2回目の実験結果は微妙ですが)。誤差はありますが**設定温度から大体10度下がるとファンが止まるようです。**データは掲載していませんが閾値の設定温度や冷却時間を変えてみても同じ傾向がみられました。

# 最後に
　これは大した実験ではありませんが、試行錯誤しながら法則を探す作業は、自分の知識と経験を掘り起こして確かめて、新たな知見を習得する楽しい体験だと思います。そして、手軽に結果を残して共有できるインフラがある。エンジニアにとって素晴らしい時代になったなぁと感じております。

以上