ニコニコとトコスティックとラズパイでドアカメラ
使用したラズパイはクアッドコアのRaspberry Pi2。シングルコアのB+でも問題ないだろう。USB端子が1つしかないA+の場合はトコスティックを接続すると全端子がふさがってしまい、ネットワーク接続を確保できない。ここでは撮った写真をサーバーにアップロードするところまで作るので、B+または2を前提に説明する。
ラズパイのWi-Fi設定については触れないが、ググればすぐ参考になるページが見つかるだろう。これから始めるラズパイ上の作業はsshで他のコンピュータからログインして行なう。
プログラミングを始める前に、ニコニコから送られてくる生データをラズパイ上で見てみよう。ターミナルソフトウエアにcuを使う例を示すので、まず次のコマンドでcuをインストールする。
sudo apt-get install cu
トコスティックをUSBポートに接続した状態で次のようにすると、受信データが表示されるはずだ。
cu -l /dev/ttyUSB0 -s 115200
ttyUSB0はUSBシリアルデバイスとして認識されたトコスティックを表し、115200はその通信レートだ。接続が成功すると、次のようなデータがぽつぽつと1秒ごとに表示される。
::ts=8380
::ts=8381
「ts」はタイムスタンプの略。ここで先ほど設定したニコニコに電池を入れると、次のようなデータが連続的に表示されるだろう。
::rc=80000000:lq=57:ct=005E:ed=81015F52:id=0:ba=2970:a1=1288:a2=0658:x=0011:y=-018:z=-136
このデータの読み方は、こちらのページで詳しく説明されている。『無線タグアプリで使ってみる』
複数のニコニコがトコスティックの受信範囲にあるとき、それらからのデータを同時に受信できるが、データは混ざりあってしまう。仕分けるには「ed=」以下のMACアドレスを見るのが一番単純な方法だ。加速度センサーのデータはx=、y=、z=の部分で、これは先ほどのスマホアプリのグラフを思い出せば意味がとれるだろう。
Pythonスクリプトで処理する
「cu」による生データ観察ができたら、「~.」(cuの終了コマンド)を入力してコマンドラインに戻ろう。そして、cuの代わりにPythonスクリプトを作ってトコスティックからデータを取得してみる。ファイル名はread2525.pyとでもしておこう。
#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys
import serial
ser1 = serial.Serial("/dev/ttyUSB0", 115200)
while 1:
if ser1.inWaiting() > 0:
sys.stdout.write(ser1.readline())
sys.stdout.flush()
この短いスクリプトを実行すると、トコスティックの出力がシェルに流れてくる。事前に
chmod 775 ./read2525.py
として、実行フラグを立てておくと便利だ。次のようにすると、ファイルにデータを保存できる。
./read2525.py > log
control+cでスクリプトを止め、lsすると、logというファイルができていて、そこにデータが保存されているはずだ。
データの流れをスクリプトで捕らえられるようになった。次はそのデータを処理するスクリプトを作る。ここでいう処理とは、次のような内容だ。
- 指定したニコニコからの「動き」を示すデータを検出する
- カメラモジュールを使って撮影し画像ファイルとして保存する
- そのファイルを指定したサーバにFTPでアップロードする
できあがったPythonスクリプトを下記に示す。
#!/usr/bin/python # -*- coding: utf-8 -*- import os, sys, datetime, threading from ftplib import FTP import picamera # apt-get install python-camera sensorAddress = "81015F52" # 対象TWE-LiteのMAC address extension = ".jpg" delay = 3 # second messageCounter = 0 def takePicture(): d = datetime.datetime.today() dt = d.strftime("%Y%m%d%H%M%S") with picamera.PiCamera() as camera: camera.resolution = (640, 480) camera.annotate_text_size = 20 camera.annotate_text = dt camera.capture(dt + extension) print dt + extension try: ftp = FTP("your.server", "id", "password") ftp.cwd("/home/your/space/") f = open(dt + extension, 'rb') command = "STOR " + dt + extension ftp.storbinary(command, f) # put file f.close() ftp.quit() except Exception, e: print "ftp error: " + str(e) while True: line = sys.stdin.readline() if "ed=" + sensorAddress in line: messageCounter += 1 if messageCounter % 2 == 1: # 1行おきに処理(動き始めだけを見る) print "acceleration detected. taking a picture..." t = threading.Timer(delay, takePicture) t.start()
先ほどのスクリプトと比較すると少し長いが、それなりに複雑な処理をこれだけの行数で記述できてしまうのだから、ラズパイとPythonの組み合わせは強力だ。もっともエラー処理をほとんどしていないので、実用に供するためには例外的な状況に対処するコードがたくさん必要となるだろう。あくまでもサンプルプログラムとして見てほしい。
スクリプト名がcamera.pyだとしたら、実行は次のようにする。
./read2525.py | ./camera.py
おっとその前に、ラズパイのカメラ設定が有効になっていることを確認しよう。コマンドラインからは
sudo raspi-config
として設定ツールを起動すれば調べることができる。設定変更もこのツールだ。それから、カメラコントロールのためのPythonライブラリも必要。
sudo apt-get install python-picamera
とすればよいだろう。
事前の設定はニコニコ側にも必要となる。スマホと組み合わせて使ったニコニコは加速度センサーのデータを一定間隔で送り続けるという設定だった。今度はドアの開閉という静止状態から突然発生する動きに反応したいので、もう一度OTA設定を行なって、動きの検出に適したモードに変更する。ニコニコの設定については次のページで詳しく説明されている。『IoT無線タグ設定の詳細説明』
このページの「動作モードとパラメータの変更」に記載されている「モード8 Active/Inactive」がドアの開閉の検出に使えそうだ。準備が整ったら、2つのスクリプトを組み合わせて実行してみよう。
./read2525.py | ./camera.py
こうするとread2525.pyが受信したデータはパイプ(|)で接続されたcamera.pyへ送られ処理される。
camera.pyは指定したMACアドレスを持つニコニコからのデータだけに反応する。ニコニコ側で動作を検出するので、データが来たら観測対象が動いたと判断して(加速度センサーの値は無視して)撮影する。ただし間髪入れず撮ってしまうとドアしか写らない。撮りたいのはドアを開けて入ってきた何かなので、ウエイト(wait)を入れられるようにした。このあたりの処理は別スレッドで行なうようになっているので、ドアが頻繁に開け閉めされるような状況でもたぶん大丈夫だろう。
サーバーへのアップロードにはFTPを使っているが、この部分は用途に応じた変更を加えてほしい。Pythonのサンプルコードはすぐに見つかるだろう。アイデアジェネレーターと連携させる場合は前回の記事の最後で紹介したスクリプトが参考になるかもしれない。
「OpenCV(オープンソースコンピュータビジョン)」を使ってサンタ検出スクリプトを作ろうと思い、サンタの帽子とヒゲをつけてみたが、服もサンタにすべきだった。OpenCVはラズパイでも動作する画像処理ソフトウェア。顔認識も可能だ。時間切れでそこまで紹介できなかったが、個人プロジェクトとして取り組むつもり。
コンテストの締め切りは11月30日
皆さんの発想の邪魔にならないよう「ドアカメラ」という地味な作例を示したわけだが、加速度センサーとカメラだけでできることは無数にありそうだ。センサーをどこに付けるかで意味合いが全然違ってくる。玄関ではなくトイレのドア、冷蔵庫の扉、ベランダの洗濯物、勝手に開けられたくない引き出し、猫ドア、家族の手首、赤ちゃんのぬいぐるみの中……。
加速度以外のデータがほしい場合は、センサー選びから始めることになるだろう。TWE-Liteモジュールにセンサーを接続するときは、次のページが参考になる。『遠隔監視 - I2C入力』
センサーによっては、ソフトウェア資産が豊富なArduinoを使うほうが楽な場合もある。そのあたりは臨機応変に考えよう。今回のドアカメラのように動きに反応して写真を撮るかわりに、モーターやソレノイドで別の動きを作り出したい場合(例えばノックすると自動的に鍵が外れるとか)は、ラズパイに駆動回路を付け加える必要がある。この場合も作例が豊富なArduinoの併用を検討するといいだろう。
浮かんだアイデアを形あるものに変える方法を見つけるには、先例を検索するのが有効な手段だ。でも、調べ物ばかりしているとなかなかモノが出来上がらなかったりもする。実際に手を動かして、試しに作ってみることも同じくらい大事だ。
コンテストの締め切りは11月30日。時間はまだあるので、手を動かして、モノを作りながら、アイデアを膨らませてほしい。