前々回(「#3-4 サーボモータ」)、サーボモータを回してみたつながりで、今回はステッピングモータを回してみます。
モータに貼り付けられたシールの型番は、28BYJ-48。
これを頼りにデータシートを検索してみます。
相変わらず、電流スペックとかは何にもわからず……。
Iduinoスタータキットの中には、「モータドライバ」と呼ばれる種類のものが2つ、入っていました。1つは、裸の16ピンIC、L293Dと、もう一つはULN2003ANとマークされたICが乗った、以下の様なモジュールです。
実は見るからに、28BYJ-48とセットで使用するのは、上図のドライバモジュールだと思われます。と、言うのは、コネクタの形状。ドライバモジュール側にはメス、ステッピングモータ側にはオスの、明らかに合致する形状のコネクタが付いています。
では、L293Dは、何に使うのでしょうか?各々データシートを検索して確認してみます。
L293Dのデータシートを検索する
ULN2003ANのデータシートを検索する
内部の回路図を見ると、明らかに構成が異なります。つまり、用途が全く異なるはず。でも、使い分けがわかりません。
その答えがArduino HPにありました。Arduino HP ⇒ REFERENCE ⇒ LIBRARIES ⇒ Stepperと進むと、回路例(Circuits)にアクセスできます。そこには、ユニポーラステッピングモータと、バイポーラステッピングモータの回路例が記されており、ユニポーラの例にULN2003、バイポーラの例にL293Dが使われています。
どうやら、一口にステッピングモータと言っても、種類があって、種類毎に制御方法が異なるようです。28BYJ-48はユニポーラ型ですので、ULN2003を使ったドライバモジュールで制御するのは正解みたいです。
他にもいろいろと調べてみると、L293Dは、ブラシDCモータを回すときにも使えるのだとか。もう一つのブラシDCモータ用に入っているのか??まあ、そちらはまた別のテーマですね。
脱線しました、ULN2003に戻りましょう。実は、ULN2003 ICのデータシートを見ても、チンプンカンプンで、何をどうして良いものか、さっぱりわかりませぬ(1^^;)。困っていると、ELEGOOスタータキット付属CD-ROMの中に、ULN2003Aを搭載した、恐らく今回のモジュールと同タイプと思われるモジュールのデータシートが見つかりました。
モータドライバモジュールのデータシートなので、ステッピングモータとの接続方法から、モジュールの制御方法に至るまで、説明があります。これで何とかなりそうです。
Arduino HP ⇒ REFERENCE ⇒ LIBRARIES ⇒ Stepperを参照して、Stepperクラスを使ってみます。前々回(「#3-4 サーボモータ」)のサーボモータと同様、インスタンスを生成します。その際、Stepper()コンストラクタを使って、モータを1回転させるのに必要なステップ数と、制御に使用する端子番号を渡す必要があります。
#include <Stepper.h>
const int stpr_STEP=64; // =360/5.625 (?実験して確認後、再設定)
const int pin_STP1=2; // stepper motor
const int pin_STP2=3;
const int pin_STP3=4;
const int pin_STP4=5;
Stepper stpr_unip=Stepper (stpr_STEP, pin_STP1,pin_STP2,pin_STP3,pin_STP4);
stpr_STEPは、モータを1回転させるのに必要なステップ数です。たぶん、setSpeed()メソッドで回転速度を指定するのに使用するパラメータだと思われます。ステッピングモータ(28BYJ-48)のデータシートにあった、「ステップ角度:5.625°/64」より、一回転360°/5.625°=64として見ました。が、「5.625°/64」の、「/64」って?ギア比が1:64とも記載されているので、もしかしたら、stpr_STEP(=64)で1回転するのはモータ本体の方で、更にギア比1:64が効いてきて、×64回繰り返さないと、外部の軸が1回転しないのかもしれないですね(その場合は、stpr_STEP=4,096)。そこいら辺は、回してみてから再調整します。
ユニポーラステッピングモータの励磁方式には、1相励磁、2相励磁、1-2相励磁などの種類があるのだそうです。ドライバモジュールのデータシートには1-2相励磁方式による制御が記載されています。たぶん、Stepperクラスも、そうなのでしょうね(?)。モータを繋ぐ前に、制御波形を確認しておきましょう。まずは、完成版プログラムをリンクしておきます。
完成版プログラム:test_stepper.ino
シリアルモニタから、以下のコマンドを受け付けるようになっています。
【stp,16】コマンドを実行したときのモータ制御波形がこちら(↓)。
おっと、イメージしていたのと違いますね……。これは……、順番がバラバラだけど、2相励磁方式?なるほど、Arduino HPのユニポーラステッピングモータ回路例(Two Pins)にある通りの、2端子制御回路用クラスだということですね?
回路例は何だか複雑な接続に見えますが、単に、ULN2003AN内のインバータを使って入力信号を反転し、逆相の信号波形を作って、モータに入力しているだけのことです。上の波形も、D3はD2の反転、D5はD4の反転になっているので、以下表のような接続にすると、同等の回路構成になるはずです。
Arduino | 接続 | ドライバモジュール | 接続 | ステッピングモータ |
D2 | → | IN1 | ||
D4 | → | IN2 | ||
D3 | → | IN3 | ||
D5 | → | IN4 | ||
コネクタ(メス) | → | コネクタ(オス) | ||
5V | × | (なし) | ||
電源モジュールから給電 | → | +電源 | ||
GND | ⇔ | −電源 |
オレンジ部分が変則的な接続になっているので、強調してあります(D3とD4がてんこしゃんこになっているので注意)。
※接続端子の方を昇順で接続して、Stepper()コンストラクタの引数で、端子の割り当て順番を変える方法もあります。
ステッピングモータの電流スペックが未知なので、さすがに今回は電源モジュール(+ACアダプタ)から別途給電します。
いよいよ、ステッピングモータを接続して回転させてみましょう。
実験サンプル:【 】内はシリアルモニタからの送信データ
【stp,256】 …… 時計回り
OK+ step 256
OK: step 256 end
【stp,-256】 …… 反時計回り
OK+ step -256
OK: step -256 end
【stp,2048】 …… 時計回りに一周
OK+ step 2048
OK: step 2048 end
回りました。1:64のギアが入っているようですので、回転スピードは遅いです。また、step()メソッドを実行すると、全てのステップを実行し終わるまで、つまり、モータの回転が止まるまで、制御が戻ってきません。これでは、モータを回している間に別な処理を進めておく、と言うような使い方は無理ですね。
さて、「一体、何ステップで一周するのか?」という疑問ですが、答えは2,048ステップでした。アレレ、計算が合いません。
何じゃろな〜。と、考えていたら、ふと思いつきました。2相励磁と1-2相励磁の違いかと。
2相励磁/ステップ→ | 0 | 1 | 2 | 3 | ||||
IN1 | 1 | 1 | ||||||
IN2 | 1 | 1 | ||||||
IN3 | 1 | 1 | ||||||
IN4 | 1 | 1 | ||||||
1-2相励磁/ステップ→ | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
IN1 | 1 | 1 | 1 | |||||
IN2 | 1 | 1 | 1 | |||||
IN3 | 1 | 1 | 1 | |||||
IN4 | 1 | 1 | 1 |
1-2相励磁の方が2倍、ステップが間延びしています。2相励磁の時に上表の4ステップで回転する角度と、1-2相励磁の時に上表の8ステップで回転する角度は、等しいはずです。つまり、1-2相励磁を基準に、一周が4,096ステップだと考えると、2相励磁にした場合には半分の2,048ステップで一周できることとなり、計算が合います。
実験サンプル:【 】内はシリアルモニタからの送信データ
【stp,8192】 …… 時計回りに4周
OK+ step 8192
OK: step 8192 end
【stp,-8192】 …… 反時計回りに4周
OK+ step -8192
OK: step -8192 end
4回転させても、ちゃんと同じ位置で停止しているようです。まあ、ほぼ無負荷状態ですので、こうでなくては困りますが……。
実験サンプル:【 】内はシリアルモニタからの送信データ
【spd,5】 …… 回転速度を5s/1周に設定
OK: set speed 12[rpm]
【stp,2048】 …… 時計回りに1周
OK+ step 2048
OK: step 2048 end
【spd,1】 …… 回転速度を1s/1周に設定
OK: set speed 60[rpm]
【stp,2048】 …… × 回転しない(設定速度が速すぎる)
OK+ step 2048
OK: step 2048 end
【spd,30】 …… 回転速度を30s/1周に設定
OK: set speed 2[rpm]
【stp,2048】 …… ゆっくり一周
OK+ step 2048
OK: step 2048 end
ギア比1:64も関係していますが、このステッピングモータはあんまり速く回りません。実力を超えるスピードで信号を入力すると、全く回転しなくなってしまうようです。
※少し負荷を増やすと、【spd,5】でも回らなくなるようです。もっとゆっくり回すのに使うモータみたいですね。
時に、ステッピングモータ(28BJY-48)のデータシートに記載されていた、「周波数100Hz」とは、何のスペックでしょうか?
さて、実験中、モータ本体や電源モジュールのレギュレータ付近に指をあててみると、結構温かく(熱く)なっています。発熱⇔消費電力の関係がありますので、そこそこ電流が流れて、電力を消費しているのでしょう。
step()メソッド実行直後の写真が下図です。
LEDが、現在通電している端子を示しています。step()メソッドの実行終了後、の写真ですので、モータは停止しています。にもかかわらず、通電されています。このまま放置すると、ずっと電流が流れ続けるので、モータは温かいままです(停止しているのに)。
step()メソッドの実行終了後に、以下を実行すると、全てのLEDが消え、電流がカットされます。この状態なら、暫くすると、モータ本体の温度が下がります。
digitalWrite (pin_STP1, LOW);
digitalWrite (pin_STP2, LOW);
digitalWrite (pin_STP3, LOW);
digitalWrite (pin_STP4, LOW);
停止したままの状態を保持するために通電してトルクを保つのであれば、こうはいきませんが、そうでないならば、上の処理を実行して通電をカットした方が、消費電力を抑えることにつながります。特に、28BYJ-48はギア比1:64のお陰で、停止したモータの軸を手で回すのは、ほぼ不可能なので(トルクを保持する必要が無い)、通電をカットしてしまって良いのではないでしょうか?
以下、【demo】コマンドの実行動画です。
簡単に回せる利点はありますが、ちょっと、Stepperクラスは使い難いですね。モータを回している間、他の処理ができないですし、励磁方式も選べないようです。本格的にステッピングモータを使うなら、自分でプログラムを起こさないと、使い物にならないでしょう。
Stepperクラスの励磁方式は2相励磁でした。他の励磁方式の特徴も調べてみました。
必ずしも、1-2相励磁方式が「一番良い」って事ではないみたいですし、「この方式でなければ回らない」という類の事でもないようです。回転が滑らかなことは、細かい位置決めができるという発想と、もう一つは、振動が少なくなるという利点にもつながっているようなので、コストや特徴を考え合わせて、最適な励磁方式が選べると良いですね。