Arduinoでステッピングモーターをマスターする:包括的ガイド
本チュートリアルでは、Arduinoでステッピングモーターを制御するために必要なすべてを学びます。NEMA17ステッピングモーターを、A4988、DRV8825、TMC2208の各ステッピングドライバーと組み合わせて制御する方法を解説します。
このモーターとドライバーの組み合わせは、位置制御が必要な無数のアプリケーション──3Dプリンター、CNCマシン、ロボティクス、自動化機械など──で使用されています。
筆者自身、以下のArduinoプロジェクトで活用してきました:
- DIYカメラスライダー
- 3Dワイヤーベンディングマシン
- DIYフォームカッティングマシン
- DIYレーザー彫刻機
- 自動ペンチェンジャー付きペンプロッター
- SCARAロボットアーム
動作原理、Arduinoとの配線、ドライバーの電流制限設定、ライブラリあり・なしでのプログラミングを詳細に解説します。また、Arduino CNCシールドを用いて、あらゆるタイプのArduinoプロジェクトで複数のステッピングモーターを簡単に制御する方法も紹介します。
内容が充実していますので、以下の動画をご覧いただくか、配線図とサンプルコードを含む本文をお読みください。
ステッピングモーターとは? その仕組み
まず、ステッピングモーターの基本と仕組みを簡単に説明します。これにより、以降の内容の理解が深まります。
ステッピングモーターは、フィードバックなしで位置を精密に制御できる、ブラシレスDCモーターの一種です。
動作原理は磁場に基づきます。主にステーター(固定子)とロータ(回転子)の2コンポーネントで構成されます。ロータは通常永久磁石で、ステーターの複数のコイルに囲まれています。
コイルに通電すると、ステーターに特定の磁場が生成され、ロータを引き寄せたり反発させたりします。コイルを特定の順序でステップごとに順次励磁することで、ロータの連続回転を実現でき、任意の位置で停止させることも可能です。
これが「ステッピング」モーターと呼ばれる理由です──離散的なステップで動くからです。
ロータの磁極数を増やせば、停止可能位置の数、すなわち分解能・精度を高められます。詳細は拙稿「ステッピングモーターの仕組み」をご参照ください。
典型的なNEMA17ステッピングモーターは、ロータに50の停止点(ステップ)を持ちます。一方、ステーターは複数のコイルを2相に配置し、4種類の磁場方向を生成できます。
したがって、ロータの50ステップ × 4磁場方向 = 1回転あたり200ステップ。360°÷200ステップ = 1ステップあたり1.8°の分解能となります。
ステーターコイルが2相に配置されていることは、モーターのリード線数(4本)からもわかります。2相分の2本ずつです。電流を両方向に流せるため、4種類の磁場方向が可能です。
5本、6本、8本リードのステッピングモーターもありますが、依然として2相で動作し、4つの制御端子で制御します。配線方法により、トルク重視や速度重視など、異なる特性を引き出せます。
以上の説明から、ステッピングモーターを駆動するには単純に電源を繋ぐだけではダメで、2相を両方向に励磁し、特定の順序でタイミングよくパルスを送る必要があることがわかります。そのためにドライバーが必要なのです。
ステッピングモーターの種類・サイズに応じて多くのドライバーがありますが、基本原理は共通で、2つのHブリッジによりモーター相を両方向に励磁します。マイクロステッピング、電流制限など、制御を容易にする多くの機能を備えています。
ArduinoとA4988ステッピングドライバーでNEMA17を制御する
まず、A4988ステッピングドライバーでNEMA17ステッピングモーターを制御する最初の例を見てみましょう。
NEMA17は、性能と価格のバランスに優れ、メイカーの間で最も人気のあるステッピングモーターです。ほぼすべてのデスクトップ3Dプリンターとレーザー彫刻機に搭載されています。
一般的なNEMA17は200ステップ(1.8°/ステップ)ですが、400ステップ(0.9°/ステップ)モデルも存在します。なお、「NEMA17」という呼称は、モーター前面プレートのサイズを示すだけです(17÷10=1.7インチ。NEMA23なら2.3インチ)。プレートサイズは固定ですが、長さは20〜60mmまで様々で、それに伴い許容電流(0.3A〜2.5A)も変わります。
モーターの定格電流に合わせて、適切なドライバーを選定する必要があります。NEMA17用として最もポピュラーなのがA4988ステッピングドライバーです。
A4988の最大定格電流はコイルあたり2Aですが、これはピーク値です。推奨は1A前後ですが、十分な冷却があれば2Aまで可能です。
A4988を含むすべてのドライバーに搭載されている優れた機能が「電流制限」です。これにより、モーター定格にかかわらず、ドライバーが供給する電流を設定できます。例えば、2.5A定格モーターを接続しても、ドライバー側で1.5Aに制限すれば使用可能です(最大性能は出ませんが)。逆に、モーター定格より高い電流制限を設定すればモーターが過熱します。モーター定格とドライバー制限を合わせるのがベストです。
A4988とArduinoの配線
A4988ドライバー、ステッピングモーター、Arduinoの接続方法です。
本チュートリアルで使用する部品の入手先:
- ステッピングモーター NEMA 17 …… Amazon / Banggood / AliExpress
- A4988ステッピングドライバー ……… Amazon / Banggood / AliExpress
- DRV8825ステッピングドライバー … Amazon / Banggood / AliExpress
- TMC2208ステッピングドライバー … Amazon / Banggood / AliExpress
- Arduino CNCシールド ……………… Amazon / Banggood / AliExpress
- Arduino Uno …………………………… Amazon / Banggood / AliExpress
注:これらはアフィリエイトリンクです。Amazonアソシエイトとして、適格販売から収益を得ています。
ドライバー右上のVMOTとGNDピンに、モーター用電源(8〜36V)を接続します。ここには、電圧スパイクからボードを保護するため、47μF以上の大容量電解コンデンサをVMOT-GND間に接続することを推奨します。
次に、4本のモーター接続ピン:1相を1A・1B、もう1相を2A・2Bに接続します。
どの2線が1相をなすか判別しにくい場合がありますが、いくつか方法があります。最も簡単なのは、モーター軸を手で回し、2線をショートさせること。同じ相の2線なら、回転が重くなります。テスターで導通を確認する方法もあります(同じ相なら短絡でビープ音)。相が特定できたら、ドライバーのどちらの位置に繋いでも構いません。
次に、ロジック電源ピン:VDDとGND(3〜5V)。反対側にStepピンとDirectionピンがあり、Arduinoの任意のピンに接続します。Directionピンで回転方向を、Stepピンでステップを制御します。Stepピンにパルスを送るたびに、設定方向へ1ステップ進みます。
その上にSleepピンとResetピンがあり、名前通りスリープモードとリセットに使用。両方ともアクティブローです。SleepピンはデフォルトHIGH、RSTピンはフローティング状態。これらの機能を使わないなら、両ピンをショートさせるのがドライバーを有効化する最も簡単な方法です。
Enableピンもアクティブローなので、HIGHにしない限りドライバーは有効です。
次のMS1、MS2、MS3ピンは、モーターのステップ分解能(マイクロステッピング)選択用です。NEMA17は通常200ステップ/回転ですが、全ドライバーにマイクロステッピング機能があり、コイルに中間電流を流すことで中間ステップ位置を生成し、分解能を向上させます。
例:1/4ステップ選択時、200ステップ × 4 = 800マイクロステップ/回転。ドライバーは4段階の電流レベルでコイルを駆動します。
A4988の最大分解能は1/16マイクロステップで、200ステップモーターなら3200ステップ/回転(0.1125°/ステップ)まで可能。これが多くのアプリケーションで採用される理由です。さらに256マイクロステップ(51200ステップ/回転、0.007°/ステップ)対応ドライバーも存在します。
これら3ピンにはプルダウン抵抗があるため、未接続ならフルステップモードで動作します。別のマイクロステッピングを選択するには、以下の表に従って5Vを適切なピンに接続します。
A4988の電流制限設定
配線がわかったところで、Arduinoプログラミングに進みたいところですが、モーターに通電する前に必ず行わなければならない重要な作業があります:ドライバーの電流制限調整です。モーター定格より高い電流制限ではモーターが過熱します。
A4988ドライバーには小型トリマーポテンショメータがあり、これを回して電流制限を調整します。時計回りで電流制限アップ、反時計回りでダウン。
実際の電流制限値を決定する2つの方法があります。
方法1:基準電圧(Vref)測定法
ポテンショメータ両端とGND間の基準電圧をテスターで測定し、以下の式で電流制限を計算します:
Current Limit = Vref / (8 × Rcs)
Rcsはチップ横の電流検知抵抗値。メーカーにより0.05、0.1、0.2Ωが一般的。実測値を確認してください。筆者のボードでは「R100」表記で0.1Ωでした。
例:Vref=0.7V、Rcs=0.1Ω → Current Limit = 0.875A。1Aに制限したいならVrefを0.8Vに調整。
方法2:コイル電流直接測定法
モーターとドライバーを接続し、コントローラー接続の代わりにDirectionとStepピンに5Vを入力してモーターを保持状態に。MSピンは未接続(フルステップ)。モーターの1相を切り離し、アンペアメータを直列に挿入。ロジック電圧(5V)とモーター電源(筆者環境では12V)を投入し、コイル電流を読み取ります。
※フルステップモードではコイル電流は設定電流制限の70%しか流れません。マイクロステッピングモードで使用する場合、アンペアメータ読み取り値に1.3を乗じて実電流制限値を求めます。
筆者は両方法を試しましたが、ほぼ同じ結果が得られました。
ステッピングモーターとArduino──サンプルコード集
それでは、Arduinoプログラミング、すなわちライブラリなし・ありでのステッピングモーター制御サンプルコードを見ていきます。
サンプルコード1:ライブラリなしで基本制御
/* Basic example code for controlling a stepper without library
* by Dejan, https://howtomechatronics.com */
#define stepPin 2
#define dirPin 5
void setup() {
pinMode(stepPin, OUTPUT);
pinMode(dirPin, OUTPUT);
}
void loop() {
digitalWrite(dirPin, HIGH); // 方向設定
for(int x = 0; x < 800; x++) { // 1回転(1/4マイクロステップ前提で800パルス)
digitalWrite(stepPin, HIGH);
delayMicroseconds(700);
digitalWrite(stepPin, LOW);
delayMicroseconds(700);
}
delay(1000);
digitalWrite(dirPin, LOW); // 方向反転
for(int x = 0; x < 1600; x++) { // 2回転
digitalWrite(stepPin, HIGH);
delayMicroseconds(500);
digitalWrite(stepPin, LOW);
delayMicroseconds(500);
}
delay(1000);
}
コード解説:
STEP・DIRピンの接続ピン番号を定義し、出力モードに設定。loop内でDirectionピンをHIGHにして方向を決定し、forループでStepピンにパルスを送信。パルス間のdelayMicrosecondsで回転速度を制御(値を小さくすると高速化)。その後、方向を反転させ、より短い遅延で2回転分パルスを送信しています。マイクロステッピング設定を変えれば、同じパルス数で回転角度が変わります。
サンプルコード2:ポテンショメーターで速度制御
ポテンショメーターをArduinoに接続し、analogRead()で値を読み取って速度を制御します。
/* Basic example code for controlling a stepper without library
* by Dejan, https://howtomechatronics.com */
#define stepPin 2
#define dirPin 5
int customDelay, customDelayMapped;
void setup() {
pinMode(stepPin, OUTPUT);
pinMode(dirPin, OUTPUT);
}
void loop() {
speedControl();
digitalWrite(stepPin, HIGH);
delayMicroseconds(customDelayMapped);
digitalWrite(stepPin, LOW);
delayMicroseconds(customDelayMapped);
}
void speedControl() {
customDelay = analogRead(A0); // 0-1023
customDelayMapped = map(customDelay, 0, 1023, 300, 3000); // 300-3000μsにマッピング
}
コード解説:
ポテンショメーターの0〜1023の値を、ステップパルス間遅延に適した300〜3000μsにマッピング。300μs未満ではステップアウト(脱調)が発生しました。この方法はシンプルな制御には有効ですが、複雑な制御が必要な場合はライブラリ使用がベストです。
AccelStepperライブラリによるステッピングモーター制御──サンプル集
Arduinoでステッピングモーターを制御する最も人気のライブラリは、Mike McCauley氏作のAccelStepperです。速度・加減速制御、目標位置設定、複数モーター同時制御など、非常に多機能です。ドキュメントも充実しており、筆者もカメラスライダー、3Dワイヤーベンディングマシン、SCARAロボットアームなどで活用しています(詳細はWebサイト参照)。
サンプル:ポテンショメーターで速度制御(AccelStepper版)
/* Basic example code for controlling a stepper with the AccelStepper library
* by Dejan, https://howtomechatronics.com */
#include
AccelStepper stepper1(1, 2, 5); // ドライバータイプ1(2ピン:STEP, DIR)
void setup() {
stepper1.setMaxSpeed(1000); // 最大速度:steps/sec
}
void loop() {
stepper1.setSpeed(analogRead(A0)); // ポテンショメーター値で速度設定
stepper1.runSpeed(); // 設定速度で継続回転
}
コード解説:
AccelStepperライブラリをインクルード(Arduino IDEライブラリマネージャからインストール)。AccelStepperインスタンスを作成:第1引数はドライバータイプ(2ピン制御なら1)、第2・3引数はSTEP・DIRピン番号。複数モーターならそれぞれインスタンス化。setupでsetMaxSpeed(最大4000だが、ドキュメントでは1000以上は不安定との記載あり)。loopでsetSpeedにアナログ入力を渡し、runSpeed()を呼び出し続けることで一定速度回転。負の値を渡せば逆回転。
サンプル:2台のステッピングモーターを加減速付きで制御
/* Controlling two stepper with the AccelStepper library
* by Dejan, https://howtomechatronics.com */
#include
AccelStepper stepper1(1, 2, 5);
AccelStepper stepper2(1, 3, 6);
void setup() {
stepper1.setMaxSpeed(1000);
stepper1.setAcceleration(500);
stepper1.setCurrentPosition(0);
stepper2.setMaxSpeed(1000);
stepper2.setAcceleration(500);
stepper2.setCurrentPosition(0);
}
void loop() {
stepper1.moveTo(800); // 目標位置:800ステップ(1/4ステップなら1回転)
stepper1.runToPosition(); // 加減速付きで目標位置まで移動(ブロッキング)
stepper2.moveTo(1600); // 2回転分
stepper2.runToPosition();
// 非ブロッキングで両モーター同時動作
stepper1.moveTo(0);
stepper2.moveTo(0);
while (stepper1.currentPosition() != 0 || stepper2.currentPosition() != 0) {
stepper1.run(); // 加減速実装しつつ1ステップずつ移動(非ブロッキング)
stepper2.run();
}
}
コード解説:
2台のモーターを定義し、setupで加速度と現在位置(0)を設定。loopでmoveTo()で目標位置を指定し、runToPosition()で加減速付き移動(到達までブロック)。非ブロッキングで同時動作させたい場合はrun()を使用。run()は1呼び出しで1ステップしか進まないため、whileループで高頻度に呼び出す必要があります。このwhile内に他の処理も追加可能。ライブラリドキュメントを参照し、ニーズに合わせて実装してください。
サンプル:MultiStepperクラスで複数モーターを協調制御
AccelStepperに付属のMultiStepperクラスを使えば、複数モーターを「同時に目標位置へ到達」させる協調制御が容易です。移動距離が異なっても、全モーターが同タイミングで到着するよう速度を自動計算します。
/* Controlling multiple steppers with the AccelStepper and MultiStepper library
* by Dejan, https://howtomechatronics.com */
#include
#include
AccelStepper stepper1(1, 2, 5);
AccelStepper stepper2(1, 3, 6);
AccelStepper stepper3(1, 4, 7);
MultiStepper steppersControl;
long gotoposition[3];
void setup() {
stepper1.setMaxSpeed(1000);
stepper2.setMaxSpeed(1000);
stepper3.setMaxSpeed(1000);
steppersControl.addStepper(stepper1);
steppersControl.addStepper(stepper2);
steppersControl.addStepper(stepper3);
}
void loop() {
gotoposition[0] = 800; // 1回転
gotoposition[1] = 1600; // 2回転
gotoposition[2] = 3200; // 3回転
steppersControl.moveTo(gotoposition);
steppersControl.runSpeedToPosition(); // 全モーター到達までブロック
delay(1000);
gotoposition[0] = 0;
gotoposition[1] = 0;
gotoposition[2] = 0;
steppersControl.moveTo(gotoposition);
steppersControl.runSpeedToPosition();
delay(1000);
}
コード解説:
MultiStepperクラスをインクルードし、インスタンス作成。目標位置格納用のlong配列を用意。setupで各モーターの最大速度設定とsteppersControlへの登録。loopで配列に目標位置を格納し、moveTo()で全モーターの必要速度を自動計算、runSpeedToPosition()で同時到達実行。※この関数はブロッキング。非ブロッキングにしたい場合はrun()を使用。MultiStepperクラスは加減速非対応なので注意。より高度な例は、前述の筆者プロジェクトを参照してください。
Arduino CNCシールド──複数ステッピングモーター制御の強力な味方
複数ステッピングモーター制御の文脈で、Arduino CNCシールドにも言及しておきます。
Arduino CNCシールドの主目的は2〜3軸CNCマシンの制御ですが、コンパクトでドライバーとモーターの接続が容易なため、複数ステッピングモーターを必要とするあらゆるプロジェクトに最適な選択肢です。
このシールドはArduino UNOにスタックし、最大4台のステッピングモーターを個別制御可能。残りのArduinoピンもすべて使用できます。筆者はこの組み合わせで4軸SCARAロボットアームを制御しています。
CNCシールドのArduinoでの使い方詳細は、近日中にこのセクションを更新予定です。
DRV8825 vs A4988
次に、DRV8825ステッピングドライバーでの制御を見てみましょう。
実は、A4988で説明したすべてのこと──動作原理、配線、コーディング──はDRV8825でもほぼ同一です。違いは技術仕様にあり、以下の3点がキーです:
- より高い電流供給が可能(追加冷却なしで1.5A vs 1A)
- より高い最大電圧(45V vs 35V)
- より高いマイクロステッピング分解能(32 vs 16マイクロステップ)
その他の細かな違い:ポテンショメータ位置が異なる(A4988はチップ下部、DRV8825は上部)、電流制限設定とVrefの関係式が異なる、ロジック電源ピンが不要でその位置がFAULT出力になる等。ただし、FAULTピンを5Vに直結すれば、A4988設計システムでDRV8825をドロップインリプレースメントとして使用可能です。
※A4988をDRV8825に置き換える際、ドライバーの向きに注意。ポテンショメータ位置が逆になるため、誤って裏返し実装しやすいです。
電流制限設定は、GNDとポテンショメータ間でVrefを測定し、以下の式で計算:
Current Limit = Vref × 2
マイクロステッピング選択は以下の表を参照。
総評:DRV8825はA4988より優れたドライバーです。より高い電流・電圧定格、より高いマイクロステッピング分解能により、ステッピングモーターの動作がより滑らかで静かになります。
TMC2208ステッピングドライバー
「より滑らかで静か」を極めるなら、TMC2208ステッピングドライバーです。TMC2208チップは、モーション制御エレクトロニクス専門のドイツTrinamic社製。A4988やDRV8825設計システムへのドロップインリプレースメントとしても使用可能。デスクトップ3Dプリンター、レーザー彫刻機、スキャナー等で広く採用されています。
このドライバーを際立たせるのが、内蔵インターポレーションユニットによる256分割マイクロステップ提供です。これにより、MSピンで選択した分解能(2、4、8、16マイクロステップ)に関わらず、チップ内部で完全な正弦波制御が生成され、モーターへ256マイクロステップが出力されます。これにより滑らかな動作と、マイクロコントローラーの負荷大幅軽減を実現。
この機能と、無音電流制御技術「StealthChop2」の組み合わせで、超静音制御を実現。騒音レベル比較:
ステッピングドライバー騒音レベル: A4988約65dB、DRV8825約67dB、TMC2208約41dB。
TMC2208はステッピングモーターを完全に静音駆動します。驚異的です。
TMC2208の定格電流はA4988よりわずかに高い1.2A(ピーク2A)。電流制限設定は、GNDとEnableピン横のテストポイントでVrefを測定し、以下の式で計算:
Current Limit = Vref × 0.71
ドロップインリプレースメント可能ですが、ピン配置がA4988と若干異なります:MSピンが2本のみ、EnableピンをGNDに接続して有効化。コーディングは他2ドライバーと同一です。
TMC2208には、UARTインターフェースによる単一ライン制御(Step/Dir 2線不要)、さらなるチューニング・制御オプションなど、他ドライバーにはない高度な機能も搭載。
総評:TMC2208はA4988・DRV8825より優秀ですが、価格も高め。これらの追加機能と静音性が不要なら、他2ドライバーで十分です。
結論
Arduinoでステッピングモーターを制御するために必要な知識を、ほぼ網羅しました。NEMA17と3種類のドライバー(A4988、DRV8825、TMC2208)は、位置制御が必要な無数のアプリケーションで驚異的な汎用性を発揮します。筆者の他のArduinoプロジェクトも参照し、さらなる学習を深めてください。
NEMA23やNEMA34など大型ステッピングモーターの制御についても、別途専用チュートリアルを予定しています。
本チュートリアルがお役に立てば幸いです。チャンネル登録をお願いします。質問はコメント欄へどうぞ。
製造プロセス
- ナックルジョイント完全解説:車両メカニズムにおける設計・機能・構造
- ブースターポンプで家庭の水圧をアップ:ステップバイステップガイド
- Arduino Uno、リレー、Androidアプリで電球をリモート制御
- オールインワン太陽光発電ハブ: 充電コントローラー、インバーター、モバイルバッテリー、LEDライト
- 精密加工成功のための工具材料必須特性
- リチウム電池コストの内訳:なぜ思ったより高いのか
- Arduino Unoで作る低コスト落雷検知器
- パン:古代の穀物から現代生産まで
- バンドソーが従来の鋸を上回る理由
- プロフェッショナル鋼材亜鉛メッキ:長持ちする防食保護
- カムシャフトの機能・構造・トラブル:エンジン性能を左右する弁駆動の要