1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

M5StickCでMQTTのQOS2をやってみました

Last updated at Posted at 2021-06-27

1 はじめに

M5stickCでMQTTのQOS2をやってみました
pubsubclientライブラリはQOS0と1のサポートのようなので
QOS2を指定できるASyncMqttClientライブラリを利用します

pubsubclientのLimitationsの抜粋
It can only publish QoS 0 messages. It can subscribe at QoS 0 or QoS 1.

2 準備

  • PlatformmIOで開発します
     導入方法や設定は別ページを参照願います
  • PlatformIOのライブラリからASyncMqttClientをadd to projestします
  • ブローカーはmosquittoを利用します
     導入方法や設定は別ページを参照願います

3 振る舞い  

  • Publish
    Aボタンを押すとQOSを0→1→2の順番で変更しながらメッセージを送信します

  • Subscribe
    受信するとシリアルにデータを表示します

4 コード

exmaples/FullyFeatured-ESP8266.inoを参考にしています

4.1 ユーザー毎の変更点

4.1.1 SSID

main.cpp
// Wi-FiのSSID
const char *ssid = "****";
// Wi-Fiのパスワード
const char *password = "****";

4.1.2 brokerのアドレス

main.cpp
#define MQTT_HOST IPAddress(**, **, **, **)

4.2 コード全体

main.cpp
#include <M5StickC.h>
#include <WiFi.h>
#include <AsyncMqttClient.h>

// Wi-FiのSSID
const char *ssid = "****";
// Wi-Fiのパスワード
const char *password = "****";

// デバイスID
const char *deviceID = "M5Stickc_1";  // デバイスIDは機器ごとにユニークにします
// メッセージを知らせるトピック
const char *pubTopic = "/pub/M5Stickc_1";

#define MQTT_HOST IPAddress(**, **, **, **)
#define MQTT_PORT 1883

#define BTN_A_PIN 37
#define BTN_B_PIN 39

#define BTN_ON  LOW
#define BTN_OFF HIGH

AsyncMqttClient mqttClient;

void connectToMqtt() {
  Serial.println("Connecting to MQTT...");
  mqttClient.connect();
}

void onMqttConnect(bool sessionPresent) {
  M5.Lcd.println("Connected to MQTT.");
  Serial.println("Connected to MQTT.");
  Serial.print("Session present: ");
  Serial.println(sessionPresent);
  uint16_t packetIdSub = mqttClient.subscribe(pubTopic, 2);
  Serial.print("Subscribing at QoS 2, packetId: ");
  Serial.println(packetIdSub);

  mqttClient.publish("test/lol", 0, true, "test 1");
  Serial.println("Publishing at QoS 0");
  uint16_t packetIdPub1 = mqttClient.publish("test/lol", 1, true, "test 2");
  Serial.print("Publishing at QoS 1, packetId: ");
  Serial.println(packetIdPub1);
  uint16_t packetIdPub2 = mqttClient.publish("test/lol", 2, true, "test 3");
  Serial.print("Publishing at QoS 2, packetId: ");
  Serial.println(packetIdPub2);
}

void onMqttDisconnect(AsyncMqttClientDisconnectReason reason) {
  Serial.println("Disconnected from MQTT.");

  if (WiFi.isConnected()) {
    delay(1000);
    connectToMqtt();
  }
}

void onMqttSubscribe(uint16_t packetId, uint8_t qos) {
  Serial.println("Subscribe acknowledged.");
  Serial.print("  packetId: ");
  Serial.println(packetId);
  Serial.print("  qos: ");
  Serial.println(qos);
}

void onMqttUnsubscribe(uint16_t packetId) {
  Serial.println("Unsubscribe acknowledged.");
  Serial.print("  packetId: ");
  Serial.println(packetId);
}

void onMqttMessage(char* topic, char* payload, AsyncMqttClientMessageProperties properties, size_t len, size_t index, size_t total) {
  Serial.println("Publish received.");
  Serial.print("  topic: ");
  Serial.println(topic);
  Serial.print("  qos: ");
  Serial.println(properties.qos);
  Serial.print("  dup: ");
  Serial.println(properties.dup);
  Serial.print("  retain: ");
  Serial.println(properties.retain);
  Serial.print("  len: ");
  Serial.println(len);
  Serial.print("  index: ");
  Serial.println(index);
  Serial.print("  total: ");
  Serial.println(total);
}

