ArduinoでステッピングモーターをA4988で制御する方法【回路図・コード・脱調対策まで徹底解説】
「ステッピングモーターって、サーボモーターと何が違うの?」「A4988ってよく名前を見るけど、どうやって使うの?」
こんな疑問を持ったことがある方、多いんじゃないでしょうか。
ステッピングモーターは位置制御が得意なモーターで、3Dプリンターや自動カーテン、CNCマシンなど「ここまで正確に動かしたい」という場面で大活躍します。サーボモーターと違ってフィードバックなしで角度を管理できるのが最大の魅力ですよね。
今回は、Arduinoとドライバモジュール「A4988」を組み合わせて、ステッピングモーターを動かすところから、実際の現場で問題になりやすい脱調(ステップ飛び)の対策まで、一気に解説します!
✅ 対象読者:Arduino基礎(Lチカ程度)を経験したことがある方
✅ 難易度:初〜中級者向け
ステッピングモーターとA4988の基礎知識

ステッピングモーターとは?
ステッピングモーター(パルスモーターとも言います)は、パルス信号1つにつき決まった角度だけ回転するモーターです。
イメージとしては「時計の秒針が1秒ごとにカチッと動く」感じ。連続回転じゃなく、ステップ単位でコマを進めるので、制御がとても正確なんです。
よく使われるバイポーラ型28BYJ-48(5V)やNEMA17がArduinoプロジェクトでは定番です。今回はNEMA17を前提に話を進めます。
A4988ドライバモジュールとは?
A4988はバイポーラステッピングモーターの専用ドライバICです。Arduinoから2本の信号線(STEPとDIR)を受け取るだけで、モーターへの複雑なコイル制御をすべて内部でやってくれます。
ArduinoだけでステッピングモーターのコイルをH橋で直接制御するのはかなり大変なので、A4988モジュール(数百円)を使うのが現実的です。
主な特徴はこのとおりです:
- 電源電圧:8〜35V(モーター用)、3.3〜5V(ロジック用)
- 最大電流:1A連続(放熱なし)、2A(放熱あり)
- マイクロステッピング対応(1/1〜1/16)
- 過熱・過電流保護機能あり
必要な部品と回路の作り方
用意するもの
- Arduino UNO(または互換機)
- A4988ステッピングドライバモジュール
- NEMA17ステッピングモーター(1.8°/ステップ)
- 12V電源(モーター用。USBだけでは動かせません!)
- 100µF電解コンデンサ × 1(電源ノイズ対策)
- ブレッドボード・ジャンパ線
回路の接続方法
まず接続の全体像を把握しましょう。A4988モジュールのピン配置はこうなっています:
| A4988ピン名 | 接続先 |
|---|---|
| VMOT | 12V電源(+) |
| GND(VMOT側) | 12V電源(−) |
| VDD | Arduino 5V |
| GND(VDD側) | Arduino GND |
| STEP | Arduino デジタルピン3 |
| DIR | Arduino デジタルピン2 |
| ENABLE | Arduino GND(常時有効) |
| 1A・1B・2A・2B | モーターコイル(A相・B相) |
| MS1・MS2・MS3 | マイクロステップ設定(後述) |
⚠️ 重要な注意点が2つあります:
- 100µFコンデンサをVMOTとGND間に必ず入れること。モーター起動時の電源スパイクでA4988が壊れることがあります。
- モーターを接続したままA4988に電源を入れること。モーター未接続で電源ONするとA4988が即死する場合があります。
電流制限(Vref)の設定
A4988には電流を制限するトリマポテンショメーターが付いています。設定しないとモーターに過電流が流れ、発熱・破損の原因になります。
設定式はこうです:
Vref = Imax × 8 × Rs
NEMA17の定格電流が1Aで、A4988基板の検出抵抗(Rs)が0.1Ωの場合:
Vref = 1.0 × 8 × 0.1 = 0.8V
電源ON状態でGNDと基板上のポテンショメーター中央をテスターで測りながら、ドライバーで0.8V付近に調整してください。
Arduinoスケッチ:まずは基本の回転から
接続と電流設定ができたら、いよいよArduinoのコードを書きましょう。
// ステッピングモーター基本制御スケッチ(A4988使用)
// 1回転(200ステップ)を正転→1秒待機→逆転で繰り返す
const int STEP_PIN = 3; // STEPピン
const int DIR_PIN = 2; // DIRピン
void setup() {
pinMode(STEP_PIN, OUTPUT);
pinMode(DIR_PIN, OUTPUT);
}
// 指定したステップ数だけモーターを動かす関数
void moveMotor(int steps, bool clockwise, int stepDelayUs) {
// 方向を設定(HIGH=正転、LOW=逆転)
digitalWrite(DIR_PIN, clockwise ? HIGH : LOW);
delay(1); // 方向切り替え後の安定待ち(重要!)
for (int i = 0; i < steps; i++) {
digitalWrite(STEP_PIN, HIGH);
delayMicroseconds(stepDelayUs); // HIGH保持時間
digitalWrite(STEP_PIN, LOW);
delayMicroseconds(stepDelayUs); // LOW保持時間
}
}
void loop() {
// 正転:200ステップ(1.8°×200=1回転)、1ステップあたり2000µs
moveMotor(200, true, 2000);
delay(1000); // 1秒停止
// 逆転:200ステップ
moveMotor(200, false, 2000);
delay(1000);
}
ポイントをまとめるとこんな感じです:
- stepDelayUs(ステップ間隔)を短くするほど速く回転する。ただし短すぎると脱調する
DIR_PINを切り替えた直後にdelay(1)を入れると安定する- NEMA17(1.8°/ステップ)は200ステップ=1回転
マイクロステッピングで動きをなめらかに
A4988のMS1・MS2・MS3ピンを組み合わせることで、1ステップをさらに細かく分割できます。
| MS1 | MS2 | MS3 | 分割数 | 1回転のステップ数 |
|---|---|---|---|---|
| LOW | LOW | LOW | フルステップ(1/1) | 200 |
| HIGH | LOW | LOW | 1/2ステップ | 400 |
| LOW | HIGH | LOW | 1/4ステップ | 800 |
| HIGH | HIGH | LOW | 1/8ステップ | 1600 |
| HIGH | HIGH | HIGH | 1/16ステップ | 3200 |
たとえば1/16マイクロステッピングを使うと、動きがとてもなめらかになります。ただし1回転に必要なステップ数が増えるので、stepDelayUsを短くするか、回転速度が落ちることを覚えておきましょう。
// 1/16マイクロステッピングで角度指定回転
// MS1=HIGH, MS2=HIGH, MS3=HIGHにピン設定済みの想定
const int STEPS_PER_REV = 3200; // 200 × 16
void rotateDegrees(float degrees, bool clockwise) {
// 指定角度に必要なステップ数を計算
int steps = (int)(degrees / 360.0 * STEPS_PER_REV);
moveMotor(steps, clockwise, 500); // 500µs間隔
}
void loop() {
rotateDegrees(90.0, true); // 90度正転
delay(500);
rotateDegrees(90.0, false); // 90度逆転
delay(500);
}
脱調(ステップ飛び)の原因と対策
実際に動かしてみると「あれ?なんか回転がズレてる…」という経験をすることがあります。これが脱調です。
脱調とは、Arduinoがパルスを送ったのにモーターがついてこられず、ステップを飛ばしてしまう現象です。
脱調の主な原因と対策一覧
| 原因 | 対策 |
|---|---|
| ステップ間隔(stepDelayUs)が短すぎる | 値を大きくして速度を落とす |
| 電流制限(Vref)が低すぎる | Vrefを適切な値に再調整する |
| モーター電源電圧が不足している | 12V以上の安定した電源を使う |
| 負荷が大きすぎる | 減速機構を追加・モーターを強いものに変更 |
| 急加速・急停止している | 加速カーブ(ランプアップ)を実装する |
| 電源ノイズ | コンデンサをVMOT-GND間に追加 |
加速カーブ(ランプアップ)の実装
脱調対策として最も効果的なのが加速カーブの実装です。いきなりフルスピードで動かさず、少しずつ速度を上げていきます。
// 加速・定速・減速のランプ制御
void moveWithRamp(int steps, bool clockwise) {
int rampSteps = steps / 4; // 全体の1/4を加速・減速に使う
int maxDelay = 3000; // 最低速(µs)
int minDelay = 800; // 最高速(µs)
digitalWrite(DIR_PIN, clockwise ? HIGH : LOW);
delay(1);
for (int i = 0; i < steps; i++) {
int currentDelay;
if (i < rampSteps) {
// 加速フェーズ:delayを徐々に短く
currentDelay = map(i, 0, rampSteps, maxDelay, minDelay);
} else if (i > steps - rampSteps) {
// 減速フェーズ:delayを徐々に長く
currentDelay = map(i, steps - rampSteps, steps, minDelay, maxDelay);
} else {
// 定速フェーズ
currentDelay = minDelay;
}
digitalWrite(STEP_PIN, HIGH);
delayMicroseconds(currentDelay);
digitalWrite(STEP_PIN, LOW);
delayMicroseconds(currentDelay);
}
}
ここが重要です:
map()関数でdelayを線形補間しているので、スムーズに加減速できる- rampStepsを増やすほど加速が緩やかになる
- maxDelayとminDelayはモーターの仕様・負荷に合わせて調整が必要
まとめ
今回学んだことを整理するとこんな感じです:
- 🔧 ステッピングモーターはパルスで正確な角度制御ができるモーター
- 🔧 A4988はSTEP/DIRの2本でバイポーラステッピングを制御できる優秀なドライバ
- 🔧 コンデンサの追加と電流制限(Vref)設定が回路の肝
- 🔧 マイクロステッピングで動作をなめらかにできる
- 🔧 脱調はstepDelayUs・Vref・加速カーブの3点で対策できる
最初は「なんか思ったより接続が多いな…」と感じるかもしれません。でも一度ちゃんと動かせると、「むずかしそう」が「なんだ、こういう仕組みか!」に変わるはずです 😊
ぜひブレッドボードで試してみてください。次は AccelStepperライブラリを使ったより高度な制御や、複数モーターの同期制御にも挑戦してみましょう!
こちらも読まれています
📡 Arduinoをもっと深く学ぼう!
Arduino・ラズパイ・ロボットプログラミングを体系的に学びたい方へ。おすすめのUdemyコースや電子部品もまとめています。
📚 関連商品・おすすめ書籍
※本記事にはアフィリエイトリンクが含まれます。





