ガイド · 読了まで18分

DCモーター、サーボ、ステッピングモーターの違い:特徴と選び方

DCモーター、サーボ、ステッピングモーターを速度・トルク・精度で比較。L298N、ULN2003、A4988ドライバ、消費電流、BLDCとESC、用途別の選び方まで解説します。

DCモーター、サーボモーター、ステッピングモーターの違いはひと言でまとめられます。DCモーターは電源を入れている間連続して高速に回り、サーボは指定した角度まで動いてその位置を保ち、ステッピングモーターは小さく数えられるステップ単位で回ります。つまり、車輪を回すならDCモーター、ふたを90度開けるならサーボ、部品を0.1 mm単位の精度で動かすならステッピングモーターを選びます。Arduino、ESP32、Raspberry Pi Picoのプロジェクトで何かを動かすときは、必ずこの3つのどれかに出会います。

このガイドでは、それぞれのモーターの内部構造、人気モデル(TTモーター、SG90、MG996R、28BYJ-48、NEMA 17)の速度・トルク・位置精度の実際の数値、必要なドライバ(L298N、PWM信号、ULN2003、A4988)、消費電流、そしてどのプロジェクトにどれを使うかを比較します。最後に、3つのモーターを同時に動かすArduino、ESP32、Picoのコード、ブラシレスモーター(BLDC)とESCの簡単な紹介、よくある失敗もまとめています。

DCモーター(TT)
DCモーター(TT)
SG90サーボ
SG90サーボ
MG996Rサーボ
MG996Rサーボ
28BYJ-48とULN2003
28BYJ-48とULN2003

結論:3つのモーターの違いを1つの表で

特徴DCモーターサーボモーターステッピングモーター
動き連続して回る指定した角度まで動いて保持(通常0〜180°)ステップ単位で回り、回転数の制限なし
制御するもの速度と回転方向角度(位置)ステップ数とステップの速さ
フィードバックなし(エンコーダーで追加)あり:内蔵のポテンショメーターなし(オープンループ)
速度非常に速い(ギアボックスなしで数千rpm)中程度(SG90:0.1 s/60°)低〜中速、速くなるほどトルクが下がる
トルクギアボックス次第サイズの割に大きい(ギアボックスのおかげ)低速で大きく、停止中も保持する
位置精度なし約1°1.8°(マイクロステップでさらに細かく)
停止時保持せず自由に回る位置を能動的に保持するコイルに通電している間はロックされる
ドライバHブリッジ(L298N、L9110S)またはMOSFET不要、ピンから直接信号を送るULN2003、またはA4988、DRV8825
配線の本数23(GND、+、信号)4または5(6のことも)
主な用途車輪、ファン、ポンプロボットアーム、ドアのラッチ、レーダー3Dプリンター、CNC、カメラスライダー

この表でいちばん大事な行はフィードバックです。サーボは内蔵のポテンショメーターで自分の位置を知っていて、何かに押されても元の位置に戻ります。ステッピングモーターは自分の位置を知りません。何ステップ進んだかを数えているだけで、その数はモーターに無理な負荷がかからず、ステップを取りこぼさない(脱調しない)限り正確です。DCモーターはどれだけ回ったかをまったく知りません。位置が必要なら、軸にエンコーダーを付ける必要があります。どのモーターを選ぶかは、プロジェクトにこの情報が必要かどうかで大きく決まります。

DCモーターの仕組み

ホビー用のDCモーターは、ほとんどがブラシ付きDCモーターです。内部には固定された磁石と回転するコイル(ローター)があり、カーボンブラシと銅の整流子がローターの回転に合わせて電流の向きを切り替えるので、止まらずに回り続けます。配線は2本で、電圧をかけると回り、配線を入れ替えると逆に回ります。電圧が速度を、流れる電流がトルクを決めます。モーターが回っている間、コイルには逆起電力(back EMF)と呼ばれる反対向きの電圧が生じて電流を制限します。軸が何かで止められるとこの逆起電力がなくなり、電流はストール電流まで一気に跳ね上がります。

ギア付きTT DCモーターと車輪のセット
定番のロボットカー用モーター:1:48のプラスチック製ギアボックス付きTTモーター。6 Vで無負荷時に約200〜250 rpmで回り、無負荷時は150 mA、ストール時は最大1.5 Aを消費します。

ギアボックスのない小型DCモーターは数千rpmで回りますが、トルクはごくわずかです。そのため、ロボットにはいつもギア付き(減速機付き)モーターが使われます。TTモーターの1:48ギアボックスは、モーター軸の約12,000 rpmを車輪で250 rpmまで落とし、その分トルクを約48倍にします(ギアの損失を除く)。速度はPWMで、回転方向はHブリッジで切り替えます。詳しくはL298NでDCモーターを制御するをご覧ください。DCモーターの弱点は位置です。同じPWM値でも電池の電圧や負荷によって速度が変わるため、「2秒間前進する」という命令でも毎回進む距離が違います。正確な距離が必要なら、車輪にエンコーダーを付けます。

サーボモーターの仕組み

