TsukuLab
See artikkel on 日本語 versioonis. Eesti versioon on ettevalmistamisel.
Arduino

Arduinoモーター制御入門|サーボ・DC・ステッピング

Uuendatud: 2026-03-19 20:02:51中村 拓也

『Arduino』でモーターを動かすときは、まず「どのモーターを選ぶか」より先に、本体から直接つながない理由を押さえるのが近道です。
サーボ、DC、ステッピングは制御したいものがそれぞれ違い、必要になる配線も信号も、サーボ信号、PWM+方向、STEP/DIRときれいに分かれます。

この記事は、これからモーター制御を始める初心者に向けて、まず3種類の違いを整理します。
つぎに最小構成の配線、必要部品、コピー&ペーストで動く最小コードまで順番に見ていきます。
Arduino公式のServo Motor BasicsArduino公式のServo Motor BasicsやStepper Motor ConfigurationsやStepper Motor Configurationsでも前提になるのは、外部電源とGND共通、そしてドライバを挟むことです。

筆者のワークショップでも、USB給電のままサーボを動かして『Arduino』が何度もリセットする場面は珍しくありませんでしたが、外部5Vを用意してGNDを共通にした瞬間に落ち着くことがよくあります。
ここが最初の山です。
この記事では、その山を越えるために、壊しやすい配線ミスや電流設定の落とし穴を具体的に避けながら進めます。

関連記事Arduino入門|初心者向けの使い方と最初のプロジェクト[Arduino](https://docs.arduino.cc/software/ide-v2/)を今日から始めたい人向けに、購入前の準備から[Arduino IDE](https://docs.arduino.cc/software/ide-v2/)の導入までを30〜60分で一直線にたどれる形にまとめました。最初のLチカ(内蔵LEDの点滅)や外部LEDの点滅まで、配線図とコードをそのまま再現できる手順に絞って解説します。

arduinoでモーター制御する前に知っておく基礎">Arduinoでモーター制御する前に知っておく基礎

Arduino UNOのI/OとPWMの基礎

ここでは『Arduino UNO』系に共通する基本だけに絞って進めます。
UNO R3と『UNO R4』は中身のマイコンや周辺機能に差がありますが、モーター制御の入口で押さえるべき「どのピンから何を出せるか」「なぜ直接つながないのか」という考え方は共通です。

『Arduino UNO』には、デジタルI/Oが14本、アナログ入力が6本あります。
このうちPWM出力として使えるピンは6本です。
初心者向けにざっくり描くと、役割は次のように整理できます。

Arduino UNO の基本イメージ

[デジタルI/O] 14本
0 1 2 3 4 5 6 7 8 9 10 11 12 13
    ↑     ↑   ↑   ↑    ↑   ↑
   PWM   PWM PWM PWM  PWM PWM

[アナログ入力] 6本
A0 A1 A2 A3 A4 A5

モーター制御でよく使うのは、この中のデジタル出力とPWMです。
たとえばブラシ付きDCモーターなら、速度調整にPWM、回転方向の切り替えにデジタル出力を組み合わせるのが基本形です。
HowToMechatronicsのDCモーター解説でも、PWMで平均電圧を変えて回転を調整し、Hブリッジで正転・逆転を切り替える構成が示されています。
ステッピングモーターではSTEPとDIR、ホビー用RCサーボではサーボ信号という具合に、モーターの種類ごとに「Arduinoから出す信号」が変わります。

ただし、ここで勘違いしやすいのが、PWMピンがあることと、モーターをそのまま回せることは別だという点です。
UNO R3系のI/Oピンは1本あたりおおよそ20mAが目安で、これは信号を出すには十分でも、モーターを駆動する電流としてはまったく足りません。
小型サーボ1個でも、負荷が急にかかった瞬間には数百mAクラスまで跳ね上がります。
筆者もUSB給電のままサーボを1個つないで試作していたとき、スケッチの書き込み直後にサーボが動き出す瞬間だけ基板がリセットし、シリアルモニタが途切れる現象を何度も経験しました。
無負荷では動いて見えても、実際の負荷変動を入れると一気に不安定になります。

Arduino® UNO™ R4store-usa.arduino.cc

直接つながない 3つの理由

モーター制御でドライバを挟むのは、回路を複雑に見せるためではありません。役割がはっきり3つあります。

1つ目は、必要な電流をモーターへ流すためです。
ArduinoのI/Oピンは信号線であって、電力線ではありません。
DCモーターもステッピングモーターも、回転開始時や負荷がかかった瞬間に大きな電流を求めます。
そこでL298PベースのArduino Motor Shield Rev3や、A4988DRV8825のような専用ドライバが、Arduinoの小さな制御信号を受け取り、外部電源からモーターへ必要な電流を供給します。

2つ目は、逆起電力から基板を守るためです。
モーターはコイルなので、回したり止めたりすると電圧の跳ね返りが発生します。
これをそのままI/Oピンに返すと、誤動作だけでなく部品破損にもつながります。
モータードライバには、フライバック対策のダイオードや保護回路が組み込まれているものが多く、この跳ね返りを受け止める役目があります。

ここが肝になります。
初心者が「Arduino が全部を動かしている」と考えると、配線や電源まわりの役割が抜け落ちがちです。
実際は Arduino は司令塔で、力仕事はドライバや電源が担います。

外部電源とGND共通

モーターを安定して動かすには、電源をArduino本体と分けて考える必要があります。
モーター側の電圧は、使うモーターやドライバの仕様に合わせます。
たとえばArduino StoreのMotor Shield Rev3では、外部電源として7〜12Vが案内されています。
ステッピングモーターでも、Arduino公式の解説は一貫して外部電源での駆動を前提にしています。

ここで外しやすいのが、Arduinoの5Vピンからモーターへ給電しないという前提です。
5Vピンはセンサや小さなロジック回路には便利ですが、モーターの起動電流や負荷変動を受け止める用途ではありません。
サーボ、DC、ステッピングのどれでも、このルールを崩すと電圧降下、リセット、ジッタ、書き込み失敗が一気に出ます。

そして、外部電源を使うときはArduino基板のGNDとモーター電源のGNDを必ず共通にする必要があります。
これは「電源を同じにする」という意味ではなく、信号の基準電位をそろえるという意味です。
ArduinoがPWMやDIR信号を出しても、相手のドライバから見てGNDの基準が合っていなければ、その信号は正しく読めません。
未共通のままだと、まったく動かない、たまにだけ動く、方向が不安定、サーボが震える、といった症状になります。
ワークショップでも、配線ミスの中で頻度が高いのはこのGNDの見落としでした。
電源プラス側ばかり追いかけて、戻り道であるGNDが抜けているパターンです。

NOTE

配線図を見るときは、「信号線がどこへ行くか」だけでなく、その信号の基準になる GND が同じ場所に戻っているかを必ず確認してください。
基準がずれていると、信号は正しく見えても相手側で正しく解釈されません。
配線図を見るときは、「信号線がどこへ行くか」だけでなく、「その信号の基準になるGNDが同じ場所に戻っているか」を一緒に追うと、原因切り分けが早くなります。

逆起電力とノイズの基本

モーター回路で起こるトラブルは、電流不足だけではありません。
もうひとつの定番が、逆起電力とノイズです。
モーターはコイルを使う部品なので、通電を切り替えるたびに電圧が跳ね、周囲の配線にもノイズをまき散らします。
DCモーターを止めた瞬間にArduinoが再起動したり、サーボが意図しない角度へ一瞬だけ振れたりするのは、この影響を疑う場面です。

対策の基本はシンプルです。
まず、保護素子を持つドライバを使うことです。
ドライバICやシールドは、この種の対策込みで設計されています。
次に、モーターまわりの配線をできるだけ短くすることです。
長い配線はアンテナのようにノイズを拾い、また放射します。
ブレッドボード上で配線が何本も遠回りしていると、不安定さの原因になります。
さらに、電源ラインにバイパス用のコンデンサを置いて電圧の揺れを吸収すると、瞬間的な落ち込みや尖ったノイズを抑えやすくなります。

ステッピングモーター用のA4988やDRV8825では電流制限設定が、Hブリッジ系では発熱と電圧降下が、サーボでは瞬間電流と制御信号の安定性が、それぞれ効いてきます。
見た目はどれも「モーターを回す」話ですが、実際には電源、保護、配線の3点が土台です。
この土台が整っていれば、その先のPWM、STEP/DIR、サーボ信号の話が素直につながります。

サーボ・DC・ステッピングモーターの違い

できることの違い

この3種類は、見た目がどれも「回る部品」なので混同されがちですが、実際には何を指定するモーターなのかが違います。
ここを先に分けて考えると、用途選びで迷いにくくなります。

まず、この記事でいうサーボモーターは、Arduino工作でよく使うRCサーボを指します。
RCサーボは「何度の位置へ動かすか」を指定するモーターです。
たとえば 0°、90°、180°のように角度を命令して、そこへ軸を持っていく使い方が中心になります。
ロボットアームの関節、首振り、車の前輪の舵取りのように、決まった角度へ止めたい場面で力を発揮します。
ワークショップでも「サーボは回るモーターだから連続回転できる」と思われがちですが、一般的なRCサーボは連続回転用ではありません。
この誤解を先にほどいておくと、部品選びの失敗が減ります。

DCモーターは発想が少し違って、主役になるのは速度と方向です。
前へ回す、逆転させる、速く回す、ゆっくり回す、といった制御に向いています。
車輪を回すロボットカー、送風ファン、ベルト搬送のように、回り続けること自体が仕事の用途ではDCモーターが素直です。
一方で、角度を90°で止める、10mmだけ送るといった位置決めは、そのままでは苦手です。
エンコーダを追加して閉ループ制御にすると位置や速度の精度を上げられますが、入門段階では構成が一段増えます。

ステッピングモーターは、何ステップ動かすかで位置を作る方式です。
代表的なものでは1回転が200ステップ、つまり1ステップあたり1.8°です。
さらにA4988なら最大1/16、DRV8825なら最大1/32のマイクロステップが使えるので、細かく刻んだ動きも作れます。
たとえば1.8°のモーターを1/16マイクロステップで動かすと、1回転は3,200分割になり、1ステップあたり約0.1125°まで刻めます。
3Dプリンタや小型CNCの送り機構でよく使われるのは、この「回した量をそのまま位置に変えやすい」性質があるからです。
反面、急に加速させたり負荷が重すぎたりすると脱調します。
動いているように見えて途中でコマが抜け、位置だけずれていく感覚で、これがステッピング特有のつまずきポイントです。

得意分野を一言で整理すると、角度ならサーボ、回し続けるならDC、決まった量だけ送るならステッピングです。
何を制御したいかを言葉にすると、選ぶべき種類がほぼ決まります。

必要部品と信号の違い

動かし方の違いは、そのまま必要部品とArduinoから出す信号の違いにつながります。ここが分かると、配線図を見たときの理解が一気に進みます。

RCサーボはホビー用途では内部に制御回路とドライバを持っているので、Arduino側から見ると比較的シンプルです。
基本は信号線、電源、GNDの3本で、Arduinoはサーボ信号を出して角度を伝えます。
制御周期は20ms、つまり50Hz系で扱うのが基本です。
『Arduino』公式のサーボ解説でもこの考え方で説明されています。
信号はシンプルですが、電源は別問題です。
小型のSG90級でも止められた状態では電流が大きく跳ねるので、サーボが複数台になるとUSB給電だけでは不安定になりやすいんですよね。
2自由度や3自由度の小型アームを組む段階で、信号は問題ないのに電源だけで挙動が乱れる、というのは初心者がぶつかりやすい壁です。

DCモーターは、ArduinoからPWMで速度、DIRで方向を指示する構成が基本です。
ただしモーターを直接つなぐのではなく、間にHブリッジドライバを入れます。
『Arduino』のMotor Shield Rev3はこの代表例で、https://docs.arduino.cc/tutorials/motor-shield-rev3/msr3-controlling-dc-motorを見ると、Arduinoが制御線を出し、モーター電流は外部電源とドライバ側で受け持つ形になっていることが分かります。DCモーターは連続回転が本業なので構造は分かりやすいです。ただし低いPWMでは回り始めず、ある程度のデューティ比で急に回転が立ち上がることがあります。ブレッドボードで試すと「プログラムの数値は少ししか変えていないのに、見た目の回り方は急に変わる」と感じやすい部分です。

ステッピングモーターはさらに役割分担がはっきりしていて、Arduinoは主にSTEPとDIRを出し、実際のコイル駆動はA4988』DRV8825TB6600などの専用ドライバが受け持ちます。
配線はサーボより多く、DCモーターよりも設定項目が増えます。
『Arduino』公式のステッパー解説では、ユニポーラとバイポーラで回路が違うこと、外部電源が前提になることが整理されています。
A4988は最大1/16、DRV8825は最大1/32のマイクロステップに対応するので、滑らかさや分解能を上げたいときに有利です。
ただしその分、必要なSTEPパルス数も増えます。
送り機構で細かく刻めるのは魅力ですが、配線だけでなく電流制限の調整も絡むので、DCモーターより一歩進んだ入門向けという位置づけです。

比較表

用途ごとの差を一気に見たいなら、次の表で整理すると把握しやすくなります。

項目RCサーボモーターブラシ付きDCモーターステッピングモーター
主な制御対象角度速度・方向ステップ位置・回転量
連続回転通常は不可
基本配線信号・電源・GNDモーター電源+Hブリッジ+制御線ドライバ+モーター+STEP/DIR
Arduino側の主な信号サーボ信号(50Hz系)PWM+方向信号STEP+DIR
追加ドライバホビー用は内蔵必須必須
得意用途ロボットアーム、首振り、舵取り車輪駆動、ファン、搬送送り機構、位置決め、定量移動
苦手な用途長時間の連続回転角度指定の位置決め急加速、高速回転、過負荷状態
初心者難易度低い中〜やや高い
主な注意点電源が弱いと不安定になるHブリッジが必要、発熱を見る電流制限、脱調、外部電源が前提

この表で注目すべき点は、単に「どれが高性能か」ではなく「何を指定したいか」を基準に選ぶことです。用途を言葉で書き出すと、候補が自然に絞れます。

TIP

「止めたい位置」が主役ならサーボかステッピング、「回り続けること」が主役ならDCモーター、と読むと表の意味がつかみやすくなります。

初心者の選び方

初めて選ぶときは、性能表よりも作りたい動きの文章化が効きます。
「90°だけ向きを変えたい」「前後に走らせたい」「1回転の何分の1だけ送って止めたい」と言い換えると、候補が自然に絞れます。

角度を決めて止めたいなら、最初の1台はRCサーボが素直です。
配線は3本で理解しやすく、ライブラリも豊富なので、首振り台や簡単なアームから入りやすい構成です。
授業でも最初に動作の違いを体感してもらうなら、サーボがいちばん説明しやすいです。
命令と動きの対応が目で追いやすく、「90°へ動かす」という結果がそのまま見えるからです。

車輪を回す、ファンを回す、ベルトを回すならDCモーターです。
速度変更や正逆転の考え方を学ぶには向いていますが、Hブリッジの理解が必要になるので、LEDやサーボの次に触る題材としてちょうどよい位置にあります。
ロボットカーの駆動輪を作りたい人は、サーボよりこちらが本命になります。

決まった量だけ送る、送りネジを回す、一定ステップで位置を合わせるならステッピングモーターが合います。
3Dプリンタや小型CNCの文脈でよく出てくるのはこのためです。
ただ、配線、ドライバ設定、電流制限、脱調の感覚まで含めて覚えることが増えるので、最初の1台として選ぶなら「位置決めをやりたい理由がはっきりしている場合」に向いています。
逆に言うと、その理由があるならサーボやDCでは代わりにくい領域です。

判断フローとしては、角度ならサーボ、回転ならDC、送り量や位置決めならステッピングで考えるのが基本です。
迷ったときに「連続回転するかどうか」だけで選ぶと、サーボの種類や用途を誤解しやすいので、そこより先に制御対象が角度か、速度・方向か、ステップ位置かを見ると判断がぶれません。

関連記事Arduinoプログラミング基礎|変数・関数・制御構文入門Lチカまでは動いたのに、サンプルコードを開くと急に意味がつながらなくなる——という初心者向けのガイドです。この記事ではまず setup() と loop() を軸に、変数・関数・if/for/while/switch を LED、ボタン、アナログ入力の動きと結びつけて整理します。

サーボモーターをArduinoで動かす方法

必要な部品

ここでは、ホビー用のRCサーボとして定番のSG90級を『Arduino』で動かす最小構成を扱います。
RCサーボの制御対象は角度で、DCモーターのような速度・方向、ステッピングモーターのようなステップ位置を主役にする方式とは役割が違います。
たとえばロボットアームの関節、センサーの首振り、前輪の舵取りのように、「この角度まで動いて止まる」動きが欲しい場面で相性が合います。
反対に、車輪を回し続ける駆動輪やファンのような連続回転の仕事は苦手です。
3種類の中で最初の1台を選ぶなら、角度を指定して止めたいならサーボ、という基準でほぼ迷いません。

必要になるのは、『Arduino UNO』系のボード、本体サーボ1個、安定した外部5V電源、ジャンパーワイヤーです。
サーボは3線で、一般的な配色では茶または黒がGND、赤が+5V、橙または黄が信号です。
ホビーサーボはドライバ回路を内蔵しているので、DCモーターのように別途Hブリッジを用意しなくてよいのが入門向けとして強いところです。Arduino公式のServo Motor Basicsでも、サーボは信号線で位置を指示する構成として整理されています。

電源まわりは部品表の中でも見落としやすいポイントです。
SG90 程度の小型サーボでも無負荷で約100〜200mA、ストール時に数百mAに達するという報告例がありますが、これはメーカーや個体差、負荷条件で大きく変わります。
ここで示したのは代表例であることを明記し、実運用では使用するサーボのデータシート(メーカー仕様)を必ず確認してください。
複数台を並列に使うときは合算電流を見積もり、PSE 等適合のある外部電源を選ぶことを推奨します。

配線

配線はシンプルです。
信号線を『Arduino』のデジタルピンに入れ、電源は外部5Vから与えます。
今回の例では、信号をD9に接続します。
サーボの赤線は外部5V電源のプラス、茶または黒線は外部電源のマイナスへつなぎ、その外部電源のマイナスと『Arduino』のGNDを必ずつなげてGNDを共通化します。

文章で配線図にすると、次の関係です。

  • サーボ信号線(橙/黄) → 『Arduino』の D9
  • サーボ電源線(赤) → 外部5V電源の +
  • サーボGND線(茶/黒) → 外部5V電源の -
  • 『Arduino』GND → 外部5V電源の -

この配線で大切なのは、サーボの電力を『Arduino』基板から取らないことです。
『Arduino』はあくまで信号を出す役で、サーボを動かす電流は外部5V電源が担当します。
ワークショップでも、ここを省いてUSBだけでつないだ結果、書き込み直後や急に負荷がかかった瞬間だけ不安定になるケースがよく出ます。
特にブレッドボード上で細いジャンパーワイヤーばかりにすると、電源ラインの抵抗が積み重なって電圧が落ちやすくなります。
電源とGNDの配線は、信号線より一段意識して太く短くすると挙動が落ち着きます。

WARNING

サーボが「少し動くが止まらない」「反応が飛ぶ」「たまに基板が再起動する」などの症状を示す場合は、まず信号よりも外部5V電源と GND 共通の確認を行ってください。
電源が原因のトラブルは見落としやすく、挙動が不安定になる代表例です。
サーボが「少し動くが止まらない」「反応が飛ぶ」「たまに基板が再起動する」という症状は、信号の書き方より先に、外部5V電源とGND共通の2点を見ると切り分けが進みます。

{{product:2}}

サンプルコード

RCサーボは、おおむね20ms周期(50Hz)の信号で角度を指示します。
『Arduino』ではServoライブラリを使うと、この周期生成を自前で書かずに扱えます。
基本は attach() でピンを関連付けて、write() で角度を指定する流れです。

#include <Servo.h>

Servo myServo;

void setup() {
  myServo.attach(9);
}

void loop() {
  myServo.write(0);
  delay(1000);

  myServo.write(90);
  delay(1000);

  myServo.write(180);
  delay(1000);
}

このコードでは、D9につないだサーボが0度、90度、180度へ順番に移動します。
命令した角度へ軸を持っていくのがサーボの役目なので、ここでも制御対象はあくまで角度です。
もし「前へ回す・逆転させる・回転数を上げ下げする」が主役ならDCモーター、「何ステップ進める」が主役ならステッピングモーターの担当になります。
コードの見た目が短いぶん、用途の違いがかえってはっきり見えます。

『Arduino UNO R4』でもServoライブラリが動作する例はありますが、互換性はボードパッケージやライブラリのバージョンに左右されます。
ビルド時に互換性エラーが出る場合の対処例を示します。

  • まずボードマネージャで UNO R4 用ボードパッケージを最新に更新する。
  • 公式の互換性リストや GitHub(例: uno-r4-library-compatibility)を参照して、問題が報告されているライブラリのワークアラウンドを確認する。
  • もし Servo ライブラリが使えない場合は、回避策として writeMicroseconds() による信号生成や、R4 に対応済みのフォーク版ライブラリを導入する方法があります。公式リファレンス公式リファレンスや該当リポジトリを参照して、環境に合わせた設定を行ってください。

動作確認とよくある落とし穴

動作確認では、まずサーボ単体を軽い負荷で動かし、0度、90度、180度にきちんと止まるかを見ます。
この段階で軸が細かく震える、到達したあとにぶるぶる鳴く、角度がときどき飛ぶといった現象があれば、コードより先に配線と電源を疑うのが近道です。
サーボは内部で位置を保とうとするので、電源が弱いと指令そのものは正しくても保持中に不安定になります。

初心者がぶつかりやすい落とし穴は、サーボの「3線で済む」という見た目の簡単さに引っ張られて、電源まで簡単だと思ってしまう点です。
SG90級は小さいので油断しがちですが、ストール時には数百mA流れます。
筆者の経験では、USB給電だけでArduino IDEから書き込んだ直後にサーボが動き、その瞬間に電圧が落ちてボードが再起動する症状が典型例です。
シリアルモニタが一瞬切れたり、アップロードは通るのに最初の動作だけ失敗したりするなら、このパターンを疑う価値があります。
対処はシンプルで、十分な電流を出せる外部5V電源を使うこと、GNDを共通にすること、電源ラインを細い配線に任せきりにしないことです。

それでもジッタが残るときは、サーボ近くの5VとGNDの間に大容量の電解コンデンサを入れると落ち着く場面があります。
起動時や急な負荷変動で電圧が沈むのを和らげるためです。
サーボは角度制御の入門としてとても扱いやすい反面、安定して見えるかどうかは電源設計で差が出ます。
逆にいえば、ここを押さえると「角度を決めて止める仕事」は3種類の中で最も取り組みやすい分野です。

DCモーターをArduinoで制御する方法

DCモーターは、3種類の中では「前へ回す・後ろへ回す・速さを変える」を最短距離で試せるモーターです。
制御対象は角度ではなく速度と方向で、ロボットカーの車輪、ファン、ベルト搬送のように回り続ける仕事と相性が合います。
逆に、90°で止める、一定量だけ送る、といった位置決めはそのままでは苦手です。
そこを担当するのがサーボの角度制御や、ステッピングモーターのステップ位置制御でした。

初心者向けの選び方を先に置くと、車輪を回して走らせたいならDCモーター、決まった角度に向けたいならRCサーボ、送り量を積み上げて位置を作りたいならステッピングモーター、という切り分けがいちばん迷いません。
ワークショップでも、ロボットカーを作りたい人がサーボを見て「これでタイヤも回せますか」と迷う場面がありますが、用途を文章に直すと選択ははっきりします。
ずっと回り続けること自体が仕事なら、まずDCモーターから入るのが素直です。

必要な部品

DCモーターを『Arduino』で動かすときは、モーター本体に加えてHブリッジドライバが必要です。
ここが。
Hブリッジは、モーターの両端に加える電圧の向きを切り替えて正転・逆転を作る役目を持ちます。
代表例がL298NやL298Pで、基本形はIN1/IN2で方向を決め、ENA(Enable)へPWMを入れて速度を変える構成です。
『Arduino』側はPWMと方向信号を出すだけで済み、重い電流はドライバとモーター用電源が受け持ちます。

最小構成なら、部品は『Arduino UNO』系ボード、ブラシ付きDCモーター1個、L298Nモジュール、モーター用外部電源、ジャンパーワイヤーです。
『Arduino UNO R4』でも考え方は同じで、デジタルI/O 14本、PWM対応ピン 6本という枠の中で組めます。
1モーターだけならピン消費は軽く、学習用にも扱いやすい構成です。

Arduino Motor Shield Rev3も使いどころがあります。
こちらはL298Pベースなので、ブレッドボード上で配線をばらすより、シールドを重ねて短時間で試作したいときに向いています。
『Arduino』公式のMotor Shield Rev3仕様では外部電源は7〜12Vが案内されていて、9Vを超える条件では基板側の電源を分ける構成が安心です。
公式チュートリアルでもDCモーター制御の配線と外部電源の考え方が整理されています。

得意用途と苦手な用途も、部品選びと一緒に押さえておくと混乱が減ります。
DCモーターは車輪駆動、送風、ポンプ、ローラーのような連続回転に向きます。
一方で、角度指定や再現性の高い停止位置を求める用途では、モーター単体では答えになりません。
そこにエンコーダやPID制御を足すと世界が変わりますが、最初の1台としては「速度と方向を変える担当」と割り切ると理解が進みます。

配線

L298Nを使うなら、まずは1モーター分だけを確実に動かす配線に絞るとつまずきません。
よく使う例として、ENAをD5、IN1をD7、IN2をD8へつなぎます。
D5はPWM対応ピンなので、analogWrite() でデューティを変えて速度を調整できます。
モーター電源はたとえば7〜12VをL298N側へ入れ、GNDは『Arduino』と共通にします。
ここが抜けると、方向信号もPWMも正しく出しているのに動作が不安定になります。

文章で配線図にすると、関係は次の通りです。

  • L298Nの ENA → 『Arduino』の D5
  • L298Nの IN1 → 『Arduino』の D7
  • L298Nの IN2 → 『Arduino』の D8
  • DCモーターの2端子 → L298Nのモーター出力端子
  • モーター用外部電源のプラス(例: 7〜12V) → L298Nの VIN
  • モーター用外部電源のマイナス → L298Nの GND
  • 『Arduino』の GND → L298Nの GND

HowToMechatronicsのL298N解説でも、Hブリッジの動作とGND共通の必要性が丁寧に説明されています。
配線の見た目は単純ですが、初心者がよく間違えるのは、モーター電源をつないだのにGNDを共有していないケースです。
信号の基準がそろっていないため、コードが正しくても結果が安定しません。

筆者はロボットカーの試作で、モーター側の配線は合っているのに「たまに動く」「向きが読めない」という状態を何度も見てきました。
原因をたどると、たいていはGND共通の抜けか、電源ラインの接触不良です。
DCモーターはサーボ以上に“回れば正解”に見えやすいぶん、たまたま動いた状態で先へ進んでしまいがちです。
最初の段階では、正転、逆転、停止の3つが毎回同じように再現するかを見たほうが切り分けが早くなります。

{{product:2}}

サンプルコード

最小コードでは、方向ピン2本を切り替えて回転方向を決め、analogWrite(D5, duty) で速度を変えます。
これだけで、DCモーターの基本である方向と速度の制御をひと通り体験できます。

const int ENA = 5;   // PWM
const int IN1 = 7;
const int IN2 = 8;

void setup() {
  pinMode(ENA, OUTPUT);
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
}

void loop() {
  // 正転
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  analogWrite(ENA, 180);
  delay(2000);

  // 停止
  analogWrite(ENA, 0);
  delay(1000);

  // 逆転
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, HIGH);
  analogWrite(ENA, 180);
  delay(2000);

  // 停止
  analogWrite(ENA, 0);
  delay(1000);
}

