🐞

M5StickC Plusで温度を測定し、スマートフォンで確認する(Eclipse Mosquitto)

2023/07/23に公開

1.はじめに

M5StickC Plusで温湿度を測定し、MQTTブローカーへ送信し、スマートフォンで温湿度を確認します。

前提条件
MQTTブローカーが動いているPCのIPアドレスは 192.168.1.12とします。

2.M5StickC Plus用のプログラム作成

温湿度・気圧を取得するサンプルプログラムは以下を使用しました。
https://github.com/m5stack/M5Unit-ENV/tree/master/examples/Hat_ENVIII_M5StickCPlus

また、MQTTのプログラムはArduino IDEのサンプルプログラムを使用しました。
上記2つのプログラムを合体したようなプログラムになりましたが、以下のように作成しました。

ENV_MQTT.ino

#include "M5StickCPlus.h"
#include <WiFi.h>
#include <PubSubClient.h> //MQTTライブラリ
#include "M5_ENV.h"  //温度センサライブラリ

//温度センサENV III 初期設定

SHT3X sht30(0x44, 1);
QMP6988 qmp6988;

float tmp      = 0.0;
float hum      = 0.0;
float pressure = 0.0;

//MQTT 初期設定

WiFiClient espClient;
PubSubClient client(espClient);

// Configure the name and password of the connected wifi and your MQTT Serve host.
//const char* ssid        = "Explore-F";
//const char* password    = "xingchentansuo123";
//const char* mqtt_server = "mqtt.m5stack.com";
const char* ssid        = "xxxxxxxxxxxxxxx";  //使用するWifi環境に合わせて変更
const char* password    = "xxxxxxxxxxxxxxx";  //使用するWifi環境に合わせて変更
const char* mqtt_server = "192.168.1.12";     //使用するネットワーク環境に合わせて変更

unsigned long lastMsg = 0;
#define MSG_BUFFER_SIZE (50)
char msg[MSG_BUFFER_SIZE];
int value = 0;

void setupWifi();
void callback(char* topic, byte* payload, unsigned int length);
void reConnect();


void setup() {

//温度センサENV III setup
    M5.begin();             // Init M5StickCPlus.
    M5.Lcd.setRotation(3);  // Rotate the screen.
    Wire.begin(0, 26);

    qmp6988.init();
//    M5.lcd.println(F("ENVIII Hat(SHT30 and QMP6988) test"));

//MQTT setup

//    M5.begin();
//    M5.Lcd.setRotation(3);
    setupWifi();
    client.setServer(mqtt_server,
                     1883);  // Sets the server details.
    client.setCallback(
        callback);  // Sets the message callback function.
}

void loop() {
    if (!client.connected()) {
        reConnect();
    }
    client.loop();  // This function is called periodically to allow clients to
                    // process incoming messages and maintain connections to the
                    // server.

    unsigned long now =
        millis();  // Obtain the host startup duration. 
    if (now - lastMsg > 2000) {
        lastMsg = now;
        ++value;
        
        //温度センサENV III 温度取得
        
        pressure = qmp6988.calcPressure();
        if (sht30.get() == 0) {  // Obtain the data of shT30.
            tmp = sht30.cTemp;   // Store the temperature obtained from shT30.
            hum = sht30.humidity;  // Store the humidity obtained from the
        } else {
            tmp = 0, hum = 0;
        }        
        
        snprintf(msg, MSG_BUFFER_SIZE,"Temp: %2.1f Humi: %2.0f%% Pressure:%2.0fPa #%ld", 
                tmp, hum, pressure, value); //温度表示
        
//        snprintf(msg, MSG_BUFFER_SIZE, "hello world #%ld",
//                 value);  // Format to the specified string and store it in MSG.
        
        
        M5.Lcd.print("Publish message: ");
        M5.Lcd.println(msg);
        client.publish("M5Stack", msg);  // Publishes a message to the specified
                                         // topic.
                                         
//表示内容が多いため、7行->4行に変更
//        if (value % 7 == 0) {
        if (value % 4 == 0) {
            M5.Lcd.fillScreen(BLACK);
            M5.Lcd.setCursor(0, 0);
        }
    }
}

//Wifi初期接続
void setupWifi() {
    delay(10);
    M5.Lcd.printf("Connecting to %s", ssid);
    WiFi.mode(
        WIFI_STA);  // Set the mode to WiFi station mode.  
    WiFi.begin(ssid, password);  // Start Wifi connection. 

    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        M5.Lcd.print(".");
    }
    M5.Lcd.printf("\nSuccess\n");
}

//メッセージ受信関数(コールバック)
void callback(char* topic, byte* payload, unsigned int length) {
    M5.Lcd.print("Message arrived [");
    M5.Lcd.print(topic);
    M5.Lcd.print("] ");
    for (int i = 0; i < length; i++) {
        M5.Lcd.print((char)payload[i]);
    }
    M5.Lcd.println();
}

//Wifi再接続
void reConnect() {
    while (!client.connected()) {
        M5.Lcd.print("Attempting MQTT connection...");
        // Create a random client ID.
        String clientId = "M5Stack-";
        clientId += String(random(0xffff), HEX);
        // Attempt to connect.  
        if (client.connect(clientId.c_str())) {
            M5.Lcd.printf("\nSuccess\n");
            // Once connected, publish an announcement to the topic.
            client.publish("M5Stack", "hello world");
            // ... and resubscribe.  
            client.subscribe("M5Stack");
        } else {
            M5.Lcd.print("failed, rc=");
            M5.Lcd.print(client.state());
            M5.Lcd.println("try again in 5 seconds");
            delay(5000);
        }
    }
}

3.M5StickC Plusへプログラムを書き込み

上記プログラムをArduino IDE開発環境を使い、M5StickC Plusへ書き込みます。
Arduino IDE開発環境のインストールは以下です。
https://zenn.dev/isi00141/articles/1c02bb3b0ed846

4.DockerでEclipse Mosquittoを動かす

以下を参考にDockerでEclipse Mosquittoを動かします。
https://zenn.dev/isi00141/articles/511a516ced27c5

4.1 受信側(Subscriber)の設定

受信側の設定をします。以下のコマンドを実行し、Dockerコンテナの中に入ります。

端末
docker exec -it mymosquitto /bin/sh

以下を実行します。メッセージをやり取りするトピックは[M5Stack]とします。

/#
mosquitto_sub -t M5Stack

5.スマートフォンでEclipse Mosquittoに接続する

以下を参考にスマートフォンでアプリ[MQTT Dashboard -IoT and Node-]をダウンロードし、MQTTブローカーのテキストデータを取得します。
https://zenn.dev/isi00141/articles/107e8a1aa788bd

6.動作確認

M5StickC Plusを起動すると、M5StickC Plusの温湿度、気圧情報が、M5StickC Plusの画面、Eclipse MosquittoのSubscribeの画面、スマートフォンの画面に表示されます。

・M5StickC Plusの画面

・Eclipse Mosquitto Subscribeの画面

・スマートフォン(MQTT Dashboard)の画面

更新履歴

2023/7/23 作成

Discussion