void onMqttPublish(uint16_t packetId) {
  Serial.println("Publish acknowledged.");
  Serial.print("  packetId: ");
  Serial.println(packetId);
}

void setup() {
  
  Serial.begin(115200);

  // Initialize the M5Stack object
  M5.begin();
     
  pinMode(BTN_A_PIN, INPUT_PULLUP);
  pinMode(BTN_B_PIN, INPUT_PULLUP);

  M5.lcd.init();

  // START
  M5.lcd.fillScreen(BLACK);
  M5.lcd.setCursor(10, 10);
  M5.lcd.setTextColor(WHITE);
  M5.lcd.setTextSize(1);
  M5.lcd.println("START");

  // Start WiFi
  Serial.println("Connecting to ");
  Serial.print(ssid);
  WiFi.begin(ssid, password);
   
  while (WiFi.status() != WL_CONNECTED) {
      delay(500);
      Serial.print("*");
  }

  mqttClient.onConnect(onMqttConnect);
  mqttClient.onDisconnect(onMqttDisconnect);
  mqttClient.onSubscribe(onMqttSubscribe);
  mqttClient.onUnsubscribe(onMqttUnsubscribe);
  mqttClient.onMessage(onMqttMessage);
  mqttClient.onPublish(onMqttPublish);
  mqttClient.setServer(MQTT_HOST, MQTT_PORT);

  connectToMqtt();
}

int publish_cnt = 0;
int publish_qos = 0;
void loop() {

  if(digitalRead(BTN_A_PIN) == BTN_ON) {
    Serial.println("press A");
    switch(publish_qos) {
      case 0:
      {
        mqttClient.publish(pubTopic, 0, true, "test 1");
        Serial.println("Publishing at QoS 0");
      }
      break;
      case 1:
      {
        uint16_t packetIdPub1 = mqttClient.publish(pubTopic, 1, true, "test 2");
        Serial.print("Publishing at QoS 1, packetId: ");
        Serial.println(packetIdPub1);
      }
      break;
      case 2:
      {
        uint16_t packetIdPub2 = mqttClient.publish(pubTopic, 2, true, "test 3");
        Serial.print("Publishing at QoS 2, packetId: ");
        Serial.println(packetIdPub2);
      }
      break;
      default:
      break;
    }
    publish_qos++;
    publish_qos %= 3;
  } else {
    //Serial.println("idle");
  }

  delay(100);
}
~~~


# 5 結果  
## 5.1 シリアル  

Connecting to
KAONM-A5DF7*Connecting to MQTT...
Connected to MQTT.
Session present: 0
Subscribing at QoS 2, packetId: 1
Publishing at QoS 0
Publishing at QoS 1, packetId: 2
Publishing at QoS 2, packetId: 3
Subscribe acknowledged.
packetId: 1
qos: 2
Publish acknowledged.
packetId: 2
Publish acknowledged.
packetId: 3
press A
Publishing at QoS 0
Publish received.
topic: /pub/M5Stickc_1
qos: 0
dup: 0
retain: 0
len: 6
index: 0
total: 6
press A
Publishing at QoS 1, packetId: 4
Publish acknowledged.
packetId: 4
Publish received.
topic: /pub/M5Stickc_1
qos: 1
dup: 0
retain: 0
len: 6
index: 0
total: 6
press A
Publishing at QoS 2, packetId: 5
Publish acknowledged.
packetId: 5
Publish received.
topic: /pub/M5Stickc_1
qos: 2
dup: 0
retain: 0
len: 6
index: 0
total: 6
press A
Publishing at QoS 0
Publish received.
topic: /pub/M5Stickc_1
qos: 0
dup: 0
retain: 0
len: 6
index: 0
total: 6
press A
Publishing at QoS 1, packetId: 6
Publish acknowledged.
packetId: 6
Publish received.
topic: /pub/M5Stickc_1
qos: 1
dup: 0
retain: 0
len: 6
index: 0
total: 6
press A
Publishing at QoS 2, packetId: 7
Publish acknowledged.
packetId: 7
Publish received.
topic: /pub/M5Stickc_1
qos: 2
dup: 0
retain: 0
len: 6
index: 0
total: 6


