Mqtt avec Arduino
Le protocole Mqtt est utilisé par les objets connectés pour communiquer. Il s’agit d’un protocole très léger de messagerie. Il permet donc à un objet connecté d’envoyer et/ou de recevoir des messages.
Un serveur Mqtt unique (Broker) sert à centraliser les messages. Ainsi un objet connecté va publier (publish) vers le Broker. Pour recevoir des messages le client va souscrire (subscribe) à leurs réception auprès du Broker.
Pour que les messages ne se mélangent pas, ils sont publiés sur une chaine (topic).
Par exemple : blaisepascal/meteo1/temperature
Pour récupérer la température de la station météo1 du lycée Blaise Pascal on va donc souscrire au topic : blaisepascal/meteo1/temperature
La bibliothèque pubsubclient.h (disponible dans Croquis – Inclure une bibliothèque – gérer les bibliothèques), permet de publier et souscrire auprès d’un Broker MQTT. (voir http://arduino.blaisepascal.fr/installer-une-bibliotheque/)
Après connexion au broker, la commande :
client.publish("esp/test", "Hello from ESP8266");
permet de publier la phrase « Hello from ESP8266 » sur le topic esp/test.
mqtt_publish("esp/test/qqchose",temp);
permet de publier un float sur le topic esp/test/qqchose.
La fonction callback permet de programmer une action lors de l’apparition d’une donnée sur un topic auquel on a souscrit. Pour souscrire a un topic, il faut utiliser la commande :
client.subscribe("esp/test/souscription");
Cette commande pourra être placée juste après la connexion au serveur Mqtt (ci-dessous la fonction reconnect().
Exemple de code Arduino avec un ESP8266 :
#include <ESP8266WiFi.h> #include <ESP8266WiFiMulti.h> #include <PubSubClient.h> //Librairie pour la gestion Mqtt //WIFI const char* ssid = "SSID"; const char* password = "mdp"; //MQTT const char* mqtt_server = "192.168.x.y";//Adresse IP du Broker Mqtt const int mqttPort = 1883; //port utilisé par le Broker long tps=0; ESP8266WiFiMulti WiFiMulti; WiFiClient espClient; PubSubClient client(espClient); void setup() { Serial.begin(115200); setup_wifi(); setup_mqtt(); client.publish("esp/test", "Hello from ESP8266"); } void loop() { reconnect(); client.loop(); //On utilise pas un delay pour ne pas bloquer la réception de messages if (millis()-tps>10000){ tps=millis(); float temp = random(30); mqtt_publish("esp/test/qqchose",temp); Serial.print("qqchose : "); Serial.println(temp); } } void setup_wifi(){ //connexion au wifi WiFiMulti.addAP(ssid, password); while ( WiFiMulti.run() != WL_CONNECTED ) { delay ( 500 ); Serial.print ( "." ); } Serial.println(""); Serial.println("WiFi connecté"); Serial.print("MAC : "); Serial.println(WiFi.macAddress()); Serial.print("Adresse IP : "); Serial.println(WiFi.localIP()); } void setup_mqtt(){ client.setServer(mqtt_server, mqttPort); client.setCallback(callback);//Déclaration de la fonction de souscription reconnect(); } //Callback doit être présent pour souscrire a un topic et de prévoir une action void callback(char* topic, byte *payload, unsigned int length) { Serial.println("-------Nouveau message du broker mqtt-----"); Serial.print("Canal:"); Serial.println(topic); Serial.print("donnee:"); Serial.write(payload, length); Serial.println(); if ((char)payload[0] == '1') { Serial.println("LED ON"); digitalWrite(2,HIGH); } else { Serial.println("LED OFF"); digitalWrite(2,LOW); } } void reconnect(){ while (!client.connected()) { Serial.println("Connection au serveur MQTT ..."); if (client.connect("ESP32Client")) { Serial.println("MQTT connecté"); } else { Serial.print("echec, code erreur= "); Serial.println(client.state()); Serial.println("nouvel essai dans 2s"); delay(2000); } } client.subscribe("esp/test/led");//souscription au topic led pour commander une led } //Fonction pour publier un float sur un topic void mqtt_publish(String topic, float t){ char top[topic.length()+1]; topic.toCharArray(top,topic.length()+1); char t_char[50]; String t_str = String(t); t_str.toCharArray(t_char, t_str.length() + 1); client.publish(top,t_char); }
Utilisation d’un Broker en ligne
L’utilisation d’un Broker gratuit en ligne permet de s’affranchir de l’installation d’un Broker et de publier/souscrire les messages Mqtt sur un Cloud.
Nous utiliserons un Broker en ligne gratuit : MaQiaTTo
Il suffit de s’inscrire avec un email. Les topics commenceront toujours par l’email.
exemple : prenom.nom@mail.org/meteo1/temperature
Code Arduino pour publier des données :
#include <ESP8266WiFi.h> #include <ESP8266WiFiMulti.h> #include <PubSubClient.h> //WIFI const char* ssid = "SSID"; const char* password = "mdp"; //MQTT #define MQTT_BROKER "maqiatto.com" #define MQTT_BROKER_PORT 1883 #define MQTT_USERNAME "your-maqiatto-user-name" #define MQTT_KEY "your-maqiatto-broker-pass" ESP8266WiFiMulti WiFiMulti; WiFiClient espClient; PubSubClient client(espClient); void setup() { Serial.begin(115200); setup_wifi(); setup_mqtt(); client.publish("emailuser@maqiatto/test", "Hello from ESP32"); } void loop() { reconnect(); client.loop(); float temp = random(30); mqtt_publish("emailuser@maqiatto/test/qqchose",temp); Serial.print("qqchose : "); Serial.println(temp); delay(10000); } void setup_wifi(){ //connexion au wifi WiFiMulti.addAP(ssid, password); while ( WiFiMulti.run() != WL_CONNECTED ) { delay ( 500 ); Serial.print ( "." ); } Serial.println(""); Serial.println("WiFi connecté"); Serial.print("MAC : "); Serial.println(WiFi.macAddress()); Serial.print("Adresse IP : "); Serial.println(WiFi.localIP()); } void setup_mqtt(){ client.setServer(MQTT_BROKER, MQTT_BROKER_PORT); reconnect(); } void reconnect(){ while (!client.connected()) { Serial.println("Connection au serveur MQTT ..."); if (client.connect("ESPClient", MQTT_USERNAME, MQTT_KEY)) { Serial.println("MQTT connecté"); } else { Serial.print("echec, code erreur= "); Serial.println(client.state()); Serial.println("nouvel essai dans 2s"); delay(2000); } } } //Fonction pour publier un float sur un topic void mqtt_publish(String topic, float t){ char top[topic.length()+1]; topic.toCharArray(top,topic.length()+1); char t_char[50]; String t_str = String(t); t_str.toCharArray(t_char, t_str.length() + 1); client.publish(top,t_char); }
Remarque :
Il faut utiliser une carte avec wifi intégré de type ESP8266 ou ESP32 :
Arduino IDE : Installer les cartes ESP32 et ESP8266
bonjour pourquoi j’obtiens chaque fois dans void setup ‘setup_wifi’ was not declared in this scope lors de la compilation une réponse me servirait grandement cordialement GM
Bonjour, normalement ça fonctionne, j’ai essayé. Au pire il faut déplacer le void setup_wifi() avant le void setup().
erreur de compilation
Il faut choisir une carte ESP32 ou ESP8266 pour avoir le wifi intégré (cf https://arduino.blaisepascal.fr/arduino-ide-installer-les-cartes-esp32-et-esp8266/)
Autant pour moi ton code marche très bien.
Par contre juste un petit détail important sur lequel je suis resté bloqué pendant très longtemps.
C’ est de ne surtout pas oublier de rajouter dans la fonction » setup() :
» pinMode( 2 , OUTPUT) » .
Voila merci à toi pour ton partage .
Bonjour, quelle version d’ Arduino utilises-tu dans ce projet?
J’aimerai aussi savoir si il serait possible d’utiliser SerialSoftware pour relier l’esp8266 ou esp32 à l’Arduino au lieu d’utiliser les Pin TX et RX ?
La version de l’IDE utilisée afin de pouvoir programmer des cartes ESP8266 ou ESP32 doit être en version 1.8 minimum.
Pour programmer les cartes j’utilise la connexion USB donc le serial hardware fonctionne bien, mais il n’y a aucune raison que softwareserial ne fonctionne pas pour communiquer avec le PC.