4時間目:つくって解るIoT -その2- 実験編

身長計をつくってみよう

プログラミング

Raspberry Pi の設定お疲れ様でした。いよいよ電子工作実験を行っていきたいと思います。ここからは次のような順番で行っていきます。

1. プログラミングの環境を整える  →  2. Raspberry Piのプログラミング  →  3. PCのプログラミング

ここから先は上手くいかないことがかなり多くなると思いますが、頑張っていきましょう。

1. プログラミングの環境を整える

まずは基礎となるプログラミングの環境を整えていきましょう。今回はNode.js を使っていきます。

Node.js は、サーバーサイドJavaScript環境です。言葉だけではイメージしにくいかもしれませんが、簡単に言うとブラウザなどの目に見えないところでも処理が行えるようにするための実行環境です。

Node.js はnpmと呼ばれる管理ソフトをつかってパッケージを利用することができます。
パッケージとは人間と機械をつなぐために必要な機能などをまとめた入れ物と考えてください。

  1. Node.js のインストール
    PCにインストールするのは簡単ですが、Raspberry Pi にインストールするとなると少し複雑になります。
    今回はv0.12.15を使います。最新のバージョンではないのですが、超音波距離センサーを使うために古いものを使います。
    Nodeのバージョン管理はnvm というシステムを使うと簡単に行うことができます。
    (1)git のインストール

    $ sudo apt-get install git-core

    これで git が使えるようになりました。
    (2)nvm のインストール

    $ git clone https://github.com/creationix/nvm.git /usr/local/nvm

    $ source /usr/local/nvm/nvm.sh

    これでnvm をインストールし、有効にすることができます。
    (3)Node.js のインストール(インストールには1時間以上時間がかかります。)

    $ nvm install v0.12.15

    これでNode.js のインストールは完了です。最後にインストールが成功したか確認します。

    $ nvm ls

  2. npm とパッケージのインストール
    Node.js のインストールが終わったら今度はnpm をインストールしましょう。
    (1)npm のインストール

    $ sudo apt-get install npm

    確認メッセージが出てきたら”y”を入力してインストールを開始してください。
    (2)パッケージのインストール
    今回使うパッケージは”r-pi-usonic”と”socket.io”の2つです。
    “r-pi-usonic”は Raspberry Piと超音波センサーを接続するためのもので、“socket.io”は非同期の双方向通信をするためのパッケージです。
    「非同期の双方向通信」とは... 例を用いて説明すると、ブラウザでサーバーにある画像を表示しているとき、サーバーの画像が更新されるとリアルタイムで更新してくれるように通信することです。

    $ mkdir -p ~/Public/app && cd $_

    $ npm init

    ここでいくつか質問されますがすべてEnterキーを押してください。

    $ npm I -D r-pi-usonic socket.io

これでプログラミングをする環境は整いました。

2. Raspberry Piのプログラミング

  1. プログラミングを始める前に配線を行っていきましょう。
    配線ではブレッドボードを使います。ブレッドボードとはハンダ付けをしなくても回路が作れる基盤のようなものです。見た目は穴が等間隔で空いているだけの板ですが中は図の黄色い線のように電気が流れるようになっています。超音波センサーのピンにも役割が書いてあるので間違えないようにしましょう。
    Vcc ― 5V
    Trig ― GPIO18
    Echo ― GPIO17
    GND ― GND
  2. ボード ボード構造 配線
  3. (1)distance.jsファイルを作成します。

    $ nano ~/Public/app/distance.js

    (2)次のコードを作成してください
    コードはこちらをクリック
    var usonic = require('r-pi-usonic'); //
    //
    var sensorConfig = {
    	echoPinGPIO:	17,
    	triggerPinGPIO: 18,
    	timeout:    	1000
    };
    /**
     *
     */
    //
    usonic.init(function (error) {
    	if (error) {
        	console.error(error)
    	}
    	else {
         	//
         	sensor = usonic.createSensor(
             	snsorConfig.echoPinGIPO,
             	sensorConfig.triggerPinGPIO,
             	sensorConfig.timeout
         	);
         	//
         	console.log( "Distance : " + sensor());
       }
    });
    
    閉じる
    (3)保存したら実行します。

    $ sudo node ~/Public/app/distance.js

    “Distance:”の後に数値が表示されたら成功です。センサーの前に手をかざして数値が変わるか試してみましょう。
  4. 距離を測定するだけならこのコードだけでできるのですが、今回はブラウザで結果が表示できるようにします。
    (1)app.jsファイルを作成

    $ nano ~/Public/app/app.js

    (2)次のコードを作成してください
    コードはこちらをクリック
    /**
     *
     */
    var port     	= 3000; //
    var intervalTime = 500;  //
    var con	= null; //
    var sensor = null; //
    var timer  = null; //
    var io 	= require('socket.io')(port);
    var usonic = require('r-pi-usonic');
    //
    var sesorConfig = {
    	echoPinGPIO:   17,
    	triggerPinGPIO:18,
    	timeout:   	1000
    };
    /**
     *
     *
     */
    //
    usonic.init(function (error) {
    	if (error) {
        	console.error(error)
    	}
    	else {
        	sensor = usonic.createSensor(
            	sensorConfig.echoPinGPIO,
            	sensorConfig.triggerPinGPIO,
            	sensorConfig.timeout
        	);
    	}
    });
    //
    io.on('connection', function (socket) {
    	con = socket;
    	//
    	socket.on('start', function (msg) {
        	timer = setInterval(function () {
            	con.emit("sensor", sensor()); //
        	}, intervalTime);
    	});
    	//
    	socket.on('end', function() {
        	clearInterval(timer);
    	});
    });
    
    閉じる
    (3)保存をしたら実行します。

    $ sudo node ~/Public/app/app.js

      
