SPRESENSE とホール素子でモーターの回転数を計ってみる(2) [ロボット]
SPRESENSEで回転数を測るための環境は整ったので、今回は実際に測定をしてみたいと思います。
まずはスケッチから。モーターを analogWrite で駆動して、ホール素子の電圧の立ち上がりを割り込みでキャッチして回転数をカウントしています。なるべく誤差が出ないように回転数の測定は10秒間と長めに行っていました。
モーターは供給電圧が低い状態では、ギアの駆動抵抗が高くて動かせないので、5msec フル電圧で動かすという小技を使っています。
測定時のログ出力の様子です。左から、PWM出力値、測定時間(ms)、左モーター回転数、右モーター回転数です。
気になる実際の測定値はこちら。まず時計方向、反時計方向の測定値です。
左右のモーター間の回転数のばらつきは想定したよりもありませんでしたが、時計方向と反時計方向の違いが顕著です。これは恐らく電気系の問題ではなく、ギヤなどメカ的な問題かも知れません。いずれにしても制御のときは考慮する必要がありそうですね。
あと長時間測定をしていたので、バッテリーの供給電力の問題が出るかなと思ったのですが思いの外、違いはなさそうです。(バッテリーにもよるとは思いますが…)
次はセンサー処理について検討をしていきたいと思います。
( ・ิω・ิ)
まずはスケッチから。モーターを analogWrite で駆動して、ホール素子の電圧の立ち上がりを割り込みでキャッチして回転数をカウントしています。なるべく誤差が出ないように回転数の測定は10秒間と長めに行っていました。
モーターは供給電圧が低い状態では、ギアの駆動抵抗が高くて動かせないので、5msec フル電圧で動かすという小技を使っています。
#define AIN01 20 #define AIN02 21 #define AIN11 18 #define AIN12 19 #define DASH 5 #define DET_PIN_1 14 #define DET_PIN_2 15 #define MEASURE_TIME 10 static uint16_t cnt_1 = 0; static uint16_t cnt_2 = 0; static uint8_t level = 5; static boolean accel = true; static boolean finish = false; void count_1() { ++cnt_1; } void count_2() { ++cnt_2; } void setup() { // put your setup code here, to run once: Serial.begin(115200); pinMode(DET_PIN_1, INPUT_PULLDOWN); pinMode(DET_PIN_2, INPUT_PULLDOWN); #ifdef INA219 ina219.begin(); #endif attachInterrupt(digitalPinToInterrupt(DET_PIN_1), count_1, RISING); attachInterrupt(digitalPinToInterrupt(DET_PIN_2), count_2, RISING); } void motor_drive(uint8_t n, bool cw) { if (n > 255) n = 255; if (n < 0) n = 0; #ifdef DASH if (n < 200) { if (cw) analogWrite(AIN01, 255); else analogWrite(AIN02, 255); if (cw) analogWrite(AIN11, 255); else analogWrite(AIN12, 255); delay(DASH); } #endif if (cw) { analogWrite(AIN01, n); analogWrite(AIN02, 0); analogWrite(AIN11, n); analogWrite(AIN12, 0); } else { analogWrite(AIN01, 0); analogWrite(AIN02, n); analogWrite(AIN11, 0); analogWrite(AIN12, n); } } void countingRot(int n) { static unsigned long mtime; interrupts(); mtime = millis(); sleep(MEASURE_TIME); mtime = millis() - mtime; noInterrupts(); Serial.print(String(n) + ","); Serial.print(String(mtime) + ","); Serial.print(String(cnt_1) + ","); Serial.println(String(cnt_2)); cnt_1 = 0; cnt_2 = 0; } void loop() { int i = 0; unsigned long mtime; do { motor_drive(i, true); countingRot(i); i += 5; } while (i <= 250); i = 255; do { motor_drive(i, true); countingRot(i); i -= 5; } while (i >= 0); i = 0; do { motor_drive(i, false); countingRot(i); i += 5; } while (i <= 250); i = 255; do { motor_drive(i, false); countingRot(i); i -= 5; } while (i > 0); while(1); }
測定時のログ出力の様子です。左から、PWM出力値、測定時間(ms)、左モーター回転数、右モーター回転数です。
気になる実際の測定値はこちら。まず時計方向、反時計方向の測定値です。
左右のモーター間の回転数のばらつきは想定したよりもありませんでしたが、時計方向と反時計方向の違いが顕著です。これは恐らく電気系の問題ではなく、ギヤなどメカ的な問題かも知れません。いずれにしても制御のときは考慮する必要がありそうですね。
あと長時間測定をしていたので、バッテリーの供給電力の問題が出るかなと思ったのですが思いの外、違いはなさそうです。(バッテリーにもよるとは思いますが…)
次はセンサー処理について検討をしていきたいと思います。
( ・ิω・ิ)
SONY SPRESENSE メインボード CXD5602PWBMAIN1
- 出版社/メーカー: スプレッセンス(Spresense)
- メディア: Tools & Hardware
最新版 モータ技術のすべてがわかる本 (史上最強カラー図解)
- 作者: 赤津 観
- 出版社/メーカー: ナツメ社
- 発売日: 2012/09/04
- メディア: 単行本
測定における時計方向と反時計方向の違いにつきまして、計測される際のギアのバックラッシの影響はいかがでしょうか?
----------
歯車のバックラッシ|歯車技術資料|小原歯車工業(株)
https://www.khkgears.co.jp/gear_technology/intermediate_guide/KHK406_1.html
by robotic-person (2020-04-27 04:31)
う~ん、メカの知識が乏しいのでどう対策をしたものか。タミヤの工作キットを使っているので、誰かなにか解決策を考えてくれているかも…ググってみます。^^
by ys_taro (2020-04-29 02:13)