ESP32でMQTT

次にESP32でMQTTにトライしてみます。

先のESP8266用のMQTTクライアントを改造して動かしてみます。(何箇所か引っかかったところがあり、こちらの記事を参考にさせていただきました)

まず、WiFiのヘッダが違いますので、インクルードするファイルを変更します。

// ESP8266
#include <ESP8266WiFi.h>

// ESP32
#include <WiFi.h>
#include <WiFiClientSecure.h>

に変更します。

WiFiClientSecure.hを見ると、FingerPrintを検証する方法はESP32版では使えないようなので、ルート証明書を使って検証する形にします。(という表現であっているのか?用語が適切ではないかもしれません)

const char* root_ca = R"(
-----BEGIN CERTIFICATE-----
  ... 証明書の中身
-----END CERTIFICATE-----
)";

として、ルート証明書をヒアドキュメントに似た raw string literal の形で貼り付けます。raw string literal についてはこちらが参考になります。ルート証明書は、

$ openssl s_client -connect example.com:443 -showcerts

として、証明書情報を表示させた中にあります。Let’s Encryptを使っている場合、

O = Digital Signature Trust Co., CN = DST Root CA X3

の部分になります。

主要な処理は以下の通りになります。

const char* mqtt_server = "..."; // MQTTサーバーのホスト名
const char* mqtt_user = "...";   // MQTTのユーザー名
const char* mqtt_pass = "...";   // MQTTのパスワード

WiFiClientSecure espClient;      // 接続にTLSを使う
PubSubClient client(espClient);

// トピックを設定
#define TOPIC_SIZE (64)
char OutTopic[TOPIC_SIZE];
char InTopic[TOPIC_SIZE];

void callback(char* topic, byte* payload, unsigned int length) {
  // メッセージ受信時のコールバック処理
}

void reconnect() {
  // 再接続に成功するまで繰り返す
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // ランダムなクライアントIDを生成
    String clientId = "ESP32Client-";
    clientId += String(random(0xffff), HEX);
    // 接続
    if (client.connect(clientId.c_str(),mqtt_user,mqtt_pass)) {
      Serial.println("connected");
      // client.publish(OutTopic, "START");
      client.subscribe(InTopic);
    } else {
      Serial.print("failed, rc=");
      Serial.println(client.state()); // 改行追加
      char buf[256];                  // SSLエラー表示のためのバッファ確保
      espClient.lastError(buf,256);   // エラーメッセージ取得
      Serial.print("SSL error: ");    // エラーメッセージ表示
      Serial.println(buf);
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}


void setup() {
  setup_wifi();

  setTopic();    // トピックを設定

  Serial.println(root_ca);
  espClient.setCACert(root_ca);
  client.setServer(mqtt_server, 8883); // 接続先のポートを 1883 ⇒ 8883 に変更する
  client.setCallback(callback);
}

void loop() {
  if (!client.connected()) {
    reconnect();
  }
  client.loop();
   :
  // 定期的な処理(例:1分間に1回)
  client.publish(OutTopic, msg);
}

あと、ついでですが、MQTTの最大パケットサイズを変更します。

#include <PubSubClient.h>
#define MQTT_MAX_PACKET_SIZE 1024

これでMQTTでデータ送信ができるようになりましたが、SmartConfigが上手く行っていません。次はそこを修正します。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)