読者です 読者をやめる 読者になる 読者になる

日記とか、工作記録とか

自分に書けることを何でも書いてゆきます。作った物、買ったもの、コンピュータ系の話題が多くなるかもしれません。

Raspberry pi 2 + Servo Motor (Pythonクラスの作成)

サーボモータの制御について少し前のブログに書きましたが、サーボモータはいろいろ使い道がありそうなので、簡単に操作できるようにクラスを作成しておくことにしました。以前も書いたように、サーボモータはSG90というものです。

私が作成したSG90のクラスは以下のようなものです。

pi@raspberrypi:~/work$ cat sg90.py
#!/usr/bin/python
# -*- coding: utf-8 -*-

import RPi.GPIO as GPIO
import time
import sys
import atexit

class sg90:
  '''
  Servo Motor SG90を簡単に使えるようにするためのクラス。
  '''
  def __init__( self, pin, direction ):
    '''
    初期化する。
    pin : GPIOのピン番号。PWMが使えること。
    direction : 初期の向き。 -100(一番左) から 100(一番右)までの場所を整数値で指定する。
    '''
    GPIO.setmode( GPIO.BCM )
    GPIO.setup( pin, GPIO.OUT )
    self.pin = int( pin )
    self.direction = int( direction )
    self.servo = GPIO.PWM( self.pin, 50 )
    self.servo.start(0.0)
    atexit.register( self.cleanup )

  def cleanup( self ):
    '''
    最後は正面に戻して終了する
    '''
    self.servo.ChangeDutyCycle(self.henkan(0))
    time.sleep(0.3)
    self.servo.stop()
    GPIO.cleanup()

  def currentdirection( self ):
    '''
    現在のSG90の向きを返す。
    '''
    return self.direction

  def henkan( self, value ):
    '''
    ChangeDutyCycleに渡すための値を計算する。
    -100から100のfloat値を入力して、2から12の値を返す。
    ChangeDutyCycleに渡す値は 0.0 <= dc <= 100.0
    ……のはずだが、なぜか2から12の間で動作している。
    '''
    return 0.05 * value + 7.0

  def setdirection( self, direction, speed ):
    '''
    SG90の向きを変える。
    direction : -100 - 100 の整数値
    speed     : 変化量
    '''
    for d in range( self.direction, direction, int(speed) ):
      self.servo.ChangeDutyCycle( self.henkan( d ) )
      self.direction = d
      time.sleep(0.1)
    self.servo.ChangeDutyCycle( self.henkan( direction ) )
    self.direction = direction

if __name__ == "__main__":
    pass
pi@raspberrypi:~/work$

sg90.setdirection()を使うことで、角度を変更します。

引数のひとつめはdirectionです。下向きにツノが立っている状態で見たときに、一番右が100,一番左を-100として、目的の角度を指定するように作ってあります。

引数のふたつめはspeedです。サーボモータはゆっくり動かしたい場合もあるはずなので、この数値分だけ動かした後、0.1秒休止するようにしています。なお、SG90の仕様としては、0.1秒で60度動くことができるそうです。

このsg90クラスを使用する側のプログラムはだいぶ簡潔になります。sg90.pyは同じディレクトリに保存されている状態で使っています。

#!/usr/bin/python
# -*- coding: utf-8 -*-

import time
import sys
import sg90

# GPIO 12番を使用 (PWM 0)
s = sg90.sg90( 12, 0 )

while True:
  print "Turn left ..."
  s.setdirection( 100, 10 )
  time.sleep(0.5)
  print "Turn right ..."
  s.setdirection( -100, -10 )
  time.sleep(0.5)

sg90クラスを作成するときにGPIOのポート番号を指定します。PWMを使用できるポートである必要があります。今回は12番ピンを使っています。そのあとは基本的にsetdirectionを呼び出すだけです。終了時のGPIOポートの開放などはsg90クラスの中で行われているので意識しなくても大丈夫です。

さて、動いている様子は動画で紹介します。今回初めてYouTube動画編集をしてみました。

Servo motor class g90.py

これでSG90を気軽に使えるようになりました。今後応用をいろいろ考えていきたいと思います。

Raspberry Piスターターパック (Pi2 用Standard)

Raspberry Piスターターパック (Pi2 用Standard)