## 5.2 パケット  
QOS設定が反映されているかパケットを確認します

---
### 5.2.1 QOS0  

~~~
+++ publisherからbrokerへPUBLISH +++
10450,548.113687872,192.168.0.21,192.168.0.22,MQTT,79,137,42,Publish Message [/pub/M5Stickc_1]
+++ brokerからsubscriberへPUBLISH +++
10451,548.113921727,192.168.0.22,192.168.0.21,MQTT,79,42,162,Publish Message [/pub/M5Stickc_1]
~~~

~~~plantuml
publisher -> broker:10450/PUBLISH

broker -> subscriber:10451/PUBLISH 
~~~

QOS0なのでPUBLISHのみ送信されています  

---

### 5.2.2 QOS1  

~~~
+++ publisherからbrokerへPUBLISH +++
10596,556.107138644,192.168.0.21,192.168.0.22,MQTT,81,162,67,Publish Message (id=4) [/pub/M5Stickc_1]
+++ brokerからpublisherへPUBACK +++
10597,556.107508385,192.168.0.22,192.168.0.21,MQTT,58,67,189,Publish Ack (id=4)

+++ brokerからsubscriberへPUBLISH +++
10599,556.115019813,192.168.0.22,192.168.0.21,MQTT,81,71,189,Publish Message (id=1) [/pub/M5Stickc_1]
+++ subscriberからbrokerへPUBACK +++
10604,556.359008912,192.168.0.21,192.168.0.22,MQTT,60,189,98,Publish Ack (id=1)
~~~

~~~plantuml
publisher -> broker:10596/PUBLISH
broker -> publisher:10597/PUBACK

broker -> subscriber:10599/PUBLISH 
subscriber -> broker:10604/PUBACK
~~~

QOS1のPUBACKを送信しているのでQOS1になっているようです  

---

### 5.2.3 QOS2  

~~~
+++ publisherからbrokerへPUBLISH +++
11353,579.125283591,192.168.0.21,192.168.0.22,MQTT,81,288,193,Publish Message (id=7) [/pub/M5Stickc_1]
+++ brokerからpublisherへPUBREC +++
11355,579.125435414,192.168.0.22,192.168.0.21,MQTT,58,193,315,Publish Received (id=7)
+++ publisherからbrokerへPUBREL +++
11367,579.160742235,192.168.0.21,192.168.0.22,MQTT,60,315,197,Publish Release (id=7)
+++ brokerからpublisherへPUBCOMP +++
11368,579.160872548,192.168.0.22,192.168.0.21,MQTT,58,197,319,Publish Complete (id=7)

+++ brokerからsubscriberへPUBLISH +++
11382,579.175784206,192.168.0.22,192.168.0.21,MQTT,81,201,319,Publish Message (id=4) [/pub/M5Stickc_1]
+++ subscriberからbrokerへPUBREC +++
11389,579.201432249,192.168.0.21,192.168.0.22,MQTT,60,319,228,Publish Received (id=4)
+++ brokerからsubscriberへPUBREL +++
11390,579.201582666,192.168.0.22,192.168.0.21,MQTT,58,228,323,Publish Release (id=4)
+++ subscriberからbrokerへPUBCOMP +++
11392,579.209742013,192.168.0.21,192.168.0.22,MQTT,60,323,232,Publish Complete (id=4)
~~~

~~~plantuml
publisher -> broker:11353/PUBLISH
broker -> publisher:11355/PUBREC
publisher -> broker:11367/PUBREL
broker -> publisher:11368/PUBCOMP

broker -> subscriber:11382/PUBLISH 
subscriber -> broker:11389/PUBREC
broker -> subscriber:11390/PUBREL 
subscriber -> broker:11392/PUBCOMP
~~~

QOS2のPUBCOMPを送信しているのでQOS2になっているようです  

終わりです




1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?