MQTTでRaspberryPiとESP32を通信してみる(その1)

mosquittoを使ってMQTT BrokerをRaspberryPi内で立てて、ESP32でPublish(送信)、RaspberryPiでSubscribe(受信)してみます!💪

1、RaspberryPi側の準備

Macの時と同じようにMQTT Brokerになるmosquittoをインストールします。

$sudo apt install mosquitto

Macの場合はツールもインストールされたのですが、RaspberryPiの場合、mosquitto_sub、mosquitto_pubはインストールされないようなので下記でインストールします。

sudo apt install mosquitto-clients

RaspberryPiの場合mosquittoをインストールすると、MQTT Brokerは自動起動になるようで、mosquitto_sub、mosquitto_pubを実行できます。リブートしても自動実行になるようです。

念のため下記のコマンドでHelloが通信できるかどうか確認します。

mosquitto_sub -h localhost -t tp1/sub1

mosquitto_pub -h localhost -t tp1/sub1 -m Hello

詳しいやりかたは前回のnoteで

2、RaspberryPiでSubscribeする

ESP32からPublishされたメッセージをSubscribeするpythonスクリプトを作成します。mosquitto_subでも受信できるんだけど、あえてpythonで作ってみます。

pythonではpaho-mqttというライブラリーを使うのでインストールしておきます。

$pip3 install paho-mqtt

プログラムがこちら

import paho.mqtt.client as mqtt
host = '127.0.0.1'
port = 1883
topic = 'tp1/sub1'
topic2 = 'tp1/sub2'
def on_connect(client, userdata, flags, respons_code):
   print('status {0}'.format(respons_code))
#topicを複数登録してみた
   client.subscribe(topic)
   client.subscribe(topic2)
   
def on_message(client, userdata, msg):
   
   #topic QOS payloadを取得
   print(msg.topic + " " + str(msg.qos) + " " + str(msg.payload))
   
if __name__ == '__main__':
   # Publisherと同様に v3.1.1を利用
   client = mqtt.Client(protocol=mqtt.MQTTv311)
   client.on_connect = on_connect
   client.on_message = on_message
   client.connect(host, port=port, keepalive=60)
   # 待ち受け状態にする
   client.loop_forever()

MQTT BrokerはRaspberryPi内の他のターミナルに立ててあるので接続先は下記になります。

host = '127.0.0.1'

このプログラムは下記によって、無限ループなってしまうので、他の処理をしたい場合は別スレッドを立ててやる必要があります。スレッドの立て方は別の機会で書きたいと思います。

client.loop_forever()

受信したメッセージはmesに格納されるので下記で取り出します。qosとはQOSのことで通信の信頼レベルの設定です。これについても別途解説しますね。

 print(msg.topic + " " + str(msg.qos) + " " + str(msg.payload))

今回はあえてtopicを複数設定してみました。下記のようにtopicを追加していけば複数設定ができるようです。

#topicを複数登録してみた
   client.subscribe(topic)
   client.subscribe(topic2)

3、ESP32でPublishする

ESP32のMQTTライブラリーをインストールします。

長いプログラムのように感じますが、よくみるといつものWiFi設定がありますね。😙

ボード上のスイッチを押すと、Publishするようになってます。

#include <WiFi.h>
#include <PubSubClient.h>
   // WiFi
   const char ssid[] = "your ssid";
   const char passwd[] = "your password";
   // Pub/Sub
   const char* mqttHost = "192.168.43.41";
   const int mqttPort = 1883;       // MQTTのポート
   WiFiClient wifiClient;
   PubSubClient mqttClient(wifiClient);
   const char* topic = "tp1/sub2";     // 送信先のトピック名
   char* payload;                   // 送信するデータ
   /**
    * Connect WiFi
    */
   void connectWiFi()
   {
       WiFi.begin(ssid, passwd);
       Serial.print("WiFi connecting...");
       while(WiFi.status() != WL_CONNECTED) {
           Serial.print(".");
           delay(100);
       }
       Serial.print(" connected. ");
       Serial.println(WiFi.localIP());
   }
   /**
    * Connect MQTT
    */
   void connectMqtt()
   {
       mqttClient.setServer(mqttHost, mqttPort);
       Serial.println("Connecting to MQTT...");
       
       while( ! mqttClient.connected() ) {      
           /*
           String clientId = "ESP32-" + String(random(0xffff), HEX);
           if ( mqttClient.connect(clientId.c_str()) ) {
               Serial.println("connected"); 
           }
           randomSeed(micros());
           */
           
           if ( mqttClient.connect("ESP32-1") ) {
               Serial.println("connected"); 
           }
           delay(1000);
   }
}
   void setup() {
       Serial.begin(115200);
       pinMode(0, INPUT_PULLUP);     // Initialize the BUILTIN_LED pin as an output
       // Connect WiFi
       connectWiFi();
       // Connect MQTT
       connectMqtt();
       
   }
int count=0;
   void loop() {
       // 送信処理 topic, payloadは適宜
       int a=digitalRead(0);
         if(a==0) {
                  count++;
                  if(count > 250){count =250;}
         }else{
                  count=0;
          }
        if(count ==2){
         payload = "Hello ESP32";
         mqttClient.publish(topic, payload);
        }    
       delay(100);
       mqttClient.loop();  
   }

MQTT BrokerのアドレスはRaspberryPiのIPアドレスになります。

const char* mqttHost = "192.168.43.41";

処理の最後にあるloop処理はMQTTの接続維持のために必要になるので定期的に実行される場所にいれておく必要があります。この処理は抜けて来るのでスレッドを立てなくても他の処理を行うことができます、

mqttClient.loop();  

処理の途中、コメントにしてある部分ですが、ベースにしたソフトが接続状況を確認しながらclientIdにユニークなコードを設定して、複数のESP32があっても別のIdが設定されるようになっていました。参考になるやり方なので紹介しておきますね。💯

        /*
           String clientId = "ESP32-" + String(random(0xffff), HEX);
           if ( mqttClient.connect(clientId.c_str()) ) {
               Serial.println("connected"); 
           }
           randomSeed(micros());
           */

ちなみに今回は1台なので固定Idで設定しています。

qttClient.connect("ESP32-1")

ランダムじゃなくてカウンターでもいいんじゃないかな?なんて思ったりもしましたが😙

参考までに同一Idは2つまで許可されるようです。

どうでしょう?あっさり繋がりますよね💮

今回、MQTTをやり始めたんだけど、結構奥が深いんですよ〜

まだまだ、試したいことがたくさんあるのでしばらくMQTTが続きそうです。

では🤚



この記事が気に入ったらサポートをしてみませんか?