目次
本記事で使用するもの
以下のリンクのスターターキットを購入した場合、上記で述べた使用するものは、PC以外すべて入手することができます。
Arduinoをまだ購入していないという方やArduinoで動かすことができるたくさんのパーツが欲しいという方は、購入を検討してみてください。
ステッピングモータについて
ステッピングモータは、電気信号を入力することで一定の角度だけ回転するモータです。
上記で紹介したスターターキットには、以下のようなステッピングモータ(28BYJ-48)が入っていたため今回はこれを使用します。
回転させる方法
ステッピングモータは、適切な順序で電圧を加えることによって、一定の角度だけ回転します。
また、電圧を加えている間は、軸が止まっていてもそれを保持するような力が働きます。
ステッピングモータ(28BYJ-48)のデータシートを見てみますと配線と電圧の加える順番が書かれていたため、今回はそれに従って電圧を加えていきます。
また、回転角度については、データシートに1ステップあたり、5.625/64=0.087890625°回転すると書かれています。
これは、電圧を加えるパターンが切り替わるたびに、0.087890625°回転することを意味しており、1回転(360°回転)させるためには、360/0.087890625=4096回パターンを切り替える必要があるということになります。
以下に私が参考にしたデータシートのリンクを貼らせていただきます。
日本語で書かれていないので、少し分かりづらいかもしれませんが、28BYJ-48について、もう少し詳しく知りたいという方は、上記のデータシートを参考にしてみてください。
回転方向
ステッピングモータの回転方向は、電圧を加える順番によって決まります。
先程の表の順番に従って電圧を加えていった場合、ステッピングモータ(28BYJ-48)の軸は反時計方向に回転します。
ここで、最初のパターンについては、基本どこから始めても問題ありません。
反対方向(時計回り)に軸を回転させたい場合は、先程の表に対して、逆向きの順番で電圧を加えていきます。
こちらも、最初のパターンについては、基本どこから始めても問題ありません。
回転速度
ステッピングモータの回転速度は、電圧のパターンを切り替える頻度によって決まります。
ステッピングモータは、電圧のパターンを切り替えると一定の角度だけ回転をして、そこで静止します。
ステッピングモータは、それらの動作を繰り返して回転するため、滑らかに回転するというよりは、一定の角度の回転と静止を繰り返して、カクカクと回転することになります。
このとき、停止している時間を短くすれば、一定の角度の回転をする頻度が多くなるので、回転速度が速くなり、停止している時間を長くすれば、一定の角度の回転をする頻度が少なくなるので、回転速度が遅くなります。
よって、電圧のパターンを切り替える頻度が多いほど、回転速度が速くなり、電圧のパターンを切り替える頻度が少ないほど、回転速度が遅くなるということになります。
回転を制御する方法
ステッピングモータの回転を制御するためには、加わっている電圧のパターンを変化させていく必要があります。
そこで、加わっている電圧のパターンを変化させるのが、Arduinoとモータドライバです。
Arduinoの出力ピンを、うまく制御すれば、モータドライバはいらないのではないかと思う方がいらっしゃるかもしれませんが、Arduinoの出力ピンで流せる電流はあまり大きいものではなく、モータを動かすには不十分な場合がほとんどです。
よって、より大きな電圧、電流を制御することができるモータドライバが必要となります。
配線の種類
実はステッピングモータは配線の仕方によって「ユニポーラ型」というものと「バイポーラ型」というものに分けられます。
今回扱うステッピングモータ(28BYJ-48)はユニポーラ型のステッピングモータであり、以下で紹介するモータドライバや制御方法はユニポーラ型のステッピングモータを制御するためのものとなっています。
バイポーラ型のステッピングモータを扱う場合は、それに適したモータドライバや制御方法が必要なので注意してください。
モータドライバ(ULN2003A)について
以下の写真は上記で紹介したスターターキットに入っていた、モータドライバ(ULN2003A)です。
正確に言うと「ULN2003A」はチップの名前であり、このモータドライバは、ユニポーラ型のステッピングモータを動かすための部品や配線をボードにまとめたものになっています。
モータドライバ(ULN2003A)のピンの役割は以下のようになっています。
ここで、各出力の状態は対応した入力(In~)が「HIGH」のとき「LOW」になり、対応した入力が「LOW」のとき「ハイインピーダンス」(めちゃくちゃ電気抵抗が高く電流が流れない状態)になります。
以下の図は、先程の表のパターン1の状態にするための入力の例です。
電源については、スターターキットに入っていた電源モジュールと9V電池を組み合わせて5Vの電源を作ります。
上記の電源モジュールと9V電池の使い方は、以下のリンクの記事で説明していますので、使い方が分からない方は、是非、先に以下の記事をご覧になってください。
ステッピングモータを回転させる
では、いよいよ以下の動画のように、ステッピングモータを回転させたいと思います。
空のスケッチを書き込む
回路を作成する前に、空のスケッチ(「ファイル」タブの「New Sketch」をクリックしたときに出てくる何の処理も書かれていないスケッチ)を書き込みます。
そうすることにより、前に書き込んだスケッチが、新しく作成しようとしている回路に影響を及ぼすことを防げます。
新しい回路を作成するときは、いつもこの作業をやっておくと、安全に回路を作成することができます。
回路を作成する
以下のような回路を作成します。
この時、9V電池の接続は、まだ行わないでください。
ここで、電源モジュールのスイッチ部分は、OFF(浮いた状態)にしておき、電池を繋いでも動かない状態にしておきます。
スケッチを書き込む
回路の作成が終わりましたら、以下のようなスケッチを書き込みます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
/* Arduinoで遊ぼう(26,ステッピングモータ); 2023/12/19 stepper_motor_test //スケッチの詳細はこちら↓ https://mecha-norimaki.com/arduino_start_26/ */ //ULN2003AのIN1に繋げたピンの番号を入れる定数 const int ULN2003A_IN1=5; //ULN2003AのIN2に繋げたピンの番号を入れる定数 const int ULN2003A_IN2=4; //ULN2003AのIN3に繋げたピンの番号を入れる定数 const int ULN2003A_IN3=3; //ULN2003AのIN4に繋げたピンの番号を入れる定数 const int ULN2003A_IN4=2; //ステップの周期(回転速度)を調整するための待機時間[ms] int step_delay=2000; void setup() { //ULN2003Aに繋げたピンを出力ピンに設定する pinMode(ULN2003A_IN1,OUTPUT); pinMode(ULN2003A_IN2,OUTPUT); pinMode(ULN2003A_IN3,OUTPUT); pinMode(ULN2003A_IN4,OUTPUT); } void loop() { //電圧信号を順番に切り替えてモータを動かす //step1 digitalWrite(ULN2003A_IN1,LOW); digitalWrite(ULN2003A_IN2,LOW); digitalWrite(ULN2003A_IN3,LOW); digitalWrite(ULN2003A_IN4,HIGH); //ステップの周期(回転速度)を調整するための待機 delayMicroseconds(step_delay); //step2 digitalWrite(ULN2003A_IN1,LOW); digitalWrite(ULN2003A_IN2,LOW); digitalWrite(ULN2003A_IN3,HIGH); digitalWrite(ULN2003A_IN4,HIGH); //ステップの周期(回転速度)を調整するための待機 delayMicroseconds(step_delay); //step3 digitalWrite(ULN2003A_IN1,LOW); digitalWrite(ULN2003A_IN2,LOW); digitalWrite(ULN2003A_IN3,HIGH); digitalWrite(ULN2003A_IN4,LOW); //ステップの周期(回転速度)を調整するための待機 delayMicroseconds(step_delay); //step4 digitalWrite(ULN2003A_IN1,LOW); digitalWrite(ULN2003A_IN2,HIGH); digitalWrite(ULN2003A_IN3,HIGH); digitalWrite(ULN2003A_IN4,LOW); //ステップの周期(回転速度)を調整するための待機 delayMicroseconds(step_delay); //step5 digitalWrite(ULN2003A_IN1,LOW); digitalWrite(ULN2003A_IN2,HIGH); digitalWrite(ULN2003A_IN3,LOW); digitalWrite(ULN2003A_IN4,LOW); //ステップの周期(回転速度)を調整するための待機 delayMicroseconds(step_delay); //step6 digitalWrite(ULN2003A_IN1,HIGH); digitalWrite(ULN2003A_IN2,HIGH); digitalWrite(ULN2003A_IN3,LOW); digitalWrite(ULN2003A_IN4,LOW); //ステップの周期(回転速度)を調整するための待機 delayMicroseconds(step_delay); //step7 digitalWrite(ULN2003A_IN1,HIGH); digitalWrite(ULN2003A_IN2,LOW); digitalWrite(ULN2003A_IN3,LOW); digitalWrite(ULN2003A_IN4,LOW); //ステップの周期(回転速度)を調整するための待機 delayMicroseconds(step_delay); //step8 digitalWrite(ULN2003A_IN1,HIGH); digitalWrite(ULN2003A_IN2,LOW); digitalWrite(ULN2003A_IN3,LOW); digitalWrite(ULN2003A_IN4,HIGH); //ステップの周期(回転速度)を調整するための待機 delayMicroseconds(step_delay); } |
スケッチの書き込みが終わりましたら、電源モジュールのスイッチがOFFになっていることをよく確認し、電池の接続を行います。
そして、もう一度回路が間違えていないかを確認してから、電源モジュールのスイッチをONにします。
回路とスケッチが正しければ先程の動画のように、モータが反時計回りに回転するのが確認できます。
もし、電源をONにして、モータが回転しない場合は、すぐに電源モジュールのスイッチをOFFにし、その後、電池を外して、回路とスケッチが間違えていないかをチェックします。
スケッチの解説
今回のスケッチは、先程の表の順番で電圧が加わるように、一定の間隔で、電圧信号を切り替え続けるといったことを行っています。
以下の表は、対応しているピンが見やすいように、先ほどの表の行を入れ替えたものです。
少しややこしいかもしれませんが、モータドライバ(ULN2003A)の特性上、入力が「HIGH」のときステッピングモータへの出力が「LOW(-)」になるので注意してください。
電圧を切り替える際には、「delayMicroseconds()」により一定の時間停止を行っています。
よって、「delayMicroseconds()」の引数である変数「step_delay」の値を調整することにより、回転速度を調整することができます。
ただし、「step_delay」の値をある段階まで小さくすると、ステッピングモータが信号に対して追従できなくなり、うまく回転ができない状態になってしまうので注意が必要です。
また、負荷が大きい場合(大きな力が加わっている場合)は、上記のような追従できなく現象が起きやすくなるため、追従できない場合は、「step_delay」の値を大きくしてゆっくりと回転させるようにする必要があります。
ちなみにステッピングモータ(28BYJ-48)のデータシートを見ると、最大自起動周波数が500[pps]であるというようなことが書いてあります。
これは動き始めや反対方向に動かすときは、1秒間に500ステップ以下、つまり間隔としては、1/500=0.002[s]=2000[μs]以上の間隔で動かすことを推奨しているということになります。
ステッピングモータの回転を制御する
次は、以下の動画のように、回転方向、回転速度、回転する角度の制御を行いたいと思います。
スケッチを書き込む
回路はそのままで以下のようなスケッチを書き込みます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
/* Arduinoで遊ぼう(26,ステッピングモータ); 2023/12/19 stepper_motor_test_2 //スケッチの詳細はこちら↓ https://mecha-norimaki.com/arduino_start_26/ */ //ULN2003AのIN1に繋げたピンの番号を入れる定数 const int ULN2003A_IN1=5; //ULN2003AのIN2に繋げたピンの番号を入れる定数 const int ULN2003A_IN2=4; //ULN2003AのIN3に繋げたピンの番号を入れる定数 const int ULN2003A_IN3=3; //ULN2003AのIN4に繋げたピンの番号を入れる定数 const int ULN2003A_IN4=2; //ステップ数をカウントする変数 int step_pattern=1; void setup() { //ULN2003Aに繋げたピンを出力ピンに設定する pinMode(ULN2003A_IN1,OUTPUT); pinMode(ULN2003A_IN2,OUTPUT); pinMode(ULN2003A_IN3,OUTPUT); pinMode(ULN2003A_IN4,OUTPUT); } void loop() { //ステップ数とステップの間隔を指定してステッピングモータを動かす(2000μs間隔で4096ステップ) move(4096,2000); //1秒間待機 delay(1000); //ステップ数とステップの間隔を指定してステッピングモータを動かす(4000μs間隔で-2048ステップ) move(-2048,4000); //1秒間待機 delay(1000); } //ステッピングモータのステップ数とステップの間隔を指定して動かす関数 void move(int step,int step_delay){ //回転方向を入れるための変数 int direction; //指定されたステップ数がマイナスのとき、ステップ数をプラスにして回転方向をマイナスとする if(step<0){ step*=-1; direction=-1; }else{ direction=1; } //指定されたステップの数だけ電圧を切り替える for(int i=1;i<=step;i++){ //出力信号のパターンを変化させる(パターンは1~8まであり、回転方向がプラスのとき1ずつ増え、マイナスのとき1ずつ減る) step_pattern+=direction; //step_patternが1から8でループするようにリセットする if(step_pattern>=9){ step_pattern=1; }else if(step_pattern<=0){ step_pattern=8; } //パターンに応じた電圧信号に切り替えてモータを動かす if(step_pattern==1){ //step1 digitalWrite(ULN2003A_IN1,LOW); digitalWrite(ULN2003A_IN2,LOW); digitalWrite(ULN2003A_IN3,LOW); digitalWrite(ULN2003A_IN4,HIGH); }else if(step_pattern==2){ //step2 digitalWrite(ULN2003A_IN1,LOW); digitalWrite(ULN2003A_IN2,LOW); digitalWrite(ULN2003A_IN3,HIGH); digitalWrite(ULN2003A_IN4,HIGH); }else if(step_pattern==3){ //step3 digitalWrite(ULN2003A_IN1,LOW); digitalWrite(ULN2003A_IN2,LOW); digitalWrite(ULN2003A_IN3,HIGH); digitalWrite(ULN2003A_IN4,LOW); }else if(step_pattern==4){ //step4 digitalWrite(ULN2003A_IN1,LOW); digitalWrite(ULN2003A_IN2,HIGH); digitalWrite(ULN2003A_IN3,HIGH); digitalWrite(ULN2003A_IN4,LOW); }else if(step_pattern==5){ //step5 digitalWrite(ULN2003A_IN1,LOW); digitalWrite(ULN2003A_IN2,HIGH); digitalWrite(ULN2003A_IN3,LOW); digitalWrite(ULN2003A_IN4,LOW); }else if(step_pattern==6){ //step6 digitalWrite(ULN2003A_IN1,HIGH); digitalWrite(ULN2003A_IN2,HIGH); digitalWrite(ULN2003A_IN3,LOW); digitalWrite(ULN2003A_IN4,LOW); }else if(step_pattern==7){ //step7 digitalWrite(ULN2003A_IN1,HIGH); digitalWrite(ULN2003A_IN2,LOW); digitalWrite(ULN2003A_IN3,LOW); digitalWrite(ULN2003A_IN4,LOW); }else if(step_pattern==8){ //step8 digitalWrite(ULN2003A_IN1,HIGH); digitalWrite(ULN2003A_IN2,LOW); digitalWrite(ULN2003A_IN3,LOW); digitalWrite(ULN2003A_IN4,HIGH); } //ステップの周期(回転速度)を調整するための待機 delayMicroseconds(step_delay); } } |
スケッチが正しければ、電源を入れた際、先程の動画のように、回転方向や回転速度を切り替えながらモータが回転するのが、確認できると思います。
スケッチの解説
今回のスケッチでは、ステッピングモータを動かす一連の処理を関数としてまとめ、「void loop()」内で呼び出してステッピングモータを動かしています。
作成した関数「move()」は、回転させたいステップ数とステップの間隔を引数として指定し、ステッピングモータを動かします。
基本的な動かし方は先ほどと同じで、表に従うように、順番に電圧信号を切り替えることによって動かしています。
ただし、回転方向を変えるために、信号の順番を逆向きにしたり、指定したステップ数の分だけ回転させたりしています。
回転方向の分岐
作成した関数「move()」内の52行目~61行目では、ステップ数(1番目の引数)がマイナスの場合、表の順番とは逆向きに電圧信号を切り替えるように分岐を行っています。
52 53 54 55 56 57 58 59 60 61 |
//回転方向を入れるための変数 int direction; //指定されたステップ数がマイナスのとき、ステップ数をプラスにして回転方向をマイナスとする if(step<0){ step*=-1; direction=-1; }else{ direction=1; } |
上記の文は、回転方向を決めるための変数「direction」を用意し、ステップ数がマイナスの場合、「-1」を、それ以外のとき「1」を入れています。
また、ステップ数がマイナスの場合は、追加でステップ数をプラスの値にする処理を行っています。
指定したステップ数だけ回転させる仕組み
作成した関数「move()」内の63行目~129行目では、for文を利用しステップ数の分だけ電圧信号の切り替えを行っています。
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
//指定されたステップの数だけ電圧を切り替える for(int i=1;i<=step;i++){ //出力信号のパターンを変化させる(パターンは1~8まであり、回転方向がプラスのとき1ずつ増え、マイナスのとき1ずつ減る) step_pattern+=direction; //step_patternが1から8でループするようにリセットする if(step_pattern>=9){ step_pattern=1; }else if(step_pattern<=0){ step_pattern=8; } //パターンに応じた電圧信号に切り替えてモータを動かす if(step_pattern==1){ //step1 digitalWrite(ULN2003A_IN1,LOW); digitalWrite(ULN2003A_IN2,LOW); digitalWrite(ULN2003A_IN3,LOW); digitalWrite(ULN2003A_IN4,HIGH); }else if(step_pattern==2){ //step2 digitalWrite(ULN2003A_IN1,LOW); digitalWrite(ULN2003A_IN2,LOW); digitalWrite(ULN2003A_IN3,HIGH); digitalWrite(ULN2003A_IN4,HIGH); }else if(step_pattern==3){ //step3 digitalWrite(ULN2003A_IN1,LOW); digitalWrite(ULN2003A_IN2,LOW); digitalWrite(ULN2003A_IN3,HIGH); digitalWrite(ULN2003A_IN4,LOW); }else if(step_pattern==4){ //step4 digitalWrite(ULN2003A_IN1,LOW); digitalWrite(ULN2003A_IN2,HIGH); digitalWrite(ULN2003A_IN3,HIGH); digitalWrite(ULN2003A_IN4,LOW); }else if(step_pattern==5){ //step5 digitalWrite(ULN2003A_IN1,LOW); digitalWrite(ULN2003A_IN2,HIGH); digitalWrite(ULN2003A_IN3,LOW); digitalWrite(ULN2003A_IN4,LOW); }else if(step_pattern==6){ //step6 digitalWrite(ULN2003A_IN1,HIGH); digitalWrite(ULN2003A_IN2,HIGH); digitalWrite(ULN2003A_IN3,LOW); digitalWrite(ULN2003A_IN4,LOW); }else if(step_pattern==7){ //step7 digitalWrite(ULN2003A_IN1,HIGH); digitalWrite(ULN2003A_IN2,LOW); digitalWrite(ULN2003A_IN3,LOW); digitalWrite(ULN2003A_IN4,LOW); }else if(step_pattern==8){ //step8 digitalWrite(ULN2003A_IN1,HIGH); digitalWrite(ULN2003A_IN2,LOW); digitalWrite(ULN2003A_IN3,LOW); digitalWrite(ULN2003A_IN4,HIGH); } //ステップの周期(回転速度)を調整するための待機 delayMicroseconds(step_delay); } |
for文の中には、先ほどのスケッチでも利用した電圧信号のパターン8つを用意しており、for文によるループが起こるたびにパターンの切り替えを行っています。
ここで、パターンを管理する変数「step_pattern」は、先程分岐させて値を入れた「direction」により、回転方向がプラスのときは1ずつ増やし、マイナスのときは1ずつ減らすような処理をfor文の先頭で行っています。
また、1から8のパターンでループするように、「step_pattern」の値が「9」になったら値を「1」にし、「step_pattern」の値が「0」になったら値を「8」に変更する処理を行っています。
ステップの間隔は、先程のスケッチと同様に、「delayMicroseconds()」によって調節されており、2番目の引数である「step_delay」の値によって変更が可能となっています。
void loop()の処理
「void loop()」内では、上記で説明した関数「move()」を呼び出して、2パターンの動きを繰り返しています。
34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
void loop() { //ステップ数とステップの間隔を指定してステッピングモータを動かす(2000μs間隔で4096ステップ) move(4096,2000); //1秒間待機 delay(1000); //ステップ数とステップの間隔を指定してステッピングモータを動かす(4000μs間隔で-2048ステップ) move(-2048,4000); //1秒間待機 delay(1000); } |
37行目では、「move(4096,2000)」と呼び出しているため、2000[μs]間隔で4096ステップ動くことになります。
つまり、2000/1000000×4096=8.192[s]かけて、5.625/64×4096=360[°]反時計回りに回転することになります。
続いて、43行目では「move(-2048,4000)」と呼び出しているため、4000[μs]間隔で-2048ステップ動くことになります。
つまり、4000/1000000×2048=8.192[s]かけて、5.625/64×2048=180[°]時計回りに回転することになります。
終わりに
皆さん上手くステッピングモータを制御することが出来たでしょうか。
ステッピングモータは、ある角度まである速度で回転させたいといったときに、便利なモータです。
ロボットなどで角度や速度を制御したいというときは、是非、使用することを検討してみてください。
今回までの記事では、「Arduinoで遊ぼう(~,~);」という題で、最初に紹介したスターターキットに入っていた部品を使いながら、Arduinoの使い方について学んできました。
次回からの記事では、スターターキット以外の部品も使い、より実践的なものづくりを行いたいと思います。
本記事はここまでです。ご清覧ありがとうございました。
広告
楽天モーションウィジェットとGoogleアドセンス広告です。
気になる商品がございましたら、チェックをしてみてください。