ブログ

Armadillo-IoT+無線センサーネットワーク「ミスター省エネ」:温度、湿度・照度、人感、CO2ノードのデータを取得して、Herokuに送信してWebブラウザで確認

at_kazutaka.bito
2016年2月24日 19時17分

Armadillo-Iotとセイコーソリューションズ株式会社様の無線センサーネットワーク を使って、 Armadillo-IoT+USBベース(SW-4000-1000)(920MHz無線親機)

温・湿・照度ノード(SW-4210-1204)(920MHz無線子機)

CO2ノード(SW-4230-1000)(920MHz無線子機)

人感ノード(SW-4220-1010)(920MHz無線子機)

の組み合わせで、 セイコーソリューションズ株式会社様の無線センサーネットワーク(920MHz無線)の 各センサーノードから温度、湿度、照度、CO2、人検出のデータをArmadillo-IoTで読み取って、クラウド(Heroku)経由で見てみました。

(ブラウザのURLの部分は、後述の手順でHerokuから割り当てられたURLになりますので、伏字(***.herokuapp.com)にしてます。)

当方で確認した手順、サンプルプログラムを下記に説明します。
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
注意)
ここでは、当方が確認した簡易的な手順を示しているに過ぎません。(エラー処理等は考慮されていません。)
本格的には、エラー処理、フェイルセーフなどを行う必要があります。
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

以下、 USBベース(SW-4000-1000)(920MHz無線親機)は、「USBベース(無線親機)」
温・湿・照度ノード(SW-4210-1204)(920MHz無線子機)は、「温・湿・照度ノード」
CO2ノード(SW-4230-1000)(920MHz無線子機)は、「CO2ノード」
人感ノード(SW-4220-1010)(920MHz無線子機)は、「人感ノード」
と呼称します。

今回の動作確認は下図のような構成です。

手順の概要は下記のようになります。
 1.機材、資料の準備
 2.Armadillo-IoTでUSBベース(無線親機)を使う準備
 3.各ノードから取得したデータの確認
 4.各ノードからデータを取得するサンプルプログラム
 5.クラウド(Heroku)側のアプリの準備
 6.温度・湿度・照度、CO2、人感ノードのデータをクラウド(Heroku)で見る

1.機材、資料の準備

機材は下記のもの使用しました。
・Armadillo-IoT+USBベース(SW-4000-1000)(920MHz無線親機)
 Aramdillo-IoTのUSBポートに、USBベース(無線親機)を接続します。
温・湿・照度ノード(SW-4210-1204)(920MHz無線子機)
CO2ノード(SW-4230-1000)(920MHz無線子機)
人感ノード(SW-4220-1010)(920MHz無線子機)

今回の動作確認において、下記の資料を参考にしました。
無線センサーネットワークのサポート(ダウンロード)
 よりダウンロードできるUSBベース(無線親機)、温度・湿度・照度、CO2、人感ノードの製品仕様書(※要ID/パスワード)
 ※)ダウンロードページのID、パスワードは、セイコーソリューションズ株式会社様へ、メールまたはフォームからお問い合わせください。

2.Armadillo-IoTでUSBベース(無線親機)を使う準備

USBベース(無線親機)の製品仕様書より、USBを仮想シリアルポートとすることで、 Armadillo-IoTとUSBベース(無線親機)はシリアルで通信できます。

同製品仕様書より、USBベース(無線親機)は、FTDI製のUSBシリアルコンバーターを使用しているので、 Armadillo-IoTのカーネルコンフィギュレーションで、FTDI製のUSBシリアルコンバーターのドライバを有効にします。

ATDEで、make menuconfigを実行して、カーネルコンフィギュレーションで下記のように設定を行います。
(USB FTDI Single Port Serial Driverを有効にします。)

Kernel Configuration
  Device Drivers --->
    [*] USB support --->
    <*> USB Serial Converter support --->
    <*> USB FTDI Single Port Serial Driver