速度を変えたいときは、180 の部分を小さくしたり大きくしたりします。
方向は IN1/HIGH, IN2/LOWIN1/LOW, IN2/HIGH の入れ替えです。
ここで見えてくるのが、サーボやステッピングモーターとの役割の違いです。
サーボは角度、ステッピングモーターはステップ位置を命令しますが、DCモーターでは「どちら向きに、どれくらいの強さで回すか」が中心になります。
『Arduino』公式のMotor Shield Rev3チュートリアルでも、DCモーター制御はこの考え方で整理されています。

シールドを使う場合も内部で行っていることは同じで、方向制御と PWM 制御を分担しているだけです。
コードを読むときは、PWM は「速さ」、IN1/IN2 は「向き」と結び付けて覚えると迷いません。
『Arduino』公式のMotor Shield Rev3チュートリアルでも、DCモーター制御はこの考え方で整理されています。
シールドを使う場合も、内部でやっていることは同じで、方向制御とPWM制御を分担しているだけです。
コードを読むときは、PWMは速さ、IN1/IN2は向きと結び付けて覚えると混乱しません。

低PWM・発熱の対処

DCモーターで最初につまずきやすいのが、PWMを低くすると回らない現象です。
これは故障ではなく、静止摩擦を越えるだけの力が足りないためです。
筆者がロボットカーで試したときも、デューティ30%では無反応なのに、40%へ上げた瞬間に急に回り出すことがありました。
低速でじわっと動かしたいつもりでも、実際には「回る最低ライン」が先に立ちはだかります。

そこで効くのが、始動時だけ高めのPWMを入れて、回り出したら目標値まで下げる方法です。
たとえば最初の数百ミリ秒だけ少し高いデューティを与え、その後に狙いの低速へ落とすと、停止状態からの立ち上がりが安定します。
筆者はロボットカーの低速発進でこの方法をよく使います。
静止摩擦を越える瞬間だけ背中を押して、その後は必要以上に速くしない考え方です。
同じ30%でも、最初から30%を当て続けるのと、一度高めで起こしてから30%に戻すのでは結果が変わります。

発熱も見逃せない。
L298NやL298Pは古典的で扱いやすい一方、電圧降下が大きめで、そのぶんドライバ自体が熱を持ちます。
モーターには届く電圧が目減りし、ドライバには熱として残るので、負荷をかけて長く回すほど温度が上がります。
筆者も夏場にL298Nモジュールをロボットカーへ積んで連続走行させたとき、しばらくすると出力が鈍り、サーマルシャットダウン気味の挙動になったことがあります。
そのときはヒートシンクの密着を見直し、風を当て、デューティの上限を少し下げることで落ち着きました。
学習用途では十分便利ですが、高電流で長時間回す担当としては無理をさせないほうが安定します。

NOTE

低速で動かしたいときに止まる場合は、始動時だけ短時間高めの PWM を入れて回転を立ち上げ、その後で目標の低速へ戻す方法が効果的です。
発熱対策が必要なら MOSFET 系ドライバへの移行を検討してください。
低速で動かしたいのに止まったままなら、PWM値を少しずつ上げるより、始動だけ高めにしてから下げるほうが結果が出ます。
発熱が増える条件では、放熱を足すか、MOSFET系ドライバへ切り替えると挙動が整います。

もし用途が最初から長時間運転や高電流寄りなら、L298系にこだわらずMOSFET系ドライバを選んだほうが素直な場面もあります。
入門で学ぶにはL298Nは仕組みが見えやすいのですが、実機で速度が伸びない、ドライバが熱くなる、電池の減りが早い、といった壁に当たったときは、回路方式そのものが原因であることがあります。
そういう意味でも、初心者向けの選び方は「まず動作原理を学ぶならL298N、実用品寄りの効率を求めるならMOSFET系」と整理しておくと迷いが減ります。

関連記事Arduinoセンサーの使い方|温度・距離・光入門Arduino UNOでセンサーを始めるなら、まずは「値がちゃんと変わる感覚」をつかむのが近道です。この記事では温度ならLM35DS18B20、距離なら超音波・IR・VL53L0X、光ならLDRを横断しながら、A0・A4・A5・Dピンの配線、必要ライブラリ、

ステッピングモーターをArduinoで制御する方法

必要な部品

ステッピングモーターは、サーボのように信号線1本で完結せず、モーター本体とドライバを分けて考えるのが出発点です。
入門でまず押さえたいのは、ユニポーラとバイポーラの違いです。
配線の考え方は『Arduino』公式のステッピングモーター解説でも整理されています(『Arduino』公式: Stepper Motor Configurations
現場ではどちらも見かけますが、これから始めるならバイポーラの4線モーターとA4988またはDRV8825の組み合わせが理解しやすく、部品もそろえやすいです)。

図にすると、違いはこう捉えると混乱しません。

