100均のBluetoothシャッターとRaspberry Piカメラでオンラインデジカメを作ってみた

百均で手に入るBluetoothシャッター(100円ではありませんが)とカメラ付きRaspberry Piで、撮影画像をS3に保存できるデジタルカメラを製作してみました。
2020.07.21

データアナリティクス事業本部の藤川です。 100均で手に入るBluetoothシャッター(100円ではありませんが)とカメラ付きRaspberry Piで、撮影画像をS3に保存できるデジタルカメラを製作してみました。

システム構成図

簡易デジカメ構成図

用意するもの

  • Bluetoothシャッター
  • Raspberry PiまたはPi Zeroシリーズ本体
  • Raspberry Pi Cameraシリーズ(v1/v2/HQ)

※その他、microSDカード、モバイルバッテリー、モバイルWifiルータ等は適宜用意してください。

前提条件

  • Raspberry Pi OS(旧Raspbian)(32bit版)がセットアップ済みであること
  • Raspberry PiがWifi経由でインターネットに接続されていること
  • Raspberry Pi本体にPi Cameraシリーズ(v1/v2/HQ)のいずれかが接続されていること
  • IAMユーザーが作成済みであること
  • Raspberry Pi OSにAWS CLI v1(Linux版)がインストールされていること
    ※Raspberry Pi OSは64bit対応していますが、多くが32bit版のため、本記事は32bit版対応とします。
$ curl "https://s3.amazonaws.com/aws-cli/awscli-bundle.zip" -o "awscli-bundle.zip"
$ unzip awscli-bundle.zip
$ sudo ./awscli-bundle/install -i /usr/local/aws -b /usr/local/bin/aws
$ aws --version
aws-cli/1.18.100 Python/2.7.13 Linux/4.19.66+ botocore/1.17.23
  • ~/.aws/config、credentialファイルがセットアップ済みであること

Bluetoothシャッターとペアリング

BluetoothシャッターとRaspberry Pi本体をペアリングします。 ここでは、コマンドラインでペアリングしていますが、GUIから作業しても構いません。

1.Bluetoothシャッターの電源をONにします。

2.Raspberry Pi OSでbluetoothctlコマンドを実行します。

$ sudo bluetoothctl

3.Bluetoothデバイスのスキャンを開始します。

[bluetooth]# power on
[bluetooth]# scan on

4.AB Shutter3というデバイスが表示されるので、MACアドレスを控えておく。

[NEW] Device FF:FF:3F:xx:xx:xx AB Shutter3

5.先ほど控えたMACアドレスを引数に指定し、pairコマンドを実行します。

[bluetooth]# pair FF:FF:3F:xx:xx:xx

6.次のように表示される。

Attempting to pair with FF:FF:3F:xx:xx:xx
(中略)
Pairing successful

7.paired-devicesコマンドで、Bluetoothシャッターがペアリングされていることを確認します。

[bluetooth]# paired-devices
Device FF:FF:3F:xx:xx:xx AB Shutter3

8.先ほど控えたMACアドレスを引数に指定し、trustコマンドを実行します。

[bluetooth]# trust FF:FF:3F:xx:xx:xx

9.次のように表示されるとBluetoothシャッターとのペアリングが完了。

Changing FF:FF:3F:xx:xx:xx trust succeeded

10.Bluetoothデバイスのスキャンを停止します。

[bluetooth]# scan off

11.bluetoothctlコマンドを終了します。

[bluetooth]# quit

12.Bluetoothシャッターの電源をOFFにしても構いません。電源ONすると、再度ペアリングされます。

Bluetoothシャッターでコマンドを実行

Bluetoothシャッターのボタンを押すと、設定したコマンドが実行されるようにします。ここでは、BlueButtonというRubyで書かれたOSSを使用します。
※参考:https://github.com/kinnalru/bluebutton

1.BlueButtonをインストールします。

$ sudo apt install ruby
$ sudo gem install bluebutton

2.BlueButtonの設定ファイルを作成します。

$ vi ~/.config/bluebutton
keyup=echo UP
keydown=echo DOWN
longup=echo LONG UP
longdown=echo LONG DOWN

3.BlueButtonを実行し、動作確認します。

$ bluebutton -d="AB Shutter3" -c /home/pi/.config/bluebutton

4.Bluetoothシャッターでボタンを押すとDOWNと表示され、ボタンを離すとUPと表示されるようになります。
※[CTRL]+[C]キーを押下すると、コマンドを終了できます。

DOWN
UP
DOWN
UP

5.Bluetoothシャッターでボタンを押すと、Raspberry Pi Cameraで撮影したJPEGファイルをローカルに保存できるようBlueButtonの設定ファイルを編集します。

