昨日、午前3時まで9時間掛かってやっとこさ100%まで再充電(寝たいんだがそれだと実験がますます遅れる)
現在2回目の24時間耐久扇風機レースの19時間目を継続中
だが、朝起きたら既に回転数が落ちていたのだ。
明日明け方3時に24時間になるが、今回は止めずの0になるまで回し続けてやる。
どう考えてもBMSかモーター制御がおかしい。
今まではレビューは到着後2日以内にはアップしてたが今回は、とことんゆっくりやってやる、と覚悟を決めた。
現役時代の翌朝レポート提出が身につきすぎてイライラするのだが・・・
ホント苦しいんだよ、ズルズル懸案事項を持ち続けるのが。
ーーーー
本日は梅雨の雨がずっと降ってるし、昨日の疲れも残ってるので家でダラダラしてたが、
ファンの回転数を計測してみたくなった。
湿度は85%とかで、部屋の中ベタベタ! もう生きていけない。エアコンずっと回しました。
外気温は23度なので、結構寒いんよ。
まずはジャンクのファンを測定したが、位置が定まらず変な値ばっかり出てくる。
しょうがないのでマジに腰を据えて環境を作ることにした。
アルミ箔を貼った黒色円盤をPWM制御のDCモータで回す。
距離とか感度の調整が結構シビアで面倒くさかった。
マブチモータを台座に乗せて固定、例の赤外線センサーをArduino2番ピンへ繋いで、針金で浮かせる。
今回はダイソーの有孔ボードへ固定して作ったよ。
この実験ボード作るほうが遥かに時間がかかってるw
やっぱり安定し味件環境が必須なのです!
プログラムは、
扇風機のペラにアルミ箔を貼って回転数を数えさせればいいはずなので、Arduinoで簡単に実現できるはず。
が、プログラムを一から作るのも面倒なので、GPTにやらせることにした。
この初期プログラム、考えは簡単なんだがダメですわ。手抜きで値がコロコロ変わる。
何回か改良させて完成。
羽根にはアルミ箔を貼って反射率を高めてパルスを捉える。
Arduino側では基板信号をキャッチする。
パルスを拾って回転数を計算させる。
そんな感じの簡単な装置でOK
まずは概要を提案して
ただし、回転数が上がっても3秒に一回シリアル通信するだけに制御
2026-06-20
条件を反映した版です。
変更点
・直近5回分の回転周期を平均化
・表示は整数RPMのみ
・シリアル出力は3秒に1回だけ
・内部では常時測定
・ノイズ除去
・停止判定あり
volatile unsigned long pulseInterval = 0;
volatile unsigned long lastPulseTime = 0;
volatile bool newData = false;
const int AVG_COUNT = 5;
unsigned long intervalBuf[AVG_COUNT];
int bufIndex = 0;
int bufCount = 0;
unsigned long lastPrint = 0;
float rpmFiltered = 0;
void pulse()
{
unsigned long now = micros();
// 10ms以下はノイズ扱い
if ((now - lastPulseTime) < 10000UL)
return;
if (lastPulseTime != 0)
{
pulseInterval = now - lastPulseTime;
newData = true;
}
lastPulseTime = now;
}
void setup()
{
Serial.begin(9600);
attachInterrupt(
digitalPinToInterrupt(2),
pulse,
RISING
);
}
void loop()
{
unsigned long interval;
// 新しい回転周期を取得
if (newData)
{
noInterrupts();
interval = pulseInterval;
newData = false;
interrupts();
if (interval > 0)
{
float rpm = 60000000.0 / interval;
// 扇風機範囲
if (rpm >= 50 && rpm <= 3000)
{
intervalBuf[bufIndex] = interval;
bufIndex++;
if (bufIndex >= AVG_COUNT)
bufIndex = 0;
if (bufCount < AVG_COUNT)
bufCount++;
// 周期平均
unsigned long sum = 0;
for (int i = 0; i < bufCount; i++)
{
sum += intervalBuf[i];
}
unsigned long avgInterval =
sum / bufCount;
rpmFiltered =
60000000.0 / avgInterval;
}
}
}
// 1秒間パルスなし → 停止
if ((micros() - lastPulseTime) > 1000000UL)
{
rpmFiltered = 0;
bufCount = 0;
bufIndex = 0;
}
// 表示は3秒ごとだけ
if (millis() - lastPrint >= 3000)
{
lastPrint = millis();
Serial.print("RPM = ");
Serial.println((int)(rpmFiltered + 0.5));
}
}
動作イメージ
低速
RPM = 520
(3秒)
RPM = 518
(3秒)
RPM = 521
高速にしても
RPM = 1240
(3秒)
RPM = 1252
(3秒)
RPM = 1248
のようになります。
また、3秒表示なのでシリアルモニタが流れず、扇風機の風量切替確認用として見やすい設定です。

