方式配線イメージ特徴
ユニポーラコイルにセンタータップあり駆動回路の考え方は比較的単純だが、入門向けモジュールの定番はやや限られる
バイポーラコイルAとコイルBの2相を反転駆動A4988DRV8825のSTEP/DIR制御と相性がよく、入門で扱いやすい

バイポーラの4線モーターでは、コイルAの2本とコイルBの2本をドライバへつなぎ、Arduino側はSTEPとDIRの2本で主に指示を出します。
ここが。
DCモーターのようにPWMで速度を作るというより、「何パルス進めるか」で位置を作る感覚になります。

モーター本体はNEMA17サイズの4線タイプが定番です。
代表的なステップ角は1.8°で、1回転あたり200stepです。
この数字が位置決めの基準になります。
さらにマイクロステップを使うと1ステップを細かく分割できます。
A4988は最大1/16、DRV8825は最大1/32まで対応します。https://www.makerguides.com/a4988-stepper-motor-driver-arduino-tutorial/やhttps://www.makerguides.com/drv8825-stepper-motor-driver-arduino-tutorial/でもこの差がまとまっています。たとえば1.8°のモーターを1/16マイクロステップで動かすと、1回転は3,200分割になり、1ステップあたり約0.1125°まで刻めます。 代表的なステップ角は1.8°(200 step/rev、NEMA17など)がよく使われます。
マイクロステップは分解能を上げる代わりに必要パルス数が増えるトレードオフがあり、A4988は最大1/16、DRV8825は最大1/32が一般的です。
必要部品の最小構成は、Arduino本体、バイポーラ4線のステッピングモーター(例: NEMA17)、ドライバ(A4988またはDRV8825)、そしてモーター用の外部電源です。
外部電源は必須で、Arduinoの5Vから給電しないでください。
6. 外部電源の GND と Arduino の GND は必ず共通にする

7. モーターの 4 本線は A1/A2, B1/B2 の組で接続する(テスターで組を確認してから差し込む)

サンプルコード

最小コードは、DIRを決めてSTEPへパルスを送るだけです。
1パルスで1ステップ進み、マイクロステップ設定時はその分だけ細かく刻みます。
仕組みが見えやすいので、まずはライブラリなしで動かすと理解が進みます。

const int DIR_PIN  = 2;
const int STEP_PIN = 3;

void setup() {
  pinMode(DIR_PIN, OUTPUT);
  pinMode(STEP_PIN, OUTPUT);

  digitalWrite(DIR_PIN, HIGH);  // 回転方向
}

void loop() {
  for (int i = 0; i < 200; i++) {   // 1.8°モーターなら200stepで1回転
    digitalWrite(STEP_PIN, HIGH);
    delayMicroseconds(5); // 微小遅延
    digitalWrite(STEP_PIN, LOW);
    delayMicroseconds(5); // 安定化待ち
  }

  delay(1000);

  digitalWrite(DIR_PIN, LOW);   // 逆方向へ切り替え

  for (int i = 0; i < 200; i++) {
    digitalWrite(STEP_PIN, HIGH);
    delayMicroseconds(5); // ノイズ抑制
    digitalWrite(STEP_PIN, LOW);
    delayMicroseconds(5); // タイミング調整
  }

  delay(1000);

  digitalWrite(DIR_PIN, HIGH);
}

このコードでは200パルスで1回転しています。
対象が1.8°、つまり200step/revのモーターだからです。
MS1〜MS3で1/16マイクロステップにすると、同じ1回転に必要なパルス数は3,200へ増えます。
分解能は上がりますが、同じ回転速度を出すにはそのぶん多くのパルスを送る必要があります。

STEPパルスにも注意が必要です。
目安としてA4988は最低約1µs、DRV8825は約1.9µsのSTEPパルス幅が求められる場合があり、実際の環境では安全側に数µsのマージンを取っておくと安定します。
最初から極限値を攻めるよりも、上のコードのように余裕を持ったパルス幅で動作確認し、問題がなければ徐々に短く詰めていく手順をおすすめします。
筆者はワークショップでも、最初は生のパルス(ライブラリを使わない形)でSTEP制御を見せます。
まずは「STEPの立ち上がりで1ステップ進む」「DIRで向きが変わる」という対応関係を目で追ってから、加減速や位置決めの話へ進むと理解が早まります。

電流制限と脱調の回避

ステッピングモーターで最初に見落とされがちなのが、電流制限設定です。
A4988もDRV8825も、Vrefを調整してモーターへ流す電流の上限を決めます。
ここを未調整のまま通電すると、ドライバがすぐ熱くなったり、モーターが唸るだけで安定しなかったりします。
筆者も試作を急いでいたとき、Vrefを触らずに通電してしまい、ドライバがすぐ高温になって慌てて電流を絞ったことがあります。
小さな基板なので油断しがちですが、ここは配線と同じくらい先に整える場所です。

設定の考え方は、まず安全側に低めから始め、負荷をかけたときにトルク不足や脱調が出るなら少しずつ上げる流れです。
いきなり高めにすると、発熱だけ増えて原因の切り分けが難しくなります。
未調整は発熱と脱調の典型的な入り口になります。

脱調は、命令したステップに実軸が追いつけなくなった状態です。
とくに急発進で起きやすく、コード上では正しく200step送っていても、実機は途中でコマを飛ばして位置がずれます。
ステッピングモーターは位置決めが得意ですが、加減速なしでいきなり高い周波数のパルスを与えると脱調しやすいという弱点があります。
動かないからといって最初からパルスを速くするのではなく、低速で確実に回る領域を見つけ、そこから加減速を入れていくほうが安定します。

TIP

マイクロステップは動きを滑らかにしますが、筆者の感覚では分解能を上げるほど「細かく静かに動く代わりに、1ステップごとの押しの強さが薄くなる」と感じます。
見た目の滑らかさとトルクは同じ方向には増えません。

この体感は実機でもはっきり出ます。
1/16や1/32にするとガクガク感は減りますが、負荷がある送り機構ではフルステップや1/8のほうが粘る場面があります。
高精度位置決めの基本は、分解能だけを見るのではなく、電流制限、外部電源、加減速、必要トルクを一緒に整えることです。
マイクロステップの数字だけで精度が決まるわけではなく、脱調せずに指令通り動ける条件まで含めて、はじめて位置決めの精度になります。

実践演習:まずはこの順で動かす

Step1:サーボ

最初の1台はSG90のようなRCサーボから入ると、命令(角度)と実際の動きの対応が視覚的に分かりやすくなります。
配線は信号線をD9、サーボの電源は外部5V供給、ArduinoのGNDと外部電源のGNDを共通にする構成で試してください(Arduino公式のServo入門でも同様の前提で説明されています)。

このステップで見たいのは、角度指定の結果が目で追えることと、電源をArduino本体から取らない理由が感覚として分かることです。
サーボは無負荷なら動いて見えても、電源が弱いと震えたり、指定角度へ届かずに細かく揺れたりします。

  • 期待される動作

    • 0°、90°、180°の指令に合わせて、サーボホーンがその位置へ移動して止まる
    • 同じ角度を再度送ったとき、余計な回転を続けず所定位置で保持する
    • USB給電だけのときより、外部5Vで安定して動く感触が得られる
  • チェックポイント

    • GNDがArduinoと外部5V電源で共通になっているか確認する
    • 外部5V電源にサーボの起動電流を受け止める余裕があるか確認する
    • サーボの電源極性を逆にしていないか

所要時間の目安は20〜30分です。
通電したままサーボのコネクタを抜き差しすると、誤配線に気づく前に基板やサーボへ無理がかかるので、この段階から電源を落として配線を触る癖をつけておくと後が安定します。

Step2:DCモーター

