Arduinoで遊ぼう - PC用ファンの回転数を表示する
Posted by arms22 on 2010年07月25日

2010/7/30 Make: Onlineで紹介されちゃいました!
Reading a PC fan speed with Arduino
http://blog.makezine.com/archive/2010/07/reading_a_pc_fan_speed_with_arduino.html

すっかりPC用ファンが扇風機代わりとして定着してしまったので、Arduinoを使ってファンの回転数を表示させてみた。マルツで買った4桁の青色7セグLEDがカッチョ良い!夜は眩しすぎるので早々に外してしまったけど、これはキットにしたら売れるんじゃないか!?と思ったり思わなかったり。
PC用ファンは扇風機以外にもこんな活用法がある。他にもっと面白い活用法があれば教えてほしい。
- ハンダ吸煙機
- MacBookクーラー
- 回転するP.O.V
回転数検出
多くのファンは回転数の検出用に回転パルス出力の端子を持っていて、1回転あたり2回のパルス(デューティ比50%)を出力する。このパルスの間隔をマイコンで計測し、2を掛けると1回の回転にかかった時間を求めることができる。さらに60秒÷1回転の時間とすると1分間あたりの回転数=RPM(Revolution Per Minute)を求めることができる。今回、このRPMを7セグLEDに表示している。
ファンの3ピンコネクタのピンアサインは次ぎのようになっている。ケーブルの色はファンによって変わると思うので注意。
- 赤→電源+(12V)
- 黒→電源-
- 黄→回転パルス出力(オープンドレイン/オープンコレクタ)
Arduinoと接続する

回転パルス出力はオープンドレインなので10K~100Kの抵抗でプルアップしてArduinoのD2ポートに接続します。7セグLEDはArduinoで直接ドライブするのでドライバICの類は必要なし。そのかわりアナログポートA0~A5をデジタルポートD14~D19として使います。7セグLEDのセグメント側の端子に電流制限抵抗を入れるのを忘れずに。この抵抗を省略すると点灯しているセグメントの数によって明るさがまちまちになります。

