West Gate Laboratory

人生を少しでも,面白く便利にするモノづくり

RaspberryPi+サーボモータでインターホンに応答する

はじめに

この記事はオートロックマンション用不在時荷物受け取りシステムの関連記事です。

westgate-lab.hatenablog.com

さて、これまでの間にRaspberryPiでインターホンの音を検知するところまでいけたので、 今回はその音に応じてインターホンの解錠ボタンを自動で押してみようと思う。(解錠ボタンの配置は以下の写真参照)

これができれば、「インターホン音を検知→解錠」が自動でできることになる。

f:id:kaname_m:20191222141738j:plain
我が家のインターホン。中心に解錠ボタンがある。

どうやって解錠ボタンを押すか

インターホンの解錠ボタンは軽く押せるので、そこまで力は必要ない。

今どきであればSwitchbotのようなIoTボタンみたいなものを買えばいいのかもしれないが、せっかくなのでサーボモータを使って押してみようと思う。

サーボモータ選び

今回、サーボモータ選びの条件は、

  • 秋月電子で売っていること
  • そこそこ小型であること
  • 安価であること
  • 通常のPWMで駆動できること

といった感じである。ボタン自体は軽いのでパワーは普通にあれば考慮しない。

最終的に選んだのはマイクロサーボ SG92Rである。

akizukidenshi.com

一般的なPWM駆動のサーボモータで、比較小型・安価である。インターホンのボタンを押すには十分。

pigpioによるサーボモータ駆動

ちょっと昔RaspberryPiの1や2を使っているときはWiringPiを使っていたが、どうやら最近はpigpioというライブラリがRaspberryPiのGPIO制御をPythonでやる場合のデファクトスタンダードらしい。

pigpioの詳細については、色んな人が書いているのでそちらを参照のこと。

karaage.hatenadiary.jp

サーボモータを駆動する場合はPWMが必要になる。pigpioによるPWM出力については以下の記事が詳しい。

qiita.com

1点、RaspberryPiからサーボモータを駆動するときの注意点として、RaspberryPiにつないでいるACアダプタによっては電力が足りず、低電圧警告が出る場合がある。RaspberryPiのDCジャック付近の赤LEDが消灯したらそれが低電圧警告である。

f:id:kaname_m:20200103114203p:plain
POWER 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である。 この値を細かく調整することで、インターホンの解錠ボタンを押すのに丁度いい角度を探っていく。あまりに角度が浅いとちょっとヘタってきたときに押せなくなるし、角度が深すぎるとサーボモータが過負荷になって焼ける可能性がある。

なお、サーボモータはインターホンの筐体に強力両面テープで貼り付けている。ソフトタイプのほうが少しクッション性があって良い。

調整がうまく行くとこんな感じで解錠ボタンを押せる。

ちょうど良いパラメータが決まったら、あとはインターホン音検知と組み合わせるだけだ。 インターホン音検知については以前の記事を参照。

westgate-lab.hatenablog.com

音検知とボタンプッシュを組み合わせると、こんな感じに使える。

これでインターホン音検知+スマホ通知(過去記事参照)+ボタン解錠ができるようになった。

あとは玄関に置き配バッグを配置しておけば、一応不在時にも荷物を受け取ることは可能である。ただ、このままではインターホンを押した人は誰でも入れてしまうセキュリティガバガバシステムが出来上がってしまうので、次はそういった方面の実装を加えていく。