🎮

ラズパイでサーボモータを制御(PCA9685)

2022/01/15に公開

はじめに

電子工作ではサーボモータを制御する機会が結構あります。そこで今回はラズパイでサーボモータを制御したいと思います。

ただ、ラズパイはサーボモータを制御するためのPWMが使えるGPIOの数が少ないためI2Cでサーボモータを制御できるサーボモータドライバ(PCA9685)を利用したいと思います。

PCA9685を使うと16個のサーボモータをI2Cで制御できるようになります。価格もAmazonで2個で1,000円台と安価で入手できます。

さらに今回は前回の記事「ラズパイでゲームパッドの入力を取得 🎮 」と組み合わせて、ゲームパッドでサーボモータを制御できるようにします。

今回使うもの

ラズパイ - Raspberry Pi 3 Model B
ワイヤレスゲームパッド - JC-U4113SBK
サーボモータドライバ - PCA9685
サーボモータ - TG9e
Python 3.9.x

Adafruit_PCA9685のインストール

PCA9685をPythonで使うためにライブラリをインストールします。

aptでインストール

$ sudo pip3 install adafruit-pca9685

回路図

「ラズパイ」→「PCA9685」→「サーボモータ」の順に信号が流れます。

ラズパイ と PCA9685

PIN1(3.3V PWR) - VCC
PIN2(5V PWR) - V+
PIN3(I2C SDA) - SDA
PIN4(I2C SCL) - SCL
PIN6(GND) - GND

PCA9685 と サーボモータ

PWM - PWM
V+ - V+
GND - GND

ラズパイのピン配列参考↗️

PCA9685でサーボモータを制御するプログラム

まずはサーボモータを単体で動かしてみます。

関数の説明

pwm.set_pwm()

pwm.set_pwm(チャンネル, 0, パルス幅) のように使います。

チャンネル:PCA9685の0〜15あるチャンネルを指定します。今回は0チャンネルにサーボモータをつないでいるので0を渡す。

0:長くなるので割愛します。とりあえず0を渡せばOK!

パルス幅:サーボモータの種類によっても変わるのですが今回はパルス幅150〜650(サーボモータの角度0〜180)を渡す。

test.py
import Adafruit_PCA9685
import time

# PCA9685初期設定
pwm = Adafruit_PCA9685.PCA9685()
pwm.set_pwm_freq(60)


def main():
    while True:
        pwm.set_pwm(0, 0, 150)
        time.sleep(1)
        pwm.set_pwm(0, 0, 650)
        time.sleep(1)


if __name__ == '__main__':
    main()

プログラム実行

$ sudo python3 test.py

【応用】ゲームパッドでサーボモータを制御

ゲームパッドのジョイスティックでサーボモータを制御してみます。

プログラムは「ゲームパッドの入力を取得」→「ジョイスティックの値を変換」→「変換した値をPCA9685に渡す」という流れになっています。

※ゲームパッドの入力を取得する方法は前回の記事「ラズパイでゲームパッドの入力を取得 🎮 」をご覧ください。

test.py
import pygame
import Adafruit_PCA9685

# pygame初期設定
pygame.init()
joystick = pygame.joystick.Joystick(0)
joystick.init()


# PCA9685初期設定
pwm = Adafruit_PCA9685.PCA9685()
pwm.set_pwm_freq(60)


# ジョイスティックの出力範囲をサーボモーターの出力範囲に変換
def map_pca9685(val):
    in_min = -100
    in_max = 100
    out_min = 150
    out_max = 650
    return int((val - in_min) * (out_max - out_min) / (in_max - in_min) + out_min)


# ジョイスティックの出力範囲を調整
def map_axis(val):
    val = round(val, 2)
    in_min = -1
    in_max = 1
    out_min = -100
    out_max = 100
    return int((val - in_min) * (out_max - out_min) / (in_max - in_min) + out_min)


# ジョイスティックの出力範囲を調整(L2 R2ボタン)
def map_axis_t(val):
    val = map_axis(val)
    if val <= 0 and val >= -100:
        in_min = -100
        in_max = 0
        out_min = 0
        out_max = 50
        return int((val - in_min) * (out_max - out_min) / (in_max - in_min) + out_min)
    else:
        in_min = 0
        in_max = 100
        out_min = 50
        out_max = 100
        return int((val - in_min) * (out_max - out_min) / (in_max - in_min) + out_min)


def main():
    while True:
        # イベントチェック
        if pygame.event.get():
            gamepad_data = {
                "joy_lx": map_axis(joystick.get_axis(0)),
                "joy_ly": -map_axis(joystick.get_axis(1)),
                "joy_rx": map_axis(joystick.get_axis(3)),
                "joy_ry": -map_axis(joystick.get_axis(4)),
                "joy_lt": map_axis_t(joystick.get_axis(2)),
                "joy_rt": map_axis_t(joystick.get_axis(5)),
                "hat_x": joystick.get_hat(0)[0],
                "hat_y": joystick.get_hat(0)[1],
                "btn_a": joystick.get_button(0),
                "btn_b": joystick.get_button(1),
                "btn_x": joystick.get_button(2),
                "btn_y": joystick.get_button(3),
                "btn_lb": joystick.get_button(4),
                "btn_rb": joystick.get_button(5),
                "btn_back": joystick.get_button(6),
                "btn_start": joystick.get_button(7),
                "btn_guide": joystick.get_button(8),
                "btn_joyl": joystick.get_button(9),
                "btn_joyr": joystick.get_button(10)
            }
            
            # ゲームパッド(左ジョイスティックのx軸)を取り出しPCA9685に渡す。
            pulse = map_pca9685(gamepad_data["joy_lx"])
            print(pulse)
            pwm.set_pwm(0, 0, pulse)


if __name__ == '__main__':
    main()

プログラム実行

$ sudo python3 test.py

終わりに

ゲームパッドでサーボモータを制御できるようになりました!そうするとラジコンカーのステアリングはこれで制御できますね!

次回はゲームパッドでDCモータを動かしてみたいと思います。

Discussion

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy