AWS IoTをNefryBTで使うメモ

AWS IoTをNefryBTで使うメモです。ESP32 DeveloperでAWS IoTを動かそうとしてハマったメモにてESP32としてはAWS IoTに接続できたので、NefryBTにもつなげてみます。

やりたいこと

image

今回はESP32 DeveloperでAWS IoTを動かそうとしてハマったメモで使われた一定時間(5秒ごと)でカウント送信をする機能と、さらに加えてD2ポートでGrove ボタンが押されるとBUTTON ONというメッセージも送る仕組みをつくります。

準備

このように、ディスプレイつきNefryBTに電源をつなげつつ、D2ポートにGrove ボタンをつけた状態です。

image

事前セットアップとしては、Nefry BTのWi-Fiセットアップを参考にNefryBTでのネットワーク設定をしておきます。

image

このように、管理画面に入り。

image

Wi-Fi設定をしておきます。

書き込むプログラム

ESP32 DeveloperでAWS IoTを動かそうとしてハマったメモで使われたものを活かして、loopの部分にボタンON/OFFの判定でBUTTON ONメッセージも飛ぶ仕組みを作っています。

#include <WiFiClient.h>
#include <WiFiClientSecure.h>
#include <PubSubClient.h>

/*
char *ssid = "<YOUR_SSID>";  // Nefry OFF
char *password = "<YOUR_WIFI_PASSWORD>";  // Nefry OFF
*/

const char *endpoint = "<YOUR_ENDPOINT_SUBDOMAIN>.iot.ap-northeast-1.amazonaws.com";
// Example: xxxxxxxxxxxxxx.iot.ap-northeast-1.amazonaws.com
const int port = 8883;
char *pubTopic = "/sample123";
char *subTopic = "/sample123";

const char* rootCA = "-----BEGIN CERTIFICATE-----\n" \
"......" \
"-----END CERTIFICATE-----\n";
  
const char* certificate = "-----BEGIN CERTIFICATE-----\n" \
"......" \
"-----END CERTIFICATE-----\n";
  
const char* privateKey = "-----BEGIN RSA PRIVATE KEY-----\n" \
"......" \
"-----END RSA PRIVATE KEY-----\n";

WiFiClientSecure httpsClient;
PubSubClient mqttClient(httpsClient);

// ボタンON/OFF管理
int buttonStateCurrent = LOW;
int buttonState = LOW;
int buttonPin = D2;

void setup() {

    pinMode(buttonPin, INPUT);

    Serial.begin(115200);

    Serial.print("MQTT_MAX_PACKET_SIZE ");
    Serial.println(MQTT_MAX_PACKET_SIZE);

    // Nefry OFF
    /*
    // Start WiFi
    Serial.println("Connecting to ");
    Serial.print(ssid);
    WiFi.begin(ssid, password);

    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
    }
    */

    Serial.println("\nConnected.");
    Serial.println(pubTopic);
    Serial.println(subTopic);

    // Configure MQTT Client
    httpsClient.setCACert(rootCA);
    httpsClient.setCertificate(certificate);
    httpsClient.setPrivateKey(privateKey);
    mqttClient.setServer(endpoint, port);
    mqttClient.setCallback(mqttCallback);
    connectAWSIoT();

}

void connectAWSIoT() {
    Serial.println("connectAWSIoT");
    while (!mqttClient.connected()) {
      Serial.print(".");
        if (mqttClient.connect("ESP32_device")) {
            Serial.println("Connected.");
            int qos = 0;
            mqttClient.subscribe(subTopic, qos);
            Serial.println("Subscribed.");
        } else {
            Serial.print("Failed. Error state=");
            Serial.print(mqttClient.state());
            // Wait 5 seconds before retrying
            delay(5000);
        }
    }
}

long messageSentAt = 0;
int dummyValue = 0;
char pubMessage[128];

void mqttCallback (char* topic, byte* payload, unsigned int length) {

    String str = "";
    Serial.print("Received. topic=");
    Serial.println(topic);
    for (int i = 0; i < length; i++) {
        Serial.print((char)payload[i]);
        str += (char)payload[i];
    }
    Serial.print("\n");
}

void mqttLoop() {
    if (!mqttClient.connected()) {
        connectAWSIoT();
    }
    mqttClient.loop();

    long now = millis();
    if (now - messageSentAt > 5000) {
        messageSentAt = now;
        sprintf(pubMessage, "{\"message\": \"%d\"}", dummyValue++);
        Serial.print("Publishing message to topic ");
        Serial.println(pubTopic);
        Serial.println(pubMessage);
        mqttClient.publish(pubTopic, pubMessage);
        Serial.println("Published.");
    }
}

void loop() {
  mqttLoop();
  // ボタン判定
  buttonStateCurrent = digitalRead(buttonPin);
  if ( (buttonStateCurrent != buttonState) && (buttonStateCurrent == HIGH) ) {
    Serial.println("BUTTON ON");
    sprintf(pubMessage, "{\"message\": \"BUTTON ON\"}");
    mqttClient.publish(pubTopic, pubMessage);
  }
  // 次のループへ状態保存
  buttonState = buttonStateCurrent;
}

これで、特に苦労なく動かせました。

以前のESPr Developer32ではソースべた書きになっていたWi-Fi設定はどうにかしたいな~、と思っていたので「Wi-Fi設定および接続はNefryBTの管理画面で設定したほうに任せたい」という想いもありましたので、Start WiFiまわりやYOUR_SSID・YOUR_WIFI_PASSWORDはコメントアウトして処理がかぶらないようしています。

(確信は持ててないのですが、NefryBTで行ったWi-Fi設定と、ソースコード内のYOUR_SSID・YOUR_WIFI_PASSWORDが異なる場合に、どちらに接続するのか迷うのか動作が不安定になっていたような気がするので、挙動を予測して、コメントアウトしました。)

また、

WiFiClientSecure httpsClient;
PubSubClient mqttClient(httpsClient);

のあたりを、NefryBTの管理画面で接続されているWi-Fiクラスとどう結びつけるべきか悩んでいたのですが、結果としては「Wi-Fi自体の接続成立とhttpsClient・MQTTまわりの接続まわりは特に関連付ける必要がなさそう」と解釈できたので、手を加えていません。

こちらをNefryBTに書き込んで設定は完了です。

動かしてみる

image

実際に起動してみます。

image

ログにも無事接続されていることが確認できました。

image

ボタンを押してみます。

image

AWS IoTでトピックを /# で全部引っ掛ける形で待っていると、ボタンを押された時はBUTTON ONが飛ばされ、5秒ごとにカウント数も送られています。

まとめ

ということでAWS IoTをNefryBTで使うメモを書いてみました。

さすがAWS IoTは動作が安定しており、仕組みが大きくなってもAWSのサービスで対応していけばいいやという安心感があって良いですね。

また、今回のESPr Developer32からのソースコードの移植をやってみて、それほど書き換えることなく動かせたのも収穫です。おかげでESP32やArduinoソースの知見も取り込みやすそうと感じました。

それでは、よき NefryBT & AWS Lifeを!