ステッピングモーターとは?Arduinoと28BYJ-48、ULN2003で正確に回す
ステッピングモーターはどう動くのか。28BYJ-48とULN2003ドライバの配線、1回転のステップ数(2048)、StepperライブラリとAccelStepperライブラリ、角度を指定して回す方法、A4988でのNEMA 17、ESP32とPicoでの使い方を解説します。
ステッピングモーターは、回転を小さく等しいステップに分けて動くモーターです。命令のたびに決まった角度だけ回るので、センサーを追加しなくても、モーターがどこで止まったかが正確にわかります。3Dプリンター、CNCマシン、カメラスライダー、自動カーテンは、この正確さのためにステッピングモーターを使っています。Arduinoで学び始めるいちばん安い方法は、28BYJ-48モーターと、それとセットで売られているULN2003ドライバ基板です。

ステッピングモーターはどう動く?
ステッピングモーターの中には、歯の付いた磁石のローターのまわりに、いくつかのコイルが並んでいます。コイルを決まった順番で励磁すると、ローターはそのたびにいちばん近いコイルに引き寄せられ、1ステップ進みます。順番を速く進めればモーターは速く回り、ゆっくり進めればゆっくり回り、順番を逆にすれば反対に回ります。モーターはステップを1つずつ数えるので位置がわかりますが、負荷が大きすぎると、気づかないままステップを飛ばすことがあります。
ステッピングモーター、サーボ、DCモーターのどれを選ぶ?
| 項目 | DCモーター | サーボモーター | ステッピングモーター |
|---|---|---|---|
| 動き | 連続して回る | 設定した角度に動く(通常0〜180°) | 回転数に制限なし、1ステップずつ |
| 位置の情報 | なし | あり(内蔵のフィードバック) | ステップを数えてわかる |
| 速度 | 非常に速い | 中くらい | 低〜中 |
| 低速時のトルク | 低い | 中くらい | 高い |
| 主な用途 | 車輪、ファン、ポンプ | ロボットアーム、ロック、ステアリング | 3Dプリンター、CNC、スライダー、時計 |
角度を決めてその位置を保てれば十分なら、サーボのほうが簡単です。詳しくはサーボモーターとは?で解説しています。速く連続して回す必要があるなら、DCモーターとL298Nモータードライバのほうが向いています。何回転も回り、しかも位置がわかる必要がある用途では、ステッピングモーターにかなうものはありません。
28BYJ-48の仕様
| 項目 | 値 |
|---|---|
| 種類 | 4相ユニポーラのステッピングモーター |
| 動作電圧 | 5 V DC |
| 内部のギア比 | 約1:64 |
| 1回転のステップ数 | 2048(フルステップ)、4096(ハーフステップ) |
| ステップ角 | 約0.18°(フルステップ) |
| 消費電流 | 約200〜250 mA |
| 最高速度 | 約10〜15 RPM |
| 線 | 5本(赤が共通) |
ULN2003ドライバの配線
モーターの5線のコネクターは、ULN2003基板のソケットに一方向にしか挿さらないので、間違えようがありません。基板のIN1〜IN4ピンをArduinoの8〜11番ピンに、+と–の端子を5 Vの電源につなぎます。ULN2003はダーリントントランジスタアレイで、Arduinoのピンからの小さな信号をコイルが必要とする電流に増幅します。基板上の4つのLEDで、コイルが順番にオンになる様子が見られます。
| ULN2003のピン | Arduino Uno |
|---|---|
| IN1 | D8 |
| IN2 | D9 |
| IN3 | D10 |
| IN4 | D11 |
| +(5〜12 V) | 外部の5 V(モーター1個ならUnoの5Vピンでも可) |
| –(GND) | GND(Arduinoと共通) |
Stepperライブラリで最初の回転
Arduino IDEに付属しているStepperライブラリは、インストール不要です。注意が必要なのはピンの順番だけです。28BYJ-48では、オブジェクトを8, 10, 9, 11(IN1、IN3、IN2、IN4)の順番で宣言する必要があります。8, 9, 10, 11と書くと、モーターは回らずにその場で震えるだけになります。これがいちばん多いミスです。
1#include <Stepper.h>
2
3const int STEPS_PER_REV = 2048; // 28BYJ-48 tam tur / full revolution
4Stepper motor(STEPS_PER_REV, 8, 10, 9, 11); // sıra: IN1, IN3, IN2, IN4 / order: IN1, IN3, IN2, IN4
5
6void setup() {
7 motor.setSpeed(10); // devir/dakika, en fazla ~15 / RPM, max ~15
8}
9
10void loop() {
11 motor.step(STEPS_PER_REV); // bir yönde tam tur / one full turn
12 delay(1000);
13 motor.step(-STEPS_PER_REV / 2); // ters yönde yarım tur / half a turn back
14 delay(1000);
15}ポテンショメーターで位置を制御する
モーターの現在位置を変数に保存しておけば、好きな位置に動かせます。下のコードはポテンショメーターの位置を0〜2048ステップに変え、モーターはつまみに合わせるように同じ位置へ動きます。10ステップの許容範囲で小さな揺れは無視します。ポテンショメーターの配線はポテンショメーターとは?で解説しています。
1#include <Stepper.h>
2
3Stepper motor(2048, 8, 10, 9, 11);
4int position = 0; // şu anki adım / current step
5
6void setup() {
7 motor.setSpeed(12);
8}
9
10void loop() {
11 int target = map(analogRead(A0), 0, 1023, 0, 2048); // potansiyometre → hedef / pot → target
12 if (abs(target - position) > 10) { // küçük titreşimleri yok say / ignore jitter
13 motor.step(target - position);
14 position = target;
15 }
16}AccelStepper:プログラムを止めずになめらかに加速する
Stepperライブラリのstep()命令は、動きが終わるまでプログラムを止めてしまいます。その間はボタンを読んだりディスプレイを更新したりできません。ライブラリマネージャからインストールできるAccelStepperは、バックグラウンドでモーターを1ステップずつ動かし、加速と減速を加えて急な動き出しを防ぎます。28BYJ-48では、1回転が4096ステップになるハーフステップモード(HALF4WIRE)を使います。
1#include <AccelStepper.h>
2
3// 28BYJ-48 + ULN2003, yarım adım: tur başına 4096 / half-step: 4096 per turn
4AccelStepper motor(AccelStepper::HALF4WIRE, 8, 10, 9, 11);
5
6void setup() {
7 motor.setMaxSpeed(1000); // adım/saniye / steps per second
8 motor.setAcceleration(400); // adım/saniye² / steps per second²
9 motor.moveTo(4096); // bir tur ileri / one turn forward
10}
11
12void loop() {
13 if (motor.distanceToGo() == 0) {
14 motor.moveTo(-motor.currentPosition()); // geri dön / go back
15 }
16 motor.run(); // her döngüde çağır, bekletmez / call every loop, non-blocking
17}より強力なモーター:NEMA 17とA4988

