CircuitPython 10行プログラミング (10) FANコントロール

 Trinket M0マイコン・ボードとCircuitPythonを使って、モータのコントロールをします。
 PCのCPUファン、ケース・ファンは、12Vをつなぐと回転します。騒音を減らす目的なのか、最近のFANは大型化し、回転数は低めです。1Uや2Uのサーバに使われている小型形状のFANは高速回転するのでとてもうるさいです。

 この用途のモータは、DCブラシレスと思われます。マブチモーターのようなDCブラシありとほぼ同様の駆動ができます。

ピンの信号

 現在、3ピンと4ピンの規格があり、4ピンに対応しているマザーボードが増えています。4ピンは3ピンの規格と互換性があるので、3ピンの部分の信号だけを利用する使い方もできます。装飾用にLEDが搭載されてモデルが主流ですが、消費電力は増えていると思われます。
 上の写真の下側の2点は、1U/2Uサーバ用です。FANが二つ合わさった構成になっているので、コネクタは6もしくは8ピンが使われます。

信号名 GND V+(12V) 回転数通知 PWM入力
3ピン  -
4ピン

 FANから出ているコネクタです。


 ファンを回転するために必要なのは、GNDと12Vです。FANによって異なりますが、12V端子の電圧は6~9Vでゆっくり回ります。10~12Vがフル回転に必要な電圧だと思われます。
 回転数を読み出すのが3番目のピンです。オープン・コレクタもしくはオープン・ドレイン出力なので、10kΩ前後の抵抗でプルアップすると信号が見えます。4番目のピンはPWM信号を与えます。FANの軸に内蔵されたモータ・コントローラからすれば入力です。回転数はPWMのディーティ比で決まります。筆者の調べた範囲で周波数は関係ありませんでした。
 4番ピンに何もつながないとディーティ比は100%なので、FANはフル回転します。4番ピンをGNDにつなぐとディーティ比は0%なので、回転しません。通常のPCでは3番ピンをつながなくてもFANは回転します。サーバは3番ピンを監視しているので、信号がつながっていないと警告が出ます。サーバによっては、BIOSから先に進みません。

 3番目のピンの回転数出力は、1回転で2パルスが出るといわれていますが、未確認です。

接続

 4ピンのコネクタが付いたFANを用意しました。消費電流を測りました。

  • 5V 0.05A
  • 10V 0.15A
  • 12V 0.22A

 12V電源は、USBの5V入力から高い電圧に昇圧するDC-DCコンバータを利用します。アマゾンで入手しました。出力電流は最大200mAのようなので、多回転半固定抵抗をまわして11Vに設定しました。

 配線です。Trinket M0マイコン・ボードの「0」をモータへ回転数を指令するPWM信号を、「1」はモータからの回転数の通知信号を受けます。「2」はアナログ入力に使い、ボリュームの電圧を読みます。この電圧をもとにPWMのデューティ比を変更します。

プログラム

 変数speedでデューティ比を変えています。

speed値 デューティ比[%]
2000 3
4000 6
8000 12
10000 15
15000 23
32000 49
38000 58
43000 66
49000 75
52000 80
59000 90
65000 99

 周波数は50Hzです。

import pulseio
import time
from board import *

speed = 2000
print('speed', speed)

pwm = pulseio.PWMOut(D0, frequency=50)
pwm.duty_cycle = speedtime.sleep(5)
pwm.duty_cycle = speed + 30000
time.sleep(5)
pwm.duty_cycle = speed + 63000
time.sleep(5)
pwm.duty_cycle = speed
time.sleep(500)

 デューティ比 3%のときです。赤色がPWM出力(4番ピン)、青色が3番ピンです。周波数は約29Hzです。

 デューティ比 50%のときです。赤色がPWM出力(4番ピン)、青色が3番ピンです。周波数は約34Hzです。

 デューティ比 99%のときです。赤色がPWM出力(4番ピン)、青色が3番ピンです。周波数は約52Hzです。ディーティ比が上がるほど、回転数は増えます。
 ディーティ比と回転数、ディーティ比と風量の関係は測定していません。

回転数をコントロール

 Tinket M0マイコン・ボードは、ロータリ・エンコーダが使えませんでした。回転数を調整するのには最適ですが、ここではボリュームを使います。両端のピンを3.3VとGNDの電源につないで、摺動部(真ん中のピン)から電圧を得、アナログ入力に入れて、回転角相当の値を得ます。

import pulseio
from time import sleep
from board import *
import analogio

pin = analogio.AnalogIn(A1)

while 1:
print(pin.value)
sleep(1)

 左に回し切ると約100、中央付近は約3000、右に回し切ると約65500でした。

 ボリュームの値をそのままduty_cycleに代入します。

import pulseio
import time
from board import *
import analogio

pwm = pulseio.PWMOut(D0, frequency=50)
pin = analogio.AnalogIn(A1)

while 1:
print(pin.value)
pwm.duty_cycle = pin.value
time.sleep(1)

 「1」の入力は、何の用途にも使っていません。