今回使用した7セグLEDの内部配線図です。カソードコモン。7セグLEDとArduinoは次のように接続します。ジャンパの接続し易さを優先したらこうなりました。
- D8→1(E)
- D9→2(D)
- D10→3(DP)
- D11→4(C)
- D12→5(G)
- D13→6(D4)
- D14→7(B)
- D15→8(D3)
- D16→9(D2)
- D17→10(F)
- D18→11(A)
- D19→12(D1)
7セグLEDライブラリ
Arduino用に7セグLEDライブラリを作成しました。ダイナミック点灯制御や便利な数字表示機能搭載です。次のURLからライブラリをダウンロードして、Arduinoのライブラリフォルダ(OSXの場合~/Documents/Arduino/libraries、Windowsの場合My Documents/Arduino/libraries)にコピーしてください。
SevenSegment-001.zip
http://code.google.com/p/arms22/downloads/detail?name=SevenSegment-001.zip
サンプルスケッチ
#include "SevenSegment.h"
SevenSegment seg7(19,16,15,13, // 桁1,桁2,桁3,桁4,
18,14,11,9,8,17,12,10); // A,B,C,D,E,F,G,DP
unsigned long lastPulseTime;
unsigned long pulseInterval;
// 回転パルス立ち下がりエッジ検出用
void senseRotation(void) {
unsigned long cur = micros();
unsigned long dif = cur - lastPulseTime; // 前回のエッジとの差分
pulseInterval = (pulseInterval - (pulseInterval >> 2)) + (dif >> 2); // 滑らかに
lastPulseTime = cur;
}
void setup() {
lastPulseTime = 0;
pulseInterval = 0;
attachInterrupt(0, senseRotation, FALLING); // 0 = D2, FALLING = 立ち下がり
seg7.begin(); // 7セグLED動作開始
}
unsigned long lastUpdateTime;
void loop() {
if(seg7.update()){ // ダイナミック点灯制御を行うのでできるだけ短い間隔で呼ぶ
unsigned long cur = millis();
if(cur - lastUpdateTime > 60){ // 60ms間隔でLEDを更新
uint16_t rpm = 60000000 / (pulseInterval * 2); // RPMを求める
seg7.print(rpm); // 7セグLED表示更新
lastUpdateTime = cur;
}
}
}
関連URL
PICマイコンを使ったファンの速度制御
http://shino.pos.to/eda/speed.html
FANの回転パルス信号
http://tutinoko.org/blog/?p=1031
Arduinoをはじめよう
posted with amazlet at 10.07.25
Massimo Banzi
オライリージャパン
売り上げランキング: 3450
オライリージャパン
売り上げランキング: 3450
Ads by Google
26 Comments
>これはキットにしたら売れるんじゃないか!?
シールドにしてしまいましょう
SSRを付けて速度のコントロールもしてしまう。
ダクトを付けて氷を入れたアイスボックスから冷気を
出して冷風扇的な感じにする。
小型化すれば卓上冷風扇として売れるかも?
7セグも涼しげな感じだから…
USB冷風扇にしましょう
シールドにしてしまいましょう
SSRを付けて速度のコントロールもしてしまう。
ダクトを付けて氷を入れたアイスボックスから冷気を
出して冷風扇的な感じにする。
小型化すれば卓上冷風扇として売れるかも?
7セグも涼しげな感じだから…
USB冷風扇にしましょう
冷風扇いいですねー。個人的にほしいかも。
この12cmファンって回すのに12Vいるみたいだから、
USBで動かす時は昇圧しないとだめですねー。
この12cmファンって回すのに12Vいるみたいだから、
USBで動かす時は昇圧しないとだめですねー。
つくってみたいですねー
ところで、7セグLEDのセグメント側端子の抵抗は100Ωくらいで大丈夫でしょうか?
ところで、7セグLEDのセグメント側端子の抵抗は100Ωくらいで大丈夫でしょうか?
今、200Ωにしてます。
VF=3.5Vらしいので、
5V - 3.5V / 200 ohm = 7.5mA / 4(桁) = 約1.8mA
で、大丈夫かなと。
atmega328は1ポートあたり40mAぐらいいけたんじゃないかな?
もう少し小さくすればもっと明るくなる。
VF=3.5Vらしいので、
5V - 3.5V / 200 ohm = 7.5mA / 4(桁) = 約1.8mA
で、大丈夫かなと。
atmega328は1ポートあたり40mAぐらいいけたんじゃないかな?
もう少し小さくすればもっと明るくなる。
素人ですのでライブラリのコードを理解できず、サンプルスケッチ以上のライブラリの使い方がわかりません。出来ましたら、簡単に使い方を解説していただけないでしょうか?
また、このライブラリは整数のみの表示でしょうか?小数点付きの数値の表示が可能でしょうか?
サンプル以上の使い方はありません。
ライブラリを好きなように改造してお使いください。
浮動小数点について現在未対応です。
整数部、小数部を分けて1桁ずつ表示する必要があります。
1桁ずつ表示する方法は次のようにwrite関数を使います。
write(digit, SevenSegment::NUMERICAL_NUMBER[value % 10]);
digitは桁
SevenSegment::NUMERICAL_NUMBERは
0-9の数字のセグメントビットパターンを格納した配列です。
次のように点灯させたいセグメントのビットをORした値が格納されています。
SEG_A_BIT | SEG_B_BIT | SEG_C_BIT | SEG_D_BIT | SEG_E_BIT | SEG_F_BIT,
ドットを点灯させたい場合、SEG_DP_BITをORすればよいでしょう。
ライブラリを好きなように改造してお使いください。
浮動小数点について現在未対応です。
整数部、小数部を分けて1桁ずつ表示する必要があります。
1桁ずつ表示する方法は次のようにwrite関数を使います。
write(digit, SevenSegment::NUMERICAL_NUMBER[value % 10]);
digitは桁
SevenSegment::NUMERICAL_NUMBERは
0-9の数字のセグメントビットパターンを格納した配列です。
次のように点灯させたいセグメントのビットをORした値が格納されています。
SEG_A_BIT | SEG_B_BIT | SEG_C_BIT | SEG_D_BIT | SEG_E_BIT | SEG_F_BIT,
ドットを点灯させたい場合、SEG_DP_BITをORすればよいでしょう。
ありがとうございました。いろいろ試してみたいと思います。
初めまして。
ファン回転数計が欲しいと思っていて検索していたらコチラに辿りつきました。
電子工作やプログラムの経験は全く無いのでお馬鹿な事聞いていたらすいません。
ファン駆動のためと回転数計の電源を別に取るなんてことは安全性の上で大丈夫でしょうか?
・ファンの12V+-線は別電源から取る。
(直流安定化電源で0V~駆動電圧~12Vまでの範囲で動かします)
・ファンのパルス線だけ回転数計に繋げる
・回転数計の電源はACアダプター7~9Vからとろうと思っています。
各電圧時の回転数が知りたいと思い、こういう繋げ方でこの回転数計を作ろうかと思うのですが、
パルス線で繋がっているので2つの電源がパルス線でぶつかっていて、もしかしてこれは危険?と思ったんですが。
また、この使い方でプログラムや電子部品を別のものに変える必要が出てくるのでしょうか?
知識が足りなくてうまく纏めることができなくてすいません。
ファン回転数計が欲しいと思っていて検索していたらコチラに辿りつきました。
電子工作やプログラムの経験は全く無いのでお馬鹿な事聞いていたらすいません。
ファン駆動のためと回転数計の電源を別に取るなんてことは安全性の上で大丈夫でしょうか?
・ファンの12V+-線は別電源から取る。
(直流安定化電源で0V~駆動電圧~12Vまでの範囲で動かします)
・ファンのパルス線だけ回転数計に繋げる
・回転数計の電源はACアダプター7~9Vからとろうと思っています。
各電圧時の回転数が知りたいと思い、こういう繋げ方でこの回転数計を作ろうかと思うのですが、
パルス線で繋がっているので2つの電源がパルス線でぶつかっていて、もしかしてこれは危険?と思ったんですが。
また、この使い方でプログラムや電子部品を別のものに変える必要が出てくるのでしょうか?
知識が足りなくてうまく纏めることができなくてすいません。
こんにちは。
僕もあまりハードウェアは詳しくないので外しているかもしれませんが、
ファンのパルス線はオープンドレインになっているようなので、
オン時はGND、オフ時オープンになると思うので大丈夫かなーと。
もし心配でしたらトランジスタを間に挟むとかいかがでしょう?
もしからしたらもっといい方法があるかも。。
僕もあまりハードウェアは詳しくないので外しているかもしれませんが、
ファンのパルス線はオープンドレインになっているようなので、
オン時はGND、オフ時オープンになると思うので大丈夫かなーと。
もし心配でしたらトランジスタを間に挟むとかいかがでしょう?
もしからしたらもっといい方法があるかも。。
素早い回答ありがとうございます。
直流安定化電源だけだとファンの0V~駆動電圧域(ファンによっても違いますが、3~6,7V辺りのようです)ではArduino側が起動しないと思い、電源2つでそれぞれ別電源で動かして、パルス線から回転数だけ取れないかみたいな考えなんです。
わざわざ回答してくださったarms22さんのコメントを見ても自分にはまだよく理解できませんでした。
まだまだ勉強あるのみのようです。
まずは勉強も兼ねてarms22さんのこの形そのままで作ってみたいと思います。
良いトピックありがとうございます。既にブックマークに入れてあります(笑
直流安定化電源だけだとファンの0V~駆動電圧域(ファンによっても違いますが、3~6,7V辺りのようです)ではArduino側が起動しないと思い、電源2つでそれぞれ別電源で動かして、パルス線から回転数だけ取れないかみたいな考えなんです。
わざわざ回答してくださったarms22さんのコメントを見ても自分にはまだよく理解できませんでした。
まだまだ勉強あるのみのようです。
まずは勉強も兼ねてarms22さんのこの形そのままで作ってみたいと思います。
良いトピックありがとうございます。既にブックマークに入れてあります(笑
パルスを拾って内部で計算して表示させてるのなら
これを応用すれば脈拍計もできそうですね
I2Cの小型LCDと組み合わせて小さいの作ろうかと
思ってまして参考になります(^^)v
これを応用すれば脈拍計もできそうですね

I2Cの小型LCDと組み合わせて小さいの作ろうかと
思ってまして参考になります(^^)v
脈拍計は作ってみたいですな~
#include "SevenSegment.h"
SevenSegment seg7(19,16,15,13, // 桁1,桁2,桁3,桁4,
18,14,11,9,8,17,12,10); // A,B,C,D,E,F,G,DP
らへんで エラーがでるんやけど>>>>>>>
どうすればっばばばばばばばっばっばbbbb
SevenSegment seg7(19,16,15,13, // 桁1,桁2,桁3,桁4,
18,14,11,9,8,17,12,10); // A,B,C,D,E,F,G,DP
らへんで エラーがでるんやけど>>>>>>>
どうすればっばばばばばばばっばっばbbbb
このコメントは管理人のみ閲覧できます
次の行を、
_numberOfDigits = 4;
次のように変更してみてください。
_numberOfDigits = 3;
これで大丈夫なはず。
だめなら配線が間違っている可能性も考慮してください。
_numberOfDigits = 4;
次のように変更してみてください。
_numberOfDigits = 3;
これで大丈夫なはず。
だめなら配線が間違っている可能性も考慮してください。
このコメントは管理人のみ閲覧できます
PCファンの回転数が測定したくて、参考にさせて頂きました。
Arduinoも初めてです。完成品っぽくシールド化してい
ます。PWMで可変速したら不調でしたので、再度煮詰めます。
フォトインタラプタとか使って試作してみようかなと思います。
Arduinoも初めてです。完成品っぽくシールド化してい
ます。PWMで可変速したら不調でしたので、再度煮詰めます。
フォトインタラプタとか使って試作してみようかなと思います。
手順通りに行うとエラーが出ていたので調べた所、
7セグLEDライブラリSevenSegment.cpp一行目を
#include "WProgram.h" から #include "arduino.h"にすることで回避できました。
ArduinoIDE1.0.1ぐらいから変わっているようです。
7セグLEDライブラリSevenSegment.cpp一行目を
#include "WProgram.h" から #include "arduino.h"にすることで回避できました。
ArduinoIDE1.0.1ぐらいから変わっているようです。
ファンの回転数の検出はどうやっているのですか?
ソフトウェアの実装の話として回答すると、ファンのパルス出力をArduinoのピン変化割り込みで検出し、割り込みと割り込みの間隔から回転数を求めています。
このコメントは管理人のみ閲覧できます
このコメントは管理者の承認待ちです
このコメントは管理者の承認待ちです
このコメントは管理者の承認待ちです
Leave a reply
該当の記事は見つかりませんでした。