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

　「[Raspberry Pi OSに搭載されたファン制御機能が怪しいので実験してみた1](https://qiita.com/nekokurono7/items/a0f634a71e6aaaaccfa8)」ではRaspberry Pi OSに搭載されたファン制御機能(以降、この機能と表記します)でファンがいつ止まるのかを実験してみました。今回は、この機能がファンの回転数を制御しているのかどうかについて実験してみました。
### ■ 実験環境(実験１と同じ)
~~~
$ 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
~~~
### ■ ファン制御の設定(実験１と同じ)
　ファンを回す温度(閾値)とファンを制御するGPIOピンを設定します。raspi-configコマンドで設定するか/boot/config.txtに直書きして再起動します。今回は60度、GPIO14(BCM)ピンに設定しています。

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

# 実験２：オン/オフ制御なのか？ PWM制御なのか？
**結論：ファンをオンにするかオフにするかといった単純な制御をしていました。回転数の微調整は制御していません。**ただし、公式ファンがPWM制御可能なため、今後のアップデートでPWM制御になるかもしれません。
　ソース解析した結果ではないので間違っていたらごめんなさい。以下、実験の過程です。

### ■ GPIO14ピンからパルスは出ているのか？
　実験１ではgpioコマンドでGPIO14ピンの値(0か1か)を観測した結果、ピンの値とファンの回転有無は連動していました。
<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>
　gpioコマンドでGPIO14ピンがOUTPUTモードになっていることはわかりますが、ピンからPWM信号が出ているかどうかはピンのモード設定ではわかりません(自分調べ)。また、温度が変わっても見た目ファンの回転数が変わっているようには見えませんでした。
　実験２では、GPIO14ピンをオシロスコープで覗いてみます。

　GPIO14ピンが"0"の時と"1"の時の波形は以下です。(映り込み、0V未調整ゴメンナサイ)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308714/bb2fb696-c6d1-cc90-2775-497f288806a6.png)
　"1"の時はほぼ3.3Vで一定なのでPWM信号は出ていないとわかります。

### ■ PWM信号が出ていたらどう見えるのか
　ハードウェアPWMが使えるGPIO18ピンでPWM信号を出力させてピンの波形を覗いてみます。
　使ったプログラムは以下です。SoC温度が40度を超えるとファンが回転を始め、50度を超えるとフル回転となります。40～50度の範囲ではSoCの温度に連動してファンの回転数を70～100%に変更します。(参考にした情報があるのですが、サイトが見つからずリンクが掲載できません。申し訳ありません)
<details><summary>PWM出力で使用したプログラム</summary><div>

``` python
# -*- coding: utf-8 -*-
import RPi.GPIO as IO
import commands
import time
 
#ピン番号指定
IO.setmode(IO.BCM)
#18番ピンを出力として利用 
PinPut = 18
IO.cleanup(PinPut)
IO.setup(PinPut, IO.OUT )
#PWM設定（1秒間の間に5個のパルスを作成）
PWM = IO.PWM(PinPut, 5)
PWM.start(0)
 
while True:
    #CPU温度の取得
    temp = commands.getoutput("vcgencmd measure_temp").split('=')
    ftemp = float(temp[1].replace('\'C', ''))
    #温度により出力を算出（40～50℃の間を70～100％で）
    pw = (ftemp - 40) / 10
    if pw < 0: pw = 0
    if pw > 1: pw = 1
    Duty = pw * 30
    if pw > 0: Duty += 70
    #PWM変更
    PWM .ChangeDutyCycle(Duty)
    #SoC温度とファンパワーを表示
    print 'temp:' + str(ftemp) + ' FANPW:' + str(pw)
    time.sleep(5)
```
</div></details>

　温度とDuty比に連動したファンパワー(比率)を出力させながらGPIO18ピンの信号をオシロスコープで観測しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308714/418c74ec-151a-dd0a-69f9-c392fcb6307d.png)
　ピンから正弦波が出ていることがわかります。正弦波で3.3V("1")にする時間が長ければファンの回転数が高くなります。

# 公式ファンについて
　Raspberry Pi財団公式のファンが発売されています。

https://www.raspberrypi.org/products/raspberry-pi-4-case-fan/

　公式の情報にはPWM制御できるとは書かれていません。

### ■ この機能に怪しさを感じた理由
　国内で取り扱っているスイッチサイエンスの商品説明によるとPWM制御できるようです。

https://www.switch-science.com/catalog/6827/

　商品画像が公式サイトと同じなので、同じファンのようです。メーカのADDAのサイトでファンの型番「AD0205DX-K59」を検索しても見つかりません。シールを剥がしてみました(自己責任で)。
![DSC_2912t.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308714/5496a2c2-38f7-74aa-c733-701fff5a5a0f.jpeg)
　ICらしきものが付いていました。「A6989HWJ37」と書いてありますが、ググってもわかりません。リード線が3本付いていますが、青と黒の間にもう1本付けられる感じです。これは想像ですが、PWM制御できる4ピンのPC用ファンを流用しているのかもしれません。
　OSに搭載されたこの機能がオン/オフ制御しかしていないのに、なぜPWM制御できる(高い)ファンを公式が発売したのか。怪しい。。。

### ■ 公式ファンをハードウェアPWN制御してみると
　公式ファンの青色の線をGPIO18ピンに接続して、先にPWM信号の波形をみたプログラムでファンを制御してみると、「FANPW:」の値が大きくなるにつれて「ヒュヒュヒュ」から「ヒュンヒュン」「ヒューンヒューン」と明らかにファンの回転音が変わりました。PWM制御できるファンのようです。なお、青線のピンをGPIOから引き抜くとファンはフル回転しました。

# まとめ
 「この機能」は今はファンをオン/オフでしか制御していませんが、PWM制御はどのGPIOピンでもできるので、将来的にはRaspberry Pi OSのアップデートでPWM制御に対応するかもしれません。

以上