Python × Pico 電子工作 | #13 DCモーターを回そう

今回は 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モーターを回そう

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ブレッドボードに刺せる
ロジック電源 Vcc14.5〜7VPico の VBUS(5V) 推奨
モーター電源 Vcc24.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 ブリッジの正転・逆転の電流経路図(4 つのスイッチの ON/OFF とモーターを流れる電流の向き)
H ブリッジが正転・逆転を切り替える仕組み。左の 正転(S1+S4 を ON) ではモーターを左→右に電流が流れ、右の 逆転(S2+S3 を ON) では右→左に逆向きに流れます。電流の向きが反対になると、モーターの回転方向も反対になります。
# 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 の制御パターン真理値表:

IN1IN2ENモーターの動き用途
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 ピン名前繋ぎ先役割
1EN1Pico GP4速度制御(PWM 入力)
2IN1Pico GP2方向制御 1
3OUT1モーター端子 Aモーターへ出力
4, 5GNDPico GND + 外部電源 GND共通グランド
6OUT2モーター端子 Bモーターへ出力
7IN2Pico GP3方向制御 2
8Vcc2外部電源 +(モーター用)モーター電源(高め OK)
16Vcc1Pico VBUS(5V)ロジック電源

⚠️ 電源の重要な注意

DC モーターは起動時や負荷がかかったとき 大きな突入電流 を引きます。Pico の VBUS(5V)から直接モーター電源を取ると、Pico がリセット したりUSB ケーブルが過熱 したりします。モーター電源(Vcc2)は必ず外部電源(単3×4本電池ボックス・別 USB アダプタ・モバイルバッテリーなど)を使ってください。外部電源の GND と Pico の GND は必ず接続して共通グランドを作ること。これを忘れると IN1/IN2 の HIGH 信号が L293D に正しく伝わらず、動かなかったり誤動作します。
L293D と DC モーターを Pico に接続した実体配線図
配線:L293D の IN1=GP2・IN2=GP3・EN=GP4 を Pico に、OUT1/OUT2 をモーターに接続。ロジック電源 Vcc1 は Pico の VBUS、モーター電源 Vcc2 は電池ボックス(単3×4本) から取り、GND は Pico と電池ボックスで共通にします。(実体配線図は Fritzing の部品画像をもとに作図・CC BY-SA 3.0)

ステップ1:50% の速度で 2 秒だけ正転させてみよう

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

DCモーターを 50% で 2 秒回すブロック
ブロック構成:DCモーター IN1=GP2・IN2=GP3・EN=GP4・速度50%・正転 → 2秒待つ → DCモーター停止。
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 のはず)
逆方向に回ってしまった 場合は、OUT1 と OUT2 のモーター線を入れ替えれば直ります。

ステップ2:正転 → 停止 → 逆転 → 停止を繰り返そう

DC モーターらしさを見るために 正転と逆転を交互に切り替えてみます。forever ループの中で 「正転 2 秒 → 停止 1 秒 → 逆転 2 秒 → 停止 1 秒」 の 4 段階を並べるだけ。方向プルダウン を 1 つは「正転」、もう 1 つは「逆転」にするのがポイント。後ほど演習 2 では 速度に変数を渡せる新ブロック pico_dcmotor_run_val を使いますが、ここではまず 固定速度のシンプル版 で動作を確認します。

DCモーターの正転と逆転を交互に繰り返すブロック
ブロック構成:ずっと繰り返す → 正転60% 2秒 → 停止 1秒 → 逆転60% 2秒 → 停止 1秒。方向のプルダウンで「正転 / 逆転」を選び分けるだけで電流方向が反転します。
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 について

標準の 「DCモーター」ブロック は速度を 0〜100 の 数字(リテラル) でしか指定できません(変数や計算結果を差し込めない)。今回のように 速度をセンサー値から計算したい 場合や、少しずつ加速・減速したい(ソフトスタート / ソフトストップ) 場合は、「DCモーター(速度可変)」ブロック を使います。速度欄が 白いまる(値の差し込み口) になっていて、変数ブロックや計算ブロックを挿せるのが違いです。次の演習 2 で実際に使います。

動作確認のコツ:「ウィーン、ウィーン」と低い駆動音 が聞こえながらモーターが両方向に切り替わって回ります。切り替わりの瞬間にカクッと音がする のは、回転中のモーターに逆向きの電流が流れる際の慣性によるもの。急な切り替えは 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 はぶつからない ので問題ありません。

▶ 模範解答と解説を見る

ブロックの組み合わせ例:

可変抵抗ノブで DC モーターの速度を制御するブロック
ブロック構成:ずっと繰り返す → アナログ入力 GP26 → pot → DCモーター速度 (pot × 100 ÷ 65535) 正転 → 0.05秒待つ。速度の式は 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 個でラジコンカーの左右タイヤを独立操作する戦車操縦風

可変抵抗ノブと DC モーターを Pico に接続した実体配線図
課題3-13-2 の配線:DC モーター + L293D(IN1=GP2・IN2=GP3・EN=GP4・モーター電源は電池ボックス)と可変抵抗ノブ(3V3・GP26・GND)を併用。電池ボックスの − と Pico の GND は 必ず共通グランドで接続してください。

課題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Ω) の解説を参照してください。

▶ 模範解答と解説を見る

ブロックの組み合わせ例:

超音波センサーで障害物検知してモーター停止するブロック
ブロック構成:ずっと繰り返す → 超音波距離 TRIG GP14 ECHO GP15 → dist → もし dist < 20 なら DCモーター停止、そうでなければ DCモーター正転60% → 0.2秒待つ。
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 モーターを Pico に接続した実体配線図
課題3-13-3 の配線:DC モーター + L293D(モーター電源は電池ボックス)と HC-SR04(VCC・GP14(TRIG)・GP15(ECHO)・GND)。HC-SR04 を 5V 動作で使う場合は ECHO に 1kΩ + 2kΩ の分圧抵抗(#09 で学習済み)を必ず入れてください。

まとめ

  • 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 モーターの仲間いろいろ

今回扱った ブラシ付き DC モーター(FA-130 / TT モーター)以外にも、ブラシレス DC モーター(BLDC、ドローン・電動工具)、ギアド DC モーター(減速ギア付き、ロボットアーム・自走ロボ向け)、連続回転サーボ(FS90R、#12 のサーボ改造版)、ステッピングモーター(角度精度重視・3D プリンタ向け、次回 #14 で扱う) など多彩な仲間がいます。用途に応じて選び分けるのが楽しいところです。

次の記事は #14「ステッピングモーターを動かそう」。28BYJ-48 + ULN2003 ドライバ を使って、「ステップ単位で正確に角度を刻む」 モーターを制御します。3D プリンタや CNC マシンの心臓部となる、精密制御モーターの世界へ。

トップへ戻る