RaspberryPi+サーボモータでインターホンに応答する
はじめに
この記事はオートロックマンション用不在時荷物受け取りシステムの関連記事です。
さて、これまでの間にRaspberryPiでインターホンの音を検知するところまでいけたので、 今回はその音に応じてインターホンの解錠ボタンを自動で押してみようと思う。(解錠ボタンの配置は以下の写真参照)
これができれば、「インターホン音を検知→解錠」が自動でできることになる。
どうやって解錠ボタンを押すか
インターホンの解錠ボタンは軽く押せるので、そこまで力は必要ない。
今どきであればSwitchbotのようなIoTボタンみたいなものを買えばいいのかもしれないが、せっかくなのでサーボモータを使って押してみようと思う。
サーボモータ選び
今回、サーボモータ選びの条件は、
- 秋月電子で売っていること
- そこそこ小型であること
- 安価であること
- 通常のPWMで駆動できること
といった感じである。ボタン自体は軽いのでパワーは普通にあれば考慮しない。
最終的に選んだのはマイクロサーボ SG92Rである。
一般的なPWM駆動のサーボモータで、比較小型・安価である。インターホンのボタンを押すには十分。
pigpioによるサーボモータ駆動
ちょっと昔RaspberryPiの1や2を使っているときはWiringPiを使っていたが、どうやら最近はpigpioというライブラリがRaspberryPiのGPIO制御をPythonでやる場合のデファクトスタンダードらしい。
pigpioの詳細については、色んな人が書いているのでそちらを参照のこと。
サーボモータを駆動する場合はPWMが必要になる。pigpioによるPWM出力については以下の記事が詳しい。
1点、RaspberryPiからサーボモータを駆動するときの注意点として、RaspberryPiにつないでいるACアダプタによっては電力が足りず、低電圧警告が出る場合がある。RaspberryPiのDCジャック付近の赤LEDが消灯したらそれが低電圧警告である。
私が使っているACアダプタではこの症状になったため、サーボモータの電源には別途5VのACアダプタを用意し、そこから電源を供給している。上の写真にはRaspberryPiの電源(USB)と別にもう一つACアダプタが見えるが、それがサーボモータ用の電源である。DCジャックをホットボンドでケースに貼り付けて、配線をそこからサーボモータに飛ばしている。GNDはRaspberryPiと共通だ。
pigpioの使い方などはいろんな記事で紹介されているが、この記事でも簡単に、(インターホンのボタンを押すのに)最低限必要な使い方を記しておく。
pigpioのインストール
sudo apt-get update sudo apt-get install pigpio
デーモンの立ち上げ
sudo pigpiod
これはRaspberryPiを起動するたびに実行しなければいけないため、/etc/rc.local
に記述して起動の度に自動実行されるようにしておいたほうが良い。
Pythonスクリプトの記述
まずは単にサーボモータを1秒ごとに動かすだけのスクリプトを書いてみる。
import time import pigpio def unlockDoor(): servoPush() time.sleep(SERVO_TIME) servoRelease() def calcServoDuty(ratio): # ratio:0-1でサーボ角度を指定 # SG92Rの制御パルスが0.5ms-2.4msなのでdutyに25000(1000000/20*0.5)-120000(100000/20*2.4)をマッピングする duty = 25000 + (120000 - 25000) * ratio return duty def moveServo(ratio): duty = calcServoDuty(ratio) pi.hardware_PWM(PORT_PWM, SERVO_PERIOD, int(duty)) def servoRelease(): moveServo(SERVO_RELEASE) def servoPush(): moveServo(SERVO_PUSH) if __name__=='__main__': # 実験的に決定したサーボのPWMパラメータ SERVO_RELEASE = 0.5 # ボタン解放状態(サーボモータ角度中間) SERVO_PUSH = 0.35 # ボタン押下状態 SERVO_TIME = 0.2 # サーボモータを押す時間[秒] pi = pigpio.pi() # servo setting PORT_PWM = 18 SERVO_PERIOD = 50 # [Hz] :PWMサイクル20ms pi.set_mode(PORT_PWM, pigpio.OUTPUT) moveServo(0.5) while 1: try: unlockDoor() time.sleep(1) except KeyboardInterrupt: break
「インターホンを押す」という目的の上で重要なのは上記スクリプトでいうSERVO_PUSHである。 この値を細かく調整することで、インターホンの解錠ボタンを押すのに丁度いい角度を探っていく。あまりに角度が浅いとちょっとヘタってきたときに押せなくなるし、角度が深すぎるとサーボモータが過負荷になって焼ける可能性がある。
なお、サーボモータはインターホンの筐体に強力両面テープで貼り付けている。ソフトタイプのほうが少しクッション性があって良い。
調整がうまく行くとこんな感じで解錠ボタンを押せる。
サーボモータがインターホンを押す練習中。 pic.twitter.com/VtkD3wGJaI
— 水田かなめ (@kmizta) January 3, 2020
ちょうど良いパラメータが決まったら、あとはインターホン音検知と組み合わせるだけだ。 インターホン音検知については以前の記事を参照。
音検知とボタンプッシュを組み合わせると、こんな感じに使える。
ラズパイ+ウェブカメラでインターホン検知→サーボモータで解錠。あまりに反応が早いと怪しいので少し間を空けて。 pic.twitter.com/BGr4zJplWk
— 水田かなめ (@kmizta) December 31, 2019
これでインターホン音検知+スマホ通知(過去記事参照)+ボタン解錠ができるようになった。
あとは玄関に置き配バッグを配置しておけば、一応不在時にも荷物を受け取ることは可能である。ただ、このままではインターホンを押した人は誰でも入れてしまうセキュリティガバガバシステムが出来上がってしまうので、次はそういった方面の実装を加えていく。