我が家は1階リビングで2階に寝室や子供部屋があります。1階で食事を作り、出来たら2階にいる子供を大声で呼んでいたのですが、大声を何度も出すのは大変だし、ご近所さんにも漏れそうだし、いやだなあと思っていて、なんとか解決しできないかと考えていました。
そこで、1階からbluetoothのボタンを押した時に、2階に設置したラズパイがその情報を取得し、子供を呼び出す音声をスピーカーから出力できるようにすればよいのではないかと思いつき作ってみることにしました。全体としては下の図のようなものになります。
準備するモノ
まずは、使用した物品です。
- ラズパイ
- 100均で売ってるBluetoothボタン(300円)
- 100均で売ってるスピーカー(500円)
ラズパイは言わずと知れた電子工作の必需品ですね。Bluetoothボタンはスマホのリモートシャッター用の製品のようです(写真左)。スピーカーはステレオミニ端子が音声入力のモノで写真に写っているUSB端子は給電用です(写真右)
これで全部です!
ラズパイの準備
これからラズパイでプログラムなど書いていくわけですが、その前にラズパイを安定して使うための準備をしました。以下のページにまとめています
Bluetoothボタンのラズパイとの接続
まずは、ラズパイのBluetoothをONにしましょう。GUIの右上の方にあるアイコンからできます。そして、ラズパイの近くでBluetoothボタンをの電源をONにしてください。あとは以下の手順になります。
- Bluetoothデバイスの検索
Bluetoothデバイスの検索は、”bluetoothctl”のコマンドを使います。そうすると対話モードに変わります。ここまでを行うと以下のようになります。
次に”scan on”のコマンドをうち、Bluetoothデバイスを検索します。デバイスが見つかるとそのMACアドレスが表示されます。sudo bluetoothctl Agent registered [bluetooth]#
xx:xx:xx:xx:xx:xxはMACアドレスです。xx-xx-xx-xx-xx-xxはデバイス名に相当する部分のようですが、設定されていないとMACアドレスをハイフンでつないだ文字列が表示されます。今回使用するデバイスは「AB Shutter3」と表示されますので、そのMACアドレスをメモしてください。上記例だと”yy:yy:yy:yy:yy:yy”になります。[bluetooth]# scan on Discovery started [NEW] Device xx:xx:xx:xx:xx:xx xx-xx-xx-xx-xx-xx [NEW] Device yy:yy:yy:yy:yy:yy AB Shutter3
何もしないとずっと探し続けて、必要なMACアドレスが見えなくなるので、
とコマンドをうって終了させましょう。[bluetooth]# scan off
MACアドレスが分かったので、ペアリングをします。”pair”のコマンドでMACアドレスを指定します。その後の動作はデバイスで多少変わるようですが、今回の場合は対話モードに変わり、そこで”connect”コマンドでMACアドレスを再度指定します。
ここまででペアリングが完了です。pair yy:yy:yy:yy:yy:yy [AB Shutter3]# connect yy:yy:yy:yy:yy:yy Connection successful
Bluetoothボタンの電源のon, offが発生するたびにこのような作業をするのは大変なので、自動的に接続するようしたいと思います。以下のコマンドを使います。
最後に”exit”コマンドで終了します。trust yy:yy:yy:yy:yy:yy
- Bluetoothボタンの動作確認
Bluetoothボタンが接続出来たら、ボタンを押してみましょう。そうすると、ラズパイのGUIの右上にあるボリュームが変化するはずです。
Bluetoothボタンを押すと音声ファイルを再生するプログラムの作成
ここからは、Bluetoothボタンを押すと音声ファイルを再生するプログラムをpythonで作成していきます。
- 必要なモジュールのインストール
Bluetoothボタンを押したことを検知するために、”evdev“というモジュールをインストールします。
MP3ファイルを再生するのに必要なmpg321というソフトをインストールします。(ここは別の方法でも大丈夫です)sudo pip3 install evdev
sudo apt install mpg321
- event番号確認
Linuxでは、キーボードやマウスなど入力装置からの入力イベントを検知していて、その内容が/dev/input/以下に、”event1″のような名前のファイルに記録されていきます。そのため、Bluetoothボタンが”event1″なのか”event2″なのか、というのを次の方法で確認します。
まず、Bluetoothボタンが接続されていない状態で次のコマンドを打ちます。(接続後90秒ボタンを押さないと接続がきれます)
そうするとls /dev/input
のような内容が表示されるので、それをメモします。by-path event0 mice
次にBluetoothボタンを接続して同じようにコマンドを打ちます。(接続するまでボタンを押し続けましょう。
そうすると内容が変わっていると思います。例えば、ls /dev/input
となっていると思います。この増えた”event1″がBluetoothボタンに相当するのでメモしておきましょう。by-path event0 event1 mice
また、次のコマンドでより詳細に”eventX”に関する情報を知ることができます。
このコマンドを使うと全てのeventに関する情報が表示されますが、今回は以下のように、N: Name=”AB Shutter3 Consumer Control”となっている、event1 (Handlers=kbd event1の部分)を使います。/proc/bus/input/devices
I: Bus=0005 Vendor=248a Product=8266 Version=0001 N: Name="AB Shutter3 Consumer Control" P: Phys=xx:xx:xx:xx:xx:xx S: Sysfs=/devices/virtual/misc/uhid/0005:248A:8266.000A/input/input20 U: Uniq=ff:ff:aa:ae:72:b4 H: Handlers=kbd event1 B: PROP=0 B: EV=13 B: KEY=1e0000 0 0 0 B: MSC=10
- ソースコード作成
こちらのページを参考にして(といかほぼコピペですが)、以下のようなコードを書きます。
1行目:先ほどインストールした”evdev”モジュールをインポートします。import evdev import subprocess import time import random while True: try: device = evdev.InputDevice('/dev/input/event1') print(device) for event in device.read_loop(): print(evdev.categorize(event)) if event.type == evdev.ecodes.EV_KEY: if event.value == 1: #0:KEYUP, 1:KEYDOWN print(event.code) num = random.randint(1,3) print(num) if num == 1: subprocess.Popen(['mpg321','gohan1.mp3']) elif num == 2: subprocess.Popen(['mpg321','gohan2.mp3']) elif num == 3: subprocess.Popen(['mpg321','gohan3.mp3']) except: time.sleep(1)
6行目:入力をずっと監視したいので、無限ループにします。
8~12行目: “evdev”モジュールのページにあるサンプルコードのままです。
8行目:読み込むイベントをしています。ここでは”event1″としていますが、適宜書き換えます。
14行目:これ以降に、Bluetoothボタンが押された時の処理を記載します。
15行目:ここで処理の分岐をするための入力をしています。今回はボタンをカチっと押し込んだときだけどうさするように、key_downの値をしています。なぜ”0″なのかはevdevのページに記載があります。
17行目:再生するファイルを飽きないように適当に変更したかったので、1~3の数字をランダムに作成して、それ以降のステップで使っています。
19行目:subprocess~のところで、mp3ファイルを再生させています。 - サービス化
無事コードが動作した後、ずっと監視させるわけですが、ラズパイを再起動させた後に、また実行させたりするのは面倒ですよね。ということでサービス化しましょう。ということで、以下の場所サービスの定義をするファイルを作成します。(call.serviceという名称にする場合)
そして以下のように記述します。sudo nano /etc/systemd/system/call.service
[Unit]のこのサービスの説明書き。[Unit] Description=Run call program [Service] ExecStart=/usr/bin/python3 call.py WorkingDirectory=/home/hogehoge/call [Install] WantedBy=multi-user.target
[Service]のExecStartには実行コマンドを記載します。通常であればpythonへのパスが通っているので、Python3 call.pyとなりますが、ここでは省略せずに全て記載します。
WorkingDirectoryには、プログラムファイルのディレクトリ(ここではcall.pyのあるディレクトリ)
[Install]にはおまじないを書く。
最後に有効化しましょう。
sudo systemctl enable callsudo systemctl start call
- 最後に
再起動すると、event1とかの数字が変わることがあるようです。動かなくなったら、そこを確認してみましょう。
これで、2階にいる子供呼ぶときに変なストレスを感じなくなるはずです!
参考ページ
- 全体的な流れ
100均Bluetoothボタンをラズパイ活用 - ls /dev/inputの詳細情報
[Linux] /dev/inutからマウスイベントを取得する - evdevのページ
python-evdev
コメント