よしたく blog

ほぼ週刊で記事を書いています

RaspberryPiとM5StackをMQTTでつなぐ

RaspberryPiをMQTTブローカーにして、M5Stackから送られるメッセージを受信する。

RaspberryPiの設定

まずはMQTTブローカーをインストールする。 MQTTブローカーのオープンソースである、「mosquitto」を使う。

sudo apt-get install mosquitto

MQTTブローカーの起動や停止はserviceから実行できる。

service mosquitto start
service mosquitto stop

今回、RaspberryPiではMQTTブローカーとしての役割とM5Stackからのメッセージ受信もおこなうのでmosquitto-clientsをインストールする。mosquitto-clientsをインストールすることで、メッセージの送信と受信ができる。MTQQブローカーとしての役割だけだったらインストールする必要はない!

sudo apt-get install mosquitto-clients

M5Stackへソースを書き込む

今回はこちらのサイトのソースを編集して使わせてもらった。 Arduino IDEからM5Stackへ書き込む。

#include <WiFi.h>
#include <PubSubClient.h>
#include <M5Stack.h>
 
// Wi-FiのSSID
char *ssid = "YOUR-SSID";
// Wi-Fiのパスワード
char *password = "YOUR-PASSWORD";
// MQTTの接続先のIP
const char *endpoint = "YOUR-MQTT-IP";
// MQTTのポート
const int port = 1883;
// デバイスID
char *deviceID = "M5Stack";  // デバイスIDは機器ごとにユニークにします
// メッセージを知らせるトピック
char *pubTopic = "/pub/M5Stack";
// メッセージを待つトピック
char *subTopic = "/sub/M5Stack";
 
////////////////////////////////////////////////////////////////////////////////
   
WiFiClient httpsClient;
PubSubClient mqttClient(httpsClient);
   
void setup() {
    Serial.begin(115200);
     
    // Initialize the M5Stack object
    M5.begin();
 
    // START
    M5.Lcd.fillScreen(BLACK);
    M5.Lcd.setCursor(10, 10);
    M5.Lcd.setTextColor(WHITE);
    M5.Lcd.setTextSize(3);
    M5.Lcd.printf("START");
     
    // Start WiFi
    Serial.println("Connecting to ");
    Serial.print(ssid);
    WiFi.begin(ssid, password);
   
    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
    }
 
    // WiFi Connected
    Serial.println("\nWiFi Connected.");
    M5.Lcd.setCursor(10, 40);
    M5.Lcd.setTextColor(WHITE);
    M5.Lcd.setTextSize(3);
    M5.Lcd.printf("WiFi Connected.");
     
    mqttClient.setServer(endpoint, port);
   
    connectMQTT();
}
   
void connectMQTT() {
    while (!mqttClient.connected()) {
        if (mqttClient.connect(deviceID)) {
            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 count = 0;
char pubMessage[128];
int led,red,green,blue;

  
void mqttLoop() {
    if (!mqttClient.connected()) {
        connectMQTT();
    }
    mqttClient.loop();
}
 
void loop() {
 
  // 常にチェックして切断されたら復帰できるように
  mqttLoop();
 
  // 5秒ごとにメッセージを飛ばす
  long now = millis();
  if (now - messageSentAt > 5000) {
      messageSentAt = now;
      sprintf(pubMessage, "{\"count\": %d}", count++);
      Serial.print("Publishing message to topic ");
      Serial.println(pubTopic);
      Serial.println(pubMessage);
      mqttClient.publish(pubTopic, pubMessage);
      Serial.println("Published.");
  }
}

実行

M5Stack

M5Stackへ無事に書き込みが完了し起動をすると、M5StackはMQTTブローカーへ向けてメッセージを送信し続ける。 5秒ごとに数字が1上がり、その値をメッセージとして/pub/M5Stackへ送信している。

/pub/M5Stackはメッセージがおいてある場所を指しており、「トピック」と呼ばれる。 送信者は指定したトピックにメッセージを送信する。 トピックはディレクトリのように「/(スラッシュ)」で区切って利用する。

/pub/M5Stack
/pub/RaspberryPi
/pub/Arduino
/pub/IoT

/message/room1
/message/room2
/message/room3

RaspberryPi

RaspberryPiはmosquitto_subコマンドを実行し、MQTTブローカーへ問い合わせる。 - 実行

mosquitto_sub -d -t /pub/M5Stack
  • 結果
{"count": 1}
{"count": 2}
{"count": 3}
{"count": 4}
...
{"count": n}