サーボモーターは、実は小さな箱に詰め込まれた完全なシステムです。DCモーター、速度を落としてトルクを上げるギア列、出力軸につながったポテンショメーター、そして制御基板が入っています。Arduinoはサーボに角度を直接送るのではなく、50 Hz(20 msに1回)のパルスを送ります。パルスの幅が目標の位置を表します。制御基板はその目標と、ポテンショメーターから読んだ実際の位置を比べ、差がゼロになるまでその方向へモーターを動かします。これを閉ループ制御といい、サーボを手で回そうとすると抵抗するのはこのためです。

SG90マイクロサーボモーター
SG90マイクロサーボ:重さ約9グラム、4.8 Vでトルク1.8 kg·cm、速度0.1 s/60°。茶色の線がGND、赤が+5 V、オレンジが信号です。
機器パルス幅の意味例
標準サーボ(180°)角度:約1 msで一端、1.5 msで中央、2 msでもう一端SG90、MG90S、MG996R
連続回転サーボ(360°)速度と方向:1.5 msで停止、短いと一方向、長いと逆方向FS90R
ESC + ブラシレスモータースロットル:1 msで停止、2 msでフルスロットルドローンやRCモデル用のESC

標準的なRCの範囲は1〜2 msですが、SG90のような安価なサーボの多くは180°いっぱいに動かすのに約0.5〜2.4 msを必要とし、ArduinoのServoライブラリも初期設定で544〜2400 µsを使います。SG90の不感帯(これより小さい変化には反応しない幅)は約10 µsで、これはおよそ1°に相当します。サーボの実用的な精度が1度前後なのはこのためです。連続回転サーボ(FS90R)は、フィードバックを無効にしたサーボです。角度ではなく速度と方向を制御することになり、位置の情報は失われます。もっとパワーが必要なら、金属ギアのMG996Rが定番です。基本的な使い方はサーボモーターとは?をご覧ください。

ステッピングモーターの仕組み

ステッピングモーターにはブラシがありません。ケース内のコイルに決まった順番で電流を流すと、磁石のローターがそのたびに次のコイルに向かって1ステップ進みます。最も一般的なハイブリッド型ステッピングモーターは1回転200ステップ、つまり1ステップあたり1.8°です。パルスを送った数だけステップが進み、速く送るほど速く回ります。コイルに通電している間、モーターはその場でロックされます。これを保持トルクといいます。重要な違いは、ステッピングモーターがオープンループだという点です。負荷がトルクを超えると脱調しますが、Arduinoはそれに気づきません。3Dプリンターが起動時に各軸をリミットスイッチまで動かす(原点復帰、ホーミング)のはそのためです。

28BYJ-48ステッピングモーターとULN2003ドライバ基板
28BYJ-48とULN2003基板:5 Vで動く最も安い入門用ステッピングモーターで、内蔵ギアのおかげで1回転約2048ステップです。基板上の4つのLEDは、どのコイルに通電しているかを示します。

ステッピングモーターには2つのタイプがあります。ユニポーラ型(28BYJ-48、5本線)はコイルに共通線があり、ULN2003のような簡単なトランジスタアレイで駆動します。バイポーラ型(NEMA 17、4本線)はコイル電流の向きを反転させる必要があり、A4988、DRV8825、TMC2209のような電流制限付きのドライバがその役目を担います。これらのドライバはマイクロステップにも対応しています。A4988は1つのフルステップを16分割し、1回転のステップ数を3200に増やして、動きをずっと静かで滑らかにします。詳しくは28BYJ-48とULN2003とA4988ステッピングモータードライバをご覧ください。

速度・トルク・位置精度:数値で比較

モデル電源速度トルク精度電流
TT DCモーター(1:48)3〜6 V≈ 200〜250 rpm(6 V、無負荷)0.8 kg·cm(6 V、ストール時)なし(エンコーダーが必要)無負荷時150 mA、ストール時1.5 A
SG90サーボ4.8〜6 V0.1 s / 60°1.8 kg·cm≈ 1°待機中はごくわずか、動作中は0.5 Aを超えることも
MG996Rサーボ4.8〜7.2 V0.17 s / 60°(4.8 V)9.4〜11 kg·cm≈ 1°動作中0.5〜0.9 A、ストール時2.5 A
28BYJ-48ステッピング5 V≈ 10〜15 rpm≈ 0.3 kg·cm≈ 0.18°(2048ステップ/回転)150〜200 mA(停止中も)
NEMA 17ステッピング(17HS4401)12〜24 V(A4988使用時)数百rpm≈ 4 kg·cm(0.4 N·m)保持トルク1.8°、1/16マイクロステップで0.1125°1相あたり最大1.7 A、Vrefで設定

トルクは普通kg·cmで表されます。1 kg·cmのモーターは、軸から1 cmの位置で1 kgの負荷を支えられますが、2 cmでは0.5 kgまでです(1 kg·cm ≈ 0.098 N·m)。たとえば6 VのMG996Rは11 kg·cmなので、15 cmのアームの先端では理論上11 / 15 ≈ 0.73 kgを支えられます。ただし、これはモーターがストールした瞬間の最大トルクで、アーム自体の重さも負荷に加わります。モーターを長持ちさせるには、この値の半分以下で使うのがよい目安です。つまり、このアームの先端で実際に運べるのは数百グラムです。

