日別アーカイブ: 2021年5月8日

サーボモータを利用したPan/Tiltカメラ台の制御(pigpioの利用)

こんな記事を発見:RPi.GPIOよりもpigpioの方が精度が良いらしい。

「RPi.GPIO と pigpio のパルス幅の精度を測定」

テストのコード

#!/usr/bin/python
# -*- coding: utf-8 -*-
import time
import pigpio
PAN=27
GP = pigpio.pi()
GP.set_mode(PAN, pigpio.OUTPUT)
GP.set_servo_pulsewidth(PAN, 500)   # gpio18   500us

time.sleep(60)
GP.stop()

実測結果

標準偏差が348nSと、OSのオーバーヘッドがないArduinoと比較すると2桁程大きいが、サーボモータの制御には十分な精度が得られそう、、、

サーボモータを利用したPan/Tiltカメラ台の制御(GPIOライブラリーでは正確な制御は無理?)

サーボモータでPan/Tiltカメラ台を制御する実験をやってみたが、意図した方向から少し外れては正しい方向へカメラ台が回転する現象が頻発している。ステッピングモータの時には、このような現象に遭遇した記憶がない。サーボモータは、制御信号のパルス幅に対応した角度まで回転するように作られているので、意図しない回転の原因は、次のように推定できる。

  • 制御信号のパルス幅がバラついている
  • サーボモータの精度が悪い(制御信号のパルスに正確に追従していない)
  • その他?(上記の両方、またはその他の原因)

安価なサーボモータを使っているので、最初はサーボモータの精度の問題と思ったりしたが、制御信号のパルス幅をオシロで観測してみることにした。オシロには測定した値の統計情報を表示する機能があり、パルス幅の評価にはこれを利用することにした。

サーボモータの制御は、次のPythonスクリプトでRaspberry pi4bのGPIOからPWM信号を発生させて行っている。500HzでDuty50%の矩形波を生成。

#GPIOの初期設定
import RPi.GPIO as GPIO
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
PAN=27
GPIO.setup(PAN, GPIO.OUT)
PWM_pan = GPIO.PWM(PAN, 500)
PWM_pan.start(0.0)

PWM_pan.ChangeDutyCycle(50)
while True:
    pass

オシロで観測した波形と統計情報

赤枠部分に表示された情報を信用すると、パルス幅の平均値が1.08mS、最大値が2.34mS、標準偏差が88.96μなどどなっている。ここで、利用したサーボモータは0.5mSから2.5mSの制御信号のパルス幅に対応して、270度の範囲で回転することになっている。回転角度を1度変更するにために必要なパルス幅の変化は、約4.7μS(=2mS/270)。ところが、観測したパルス幅の標準偏差が88.96μということなので、サーボモータが制御信号に忠実に反応した場合、回転角度が数度以上変動することになる。実際に、この制御信号をサーボモータへ与えると、モータは静止せずに微動を繰り返す状態となった。

制御パルス生成にArduino Microを用いた場合

PIN6からPWM信号を生成

int PAN = 6;

void setup() {
  pinMode(PAN, OUTPUT);
  analogWrite(PAN,128);
}

void loop() {
}

オシロで観測した様子

なんと標準偏差が1桁のnSオーダー。Raspberry Pi4の1/1000以下となりました。