このライブラリ開発記録のその1はこちらです。
ライブラリの改良等をしていたため少し書くのが遅くなりましたが、公開できるレベルにはなったので公開したいと思います。
Suteppaとは
Suteppaは、Arduinoでのステッピングモーターの制御を助けるためのライブラリです。注意して頂きたいのは、このライブラリ自体にステッピングモーターを回転させる機能は無いという事です。少しややこしいですが、実際にモーターを回すコードを貼ります。
「1回転→1秒→逆に1回転→1秒」を繰り返すソース
解説
void step(int d) { static const int hs[8] = {省略}; static int i; i += d; if(i > 7) i = 0; if(i < 0) i = 7; byte b = hs[i]; digitalWrite(IN1, bitRead(b, 0)); digitalWrite(IN2, bitRead(b, 1)); digitalWrite(IN3, bitRead(b, 2)); digitalWrite(IN4, bitRead(b, 3)); }
step
という関数がありますが、これは1-2相励磁でステップさせるために用意した関数です。この関数をSuteppaのinitに渡しています。Suteppaは渡されたstepを使って回転させます。このような設計にした理由は、1-2相励磁以外のいろいろな方法に対応する為です。ほかの励磁方法や、またマイクロステップをさせたい場合もあると思います。そういった場合に備えてステップを刻む関数は自分で作って渡してもらう事にしました。
引数のint d
ですが、これはステップ方向を示しています。Suteppaがstep
を呼ぶとき、dには-1
か1
が入ります。dによって回転方向が変わるような設計にしてください。
s.init(4096, step);
ここでSuteppaをinitしています。一回転のステップ数
と、上で説明したstep用関数
を渡しています。1回転のステップ数は用途によっては必要ですが、分からない場合や、DVDのモーターのような回転せずスライドするタイプの場合等は0でも良いです。これが必要になるケースは後ほど説明しますが、基本的に0で良いと考えてください。
//100ステップを加減速に使い, 開始速度は2000us s.beginSmooth(100, 2000); //通常速度は700us s.setSpeed(700);
beginSmooth
メソッドは加減速をスムーズに行うための設定用メソッドです。ここでは、加減速に最大100ステップ(合わせて200ステップ)を使い、開始速度は2000usという設定にしています。
setSpeed
で通常の速度を設定します。つまり今回の場合、100ステップかけて2000usから700usまで加速し、100ステップかけて700usから2000usまで減速します。
※usが小さい方が早く、大きい方が遅く回るので注意です。
//4096ステップ回転 s.rotate(Suteppa::RELATIVE, 4096); delay(1000); //0ステップへ戻る s.rotate(Suteppa::ABSOLUTE, 0); delay(1000);
rotate
メソッドは第1引数で回転モード
を、第2引数にはステップ
を指定ます。ステップは負にすれば逆回転します。
Suteppa::RELATIVE
は相対ステップで、Suteppa::ABSOLUTE
は絶対ステップで回転させます。よって今回の場合、現在の位置から、4096ステップ回し、その後0ステップに戻る。という事になります。
第3引数を含めた詳しいrotateの解説は下で行います。以上でデモのソースコードの解説を終わります。
rotateメソッドとtick
rotate(int mode
, long step
, bool sync
)
Suteppa::RELATIVE
相対ステップです。現在の位置から相対的にステップします。
Suteppa::ABSOLUTE
絶対ステップです。デフォルト位置からのステップへ移動します。
Suteppa::ABSOLUTE_SKIP
同じく絶対ステップですが、最短で移動します。たとえば、一回転360ステップのモーターの場合、270ステップ地点から、0ステップへ移動するためには、+90ステップするか、-270ステップするかの2通りがあります。このモードでは、+90して最短で移動します。注意すべきはここでステップは0になります。360にはなりません。
tick
rotateメソッドのsyncは省略できます。デフォルトではtrueです。ただ、このままだとモーターが1台しか制御できないという問題点があります。以下がその例です。s1
とs2
の2台のモーターを制御します。
Suteppa s1; Suteppa s2; //初期化省略 s1.rotate(Suteppa:ABSOLUTE, 100); s2.rotate(Suteppa:ABSOLUTE, 100); Serial.println("ok");
しかし、これだとs1
の回転が完了した後にs2
が回転します。同時には回転しません。rotateメソッドが処理を止めてしまうのです。
この問題を解決すべく、tickで回転を行うという方法を用意しました。
s1.rotate(Suteppa:ABSOLUTE, 100, false); s2.rotate(Suteppa:ABSOLUTE, 100, false); while(s1.tick() || s2.tick()){} Serial.println("ok");
こうするとs1
とs2
が同時に回ります。tick
はモーターを回すためのメソッドで、回転中はtrueを返し、完了すればfalseを返します。回転完了後にtickを呼び続けても平気です。それ以上回転することはありません。
ソースを見ればわかりますが、rotate
メソッドはsync
がtrueだった場合最後にwhile(tick()){}
をしています。tick
を呼ぶ周期は可能な限り短い方が良いです。最低でも50usごとには呼んでほしいです。それ以上だとスムーズな加減速が出来なくなります。
スピードとスムーズモード
最初のサンプルコードでも使っていますが、スムーズモードがこのライブラリの特徴です。加減速を調整することで脱調を防ぐことが出来ます。またステッピングモーターを確実に最高速度で回すことが出来ます。
setSpeed(通常速度us); beginSmooth(ステップ数, 開始速度us);
開始速度us
から通常速度us
までステップ数
分のステップでスムージングします。
スムーズモードの有効化と無効化
s.setSpeed(900); s.beginSmooth(100, 2000); s.rotate(Suteppa::RELATIVE, 1024); s.endSmooth(); s.rotate(Suteppa::RELATIVE, -1024);
スムーズモードはbeginSmooth
メソッドで有効化します。endSmooth
メソッドを呼ぶことでスムーズモードを解除できます。上記の場合、1024ステップをスムーズモード(2000usから900usまでを100ステップでスムーズに変化)で移動し、スムーズを無効化したのち1024ステップ戻ります。
脱調する場合
脱調は、急な加速や減速が原因なので、脱調する場合はステップ数
を増やすか、開始速度us
を下げます(数値を上げます)。ただし開始速度us
と通常速度us
の差が開きすぎるのも良くありません。その分ステップ数
を増やせばよいですが、そこらへんは調整してください。基本的にステッピングモーターが始動できる速度を開始速度us
に当てはめるのが良いでしょう。
デフォルトスムーズ
頻繁にスムーズモードを有効化したり無効化する場合、いちいち値をセットするのは面倒です。そこでsetDefaultSmooth
を用意しました。
s.setDefaultSmooth(ステップ数, 開始速度us);
//色々省略
s.beginSmooth();
s.rotate(省略);
s.endSmooth();
s.rotate(省略);
s.beginSmooth();
s.rotate(省略);
s.endSmooth();
一度defautSmooth
をセットすればbeginSmooth
するだけでスムーズモードを有効化できます。
基準点のセット
setHome
メソッドを用意しました。このメソッドを呼んだ位置が0ステップとしてセットされます。キャリブレーションを行う時に使えます。例えば以下のように。
s.rotate(Suteppa::RELATIVE, -9999, false); while(s.tick()){ if(digitalRead(SW) == 1){ break; } } s.setHome(); s.rotate(Suteppa::ABSOLUTE, 1024);
先頭につけたスイッチ(SW)を押すまでマイナスへ回り続けます。tick
ごとにdigitalRead(SW)で先頭スイッチが押されたかを確認します。押されたらwhileを抜けて回転を中止。その位置をhomeにセット。その後1024絶対ステップで回す。という流れです。キャリブレーションも簡単に実装できますね。キャリブレーションのデモは別記事で詳しく書く予定です。
おまけ
static const int RELATIVE = 0; static const int ABSOLUTE = 1; static const int ABSOLUTE_SKIP = 2;
こうなっているので、長くて面倒な場合は数字でも良いです。