速度になると順位は逆転します。DCモーターが断トツで速く、SG90サーボは180°の動きに約0.3秒かかり、それより速くは動けません。ステッピングモーターは速くなるほどトルクが下がります。1ステップごとにコイル電流が十分に立ち上がる時間がなくなるためで、28BYJ-48は約15 rpmを超えると脱調し始めます。A4988で駆動するNEMA 17は、12 Vではなく24 Vで給電すると高速域のトルクが増えます。電流はどのみちドライバが制限するからです。一方、精度ではステッピングモーターが勝ちます。NEMA 17はフルステップで1.8°、1/16マイクロステップなら理論上0.1125°です。ちょっとした注意点として、28BYJ-48の内部ギア比はちょうど1:64ではなく約1:63.68なので、実際の1回転は2048ステップではなく約2038ステップです。時計のように回り続けるプロジェクトでは、この差が積み重なります。

各モーターに必要なドライバは?

Arduinoのピンが出せる電流は最大40 mAで、安全な目安は20 mA程度です。小さなTTモーターでも無負荷でその約7倍、ストール時には70倍以上を消費します。さらに、モーターのコイルは電流が切れた瞬間に高い逆電圧のスパイクを発生させ、保護のないピンを壊すことがあります。そのため、モーターとボードの間には必ずドライバを入れます。ボードは小さな制御信号を送るだけで、モーターの電流は電源からドライバを通って直接流れます。ドライバの中にはトランジスタと、逆電圧を吸収するダイオードが入っています。一方向にしか回らないファンやポンプなら、MOSFET1個で十分です。

モータードライバArduino側備考
DCモーター(一方向)MOSFET(例:IRLZ44N)+ ダイオードPWMピン1本ファン、ポンプ、振動モーター
DCモーター(双方向)L298N、L9110S、TB6612FNG方向ピン2本 + PWMピン1本Hブリッジで方向を切り替え、PWMで速度を調整
サーボモーター不要(内蔵)ピン1本、50 Hzの信号多数のサーボにはPCA9685基板(16チャンネル、I2C)
ユニポーラ型ステッピング(28BYJ-48)ULN2003ピン4本コイルを順番にオンにする、1チャンネルあたり500 mA
バイポーラ型ステッピング(NEMA 17)A4988、DRV8825、TMC2209ピン2本(STEP、DIR)電流制限はVrefで設定、マイクロステップに対応
ブラシレスモーター(BLDC)ESCピン1本、サーボ信号電流定格がモーターに合っていること(例:30 A)
A4988ステッピングモータードライバモジュール
A4988ステッピングドライバ:モーター電源8〜35 V、ヒートシンクなしで1相あたり約1 A、最大1/16のマイクロステップ。上にある小さな半固定抵抗(トリマー)で電流制限(Vref)を設定します。
Arduino UnoではServoライブラリがTimer1を使うため、最初のサーボを接続(attach)した時点で、サーボをどのピンにつないでいても9番と10番ピンのanalogWrite(PWM)が使えなくなります。L298NのENAやENBピンを9番か10番につないでいると、モーターの速度が思ったとおりに変わりません。サーボと一緒にDCモーターの速度を制御するなら、PWMには3、5、6、11番ピンを使ってください。

消費電力:それぞれのモーターの消費電流は?

3つのモーターは電流の流れ方がまったく違うので、それに合わせて電源を選ぶ必要があります。DCモーターは負荷が大きくなるほど多くの電流を消費し、起動時や車輪が引っかかったときにはストール電流に近づきます。電源は無負荷時の電流ではなく、このピーク電流に合わせて選びましょう。サーボは待機中はほとんど電流を消費しませんが、動くたびに短く鋭い電流のスパイクが生じます。SG90が1個だけでも瞬間的に0.5 Aを超えることがあり、MG996Rは負荷がかかると2.5 Aに達します。このスパイクで電圧が下がると、Arduinoがリセットされたり、ESP32ではブラウンアウトエラーが起きたりします。一方、ステッピングモーターは、まったく動いていなくてもコイルに電流が流れ続けます。28BYJ-48は止まっていても150〜200 mAを消費し、温かくなります。電池で動かすプロジェクトで保持トルクが不要なら、コイルの通電を切る(A4988ならENピンをHIGHにする)と、電池の持ちがかなり延びます。

  • 別電源を使う:モーターをArduinoの5Vピンから給電しないでください。USBポートが供給できるのは約500 mAで、その一部はボード自身が使います。小さなサーボ1個を除き、どのモーターにも専用の電源が必要です。
  • GNDをつなぐ:モーター用電源のマイナス端子は必ずボードのGNDに接続します。そうしないと制御信号の基準がなくなります(共通GNDを参照)。
  • コンデンサを追加する:サーボの電源ラインに470〜1000 µFの電解コンデンサ、A4988のVMOT入力に47 µF以上、ブラシ付きDCモーターの端子間に100 nFのセラミックコンデンサを入れます。最初のものは電圧降下を、最後のものはブラシのノイズを減らします。
  • 電源はピーク電流に合わせて選ぶ:たとえば、サーボ4個のロボットアームには3 A以上を出せる5〜6 Vの電源が、TTモーター2個の車には2 × 1.5 Aに耐えられる電池パックが必要です。電池がどれくらい持つかは電池寿命計算ツールで計算できます。
  • 電圧を正しく下げる:7.4 Vのパックからサーボ用に5〜6 Vを作るなら、LM2596のようなスイッチングレギュレーターを使います。7805のようなリニアレギュレーターは、アンペア級の電流ではとても熱くなります。

