はじめての電子工作超入門

番外編① XOceanを使ってみた〜ArduinoとEnOceanを使用した温湿度表示

みなさん、はじめまして。新米ライターの小西と申します。私、組み込み系の知識はあるものの電子工作の経験が浅いのですが、Makersブームの波にのって電子工作にチャレンジしたいと思います!

新米ライター小西

 
というのも、先日、上司に「君にEnOceanを扱えるかな……?フッフッフ」とバカにされちゃったのです。

上司

「な、なんだ!EnOceanって!汗」と思いつつも、彼にギャフンと言わせるべく、そして最後には「Good Job!」が聞きたい、という不純な動機で、この「超入門」の場をお借りして、記事を書き始めたのであります……。

そもそもEnOcean通信って、なんだろう……

http://www.enocean.com/jp/home/
http://www.rohm.co.jp/web/japan/enocean

EnOcean通信とは、エナジーハーベスト(環境発電)と無線通信が組み合わされた技術だそうです。スイッチを押す力を電気エネルギーに変換したり、室内照明の光を電気エネルギーに変換して、その電力をセンシングや無線通信に使うのだそうです。要するに、発電機構を内蔵した、無線センサなのですね。自分で発電して動くので、電池交換が不要。すなわち、一度置いたらほったらかしにしても良いということです。おもしろい技術ですね。

ググってみると、いろんな製品があります。

01

温度センサと湿度センサが環境測定としてはわかりやすそう。組み込みケースも用意されているのですね。これなら実際に設置も可能です。

というわけで、みなさんもお馴染みのArduinoと、ニューカマーのEnOceanで、温湿度センサを2回に渡って作ってみましょう。

今回はセンサ情報の収集をやってみたいと思います。

今回の電子工作レシピ

完成までの時間目安:120分 難易度:(★★★★☆)
必要なパーツ

さっそくコアスタッフで温湿度センサを買ってみました。
ケースに入った状態手に入れましたが、温湿度センサがどういった構成になっているか確認しましょう。中身の大きさは5cmくらい。意外と小さい印象。

02

温度センサモジュールと、湿度センサを接続します。
コネクタを合わせてあるので、ブスっと挿すだけで簡単に接続できます。

03

次にケースに組み込んでみました。これも、簡単に組めました。
意外とコンパクトで、存在感なくセンサが置けそうな気がします。

04

センサは、送信側になるので、受信側も準備が必要なのですね。Gateway開発KITのようなKITも出ているようですが、今回はArduinoを使います。

色々とネットで探していると、EnOceanが乗っている新しいモジュールが出るみたいです。それが題名にもある「XOcean」という、EnOcean通信モジュールです。こちらは2015年7月末よりコアスタッフで販売開始しているようなので、さっそくできたてホヤホヤを入手しちゃいました。(XOcean世界最速レポートなるか?)

06XOcean

XBee®コネクタにそのまま挿せるタイプなのですね。
黄色い配線は、アンテナか。TELECマークもついているので、電波法も問題なし、と。
持っていたArduino基盤に、XBeeコネクタがついていなかったので(汗)、まずはXBeeシールドに接続します。XBeeシールドのシルクに合わせて接続すれば良いようです。

07

続いてXBeeシールドをArduinoに接続しました。こちらもピンをArduinoのシールド用コネクタに合わせて接続するだけです。

09Arduino+XOcean

さらに同じようにLCDシールドを接続します。

10Arduino+XOcean+LCDシールド

これで、ハードウェアはそろいました!非常に簡単で、作業時間は5分もかかりませんでした。

それでは、さっそくソフトウェアの開発に移りましょう。いきなりLCDシールドまで接続して動作させようと思うとやることが多すぎて大変なので、ArduinoとXOceanでPCのディスプレイ上に温湿度センサのデータ表示をしましょう。一歩ずつ着実に……。

さて、EnOcean通信が電池不要で動くのはわかりましたが、実際どのようなデータが送られているかわからないので規格やプロファイルを調べました。

EnOceanの無線通信とシリアル通信規格、機器情報プロファイル

無線通信とシリアル通信の規格および機器情報プロファイルが決められています。
センサも色々あるので、無線データの配列を決めておかないと、無意味なデータになってしまいます。また、データ配列をいちいち覚えてられないので、機器情報も決められているのですねー。(EnOcean通信に限らず、無線としては、当たり前か…)

13EnOceanのエネルギーハーベスティング無線センサソリューション(EnOceanホームページより、一部追記)