上記の設定後、ビルドしたイメージをArmadillo-IoTに書き込んで、起動します。

Armadillo-IoTにUSBベース(無線親機)が接続されている状態の場合、下記のように認識されているログが表示されます。

[root@armadillo-iotg (ttymxc1) ~]# usb 1-1: new high-speed USB device number 3 using ci_hdrc
hub 1-1:1.0: USB hub found
hub 1-1:1.0: 2 ports detected
usb 1-1.1: new full-speed USB device number 4 using ci_hdrc
ftdi_sio 1-1.1:1.0: FTDI USB Serial Device converter detected
usb 1-1.1: Detected FT232RL
usb 1-1.1: Number of endpoints 2
usb 1-1.1: Endpoint 1 MaxPacketSize 64
usb 1-1.1: Endpoint 2 MaxPacketSize 64
usb 1-1.1: Setting MaxPacketSize 64
usb 1-1.1: FTDI USB Serial Device converter now attached to ttyUSB0
usb 1-1.2: new full-speed USB device number 5 using ci_hdrc

上記のログより、USBシリアルコンバーターはttyUSB0として認識されています。 以降の説明において、USBベース(無線親機)のデバイスファイルは、"/dev/ttyUSB0"の場合で説明します。

3.各ノードから取得したデータの確認

Armadillo-IoTでtipコマンドを使って、USBベース(無線親機)とシリアル通信を始めます。
(デバイスファイル名は、手順2で確認した"/dev/ttyUSB0"を指定します。  ボーレートは、USBベース(無線親機)の製品仕様書より、115200を指定します。)

温・湿・照度ノード、CO2ノード、人感ノードの電源がONになっている場合、下記のようなログが表示されます。
(各ノードは定期的にデータを送信しているので、データを受信次第、ログが追加されます。  他にもソフトウェアバージョン通知などのログも出力されますが、下記は今回使用するログのみを抜粋しています。)

[root@armadillo-iotg (ttymxc1) ~]# tip -l /dev/ttyUSB0 -s 115200
Connected.
GID:0x65,RID:0x00,CH:0x3C,MSG:0x0B0000000000000000000006,IDX:0xF8,SID:0xE6,RT:0x00E6FFFFFF380000A5A0
GID:0x65,RID:0x00,CH:0x3C,MSG:0x03000000A0269A310A000955,IDX:0xF9,SID:0xE7,RT:0x00E7FFFFFF380000A5C6
GID:0x65,RID:0x00,CH:0x3C,MSG:0x200000000000000000001142,IDX:0x09,SID:0xE8,RT:0x00E8FFFFFF380000A58A
(と、出力し続ける。)
("~."と入力(文字は表示されない)するとシリアル通信終了。)

各ノードの製品仕様書を参考に読み解くと、

GID:グループID
RID:宛先ID
CH:通信チャネル
MSG:メッセージ
IDX:インデックス
SID:通信元ID
RT:ルート情報

という意味で、MSGの箇所が各ノードによって、異なるデータとなっているようです。

各ノードの製品仕様書と照らし合わせると、 温・湿・照度ノードは、MSGの頭の2文字が"03"と定義されており、上記のログの場合、
MSG:0x03000000A0269A310A000955

03:ユニットタイプ(温・湿・照度ノード)
00:制御コード(00:温度・湿度データ)
00:電池電圧(00:2.8V以上)
00:固定値
A:固定値
0:温度データの符号(0:プラス)
269:温度(BCDフォーマットなので、26.9[度])
A:固定値
310:湿度(BCDフォーマットなので、31.0[%])
A0:固定値
00955:照度(BCDフォーマットなので、955[lx])

CO2ノードは、MSGの頭の2文字が"20"と定義されており、上記のログの場合、
MSG:0x200000000000000000001142

20:ユニットタイプ(CO2ノード)
00:制御コード(00:CO2ノード)
00:サブ制御コード(00:出力)
000000:固定値
000000001142:CO2濃度(BCDフォーマットなので、1142[ppm])