3DプリンターやCNCマシンのように力が必要な用途には、NEMA 17のようなバイポーラのステッピングモーターが使われます。これらのモーターは1回転が200ステップ(1.8°)で、28BYJ-48よりずっと強力です。駆動にはA4988やDRV8825のようなドライバを使います。STEPのパルスが1つ来るたびにモーターが1ステップ進み、DIRピンで回転方向を決めます。ドライバは8〜35 Vで動き、マイクロステップを使うと各ステップを最大16分割して、よりなめらかに動かせます。
1const int STEP_PIN = 3;
2const int DIR_PIN = 4;
3
4void setup() {
5 pinMode(STEP_PIN, OUTPUT);
6 pinMode(DIR_PIN, OUTPUT);
7}
8
9void loop() {
10 digitalWrite(DIR_PIN, HIGH); // yön / direction
11 for (int i = 0; i < 200; i++) { // NEMA 17'de 200 adım = 1 tur / 200 steps = 1 turn
12 digitalWrite(STEP_PIN, HIGH);
13 delayMicroseconds(800); // küçüldükçe hız artar / smaller = faster
14 digitalWrite(STEP_PIN, LOW);
15 delayMicroseconds(800);
16 }
17 delay(1000);
18}ESP32とRaspberry Pi Picoでステッピングモーターを使う
ULN2003の入力は3.3 Vの信号でも問題なく動きますが、モーターは別に5 Vから給電してください。ESP32では、AccelStepperライブラリがそのまま動きます。6〜11番と34〜39番以外のピン、たとえばGPIO 19、18、5、17が使えます。MicroPythonを使うPicoでは、ハーフステップの順番を4本のピンに順に書き込んでモーターを回します。
1from machine import Pin
2import time
3
4pins = [Pin(n, Pin.OUT) for n in (2, 3, 4, 5)] # IN1–IN4 → GP2–GP5
5SEQ = [[1,0,0,0],[1,1,0,0],[0,1,0,0],[0,1,1,0],
6 [0,0,1,0],[0,0,1,1],[0,0,0,1],[1,0,0,1]] # yarım adım dizisi / half-step sequence
7
8def rotate(steps, delay_ms=2):
9 direction = 1 if steps > 0 else -1
10 for i in range(abs(steps)):
11 for pin, value in zip(pins, SEQ[(i * direction) % 8]):
12 pin.value(value)
13 time.sleep_ms(delay_ms)
14 for pin in pins:
15 pin.value(0) # bobinleri bırak / release coils
16
17rotate(4096) # bir tur / one turn (half-step)
18rotate(-1024) # çeyrek tur geri / quarter turn backステッピングモーターのプロジェクトアイデア
- アナログ時計:時針と分針をステッピングモーターで回す置き時計です。
- カメラスライダー:タイムラプス撮影のために、カメラをごくゆっくり動かすレールです。
- 自動給餌器(魚用):1日2回ホッパーを回してエサを落とすしくみです。
- 太陽を追うパネル:2つの光センサーで、パネルをいちばん明るい方向に向けます。光の部分はLDR光センサーを参照してください。
- ターンテーブル:商品写真や3Dスキャンのために、物を等しいステップで回す台です。
- 自動カーテン:ひもを巻き取ってカーテンを開け閉めし、位置を覚えておくモーターです。
よくあるミスと直し方
- モーターが震えるだけで回らない:Stepperライブラリのピンの順番が違います。8, 9, 10, 11ではなく8, 10, 9, 11と書いてください。
- モーターがステップを飛ばす:速度が速すぎるか、負荷が重すぎます。28BYJ-48は15 RPM未満に抑え、AccelStepperで加速を加えてください。
- Arduinoがリセットする:電源が足りていません。モーターは外部の5 V電源から給電し、GNDどうしをつないでください。
- 止まっているのにモーターが熱くなる:コイルが励磁されたままです。動きが終わったら4本のピンをすべてLOWにしてください。
- 回転数がずれる:フルステップでは2048、ハーフステップでは4096ステップで、NEMA 17は200ステップです。モードとモーターを取り違えないでください。
- A4988でモーターが回らない:電流制限が低すぎる、モーターの電源がない、またはRESETとSLEEPのピンがつながっていません。
ステッピングモーターは「ちょうどこれだけ回す」を実現するいちばん簡単な方法で、CNCルーターや3Dプリンターのような機械の基本になっています。BlueGraysアプリには、28BYJ-48ステッピングモーターの使い方や、ステッピングモーターで360度サーボを作るプロジェクトが、回路図とコード付きでステップごとに載っています。
よくある質問
28BYJ-48は1回転に何ステップ進みますか?
フルステップモードで約2048、ハーフステップモードで約4096です。内部のギア比がぴったり1:64ではないため、とても長い動きでは小さなずれがたまることがあります。正確さが必要な用途では、リミットスイッチでときどき位置をゼロに戻すとよいでしょう。
ステッピングモーターが震えるだけで回らないのはなぜですか?
いちばん多い原因は、コイルを違う順番で駆動していることです。ArduinoのStepperライブラリでは、28BYJ-48のピンを8, 10, 9, 11(IN1、IN3、IN2、IN4)の順番で書く必要があります。速度が速すぎたり電源が弱すぎたりしても、モーターは回らずに震えることがあります。
ULN2003をArduinoの5Vピンから給電できますか?
28BYJ-48が1個なら、たいてい大丈夫です。モーターの消費電流は約240 mAで、USBでまかなえます。モーターが2個のときや、サーボなどほかの負荷があるときは、ArduinoのレギュレーターとUSBポートに負担がかかります。その場合は外部の5 V電源を使い、GNDどうしをつないでください。
ステッピングモーターはどうやって位置を知るのですか?
ステッピングモーターは位置を測っているのではなく、進んだステップを数えて知っています。そのため、起動時にモーターを基準点(リミットスイッチなど)まで動かしてゼロに合わせ、負荷や高速によるステップ飛びを避ける必要があります。
ステッピングモーターとサーボモーター、どちらを使うべきですか?
0〜180度の角度に動いてその位置を保てれば十分なら、ドライバが内蔵されているサーボのほうが簡単です。何回転も回す、低速で強いトルクが必要、非常に正確な位置決めが必要、といった用途ならステッピングモーターを選びましょう。
28BYJ-48とNEMA 17の違いは何ですか?
28BYJ-48は、ギアボックスのおかげでゆっくりですが正確に回る、小さくて安い5 Vのモーターです。NEMA 17は、1回転200ステップの、はるかに強力で速いバイポーラのモーターで、A4988のようなドライバと12〜24 Vの電源が必要です。28BYJ-48は趣味のプロジェクトに、NEMA 17は3DプリンターやCNCルーターのような機械に使われます。
この記事を読んだ後に作れるプロジェクト
全プロジェクトを見る
ステッピングモーターの使い方
時計の針のように、必要な分だけ正確に少しずつ回転するモーターです。Arduinoがドライバーボードを介して小さなステッピングモーターを一方向に1回転させ、1秒待ってから逆方向に1回転させます。ドア、カーテン、回転台など、正確な回転が必要なプロジェクトの基礎を学べます。

