このリポジトリには、Raspberry Pi 上で H ブリッジ経由で左右のモーターを制御するための Python スクリプトが含まれています。各スクリプトは入力の取り扱いや制御ループが異なり、 用途に応じて「キーを押したときだけ短いパルスを出す」「スロープで立ち上げる」「押している間は一定速度を保持する」 「Web UI で操作する」などの動作を実現します。
- ハードウェア(必要な部品)
- ソフトウェア(必要なもの)
- 配線
- 各スクリプトの概要(比較表あり)
- クイックスタート
- 実行上の注意点
- Raspberry Pi 本体(3B/3B+ or 4)
- microSD カード(Raspberry Pi OS)
- TA7219P(または TA7291P 系)× 2(左右モーター用に各1個)モータードライバー
- DC モーター × 2(定格は使用する電源・ドライバの範囲内)
- 電源
- Raspberry Pi 用 5V/3A 以上の安定電源
- モーター用電源(単三電池ケース、または 6–12V 程度の別系統を推奨)
- 注: 実験以外では Pi の 5V からモーターへ直接給電しないでください(電圧降下・リセットの原因)
- 抵抗 3kΩ〜10kΩ × 2(各 IC の Vref→VS 間、推奨)
- バイパス用コンデンサ(推奨)
- 0.1µF セラミック × 2(各 IC の電源付近)
- 100〜470µF 電解 × 1(モーター電源系の安定化)
- ブレッドボード/ユニバーサル基板、ジャンパワイヤ一式
- オプション: モーター端子のノイズ低減用コンデンサ(0.047〜0.1µF)、ヒューズ/スイッチ、ヒートシンク
- Raspberry Pi OS(または
RPi.GPIOとvcgencmdが利用できる環境) - Python 3.8/3.9 以上(Raspberry Pi のシステム Python を想定)
- Python パッケージ:
RPi.GPIO(GPIO 制御)flask(webcars.pyの Web サーバ)flask-socketio(WebSocket 経由のコマンド送受信)eventlet(flask-socketioの非同期ワーカーとして推奨)
インストール例:
pip install RPi.GPIO flask flask-socketio eventletすべてのスクリプトは BCM ピン番号を前提としています。以下は Raspberry Pi 3B/3B+ と、左右それぞれ 1 個の TA7219P(TA7291P 系)を用いた基本的な配線例です。
- 5V(物理ピン 2 または 4)を左右両方の TA7219P の
VCC(7)とVS(8)へ供給。 - GND(物理ピン 6/9/14/20/25/30/34/39 のいずれか)を左右両方の
GND(1)に接続。 GPIO5(BCM, 物理ピン 29)→ 左 IC のIN1(5)GPIO6(BCM, 物理ピン 31)→ 左 IC のIN2(6)GPIO16(BCM, 物理ピン 36)→ 右 IC のIN1(5)GPIO26(BCM, 物理ピン 37)→ 右 IC のIN2(6)
| ピン | 役割 | 接続先 |
|---|---|---|
| 1 | GND | Raspberry Pi の GND |
| 2 | OUT1 | モーター端子 A |
| 3 | NC | 未使用 |
| 4 | Vref | 抵抗 3kΩ〜10kΩ を介して VS(8) へ(推奨)。抵抗が無い場合は最終手段として直結(不安定・発熱リスクあり)。 |
| 5 | IN1 | 左 IC: GPIO5、右 IC: GPIO16 |
| 6 | IN2 | 左 IC: GPIO6、右 IC: GPIO26 |
| 7 | VCC | Raspberry Pi の 5V |
| 8 | VS | Raspberry Pi の 5V(※ Pi から直接供給するのは実験限定で推奨されません) |
| 9 | NC | 未使用 |
| 10 | OUT2 | モーター端子 B |
- 左モーター: 左 IC の
OUT1(2)とOUT2(10)を接続。 - 右モーター: 右 IC の
OUT1(2)とOUT2(10)を接続。 - 回転方向が逆の場合は各モーターの
OUT1/OUT2を入れ替えるか、ソフト側でDIR_L/DIR_Rを-1に変更します。
Raspberry Pi 3B/3B+ (BCM)
5V ─────────┬─────────────┬──→ VCC(7) [左IC]
│ └──→ VS(8) [左IC]
│
│ ┌──→ VCC(7) [右IC]
└─────────────┴──→ VS(8) [右IC]
GND ─────────────→ GND(1) [左IC] & GND(1) [右IC](共通)
GPIO5(29) ─────────→ IN1(5) [左IC]
GPIO6(31) ─────────→ IN2(6) [左IC]
GPIO16(36) ────────→ IN1(5) [右IC]
GPIO26(37) ────────→ IN2(6) [右IC]
[左IC] OUT1(2) ──┐
├── 左モーター ── [左IC] OUT2(10)
[右IC] OUT1(2) ──┐
├── 右モーター ── [右IC] OUT2(10)
Vref(4) [左右IC] ──(3k〜10kΩ)──→ VS(8) ※抵抗が無ければ最終手段で直結
| ファイル | 入力手段 | 挙動の概要 | 主な用途 |
|---|---|---|---|
test.py |
端末の WASD キー | 押下で固定パルス出力→即停止 | 微調整/単発操作 |
test2.py |
端末の WASD キー | ランプ(スロープ)で TARGET まで上げて保持→停止 |
急発進を避けたい |
test3.py |
端末の WASD キー | 押している間は一定速度ホールド(一次遅れ追従) | 直感的な走行 |
webcars.py |
ブラウザ(WASD/ボタン) | サーバ側でホールド制御+テレメトリ送信 | 離れた場所から操作 |
-
test.py(wasd_drive_fixed)- 動作: キー入力(W/A/S/D)で短い固定パルス(
PULSE秒)を出力し、 その後すぐ停止する。単発のタップ操作に適します。 - 主なパラメータ:
DUTY(デューティ比)、PULSE(パルス長)、PWM_FREQ。 - 依存: 標準ライブラリと
RPi.GPIO。
- 動作: キー入力(W/A/S/D)で短い固定パルス(
-
test2.py(wasd_ramp)- 動作: キー入力で
TARGETまで滑らかに(RAMP_TIME)上げ、HOLD_TIME分保持してから停止する。急発進を抑えたい場面向け。 - 主なパラメータ:
TARGET,RAMP_TIME,HOLD_TIME,PWM_FREQ。 - 依存: 標準ライブラリと
RPi.GPIO。
- 動作: キー入力で
-
test3.py(wasd_hold_constant)- 動作: 押している間は目標デューティ(
TARGET)へ一次遅れ(ACC_UP/ACC_DOWN)で追従し、 一定時間入力がなければ自動的に停止する(IDLE_STOP)。 - 主なパラメータ:
TARGET,ACC_UP,ACC_DOWN,IDLE_STOP,DT。 - 端末入力は非ブロッキングで読み取る(
selectを利用)。 - 依存: 標準ライブラリと
RPi.GPIO。
- 動作: 押している間は目標デューティ(
-
webcars.py(Web UI + サーバ側 hold 制御)- 動作: Flask + Socket.IO による Web インターフェースを提供し、サーバ側で
押している間の保持ロジック(
wasd_hold_constantと同等)を実行します。 また CPU 温度や電圧降下(vcgencmd)などのテレメトリをクライアントへ送信します。 - 特徴: ブラウザのフォーカス喪失や非表示時に安全停止する仕組みあり。
- 依存:
flask,flask-socketio,eventlet,RPi.GPIO。
- 動作: Flask + Socket.IO による Web インターフェースを提供し、サーバ側で
押している間の保持ロジック(
- モーターの回転方向が逆の場合、
DIR_LとDIR_Rを-1に設定して極性補正してください。 webcars.pyのテレメトリは/usr/bin/vcgencmdを呼び出します。環境によっては利用できない場合があり、 その場合は温度取得を別の方法にフォールバックしますが、電圧関連の値はNoneになります。- キーボード制御スクリプト(
test.py,test2.py,test3.py)はローカル端末での実行を想定しており、 実行中に端末のモードを変更します。終了時に元に戻す処理がありますが、異常終了した場合は端末設定が残る可能性があります。 webcars.pyを使う場合はブラウザでhttp://<raspberry-pi-ip>:5000/にアクセスしてください。
- 依存パッケージをインストールします。
pip install RPi.GPIO flask flask-socketio eventlet- 端末でキーボード版を試す場合(ローカル実行):
python3 test.py
# または
python3 test2.py
python3 test3.py- Web UI を使う場合:
python3 webcars.py
# ブラウザで http://<RPI_IP>:5000/ を開くThis repository contains Python scripts to control left and right DC motors on a Raspberry Pi using H-bridge driver ICs. Each script differs in how it handles input and the control loop, enabling behaviors such as "short pulse while a key is pressed", "ramp-up (slew) to target", "hold constant speed while pressed", and "control via Web UI".
- Hardware (required parts)
- Software (requirements)
- Wiring
- Overview of each script (comparison)
- Quick start
- Notes and cautions
- Raspberry Pi board (3B/3B+ or 4)
- microSD card with Raspberry Pi OS
- TA7219P (or TA7291P-family) x2 (one per motor)
- DC motors x2 (spec depending on your power/drivers)
- Power supplies:
- Stable 5V/3A+ for the Raspberry Pi
- Separate motor power supply (e.g., AA battery pack or 6–12V supply recommended)
- Note: Do not power motors directly from the Pi's 5V in non-experimental setups (risk of voltage drop and Pi resets)
- Resistors 3kΩ–10kΩ x2 (connect Vref → VS on each IC, recommended)
- Bypass capacitors (recommended):
- 0.1µF ceramic x2 (near each IC VCC)
- 100–470µF electrolytic x1 (motor supply stabilization)
- Breadboard/PCB, jumper wires
- Optional: motor noise suppression caps (0.047–0.1µF), fuses/switches, heatsinks
- Raspberry Pi OS (or an environment that supports
RPi.GPIOandvcgencmd) - Python 3.8/3.9+ (system Python on Pi assumed)
- Python packages:
RPi.GPIO(GPIO control)flask(forwebcars.pyweb server)flask-socketio(WebSocket command exchange)eventlet(recommended async worker forflask-socketio)
Install example:
pip install RPi.GPIO flask flask-socketio eventletAll scripts use BCM pin numbering. Below is a basic wiring example for a Raspberry Pi 3B/3B+ with a TA7219P (TA7291P-family) for each side.
Raspberry Pi side (BCM / physical pins)
- 5V (physical pin 2 or 4) → VCC(7) and VS(8) of both TA7219P ICs
- GND → GND(1) of both ICs
GPIO5(BCM, physical 29) → left ICIN1(5)GPIO6(BCM, physical 31) → left ICIN2(6)GPIO16(BCM, physical 36) → right ICIN1(5)GPIO26(BCM, physical 37) → right ICIN2(6)
TA7219P pins (same for left/right)
| Pin | Role | Connection |
|---|---|---|
| 1 | GND | Raspberry Pi GND |
| 2 | OUT1 | Motor terminal A |
| 3 | NC | Unused |
| 4 | Vref | Via 3k–10kΩ to VS(8) (recommended) |
| 5 | IN1 | GPIO (see above) |
| 6 | IN2 | GPIO (see above) |
| 7 | VCC | Raspberry Pi 5V |
| 8 | VS | Motor supply (5V when using Pi supply; avoid for non-experimental setups) |
| 9 | NC | Unused |
| 10 | OUT2 | Motor terminal B |
Motor wiring
- Left motor: connect to left IC
OUT1(2)andOUT2(10) - Right motor: connect to right IC
OUT1(2)andOUT2(10) - If rotation is reversed, swap
OUT1/OUT2or setDIR_L/DIR_Rto-1in software.
Text wiring diagram (summary)
Raspberry Pi 3B/3B+ (BCM)
5V ─────────┬─────────────┬──→ VCC(7) [Left IC]
│ └──→ VS(8) [Left IC]
│
│ ┌──→ VCC(7) [Right IC]
└─────────────┴──→ VS(8) [Right IC]
GND ─────────────→ GND(1) [Left IC] & GND(1) [Right IC] (shared)
GPIO5(29) ─────────→ IN1(5) [Left IC]
GPIO6(31) ─────────→ IN2(6) [Left IC]
GPIO16(36) ────────→ IN1(5) [Right IC]
GPIO26(37) ────────→ IN2(6) [Right IC]
[Left IC] OUT1(2) ──┐
├── Left motor ── [Left IC] OUT2(10)
[Right IC] OUT1(2) ──┐
├── Right motor ── [Right IC] OUT2(10)
Vref(4) [each IC] ──(3k–10kΩ)──→ VS(8) # If absent, direct connection is a last resort (risk: instability/heating)
| File | Input method | Behavior summary | Typical use |
|---|---|---|---|
test.py |
Terminal WASD | Short fixed pulse while pressed → immediate stop | Fine adjustments/single taps |
test2.py |
Terminal WASD | Ramp (slew) to TARGET and hold → then stop |
Avoid aggressive starts |
test3.py |
Terminal WASD | While pressed, hold constant speed with first-order lag | Intuitive driving |
webcars.py |
Browser (WASD/buttons) | Server-side hold control + telemetry | Remote control via browser |
-
test.py(wasd_drive_fixed)- Behavior: WASD keys produce a short fixed pulse (
PULSEseconds), then stop. - Parameters:
DUTY,PULSE,PWM_FREQ. - Dependencies: standard library +
RPi.GPIO.
- Behavior: WASD keys produce a short fixed pulse (
-
test2.py(wasd_ramp)- Behavior: key press ramps to
TARGEToverRAMP_TIME, holds forHOLD_TIME, then stops. - Parameters:
TARGET,RAMP_TIME,HOLD_TIME,PWM_FREQ.
- Behavior: key press ramps to
-
test3.py(wasd_hold_constant)- Behavior: While pressed, the output follows
TARGETwith first-order lag (ACC_UP/ACC_DOWN). If no input for some time, it stops (IDLE_STOP). - Parameters:
TARGET,ACC_UP,ACC_DOWN,IDLE_STOP,DT. - Uses non-blocking terminal input (
select).
- Behavior: While pressed, the output follows
-
webcars.py(Web UI + server hold control)- Behavior: Provides a Flask + Socket.IO web interface; server implements hold control logic (similar to
wasd_hold_constant) and sends telemetry (CPU temp, voltages viavcgencmd). - Note: Safety handling for browser focus loss and hidden tabs exists.
- Behavior: Provides a Flask + Socket.IO web interface; server implements hold control logic (similar to
- If a motor runs in the opposite direction, set
DIR_Land/orDIR_Rto-1to correct polarity. webcars.pytelemetry uses/usr/bin/vcgencmd. Ifvcgencmdis unavailable in your environment, temperature readings will fall back and voltage values may beNone.- Keyboard control scripts (
test.py,test2.py,test3.py) change terminal modes while running. They attempt to restore the terminal on exit, but an abnormal termination may leave the terminal in a modified state. - For
webcars.py, openhttp://<raspberry-pi-ip>:5000/in your browser after starting the server.
- Install dependencies:
pip install RPi.GPIO flask flask-socketio eventlet- Try a keyboard-driven script locally:
python3 test.py
# or
python3 test2.py
python3 test3.py- Use the Web UI:
python3 webcars.py
# then open http://<RPI_IP>:5000/ in your browser