無線通信はEnOcean Radio Protocol(ERP)、シリアル通信はEnOcean Serial Protocol(ESP)、機器情報プロファイルはEnOcean Equipment Profile(EEP)という名称で規定されていて以下URLからドキュメントをダウンロードできます。

ERP:http://www.enocean.com/erp2/
ESP:http://www.enocean.com/esp
EEP:http://www.enocean-alliance.org/eep/

ArduinoとXOceanはシリアル接続となるのでESP3の内容がわかればArduinoでEnOcean製品のセンサ情報が取得できますね。

XOceanのデータを受信する

XOceanはArduinoの1,2番ピンと接続されているようなので、Arduinoのハードウェアシリアルを使ってXOceanのデータを受信しました。

void setup() {
    Serial.begin(57600); // 57600bps-EnOcean Serial Protocol 3
}

ハードウェアシリアルのボーレート変更

EnOceanの製品はUARTというシリアル通信で接続されるみたいなので、このようにボーレートをEnOceanの製品に合わせ込みます。ボーレートの合わせ込みができればデータを受信できるようになりそうです。
それでは受信したデータを確認してみましょう。受信したデータをそのままArduino IDEのシリアルモニタ上に表示させています。

void loop()
{
  unsigned char dataReceive = 0 ;  //受信確認フラグ
  unsigned char aChar = 0 ;        //データ格納用変数
  char buf[1] ;

  while(Serial.available()>0){    // XOcean受信したか?
   delay(5);
   aChar = Serial.read(); // シリアルデータ取得
// シリアルモニタ出力
    sprintf(buf, "%02X", aChar);
    Serial.print(buf);
    Serial.print("  ");
    dataReceive = 1 ;
  }
  if(dataReceive ==1){
    Serial.println("");
  }

受信したデータを変数であるaCharに格納し、取得したデータを16進数の文字列としてArduino IDEのシリアルモニタを使ってディスプレイ上に出力させました。ちなみにArduinoのIDEのシリアルモニタはメニューバーの「ツール > シリアルモニタ」を選択して立ち上げることができます。

14シリアルモニタの立ち上げ

シリアルモニタを立ち上げた際、画面右下にあるボーレートを57600bpsへ変更するのを忘れずに!最初変な文字が出てきて焦りました…

15

ボーレートを変更してEnOceanからデータが送られてきました。

16EnOceanシリアルデータの表示

こんな感じでEnOceanの製品からデータが送られてきてるんですね。データが受信できただけでなんとなく出来た感がでます。うれしいです。

データ解釈~ESP3編

ただし、このままではただの文字列なのでどこにどんなデータが入っているかわかりません。文字列の解釈をするため、ESP3のドキュメントを読み解きます。

ESP3のシリアル信号(ドキュメントのP.13)、EnOceanのシリアル信号は一つのかたまりで「パケット」と呼ばれているようで構造は下の図のようになっています。

17ESP3のパケット構造

この図を読み解くと、主に“Header”、“Data”、“Optional Data”という3つの要素で構成されているようです。それでは先ほどのデータを当てはめてみましょう。

18

このようにHeaderとDataとOption Dataの切り分けができました。
パケットタイプとデータを確認することでセンサの情報を取得することができます。
温湿度センサが送信するデータはパケットタイプが0x0A→10なのでパケットタイプ10を見てみましょう。

19Packet type10(RADIO_ERP2) ESP3ドキュメントのP.73

20

Option DataはTelegram NumberとRSSIであることがわかりました。欲しいデータは温度と湿度の情報なので今はそれほど必要ではないですね。肝心のデータについてはERPに従うようです。次はERPのドキュメントを確認しましょう。

データ解析~ERP2編

ERP2のドキュメントを読み進めていきますと、データ構造について書かれているページがありました。

21ERPのデータ構造(ERPドキュメントのP.16)

図の内容を確認していくと温湿度センサは送信元IDが4バイト、信号の種類が4BS(4バイトのテレグラム)といった内容がわかりました。シリアル通信のようにこちらもデータを割り当ててみます。

22

4バイトのデータ(4BS)の中に温度と湿度の情報が入っています。4バイトのデータのうち、どの部分に入っているかはEEPのドキュメントと照らし合わせる事が必要です。この温湿度センサのEEPは製品を購入したコアスタッフさんより”A5-04-01”と伺ったので、該当部分を確認します。

データ解析~EEP編

EEPのドキュメントを確認して”A5-04-01”のプロファイルを確認しましょう。

23EEP “A5-04-01”

この図に従って取得したデータを温度、湿度の値に変換します。

00 : Not use
78 : 湿度  123(0x7B) × (100-0)/(250-0) = 49.20 %
A2 : 温度  159(0x9F) × (40-0)/(250-0) = 25.44 ℃
0A : Data Telegram ,Temperature sensor available

これで無事温湿度センサのデータ内容が把握できました!
あとはこの解析した内容をプログラムにするだけです。
ポイントは温湿度データを取得したいので、EnOceanから送られてくるデータの順番を把握してどのデータなのかを確認しています。

#define TEMPID  0x0040179BD          // EnOceanモジュールID
#define SYNC    0x55                 // SYNCバイト

void setup()
{
  //Pin 0/1
  Serial.begin(57600);              // 57600-EnOcean Serial Protocol 3
  Serial.println("Working");
}

void loop()
{
  unsigned char   dataReceive = 0 ;  //受信確認フラグ
  unsigned char   aChar = 0 ;        //データ格納用変数
  unsigned char   pos = 0 ;          //ESPデータ位置
  unsigned long   senderID = 0 ;     //温湿度モジュールのID
  unsigned short  dataLength = 0 ;   //データ長
  unsigned char   optLength = 0 ;    //オプションデータ長
  unsigned char   packettype = 0 ;    //パケットタイプ
  float Temp = 0 ;                 //温度データ
  float Hum = 0 ;                  //湿度データ
  char buf[1] ;

  while(Serial.available()>0){    // XOcean受信したか?
    aChar = Serial.read();
    switch(pos){
      case(0):
      if( SYNC == aChar){          // SYNCバイトだったら受信開始
        delay(5);
        pos++;                     // pos移動 SYNC -> dataLength
        dataReceive = 1 ;
      }
      break;
      case(1):
      dataLength = 0x00FF & aChar ;  // dataLength 上位1バイトです。
      pos++;                        // pos移動 dataLength -> dataLength
      break;
      case(2):
      dataLength = (dataLength<<8) + aChar ; // dataLength 下位1バイトです。
      pos++ ;                                // pos移動 dataLength -> optLength
      break;
      case(3):
      optLength = aChar ;          //  optionLength
      pos++ ;                      // pos移動 optLength -> packet type
      break;
      case(4):
      packettype = aChar ;        //   packettype
      pos++;                      // pos移動  packet type -> crc
      break;
      case(5):
      pos++;                      // pos移動 crc -> header
      break;
      case(6):
      pos++;                      // pos移動  header -> ID1
      break;
      case(7):
      senderID =  0x0000FF & aChar ;  // ID1バイト
      pos++;                      // pos移動  ID1 -> ID2
      break;
      case(8):
      case(9):
      case(10):
      senderID =  (senderID<<8) + aChar ;  // ID2-4バイト
      pos++;                      // pos移動  ID2 -> ID4 -> data1
      break;
      case(11):
      pos++;                      // pos移動  data1 -> data2
      break;
      case(12):
      Hum = (float)aChar * 100/250 ;    //  humdata
      pos++;                      // pos移動  data2(hum) -> data3(temp)
      break;
      case(13):
      Temp = (float)aChar * 40/250 ;    //  Tempdata
      pos++;
      break;
    default:
      break;
    }  

  }
  if(dataReceive ==1){
    if(TEMPID == senderID ){
      Serial.print("Temperature = ");
      Serial.print(Temp ,  2);
      Serial.println( " (deg)");
      Serial.print("Humidity = ");
      Serial.print(Hum ,  2);
      Serial.println( " (%)");
      Serial.println("");
    }
    dataReceive = 0 ;
  }

}

posという変数で位置を確認し、EnOceanから送られてくるデータを取得してみました。また、受信した後、モジュールが持っているIDの値と比較し、一致していたら値を表示させています。これで例え同じようなセンサがたくさんあっても確認したいセンサのみの情報を取ることができますね。いずれ来るEnOcean時代(?)のために対策しました。

11

 
 
これで前半戦が終了です。
ふう……これまでのArduinoの連載よりかなりの上級編と感じたのですが、「これも上司をギャフンと言わせるためだ」と自分に鞭を打ちつつなんとかデータ内容の把握/表示までやってやりました。

新米ライター小西

次回はここにLCDシールドを接続し、機器として自立した、「Arduino×EnOcean」で電池不要の温湿度センサモニタ機器を作っちゃいます!

NHK学生ロボコン2016 出場ロボット解剖計画
小西さん

ローム株式会社 LSI商品開発本部 無線モジュール商品開発部所属。名古屋大学工学部物理工学科卒業後、紆余曲折を経てローム株式会社に入社。音楽が好きでトランペットやベースなど様々な楽器をやっていますが、今は子育てに夢中です!

http://www.rohm.co.jp/web/japan/