次はL298Nを使って、ブラシ付きDCモーターの速度と方向を分けて扱います。
配線はENAをD5、IN1をD7、IN2をD8、モーター用電源はVINへ外部電源から入れる構成です。
サーボでは1本の信号で角度を出していましたが、DCモーターではPWMで速さ、IN1とIN2で正逆転を決めるという分担になります。
ここが分かると、「モーター制御は全部同じではない」という感覚が一段はっきりします。
試す順序はまず「正転→停止→逆転」を確実に確認し、その後でENAへのPWM値を段階的に変えて回転の勢いを観察してください。
低いPWMで回らない場合は始動トルク不足が原因であることが多く、試験的に始動時だけ短時間高めのPWMを入れて回り始めたら目標値へ下げると安定しやすいです。
Arduino公式のMotor Shield Rev3チュートリアルも、モーター電源を外部にして制御線を分ける前提で同様の操作順を推奨しています。

  • 期待される動作

    • IN1とIN2の組み合わせで正転と逆転が切り替わる
    • ENAへPWMを入れると回転の勢いが段階的に変わる
    • 停止時には惰性で少し回ってから止まり、サーボのような位置保持はしない
  • チェックポイント

    • GNDがArduino、L298N、外部電源で共通になっているか確認する
    • 外部電源がモーター起動時の電流変動を受け止められるか確認する
    • モーター端子と電源端子の極性・接続先を取り違えていないか

所要時間の目安は20〜30分です。
ここでも通電中の配線抜き差しは避けます。
Hブリッジは配線ミスがあると発熱の原因が一気に見えにくくなるので、電源を落としてから1本ずつ確認する進め方のほうが切り分けが早くなります。

Step3:ステッピング

3段目はA4988またはDRV8825でステッピングモーターを動かします。
配線はDIRをD2、STEPをD3、モーター電源はVMOTへ外部電源から入れ、通電前にVrefを調整して電流制限を決める流れです。
ここでは「何度へ動かすか」でも「どの速さで回すか」でもなく、「何パルス送ったか」で位置を作る考え方に切り替わります。

まずはフルステップで200パルス送り、1回転の感覚を確認します。
代表的な1.8°のモーターなら1回転は200ステップです。
次にマイクロステップ設定を変えて、同じ1回転に必要なパルス数がどう増えるかを見ます。
A4988は最大1/16、DRV8825は最大1/32まで設定できるので、分解能の変化が目視でも分かります。
1.8°モーターを1/16にすると1回転は3,200ステップになり、1ステップあたり約0.1125°まで刻めます。
筆者はこの数字を説明するとき、ただ「細かい」と言うより、フルステップの200とマイクロステップ時の3,200を並べて見せるようにしています。
そのほうが、なぜパルス数が急に増えるのかが伝わります。

この順番にしているのは、学習者が引っかかる場所が増えていく順でもあるからです。
サーボで3本配線、DCモーターでドライバとPWM、ステッピングで電流制限とSTEP/DIRへ進むと、毎回「前の理解を少し拡張する」形になります。
いきなりステッピングから始めると、配線、Vref、マイクロステップ、脱調の切り分けが一度に来て、手を動かす前に情報量で詰まりがちです。
この並びにすると、1つ動くごとに理解が積み上がる感覚が残ります。

  • 期待される動作

    • DIRの状態で回転方向が切り替わる
    • STEPパルスの数に応じて回転量が決まる
    • マイクロステップ設定を上げると動きが細かくなり、1回転に必要なパルス数が増える
  • チェックポイント

    • GNDがArduinoとドライバ側で共通になっているか確認する
    • VMOTへ入れる外部電源に余裕があり、モーター起動時に電圧が落ち込まないか確認する
    • モーター配線の組と電源の極性を取り違えていないか確認する
    • 通電前にVrefを調整して、電流制限が未設定のままになっていないか

所要時間の目安は20〜30分です。ステッピングドライバは小型でも発熱源を内蔵しているので、配線を触る前に電源を切る手順を徹底したほうが事故が減ります。

チェックリスト

3つを続けて試すときは、毎回ゼロから考えるより、見る項目を固定したほうが迷いません。
筆者はワークショップでも、動かないときの確認順を共通化しています。
モーターの種類が変わっても、止まる原因は配線、GND共通、電源容量、極性のどこかに集まりやすいからです。

  • サーボはSG90 1個を外部5Vで動かし、信号はD9へ入れた
  • Arduino側と外部電源側のGNDを共通化した
  • DCモーターはL298Nで、ENA D5、IN1 D7、IN2 D8、VINは外部電源にした
  • 正転、停止、逆転、PWMによる速度変化を順に確認した
  • ステッピングはA4988またはDRV8825で、DIR D2、STEP D3、VMOTは外部電源にした
  • Vrefを通電前に調整した
  • マイクロステップ設定を変えたとき、必要ステップ数の変化を確認した
  • どのステップでも、通電中に配線を抜き差ししていない

この順で進めると、1回目の成功が早いサーボで手応えを作り、その直後にDCモーターでPWMと方向制御へ進み、ステッピングで位置決めの考え方へ入れます。
初心者向けの実習では、この積み上がり方がそのまま理解の順番になります。

閉ループ制御の入口:DCモーター+エンコーダ+PI/PID

開ループ vs 閉ループ

ここまで見てきた3種類のモーターを、制御の視点で並べると役割がはっきりします。
RCサーボは主な制御対象が角度、ブラシ付きDCモーターは速度と方向、ステッピングモーターはステップ位置です。
用途に置き換えると、アームの関節や舵取りはサーボ、車輪駆動やファンはDCモーター、送り機構や位置決めはステッピングという住み分けになります。

この中で、DCモーターは「ただPWMを出すだけ」の開ループ制御から入ることが多いのですが、負荷が変わると回転数がそのまま落ちます。
たとえば同じPWM値でも、無負荷では元気に回っていたのに、タイヤを床に押し当てたり、機構が少し重くなったりすると回転が鈍ります。
ここで効いてくるのが閉ループ制御です。
モーターの回転をセンサーで測り、目標との差を見ながら出力を補正します。

考え方を図にすると次の流れです。

目標値 → 制御器(PI/PID)→ モータードライバ+DCモーター → 実際の回転        ↑                ↓     比較器 ← センサー(エンコーダ)← 計測値

開ループではこの「戻り道」がありません。
閉ループではエンコーダで回転を読み取り、目標と比較して、足りなければPWMを増やし、出過ぎなら下げます。
負荷変動への強さが主眼で、ここがDCモーターを一段上の道具に変える境目です。
筆者がワークショップでよく見せるのは、回転中の車輪に指を軽く当てる場面です。
開ループだとそのまま失速するのに、閉ループでは一瞬だけ踏ん張って回転数を保とうとします。
この粘りが見えた瞬間に、受講者の表情が変わります。

モーター選びに引きつけて言うと、角度を指定して止めたい初心者はRCサーボ、まず回し続けたいならDCモーター、送り量をパルスで積み上げたいならステッピングが基本線です。
そのうえで、DCモーターにエンコーダを足して閉ループ化すると、速度制御や簡単な位置推定まで守備範囲が広がります。
反対に、最初から高精度な絶対位置決めを狙う用途では、サーボかステッピングのほうが話が早い場面も多いです。
DCモーター+エンコーダ+PI/PIDは、車輪駆動、搬送、回転数一定のファン制御のような用途で力を発揮しますが、電源、ドライバ、センサー読み取り、制御調整の4点が一度に入るので、入門直後の1台目としては少し荷が重くなります。

エンコーダ読み取り

閉ループに入るとき、追加で必要になる部品は明確です。DCモーター本体、Hブリッジのモータードライバ、エンコーダ、外部電源、Arduino本体、配線材が最小構成になります。
Arduino側はPWM出力と方向制御に加えて、エンコーダ信号を読む入力ピンが必要です。
『Arduino UNO』系なら割り込み対応ピンとしてD2とD3を使う構成が定番で、A相とB相の2相エンコーダをここへ入れておくと扱いやすくなります。

エンコーダ読み取りの基本は、パルス数から位置、単位時間あたりの増分から速度を求めることです。
たとえば一定周期ごとにカウント差分を取り、その差分を回転数の指標として使います。
A相だけ数える簡略法なら実装は軽く、速度制御の学習用として十分です。
A相とB相の位相差まで見れば回転方向も判断できるので、前進・後退のある車輪制御ではこちらが便利です。

実装の最小形は、割り込みでカウントを増減し、メインループで一定周期ごとに差分を読む方法です。考え方だけを抜き出すと、次のようになります。

volatile long encoderCount = 0;

void isrA() {
  // 割り込み: A相の立ち上がりでカウントを増やす(処理は軽量に)
  encoderCount++;
}

void setup() {
  pinMode(2, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(2), isrA, RISING);
}

