PC用のPWMファンを回す

# PWMファンとは

すでにご存知だとは思いますが、PC関係の**ファン**といえば、CPUを冷やすヒートシンクやラジエーターに取り付ける**ファン**、筐体内部の熱を逃がすケース**ファン**などが代表的です。また、電源装置やグラフィックボードにも独立した**ファン**が組み込まれていることが多いです。

これらの**ファン**は、ファンの回転数制御として、**DCファン**と**PWMファン**に大別されるそうです。
**DCファン**は加印する電圧によって回転数を制御し、**PWMファン**はパルス信号によって回転数を制御するそうです。電源電圧はDC12Vで、DCファンは2ピンもしくは**3ピン**、PWMファンは**4ピン**接続です。また、3ピンと4ピンのファンは、ファンから回転数を取得することができるようです。
　**参考**：[冷却ファン 2/3/4ピンで何が違うの？](https://bablishe.com/234pintypefan/)

>ちなみに、**Raspberry Pi 4**用の[公式ケースファン](https://www.raspberrypi.com/products/raspberry-pi-4-case-fan/)は、DC5V駆動で3ピンのPWMファンで回転数は取得できないタイプです。

今回は、使わなくなったPWMファンをお手軽に回転数制御してモバイル扇風機として再利用することを目的とし、その製作過程を記事にします。

# 使用するPWMファン

10年ほど前のPCで使われていた、下記2つのファンを対象とします。型番で検索すると、今でも入手可能なようです。
2枚の写真のスケールが不一致なので大きさの対比がしずらいですが、この記事では左側のファンを90mmFAN、右側のファンを70mmFANと呼ぶことにします。
90mmFANの詳細仕様は不明ですが、70mmFANはデータシートを見つけたので仕様が細かく分かりました。

||90mmFAN|70mmFAN|
|:-:|:-:|:-:|
|物|![IMG_9413.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283293/a0be254d-d237-1b58-9a38-986902bead7a.png)|![IMG_9424.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283293/6351aa32-2f78-9680-970a-b76ed0f6e15a.png)|
|型番<br>_ブランド_|F129025SU<br>_EVERFLOW_|AFC0712DD<br>_DELTA_|
|定格|DC12V 0.38A |DC12V 0.45A|
|コネクタ|4ピン|4ピン|
|回転数|不明|5000±10% rpm|
|PWM周波数|不明|推奨20KHz<br>30Hz〜300KHzまで可|


# Arduinoを使って回してみる

ネットを検索すると「Arduino標準PWMの490Hzで回る」派と、「PWMファンは25KHzだからArduino標準では使えない」派の両方の情報がヒットします。では、実際にArduino標準の490Hzで実験してみます。また、同時にファンの回転数も取得してみます。

ファンとArduinoの配線図は[こちらのブログ](http://venticappuccino.blog.fc2.com/blog-entry-29.html)を参考にしました。また、ファンの回転数の取得は[こちらのブログ](https://asukiaaa.blogspot.com/2019/08/arduino.html)を参考にファンからのパルス波の周波数を取得し、回転数(rpm)に変換しました。

Arduino標準PWMのデューティ比を0%から100%まで変化させ、ファンから回転数を取得しグラフ化しました。結果、Arduino標準の490Hzでも問題なく回せることが確認できました。（ファンへは安定化電源装置の12.0V(CCモード)で給電）

_同じデューティ比を10秒間維持し、その間、ファンからのパルス周波数を1秒ごとに取得。10回取得した周波数の最小値と最大値を除いた8個の周波数の平均値からファンの回転数(rpm)を算出。_

![rpm_g.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283293/4890ac00-c21d-94fe-d115-5ef5a19f4dae.png)
上のグラフはX軸がデューティ比、Y軸がファンの回転数で、明らかに相関関係が見られます。

最大回転数（デューティ比100%）は、70mmFANは5000rpmでスペック通り、90mmFANは4200rpmと分かりました。
ただ、両方のファンともデューティ比25%ぐらいまで、回転数に変化が見られません。そういう仕様なのかは不明。

また、デューティ比0%の時はファンの回転は止まる（70mmFANのデータシートに記載あり）と想定したが、実際は両方のファンとも低速で回っていました。念のため、ファンのPWM入力信号線を直接GNDに接続しても結果は同じで、やはりデューティ比0%でもファンは回るようです。

> Arduino標準API[`analogWrite(pin, value)`](https://www.arduino.cc/reference/en/language/functions/analog-io/analogwrite/)（value: the duty cycle: between 0 (always off) and 255 (always on). Allowed data types: int.）
valueには0〜255の整数を指定し、0がデューティ比0%、255がデューティ比100%の意味となる。よって、上のグラフでは、「value÷255×100%」をデューティ比とした。アナログといっても256階調。


# PWMファンの考察

前項で実際にファンを回してみて分かったことは、

- (おそらく大半の)PWMファンは、Arduino標準の490HzのPWMでも回転数を制御できる
- デューティ比0%でもファンの回転は止まらない（前出のRaspberry Pi 4用ファンは止まるので、一概に断定はできない）
- デューティ比25%から100%にかけて、ほぼリニアに回転数が上がっていく（ファンの固有差で断定はできないかも）


# ボリュームを使い任意の回転数に設定する

前出の配線図にあったように、Arduinoに10KΩの可変抵抗器（ボリューム）をつなぎ、分圧した電圧値を`analogRead`で読み取り、その結果でPWMのデューティ比を指定するようにしました。

```c++
auto sensorValue = analogRead(0);
auto outputValue = map(sensorValue, 0, 1023, 0, 255); 
analogWrite(9, outputValue);
```

上記は、Arduino UNOのA0ポートにて可変抵抗器で分圧された電圧値を読み取り、A9ポートに接続したPWMファンのデューティ比を変化させるコードです。_2行目の[`map`関数](https://www.arduino.cc/reference/en/language/functions/math/map/)が、入力値の0〜1023を出力の0〜255に変換する関数。_

[Bカーブの可変抵抗器](https://www.marutsu.co.jp/contents/shop/marutsu/mame/78.html)の場合、ボリュームつまみを回す角度に比例して抵抗値が変化するので、つまみを回すとリニアに回転数が上がるという制御ができます。

しかし、前出のグラフで示した通り、デューティ比0%〜25%は回転数がほとんど変わらないため、つまみを回しても最初のうちは比例感が伝わりません。そこで、少しオフセットしてあげて、ダイレクトに比例感が伝わるようにします。

```c++
auto sensorValue = analogRead(0);
auto outputValue = map(sensorValue, 0, 1023, 64, 255);
if (sensorValue == 0) outputValue = 0;
analogWrite(9, outputValue);
```

最初のコードとの差は、`map`関数の4番目の引数で、入力値0〜1023を出力の64〜255（デューティ比25%〜100%）にマップします。こうすることで本当にリニアに反応するようになります。
また、デューティ比0%のときに回転が停止するファンのために、出力値を0に戻しておきます。

ここまででファンを回す制御は理解できました。この回転数制御を[ATTiny85マイコン](https://www.microchip.com/en-us/product/ATTINY85)で実現します。


# ATTiny85マイコンでPWM制御する

お試しではArduino UNOを使いましたが、モバイル環境では、あんな大きい（サイズ及び消費電力）ボードは使えません。サイズも消費電力も小さいATTiny85を使って制御することにします。

PWM制御の方法は[こちらのソースコード](https://github.com/swvincent/arduino-fan-controller/blob/master/attiny-pot/attiny-pot.ino)を参考にしました。25KHzのPWM制御になっていて、デューティ比の分解能は160階調ですが実用上は十分です。

ATTiny85にプログラムを書き込み実際のPWM出力を測定しました。周波数が測れるデジタルテスターと[簡易オシロスコープ](https://www.iizuka.kyutech.ac.jp/faculty/physicalcomputing/pc_kitscope)で確認したところ、どちらも周波数は26KHz付近と出ました。

可変抵抗器で分圧した0V、2.5V、5VでのPWM波形の簡易オシロのスクショを貼っておきます。上側(Ch1)の波形がPWM出力波形、下側(Ch2)の直線波形が分圧値です。

- 分圧0V
![0v.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283293/867e8ef2-2c75-e7a7-98f5-42b109f643d9.png)
本来デューティ比0%ですが、下限を25%にオフセットさせているため矩形波形が出ています。


- 分圧2.5V
![2.5v.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283293/372d24e7-2bab-096e-e110-64cce4902b3f.png)
設計上はデューティ比62.5%のはず。波形からは63.2%に見える？


- 分圧5.0V
![5v.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283293/6747179d-2a13-410b-12b2-a94abf628d60.png)
最大の5Vなのでデューティ比100%になっています。


実際にファンを付けて可変抵抗器（ボリューム）を回すと、Arudinoで実験したときと同じようにファンの回転がリニアに変化します。ATTiny85化はこれで完了です。




>余談ですが、
上の[簡易オシロスコープ](https://www.iizuka.kyutech.ac.jp/faculty/physicalcomputing/pc_kitscope)の見た目は、[こちらのブログ](https://dbpro.xyz/4975)を参考に着せ替えしています。
このオシロはお手軽に電圧波形を見れるのですごく重宝しています（九工大さんありがとう！）。さらに、この画面上にリアルタイムに周波数や実効電圧も表示されるともっと便利だなと思います。Processingを勉強していつか自分で機能追加したいと思います。
本物のオシロスコープが欲しいですが、2Ch仕様だと数万するのでなかなか手が出ません。1Ch仕様だと数千でありますが、やっぱり最低2Ch欲しい。


# モバイル扇風機にするための最後の追い込み

回転数の制御はほぼ出来上がったので、残るは**入力電源**です。

## 電源

モバイル扇風機にするため、使用する電源はモバイルバッテリもしくはUSB充電器を想定しています。そのため、DC5Vからファンを回すDC12Vに昇圧させる必要があり、ここは安価な昇圧モジュールで済ませます。例えば、[こちらの製品](https://www.aitendo.com/product/20303)だと、5V入力で12V 0.8Aを出力できます。
なお、入力電源の5VでATTiny85マイコンも駆動させます。

>ちなみに、手持ちのファンはDC5Vでも回りますが、まともな風力は得られませんでした。やはり12Vで回してやる必要があります。


## 電源スイッチ

たとえデューティ比0%のときに回転が停止したとしても、電力は消費され続けるので、電源オフは必須です。スイッチ付きのボリュームを使えば、つまみを反時計回りに最大回すとスイッチがオフになるので、ここに入力電源のプラス側を通すのがスマートです。
単なる可変抵抗器の場合は、別にスライドスイッチ等が必要。


# プロトタイプの作成

電源スイッチを除くパーツをブレッドボード上で配線して最終の動作確認をしました。問題なくファンは回り、回転制御もできています。
![IMG_9430.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283293/a034a4dd-2ebc-b96a-aba0-dcaab8caf7ea.png)
5V2.1Aのモバイルバッテリからの昇圧でもMAX回転での風圧はかなりのものです。風圧でファンが飛んでいくのでテープで固定しました。


# 完成形

今回は以下のような構成を完成形とします。
**①**マイクロUSBメス端子、**②**スライド式電源スイッチ、**③**ATTiny85マイコン、**④**昇圧モジュール、**⑤**ダイアル調の可変抵抗器、**⑥**ファン接続コネクタ、という部品構成です。これをユニバーサル基板上にハンダ付けして完成させました。

指で風力調整し易いように細長に実装して、サイズは H20mm x W80mm です。仕上げに収縮チューブに入れれば完成。

![mobile_fan_controller.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283293/9925f004-6a35-b41e-cc34-1c1d3d6f96ed.png)
写真右端のコネクタに抵抗がハンダ付けしてありますが、これは扇風機としては不要な部品のため、上の部品リストには無いです。ただ、完成形にした後のファンの回転数を知りたかったので、今回はプルアップ抵抗を仕込んでおきました。


部品は以前に購入してストックしてあるものがほとんどでしたが、調べると部品代の合計は税込726円でした。（昇圧モジュールが高い！、もっと安価な同等品を探すか）

ファンが2個あるので、もう一つ作る予定です。
専用のPCBを起こしたらもう少しコンパクトにできますね。ハンダ付けも楽になるし。夏までまだ時間があるので、PCBを設計しようかな。



## ファンの回転数を調べる

完成した基板に70mmFANを接続、入力は5V3AのUSB電源、風力調整ダイアルを最大にした時の測定で、約5100prmでした。12V駆動時よりも回っています。入力のUSBテスターの表示は5.1V 2.2A。出力側は12.04Vで電流値は未測定。最大風力なのでさすがに電力喰いますね。夏場のモバイルバッテリーでの運用はどんな感じなのか、夏までにロードテストすることにします。

忘れてましたが、ファンのプロペラが剥き出しなので何らか保護が必要ですね。何か考えなきゃ。


# 終わりに

まだまだ寒い日が続いていますが、暑い夏の到来に備えてモバイル扇風機を製作することにしました。今回はPWMファンの仕組みを知る良い機会となりました。次回はPCの電源装置の再利用を考えようと思います。

今回もネットに公開されている様々な情報に助けられました。本当にありがたいです。この記事も誰かの参考になれば幸いです。

**以上**


# 2022.5.4追記

PCBが出来上がりました。サイズは H16.4mm x W79.3mm と、約20％小さくなりました。
![FAN_PCB.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283293/9af4b896-7f97-2f59-f1c5-225cd2a31de9.png)
<i>あれっ、<b>Dial</b>の文字がひっくり返ってますが、愛嬌ということで・・・</i>

[BOOTH](https://orijinalj.booth.pm/items/3871890)で販売中。