デバイス

PubSubClient の便利さと注意点

Arduino から AWS IoT に MQTT メッセージを送りたい時には、簡単に使えるので以下の PubSubClient を使用したりしています。

A client library for the Arduino Ethernet Shield that provides support for MQTT. - knolleary/pubsubclient
GitHub - knolleary/pubsubclient: A client library for the Arduino Ethernet Shield that provides support for MQTT. - GitHub

以下のようなコードを書くだけで、AWS IoT で発行したデバイス証明書を使用して AWS IoT に MQTT メッセージを送信できるので個人的に便利で使っています。

#include <M5StickCPlus.h>
#include <WiFi.h>
#include <PubSubClient.h>
#include <WiFiClientSecure.h>

// WiFi SSID and password
const char *ssid = "xxxxx";
const char *password = "xxxxx";

// AWS IoT endopoint and MQTT topic
const char* aws_endpoint = "xxxxx";
const char* mqtt_topic = "xxxxx";

// Device certificate
const char *cert = R"KEY(
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
)KEY";

const char *private_key = R"KEY(
-----BEGIN RSA PRIVATE KEY-----
...
-----END RSA PRIVATE KEY-----
)KEY";

const char *root_ca = R"KEY(
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
)KEY";

WiFiClientSecure net;
PubSubClient client(net);

void connectAWS() {
    M5.Lcd.println("Connecting to AWS");
    while (!client.connected()) {
        if (client.connect("M5StickCPlusClient")) {
            M5.Lcd.println("Connected to AWS");
        } else {
            M5.Lcd.print("Failed, rc=");
            M5.Lcd.print(client.state());
            delay(5000);
        }
    }
}

void callback(char* topic, byte* payload, unsigned int length) {
    M5.Lcd.print("Message arrived [");
    M5.Lcd.print(topic);
    M5.Lcd.print("] ");
    for (unsigned int i = 0; i < length; i++) {
        M5.Lcd.print((char)payload[i]);
    }
    M5.Lcd.println();
}

void setup() {
    M5.begin();
    M5.Lcd.setTextSize(1);
    M5.Lcd.setRotation(3);
    M5.Lcd.println("Connecting to WiFi");

    // WiFi connection
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        M5.Lcd.print(".");
    }
    M5.Lcd.println("\nWiFi connected");

    // Set device certificate
    net.setCACert(root_ca);
    net.setCertificate(cert);
    net.setPrivateKey(private_key);

    client.setServer(aws_endpoint, 8883);
    client.setCallback(callback);

    if (!client.connected()) {
        connectAWS();
    }
}

void loop() {
    if (!client.connected()) {
        connectAWS();
    }
    client.loop();

    // Sending message
    String message = "Hello from M5StickCPlus";
    client.publish(mqtt_topic, message.c_str());
    delay(10000);
}

しかし、Limitations を見ると subscribe は QoS 1 にも対応していますが、publish は QoS 0 までとなっていました。publish で QoS 1 を使いたい場面はそれなりにあると思うので対応して欲しいところですが、最後のコミットが 4 年前なので、少なくともすぐには対応されなそうです。

It can only publish QoS 0 messages. It can subscribe at QoS 0 or QoS 1.

https://github.com/knolleary/pubsubclient/tree/master?tab=readme-ov-file#limitations

また、デフォルトのメッセージサイズの上限が 256 バイトになっているのですが、これを超過したメッセージを受信する際は、エラーメッセージなどが出力されなかったので、デバッグに少し苦労しました。

The maximum message size, including header, is 256 bytes by default. This is configurable via MQTT_MAX_PACKET_SIZE in PubSubClient.h or can be changed by calling PubSubClient::setBufferSize(size).

https://github.com/knolleary/pubsubclient/tree/master?tab=readme-ov-file#limitations

zuqqhi2

某Web系の会社でエンジニアをやっています。 学術的なことに非常に興味があります。 趣味は楽器演奏、ジョギング、読書、料理などなど手広くやっています。

Share
Published by
zuqqhi2
Tags: pubsubclient