void loop() {
  static long lastCount = 0;
  static unsigned long lastMs = 0;

  if (millis() - lastMs >= 100) {
    long nowCount = encoderCount;
    long diff = nowCount - lastCount;

    // diff がこの100msで増えたパルス数
    // これを速度の指標として使う

    lastCount = nowCount;
    lastMs = millis();
  }

この段階では、まず速度制御から始めるのが素直です。
位置制御まで一気に進むと、目標位置、減速タイミング、オーバーシュート、停止判定と考えることが増えます。
速度制御なら「100msで何カウント増えたか」を目標値にすればよく、PI/PIDの効き方も観察しやすくなります。
筆者の経験では、最初に「回転数をそろえる」感覚をつかんだ受講者は、その後の位置制御にも入りやすくなります。

なお、UNO系はデジタルI/Oが14本、アナログ入力が6本、PWM対応が6本あるので、小規模な閉ループ実験なら十分に組めます。
『Arduino UNO R4』でも基本の考え方は同じですが、ライブラリ互換性には差があるため、使うライブラリの対応状況は意識しておくとつまずきが減ります。

PI/PIDの基礎と実装例

PI/PIDは、目標値と計測値の差を埋めるための制御器です。
役割を短く言うと、Pは比例で偏差を詰めます。
Iは積分で残り続けるズレを消し、Dは微分で応答の形を整えるという分担です。
DCモーターの速度制御では、まずPIから入ると理解しやすく、Dはあとから足す形で十分です。
University of MichiganのDCモーター教材でも、速度制御の入口としてPI制御が扱われています。

Pだけでも、目標から外れたぶんだけ強く押し返すので、負荷が変わったときの落ち込みは減ります。
ただしPだけだと、負荷がある状態で少し低い回転数のまま落ち着くことがあります。
そこでIを足すと、残り続ける偏差を時間とともに積み上げて押し戻せます。
筆者はこの段階で、さきほどの「指を軽く当てる」実演をもう一度やります。
PIを入れたほうが、押された直後に回復する感じが明確だからです。

一方で、Dは変化の速さを見るので、急な立ち上がりを穏やかにしたり、行き過ぎを抑えたりするのに効きます。
ただしエンコーダ値には細かな揺れが乗るため、Dはノイズの影響を受けやすいです。
最初からPID全部を触るより、P → PI → 必要ならPIDの順で進めたほうが、何が効いたのかを切り分けられます。

『Arduino PID Library』を使うと、最小構成の速度制御は比較的短いコードで組めます。
ライブラリはBrett Beauregardの『Arduino-PID-Library』が定番です。
DCモーターの速度制御なら、Inputに計測した速度、Setpointに目標速度、OutputにPWM値を入れる形になります。

#include <PID_v1.h>

const int pwmPin = 5;
const int in1Pin = 7;
const int in2Pin = 8;

volatile long encoderCount = 0;

double Input = 0;
double Output = 0;
double Setpoint = 50;  // 100msあたりの目標カウント数

double Kp = 2.0;
double Ki = 5.0;
double Kd = 0.0;

PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);

void isrA() {
  encoderCount++;
}

void setup() {
  pinMode(pwmPin, OUTPUT);
  pinMode(in1Pin, OUTPUT);
  pinMode(in2Pin, OUTPUT);
  pinMode(2, INPUT_PULLUP);

  digitalWrite(in1Pin, HIGH);
  digitalWrite(in2Pin, LOW);

  attachInterrupt(digitalPinToInterrupt(2), isrA, RISING);

  myPID.SetOutputLimits(0, 255);
  myPID.SetMode(AUTOMATIC);
}

void loop() {
  static long lastCount = 0;
  static unsigned long lastMs = 0;

  if (millis() - lastMs >= 100) {
    long nowCount = encoderCount;
    Input = nowCount - lastCount;

    myPID.Compute();
    analogWrite(pwmPin, (int)Output);

    lastCount = nowCount;
    lastMs = millis();
  }

このコードの学習ポイントは、速度そのものを厳密なrpmに換算しなくても、まずは一定周期あたりのカウント数で閉ループを体験できることです。
思ったより回転が遅いときはOutputが上がり、速すぎると下がる。
この一往復が見えれば、閉ループの骨格はつかめています。
そのあとで、エンコーダのパルス数と計測周期から回転数へ換算する流れに進むと理解がつながります。

初心者向けの選び方としては、3種類のモーターの中で「負荷が変わっても回転数をそろえたい」なら、DCモーター+エンコーダ+PIが最初の候補です。
サーボのような角度命令が欲しいならRCサーボ、1パルスごとの位置送りが欲しいならステッピングを選んだほうが回り道が減ります。
DC閉ループは得意用途がはっきりしていて、車輪速度の安定化や搬送速度の維持では強い一方、サーボのような「90°へ行って止まる」を最短で実現する道具ではありません。

GitHub - br3ttb/Arduino-PID-Librarygithub.com

注意点

閉ループ制御では、ソフトウェアだけでなくハードウェアの出来がそのまま挙動に出ます。
まず見逃せないのが電源設計とドライバ選定です。
DCモーターは起動時や負荷変動時に電流が跳ねるので、Hブリッジはモーターの通常電流だけでなく、その変動も受け止められる余裕が必要です。
『Arduino』公式のMotor Shield Rev3も外部電源での駆動を前提に説明していて、公式ストアでは推奨外部電源として7〜12Vが示されています。
閉ループでは回転数を保とうとして出力を上げる場面があるので、電源が弱いと制御以前に頭打ちになります。

制御側では積分飽和にも気をつけます。
I項は便利ですが、モーターが止まっている時間や、目標に届かない状態が長いと、積分だけがたまり続けます。
その状態で急に負荷が抜けると、ため込んだぶんだけ出力が出て大きく行き過ぎます。
『Arduino PID Library』のSetOutputLimits()で出力範囲を先に決めておくのはこのためです。
必要なら目標値を急に飛ばさず、段階的に変えるだけでも挙動は整います。

配線ではエンコーダ信号のノイズ対策が効きます。
エンコーダ線はモーター電源線の近くを長く並走させると、余計なパルスを拾いやすくなります。
現場では、A相とGND、B相とGNDを寄せてツイストし、入力はINPUT_PULLUPを基本にすると、カウント飛びが減ります。
ブレッドボード上でうまく動いていたのに、配線を延ばした途端に速度が暴れるときは、制御係数より先にこの部分を疑うほうが早いです。

TIP

最初の1台は、位置制御より速度制御、PIDよりPI、2相全読みによる高機能化よりA相だけのカウントから入ると、トラブルの切り分けが一気に楽になります。

つまずき方をモーター別に整理すると、RCサーボは角度制御が得意で初心者の1台目に向きますが、長時間の連続回転は守備範囲外です。
ステッピングモーターはステップ位置の管理に向き、送り機構や位置決めでは強い反面、急加速や過負荷で脱調すると位置が静かにずれていきます。
DCモーター+エンコーダは速度・方向の制御に加えて負荷変動への強さを得られますが、必要部品が増え、調整の勘所も増えます。
筆者なら、初心者にはまずサーボで「角度」、次に開ループDCで「速度と方向」、その次にエンコーダ付きDCで「閉ループ」、位置決めが主目的ならステッピングへ進む順を勧めます。
この順番だと、それぞれのモーターが何を得意とし、どこで無理が出るのかを手触りで理解できます。

{{product:8}}

よくあるトラブルと切り分け

電源・配線系

モーター制御で最初に疑う場所は、コードより先に電源とGNDです。
ワークショップでもっとも多いのはGND共通忘れで、モーターが動かない、たまにだけ動く、センサ値がおかしい、と症状が散らばって見えるのに、原因は同じという場面を何度も見てきました。
筆者はまずテスターを当てて、Arduino側のGNDとドライバ側のGNDが本当に導通しているかを見ます。
ここがつながっていないと、PWMやSTEP、DIRの信号は出していても基準電位が一致せず、信号が相手に届きません。

サーボをつないだ瞬間にArduinoが再起動する症状も、ほとんどは電源側の問題です。
RCサーボは信号線こそ1本ですが、電源は軽く見てはいけません。
SG90級でも止められた瞬間には電流が跳ねるので、USB給電の5Vにそのままぶら下げると、サーボが動き出す瞬間だけ電圧が沈み、基板がリセットされます。
『Arduino』のServoライブラリは20ms周期の制御を前提にしていますが、信号の周期が正しくても電源が弱ければ安定動作にはつながりません。
こういうときはサーボ電源を外部5Vへ分け、ArduinoとはGNDだけ共通にする構成へ戻すと、挙動が一気に落ち着きます。
あわせて、ジャンパ線が細すぎないか、サーボコネクタが半差しになっていないか、ブレッドボードの接触が浮いていないかも見ます。
実際には、電源容量不足と接触不良が同時に出ていることも珍しくありません。

モーターだけ動かない場合も、切り分けの順番を決めると迷いません。
ArduinoのLEDが点滅していてスケッチも動いているなら、まずGND共通、次にドライバのEnableピン、次にIN1/IN2やDIRの配線順を見ます。
HブリッジではIN1とIN2の極性違いで正転逆転が入れ替わるだけでなく、組み合わせによってはブレーキ状態に入り、回らないように見えることがあります。
ステッピングドライバでもEnableが無効側に入ったままだと、STEP信号を出しても軸は沈黙したままです。
コードを書き換える前に、信号線1本ごとに「どこからどこへ行っているか」を指で追うと、意外なほど早く見つかります。

電源が熱い、あるいはモーターを回すと電圧が落ちるときは、電源そのものが悲鳴を上げています。
容量の小さいACアダプタでモーターを回している、USBからそのまま給電している、ドライバにヒートシンクがなく熱だまりを起こしている、といった条件が重なると、動くには動くのに数十秒後から不安定になる、という崩れ方になります。
Arduino Motor Shield Rev3も外部電源前提で案内されていて、Arduino StoreArduino Storeでは7〜12Vが推奨範囲です。
電源が熱くなる系統のトラブルは、ソフトの修正では止まりません。
触って熱い部品があるなら、その部品に無理をさせていると考えたほうが早いです)。

