今回は DC モーター を使って、「ぐるぐる回り続けるモーター」 の制御を学びます。前回 #12 のサーボモーターは 0〜180° の角度を指定して止まる モーターでしたが、DC モーターは 電気を流している間ずっと回り続ける のが特徴。ラジコンカーの車輪・扇風機・電動ドライバー・ミニ四駆 など、「位置決めはせず連続的に回したい」 場面で大活躍します。
ただし DC モーターは Pico の GPIO ピンに直接繋いでは絶対にダメ。GPIO 1 本で流せる電流は最大 16mA 程度ですが、DC モーターは 100mA〜数 A を平気で食べます。そこで 「H ブリッジドライバ」 という「弱い信号で大きな電流を ON/OFF するスイッチ IC」 を間に挟みます。今回使うのは教科書的な定番 L293D(または兄弟チップの L298N)。正転・逆転・速度制御・停止 の 4 つを 3 本の制御線(IN1・IN2・EN)で全部できる優れものです。
- DC モーターの仕組み(電磁石とブラシで連続回転)と GPIO 直結が NG な理由
- L293D(H ブリッジ IC) のピン配置と IN1/IN2/EN 3 線の意味
- H ブリッジで電流方向が反転 → 正転/逆転が切り替わる 仕組み
- EN ピンに PWM を入れて速度を 0〜100% で制御 する方法
- 速度に 変数や式 を差し込める
pico_dcmotor_run_val新ブロック - 可変抵抗・超音波センサーと組み合わせた センサー連動の自動制御
- ロジック電源・モーター電源・共通グランド の正しい接続
今回は PycoBlocks(MicroPythonモード) の 「モーター」カテゴリ にある「DCモーター」 ブロックを使います。IN1・IN2・EN の 3 ピンを指定 + 速度 0〜100% + 正転/逆転 を選ぶだけで、内部では 方向 2 線への HIGH/LOW 出力と EN ピンへの PWM が自動で組み立てられます。

DC モーターと L293D の基礎
DC モーター は内部に 電磁石(コイル)と永久磁石、ブラシ(接点) を持ち、電気を流すと電磁石の磁界が回転軸を 連続的に押し続ける ことでぐるぐる回ります。電流の向きを反対にすれば、回転方向も反対になるのがポイント。電圧を上げれば回転数が増え、電流が増えればトルク(回す力)が増えます。今回想定するのは 3〜6V 動作の小型ホビーモーター(FA-130 / RE-260 / TT モーター等)です。
L293D は 「2 個の H ブリッジ回路を 1 つの IC に詰めた」 モータードライバ IC。16 ピン DIP パッケージ でブレッドボード実装にぴったりで、1 個で 2 個の DC モーターを独立制御 できます。最大連続電流は 0.6A(瞬間 1.2A)なので、上記の小型ホビーモーターには十分。より強力なモーター(ミニ四駆改造、大型ラジコン)には L298N(最大 2A) やTB6612(より新しく効率良い) を選ぶと良いですが、ピン配置と制御方法はほぼ共通です。
| 項目 | L293D 仕様 | 備考 |
|---|---|---|
| パッケージ | 16 ピン DIP | ブレッドボードに刺せる |
| ロジック電源 Vcc1 | 4.5〜7V | Pico の VBUS(5V) 推奨 |
| モーター電源 Vcc2 | 4.5〜36V | モーターに合った外部電源 |
| 最大連続電流 | 0.6A / チャンネル | 瞬間 1.2A まで |
| 論理入力 | TTL / CMOS 互換 | 3.3V GPIO で OK |
| 動作周波数 | 最大 5kHz(PWM) | 1kHz 程度が無難 |
| 内蔵保護 | フリーホイールダイオード内蔵 | 逆起電力対策が不要 |
| チャンネル数 | 2 個(DC モーター 2 台) | L298N も同じく 2 台 |
| 価格 | 100〜300円 | 互換品多数 |
H ブリッジの仕組み:なぜ正転と逆転ができるのか
H ブリッジ とは、「4 つのスイッチを H 字型に配置した回路」。中央のモーターに対して 左上 (S1)・左下 (S2)・右上 (S3)・右下 (S4) の 4 つのスイッチを使い、「どのペアを ON にするかでモーターに流れる電流の向きを反転」 させます。L293D の中には 4 つのトランジスタ(半導体スイッチ) が入っており、外から見ると IN1・IN2 の 2 本 でこの 4 つのスイッチを賢く制御してくれます。

