LoginSignup
1
4

Raspberry Pi サーボモータ制御用クラス

Posted at

はじめに

Raspberry Piを使用して複数のサーボモータを制御するためのクラスを作成しました。
初期設定は下記サイトが参考になります。
自分も参考にさせていただきました。

ソースコード

クラスを使用することで複数のサーボモータを独立して制御できます。
また、インスタンスが現在の角度情報を保持しているので値を参照できます。

ServoMotor.py
import pigpio
import time


class ServoMotor:
    """
    サーボモータを制御するクラス

    Attributes:
        pin: GPIOのピン番号
        max_angle: 最大移動角度
        min_angle: 最小移動角度
        angle: 現在の角度
        ini_angle: 初期設定角度
        pi: gpio制御
    """
    def __init__(self, pin=17, min_angle=0, max_angle=180, ini_angle=90) -> None:
        """
        サーボモータを制御するクラス
        """
        self.pin = pin
        self.max_angle = max_angle
        self.min_angle = min_angle
        self.angle = 0
        self.ini_angle = ini_angle
        self.pi = None

    def start(self) -> None:
        """
        GPIOの開始処理
        """
        self.pi = pigpio.pi()
        self.pi.set_mode(self.pin, pigpio.OUTPUT)

    def stop(self) -> None:
        """
        GPIOの終了処理
        """
        self.pi.set_mode(self.pin, pigpio.INPUT)
        self.pi.stop()

    def set_angle(self, target_angle: int) -> None:
        """
        サーボモータを指定角度に移動する

        Args:
            target_angle (int): 動作させる角度
        """
        if target_angle < self.min_angle or target_angle > self.max_angle:
            print(f"角度は{self.min_angle}から{self.max_angle}度の間で指定してください。")
            return

        # 角度を500から2500のパルス幅にマッピングする
        pulse_width = (target_angle / 180) * (2500 - 500) + 500
        self.angle = target_angle
        # パルス幅を設定してサーボを回転させる
        self.pi.set_servo_pulsewidth(self.pin, pulse_width)
        time.sleep(0.2)  # サーボモータが移動するのを待つために少し待つ

    def set_ini_angle(self) -> None:
        """
        サーボモータを初期設定の角度に移動する
        """
        self.set_angle(self.ini_angle)

if __name__ == "__main__":
    # 動作サンプル

    """
    動作サンプルではサーボモータを2台接続
    サーボそれぞれの信号ピンを17番、18番に接続
    """
    
    """
    ServoMotorクラスのインスタンス化
    pin: サーボモータ信号端子の接続先ピン番号(設定しない場合 17番)
    max_angle: 最大角度(設定しない場合 180度)
    min_angle: 最小角度(設定しない場合 0度)
    ini_angle: 初期設定角度(設定しない場合 90度)
    """
    servo_motor_horizontal = ServoMotor(pin=17, max_angle=160, min_angle=0, ini_angle=90)
    servo_motor_vertical = ServoMotor(pin=18, max_angle=130, min_angle=0, ini_angle=40)

    # サーボ動作開始
    servo_motor_horizontal.start()
    servo_motor_vertical.start()

    # サンプル動作 
    servo_motor_vertical.set_angle(20)
    for angle in range(0, 181, 10):
        servo_motor_horizontal.set_angle(angle)

    servo_motor_vertical.set_angle(40)
    for angle in range(180, -1, -10):
        servo_motor_horizontal.set_angle(angle)

    servo_motor_vertical.set_angle(60)
    for angle in range(0, 181, 10):
        servo_motor_horizontal.set_angle(angle)

    # 初期位置(ini_angle)に移動
    servo_motor_vertical.set_ini_angle()
    servo_motor_horizontal.set_ini_angle()

    # 現在の角度を表示
    print(servo_motor_vertical.angle)
    print(servo_motor_horizontal.angle)

    # サーボ動作停止
    servo_motor_horizontal.stop()
    servo_motor_vertical.stop()

制作物

少し変更を加えていますが、下記制作で使用しています。

1
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
4