MQTTで始めるIoTデバイスの作り方 第4回:ArduinoをMQTTブローカーに接続するMQTTで始めるIoTデバイスづくり(4)(3/4 ページ)

» 2016年06月21日 07時00分 公開
[今岡通博MONOist]

publishスケッチ

 Arduinoではプログラムのことを「スケッチ」と呼ぶことがあります。次のリストはArduinoからESP8266経由でMQTTブローカーに対し、publishするスケッチの例です。

#include <SoftwareSerial.h>
SoftwareSerial mySerial(10, 11); // RX, TX
char con[]={0x10,0x21,0x00,0x06,'M','Q','I','s','d','p',0x03,0x02,0x00,0x3c,0x00,0x13,
            'm','o','s','q','s','u','b','/','1','2','5','1','6','-','h','i','r','o','3'};
byte pub[]={  0x30,0x15,0x00,0x06,'s','e','r','v','e','r','/','s','a','m','p','l','e','/','h','e','l','l','o'};
void getResponse(int j){
  int i;
  for (i=0;i<j;i++){
      if (mySerial.available())
         Serial.write(mySerial.read());
      delay(1);
    }
  }
void setup(){
  int i,j;
  Serial.begin(9600);
  mySerial.begin(9600); 
  while(!Serial);
  mySerial.print("AT+RST\r\n");
  getResponse(5000);
  mySerial.print("AT+CIPSTART=\"TCP\",\"192.168.1.16\",1883\r\n");
  getResponse(1000);
  mySerial.print("AT+CIPSEND=35\r\n");
  getResponse(1000);
  for (i=0;i<35;i++)mySerial.write(con[i]);                  
  getResponse(1000); 
}
void loop(){
  mySerial.print("AT+CIPSEND=23\r\n");
  getResponse(1000);  
  for (i=0;i<23;i++)mySerial.write(pub[i]); 
  getResponse(1000);  
  }

 1行目でSoftwareSerial.hというヘッダファイルをインクルードしています。これはソフトシリアルの機能を使うための前準備です。今回の構成では2系統のシリアルポートが必要です。1つはUSB経由でPCとやりとりするためのシリアルポート、もう1つはESP8266との通信を行うシリアルポートです。

 ArduinoのCPUはATMEGA328Pを採用していますが、ハードウェアとしてのシリアルポートは1つしか用意されていません。PCとの通信はモニター程度なので、これをESP8266側に割り当てればよいのですが、この通信ポートはPCからArduinoにプログラムをダウンロードするためにも用いられる大事なシリアルポートなのです。

 そのため基板上で結線されており、ユーザーがこのポートを別の用途に割り当てることはできません。そこで今回はソフトウェアでGPIOをシリアルポートの代わりに使えるソフトウェアシリアルを使うことにしました。ソフトウェアシリアルはあまり高速なボーレートでは使えないので、今回はESP8266のボーレートを設定可能な最も遅い9600bpsに設定します。ボーレートの設定コマンドは以下の通りです。このコマンドは一度実行すると設定が不揮発的にESP8266に残ります。

 
AT+UART_DEF=9600,8,1,0,0
 

 2行目で送信側のTxDをGPIOの11番、そして RXDを12番としてSoftwareSerialのmySerialというオブジェクトを生成しています。3行目と5行目は先に説明したmqttコマンドメッセージをbyte配列に格納したものです。

 7行目でgetResponseという関数を定義していますが、これはESP8266からシリアル経由で送信されるデータをPC側に送るための関数です。引数でループ回数を指定しますが、毎回delay(1)が入っていますので、引数を1000とすれば約1秒間にESP8266から受信したデータをPC側に送ることになります。

 次のsetup関数内は一度だけ実行される命令を書きます。シリアルポートとソフトウェアシリアルポートを9600bpsに設定します。

 19行でシリアルポートの設定完了を待ち、20行でATコマンドを用いてESP8266をリセットしています。その後、5秒間ESP8266の反応を待ちます。次に22行でブローカーのIPアドレスとポート番号を指定して接続に行きます。これが成功するとTCP/IPレベルでのセッションが確立したことになります。

 1秒置いた後、今度はMQTTのコネクト要求を送ります。まずATコマンドで35文字送信することをESP8266に伝えます(24行)。1秒後、byte配列として用意したコネクト要求コマンドを送ります。loop関数内には何度も繰り返して実行される命令を記述します。ここでは定期的(約2秒ごと)にパブリッシュメッセージを送ります。

Copyright © ITmedia, Inc. All Rights Reserved.