# H ブリッジ回路図(概念図)
#
# V+ (モーター電源)
# │
# ┌────────┼────────┐
# │ │
# S1 S3
# │ │
# ├───[ Motor ]─────┤
# │ │
# S2 S4
# │ │
# └────────┬────────┘
# │
# GND
#
# 正転: S1=ON, S4=ON → 電流: V+ → S1 → Motor(左→右) → S4 → GND
# 逆転: S3=ON, S2=ON → 電流: V+ → S3 → Motor(右→左) → S2 → GND
# 停止: 全 OFF または S2=ON+S4=ON(モーター両端を GND ショート)
# 禁止: S1+S2 同時 ON / S3+S4 同時 ON → 電源ショート!
L293D の制御パターン真理値表:
| IN1 | IN2 | EN | モーターの動き | 用途 |
|---|---|---|---|---|
| HIGH (1) | LOW (0) | PWM | 正転(速度は EN の duty 比) | 前進 |
| LOW (0) | HIGH (1) | PWM | 逆転(速度は EN の duty 比) | 後退 |
| LOW (0) | LOW (0) | 任意 | フリー停止(惰性で回転) | 自然停止 |
| HIGH (1) | HIGH (1) | 任意 | ブレーキ(即座に停止) | 急停止 |
| 任意 | 任意 | LOW (0) | 出力カット(モーターに電流流れない) | 省電力待機 |
PycoBlocks の 「DCモーター」ブロック はこのうち「正転 + 速度」 と 「逆転 + 速度」 をプルダウンで選び、「DCモーター停止」ブロック はフリー停止(IN1=IN2=LOW)を出力します。EN ピンには内部で自動的に PWM が出力 され、速度 50% なら duty_u16=32768 が送られます。
配線:L293D とモーターを Pico に繋ぐ
L293D は 16 ピン DIP なのでブレッドボードの中央溝をまたぐように差し込みます。1 番ピン(左上の半円マーク側) から反時計回りに番号が付きます。今回は DC モーター 1 台だけ繋ぐので、L293D の 左半分(1〜8 ピン) を使います。
| L293D ピン | 名前 | 繋ぎ先 | 役割 |
|---|---|---|---|
| 1 | EN1 | Pico GP4 | 速度制御(PWM 入力) |
| 2 | IN1 | Pico GP2 | 方向制御 1 |
| 3 | OUT1 | モーター端子 A | モーターへ出力 |
| 4, 5 | GND | Pico GND + 外部電源 GND | 共通グランド |
| 6 | OUT2 | モーター端子 B | モーターへ出力 |
| 7 | IN2 | Pico GP3 | 方向制御 2 |
| 8 | Vcc2 | 外部電源 +(モーター用) | モーター電源(高め OK) |
| 16 | Vcc1 | Pico VBUS(5V) | ロジック電源 |
⚠️ 電源の重要な注意

ステップ1:50% の速度で 2 秒だけ正転させてみよう
まずは 1 回だけ正転・指定時間後に停止 する最小コードです。「DCモーター ピン GP2/GP3/GP4・速度 50%・正転」 ブロックを置き、「2 秒待つ」 → 「DCモーター停止」 の順に並べるだけ。実行ボタンを押すと、モーターが 50% の速度で 2 秒間回転 → 停止 します。