1台のArduinoで3つのモーターを動かす:手順

違いを知るいちばんの方法は、3つを並べて動かしてみることです。下の回路では、TTモーターをL298Nで、SG90をピンから直接、28BYJ-48をULN2003基板で駆動します。ピンの表はArduino Uno、ESP32、Raspberry Pi Picoの3つのコードすべてに対応しています。

接続Arduino UnoESP32Raspberry Pi Pico
L298N ENA(速度、PWM)D5GPIO 25GP15
L298N IN1D7GPIO 26GP14
L298N IN2D8GPIO 27GP13
サーボ信号(オレンジ)D9GPIO 18GP16
ULN2003 IN1D10GPIO 19GP2
ULN2003 IN2D11GPIO 21GP3
ULN2003 IN3D12GPIO 22GP4
ULN2003 IN4D13GPIO 23GP5
GND(すべての電源)GNDGNDGND
  1. L298NのENAジャンパーを外し、ENA、IN1、IN2を表のピンに、DCモーターをOUT1とOUT2の端子につなぎます。モーター用電源(たとえば18650電池2本を直列にした7.4 V)を12V端子に入れます。
  2. サーボの茶色の線をGNDに、赤い線を別の5〜6 V電源に、オレンジの信号線をD9につなぎます。
  3. 28BYJ-48の白いコネクターをULN2003基板に差し込み、IN1〜IN4をD10〜D13につなぎ、基板の+端子に5 V電源から給電します。
  4. すべての電源のマイナス端子とArduinoのGNDをまとめて接続します。
  5. Arduino IDEでコードを書き込みます。ServoライブラリとStepperライブラリはIDEに付属しているので、インストールは不要です。
  6. モーター用電源を入れ、3つのモーターが順番にどう動くかを観察します。
C++ (Arduino IDE)
1#include <Servo.h>
2#include <Stepper.h>
3
4// DC motor (L298N): ENA=5, IN1=7, IN2=8
5const int ENA = 5;                 // PWM; Servo kütüphanesi 9 ve 10'un PWM'ini kapatır / Servo library disables PWM on 9 and 10
6const int IN1 = 7;
7const int IN2 = 8;
8
9const int SERVO_PIN = 9;           // servo sinyali / servo signal
10Servo servo;
11
12const int STEPS_PER_REV = 2048;    // 28BYJ-48 tam tur / full revolution
13Stepper stepper(STEPS_PER_REV, 10, 12, 11, 13);   // sıra: IN1, IN3, IN2, IN4 / order: IN1, IN3, IN2, IN4
14
15void releaseStepper() {            // bobinleri bırak, boşta akım çekmesin / release coils, no idle current
16  for (int pin = 10; pin <= 13; pin++) {
17    digitalWrite(pin, LOW);
18  }
19}
20
21void setup() {
22  pinMode(ENA, OUTPUT);
23  pinMode(IN1, OUTPUT);
24  pinMode(IN2, OUTPUT);
25  servo.attach(SERVO_PIN);
26  stepper.setSpeed(10);            // devir/dakika, 28BYJ-48 için en fazla ~15 / RPM, max ~15 for 28BYJ-48
27}
28
29void loop() {
30  // 1) DC motor: hız ve yön, konum yok / speed and direction, no position
31  digitalWrite(IN1, HIGH);
32  digitalWrite(IN2, LOW);
33  analogWrite(ENA, 180);           // yaklaşık %70 güç / about 70% power
34  delay(2000);
35  analogWrite(ENA, 0);             // motoru serbest bırak / let the motor coast
36  delay(500);
37
38  // 2) Servo: açı ver, gidip orada kalsın / give an angle, it goes there and holds
39  servo.write(0);
40  delay(600);
41  servo.write(180);
42  delay(600);
43  servo.write(90);
44  delay(600);
45
46  // 3) Step motor: tam çeyrek tur ileri ve geri / exactly a quarter turn forward and back
47  stepper.step(STEPS_PER_REV / 4);   // 512 adım = 90° / 512 steps = 90°
48  delay(500);
49  stepper.step(-STEPS_PER_REV / 4);
50  releaseStepper();
51  delay(1000);
52}
行モーター動作
digitalWrite(IN1/IN2)DC方向を決める:HIGH-LOWで前進、LOW-HIGHで後退
analogWrite(ENA, 180)DC速度を決める:180 / 255 ≈ 70%の出力。モーターがどこで止まるかは分からない
servo.write(90)サーボサーボを90°まで動かし、信号が来ている間その位置に保つ
stepper.setSpeed(10)ステッピング毎分10回転になるようにステップ間の時間を設定する
stepper.step(512)ステッピングちょうど512ステップ(90°)進む。終わるまでコードは止まる
releaseStepper()ステッピング4つのコイルをすべてオフにする。モーターは自由に回り、電流を消費しない