人感ノード(イベントドリブン)は、MSGの頭の2文字が"0B"と定義されており、上記のログの場合、
MSG:0x0B0000000000000000000006

0B:ユニットタイプ(人感ノード:イベントドリブン)
00:制御コード(00:検出時送信、検出カウント数)
00:電池電圧(00:2.8V以上)
000000:固定値
000000000006:カウント数(BCDフォーマットなので、6[回])

のようなデータになっています。

4.各ノードからデータを取得するサンプルプログラム

手順3のとおり、Armadillo-IoTとUSBベース(無線親機)は、シリアルで通信します。

そこで、Armadillo実践開発ガイド第2部6.5.1. シリアルエコーサーバー をベースに、手順3で確認したシリアル通信で得られるテキストデータから 各ノードのセンサーの値を算出し、ログに出力するサンプルプログラムを作成しました。 serial_seiko_nodes.tar.gz

<サンプルプログラムの用法>
添付のサンプルプログラムをATDE上に解凍して、serial_seiko_nodesディレクトリ内でmakeすると、 serial_seiko_nodesという実行ファイルができます。

この実行ファイルをArmadillo-IoTに置いて、シリアル通信のデバイスファイルを引数として実行します。

serial_seiko_nodes <device>
引数
 device:デバイスファイル(手順3で確認した"/dev/ttyUSB0")

温・湿・照度ノード、CO2ノード、人感ノードの電源がONになっている場合、本プログラムを実行すると、各ノードからのデータを受信した場合、下記のようなログファイルの生成と、ログ表示を行います。
・log_tmp.txt:温・湿・照度ノードのログファイル
(sid_tmp:SID(送信元ID)、tmp:温度、hum:湿度、lux:照度)

sid_tmp=231&tmp=28.1&hum=31.7&lux=956

・log_co2.txt:CO2ノードのログファイル
(sid_co2:SID(送信元ID)、co2:CO2濃度)

sid_co2=232&co2=1745

・log_human.txt:人感ノードのログファイル
(sid_human:SID(送信元ID)、detect_count:検出数)

sid_human=230&detect_count=39

補足)各ログファイル内の各パラメータは、
 5.クラウド(Heroku)側のアプリの準備
で、クラウド側のアプリで受けとるデータ区切りに合わせて、"&"で区切っています。

ログ表示

[root@armadillo-iotg (ttymxc1) ~]# ./serial_seiko_nodes /dev/ttyUSB0
 
****************************************************
-------- Start to reveive data from nodes --------
 
****************************************************
GID:0x65,RID:0x00,CH:0x3C,MSG:0x200000000000000000001745,IDX:0x12,SID:0xE8,RT:0x00E8FFFFFF380000A5BB
 
GID(101), RID(0), CH(60), IDX(18), SID(232)
Root Information: 0x00E8FFFFFF380000A5BB
 
--------- CO2 sensor data --------
CO2[ppm]: 1745
 
****************************************************
GID:0x65,RID:0x00,CH:0x3C,MSG:0x0B0000000000000000000029,IDX:0x39,SID:0xE6,RT:0x00E6FFFFFF380000A590
 
GID(101), RID(0), CH(60), IDX(57), SID(230)
Root Information: 0x00E6FFFFFF380000A590
 
--------- Human Detect sensor data --------
Count of Human Detction: 29
 
****************************************************
GID:0x65,RID:0x00,CH:0x3C,MSG:0x03000000A0281A314A000955,IDX:0x3A,SID:0xE7,RT:0x00E7FFFFFF380000A54D
 
GID(101), RID(0), CH(60), IDX(58), SID(231)
Root Information: 0x00E7FFFFFF380000A54D
 
--------- Tmp/Hum/Lux sensor data --------
Temparature[degC]: 28.1
Humidity[%RH]: 31.4
Ambient[Lx]: 955