$ mkdir ~/pictures
$ vi ~/.config/bluebutton
keyup=echo READY
keydown=echo SHOT; raspistill -n -t 1 -o /home/pi/pictures/image_`date +%Y%m%dT%H%M%SZ`.jpg

6.もう一度、BlueButtonを実行し、動作確認します。

$ bluebutton -d="AB Shutter3" -c /home/pi/.config/bluebutton

7.Bluetoothシャッターでボタンを押すとSHOTと表示され、ボタンを離すとREADYと表示されるようになります。

8.問題なければ、Raspberry Pi OS起動時にBlueButtonが常駐するよう設定します。

$ crontab -e
@reboot /usr/local/bin/bluebutton -d="AB Shutter3" -c /home/pi/.config/bluebutton

S3バケットを作成

撮影画像の保存先となるS3バケットを作成します。バケットへのアクセス権限はIAMユーザーでコントロールします。

1.S3バケットを作成します。

$ aws s3 mb s3://bucket-name
make_bucket: bucket-name

2.バケットポリシーエディターでバケットポリシーファイルを作成します。
※ここでは、例として、iot-userというIAMユーザーに作成したS3バケットのオブジェクトに対するフルアクセス権限を付与しています。

Key Value
Select Type of Policy S3 Bucket Policy
Effect Allow
Principal arn:aws:iam::xxxxxxxxxxxx:user/iot-user
Actions All Actions('*')
Amazon Resource Name (ARN) arn:aws:s3:::bucket-name/*

3.[Add Statement]ボタンをクリックします。

4.[Generate Policy]ボタンをクリックします。

5.バケットポリシーファイルを保存します。
※AWS CLIコマンドを実行できる環境で作業してください。Raspberry Piでも構いません。

$ vi bucket-policy.json
{
  "Id": "Policy1595174135036",
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "Stmt1595174066635",
      "Action": "s3:*",
      "Effect": "Allow",
      "Resource": "arn:aws:s3:::bucket-name/*",
      "Principal": {
        "AWS": [
          "arn:aws:iam::xxxxxxxxxxxx:user/iot-user"
        ]
      }
    }
  ]
}

6.作成したバケットにバケットポリシーを設定します。

$ aws s3api put-bucket-policy --bucket bucket-name --policy file://bucket-policy.json

撮影画像をS3にアップロード

S3Sync(AWS CLI)を使用して、Raspberry Pi OSのローカルフォルダとS3バケットを同期します。一定間隔で同期することで、撮影画像がS3にアップロードされるように振る舞います。

1.~/picturesフォルダからbucket-nameバケットに同期します。
※バケットポリシーで設定したIAMユーザーで同期するよう、~/.aws/configファイルに設定してください。

$ aws s3 sync ~/pictures s3://bucket-name

2.bucket-nameバケットにあるオブジェクトを一覧表示し、撮影画像が同期されていることを確認します。

$ aws s3 ls s3://bucket-name

3.Raspberry Pi OSが起動すると、一定間隔(例では1分間隔)で同期されるよう設定します。

$ crontab -e
*/1 * * * * /usr/local/bin/aws s3 sync /home/pi/pictures s3://bucket-name

完成

Raspberry Pi OSをリブートし、Bluetoothシャッターを電源OFF/ONしてください。これで、簡易デジタルカメラの完成です。

$ sudo reboot

今後の改善ポイント

撮影画像はS3にアップロードされていますので、撮影から1ヶ月以上経過したファイルを削除したいと考えました。 Raspberry PiのmicroSDカード容量を節約できて良いのですが、万が一、長期間ネットワークに接続できなかったときのことを考えると、自動削除は危険と判断し、対応しませんでした。

そして、何より、撮影画像の参照方法が実用的ではありません。AWSマネジメントコンソールでS3を参照させるのは、ちょっといただけません。この辺りは、今後の改善課題にしたいと思います。

さいごに

raspistillコマンドの処理が遅い場合、-tパラメータの値を疑ってください。-t 1と指定すると、撮影開始まで1ms待ちます。-nパラメータはプレビュー表示しないためのオプションです。

製品名 イメージセンサー イメージサイズ 画素数 有効画素数 raspistillコマンド処理時間(待機時間1msを含む)
Raspberry Pi Camera Module v1 OmniVision OV5647 1/4インチ 5M 2,592 x 1,944 0.726s
Raspberry Pi Camera Module v2 Sony IMX219 1/4インチ 8M 3,280 x 2,464 ※手元にありません
Raspberry Pi HQ Camera Sony IMX477 1/2.3インチ 12.3M 4,056 x 3,040 2.001s
  • 画像圧縮処理の影響を排除するため、レンズをレンズキャップ等で覆い、次のコマンドを実行して測定
$ time raspistill -n -t 1 -o ~/pictures/image.jpg