コードを動かすと違いは一目瞭然です。DCモーターは2秒間回りますが、軸が止まる位置は毎回違います。サーボは0°、180°、90°へさっと動き、手で回そうとすると抵抗します。ステッピングモーターはゆっくりとちょうど4分の1回転進み、同じ位置に戻ります。releaseStepper()が呼ばれたあとは、軸を手で自由に回せます。Stepperライブラリのstep()関数は、動きが終わるまでコードを止めてしまいます。複数のモーターを同時に、滑らかな加速で動かしたいなら、AccelStepperライブラリに切り替えましょう。

ESP32でDCモーター、サーボ、ステッピングモーターを動かす

ESP32のピンの出力は3.3 Vです。L298NとULN2003の入力はこのレベルをHIGHとして認識し、サーボも3.3 Vの信号で動きます。ただし、モーターにはやはり専用の電源が必要です。違うのはサーボです。Arduino標準のServoライブラリはESP32に対応していません。ESP32Servoライブラリをインストールするか、以下のようにESP32のハードウェアPWMユニットLEDCで50 Hzの信号を自分で作ります。DCモーター用に1 kHz、サーボ用に50 Hzという2つの異なる周波数を使うので、ledcAttachChannelでチャンネルを別々のタイマー(チャンネル0と2)に割り当てています。コアのバージョンによっては、隣り合うチャンネルが同じタイマーを共有するためです。このコードはESP32 Arduinoコア3.x用で、2.xではledcSetupとledcAttachPinを代わりに使います。StepperライブラリはESP32でもそのまま動きます。ESP32が初めてならESP32とは?をご覧ください。

C++ (Arduino IDE)
1#include <Stepper.h>
2
3// ESP32 Arduino çekirdeği 3.x / ESP32 Arduino core 3.x
4const int ENA = 25;                // L298N hız (PWM) / L298N speed (PWM)
5const int IN1 = 26;
6const int IN2 = 27;
7const int SERVO_PIN = 18;          // servo sinyali / servo signal
8
9const int STEPS_PER_REV = 2048;
10Stepper stepper(STEPS_PER_REV, 19, 22, 21, 23);   // sıra: IN1, IN3, IN2, IN4 / order: IN1, IN3, IN2, IN4
11
12void motor(int speed) {            // -255 … 255
13  digitalWrite(IN1, speed > 0);
14  digitalWrite(IN2, speed < 0);
15  ledcWrite(ENA, abs(speed));
16}
17
18void servoWrite(int angle) {       // 0 … 180
19  int us = map(angle, 0, 180, 500, 2400);              // açı → darbe (µs) / angle → pulse (µs)
20  ledcWrite(SERVO_PIN, (uint32_t)us * 65535 / 20000);  // 20 ms içindeki pay / share of the 20 ms period
21}
22
23void setup() {
24  pinMode(IN1, OUTPUT);
25  pinMode(IN2, OUTPUT);
26  ledcAttachChannel(ENA, 1000, 8, 0);        // kanal 0: 1 kHz, 8 bit (0–255) / channel 0: 1 kHz, 8-bit
27  ledcAttachChannel(SERVO_PIN, 50, 16, 2);   // kanal 2, ayrı zamanlayıcı: 50 Hz, 16 bit / channel 2, separate timer: 50 Hz, 16-bit
28  stepper.setSpeed(10);                      // devir/dakika / RPM
29}
30
31void loop() {
32  motor(200);         delay(2000);   // DC: ileri / forward
33  motor(0);           delay(500);    // DC: dur / stop
34  servoWrite(0);      delay(600);    // servo: 0°
35  servoWrite(180);    delay(600);    // servo: 180°
36  servoWrite(90);     delay(600);    // servo: 90°
37  stepper.step(512);  delay(500);    // step: çeyrek tur / quarter turn
38  stepper.step(-512); delay(1000);
39}

Raspberry Pi Pico用のMicroPythonコード

Picoでは、すべてのGPピンでPWMを出力できます。MicroPythonでは、duty_u16()でDCモーターの速度を0〜65535の範囲で、duty_ns()でサーボのパルス幅をナノ秒単位で設定します。ステッピングモーターは、ハーフステップのシーケンスを4本のピンに順番に書き込んで回します。ハーフステップでは、28BYJ-48の1回転は4096ステップです。Picoが初めてならRaspberry Pi Picoとは?から始めましょう。

