Raspberry Pi 3 で映像＋音声対応のベビーモニターを作る

赤ちゃんの様子を映像と音声で伝えてくれるベビーモニターは、既成品も色々とあるのですが、専用の受信端末でしか見れなかったり、「画面が小さい」「画質があまり良くなかった」という声が聞こえてきたり、またあまりに安すぎる海外製のWIFI機器をホームネットワークにつなぐのも何となく嫌だったので、Raspberry Piで自作することにしました。

結論から言うと、画質・音質ともに非常に満足のいく素晴らしいものができました！
![sample_on_ipad.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/195133/f281cbef-0827-5631-b543-93a56929081d.png)

# お世話になったページ

- https://kamranicus.com/guides/raspberry-pi-3-baby-monitor
- https://github.com/iizukanao/picam
- https://github.com/iizukanao/node-rtsp-rtmp-server

# 要件

お父さんの作業部屋やキッチンから直線距離で見えないところにベビーベッドを置いているので、ざっくり以下のような要件で考えました。

- **「映像」だけでなく「音声」も聞こえる**
- **PCやiPad、スマホなど「複数の端末」で「同時」に視聴できること**
- **外からの視聴は想定しない**

いろいろ検索した結果、[Building a Raspberry Pi 3 Baby Monitor](https://kamranicus.com/guides/raspberry-pi-3-baby-monitor)というサイトで紹介されていた[picam](https://github.com/iizukanao/picam)を使って作ったものがイメージに近かったため、こちらを参考に作らせていただきました！

# 完成イメージ
![back.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/195133/9bc82d63-245b-428c-eb11-89242ce57ff6.png)

※ 上記写真は5GHz未対応のRPi 3 B(+無し)を使ったためUSBのWIFIアンテナを刺していますが、2.4GHz帯でよい、あるいは本記事のようにRPi 3 B+を買えば外付けアンテナは不要です。

# 部品

- **Raspberry Pi 3 B+ 本体**
    - https://www.amazon.co.jp/gp/product/B07BFH96M3/ (5000円くらい)
- **microSDカード**
    - 8〜16GBくらいあれば十分だと思います
- **ケース**
    - https://www.amazon.co.jp/gp/product/B07CBPJTZG (1000~2000円くらい)
    - なんでもお好みのもので良いですが、カメラモジュールが引き出せる穴があるものを選んでください
    - ↑のようにon/offのスイッチが付いていると便利です
- **カメラモジュール**
    - https://www.amazon.co.jp/gp/product/B00FGKYHXA/ (1700円くらい)
    - 今回はpicamを使って楽をするので、USB接続のWebカメラではなく、Raspberry Pi用のものを使います
- **フレキシブルアーム**
    - https://www.amazon.co.jp/gp/product/B01E71UM5A/ (1000円くらい)
- **USBマイク**
    - https://www.amazon.co.jp/gp/product/B01M7YIYZV/ (2000円くらい)
    - 形状が取り回しやすそうだったのでこれにしましたが、もっと安いものでも大丈夫かもしれません
- **マスキングテープ**
    - https://www.amazon.co.jp/dp/B005JWNIQ2/ (200円くらい)
    - カメラモジュールの配線が長かったのでテープで雑に止めましたが、無くても大丈夫です

総額は12,000円くらいでした。

Raspberry Pi本体は「3 B」 (+無し)でも動きますが、オンボードでは2.4GHz帯にしか対応していないため、電子レンジを使ったときにキッチンで見れなくなりました。今買うならオンボードで5GHzに対応している「B+」がよいと思います。

# 組み立て

組み立てといっても基本的には部品を刺すだけなのであまりやることはありません。ただし、以下の点には注意していただいたほうがよいと思います。

- **万が一本体が落下しても、赤ちゃんにぶつからない位置に設置する**
- **できればベッドとは切り離されたところに取り付ける**
    - ベッドの枠にクリップすると、赤ちゃんがあんよをバタバタさせたときにすごく揺れます
- **部屋を真っ暗にしたときにLEDが明るすぎる場合は、テープを貼ったりして隠す**
    - チカチカしてもよく寝てくれる赤ちゃんなら大丈夫ですが、、、

![closeup.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/195133/1a8fc20d-6770-115f-7bd8-8a702fd21be1.png)
![bottom.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/195133/bce526a9-39c4-c821-18e6-01cded69fb40.png)

# 作り方

- WIFIやユーザーアカウントなど、Raspberry Pi (Raspbian)自体の基本設定は、以下に僕が作業用にメモした手順を紹介しますが、やり慣れた手順があればどんなやり方でも構いません。
- 通常はRaspberry Pi本体にHDMIディスプレイとUSBキーボードを接続してセットアップすることが多いと思いますが、余っているディスプレイやキーボードが無い場合、メインで使用しているデスクトップ機が使えなくなってしまうので、今回は有線LAN接続→Bonjourを使って `ssh pi@raspberrypi.local` してWIFIを設定、以降はWIFI経由でsshして作業、という手順を取っています。

### OS (Raspbian) をSDカードにインストールする

Raspbianは基本的には最新のものを使えば問題ないです。
執筆時点では、StretchのKernel version 4.14のものを使っています。

公式のダウンロードページ：[Download Raspbian for Raspberry Pi](https://www.raspberrypi.org/downloads/raspbian/)
公式の手順：[Installing operating system images](https://www.raspberrypi.org/documentation/installation/installing-images/README.md)

今回はデスクトップ環境は不要なので **[Raspbian Stretch Lite]** をダウンロードしてください。

SDカードへの書き込みは公式サイトで紹介されている[Etcher](https://www.balena.io/etcher/)を使っています。（シンプルで使いやすくおすすめです！）

### 有線LAN経由でsshでログインする

Etcher等の書き込みソフトでmicroSDカードの書き込みが終わったら、エクスプローラ(Win)やFinder(Mac)で開き、「boot」というボリュームの中に「ssh」という名前の空のファイルを作っておきます。これにより、初回起動時点でssh接続が有効になります。

次に、RPi本体を有線LANでルーターに接続して電源を入れます。
これだけでMacであれば `ssh pi@raspberrypi.local` でログインできるようになります。
piユーザーのデフォルトパスワードは `raspberry` です。

Windowsの場合は[iTunes](https://www.apple.com/jp/itunes/download/)を入れることで上記のsshに必要なBonjourが入るので、iTunesを入れてからお試しください。

### カメラの有効化とWIFIの設定

sshでログインできたら、さっそく設定をしていきましょう。

※ 公開鍵でのSSHの設定や、ユーザー名/パスワードの変更などは省略しています。ベビーモニターに直接関係しないRaspberry Pi共通の話題なので、気になる方は「Raspberry Pi Stretch 初期設定」「公開鍵 ssh」などで検索したうえでお好みで設定してください。

```bash
# カメラの有効化とメモリの割当
sudo raspi-config nonint do_camera 0
sudo raspi-config nonint do_memory_split 256

# 必要なアプリケーションやライブラリのインストール
sudo apt update && sudo apt install -y git npm libharfbuzz0b libfontconfig1

# WIFIの設定
SSID=使用するWIFIのSSID
PASS=使用するWIFIのパスワード
sudo raspi-config nonint do_wifi_country JP
sudo sh -c "wpa_passphrase ${SSID} ${PASS} | grep -v '#psk=' >> /etc/wpa_supplicant/wpa_supplicant.conf"

# 再起動
sudo shutdown -r now

# ここで一度接続が切れるので、数分待って再度ssh pi@raspberrypi.localでログインします

# 再起動が完了したら
ifconfig
```

WIFIの設定が正常に行われていたら `wlan0` という項目が出てくるはずです。
この `wlan0` の中の `HWaddr` または `ether` の値がMACアドレスなので、これをメモしておきます。

### DHCPの割当アドレスを固定する

RPiのローカルIPアドレスを固定する方法はいくつかありますが、ルーターに割当機能がある場合はそれがもっとも手軽で確実です。

使用しているルーターの設定画面から、先程メモしたMACアドレスに固定のIPアドレスを割り当てる設定をしてください。

ルーターに固定割当機能がない場合は、他にもいくつか方法はあるので「Raspberry Pi IPアドレス 固定」などで参考になりそうな記事を探してみてください。（これもベビーモニターに関わらずRaspberry Pi共通の話題ですでに他にたくさん記事が出ているためここでは省略します）

### WIFI経由でログインできることを確認する

```bash
# もう一度再起動します
sudo shutdown -r now

# 再度ssh pi@raspberrypi.localでログインし、割り当てられたIPアドレスを確認
ifconfig
```

 `wlan0` の欄に、さきほど固定で割り当てる設定をしたIPアドレスが表示されていることを確認します。

正しく表示されていたら、次にこのIPアドレスでsshできることを確認しておきます。

```bash
#一旦ログアウトします
exit

#ローカル端末でWIFIのIPアドレスへsshします
ssh pi@固定IPアドレス
```

これでログインできたら、以降はWIFI経由でログインできるはずなので、有線を外し、シャットダウンしたうえで、場所を移動させて大丈夫です。

```bash
# シャットダウン
sudo shutdown -h now

# ここからはWIFI経由でログイン
ssh pi@固定IPアドレス
```

### マイクが認識されていることを確認する
```bashh
arecord -l
```

ここで接続したUSBマイクの情報が出てくれば大丈夫です。
前述したサンワサプライのUSBマイクだとこのように表示されます

```bash
**** List of CAPTURE Hardware Devices ****
card 1: Microphone [USB Microphone], device 0: USB Audio [USB Audio]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
```

### Picamの設定

```bash
# 必要なディレクトリとシンボリックリンクの作成
cat > make_dirs.sh <<'EOF'
#!/bin/bash
DEST_DIR=~/picam
SHM_DIR=/run/shm
mkdir -p $SHM_DIR/rec
mkdir -p $SHM_DIR/hooks
mkdir -p $SHM_DIR/state
mkdir -p $DEST_DIR/archive
ln -sfn $DEST_DIR/archive $SHM_DIR/rec/archive
ln -sfn $SHM_DIR/rec $DEST_DIR/rec
ln -sfn $SHM_DIR/hooks $DEST_DIR/hooks
ln -sfn $SHM_DIR/state $DEST_DIR/state
EOF

chmod +x make_dirs.sh
./make_dirs.sh

# Picamのダウンロード
ver=1.4.7 #最新バージョンに置き換えてください
url=https://github.com/iizukanao/picam/releases/download/v${ver}/picam-${ver}-binary.tar.xz
wget ${url} -O picam-${ver}.tar.xz
tar xvf picam-${ver}.tar.xz
cp picam-${ver}-binary/picam ~/picam/
rm -rf ./picam-${ver}*

# 配信サーバー(node-rtsp-rtmp-server)のセットアップ
sudo npm install -g coffee-script
git clone https://github.com/iizukanao/node-rtsp-rtmp-server.git
cd node-rtsp-rtmp-server
npm install -d
./start_server.sh
```

配信サーバーが無事起動したら、ターミナルウィンドウを別にもう一つ開き、同様にsshでログインします。

```
# Picamの起動
cd
cat > run_picam.sh <<'EOF'
#!/bin/bash
sudo bash /home/pi/make_dirs.sh
sudo /home/pi/picam/picam --alsadev hw:1,0 --rtspout -w 640 -h 480 -v 1000000 -f 30
EOF

chmod +x run_picam.sh
./run_picam.sh
```

正常に起動すれば、この時点でもうベビーモニターは見れる状態になっているはずです。
ビューアーソフトを入れて確認してみましょう。

### 視聴できるか確認する

視聴には[VLC](https://www.videolan.org/vlc/index.ja.html)というアプリを使います。Win版、Mac版、iOS版、Android版とあり、色々なデバイスで視聴できます。

今回はWin版で確認します。(どのデバイスでも大丈夫です)
![ss_vlc_all.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/195133/c2582b35-57e8-fc4a-684e-4819a2d94762.png)
- 「ファイル」→「ネットワークストリームを開く」
- URLを次のように入力「rtsp://固定したIPアドレス:80/live/picam」
- 「再生」をクリック

iPhoneの場合は画面左上のカラーコーンアイコンを押すとメニューが出てくるので、中から「ネットワークストリーム」を選択し、同様にURLを指定して再生します。
![vlc_s.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/195133/884a1c77-f28d-f1b8-03ed-eef2ef48e70d.png)


### 自動起動の設定をする

さて、無事に視聴できることが確認できましたが、今のままではRPiの再起動時に毎回sshで入ってPicamと配信サーバーを手動で立ち上げなければなりません。自動起動するように設定します。

```bash
# rootになってから作業します
sudo su

cat > /etc/systemd/system/picam_svr.service <<'EOF'
[Unit]
Description=node-rtsp-rtmp-server for picam
Wants=network-online.target
After=network-online.target

[Service]
ExecStart=/usr/local/bin/coffee /home/pi/node-rtsp-rtmp-server/server.coffee
Restart=always
Type=simple

[Install]
WantedBy = multi-user.target
EOF

cat > /etc/systemd/system/picam.service <<'EOF'
[Unit]
Description=picam
Wants=picam_svr.service
After=picam_svr.service

[Service]
ExecStart=/home/pi/run_picam.sh
Restart=always
RestartSec=10s
Type=simple

[Install]
WantedBy = multi-user.target
EOF

systemctl daemon-reload
systemctl enable picam_svr
systemctl enable picam
```

試しに再起動をして、数分待ってVLCから視聴可能になっていることを確認してください。

これで完成です！
さっそくベビーベッドに取り付けてみましょう。

# まとめ

今回の構成のポイントはやはり複数の端末で同時に視聴できることです。キッチンにはiPadを常設し、お父さんの作業部屋ではデスクトップのWindows画面に映し、トイレに行くときはスマホで確認するなど、どんなときでも赤ちゃんの様子が確認できて安心です。

また、アームをちょっとひねればカメラの方向を簡単に変えられるので、ベビーベッドから下ろして遊ばせるときでも大丈夫です。

そして何よりRaspberry Piがベースとなっているので、ここから様々なセンサーやデバイスを追加して、工夫次第で色々な機能を追加していくことができます。最新のRaspberry Piは簡単な機械学習にも耐えられるスペックを持っているので、画像認識や音声認識と組み合わせても面白そうですね。

ぜひいろいろ試してみてください！