<サンプルプログラムの補足>
serial_seiko_nodes.c
Armadillo実践開発ガイド第2部 6.5.1. シリアルエコーサーバーをベースに今回のサンプル特有の箇所を抜粋します。)

/**** sample: response data from nodes: begin ****/
// ノードからの受信データと、各ノード別のデータ用の構造体
/**** sample: response data from nodes: end ****/
 
/**** sample: Nodes response: begin ****/
// ノードからのレスポンス判断用の文字列。(頭の3文字に"GID"があることで判断)
/**** sample: Nodes response: end ****/
 
/**** sample: char(HEX) to int: begin ****/
// テキスト表記の16進数を整数に変更する関数
/**** sample: char(HEX) to int: end ****/
 
/**** sample: variable: begin ****/
// ノードのレスポンスの最初が"GID"で始まるテキストかどうかのフラグ
    int flag_start, flag_end;
/**** sample: variable: end ****/
/**** sample: receive data from nodes: begin ****/
// データの読み込みの開始
/**** sample: analize sensor data: begin ****/
// データの解析の開始
// 手順3のテキスト文字の位置と製品仕様書のフォーマットに合わせて、
// センサーデータを抽出し、計算
/**** output Tmp/Hum/Lux sensor data to stdout: begin ****/
// 温度・湿度・照度ノードの場合のログ表示
/**** output Tmp/Hum/Lux sensor data to stdout: end ****/
 
/**** output Tmp/Hum/Lux sensor data to log file: begin ****/
// 温度・湿度・照度ノードの場合のログファイルへの出力
/**** output Tmp/Hum/Lux sensor data to log file: end ****/
 
/**** output Human Detect sensor data to stdout: begin ****/
// 人感ノードの場合のログ表示
/**** output Human Detect sensor data to stdout: end ****/
 
/**** output Human Detect sensor data to log file: begin ****/
// 人感ノードの場合のログファイルへの出力
/**** output Human Detect sensor data to log file: end ****/
 
/**** output CO2 sensor data to stdout: begin ****/
// CO2ノードの場合のログ表示
/**** output CO2 sensor data to stdout: end ****/
 
/**** output CO2 sensor data to log file: begin ****/
// CO2ノードの場合のログファイルへの出力
/**** output CO2 sensor data to log file: end ****/
 
/**** sample: analize sensor data: end ****/
/**** sample: receive data from nodes: end ****/

5.クラウド(Heroku)側のアプリの準備

5.1.準備
まず、Armadillo-IoT + Heroku(Node.js)でHello World のとおり、Armadillo側からのデータ送信と動作確認まで行ってください。
以下、この手順を実行したことをベースに説明します。 よって以下では、ATDE5の ~/temp/myapp がクラウド(Heroku)側のアプリ用のディレクトリとします。

5.2.サンプル
クラウド(Heroku)側のアプリのサンプルソースを添付します。
myapp_seiko_20160224.tar.gz を解凍して、myapp_seiko_20160224ディレクトリの中身を ~/temp/myapp ディレクトリの下にコピーしてください。

<サンプルソースの説明>
今回のサンプル特有の部分のみ説明します。

app.js

・HerokuのURL(***.herokuapp.com)にアクセスした際、index.ejsを表示するようにします。
 表示の際、index.ejsに各ノードのid、湿度、温度、照度、CO2、人感の検出回数を与えています。

app.get('/', function(req, res){
  res.render('index', {sid_tmp: sid_tmp, hum: hum, tmp: tmp, lux: lux, sid_co2: sid_co2, co2: co2, sid_human: sid_human, detect_count: detect_count});
});

・HerokuのURL(***.herokuapp.com/series)にポストされたデータ(※)をパースして、上記のindex.ejsに渡す変数に代入しています。
※)上記サンプルアプリ(serial_seiko_nodes)を実行時のログファイル
・log_tmp.txt:温・湿・照度ノードのログファイル
・log_co2.txt:CO2ノードのログファイル
・log_human.txt:人感ノードのログファイル
の内容をスクリプトで合成して、生成される

