「ステッピングモーターって、サーボモーターと何が違うの?」「A4988ってよく名前を見るけど、どうやって使うの?」

こんな疑問を持ったことがある方、多いんじゃないでしょうか。

ステッピングモーターは位置制御が得意なモーターで、3Dプリンターや自動カーテン、CNCマシンなど「ここまで正確に動かしたい」という場面で大活躍します。サーボモーターと違ってフィードバックなしで角度を管理できるのが最大の魅力ですよね。

今回は、Arduinoとドライバモジュール「A4988」を組み合わせて、ステッピングモーターを動かすところから、実際の現場で問題になりやすい脱調(ステップ飛び)の対策まで、一気に解説します!

✅ 対象読者:Arduino基礎(Lチカ程度)を経験したことがある方
✅ 難易度:初〜中級者向け

ステッピングモーターとA4988の基礎知識

stepper motor arduino
stepper motor arduino / Photo by Jakub Zerdzicki via Pexels

ステッピングモーターとは?

ステッピングモーター(パルスモーターとも言います)は、パルス信号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コースや電子部品もまとめています。

Arduinoロボット入門のおすすめコース・部品を見る →

📚 関連商品・おすすめ書籍

スッキリわかるPython入門 第2版 (スッキリわかる入門シリーズ)

もしも

スッキリわかるPython入門 第2版 (スッキリわかる入門シリーズ)

初心者に定番のPython入門書

Amazonで見る

Arduinoをはじめよう 第4版 (Make: PROJECTS)

もしも

Arduinoをはじめよう 第4版 (Make: PROJECTS)

Arduino公式推薦の定番入門書

Amazonで見る

徹底攻略! 電子工作&プログラミング Arduinoで学ぶ電子工作完全ガイド

もしも

徹底攻略! 電子工作&プログラミング Arduinoで学ぶ電子工作完全ガイド

電子工作とプログラミングを同時に学べる

Amazonで見る

※本記事にはアフィリエイトリンクが含まれます。

ABOUT ME
やまちゃん
これまで学生と社会人を合わせて5000人以上にプログラミング学習を指導。 ゼロからイチをわかりやすく解説する専門家として活動しており、本業ではArduinoを用いたIoT開発とロボットプログラミングが専門。 Pythonを用いたアプリ開発、ウェブアプリケーションの開発で業務の効率化をサポートしています。