MicroPython
1from machine import Pin, PWM
2import time
3
4# DC motor (L298N): ENA=GP15, IN1=GP14, IN2=GP13
5ena = PWM(Pin(15))
6ena.freq(1000)
7in1 = Pin(14, Pin.OUT)
8in2 = Pin(13, Pin.OUT)
9
10# Servo: GP16, 50 Hz
11servo = PWM(Pin(16))
12servo.freq(50)
13
14# Step motor (ULN2003): IN1–IN4 = GP2–GP5
15coils = [Pin(n, Pin.OUT) for n in (2, 3, 4, 5)]
16SEQ = [(1,0,0,0), (1,1,0,0), (0,1,0,0), (0,1,1,0),
17       (0,0,1,0), (0,0,1,1), (0,0,0,1), (1,0,0,1)]   # yarım adım dizisi / half-step sequence
18
19def motor(speed):                    # -100 … 100
20    in1.value(speed > 0)
21    in2.value(speed < 0)
22    ena.duty_u16(int(abs(speed) * 655.35))
23
24def servo_angle(angle):              # 0 … 180
25    us = 500 + angle * 1900 // 180   # 500–2400 µs
26    servo.duty_ns(us * 1000)
27
28phase = 0                            # dizideki konum, çağrılar arasında korunur / position in the sequence, kept between calls
29
30def step(steps, delay_ms=2):         # yarım adımda 4096 adım = 1 tur / 4096 half-steps = 1 turn
31    global phase
32    d = 1 if steps > 0 else -1
33    for _ in range(abs(steps)):
34        phase = (phase + d) % 8
35        for pin, v in zip(coils, SEQ[phase]):
36            pin.value(v)
37        time.sleep_ms(delay_ms)
38    for pin in coils:
39        pin.value(0)                 # bobinleri bırak / release coils
40
41while True:
42    motor(70)                        # DC: %70 ileri / 70% forward
43    time.sleep(2)
44    motor(0)                         # DC: dur / stop
45    time.sleep(0.5)
46    for a in (0, 180, 90):           # servo: üç açı / three angles
47        servo_angle(a)
48        time.sleep(0.6)
49    step(1024)                       # step: çeyrek tur / quarter turn
50    time.sleep(0.5)
51    step(-1024)
52    time.sleep(1)

どのプロジェクトにどのモーター?

プロジェクト適したモーター理由
ロボットカー、ライントレースロボットギア付きDCモーター(TT、N20)連続して回り、安価で、PWMによる速度調整で十分
駐車場のゲートバー、ドアのラッチ、錠サーボ(SG90。重いふたにはMG996R)2つの位置の間を動いてそこで止まる
自動スライドドア、ガレージのシャッターギア付きDCモーター + リミットスイッチ移動距離が長く力も大きい。端の位置はスイッチで検出する
3Dプリンター、CNC、レーザー彫刻機NEMA 17ステッピング + A4988またはTMC22090.1 mmより細かく、繰り返し再現できる位置決め
ロボットアームサーボ(土台にMG996R、グリッパーにSG90)各関節を決まった角度で止める必要がある
カメラスライダー、ターンテーブル、スマートカーテンステッピングモーターゆっくり滑らかで、再現性のある動き
レーダー、パンチルトカメラ、太陽追尾装置サーボ0〜180°の首振りで十分、コードもとても簡単
ファン、ウォーターポンプDCモーター + MOSFET一方向で十分。速度調整かオン・オフだけ
ドローン、RC飛行機、電動スケートボードブラシレスモーター(BLDC)+ ESC非常に高い速度、効率、パワー

どちらのモーターでも使えるプロジェクトもあり、その場合は細かい点で選ぶことになります。ロボットカーの車輪ならDCモーターで十分ですが、ちょうど50 cm走らせたいなら、エンコーダーを付けるか、車輪をステッピングモーターで回します。ロボットアームではサーボがいちばん手軽です。重くて精密なアームでは、関節にステッピングモーターとギアを使います。3Dプリンターでは、軸が1 mm進むのに何ステップ必要かを簡単に計算できます。200ステップのモーター、1/16マイクロステップ、20歯のGT2プーリー(歯のピッチ2 mm)なら200 × 16 / (20 × 2) = 80ステップ/mm、リード8 mmのT8台形ねじなら200 × 16 / 8 = 400ステップ/mmになります。レーダーや太陽追尾装置のように0〜180°を首振りするプロジェクトでは、サーボがいちばん安くて簡単な解決策です。

ブラシレスモーター(BLDC)とESCの簡単な紹介

ブラシレスDCモーター(BLDC)は逆の構造になっています。磁石が回転側にあり、コイルは固定されたケース側にあります。ブラシも整流子もないので、摩擦や火花、摩耗がありません。効率がよく、静かで、ずっと長持ちします。その代わり、電流の向きはブラシではなく電子回路で切り替える必要があります。そのためBLDCモーターは3本線で、電池に直接つないでも回りません。模型用モーターでは、速度はKV値、つまり1 Vあたりの無負荷回転数で表されます。1000 KVのモーター(例:A2212)を3セルのLiPo(11.1 V)で回すと、無負荷で約11,100 rpmになります。ドローン、RC飛行機、電動スケートボードや電動キックボード、パソコンのファン、ハードディスクには、どれもブラシレスモーターが使われています。