from machine import Pin, PWM
import utime
Pin(2, Pin.OUT).value(1); Pin(3, Pin.OUT).value(0)
PWM(Pin(4)).duty_u16(32768)
utime.sleep(2)
Pin(2, Pin.OUT).value(0); Pin(3, Pin.OUT).value(0)
動作確認のコツ:モーターのシャフトに マスキングテープを巻いて目印 を付けると回転が見やすくなります。動かない 場合は次を順にチェック:
- 外部電源の電圧と極性(電池がへたっていないか・+−を逆に挿していないか)
- Vcc1 と Vcc2 の両方 に電源が来ているか(Vcc1=Pico VBUS、Vcc2=外部)
- 共通 GND(Pico GND と外部電源 GND が同じ列に繋がっているか)
- IN1/IN2 の極性(正転は IN1=HIGH, IN2=LOW のはず)
ステップ2:正転 → 停止 → 逆転 → 停止を繰り返そう
DC モーターらしさを見るために 正転と逆転を交互に切り替えてみます。forever ループの中で 「正転 2 秒 → 停止 1 秒 → 逆転 2 秒 → 停止 1 秒」 の 4 段階を並べるだけ。方向プルダウン を 1 つは「正転」、もう 1 つは「逆転」にするのがポイント。後ほど演習 2 では 速度に変数を渡せる新ブロック pico_dcmotor_run_val を使いますが、ここではまず 固定速度のシンプル版 で動作を確認します。

from machine import Pin, PWM
import utime
while True:
# 正転 60%
Pin(2, Pin.OUT).value(1); Pin(3, Pin.OUT).value(0)
PWM(Pin(4)).duty_u16(39321)
utime.sleep(2)
# 停止
Pin(2, Pin.OUT).value(0); Pin(3, Pin.OUT).value(0)
utime.sleep(1)
# 逆転 60%
Pin(2, Pin.OUT).value(0); Pin(3, Pin.OUT).value(1)
PWM(Pin(4)).duty_u16(39321)
utime.sleep(2)
# 停止
Pin(2, Pin.OUT).value(0); Pin(3, Pin.OUT).value(0)
utime.sleep(1)
📝 新ブロック pico_dcmotor_run_val について
動作確認のコツ:「ウィーン、ウィーン」と低い駆動音 が聞こえながらモーターが両方向に切り替わって回ります。切り替わりの瞬間にカクッと音がする のは、回転中のモーターに逆向きの電流が流れる際の慣性によるもの。急な切り替えは L293D とモーターへの負荷 になるので、実用では 「停止 → 待機 → 逆転」 の順を守ると長持ちします。停止時間を 0.5 秒に縮めてみる と、より機敏な動きになります。
演習課題
課題3-13-1:H ブリッジの真理値表と禁止パターンを整理しよう
H ブリッジの理解を 真理値表 でしっかり固めましょう。L293D の内部にある 4 つのスイッチ(S1〜S4)が IN1/IN2 でどう動くかを考えます。
問1: L293D 内部では 「IN1=HIGH → S1+S4 が ON、IN1=LOW → S1+S4 が OFF」、「IN2=HIGH → S2+S3 が ON、IN2=LOW → S2+S3 が OFF」 のように制御される。次の入力に対して、モーターはどう動くか答えよ。(a) IN1=1, IN2=0 / (b) IN1=0, IN2=1 / (c) IN1=0, IN2=0 / (d) IN1=1, IN2=1
問2: もし回路設計者が誤って 「S1 と S2 を同時に ON」(つまり H ブリッジの左側 2 つを同時に閉じる)してしまうと何が起きるか説明せよ。なぜ L293D は IN1/IN2 という 2 線で制御することでそのミスを起こせなくしているか 考えてみよ。
問3: 速度を EN ピンの PWM duty 比 で変えるのはなぜか。「電圧を直接変える方法」 ではなく PWM を使う理由を、効率と発熱の観点から説明せよ。
▶ 模範解答と解説を見る
# 問1: H ブリッジ真理値表
# (a) IN1=1, IN2=0 → 正転(S1+S4 ON、S2+S3 OFF)
# 電流: V+ → S1 → モーター(左→右) → S4 → GND
# (b) IN1=0, IN2=1 → 逆転(S2+S3 ON、S1+S4 OFF)
# 電流: V+ → S3 → モーター(右→左) → S2 → GND
# (c) IN1=0, IN2=0 → フリー停止(全スイッチ OFF)
# モーターは惰性で回転を続け、徐々に止まる
# (d) IN1=1, IN2=1 → ブレーキ(S1+S3+S4+S2 全 ON、両端ショート)
# ※ 実際の L293D では IN1+IN2 同時 HIGH はブレーキ動作(即停止)
# 問2: S1+S2 同時 ON の危険性
# H ブリッジ左側で V+ → S1 → S2 → GND の直結ショート回路が成立。
# 大電流が流れて L293D 内部のトランジスタが焼損する。
# L293D は IN1/IN2 という「2 線で 4 スイッチを制御する」設計のため、
# 同じ列の 2 個(S1+S2 や S3+S4)が同時 ON になるパターン自体を作れない。
# つまりハードウェア的に「ショートが起きないよう」設計されている。
# 問3: なぜ PWM で速度制御するのか
# 方法A(電圧を変える): 可変抵抗で電圧を 5V→3V に下げると、
# 差分の 2V × 電流 = 大きな熱が抵抗で発生(効率が悪い)。
# 方法B(PWM): 5V を高速で ON/OFF し、ON 比率で平均電力を変える。
# スイッチング素子(トランジスタ)は完全 ON または完全 OFF なので
# 発熱がほぼ起きず、効率 90% 以上を実現できる。
# DC モーターはコイル(インダクタ)を含むので、PWM の高速 ON/OFF を
# 電気的に「平均化」して滑らかな回転になる。
解説: 解説:H ブリッジは 「電池の向きを切り替える小さなスイッチ箱」 と考えると分かりやすいです。PWM 制御の効率の良さ は、家電全般(インバーターエアコン・電気自動車・スマホの充電)にも応用されている重要な技術。「電圧を下げる代わりに高速で ON/OFF して平均化」という発想が、現代のパワーエレクトロニクスの基本です。L293D の最大 PWM 周波数は 5kHz。もっと滑らか(人間の耳に聞こえないように)したいなら 20kHz 以上対応の TB6612 を選ぶと、可聴域のキーキー音が消えて静かになります。
課題3-13-2:可変抵抗ノブでモーターの速度をコントロールしよう
#05 で使った可変抵抗ノブ(ADC:GP26)を回すと、モーターの速度が連動して変わる ような直感的なコントローラを作ります。ADC 値(0〜65535)を 「× 100 ÷ 65535」 の式で 0〜100% に変換し、新ブロック 「DCモーター(速度可変)」 に差し込みます。電動ドライバーのトリガー のような感覚で、握り具合に応じて回転数を調整できます。
配線追加:DC モーター回路(GP2/GP3/GP4 + 外部電源)に加えて、可変抵抗ノブを3V3・GP26・GND(3 ピン)に繋ぎます。DC モーターのピン GP2/3/4 と GP26 はぶつからない ので問題ありません。
▶ 模範解答と解説を見る
ブロックの組み合わせ例:

py_math_op を 2 回ネストして (pot × 100) ÷ 65535 を作っています。from machine import ADC, Pin, PWM
import utime
_adc26 = ADC(26)
while True:
pot = _adc26.read_u16()
Pin(2, Pin.OUT).value(1); Pin(3, Pin.OUT).value(0)
PWM(Pin(4)).duty_u16(int(max(0, min(100, pot * 100 / 65535)) * 65535 // 100))
utime.sleep(0.05)
解説: 動作確認のコツ:ノブを左いっぱい → モーター停止、ノブを右いっぱい → フルスピード、ノブを真ん中 → 50% 速度で回ります。低速時にモーターが回らない 場合は、モーターには 「最低始動電圧」(数字でいうと 20〜30%)があるためで、これより下の duty 比では摩擦に負けて回りません。発展:
- 正逆切替を加える:ノブを中央 50% から左に回したら逆転・右に回したら正転にする。
if pot < 32768: 逆転 / else: 正転の if 文と、speed = abs(pot - 32768) × 100 / 32768の式を組み合わせる - ソフトスタート:速度を
0 → 100 を 2 秒でゆっくり上げる。for s in range(0, 101): モーター速度 s / utime.sleep(0.02) - 2 個のモーターを左右独立に制御:L293D の右半分(9〜16 ピン)にもう 1 個 DC モーターを繋ぎ、可変抵抗 2 個でラジコンカーの左右タイヤを独立操作する戦車操縦風

課題3-13-3:超音波センサーで障害物検知&自動停止を作ろう
#09 で使った超音波センサー HC-SR04 と組み合わせて、「20cm 以内に物が近づいたら自動で停止する」 安全機能付きラジコン基板を作ります。距離が 20cm 未満なら停止、それ以上なら正転 60% という条件分岐。実際にギアボックスとタイヤを付けたミニロボに搭載すれば 壁にぶつからない自走ロボット になります。
配線追加:DC モーター回路(GP2/GP3/GP4 + 外部電源)に加えて、HC-SR04 をVBUS(5V)・GP14(TRIG)・GP15(ECHO) + 分圧抵抗・GND に繋ぎます。DC モーターのピン GP2/3/4 と HC-SR04 の GP14/15 はぶつからない ので、今回は HC-SR04 の標準ピン構成のまま 使えます(#12 のサーボとは違って衝突回避不要)。HC-SR04 の 5V 動作については #09 の 分圧抵抗(1kΩ + 2kΩ) の解説を参照してください。
▶ 模範解答と解説を見る
ブロックの組み合わせ例:

from machine import Pin, PWM, time_pulse_us
import utime
_trig = Pin(14, Pin.OUT)
_echo = Pin(15, Pin.IN)
while True:
_trig.value(0); utime.sleep_us(2)
_trig.value(1); utime.sleep_us(10); _trig.value(0)
_t = time_pulse_us(_echo, 1, 30000)
dist = _t / 58 if _t > 0 else -1
if dist < 20:
Pin(2, Pin.OUT).value(0); Pin(3, Pin.OUT).value(0)
else:
Pin(2, Pin.OUT).value(1); Pin(3, Pin.OUT).value(0)
PWM(Pin(4)).duty_u16(39321)
utime.sleep(0.2)
解説: 動作確認のコツ:手を 20cm 以内に近づけるとモーターが 「ピタッ」と停止 し、離すと スルスルと回り始める 挙動を確認しましょう。0.2 秒の wait は HC-SR04 の測定間隔(最小 60ms) よりも余裕があり、反応速度と誤検知防止の両方をバランスよく実現します。発展:
- 段階的減速:
dist < 10 → 停止、dist < 30 → 30% 速度、else → 100% 速度の 3 段階制御で、近づくほどゆっくり減速する賢いロボに - 障害物を避けるロボ:障害物検知時に 逆転で後退 → 一時停止 → 正転再開 を組み合わせ、ぶつかったら自動でバックして方向転換
- LCD で速度・距離を表示:#08 の I2C LCD を組み合わせて「距離 35 cm / 速度 60%」のような状態表示を加える

まとめ
- DC モーター は電流の向きで回転方向、電流の大きさ(PWM duty 比)で速度が決まる 「連続回転モーター」。
- GPIO ピンで直接駆動は不可。L293D(または L298N / TB6612)H ブリッジ IC を間に挟む。
- L293D は IN1 + IN2 + EN の 3 ピン で 1 個の DC モーターを正転・逆転・速度制御・停止 の 4 動作で制御できる。
- 標準ブロック 「DCモーター」 は速度をリテラル指定(0〜100%)。今回追加した 「DCモーター(速度可変)」(_val 版) は変数や計算式を差し込める。
- ロジック電源(Vcc1)は VBUS(5V)、モーター電源(Vcc2)は 外部電源を別に用意。必ず Pico と外部電源の GND を共通 に接続。
- 可変抵抗(#05)・超音波センサー(#09)と組み合わせれば、速度連動コントローラ・障害物回避自走ロボ など実用的な応用が可能。
📝 DC モーターの仲間いろいろ
次の記事は #14「ステッピングモーターを動かそう」。28BYJ-48 + ULN2003 ドライバ を使って、「ステップ単位で正確に角度を刻む」 モーターを制御します。3D プリンタや CNC マシンの心臓部となる、精密制御モーターの世界へ。