Arduinoの基礎 - ステッピングモータ
概要
ここでは、2相4ワイヤの小さなステッピングモータとを、Arduinoから制御する方法について記載する。
一般的なモータは連続回転するのを期待する時に使用するが、ステッピングモータは特定の角度だけ回って止まるような動作をしたい場合に使用する。
制御単位となるのはステップで、それぞれのステッピングモータ毎に1ステップでどのくらいの角度で回転するか決まっている。
ステッピングモータ : バイポーラ結線とユニポーラ結線
ステッピングモータには、バイポーラ結線タイプとユニポーラ結線タイプがあり、それぞれにメリットとデメリットがあるので、
特徴を理解して用途に合わせて利用する。
- バイポーラ結線
- バイポーラ結線は下図のような結線で、1つの巻線に対して双方向に電流を流す駆動方式(バイポーラ駆動)である。
- モータとしての構造は簡単で端子数も少ないが、1つの端子の極性を制御しないといけないので駆動回路は複雑になる。
- しかしながら、巻線の利用効率がよく、細やかな制御ができるので高い出力トルクが得られる。
- また、コイルに発生する逆起電力を低減できるので、耐圧が低めのモータドライバを利用できる。
- ユニポーラ結線
- ユニポーラ結線は下図のようにセンタータップを持ち、1つの巻線に対して常に一定方向に電流を流す駆動方式(ユニポーラ駆動)である。
- モータとしての構造は複雑になるが、電流のオン / オフだけの制御で済むので駆動回路が簡単になる。
- しかしながら、巻線の利用効率が悪く、バイポーラ結線に比べ約半分程度の出力トルクしか得られない。
- また、電流のオン / オフの際にコイルに高い逆起電力が発生するので、高耐圧のモータドライバが必要になる。
L293D : ステッピングモータ(バイポーラ)
ここで使用する小さなステッピングモータは、1ステップで18[度]回転するモータで、20ステップで1回転する。
また、使用するステッピングモータの種類は、バイポーラステッピングモータといい、内部にコイルが2つあり、その極性を切り替えることでモータの回転角を操作する。
ステッピングモータドライバIC(トランスレータ)として、L293Dを使用する。
L293DはデュアルHブリッジICであり、以下のように接続する。
1 in、2 in、3 in、4 inと記載した箇所は、Arduinoに接続する。
また、L293Dはインターナルのフライバックダイオードを内蔵している。
他のステッピングモータドライバICを使用する場合(SN754410等)は、フライバックダイオードを付ける必要がある。
ブレッドボードに接続した様子は次の通り。
ここで使用するステッピングモータは、下図のようなペア(1 inと2 inまたは3 inと4 in)とする。
Arduinoのサンプルコードを以下に記述する。
ArduinoのStepper
ライブラリが使用できる。
Stepper
クラスのsetSpeed
メソッドでモータの回転速度をRPMで指定する。
RPMは1分間に回転する回転数である。例えば、60[rpm]なら1分間に60回転、すなわち、1秒で1回転する。
サンプルコードでは、180[rpm]を指定している。
step
メソッドでは、現在の位置から回転するステップ数を指定する。負の値を指定すると逆回転になる。
なお、step
メソッドは同期関数で、操作が終了するまでブロックする。したがって、モータが回転している際は他の動作が止まる。(割り込み制御は可能)
#include <Stepper.h>
const int stepsPerRevolution = 20;
Stepper stepper(stepsPerRevolution, 8, 9, 10, 11);
void setup()
{
stepper.setSpeed(180);
}
void loop()
{
stepper.step(10);
delay(1000);
stepper.step(-10);
delay(1000);
}
28BYJ-48 : ステッピングモータ(ユニポーラ)
このセクションでは、ユニポーラステッピングモータである28BYJ-48を使用する。
ここでは、ステッピングモータドライバICとしてULN2003搭載ドライバボードを使用している。
このドライバボードの詳細が確認できなかったので少し曖昧な点がある。
そのため、実験的なスタンスで見ること。
ステッピングモータ28BYJ-48のデータシートは下図の通りである。
モータの出力軸は5[mm]径である。
また、配線図は下図の通りである。
ここでは、ULN2003搭載ドライバボードの電源電圧に9[V]電池を使用しているが、5[V]の方がよい可能性がある)
Arudinoのサンプルコードを以下に記述する。
ArduinoのStepper
ライブラリが使用できる。
ここでは、電動スライダとしては使用している。28BYJ-48は、内部で1/64のギア比があるため、小さいながらもトルクがあって使いやすい。
#include <Stepper.h>
const int number_of_steps = 32;
const int steps_output_rev = 32 * 64; // 2048
const int CW = 1;
const int CCW = -1;
Stepper stepper(number_of_steps, 8, 10, 9, 11);
void setup()
{
stepper.setSpeed(300);
}
void loop()
{
int steps;
steps = get_step_by_rev(CW, 1);
stepper.step(steps);
delay(3000);
steps = get_step_by_rev(CCW, 1);
stepper.step(steps);
delay(3000);
}
int get_step_by_rev(int dir, float rev)
{
return dir * (steps_output_rev * rev);
}
A4988
このセクションでは、ステッピングモータはNEMA17 17HS2408、ステッピングモータドライバはA4988を使用する。
A4988のピン配置
A4988のピン配置は、下図の通りである。
- ENABLEピン
- Lowにすると出力が有効になり、Highにすると出力が無効になる。
- MS1ピン / MS2ピン / MS3ピン
- ステップモードを設定する。(下表を参照)
- プルダウン抵抗があり、何も接続しない場合は全てLow(フルステップ)になる。
MS1ピン | MS2ピン | MS3ピン | マイクロステップ |
---|---|---|---|
L | L | L | フルステップ |
H | L | L | |
L | H | L | |
H | H | L | |
H | H | H |
- RESETピン
- Lowの時はトランスレータへの入力をリセットして、Highになるまで入力を無視する。(トランスレータへの入力とは、STEP、DIR、MS1、MS2、MS3である)
- SLEEPピン
- Lowで電力消費を最小限にするスリープモードにする。
- SLEEPピンとVDDピンの間にプルアップ抵抗があるので、接続しない状態ではHighとなる。
- STEPピン
- パルス信号を入力して、モータを回転させる。
- パルス信号の立ち上がり時に、モータの回転を1つ進める。
- 17HS2408は、2相ステッピングモータであり、基本回転角は1.8[度]である。
- フルステップ(1.8[度])で、で1回転する。
- どのくらい、どちらの向きに進めるかは、DIR、MS1、MS2、MS3の組み合わせで決まる。DIRピンのLowとHighで進む向きが変わる。
- また、STEPピンに入力するパルス信号の最小幅は、High / Lowともに1[µs]である。
- VDDピン
- ロジック電源電圧(3〜5.5[V])で、3.3[V]と5[V]ともにサポートしている。
- VMOTピン
- モータ駆動用の電源電圧である。最大35[V]である。(8〜35[V])
- ドライバ保護のため、デカップリングコンデンサをモータ供給電源に接続する。
- 容量は、100[µF]程度(最低でも、47[µF])にする。
- 17HS2408の定格電流は、0.6[A]である。
- このセクションでは、DC供給電源は、Tacklife製MDC01を使用している。
- A1ピン / A2ピン / B1ピン / B2ピン
- ステッピングモータとの接続ピンである。
- モータの仕様を確認すること。
- 17HS2408の付属のコネクタ(JST-PHコネクタ)では、下図の色のように指定されている。
A4988の出力電流制限の設定
A4988では、出力電流の制限設定はポテンショメータで設定できる。
ステッピングモータへの最大制限電流Imaxは、下式で計算できる。
ここで、Rcsは電流検出抵抗であり、旧モデル(2016年12月まで)のA4988では0.050[Ω]、新モデル(2017年1月以降)では0.068[Ω]である。
※注意
として電流の制限値を示している情報が見かけるが、それは、0.050[Ω]での計算値である。
新モデルのA4988では0.068[Ω]なので、である。
2相ステッピングモータの各コイルに流れる電流は、フルステップモードでおよそ制限電流の70[%]となる。
そのため、コイルに流れる電流を0.6[A]に制限する場合は、を最大電流になるように設定する。
したがって、以下の計算式からVrefが決まる。
Vrefは、ポテンショメータとGND間で測定できる。
また、Vrefの調整は、ポテンショメータを回して行う。
調整する時は、マルチメータのマイナス端子をGNDに接続して、プラス端子をクリップで金属製の精密ドライバを繋いでポテンショメータを回すと調整しやすい。
このセクションでは、約470[mV]になるように設定している。
サンプルコード
ArduinoとA4988を使用して、ステッピングモータを制御する。
配線図は、下図の通りである。
Arduinoとの接続において、ロジック電源の5[V]の他は、電源DIRピンのD8、STEPピンのD9だけである。
Arduinoのサンプルコードを以下に記述する。
const int DIR = 8;
const int STEP = 9;
void setup()
{
pinMode(DIR, OUTPUT);
pinMode(STEP, OUTPUT);
digitalWrite(DIR, LOW);
digitalWrite(STEP, LOW);
}
void loop()
{
digitalWrite(DIR, HIGH);
for (int i = 0; i < 200; i++)
{
digitalWrite(STEP, HIGH);
delayMicroseconds(2000);
digitalWrite(STEP, LOW);
delayMicroseconds(2000);
}
delay(1000);
digitalWrite(DIR, LOW);
for (int i = 0; i < 200; i++)
{
digitalWrite(STEP, HIGH);
delayMicroseconds(2000);
digitalWrite(STEP, LOW);
delayMicroseconds(2000);
}
delay(1000);
}
サンプルコード : ArduinoのA4988ライブラリ(StepperDriverライブラリ)の使用
上記のセクションでは、ステップのパルス信号を作るところからソースコードを記述している。
しかし、ステッピングモータの動作を抽象化して(例えば、60度回転など)、ハイレベルな指示をできる方が扱いやすい。
そのため、このセクションでは、StepperDriverライブラリを使用する。
まず、StepperDriverライブラリをインストールする必要がある。
[Sketch]メニュー - [Include Library] - [Manage Library...]を選択して、表示されたライブラリマネージャから"a4988"と検索して、
StepperDriverライブラリをインストールする。
StepperDriverライブラリをインストール後、[Sketch]メニュー - [Include Library] - [StepperDriver]を選択する。
StepperDriverライブラリを使用したサンプルコードを以下に記述する。
モータの回転は、rotate()
関数に回転角度を度数で渡すことで行う。
また、回転の速さは、setRPM()
関数で設定できる。
#include <A4988.h>
const int MOTOR_STEPS = 200;
const int DIR = 8;
const int STEP = 9;
float rpm = 10;
int microsteps = 30;
A4988 stepper(MOTOR_STEPS, DIR, STEP);
void setup()
{
stepper.begin(rpm, microsteps);
}
void loop()
{
stepper.rotate(360);
delay(1000);
stepper.rotate(-360);
delay(1000);
}
以下のサンプルコードでは、ステッピングモータがどのような設定で動作しているかを、LCDに表示している。
※備考
LCDの使用については、Arduinoの基礎 - SC1602やSC1602 I2Cアダプタを利用するを参照すること。
#include <LiquidCrystal_I2C.h>
#include <A4988.h>
const int MOTOR_STEPS = 200;
const int DIR = 8;
const int STEP = 9;
float rpm = 10;
int microsteps = 1;
A4988 stepper(MOTOR_STEPS, DIR, STEP);
LiquidCrystal_I2C lcd(0x27, 16, 2);
void setup()
{
// LCD
lcd.init();
lcd.backlight();
lcd.print("");
// ステッピングモータ
stepper.begin(rpm, microsteps);
}
void loop()
{
// RPM
rpm = rpm == 20 ? 10 : 20;
stepper.setRPM(rpm);
printStatus(90);
stepper.rotate(90);
delay(1000);
printStatus(-180);
stepper.rotate(-180);
delay(1000);
}
// 状態を LCD に表示
void printStatus(long deg)
{
lcd.clear();
String s = String("RPM ");
s += String(rpm);
lcd.setCursor(0,0);
lcd.print(s);
s = String("Degree ");
s += String(deg);
lcd.setCursor(0,1);
lcd.print(s);
}