2015年1月13日

RaspberryPi + Webカメラ + GrovePi を試してみた

はじめに

Raspberry Piは安価(モデルによりますが3000円~5000円程度)で小型ながらもLinuxが動作するコンピュータであり、GPIOやI2Cといった各種I/Oを備えていることから、ロボット制御や簡易サーバに用いられています。

http://www.raspberrypi.org/

今回はRaspberry Piを使って、簡単な実験を行ってみたいと思います。
実験ではカメラとセンサー・制御デバイスを使ってみたかったので、以下のものを用意しました。

  • Raspberry Pi 本体
  • Webカメラ(Logicool製のものを用いました)
  • GrovePi 本体
  • Groveセンサー(今回は光センサと温度・湿度センサ)
  • LED(青,赤,緑)と抵抗
  • ブレッドボード、ジャンパ線
  • USBシリアルケーブル(無くてもよいがあったほうが便利)


GroveセンサーはArduinoプラットフォームでよく利用されているセンサー類や制御デバイス類であり、GrovePi は Groveセンサーを Raspberry Pi に接続するためのボードです。

http://www.dexterindustries.com/GrovePi/

GroveセンサーやGrovePiを扱っているところは少なそうですが、秋葉原や通販で入手可能なようです(私は秋葉原で購入しました)。

全体構想

ざっくりとした全体構想としては以下のようなものを考えました。

  • Raspberry PiにWebカメラを接続して、リモートから動画が見れる。
  • Grove Piに各種センサーを接続して、環境モニタリングができる。
  • LEDやモーターを接続して、遠隔からデバイス制御が行える。
  • ユーザーインターフェースはWebブラウザを用いる。


さっそくハードウェアおよびソフトウェア構成を検討したいと思います。

ハードウェア構成

Raspberry Pi と各種ハードウェアは以下のように接続しました。