sid_tmp=231&tmp=28.1&hum=31.7&lux=956&sid_co2=232&co2=1745&sid_human=230&detect_count=39

という形式のデータです。"&"で温度、湿度等の各データを区切っています。

app.post('/series', function(req, res) {
    console.log('post:/series');
 
    sid_tmp = req.body.sid_tmp;            // 温度・湿度・照度ノードのID
    tmp = req.body.tmp;                // 温度
    hum = req.body.hum;                // 湿度
    lux = req.body.lux;                // 照度
 
    sid_co2 = req.body.sid_co2;            // CO2ノードのID
    co2 = req.body.co2;                // CO2
 
    sid_human = req.body.sid_human;        // 人感ノードのID
    detect_count = req.body.detect_count;    // 人感の検出回数
 
    res.send("Received\n");
});
view/index.ejs

・上記app.get('/', function(req, res)により、受け取った各ノードのデータを表示するhtmlです。

5.3.サンプルの実行
下記のコマンドで、クラウド(Heroku)にアップロードします。

[atde ~/temp/myapp]$ git add --all
[atde ~/temp/myapp]$ git commit -m "seiko_node"
[atde ~/temp/myapp]$ git push heroku master:master

5.4.アプリの動作確認
Webブラウザで https://***.herokuapp.com (***.herokuapp.comの部分は、手順6.1で確認したHerokuのURL) を実行すると、冒頭のWebブラウザの写真のように表示されます。 (ここまでの手順では、データを受信してないので、各値はオール0になります。)

6.温度・湿度・照度、CO2、人感ノードのデータをクラウド(Heroku)で見る

Armadillo-IoTから各ノードのデータをクラウドに送信するスクリプト
send_seiko_nodes.sh を添付します。

このスクリプトをArmadillo-IoTの/rootディレクトリに置いて、実行権限をつけてください。 サンプルプログラムserial_seiko_nodesもArmadillo-IoTの/rootディレクトリに置いて実行します。

[armadillo ~]# chmod +x send_seiko_nodes.sh
[armadillo ~]# ls /root
send_seiko_nodes.sh
serial_seiko_nodes

send_seiko_nodes.shは、下記のように使用します。

send_seiko_nodes.sh <device> <HerokuのURL>
引数
 device:デバイスファイル(手順2で確認した"/dev/ttyUSB0")
 HerokuのURL:手順5.1で確認したHerokuのURL

例)USBベース(無線親機)のデバイスファイルが/dev/ttyUSB0で、Herokuのアカウントが***.herokuapp.comの場合、

[armadillo ~]# ./send_seiko_nodes.sh /dev/ttyUSB0 https://***.herokuapp.com/series

上記のスクリプトを実行すると、Armadillo-IoTは 各ノードのID、湿度、温度、照度、CO2、人感の検出回数のデータを
・log_tmp.txt:温・湿・照度ノードのログファイル
・log_co2.txt:CO2ノードのログファイル
・log_human.txt:人感ノードのログファイル
から読みだして、クラウド(Herokuのhttps://***.herokuapp.com/series)に約10秒ごとに送信します。

Webブラウザで、https://***.herokuapp.comにアクセスすると、Armadillo-IoTが送信したIoTスマートモジュールのデータが 冒頭のWebブラウザの写真のように見ることができます。
補足)
Webブラウザの表示の更新には再読み込みが必要です。
上記のスクリプトでは10秒毎にクラウド(Heroku)に送信していますが、Webブラウザで表示されるデータの更新間隔は、 各ノードのデータ更新間隔(1分/5分/10分から選択)に依存します。 クラウド(Heroku)側のアプリがデータを受信した場合は、"Received"という文字をArmadillo-IoTに送信するので、 クラウド(Heroku)側が受け取ったかどうかを、Armadillo-IoTの標準出力で確認することができます。