BLDCモーターをArduinoにつなぐにはESC(電子スピードコントローラー)が必要です。ESCは電池の直流電圧を、モーター用の三相パルスに変換します。センサーレスESCは、通電していないコイルに生じる逆起電力からローターの位置を推定します。うれしいことに、ESCの制御入力はサーボと同じです。50 Hzのパルスで1000 µsが停止、2000 µsがフルスロットルを意味します。ESCの電流定格(例:30 A)はモーターが流しうる最大電流より大きくなければならず、ほとんどのESCには5 Vを出力するBECが付いています。安全のため、ESCは電源を入れたときにまず最小スロットルを受け取る必要があります。これをアーミングといい、この信号を受け取るまでモーターは回りません。下のコードでは、ESCの信号線をD9に、スロットル用ポテンショメーターの中央端子(ワイパー)をA0につないでいます。

C++ (Arduino IDE)
1#include <Servo.h>
2
3Servo esc;                         // ESC bir servo gibi sürülür / an ESC is driven like a servo
4const int POT_PIN = A0;            // gaz potansiyometresi / throttle potentiometer
5
6void setup() {
7  esc.attach(9, 1000, 2000);       // 1000–2000 µs aralığı / 1000–2000 µs range
8  esc.writeMicroseconds(1000);     // en düşük gaz: ESC'yi kur (arming) / minimum throttle: arm the ESC
9  delay(3000);                     // bip seslerini bekle / wait for the beeps
10}
11
12void loop() {
13  int throttle = map(analogRead(POT_PIN), 0, 1023, 1000, 2000);   // pot → gaz / pot → throttle
14  esc.writeMicroseconds(throttle);
15  delay(20);                       // bir servo periyodu / one servo period
16}
ブラシレスモーターをテストするときは必ずプロペラを外してください。1000 KVのモーターは一瞬で10,000 rpmを超え、プロペラで大けがをするおそれがあります。LiPoバッテリーは必ず専用の充電器で充電し、絶対にショートさせず、膨らんだバッテリーは使わないでください。ArduinoをUSBで給電している場合は、ESCのBECから来る赤い線はつながないでください。信号線とGNDだけで十分です。

よくある失敗と対策

  • モーターが動くとArduinoがリセットされる:モーターやサーボをボードの5Vピンから給電しています。別電源を使い、GNDをつなぎ、電源に大容量のコンデンサを追加してください。
  • サーボが震える、またはピクピク跳ねる:電源が弱い、配線が細くて長い、またはGNDが共通になっていません。1 A以上を出せる5〜6 Vの電源にサーボをつないでください。
  • サーボを使うとDCモーターの速度が変わらない:UnoでENAが9番か10番ピンにつながっています。Servoライブラリはこの2本のピンのPWMを無効にしてしまいます。ENAを3、5、6、11番のいずれかに移してください。
  • PWM値が小さいとDCモーターが回らず、うなるだけ:静止摩擦に打ち勝つだけのパワーが足りません。一瞬だけ大きな値で起動してから速度を下げるか、最小値を80〜100程度に保ってください。L298Nの約2 Vの電圧降下も考慮しましょう。
  • ステッピングモーターが振動するだけで回らない:コイルの順番が違うか、速度が速すぎます。28BYJ-48ではStepper(2048, IN1, IN3, IN2, IN4)の順番を使い、速度を15 rpm未満に保ってください。
  • ステッピングモーターが脱調する:負荷が重すぎる、加速が急すぎる、またはA4988の電流制限が低すぎます。I = Vref / (8 × Rcs)の式でVrefを設定し(Rcsは基板上の電流検出抵抗)、AccelStepperでゆるやかに加速させてください。
  • A4988が焼けた:ドライバに通電したままモーターのケーブルを抜き差しした、Vrefが高すぎた、またはVMOTにコンデンサを付けていなかった、のいずれかです。モーターは必ず電源を切った状態でつないでください。
  • ESCがモーターを回さず、ビープ音を鳴らし続ける:起動時に最小スロットルの信号を受け取っていません。setup()でwriteMicroseconds(1000)を送り、数秒待っているか確認してください。必要ならマニュアルに従ってESCをキャリブレーションします。
迷ったら、ひとつだけ自問してみてください。モーターは連続して回るのか(DCモーター)、決まった角度まで動いてそこで止まるのか(サーボ)、それとも何回転もしながら正確な位置を把握し続けるのか(ステッピングモーター)。非常に高い速度と効率が必要なら、答えはブラシレスモーターとESCです。

まとめると、DCモーターは速度、サーボは角度、ステッピングモーターは位置です。正しいモーターと正しいドライバを組み合わせれば、プロジェクトの半分は解決したようなものです。まずSG90とTTモーターから始めて、次にステッピングモーターに進むのが、3つすべてを身につけるいちばん簡単な道です。BlueGraysアプリでは、サーボモーターの基本、ポテンショメーターによるサーボ制御、ステッピングモーターの基本、ステッピングモーターで作る360度サーボ、L298NによるBluetooth操作の車、障害物を避けるロボットを、回路図とコード付きでステップごとに学べます。

よくある質問

サーボとステッピングモーターの違いは何ですか?

サーボは内蔵のポテンショメーターで自分の位置を把握し、通常は0〜180°の範囲で指定した角度まで動いてそこで止まります。ステッピングモーターは回転数の制限なく回れ、ステップ数を数えることで位置を把握しますが、負荷がかかりすぎて脱調しても気づきません。短く素早い角度の動きにはサーボ、何回転にもわたる精密な位置決めにはステッピングモーターを選びましょう。

