サーボモーター(SG-90)を試す
配線
マイクロサーボ9g SG-90 [SG-90] 通販コード M-08761 発売日 2014/12/09 メーカーカテゴリ Tower Pro Pte Ltd ◆主な仕様 ・PWMサイクル:20mS ・制御パルス:0.5ms~2.4ms ・制御角:±約90°(180°) ・配線:茶=GND、赤=電源[+]、橙=制御信号 [JRタイプ] ・トルク:1.8kgf・cm ・動作速度:0.1秒/60度 ・動作電圧:4.8V(~5V) ・温度範囲:0℃~55℃ ・外形寸法:22.2x11.8x31mm ・重量:9g
と、有るが、真ん中がどうにも赤に見えなくて不安になる!
真ん中の赤を 5Vに配線して、茶色をGNDに、橙色をGPIOのどっかに刺す。今回はGPIO21にした。
テックシェアストア(TechShareStore)
windvoice.hatenablog.jp
上記を参考に、下記のスクリプトを書いた。
#!/usr/bin/python # coding: utf-8 import RPi.GPIO as GPIO import time import signal import sys def exit_handler(signal, frame): # Ctrl+Cが押されたときにデバイスを初期状態に戻して終了する。 print("\nExit") servo.ChangeDutyCycle(2.0) time.sleep(0.5) servo.stop() GPIO.cleanup() sys.exit(0) # 終了処理用のシグナルハンドラを準備 signal.signal(signal.SIGINT, exit_handler) GPIO.setmode(GPIO.BCM) # GPIO 21番を使用 gp_out = 21 GPIO.setup(gp_out, GPIO.OUT) # pwm = GPIO.PWM([チャンネル], [周波数(Hz)]) servo = GPIO.PWM(gp_out, 50) # 初期化 servo.start(0.0) while True: for angle in range(0, 180, 30): dc =(1.0 + angle/180.0)/20.0*100.0 # calculate duty servo.ChangeDutyCycle(dc) print("Angle = %d" % angle) print("dc = %d" % dc) time.sleep(0.5) for angle in range(180, 0, -30): dc =(1.0 + angle/180.0)/20.0*100.0 # calculate duty servo.ChangeDutyCycle(dc) print("Angle = %d" % angle) print("dc = %d" % dc) time.sleep(0.5)
・・・思うような角度にならない。
これは、0度 ~ 180度 ではなくて、
-90度 ~ +90度 で動くからではないかと考えると、
new_duty =(1.0 + angle/180.0)/20.0*100.0 # calculate duty
とか書いてあるから、この式で行くと、
angle new_duty -90 2.5 -45 3.75 0 5 45 6.25 90 7.5
と成るはずだが・・・。
実際には dc は 2-12 で180度動く。
データシートを見ると、
PWMサイクル:20mS 制御パルス:0.5ms~2.4ms
の仕様になっている。
デューティ = パルス / 周期
だから、
-90度 = 0.5ms / 20ms = 2.5%。 +90度 = 2.4ms / 20ms = 12.0%
そうなると、
2.5 ~ 12.0 の間を 180 で割ったのが、狙った角度になるかな。
そうなると、
2.5 4.875 7.25 9.625 12
のリストになるのかな。
んで、書き直したのがこれ。
#!/usr/bin/python # coding: utf-8 import RPi.GPIO as GPIO import time import signal import sys def exit_handler(signal, frame): # Ctrl+Cが押されたときにデバイスを初期状態に戻して終了する。 print("\nExit") servo.ChangeDutyCycle(2.5) time.sleep(0.5) servo.stop() GPIO.cleanup() sys.exit(0) # 終了処理用のシグナルハンドラを準備 signal.signal(signal.SIGINT, exit_handler) GPIO.setmode(GPIO.BCM) # GPIO 21番を使用 gp_out = 21 GPIO.setup(gp_out, GPIO.OUT) # pwm = GPIO.PWM([チャンネル], [周波数(Hz)]) servo = GPIO.PWM(gp_out, 50) # 初期化 servo.start(0.0) val = [2.5,3.6875,4.875,6.0625,7.25,8.4375,9.625,10.8125,12] servo.ChangeDutyCycle(val[0]) time.sleep(0.5) servo.ChangeDutyCycle(val[8]) time.sleep(0.5) servo.ChangeDutyCycle(val[0]) time.sleep(0.5) while True: for i, dc in enumerate(val): servo.ChangeDutyCycle(dc) print("Angle:" + str(i*22.5)+" dc = %.4f" % dc) time.sleep(0.5) for i, dc in enumerate( reversed(val) ): servo.ChangeDutyCycle(dc) print("Angle:" + str(180 - i*22.5)+" dc = %.4f" % dc) time.sleep(0.5)
なお、サーボモーターを動かしていると、 私の環境では電圧低下の警告(画面右上の虹色四角と赤色LEDが消灯)が出ました。
このことは、モーターの電力を外部(USBなどから)取り、GNDを共通にすることで回避します。