ステッピングモーターで作る360度サーボモーター
普通のステッピングモーターを、1周の範囲で好きな角度へ動かせるようにします。Arduinoが各角度に必要なステップ数を計算し、モーターは0、90、45、180、135、360度へ順番に移動します。それぞれの位置で少し止まり、最初から繰り返します。通常は半回転の範囲に限られるサーボモーターの働きを、1周全体で実現する仕組みを作れます。

ジョイスティックでサーボモーターを制御
防犯カメラの向きを変えるように、ジョイスティックで2つのモーターを操作します。スティックを左右に倒すと下側のサーボモーターがゆっくり回り、上下に倒すと上側のサーボモーターが上下に傾きます。手を離すと、どちらもその位置で止まります。カメラやレーザーの台座など、2方向に動く装置の基礎を作ります。

ESP32サーボモーター(ポテンショメーター制御)
このプロジェクトでは、ポテンショメーターでSG90サーボモーターを制御します。ポテンショメーターから読み取ったアナログ値を0~180度の範囲に変換し、サーボの角度を調整します。ESP32Servoライブラリは、ESP32の出力に対応した適切なGPIOでサーボ信号を生成します。このプロジェクトではGPIO 18を使います。ロボットアームやカメラ用ジンバル、自動ドアの機構に使われる基本的な制御方法です。

L298Nで作るBluetooth操作の車
スマートフォンをリモコンにして、自作のロボットカーを操作できます。ArduinoはBluetoothモジュールを通じてスマートフォンのリモコンアプリから指令を受け取り、モータードライバーで車輪を回します。前進、後退、左右や斜めへの移動ができ、速度もスマートフォンから調整できます。停止ボタンを押すと、短いブレーキ動作でモーターがすぐに止まります。

障害物回避ロボット
自分で進む道を見つける、賢い車を作ってみませんか?障害物回避ロボットは、前面の超音波センサーで周囲を常に調べます。障害物を見つけると停止し、サーボモーターで左右を確認して、最も障害物の少ない方向を選んで進みます。自動運転の基礎を学ぶのにぴったりの入門プロジェクトです。

ジョイスティックでLEDを制御
ジョイスティックのスティックをいずれかの方向へいっぱいに倒すと、その方向のLEDが点灯します。右、左、上、下にそれぞれ異なる4色のLEDがあります。スティックを離すと中央に戻り、すべてのLEDが消灯します。ロボットカーや画面上のゲームを操作するための第一歩です。

ESP32駐車センサー(HC-SR04 + 5連LEDバー + ブザー + OLED)
車の駐車センサーをESP32で作ります!HC-SR04超音波センサーで前方の物体までの距離を測ります。距離が縮まるほど5連LEDバーが緑 → 黄 → 赤の順に点灯し、ブザーの鳴る間隔が短くなります。10 cm未満まで近づくとアラームが鳴り続け、すべてのLEDが点灯します。SSD1306 OLEDには現在の距離をcm単位の大きな文字で表示し、状態メッセージ(落ち着いて / 注意 / 接近 / 停止! / 危険)とLEDバーのシミュレーションも表示します。HC-SR04のpulseIn、複数のデジタル出力、ブザーを学べる定番のプロジェクトです。
ほかの記事
BlueGraysアプリ
この回路をスマホでステップごとに作る
回路図、コード、部品リストを1つの画面で確認できます。Arduino、ESP32、Picoのプロジェクトを200件以上用意しています。