DCモーターはArduinoに直接つなげますか?

いいえ。Arduinoのピンが出せる電流は最大40 mAですが、小さなDCモーターでも数百ミリアンペアを消費し、電流が切れたときにはピンを壊しかねない逆電圧のスパイクを発生させます。一方向の制御にはMOSFETとダイオードを、正転・逆転にはL298NやL9110SのようなHブリッジドライバを使ってください。

ステッピングモーターが熱くなるのはなぜですか?

ステッピングモーターは、止まっていても保持トルクを出すためにコイルに電流が流れ続けます。そのため、ケースが温かい、あるいは熱くなるのは正常です。数秒以上手を当てていられないほど熱いなら、A4988の電流制限(Vref)が高すぎます。位置を保持する必要がないときは、ENピンをHIGHにするかコイルの通電を切ると、発熱と消費電流を減らせます。

サーボモーターは360度回転できますか?

標準的なサーボは内部に機械的なストッパーがあるため、通常は0〜180°の範囲でしか回りません。FS90Rのような連続回転(360°)サーボは1回転以上回れますが、その場合は角度ではなく速度と方向を制御することになり、位置の情報は失われます。1回転以上の回転と正確な位置の両方が必要なら、ステッピングモーターのほうが適しています。

3Dプリンターにステッピングモーターが使われるのはなぜですか?

ステッピングモーターは受け取ったパルス1回ごとに決まった角度だけ回るので、追加のセンサーなしで再現性のある精密な位置決めができます。NEMA 17モーターに1/16マイクロステップとGT2ベルトを組み合わせると1 mmあたり80ステップ、つまり1ステップあたり約0.0125 mmになります。安価で丈夫、制御も簡単なため、ホビー用3DプリンターやCNCマシンの標準になっています。

ブラシレス(BLDC)モーターをArduinoで制御するには?

ブラシレスモーターはピンから直接、あるいはL298Nで駆動することはできず、間にESCが必要です。ESCの信号線をArduinoのピンにつなぎ、Servoライブラリを使ってwriteMicroseconds(1000)で停止、writeMicroseconds(2000)でフルスロットルにします。電源投入時には、数秒間最小スロットルを送ってESCをアーミングする必要があります。

全プロジェクトを見る
サーボモーターの使い方
#35初級
プレミアム

サーボモーターの使い方

小型サーボモーターのアームが、一方の端、中央、もう一方の端の3つの位置へ順番に回り、それぞれの位置で2秒間止まります。Arduinoが保持する角度をモーターに指示すると、モーターはその位置まで動いて止まります。ロボットアームや自動開閉するふたが動く仕組みを学べます。

4.7(48)
67
ステッピングモーターの使い方
#67中級
プレミアム

ステッピングモーターの使い方

時計の針のように、必要な分だけ正確に少しずつ回転するモーターです。Arduinoがドライバーボードを介して小さなステッピングモーターを一方向に1回転させ、1秒待ってから逆方向に1回転させます。ドア、カーテン、回転台など、正確な回転が必要なプロジェクトの基礎を学べます。

4.5(31)
42
L298Nで作るBluetooth操作の車
#80上級
プレミアム

L298Nで作るBluetooth操作の車

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

5.0(38)
65
ポテンショメーターでサーボモーターを操作
#36初級
プレミアム

ポテンショメーターでサーボモーターを操作

ポテンショメーターのつまみを回すと、サーボモーターのアームもそれに合わせて回ります。つまみの一方の端が0度、もう一方の端が半回転に対応します。Arduinoがつまみの位置を常に読み取り、サーボモーターが動きにすぐ反応します。ロボットアームや回転式カメラ台などのプロジェクトへの第一歩です。

4.6(37)
52
ステッピングモーターで作る360度サーボモーター
#68中級
プレミアム

ステッピングモーターで作る360度サーボモーター

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

4.5(22)
32
障害物回避ロボット
#81上級
プレミアム

障害物回避ロボット

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

5.0(38)
49
ESP32サーボモーター(ポテンショメーター制御)
#118中級
プレミアム

ESP32サーボモーター(ポテンショメーター制御)

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

4.3(29)
42
ESP32のRFIDドアロック(RC522 + サーボモーター + OLED + ブザー + LED)
#137上級
プレミアム

ESP32のRFIDドアロック(RC522 + サーボモーター + OLED + ブザー + LED)

ESP32、RC522 RFIDモジュール、SG90サーボモーター、SSD1306 OLEDディスプレイ、アクティブブザー、LED2個を使ってスマートドアロックを作ります。カードを読み取ると、UIDをコード内に登録した許可済みカードの一覧と照合します。許可されたカードなら、サーボモーターを回して解錠し、緑色のLEDが点灯して短い音が2回鳴ります。5秒後に自動で施錠します。許可されていないカードでは赤色のLEDが点灯し、短い間隔で3回音を鳴らして警告し、読み取ったUIDをOLEDに表示します。実際のIoTセキュリティの仕組みを実践的に学べます。

4.8(9)
15