倒立振子を作るためにFEETECHのFM90を買ったのですが、4個セットだったので2個余っていました。
ラズパイゼロ2Wでも使ってみたかったので、モータードライバL298Nを購入し、ゲームパッドで動かしてみました。

アマゾンで2個750円くらい。安いのですがアマプラに加入していないと送料を取られます。
L298Nは最大電圧12V、駆動電流2Aで、入力の電源により出力電圧が変わるようです。
今回はドライバの電源は単3電池4本の6Vでモーターを動かします。ラズパイの電源は別途USBから給電しています。
配線図は以下

ラズパイ5ではハードウェアPWMを使うためにconfig.txtをいじる必要がありましたが、ゼロ2wではpigpioが使えるのでいらないみたいです。
今回はPS4のコントローラをBluetoothで接続して動かしてみました。
まずは必要モジュールのインストールから。ラズパイのターミナルで実行します。
sudo apt update sudo apt install pigpio sudo systemctl enable pigpiod sudo systemctl start pigpiod sudo apt install python3-evdev
pigpioはすでにインストールされてました。
evdevはコントローラを使うために必要みたいです。
PS4コントローラとの接続はラズパイのデスクトップ上でBluetoothのアイコンからデバイスを追加することでできました。
デバイスの番号を調べるには、
ls /dev/input
でわかります。event1がパッドのジャイロ、event2がパッドの操作です。
プログラムは以下の通り
from gpiozero import Motor, PWMOutputDevice from gpiozero.pins.pigpio import PiGPIOFactory from evdev import InputDevice, ecodes from threading import Thread import time # ---------- pigpio ---------- factory = PiGPIOFactory() # ---------- GPIO設定 ---------- LEFT_EN = 18 LEFT_IN1 = 23 LEFT_IN2 = 24 RIGHT_EN = 19 RIGHT_IN1 = 27 RIGHT_IN2 = 22 # PWMは低め(重要) left_pwm = PWMOutputDevice(LEFT_EN, frequency=200, pin_factory=factory) right_pwm = PWMOutputDevice(RIGHT_EN, frequency=200, pin_factory=factory) left_motor = Motor(forward=LEFT_IN1, backward=LEFT_IN2, pin_factory=factory) right_motor = Motor(forward=RIGHT_IN1, backward=RIGHT_IN2, pin_factory=factory) # ---------- PS4コントローラ ---------- gamepad = InputDevice('/dev/input/event2') # 必要なら変更 print(gamepad) # ---------- 状態 ---------- LEFT_GAIN = 1.0 RIGHT_GAIN = 0.69 left_val = 0.0 right_val = 0.0 running = True DEADZONE = 10 MAX_PWM = 0.7 # 最大速度制限(安全) # ---------- ユーティリティ ---------- def clamp(v, min_v=0.0, max_v=1.0): return max(min(v, max_v), min_v) def stick_to_power(value): if value is None: return 0.0 center = 128 diff = value - center if abs(diff) < DEADZONE: return 0.0 power = diff / 127.0 power = max(min(power, 1.0), -1.0) # 前倒しで前進にする return -power def drive(left, right): # 左 if left >= 0: left_motor.forward() left_pwm.value = clamp(left * MAX_PWM) else: left_motor.backward() left_pwm.value = clamp(-left * MAX_PWM) # 右 if right >= 0: right_motor.forward() right_pwm.value = clamp(right * MAX_PWM) else: right_motor.backward() right_pwm.value = clamp(-right * MAX_PWM) def stop(): left_pwm.value = 0 right_pwm.value = 0 left_motor.stop() right_motor.stop() # ---------- モーター制御スレッド(50Hz) ---------- def motor_loop(): while running: drive(left_val, right_val) time.sleep(0.02) # 50Hz motor_thread = Thread(target=motor_loop, daemon=True) motor_thread.start() # ---------- メイン(入力処理のみ) ---------- try: print("PS4 Tank Drive Start") for event in gamepad.read_loop(): if event.type == ecodes.EV_ABS: if event.code == ecodes.ABS_Y: power = stick_to_power(event.value) left_val = power * LEFT_GAIN elif event.code == ecodes.ABS_RY: power = stick_to_power(event.value) right_val = power * RIGHT_GAIN '''左右1スティック動作 if event.code == ecodes.ABS_Y: power = stick_to_power(event.value) left_val = power * LEFT_GAIN right_val = -power * RIGHT_GAIN ''' except KeyboardInterrupt: print("Exit") finally: running = False stop() left_pwm.close() right_pwm.close() left_motor.close() right_motor.close()
実行するとPS4コントローラで動かせました。
左右のモーターで出力差があったため、遅い方のモーターに合わせて出力調整をしています。
ラズパイ2WでFM90動かしてみた。
— slowtech (@slowtech) 2026年1月11日
PS4コントローラーで操作できるようになったので、ラジコン作れます。#ラズパイ #電子工作 pic.twitter.com/ILIEuc2qi1
やっぱり精密な制御の場合はエンコーダがあるモーターじゃないと無理っぽいです。
今までFA機器を使っていてここまで個体差がある部品を使った事がなかったので、やはり産業用機器は精度が全然違うんだなぁ。と思いました。
もう少し慣れてきたらエンコーダ付きのモーターを使ってみたいです。
前回ブラウザでカメラモジュールのストリーミングができるようになったので、これでモニター付きラジコンカーを作れるようになりました。