これでRaspberry Pi側からブラウザへ接続する準備ができました。

3. PCのプログラミング

意見Raspberry Piでブラウザにデータを反映する準備ができたので、今度はPC側の準備をしていきましょう。

  1. 接続しているPCにディレクトリを作成します。

    $ mkdir -p ~/Sintyou
    $ cd Sintyou

  2. このディレクトリにhtml.indexを作成します

    $ nano index.html

  3. index.htmlを編集します
    ソース
  4. 保存をしたら、index.jsを作成します

    $ nano index.js

  5. index.jsを次のように編集します。
    ソースはこちらをクリック
    /**
      *
      */
    var element = document.getElementById("distance");
    var start   = document.getElementById("start");
    var end   = document.getElementById("end");
    var socket  = null;
    var isStart = false;
    var host	="Raspberry PiのIPアドレスを入力"; //
    var port	="Raspberry Piのポート番号を入力"; //
    var criteria       = 200;                                                 //
    //
    function init () {
    	//
    	start.addEventListener("click", function () {
        	if (isStart) return;
    	//
    	isStart = true;
    	
    	//
    	start.disabled = isStart;
    	end.disabled   = !isStart;
    	//
    	open();
    	//
    	socket.emit ('start', "");
     });
     //
     end.addEventListener("click", function () {
     	if (!isStart) return;
     	//
     	isStart = false;
     	//
     	start.disabled = isStart;
     	end.disabled   = !isStart;
    	//  
    	socket.emit ('end', "");
     }); 	
    }
    /**
     *
     *
     */
    function open () {
    	if (socket == null) {
        	//
        	socket = io(host + ':' + port);
        	//
        	socket.on('connect_error', function (error) {
            	console.error(error)
        	//
        	isStart = false;
        	//
        	start.disabled = isStart;
        	end.disabled   = !isStart;
     	});
     	//
     	socket.on('connect', function (con) {
         	console.log('connected!);
     	});
     	//
     	//
     	socket.on('sensor', function (value) {
         	//
         	height = parseFloat(value);
               height = criteria - height;
    
         	//
         	element.innerText = height.toFixed(2) + 'cm';
     	});
       }
    } 
    
    //
    init();
    
    閉じる
  6. 保存したらindex.htmlを実行してみましょう
    身長 Startボタンを押すと200からdistance.jsで計測した数値を引いた値が出てきます。
    ここまでの作業が完了したら、超音波距離センサーを床から2mの高さに設置しましょう。設置する高さを上げたいときにはindex.jsの”var criteria = 200”の数字を設置したい高さに変更すれば身長は正しく計測されるはずです。

実験結果と考察

プログラミング ここまで実験の手順を紹介してきましたが、今回自分たちで作った結果、Raspberry Piで距離を測るところまでしかたどり着けませんでした。
Index.jsの編集まで行ったものの、”start”を押しても数値がブラウザに反映しませんでした。

<考えられる要因>
● スペースが本来半角であるべきなのに全角で入力してしまっている。
● Raspberry Piとブラウザとの間のデータのやり取りが何らかの原因でうまく動作していない
● コード内では予期されていなかったことが起きたため、反応が返ってこない。
などがあげられます。
何度も設定を見直したり、ソースを書き直したり、本やインターネットで調べて試行錯誤しましたが残念ながら、このWebページの締め切りまでには解決することができませんでした。


<センサーの調査>
そこで、今回は超音波距離センサーによる距離測定の精度を調べました。まず、センサーとの距離20cmの場所に置いた板までの距離を調べた場合、ピッタリではなかったものの、ほぼ20cmの値を計測することができました。

結果1

次に、同じ20cmの場所に板を斜めに置いて調べます。その結果、かなり大きな誤差が生まれていることがわかります。

結果2

これは、板が傾いているために超音波がいろいろな方向へ反射してしまうため、超音波を受信しても正確な数値を出すことができないからです。

考える Raspberry Pi工作実験のまとめと感想

4時間目ではRaspberry Piを使って、電子工作実験にチャレンジしました。
実験の目標(スマート身長計で身長を測定する)を完成することができませんでしたが、「電子工作を楽しむ」「IoTの仕組みを考える」というこのページの目的には到達することができました。同時にコマンドなどを使ってIoTを作り上げていくという難しさを知りました。

<反省点>

・準備不足
限られた予算と時間の中で、必要なものを本などで調べて準備たが、もう少し計画段階で検討する必要があると感じた
・環境依存
開発する場所のネットワーク環境(例:セキュリティソフトやファイヤーウォール等)に依存する違いがあった
・作業分担
プログラミング作業という特性上、特定のメンバーに作業が集中した
・経験・知識不足
作業に行き詰まった時に、経験者に意見を聞いたりしたが、環境の違いからか同じ不具合を再現して説明できず適切なアドバイスを受けることができなかった


しかし、IoT製品を発想しそれをカタチにしていく実践過程と困難性を体験できたことは、大きな収穫となりました。
以下活動の記録です。

実験のまとめ


現在皆さんが使っているGUI環境のPCでは、データのダウンロードやファイルの新規作成などの動作を簡単に行うことができますが、プログラミングなどを用いて文字だけでコンピューター上の動作が実行できるようにするということの難しさは実際にRaspberry Piなどの機器を扱ってみると体感できると思います。

「スマート身長計」を皆さんにお見せすることができずに終わり残念ですが、皆さんも、色々なアイデアを実際に作ってみてプログラミングやIoTを体験してみてください。
僕たちも次のアイデアを考え、またぜひチャレンジしてみたいと思います!

もどる ホームページへ すすむ


Webコンテスト
「知っ得!IoTハイスクール」は、第20回全国中学高校Webコンテスト参加作品です。