概要
エンコーダー内蔵BLDCモーターにArduino繋いで回転数を測定してみます。言語ライブラリなど探すといくつか万能なものが見つかります。チャタリング対策してたり、回転位置を正確に算出できたりと便利な物。ただ今回はモーター回転数と方向が知りたいだけなので簡単なプログラムを作って回転数を計測してみました。
モーター内蔵のエンコーダー
商品ページに分解した写真がありました。ロータリーエンコーダーには機械式とか光学式とかあるようですが光学式のフォトインタラプタっぽい感じのエンコーダー。信号線がA相、B相と2線あるため4逓倍?の分解能でカウントできそうです。今回は回転方向と回転数(速度)だけ計測できればいいのでなるべく簡素にカウントしてみます。
カウント方法
A相、B相のそれぞれの入力波形。A相立ち上がりの際、時計回りであればB相は必ずLOW。反時計廻りであれば必ずHIGHの関係となります。なので単純に回転方向と回転速度を確認したいだけであれば、割り込みなどでA相の立ち上がりエッジの回数(間隔)とその時のB相の入力を確認するだけ。
スケッチ
プログラムの抜粋。
void setup() { attachInterrupt(0, CALL_ENC, RISING); } void loop() { currentTime = micros(); if (currentTime - encTime >= 1000000) { //1000ms encTime = micros(); Serial.printf("ENC COUNT %d\n", 60 * enc_count / 100); enc_count = 0; } } void CALL_ENC() { digitalRead(3) == LOW ? enc_count++ : enc_count--; }
A相接続ピンの立ち上がりエッジで外部割り込み。割り込み処理では、B相ピン状態を確認して時計回り(LOW)ならプラス、反時計回り(HIGH)ならマイナスのカウントを行ってます。
メインループでは1秒毎に回転速度(RPM)にしてシリアル出力してます。1秒間は同じ方向に回り続ける前提。途中で回転方向が変わってしまうとおかしなことになります。
▼4逓倍▼(抜粋)
attachInterrupt(0, CALL_ENC_A, CHANGE); attachInterrupt(1, CALL_ENC_B, CHANGE); void CALL_ENC_A() { if (digitalRead(2) == 1) digitalRead(3) == 0 ? enc_count++ : enc_count--; if (digitalRead(2) == 0) digitalRead(3) == 1 ? enc_count++ : enc_count--; } void CALL_ENC_B() { if (digitalRead(3) == 1) digitalRead(2) == 1 ? enc_count++ : enc_count--; if (digitalRead(3) == 0) digitalRead(2) == 0 ? enc_count++ : enc_count--; }
4逓倍(分解能4倍)のパターンも試してみました。A相、B相でそれぞれピン変化割り込みを行って、各々の状態を確認してカウントしてます。
確認
一応ライブラリを使用した場合と測定結果に違いがでないかを比較してみました。
適当に速度(デューティ比)を変えて回転速度を取得。値を比較してみます。
計測結果
計測結果はライブラリとほぼ変わりなし。
ということでライブラリは使わずにいこうと思います。
コメント