Raspberry Piと専用のカメラモジュールを使用し、ONVIF対応の監視カメラを作成するシリーズ記事です。
本記事はリンク情報システム株式会社の有志が作成しています。
カメラの首振り機能用にサーボモータを付けたので、サーボモータを制御して前後左右にカメラを動かします。
#サーボモータ制御 (I2C)
###サーボモータ制御
今回使用するPWMコントローラを搭載するボードはAdafruit社が発売しており、同社より、Adafruit_PWMServoDriver.cppと言うドライバのソースが公開されています。
参考元:Adafruit-PWM-Servo-Driver-Library/Adafruit_PWMServoDriver.cpp at master · adafruit/Adafruit-PWM-Servo-Driver-Library · GitHub
このソースは、arduinoを対象として作成されておりますが、シンプルなC言語なので、大半の処理は流用する事が可能です。
サーボモータ制御処理の流れは以下のようになります。
1.初期化
2.サーボ移動
ポイントとなる実際の処理を抜粋して解説します。
#####1.初期化
RaspberryPiでI2C通信を行う場合、"/dev/i2c-1" をオープンし、スレーブアドレスの設定を行います。
i2c = open("/dev/i2c-1", O_RDWR);
ioctl(i2c, I2C_SLAVE, 0x40);
これで、PCA9685と通信できるようになりましたので、リセットしてから、サーボを動作させます。
// PCA9685をリセット
write8(PCA9685_MODE1, 0x0);
// サーボ制御パルス周波数設定
setPWMFreq(60);
// 中心に移動する
setPWM(1, 0, CalcPulseWidth(90));
setPWM(0, 0, CalcPulseWidth(90));
#####2.サーボ移動
角度を指定してサーボを移動させます。
// 1 = 左右用のサーボを移動
setPWM(1, 0, CalcPulseWidth([角度]));
// 0 = 上下用のサーボを移動
setPWM(0, 0, CalcPulseWidth([角度]));
角度は、90度が中央、45度 ~ 135度を指定して左右、上下に移動できると考えてください。
また、第一引数の 1 / 0 は、X方向のサーボかY方向のサーボかを示します。
今回の接続方法の場合、1チャンネルはX方向(左右)、0チャンネルはY方向(上下)に相当します。
###ドライバの移植について
今回使用したPCA9685のハードウェアのように、一般的にはメーカーからドライバのソースが公開され、ユーザが使用する事ができるようになっています。
ですが、I2CやGPIOでの通信制御は、それぞれの環境において提供されるライブラリが異なっているため、必ずしも全ての環境で、そのまま使用できるような形でドライバが提供される事はありません。
ですので、大抵のドライバのソースは、HAL(HardwareAbstrationLayer)と言うような形式で、通信部分を抽象化し関数を別に分け、その部分のみ改造することで、ドライバを移植できるような形式になっています。
今回のAdafruit-PWMのドライバの場合は、TwoWireと言うクラスを定義されており、そのクラスにI2C通信の処理を実装させているようでした。
ですので、このドライバをそのまま使用したいと考えた場合は、TwoWireクラスを実装する必要があります。
###注意事項
今回使用しているサーボは、起動の度にズレが発生するため、90度が必ずしも中央になるとは限りません。その為、何らかの機械的な仕組みやセンサーを利用して、電源ONの度に、トリム調整を行い、都度、ずれている分を角度に反映するなどの工夫が必要だと思います。(今回の試作ではそこまでの機能は用意しておりません。)
リンク情報システム株式会社では一緒に働く仲間を随時募集しています!
また、お仕事のご依頼、ビジネスパートナー様も募集しております。お気軽にご連絡ください。