連載
» 2016年07月21日 07時00分 公開

MQTTで始めるIoTデバイスづくり(5):MQTTで始めるIoTデバイスの作り方 第5回:部屋の明るさを「パブリッシュ」する (4/5)

[今岡通博,MONOist]

 ほとんどが以前に紹介したパブリッシュのプログラムと同じですので、ここで説明しない箇所については連載の第4回を参考にしてください。

 このプログラムが動く前提として、ESP8266がブローカーや他のサブスクライバーと同じセグメントの無線LANに、ステーションモードで接続されている必要があります。これらの方法については以下の記事を参照してください。

・話題の技適Wi-Fiモジュール「ESP8266」でIoTを手作りする

・ESP8266を宅内Wi-Fiにぶら下げるATコマンド実例

 2行目でソフトウェアシリアルを使うためのオブジェクトを生成しています。10番ピンが受信(RXD)、11番ピンが送信(TXD)となります。これらはESP8266のTXDとRXDにつながっており、ESP8266との間でシリアル通信を行うために使います。

SoftwareSerial mySerial(10, 11); // RX, TX
2行目

 4行目でByte配列にパブリッシュメッセージのひながたのバイト列を格納しています。“arduino/a2/”がトピックで“0000”がメッセージです。それ以外のメッセージのバイト列については以前の記事、あるいはMQTTのプロトコル仕様書を参照してください。

byte pub[]={0x30,0x11,0x00,0x0b,'a','r','d','u','i','n','o','/','a','2','/','0','0','0','0'};
4行目

 17行目でシリアルポートのbpsを9600bpsに設定していますが、こちらのシリアルポートはArduinoに内蔵されたUSBシリアル変換チップにつながっています。本来はPCとの間でシリアル通信を行うためのもので、PC上のターミナルエミュレーターとの間でデータをやりとりします。今回はこれは必須ではありませんが、プログラムの動作を確かめたい時やデバッグの際、ターミナルエミュレーターでモニターするためにコードとしては残しています。

Serial.begin(9600);
17行目

 20行目で“AT+RST”を送っていますが、これによってESP8266にソフトウェアリセットをかけています。Wi-Fiルーターとの接続も含めいったん切断し、再接続します。そのため、5秒程度の時間を置いています。またこのコマンドの末尾に“\r\n”とありますが、こらは「CR」と「LF」を送っています。ATコマンドは行末をCR+LFで終わらないと認識してくれません。

mySerial.print("AT+RST\r\n");
20行目

 22行目でブローカーのあるノードへTCP/IP接続を行っています。ブローカーのIPアドレスは192.168.1.16となっていますが、これは環境に応じて変更してください。次にポートを指定しています。ポート番号1883はmqtt標準のポート番号ですが、ブローカーをほかのポートアで立ち上げている場合はこれも変更してください。

 loop関数に記述したものは繰り返し実行されます。明るさの測定と測定した値のパブリッシュはここで行っています。

mySerial.print("AT+CIPSTART=\"TCP\",\"192.168.1.16\",1883\r\n");
22行目

 30行目で整数型の変数 v と n を定義しています。vはセンサーの値を入れる変数です。nは各桁を数字文字に変換するときに用いる変数です。

int i,v,n;
30行目

 33行目で変数 v に2番のアナログ入力ピンの値を代入しています。すなわち、フォトセンサーの出力した電圧が量子化され、整数型の変数に代入されます。量子化とはADC(アナログ・デジタルコンバーター)の分解能力に応じて、電圧をいくつかの階級に分割して整数値として取り出すことです。ArduinoのADCの分解能力は10bitですので、入力電圧が0Vであれば、量子化された値は0となり、5Vの時には1023となります。

v = analogRead(2);
33行目

 34行から43行までは変数 vの値を4桁の数字文字に変換して、パブリッシュメッセージのバイト列( pub[] )のメッセージに代入します。

n=int(v/1000);
  pub[15]='0'+n;
  v = v -(n*1000);
  n=int(v/100);
  pub[16]='0'+n;
  v = v - (n*100);
  n=int(v/10);
  pub[17]='0'+n;
  v = v - (n*10);
  pub[18]='0'+v;
34〜43行目

 44行目では、この値を代入したメッセージのバイト列を送信します。

for (i=0;i<19;i++)mySerial.write(pub[i]); 
44行目

 送信して約1秒間、ESP8266からのレスポンスを待ちます。レスポンスがあればUSBシリアルモジュール経由でPC側に送達します。

 これを繰り返すことになりますが、32行目でも約1秒ESP8266からのレスポンスを待っていますので、約2秒間隔でフォトセンサーの値をパブリッシュすることになります。

Copyright © ITmedia, Inc. All Rights Reserved.