モータを動かす その3 直線の動き
モータは回転しますが、動かしたいものは直線の運動が多いです。そのためにボールねじ機構を導入します。ステッピング・モータとボールねじはカプリングでつなぎます。少しの傾きなどをバックラッシュなしで吸収してくれます。
●両端でモータを止めなければならない
モータを回し続けると、移動台は端にぶつかります。そこで、マイクロスイッチを取り付け、割り込みで止めるようにします。X-NUCLEO-IHM01A1 ボードは、ArduinoUNOで使える二つのうち一つをエラー処理MyFlagInterruptHandler()で使っています。3番ピンは使われていないので、マイクロスイッチ二つをつなぎこみました。プルアップの指定をしないとランダムに割り込みが入るので、次の2行で割り込みが発生したときの処理関数endStopを指定します。
pinMode(3, INPUT_PULLUP);
attachInterrupt(1, endStop, FALLING);
割り込みが起こったとき、モータを止めます。SoftStop()は単独ではモータを止められますが、割り込み記述関数内では止まらなかったのでHardStop()を使いました。
マイクロスイッチはチャタリングは少ないほうだと思っていたのですが、バタバタします。実害はないので対策をしていません。写真のように、マイクロスイッチは接触部分より下側についているので、引っ掛かりやすいです。取り付け上の注意点はこちらを参照ください。
モータの回転角度などから移動距離などを求めるのは、こちらを参照ください。ライブラリはマイクロステップが有効になっています。
●スケッチ
行ったり来たりするスケッチです。移動台がリミット・スイッチに触れると一度止まり、そのルーチンを抜け、逆向きに動き始めます。GetPosition(0)は正確に位置情報を返してきます。往復している間に誤差が蓄積することもなく、位置決めには適しているモータだと感じます。引数の0はボードのIDを現していて、1枚だけだと0です。
#include <l6474.h>#include <SPI.h>
L6474 myL6474;
int Position =32000;
void setup()
{
Serial.begin (9600);
int32_t pos;
uint16_t mySpeed;
myL6474.Begin(1);
myL6474.AttachFlagInterrupt(MyFlagInterruptHandler);
pinMode(3, INPUT_PULLUP);
attachInterrupt(1, endStop, FALLING);
}
void loop()
{
Serial.println(" speed = "+String(myL6474.GetCurrentSpeed(0)) );
myL6474.Move(0, FORWARD, Position);
Serial.println("FORWARD "+String(Position));
myL6474.WaitWhileActive(0);
Serial.println(" Position1 = "+String( myL6474.GetPosition(0)) );
delay(2000);
Serial.println("go BACKWARD ");
myL6474.Move(0, BACKWARD, Position);
myL6474.WaitWhileActive(0);
Serial.println(" Position2 = "+String( myL6474.GetPosition(0) ));
delay(2000);
}
void MyFlagInterruptHandler(void)
{
Serial.println("Error ");
}
void endStop(void)
{
myL6474.HardStop(0);
myL6474.WaitWhileActive(0);
Serial.println("END Stop "+String(myL6474.GetPosition(0)) );
}
実行中です。