TIP

モーターが絡む不具合は、最初の3分でGND導通、電源電圧、コネクタの差し込みを見切るだけで、遠回りがぐっと減ります。

信号・設定系

DCモーターが低PWMで回らないのは、故障ではなく始動トルク不足であることが多いです。
止まっている状態から回り始めるには、回転中より大きい力が必要です。
そのため、analogWrite()の値を低くしたままでは唸るだけで軸が動かず、少し高くすると急に回り出します。
こういうときは、始動時だけデューティを一時的に高くし、回転が乗ったら下げる方法が効きます。
同時に、ギアの噛み込み、タイヤの押しつけ、軸受けの渋さといった機械抵抗も見ます。
電源電圧が足りず、そもそも必要な始動エネルギーに届いていないケースもあります。
PWMの値だけをいじり続けるより、まず「手で回したときに軽く回るか」「電源が落ち込んでいないか」を切り分けたほうが前へ進みます。

ステッピングモーターが脱調する場合は、速度設定だけでなく立ち上げ方を疑います。
1.8°の一般的なステッピングモーターは1回転200ステップで、A4988なら最大1/16、DRV8825なら最大1/32のマイクロステップが使えます。
分解能を上げるほど必要なパルス数も増えるので、いきなり高速で回そうとすると、モーターが追いつけず位置だけずれていきます。
加減速を入れてゆっくり立ち上げる、ドライバの電流制限をモーター定格に合わせる、STEPパルス幅を十分に取る、供給電圧や配線の電圧降下を見直す、という順で整えると改善することが多いです。
Makerguidesが整理している値では、A4988の最小STEPパルス幅は1µs、DRV8825は1.9µsですDRV8825は1.9µsです
短すぎるパルスを高速で連打していると、ソフト上では送ったつもりでも、ドライバ側では取りこぼします)。

TB6600系のドライバでNEMA17を回す場面でも、電流設定の食い違いは見逃せません。
たとえばモーターが1.2A級なのに、TB6600モジュール側を高い電流設定のまま使うと、モーター本体より先にドライバが熱を持ち、長めの運転で不安定になります。
逆に電流が低すぎると、加速時にトルクが足りず脱調へつながります。
DIPスイッチ設定を合わせたつもりでも、一段ずれていたというのは現場ではよくある話です。
ステッピングの不具合は「ソフトのバグ」に見えて、実際は電流設定と加速プロファイルの組み合わせで起きていることが少なくありません。

エンコーダ値が飛ぶ、回転数が急に跳ねるといった症状は、ノイズと割り込み処理の両面で見ます。
モーター線とエンコーダ線を長く並走させると、カウントしていないはずのパルスを拾いやすくなります。
入力のプルアップが弱い配線でも、波形の立ち上がりが鈍って誤カウントを呼びます。
さらに、割り込み内で重い処理をしていたり、Serial.print()を多用してループ全体が詰まっていたりすると、取りこぼしが増えます。
筆者の経験では、制御係数をいじる前に、エンコーダ線の引き回しを変えて割り込み処理を最小限にするだけで、波形が別物のように落ち着くことがあります。

How to control a stepper motor with DRV8825 driver and Arduinomakerguides.com

ソフト・ライブラリ系

配線と電源に問題がないのに動かないときは、ライブラリとボード設定へ視点を移します。
コンパイルエラーの典型は、Servo.hの未導入、ボード設定の取り違え、使用しているライブラリが対象ボードを想定していない、の3つです。
特に『Arduino UNO R4』は従来のAVR系UNOとはアーキテクチャが異なるため、古いライブラリではそのまま通らないことがあります。
『Arduino』公式のServoライブラリ自体は公式リファレンス(https://www.arduino.cc/reference/en/libraries/servo/がありますが、手元の環境に入っている版や依存関係まで含めると、UNO R4で素直に通るものと調整が必要なものが混ざります。
スケッチは正しく見えるのに #error で止まる場合、ロジックより先にライブラリ対応状況を疑ったほうが早いです)。

アップロードエラーでは、ボード種別やポート選択のミスも定番です。
UNO R4 Minimaなのに旧UNO向け設定のまま書き込もうとして失敗する、USBケーブルが給電専用でシリアル通信が通っていない、というのは入門時に何度も起きます。
モーター制御のトラブルに見えて、実際はスケッチが基板へ入っていないだけ、ということもあります。
モーターが回らない問題は、ハードとソフトの境界で起きるので、LED点滅の最小スケッチやシリアル出力の最小確認に一度戻すと、どこから先が壊れているのかが見えます。

サーボ関連では、ライブラリのタイマ使用と他機能の競合にも注意が要ります。
サーボ信号は20ms周期のパルス生成が必要で、実装はタイマに依存します。
そのため、同じタイマ資源に依存するPWM出力や別ライブラリを同時に使うと、サーボの震えやPWMの挙動変化として表に出ることがあります。
現象だけ見るとサーボ不良に見えますが、実際にはライブラリ同士の取り合いです。
モーターだけ動かない、あるいは片方だけ変な周期になるとき、配線と電源に続く3番目の容疑者がここです。

ソフト側の切り分けでは、いきなり完成版へ戻さず、最小コードへ縮めるのが効きます。
サーボなら角度固定、DCなら一定PWM、ステッピングなら低速一定パルスまで落とし、そこから1要素ずつ戻します。
筆者はこの段階で「モーター制御の問題」ではなく「ライブラリが入っていない」「Enableをコードで無効にしていた」「ボード設定が違った」といった初歩的な原因を何度も拾ってきました。
初心者向けのトラブルほど、派手な不具合ではなく、基本の1か所が外れているだけという形で現れます。

どのモーターを選ぶべきか

用途で選ぶなら、角度を決めて動かす仕事はRCサーボ、回り続けること自体が目的ならDCモーター、高精度の送りや位置決めならステッピングモーター、そして精度を保ったまま負荷変動にも強くしたいなら閉ループDCか産業用サーボ、という整理で考えると迷いません。
筆者の現場感覚でも、小型ロボットカーはDC、カメラのパンチルトはサーボ、3DプリンタのZ軸はステッピング、という組み合わせがいちばん素直にまとまります。
部品選びで遠回りしないコツは、モーターの名前ではなく「どんな動きをさせたいか」を先に決めることです。

(続き)用途で選ぶなら、角度を決めて動かす仕事は RC サーボ、回り続けることが目的なら DC モーター、高精度の送りや位置決めならステッピングモーター、という整理で迷いが少なくなります。

Jaga seda artiklit

中村 拓也

大手メーカーで組込みシステムの開発に15年従事。Arduino・Raspberry Piを活用した自作IoTデバイスの制作実績多数。電子工作の基礎から応用まで、実務経験に基づいた解説を得意とする。