RaspberryPi 本体
  + Web カメラ (Raspberry Pi と USB 接続)
  + GrovePi (Raspberry Pi の I/O ピンに直接接続)
    + 光センサー (GrovePi の A0 コネクタに接続
    + DHT11 温度・湿度センサー(GrovePi の D5 コネクタに接続)
    + LED (GrovePi の D2~D4 コネクタに接続)

全て接続すると以下の様な感じになります(Webカメラが写ってませんが...)。



ブレッドボード上には赤・緑・青のLEDと抵抗を差し込んでGrovePiのデジタル用コネクタに接続しています(写真では青が点灯しています)。また写真の右上にあるのが光センサー(左)と温度・湿度センサー(右)です。

ソフトウェア構成

動画ストリーミング

Rasberry PiにUSBで接続したWebカメラから、ブラウザで閲覧可能な形式でストリーミング配信できるソフトウェアを検討したところ mjpg-streaming というソフトウェアが適しているようでした。

http://sourceforge.net/projects/mjpg-streamer/

ソースコードからビルドしたあと、例えば以下のように mjpg_streamer コマンドを実行することで HTTP による動画配信が開始されます。

$ sudo ./mjpg_streamer -i "./input_uvc.so -f 30 -r 320x240 -d /dev/video0" -o "./output_http.so -w ./www -p 8080"


GrovePi ライブラリ

GrovePi に接続したセンサーや制御デバイスにアクセスするための、Python 用ライブラリが提供されているため、これを用います。

http://www.dexterindustries.com/GrovePi/engineering/python-library-documentation/

例えば、D2 に接続した LED の点灯は以下のように簡単にできます。

import grovepi
grovepi.pinMode(2, "OUTPUT")
grovepi.digitalWrite(2, 1)

なお grovepi ライブラリを import した時点でハードウェアにアクセスするようです。そのため、この python プログラムは root 権限(sudo)で起動する必要があります。


サーバサイド

ユーザインターフェースとしてはWebブラウザを想定しているので、サーバサイドには軽量なWebフレームワークを利用したいと思います。今回の実験ではデータベース連携なども不要なので Flask を利用することにしました。

http://flask.pocoo.org/

簡単に Web アプリを作成でき、例えば HTTP で '/' にGETアクセスされた時に、用意してあるテンプレートファイル 'index.html' を返すだけなら以下のように書けます。

from flask import Flask, render_template
app = Flask(__name__)

@app.route('/')
def index():
    return render_template('index.html')

if __name__ == '__main__':
    app.run(host = '0.0.0.0')

センサー値取得

GrovePi に接続したセンサーから値を取得するのに GrovePi の Python ライブラリを利用します。
  • 光センサーは A0 コネクタに接続しているので、grovepi.analogRead(0) で値が取得できます。
  • 温度・湿度センサーからの値取得には grovepi.dht() という専用の関数を利用します。センサーは D5 コネクタに接続したので、grovepi.dht(5,0) で値が取得できます。第二引数で温度・湿度センサーの種類を指定していますが、今回利用したセンサー(DHT11)では 0 を指定します。
/sensor という URL に GET アクセスすると、各種センサーの値を取得して JSON 形式で返す関数を用意します。

@app.route('/sensor')
def sensor():
    light = grovepi.analogRead(0)
    dht = grovepi.dht(5,0)
    return jsonify(light=light, dht=dht)

JSON 形式でレスポンスを返すため、Flask が提供する jsonify() 関数を用いています。

デバイス制御

デバイス制御にも GrovePi の Python ライブラリを利用しています。/ctrl/led/red や /ctrl/led/green など LED 毎に割り当てた URL に PUT または POST アクセスがあった場合に、LED を点灯(ctrl == 'on')または消灯(ctrl != 'on')させるコードは例えば以下のようになります。

@app.route('/ctrl/led/', methods=['PUT', 'POST'])
def ctrl_led(color=None):
    led_pin = dict(red=2, green=3, blue=4)
    ctrl = request.form.get('ctrl')
    led_on = 1 if ctrl == 'on' else 0
    grovepi.digitalWrite(led_pin[color], led_on)
    return jsonify(led=color, var=led_on)

ここでも結果は jsonify() 関数を使って JSON 形式で返しています。

クライアントサイド

ブラウザ側ではボタンが押されたときにデバイス制御を行ったり、定期的にセンサーの値を取得するために、Ajax でサーバにリクエストを送信することで実現しています。クライアントサイドでは jQuery ライブラリを利用していますので、以下のようにイベントハンドラで Ajax の発行を行っています。

$('.led-ctrl-red').on('mousedown mouseup', function(e){
    $.ajax({url: '/ctrl/led/red', data: {ctrl: e.type == 'mousedown' ? 'on' : 'off'}});
})

この例ではマウスを押下したときと離した時に、Ajax リクエストを発行しています。

動作確認

少し分かりにくいですが、動作させている様子です。

GREEN ボタンを押下している最中のスクリーンショットで、緑の LED が点灯していることが分かるかと思います。また、光センサーや温度・湿度センサーの値も毎秒取得して表示しています。温度は26度・湿度34度であることは分かりますが、光センサーはアナログの入力値をそのまま表示しているため、程度は分かりません。ただ、物をかぶせて暗くすると数値は下がるので、強弱の遷移などは分かりそうです。

 あと静止画のキャプチャなので分かりませんが、背景画像はWebカメラのストリーミングを表示しています。mjpg-streamer は非力な Raspberry Pi でも大きな遅延なく動画配信できているので、なかなか優秀ですね。

まとめ

RaspberryPi に Webカメラや GrovePi を接続して、ブラウザ上で動画やセンサー情報を見ながら、デバイス制御が出来ることは確認できました。これをベースにもう少し複雑なデバイス制御や、他のセンサーとの連携などの発展を考えていきたいと思います。

0 件のコメント:

コメントを投稿

注: コメントを投稿できるのは、このブログのメンバーだけです。