1. はじめに
モータや回転機械の回転数を測定する方法の一つに、反射型赤外線センサを使った非接触測定があります。
今回は、M5Stackの小型マイコン「M5StickS3」と反射型赤外線センサ「Reflective IR Unit」を組み合わせ、簡易的な非接触回転計を製作しました。
さらに、LEGOのタイヤと回転数を制御できるモータを使って実験装置を組み立て、製作した回転計の測定値をモータ内蔵のエンコーダと比較しました。
また、白色テープを1枚から2枚に増やすことで、検出するパルスの周波数が2倍になることも確認しました。
この記事では、回転計の測定原理、センサの接続、Arduinoプログラム、測定実験の結果について紹介します。
2. 使用した機器
今回使用した主な機器を表1に示します。
表1 使用した主な機器
| 機器 | 型式・用途 |
|---|---|
| 小型マイコン | M5StickS3(M5Stack) |
| 反射型赤外線センサ | Reflective IR Unit U175(M5Stack) |
| モータ | Roller485 Lite(M5Stack) |
| モータ制御用マイコン | M5GO(M5Stack) |
| 回転体・支持部材 | LEGOのタイヤ、ブロック |
| その他 | 白色テープ、接続ケーブルなど |
非接触回転計の製作に必要なのは、M5StickS3と反射型赤外線センサです。
M5GO、Roller485 Lite、LEGOなどは、製作した回転計の動作を確認するための実験装置に使用しました。
3. 非接触回転計の測定原理
3.1 反射型赤外線センサによるパルスの検出
反射型赤外線センサは、赤外線を照射し、対象物から反射して戻ってくる光の強さを検出するセンサです。
回転体の表面に白色テープを貼り付けると、テープと周囲の表面で赤外線の反射量が変化します。
この変化を利用することで、テープがセンサの前を通過したことを検出できます。
例えば、回転体に反射テープを1枚貼り付けた場合、1回転するごとに1つのパルスが発生します。
このパルスの発生間隔から回転数を求めます。
3.2 パルス間隔から回転数を計算する
パルス間隔を (T)(秒)、1回転当たりのパルス数を (P) とすると、回転数 (N)(rpm)は次式で求められます。
$$
N=\frac{60}{TP}
$$
今回製作した回転計では、マイコンの micros() 関数を使用して、パルスの発生間隔をマイクロ秒(µs)単位で測定します。
1分間は60,000,000 µsなので、プログラムでは次の式を使用します。
rpm = 60000000.0f /
(period * PULSES_PER_REV);
ここで、
-
period:パルス間隔(µs) -
PULSES_PER_REV:1回転当たりのパルス数
です。
例えば、反射テープが1枚で、パルス間隔が100,000 µs(0.1秒)であれば、
$$
N=\frac{60,000,000}{100,000\times1}
=600\ \mathrm{rpm}
$$
となります。
4. M5StickS3とセンサの接続
今回使用した反射型赤外線センサU175には、アナログ出力とデジタル出力があります。
今回はデジタル出力を使用し、M5StickS3のGPIO9に接続しました。
表2 センサの接続
| Reflective IR Unit U175 | M5StickS3 |
|---|---|
| 5V | Grove端子の5V |
| GND | GND |
| D.OUT | GPIO9 |
今回使用したU175は5 V電源で動作し、デジタル出力は内部の3.3 V系にプルアップされています。
そのため、デジタル出力をM5StickS3のGPIO9に入力できます。なお、別のセンサを使用する場合は、出力電圧を確認する必要があります。
M5StickS3からセンサに電源を供給するため、プログラムではGrove端子の外部電源出力を有効にしています。
M5.Power.setExtOutput(true);
5. Arduinoプログラム
5.1 開発環境
プログラムはArduino IDEを使用して作成しました。
M5StickS3の制御には、M5Stackの共通ライブラリである M5Unified を使用しています。
Arduino IDEでM5StickS3に対応するボードを選択し、必要なライブラリをインストールしてからプログラムを書き込みます。
5.2 プログラム全文
以下は、今回の実験で実際に使用したプログラムです。
反射型赤外線センサからのパルスを割り込み処理で検出し、パルス間隔から回転数を計算します。
M5StickS3のディスプレイには、回転数(RPM)と起動後の累積パルス数(Pulse)を表示します。
#include <M5Unified.h>
constexpr int SENSOR_PIN = 9;
constexpr int PULSES_PER_REV = 1;
constexpr uint32_t MIN_PULSE_US = 1000;
constexpr uint32_t STOP_TIMEOUT_US = 2000000;
volatile uint32_t lastPulseUs = 0;
volatile uint32_t periodUs = 0;
volatile uint32_t pulseCount = 0;
void IRAM_ATTR onPulse() {
uint32_t now = micros();
uint32_t dt = now - lastPulseUs;
if (lastPulseUs == 0 || dt >= MIN_PULSE_US) {
if (lastPulseUs != 0) {
periodUs = dt;
}
lastPulseUs = now;
pulseCount++;
}
}
void setup() {
auto cfg = M5.config();
M5.begin(cfg);
// Grove端子の5V出力を有効化
M5.Power.setExtOutput(true);
Serial.begin(115200);
M5.Display.setRotation(1);
M5.Display.setTextColor(WHITE, BLACK);
M5.Display.setTextSize(2);
pinMode(SENSOR_PIN, INPUT);
// 反射テープ検出時の信号極性に応じて変更
attachInterrupt(
digitalPinToInterrupt(SENSOR_PIN),
onPulse,
FALLING
);
}
void loop() {
M5.update();
static uint32_t lastDisplayMs = 0;
if (millis() - lastDisplayMs >= 200) {
lastDisplayMs = millis();
uint32_t period;
uint32_t lastTime;
uint32_t count;
noInterrupts();
period = periodUs;
lastTime = lastPulseUs;
count = pulseCount;
interrupts();
float rpm = 0.0f;
if (lastTime != 0 &&
(uint32_t)(micros() - lastTime)
< STOP_TIMEOUT_US &&
period > 0) {
rpm = 60000000.0f /
(period * PULSES_PER_REV);
}
M5.Display.fillScreen(BLACK);
M5.Display.setCursor(10, 20);
M5.Display.printf("RPM: %.1f", rpm);
M5.Display.setCursor(10, 65);
M5.Display.printf("Pulse: %lu",
(unsigned long)count);
Serial.printf("RPM=%.1f, Pulse=%lu\n",
rpm, (unsigned long)count);
}
}
5.3 プログラムのポイント
(1)センサへの電源供給
M5.Power.setExtOutput(true);
M5StickS3のGrove端子から反射型赤外線センサへ電源を供給するため、外部出力を有効にしています。
(2)割り込みによるパルスの検出
attachInterrupt(
digitalPinToInterrupt(SENSOR_PIN),
onPulse,
FALLING
);
センサのデジタル出力がHIGHからLOWに変化したときに、割り込み関数 onPulse() を実行します。
割り込みを利用することで、画面表示などの処理中でもパルスを検出できます。
なお、センサの出力極性によっては、FALLING を RISING に変更する必要があります。
(3)パルス間隔の測定
uint32_t now = micros();
uint32_t dt = now - lastPulseUs;
micros() 関数で現在の時刻を取得し、前回のパルス検出時刻との差からパルス間隔を求めます。
(4)ノイズ対策
constexpr uint32_t MIN_PULSE_US = 1000;
パルス間隔が1,000 µs(1 ms)未満の場合は、ノイズと判断して除外しています。
この値は今回の実験用に設定したものであり、測定対象やセンサの状態に応じて変更する必要があります。
(5)回転数の計算
rpm = 60000000.0f /
(period * PULSES_PER_REV);
測定したパルス間隔から回転数を計算します。
PULSES_PER_REV は1回転当たりのパルス数です。今回の実験では、反射テープを1枚貼った状態を基本としているため、1に設定しています。
(6)停止判定
constexpr uint32_t STOP_TIMEOUT_US = 2000000;
最後にパルスを検出してから2秒以上経過した場合は、回転数を0 rpmと表示します。
この設定では、反射テープ1枚の場合、30 rpm付近以下の低回転数では安定した測定が難しくなります。
(7)測定結果の表示
ディスプレイには回転数と累積パルス数を表示します。
表示の更新間隔は200 msです。
なお、Pulse は起動後に検出した累積パルス数であり、回転数の計算には使用していません。
6. LEGOを使った回転数測定実験
6.1 実験装置
製作した非接触回転計の動作を確認するため、LEGOのタイヤとM5StackのRoller485 Liteを使用して実験装置を組み立てました。
Roller485 Liteは、内部のエンコーダによって回転数を取得できるモータです。
今回は、M5GOを使用してモータの回転数を制御し、ボタン操作で設定回転数を100 rpmずつ変更できるようにしました。
M5GOのディスプレイには設定回転数とエンコーダから取得した実回転数を表示します。
一方、M5StickS3では、反射型赤外線センサによって測定した回転数を表示します。
6.2 反射テープ1枚での測定
最初に、LEGOのタイヤに白色テープを1枚貼り付けて測定しました。
モータの設定回転数を100~600 rpmの範囲で変更し、モータのエンコーダによる実回転数と非接触回転計の表示値を比較しました。
測定結果を表3に示します。
表3 反射テープ1枚での測定結果
| 設定回転数 (rpm) | エンコーダ (rpm) | 非接触回転計 (rpm) |
|---|---|---|
| 100 | 100.4 | 100.2 |
| 200 | 198.5 | 201.6 |
| 300 | 299.1 | 301.1 |
| 400 | 398.3 | 401.8 |
| 500 | 501.2 | 502.3 |
| 600 | 599.4 | 602.5 |
非接触回転計の表示値は、モータのエンコーダによる実回転数とおおむね一致しました。
この結果から、反射型赤外線センサを利用して、回転数を非接触で測定できることが確認できました。
なお、今回は両装置の表示値を撮影して比較しており、厳密な測定精度の評価を行ったものではありません。
6.3 反射テープ2枚での測定
次に、タイヤの180°反対側に白色テープをもう1枚貼り付け、同様の実験を行いました。
写真4 反射テープを2か所に貼り付けたタイヤ
反射テープが1枚の場合、タイヤが1回転するごとに1つのパルスが発生します。
一方、反射テープを2枚にすると、1回転当たり2つのパルスが発生します。
したがって、同じ回転数であれば、パルスの発生間隔は約半分になります。
ただし、今回の実験では、プログラムの PULSES_PER_REV を1のまま変更していません。
そのため、表示される回転数は、実際の回転数の約2倍になると予想されます。
測定結果を表4に示します。
表4 反射テープ2枚での測定結果
| エンコーダ (rpm) | 非接触回転計表示値 (rpm) | 倍率 |
|---|---|---|
| 100.7 | 202.7 | 2.013 |
| 197.6 | 401.5 | 2.032 |
| 299.8 | 595.3 | 1.986 |
| 401.1 | 802.8 | 2.001 |
| 502.6 | 997.6 | 1.985 |
| 602.4 | 1203.0 | 1.997 |
測定の結果、非接触回転計の表示値は、予想どおりモータの実回転数のほぼ2倍となりました。
例えば、モータの実回転数が約600 rpmの場合、非接触回転計では約1,200 rpmと表示されました。
これは、モータの回転数が2倍になったわけではなく、反射テープを2枚にしたことで、検出パルスの周波数が2倍になったためです。
この結果から、約1,200 rpmに相当するパルス周波数を検出できることが確認できました。ただし、実際に1,200 rpmで回転する物体を測定したわけではありません。
なお、テープ2枚で実際の回転数を表示したい場合には、プログラムの設定を次のように変更します。
constexpr int PULSES_PER_REV = 2;
このように、反射テープの枚数に応じて1回転当たりのパルス数を設定することで、回転数を計算できます。
また、2枚のテープの位置が正確に180°離れていない場合には、パルス間隔が交互に変化するため、表示回転数がばらつく可能性があります。
7. おわりに
今回は、M5StickS3と反射型赤外線センサを組み合わせ、簡易的な非接触回転計を製作しました。
LEGOのタイヤとRoller485 Liteを使った実験では、100~600 rpmの範囲で、モータのエンコーダによる回転数とおおむね一致する結果が得られました。
さらに、反射テープを2枚に増やすことで、検出パルスの周波数が約2倍となり、表示回転数も約2倍になることを確認しました。
今回の実験では、モータの回転数を高くすることなく、反射テープの枚数を変えることで、異なるパルス周波数での動作を確認できました。
このように、小型マイコンとセンサを組み合わせることで、比較的簡単に回転数の測定装置を製作できます。
今回製作した回転計は簡易的なものであり、測定精度や測定可能な回転数の範囲を保証するものではありませんが、回転数測定の原理を理解したり、マイコンを使った計測を試したりするための教材としても利用できると考えています。


