Différences entre les pages « Code Minimal Réseau - (2) Héberger un site web sur mon Wemos D1 mini » et « Code Minimal Réseau - (4) Mes Wemos D1 Mini discutent sur Internet avec MQTT »

 
 
Ligne 3 : Ligne 3 :
 
|Licences=Attribution (CC-BY)
 
|Licences=Attribution (CC-BY)
 
|Description=Utilisation des fonction réseau des cartes compatibles Arduino, possédant une puce Wi-Fi  
 
|Description=Utilisation des fonction réseau des cartes compatibles Arduino, possédant une puce Wi-Fi  
<br/>===  Episode n° 2 : Héberger un site web sur mon Wemos D1 Mini ===
+
<br/>===  Episode n° 4 : Mes Wemos D1 Mini discutent sur Internet avec MQTT ===
 
|Disciplines scientifiques=Arduino, Computing
 
|Disciplines scientifiques=Arduino, Computing
 
|Difficulty=Technical
 
|Difficulty=Technical
Ligne 15 : Ligne 15 :
  
 
#[https://www.wikidebrouillard.org/wiki/Code_Minimal_R%C3%A9seau_-_(1)_Connecter_le_Wemos_D1_mini_%C3%A0_internet_en_wifi Connecter le Wemos D1 Mini à internet en Wi-Fi].
 
#[https://www.wikidebrouillard.org/wiki/Code_Minimal_R%C3%A9seau_-_(1)_Connecter_le_Wemos_D1_mini_%C3%A0_internet_en_wifi Connecter le Wemos D1 Mini à internet en Wi-Fi].
#Héberger un site web sur mon Wemos D1 Mini --- ''cette page''.
+
#[https://www.wikidebrouillard.org/wiki/Code_Minimal_R%C3%A9seau_-_(2)_H%C3%A9berger_un_site_web_sur_mon_Wemos_D1_mini Héberger un site web sur mon Wemos D1 Mini].
#[https://www.wikidebrouillard.org/wiki/Code_Minimal_R%C3%A9seau_-_(3)_Mon_D1_Mini_r%C3%A9cup%C3%A8re_des_donn%C3%A9es_sur_Internet_(Json) Mon Wemos D1 Mini récupère des données sur Internet  (format Json)].
+
#[https://www.wikidebrouillard.org/wiki/Code_Minimal_R%C3%A9seau_-_(3)_Mon_D1_Mini_r%C3%A9cup%C3%A8re_des_donn%C3%A9es_sur_Internet_(Json) Mon Wemos D1 Mini récupère des données sur Internet  (format Json)] .
#[https://www.wikidebrouillard.org/wiki/Code_Minimal_R%C3%A9seau_-_(4)_Mes_Wemos_D1_Mini_discutent_sur_Internet_avec_MQTT Mes Wemos D1 Mini discutent sur Internet (protocole MQTT)]
+
#Mes Wemos D1 Mini discutent sur Internet avec MQTT --- ''cette page''.
  
  
Ligne 45 : Ligne 45 :
 
}}
 
}}
 
{{Tuto Step
 
{{Tuto Step
|Step_Title=Mise en place d'un serveur Web (consultation)
+
|Step_Title=MQTT ? qu'est-ce que c'est ?
|Step_Content=Une première possibilité d'utilisation du Wi-Fi sur nos cartes, est d'y définir un mini-serveur web , qui nous permettra d'afficher voire de modifier, depuis n'importe quel navigateur,  des données gérées par la carte - et par conséquent de récupérer la valeur de  capteurs (température, ...) ou gérer des actionneurs (moteurs, leds, ...).
+
|Step_Content=MQTT (Message Queuing Telemetry Transport) permet l'envoi et la réception de messages de petite taille. MQTT s'appuie sur un "broker MQTT", serveur externe, qui va recevoir les données d'un système, et les redistribuer à d'autres systèmes.   
 +
 
 +
MQTT est souvent utilisé pour collecter des données en provenance de petits capteurs (par exemple, capteurs de température dans un système domotique, capteurs de pollution au niveau d'une région voire d'un pays), car il a aussi comme avantage d'être peu consommateur de ressources.  
 +
 
 +
 
 +
MQTT est basé sur un principe d'abonnement : le système émetteur doit préciser à quel sujet ("topic") se rattache son message, et tous les systèmes qui s'étaient préalablement abonnés à ce "topic" recevront alors le message. Principe proche de Twitter ou Instagram et leurs "hashtags", donc.
 +
 
 +
 
 +
On peut implémenter son propre broker MQTT (le code est libre d'usage), ou s'appuyer sur des brokers gérés par des associations ou des entreprises. Dans l'exemple ci-après, on utilise le broker des Petits Débrouillards, à utiliser avec modération.
 +
 
 +
 
 +
Mais ce n'est pas l'objet du tutoriel, nous nous intéressons ici uniquement à la partie "client", c'est à dire ce qu'il faut mettre en œuvre sur nos cartes D1 mini ou ESP.
 +
}}
 +
{{Tuto Step
 +
|Step_Title=Mise en œuvre sur nos petites cartes
 +
|Step_Content=Il existe plusieurs bibliothèques Arduino permettent de gérer des messages MQTT. Pour notre part, on utilise celle-ci (à aller chercher dans le gestionnaire de bibliothèque) :
 +
<br />{{#annotatedImageLight:Fichier:Code minimal des fonctions reseau Biblio MQTT.png|0=945px|hash=|jsondata=|mediaClass=Image|type=frameless|alt=Bibliothèque MQTT|align=default|src=https://www.wikidebrouillard.org/images/d/d7/Code_minimal_des_fonctions_reseau_Biblio_MQTT.png|href=./Fichier:Code minimal des fonctions reseau Biblio MQTT.png|resource=./Fichier:Code minimal des fonctions reseau Biblio MQTT.png|caption=Bibliothèque MQTT|size=945px}}
  
  
On peut trouver quelques exemples d'applications de ce type, réalisée par des Petits Débrouillards, en particulier le [https://github.com/julienrat/petitbot Petit Bot], petit robot commandable, ou encore [https://www.wikidebrouillard.org/wiki/Commander_un_D1_mini_avec_une_interface_web Commander un D1 mini avec une interface web], permettant d'animer des leds, de gérer un moteur, et de récupérer des données du D1 mini sur une interface web.
 
  
  
Ligne 55 : Ligne 70 :
 
| height="17" bgcolor="#999999" align="left" |
 
| height="17" bgcolor="#999999" align="left" |
 
| valign="middle" bgcolor="#999999" align="center" |
 
| valign="middle" bgcolor="#999999" align="center" |
| bgcolor="#999999" align="center" |Site web
+
| bgcolor="#999999" align="center" |Gestion du MQTT
 
|-
 
|-
 
| rowspan="2" valign="middle" height="49" bgcolor="#999999" align="center" |Avant le Setup
 
| rowspan="2" valign="middle" height="49" bgcolor="#999999" align="center" |Avant le Setup
 
| valign="middle" bgcolor="#999999" align="center" |Importation de la bibliothèque
 
| valign="middle" bgcolor="#999999" align="center" |Importation de la bibliothèque
| valign="middle" align="left" |#include <ESP8266WebServer.h>     // Pour le D1 Mini, ou ...
+
| valign="middle" align="left" |#include <MQTT.h>
 
+
|-
<nowiki>#</nowiki>include <WebServer.h>    // ... pour l'ESP32
+
| valign="middle" bgcolor="#999999" align="center" |Création de l’objet
 +
| valign="middle" align="left" |MQTTClient myMQTTClient;
 +
|-
 +
| rowspan="5" valign="middle" height="17" bgcolor="#999999" align="center" |Dans le Setup (ou le loop)
 +
| valign="middle" bgcolor="#999999" align="center" |Initialisation
 +
| valign="middle" align="left" |myMQTTClient.begin(@IP Broker, Port Broker, Client Wifi) ;
 +
|-
 +
| valign="middle" bgcolor="#999999" align="center" |Se préparer à la réception de messages
 +
| valign="middle" align="left" |myMQTTClient.onMessage(référence de la fonction à appeler sur réception d'un message) ;
 
|-
 
|-
| valign="middle" bgcolor="#999999" align="center" |Création du serveur web (sur le port 80)
+
| valign="middle" bgcolor="#999999" align="center" |Connexion au broker MQTT
| valign="middle" align="left" |ESP8266WebServer myWeb(80);          // Pour le D1 Mini , ou ...
+
|myMQTTClient.connect(ID unique)
 
 
// WebServer myWeb(80) ;              // ... pour l'ESP32
 
 
|-
 
|-
| rowspan="2" valign="middle" height="17" bgcolor="#999999" align="center" |Dans le Setup
+
| valign="middle" bgcolor="#999999" align="center" |Souscrire à un "topic" particulier
| valign="middle" bgcolor="#999999" align="center" |Déclaration de la fonction qui s'occupera
+
|myMQTTClient.subscribe(topic) ;
de la génération de la page web
 
| valign="middle" align="left" |myWeb.on ( "/", runPage01 );
 
 
|-
 
|-
| valign="middle" bgcolor="#999999" align="center" |Démarrage du serveur web
+
| valign="middle" bgcolor="#999999" align="center" |Publier un message
|myWeb.begin();
+
|myMQTTClient.publish(topic, message) ;
 
|-
 
|-
| valign="middle" height="41" bgcolor="#999999" align="center" |Dans le Loop
+
| valign="middle" bgcolor="#999999" align="center" |Dans le Loop
| valign="middle" bgcolor="#999999" align="center" |Traitement des requêtes web
+
| valign="middle" bgcolor="#999999" align="center" |Activation régulière
| valign="middle" align="left" |myWeb.handleClient();
+
|obligatoire : myMQTTClient.loop() ;
|}<br />'''Code Minimal 4a : affichage d'un paramètre de la carte.'''
+
|}
 
 
  
La page web hébergée sur notre carte doit être codée en HTML. La page peut être assez évoluée, intégrer du code javascript, être formatée en mode CSS, etc ... Dans l'exemple "minimal" ci-dessous, on se contente d'une page HTML basique.
+
Pour connaître toutes les autres possibilités de cette bibliothèque, voir sa référence, [https://github.com/256dpi/arduino-mqtt ici].
  
''Une fois le code téléversé sur votre carte, pour voir le résultat, connectez-vous (avec un ordinateur ou un mobile) sur le point d'accès "AP_PetitDeb" (mot de passe "PSWD1234"), puis lancez votre navigateur préféré et tapez 192.168.4.1.''
+
'''Code minimal :'''
<br />{{#annotatedImageLight:Fichier:Code minimal des fonctions reseau Ecran-Etape-4.png|0=785px|hash=|jsondata=|mediaClass=Image|type=frameless|alt=Ecran-Etape-4A|align=center|src=https://www.wikidebrouillard.org/images/9/98/Code_minimal_des_fonctions_reseau_Ecran-Etape-4.png|href=./Fichier:Code minimal des fonctions reseau Ecran-Etape-4.png|resource=./Fichier:Code minimal des fonctions reseau Ecran-Etape-4.png|caption=Ecran-Etape-4A|size=785px}}
 
  
  
  
<br /><syntaxhighlight lang="arduino" line="1">
+
Dans cet exemple, notre carte est à la fois émettrice (elle va envoyer des "Pings") et réceptrice sur le topic "PING_PONG". Elle va aussi répondre "Pong" sur réception d'un "Ping". En règle générale, dans les vraies applications, une carte est souvent émettrice (envoi de données d'un capteur de pollution, par exemple), et il peut y avoir une seule autre carte chargée d'exploiter les données remontées par plusieurs capteurs.<br /><syntaxhighlight lang="arduino" line="1">
 
/* =========================================================================================================
 
/* =========================================================================================================
 
  *  
 
  *  
  *                              CODE MINIMAL RESEAU - ETAPE 4 : site WEB
+
  *                              CODE MINIMAL RESEAU - ETAPE 6 : Messages MQTT
*         
 
*              CAS A : Page HTML Basique, consultation d'une variable de la carte
 
 
  *           
 
  *           
 
  * ---------------------------------------------------------------------------------------------------------
 
  * ---------------------------------------------------------------------------------------------------------
Ligne 100 : Ligne 115 :
 
  * ========================================================================================================= */
 
  * ========================================================================================================= */
  
// Bibliothèques WiFi et WebServer: ATTENTION, choisir celles correspondant à votre matériel.
+
// Bibliothèques requises
 
// ATTENTION AUX MAJUSCULES & MINUSCULES ! Sinon d'autres bibliothèques, plus ou moins valides, seraient utilisées.
 
// ATTENTION AUX MAJUSCULES & MINUSCULES ! Sinon d'autres bibliothèques, plus ou moins valides, seraient utilisées.
  
#include <ESP8266WiFi.h>               // A utiliser pour le D1 Mini
+
#include <WiFiManager.h>                         // Gestion de la connexion Wi-Fi (recherche de points d'accès) 
#include <ESP8266WebServer.h>          // A utiliser pour le D1 Mini
+
#include <WiFiClientSecure.h>                    // Gestion de la connexion à un serveur de données
//#include <WiFi.h>                    // A utiliser pour l'ESP32
+
#include <MQTT.h>                                 // Gestion des requêtes MQTT
//#include <WebServer.h>               // A utiliser pour l'ESP32
 
  
const char* mySSID = "AP_PetitDeb" ;    // On va utiliser le mode "Access Point" pour cet exemple
 
const char* mySecKey = "PSWD1234" ;
 
  
// Déclaration de notre serveur web interne.
+
// Variables globales
  
ESP8266WebServer myWeb(80);           // A utiliser pour le D1 Mini
+
WiFiManager myWiFiManager;                       // Manager Wi-Fi
// WebServer myWeb(80) ;             // A utiliser pour l'ESP32
+
WiFiClient myWiFiClient ;                        // Client WiFi
 +
const char* mySSID  = "AP_PetitDeb" ;           // Nom de la carte en mode Point d'Accès.
 +
const char* mySecKey = "PSWD1234" ;              // Mot de passe associé, 8 caractères au minimum.
  
/* --------------------------------------------------------------------------------------------------------
 
*  webPage01 : formattage HTML de la page web.
 
*  - En fait cette fonction doit rendre une chaîne (String) contenant l'intégralité du code HTML qui sera
 
*    envoyé au navigateur de l'utilisateur.
 
*  - On peut y insérer des informations de la carte, comme ici par exemple, le nom du Point d'accès (mySSID).
 
*    Dans une véritable application, ça pourrait être la valeur d'un capteur de température.
 
* - Pour pouvoir débugger facilement le code HTML/Javascript sur un browser (par exemple Firefox / Outils
 
*  supplémentaires / Outils de développement Web), il est préférable d'indenter le code à l'intérieur de la chaîne
 
*  de caractère, et de mettre des sauts de ligne ("\n") à la fin de chaque ligne de code HTML.
 
*  -------------------------------------------------------------------------------------------------------- */
 
String webPage01() {
 
 
 
    String p;
 
    p =  "<html lang=fr-FR><head><title>ETAPE 4 (Mini-Web)</title></head>\n" ;
 
    p += "<body>\n" ;
 
    p += "    <br><br><br><center><font size=\"12\">\n" ;
 
    p += "    Bonjour, je suis " + String(mySSID) + "...\n" ;          // C'est ici qu'on place l'information SSID.
 
    p += "    <br>... tr&egrave;s heureux de te rencontrer !\n" ;
 
    p += "    </center>\n" ;
 
    p += "</body></html>\n" ;
 
    return p;
 
 
 
}
 
  
/* --------------------------------------------------------------------------------------------------------
+
#define MQTT_BROKER_IP "debrouillards.ddns.net"  // Serveur sur lequel est installé le Broker MQTT.
*  runPage01 : gestion de la page web
+
#define MQTT_BROKER_PORT 1883                    // Port sur lequel écoute le broker MQTT
*  -------------------------------------------------------------------------------------------------------- */
 
void runPage01() {
 
  
    // Affichage de la page Web.
+
char MY_MQTT_ID[20] ;                            // Id unique de notre objet, basé sur ESP.getChipId()
    myWeb.send ( 200, "text/html", webPage01() );
+
const char MY_MQTT_TOPIC[] = "PING_PONG" ;        // Nom de notre topic (sujet) MQTT
}
 
  
/* --------------------------------------------------------------------------------------------------------
+
MQTTClient myMQTTClient;                          // Client MQTT
*  SETUP : Initialisation
 
*  -------------------------------------------------------------------------------------------------------- */
 
void setup() {
 
  
    // Initialisation de la liaison série, affichage 1er message
+
bool IHaveToAnswer = false ;                      // Passe à 'true' si on doit répondre.
  
    Serial.begin(115200);
+
#define TEN_SECONDS 10000                        // On enverra un message au broker toutes les 10000 ms = 10 secondes.
    delay(100) ;
+
unsigned long myWakeUp ;                         // Timer mis en place pour limiter le nombre d'envois au broker.
    Serial.println();
 
    Serial.println("----------------------") ;
 
    Serial.println("Exemple de serveur WEB") ;
 
    Serial.println("----------------------") ;
 
  
    // Déclaration du mode "Point d'Accès". On s'arrête là si échec.
+
/* --------------------------------------------------------------------------------------------------------------
 +
* MQTT_Received : réception d'un message MQTT
 +
* ------------------------------------------------------------------------------------------------------------- */
 +
void MQTT_Received(String &topic, String &payload) {
  
     Serial.println("Déclaration Mode AP, SSID \"" + String(mySSID) + "\"") ;
+
     char myTrace[80] ;
    if (!WiFi.softAP(mySSID,mySecKey)) {
 
        Serial.println("Mode AP KO ... :-(") ;
 
        return ;
 
    }
 
  
     // Affichage de l'adresse IP principale du Point d'Accès.
+
     sprintf(myTrace, "Réception sur le topic \"%s\" du message MQTT \"%s\".", topic, payload) ;
 +
    Serial.println(myTrace) ;
  
     Serial.print("Mode AP OK, IP Address : ") ;
+
     // Comme indiqué dans la documentation, il ne faut pas renvoyer de messages dans cette fonction,
     Serial.println(WiFi.softAPIP()) ;
+
    // ça risque de mal se passer (blocages, ...). Si on souhaite répondre au message reçu, il vaut
 +
     // mieux mettre à jour une variable globale, qui sera vérifiée dans la partie loop().
  
     // Définition des points d'entrée du serveur Web (un seul ici), et démarrage du serveur.
+
     if (payload == String("Ping")) {
 +
        IHaveToAnswer = true ;
 +
    }
 
    
 
    
    myWeb.on ( "/", runPage01 );
 
    myWeb.begin();
 
   
 
 
}
 
}
  
 
/* --------------------------------------------------------------------------------------------------------------
 
/* --------------------------------------------------------------------------------------------------------------
  *  LOOP : fonction appelée régulièrement par le système
+
  *  MQTT_Connect : Connexion - ou reconnexion - au broker MQTT.
  * ------------------------------------------------------------------------------------------------------------- */
+
  * ------------------------------------------------------------------------------------------------------------- */
void loop() {  
+
void MQTT_Connect() {
 
 
    // Traitement des requêtes web.
 
    myWeb.handleClient();
 
     
 
}
 
  
</syntaxhighlight><br />
+
    // Vérification WiFi OK.
}}
+
   
{{Tuto Step
+
    int nbTries = 0 ;
|Step_Title=Mise en place d'un serveur Web (modification)
+
    while (WiFi.status() != WL_CONNECTED) {
|Step_Content=<br />'''Code Minimal 4b : actionner la carte via l'interface web'''
+
        if (nbTries++ > 10) {
 +
            Serial.println("Connexion WiFi KO :-(") ;
 +
            return ;
 +
        }
 +
        delay(500);
 +
    }
  
 
+
    // Connexion au broker.
Dans l'exemple précédent, on se contente de récupérer un paramètre de la carte. Mais il est également possible de modifier un paramètre (par exemple l'état d'une des sorties de la carte, et donc d'agir sur un de ses périphériques : led, moteur, ...).
 
 
 
 
 
Le code ci-dessous présente donc un code "moins minimal", permettant d'afficher et de modifier une variable du programme Arduino. Dans une application réelle, il suffira alors d'utiliser cette variable pour afficher et agir sur sur l'état d'une des entrées/sorties de la carte.
 
 
 
La partie HTML  est un peu plus complexe, car on va y définir une fonction javascript, qui permettra de faire passer des informations du navigateur au serveur web hébergé. Voir les explications complémentaires dans le code lui-même. 
 
 
 
{{#annotatedImageLight:Fichier:Code minimal des fonctions reseau Ecran-Etape4B.png|0=790px|hash=|jsondata=|mediaClass=Image|type=frameless|alt=Ecran-Etape4B|align=center|src=https://www.wikidebrouillard.org/images/2/27/Code_minimal_des_fonctions_reseau_Ecran-Etape4B.png|href=./Fichier:Code minimal des fonctions reseau Ecran-Etape4B.png|resource=./Fichier:Code minimal des fonctions reseau Ecran-Etape4B.png|caption=Ecran-Etape4B|size=790px}}   
 
 
 
<syntaxhighlight lang="arduino" line="1">
 
/* =========================================================================================================
 
*
 
*                              CODE MINIMAL RESEAU - ETAPE 4 : site WEB
 
*         
 
*              CAS B : Page HTML plus évoluéee, et modification d'une variable de la carte
 
*         
 
* ---------------------------------------------------------------------------------------------------------
 
* Les petits Débrouillards - décembre 2022 - CC-By-Sa http://creativecommons.org/licenses/by-nc-sa/3.0/
 
* ========================================================================================================= */
 
 
 
// Bibliothèques WiFi et WebServer: ATTENTION, choisir celles correspondant à votre matériel.
 
// ATTENTION AUX MAJUSCULES & MINUSCULES ! Sinon d'autres bibliothèques, plus ou moins valides, seraient utilisées.
 
 
 
#include <ESP8266WiFi.h>                // A utiliser pour le D1 Mini
 
#include <ESP8266WebServer.h>          // A utiliser pour le D1 Mini
 
//#include <WiFi.h>                    // A utiliser pour l'ESP32
 
//#include <WebServer.h>                // A utiliser pour l'ESP32
 
 
 
const char* mySSID = "AP_PetitDeb" ;    // On va utiliser le mode "Access Point" pour cet exemple
 
const char* mySecKey = "PSWD1234" ;
 
 
 
// Déclaration de notre serveur web interne, qui écoutera sur le port 80.
 
 
 
ESP8266WebServer myWeb(80);          // A utiliser pour le D1 Mini
 
// WebServer myWeb(80) ;              // A utiliser pour l'ESP32
 
 
 
// Variable qui sera affichée et modifiée depuis notre interface web.
 
 
 
int myValue = 0 ;
 
 
 
/* --------------------------------------------------------------------------------------------------------
 
*  webPage01 : formattage HTML de la page web.
 
*  - En fait cette fonction doit rendre une chaîne (String) contenant l'intégralité du code HTML qui sera
 
*    envoyé au navigateur de l'utilisateur.
 
*  - Comme dans l'exemple précédent (Exemple_4A), on insère dans cette chaîne une information de la carte,
 
*    ici la valeur de notre variable 'my value'. Mais on va aussi ajouter des boutons permettant de modifier
 
*    cette valeur sur la carte.
 
* - Idem Exemple_4A : pour pouvoir débugger facilement le code HTML/Javascript sur un browser (par exemple
 
*  Firefox / Outils supplémentaires / Outils de développement Web), il est préférable d'indenter le code à
 
*  l'intérieur de la chaîne de caractère, et de mettre des sauts de ligne ("\n") à la fin de chaque ligne
 
*  de code HTML.
 
*  -------------------------------------------------------------------------------------------------------- */
 
String webPage01() {
 
 
 
    String p; 
 
 
 
    // Début de construction de la page web (entête, titre, paramètres)
 
 
      
 
      
     p =  "<html lang=fr-FR><head>\n" ;
+
     Serial.println("--- Connexion MQTT, Id unique \"" + String(MY_MQTT_ID) + "\" ") ;
    p += "<title>ETAPE 4B</title>\n" ;             // Titre de la page
+
     nbTries = 0 ;
     p += "   <meta charset='UTF-8'>\n" ;           // Codage des caractères, UTF-8 est fortement recommandé
+
    while (!myMQTTClient.connect(MY_MQTT_ID)) {                                     
    p += "</head>\n" ;
+
        Serial.print(".") ;  
 +
        if (nbTries++ > 10) {
 +
            Serial.println(" KO :-(") ;
 +
            return ;
 +
        }
 +
        delay(500);
 +
    }
  
     // Définitions CSS (), qui permettent de décrire le format des objets sur la page web.  
+
     // Abonnement au topic.
    // Si vous voulez tout savoir sur CSS, on peut trouver une bonne introduction ici : https://developer.mozilla.org/fr/docs/Learn/CSS
 
    // et une référence complète ici : https://developer.mozilla.org/fr/docs/Web/CSS/Reference
 
 
      
 
      
     p  += "<style>\n" ;
+
     Serial.println("--- Abonnement au sujet \"" + String(MY_MQTT_TOPIC) + "\"") ;  
    p += "    body { background-color: #000088; color: white; font-size: 25px; }\n";          // couleur fond écran (bleu foncé) et textes (blanc).
+
     myMQTTClient.subscribe(MY_MQTT_TOPIC)
    p += "    input { width:25%; margin:10px; font-size:20px; border-radius: 5px; }\n";        // format des boutons (taille, coins arrondis, ...).
 
    p += "</style>\n" ;
 
 
 
    // Début du code javascript. Javascript est le langage utilisé au niveau des navigateurs web (Firefox, Microsoft Edge, Google Chrome, ...)
 
    // pour introduire un peu de dynamisme et d'intelligence dans les pages web. Cela peut permettre, par exemple, de réaliser une action
 
    // locale et immediate, telle que l'agrandissement d'une image, le changement d'un texte, etc ... sans avoir à réinterroger le serveur web.
 
    //
 
    // Dans notre cas, la fonction 'addition(val)' ci-dessous va ajouter le paramètres 'val' à l'adresse du serveur web, et va ensuite appeler
 
    // la page web de notre carte, avec ce paramètre. Par exemple, si l'adresse du site web de notre carte est 192.168.4.1, l'appel à la fonction
 
    // addition(-1) va demander la page '192.168.4.1?add=-1'. Le paramètre 'add' de valeur '-1' sera alors exploité par la carte dans la
 
    // fonction runPage01() définie plus bas.
 
    //
 
    // Dans un exemple réel on pourrait bien sûr définir plusieurs paramètres, du style '192.168.4.1?voyant=vert&servo1=90&servo2=0'
 
 
 
    p += "<script>\n" ;
 
    p +=  "function addition(val) {\n";                                           
 
    p +=  "    window.location = window.location.pathname + '?add=' + val ;\n";   
 
    p +"}\n";
 
    p += "</script>\n" ;
 
 
 
     // Corps de la page web : affichage de la valeur récupérée sur la carte, et de deux boutons 'ajouter 1' et 'enlever 1'.
 
    // La fonction addition() définie dans le code javascript ci-dessus, sera appelée lorsqu'on appuie sur ces boutons.
 
 
      
 
      
    p += "<body><center>\n" ;
 
    p += "    </br></br>Valeur actuelle : " + String(myValue) + "</br></br>\n";               
 
    p +=  "  <form>\n"; 
 
    p +=  "        <input type='submit' value='ajouter 1' formaction='javascript:addition(1);' formmethod=post>\n" ;
 
    p +=  "        <input type='submit' value='enlever 1' formaction='javascript:addition(-1);' formmethod=post>\n" ;
 
    p +=  "  </form>\n";
 
    p += "</center></body></html>" ;
 
 
    // ça y est, la page web est complètement constituée !
 
 
    return p;
 
 
 
 
}
 
}
 
/* --------------------------------------------------------------------------------------------------------
 
*  runPage01 : gestion de la page web
 
*  -------------------------------------------------------------------------------------------------------- */
 
void runPage01() {
 
 
    // Si la page a un paramètre 'add', alors on récupère sa valeur, et on l'ajoute à notre variable 'myValue'.
 
 
 
    if ( myWeb.hasArg("add") ) {
 
        Serial.println("Traitement pge web, arg = '" + String(myWeb.arg("add")) + "'") ;
 
        int myArg = myWeb.arg("add").toInt() ;
 
        myValue = myValue + myArg ;
 
        Serial.println("Traitement page web, arg = '" + String(myWeb.arg("add")) + "' --> Nouvelle valeur : " + String(myValue)) ;
 
    }
 
 
    // On renvoie la page Web.
 
    myWeb.send ( 200, "text/html", webPage01() );
 
}
 
 
 
/* --------------------------------------------------------------------------------------------------------
 
/* --------------------------------------------------------------------------------------------------------
 
  *  SETUP : Initialisation
 
  *  SETUP : Initialisation
  * -------------------------------------------------------------------------------------------------------- */
+
  * -------------------------------------------------------------------------------------------------------- */
 
void setup() {
 
void setup() {
  
Ligne 334 : Ligne 209 :
 
     delay(100) ;
 
     delay(100) ;
 
     Serial.println();  
 
     Serial.println();  
     Serial.println("----------------------") ;
+
     Serial.println("---------------------") ;
     Serial.println("Exemple de serveur WEB") ;
+
     Serial.println("Exemple messages MQTT") ;
     Serial.println("----------------------") ;
+
     Serial.println("---------------------") ;
 +
 
 +
    // Tentative de connexion au Wi-Fi. Si la carte n'a pas réussi  se connecter au dernier Point d'Accès connu,
 +
    // alors elle va se positionner en mode Point d'Accès, demandera sur l'adresse 192.168.4.1 quel nouveau
 +
    // Point d'Accès choisir. Par défaut, on restera bloqué tant que l'utilisateur n'aura pas fait de choix.
 +
   
 +
    Serial.println("Connexion au Wi-Fi ...");
 +
    if (myWiFiManager.autoConnect(mySSID, mySecKey)) {
 +
        Serial.println(); Serial.print("Connecté ! Adresse IP : ");
 +
        Serial.println(WiFi.localIP());
 +
    }
 +
    else {
 +
        Serial.println("Connexion Wi-Fi KO :-(");   
 +
    }
  
     // Déclaration du mode "Point d'Accès". On s'arrête là si échec.
+
     // Initialisation du MQTT
  
     Serial.println("Déclaration Mode AP, SSID \"" + String(mySSID) + "\"") ;
+
     Serial.println("Initialisation MQTT ...");
     if (!WiFi.softAP(mySSID,mySecKey)) {
+
     myMQTTClient.begin(MQTT_BROKER_IP, MQTT_BROKER_PORT, myWiFiClient);              // lancement du client MQTT ...
        Serial.println("Mode AP KO ... :-(") ;
+
    myMQTTClient.onMessage(MQTT_Received);                                           // ... qui appelera la fonction MQTT_Received si un message est reçu.
        return ;
 
    }
 
  
     // Affichage de l'adresse IP principale du Point d'Accès.
+
     strncpy(MY_MQTT_ID, String(ESP.getChipId()).c_str(),sizeof(MY_MQTT_ID)) ;        // Fabrication de mon ID unique, sur la base du n° de puce
 +
    MY_MQTT_ID[sizeof(MY_MQTT_ID)-1] = '\0' ;
  
     Serial.print("Mode AP OK, IP Address : ") ;
+
     // Connexion au broker
    Serial.println(WiFi.softAPIP()) ;
 
  
     // Définition des points d'entrée du serveur Web (un seul ici),
+
     MQTT_Connect() ;
    // et démarrage du serveur.
 
 
 
    myWeb.on ( "/", runPage01 );
 
    myWeb.begin();
 
 
      
 
      
 +
    // Initialisation du timer qui sera testé dans loop() - pour faire appel au serveur seulement toutes les 10 secondes
 +
    // millis() est une fonction système donnant le nombre de ms depuis le lancement ou la réinitialisation de la carte.
 +
 +
    unsigned long myWakeUp = millis() + TEN_SECONDS ;
 +
 
}
 
}
  
Ligne 363 : Ligne 250 :
 
  *  ------------------------------------------------------------------------------------------------------------- */
 
  *  ------------------------------------------------------------------------------------------------------------- */
 
void loop() {  
 
void loop() {  
 
+
 
     // Traitement des requêtes web.
+
     // Réactivation du client MQTT
     myWeb.handleClient();  
+
 
     
+
    myMQTTClient.loop() ;
 +
    delay(10) ;            // Problèmes de stabilité Wi-Fi ? (Cf. doc MQTT)
 +
 
 +
     // Reconnexion au broker MQTT si nécessaire ...
 +
 
 +
    if (!myMQTTClient.connected()) {
 +
        MQTT_Connect();
 +
    }
 +
 
 +
    // Si on a précédemment reçu un 'Ping', on va répondre 'Pong'
 +
 
 +
    if (IHaveToAnswer) {
 +
        IHaveToAnswer = false ;
 +
        Serial.println("Envoi de la réponse \"Pong\" sur le topic \"" + String(MY_MQTT_TOPIC) + "\".") ;
 +
        myMQTTClient.publish(MY_MQTT_TOPIC, "Pong") ;
 +
    }
 +
 
 +
    // Envoi d'un message toutes les 10 secondew.
 +
 
 +
    unsigned long myNow = millis() ;
 +
    if (myNow >= myWakeUp) {
 +
        Serial.println("Wake Up ! envoi du message \"Ping\" sur le topic \"" + String(MY_MQTT_TOPIC) + "\".") ;
 +
        myMQTTClient.publish(MY_MQTT_TOPIC, "Ping") ;
 +
        myWakeUp = myNow + TEN_SECONDS ;       
 +
    }
 +
 
 +
 
 
}
 
}
 
</syntaxhighlight>
 
</syntaxhighlight>
 
}}
 
}}
 
{{Tuto Step
 
{{Tuto Step
|Step_Title=La suite, la suite ! ... :-)
+
|Step_Title=La suite, la suite ... à vous de jouer !
|Step_Content=*'''Episode 3 :''' [https://www.wikidebrouillard.org/wiki/Code_Minimal_R%C3%A9seau_-_(3)_Mon_D1_Mini_r%C3%A9cup%C3%A8re_des_donn%C3%A9es_sur_Internet_(Json) Mon Wemos D1 mini récupère des donnée sur Internet  (Json)].
+
|Step_Content=... Si vous avez suivi tous les épisodes ... :-)
*'''Episode 4 :''' [https://www.wikidebrouillard.org/wiki/Code_Minimal_R%C3%A9seau_-_(4)_Mes_Wemos_D1_Mini_discutent_sur_Internet_avec_MQTT Mon Wemos D1 mini discute sur Internet avec MQTT].
+
 
 +
 
 +
Les exemples de code "minimal" fournis peuvent servir de base pour vos futures réalisations, ou pour gagner un temps précieux  pendant un hackathon.  Tous les codes sont regroupés dans un dossier compressé, accessible dans la rubrique "Fichiers" en début de cette page.
 +
 
 +
 
 +
Pour aller plus loin, n'hésitez pas à copier ces programmes minimaux, et à les modifier en douceur pour obtenir autre chose que des traces dans le moniteur série Arduino. Juste quelques idées ...
 +
 
 +
<br />
  
''Ces épisodes sont indépendants les uns des autres''.
+
*Sur la base du code de l'étape 4 (serveur web), et d'un [https://www.wikidebrouillard.org/wiki/Item:Servomoteur servomoteur], fabriquer un coffre secret qui ne s'ouvre que lorsque son/sa propriétaire tape un code sur son téléphone ;
 +
*Sur la base du code de l'étape 5 (JSON) et d'un [https://www.wikidebrouillard.org/wiki/Item:Ruban_de_Led_-_WS2812B ruban de leds], faire un thermomètre affichant la température de votre ville préférée. Il y a de nombreux sites web proposant gratuitement (si on n'abuse pas) des informations météo en mode JSONs, par exemple :
 +
**[https://api.tutiempo.net/fr/json.html TuTiempo.net]
 +
**[https://openweathermap.org/api OpenWeather]
 +
**[https://prevision-meteo.ch/services Previsionsmeteo.ch]
 +
*Sur la base du code de l'étape 6 (MQTT),  et d'un [https://www.wikidebrouillard.org/wiki/Item:Capteur_de_temp%C3%A9rature_et_d%27humidit%C3%A9_DHT11 capteur de température et d'humidité],  ... ah, on me glisse dans l’oreillette que [https://www.wikidebrouillard.org/wiki/Envoyer_des_donn%C3%A9es_sur_le_WEB_gr%C3%A2ce_%C3%A0_MQTT ça existe déjà sur le Wikidébrouillard] ! (avec une autre bibliothèque MQTT). ... Ou bien alors, avec deux D1 Mini, deux  [https://www.wikidebrouillard.org/wiki/Item:Bouton_poussoir boutons poussoirs] et deux [https://www.wikidebrouillard.org/wiki/Item:Ruban_de_Led_-_WS2812B rubans de leds], faire une version "jeu à distance" du célèbre [https://www.wikidebrouillard.org/wiki/D1-Pong D1-Pong] !
 
}}
 
}}
 
{{Notes}}
 
{{Notes}}

Version actuelle datée du 1 février 2023 à 17:35

Auteur avatarPhilippe Blusseau | Dernière modification 1/02/2023 par Philby

Code minimal des fonctions r seau WiKi Reseau1.png
Utilisation des fonction réseau des cartes compatibles Arduino, possédant une puce Wi-Fi
=== Episode n° 4 : Mes Wemos D1 Mini discutent sur Internet avec MQTT ===
Difficulté
Technique
Durée
2 heure(s)
Disciplines scientifiques
Arduino, Informatique
<languages />
Licence : Attribution (CC-BY)

Introduction

Cette expérience fait partie d'une série de 4 épisodes, présentant différentes façons de bénéficier des capacités de communication des cartes compatibles Arduino possédant une puce Wi-Fi (Wemos D1 mini, ESP32, ...). On suppose (Cf. "Expériences ré-requises" ci-après) que vous avez déjà manipulé une carte Arduino et son environnement de développement. Ces 4 épisodes sont les suivants :


  1. Connecter le Wemos D1 Mini à internet en Wi-Fi.
  2. Héberger un site web sur mon Wemos D1 Mini.
  3. Mon Wemos D1 Mini récupère des données sur Internet  (format Json) .
  4. Mes Wemos D1 Mini discutent sur Internet avec MQTT --- cette page.


Il est nécessaire de commencer par l'épisode 1, par contre les épisodes suivants peuvent être consultés dans n'importe quel ordre.


Dans la même philosophie que les expériences "Code minimal des capteurs pour Arduino" et "Code minimal des actionneurs pour Arduino", nous fournirons ici uniquement le code relatif à nos besoins de connexion, sans mettre au point une quelconque application. Donc, ici, pas besoin de connecter une led ou un capteur, donc pas de schéma de montage : vous branchez simplement votre carte en USB sur votre ordinateur, et les résultats seront visibles en mode texte dans le moniteur série de l'environnement de développement Arduino.
  • Expériences pré-requises
  • Fichiers

Étape 1 - MQTT ? qu'est-ce que c'est ?

MQTT (Message Queuing Telemetry Transport) permet l'envoi et la réception de messages de petite taille. MQTT s'appuie sur un "broker MQTT", serveur externe, qui va recevoir les données d'un système, et les redistribuer à d'autres systèmes.

MQTT est souvent utilisé pour collecter des données en provenance de petits capteurs (par exemple, capteurs de température dans un système domotique, capteurs de pollution au niveau d'une région voire d'un pays), car il a aussi comme avantage d'être peu consommateur de ressources.


MQTT est basé sur un principe d'abonnement : le système émetteur doit préciser à quel sujet ("topic") se rattache son message, et tous les systèmes qui s'étaient préalablement abonnés à ce "topic" recevront alors le message. Principe proche de Twitter ou Instagram et leurs "hashtags", donc.


On peut implémenter son propre broker MQTT (le code est libre d'usage), ou s'appuyer sur des brokers gérés par des associations ou des entreprises. Dans l'exemple ci-après, on utilise le broker des Petits Débrouillards, à utiliser avec modération.


Mais ce n'est pas l'objet du tutoriel, nous nous intéressons ici uniquement à la partie "client", c'est à dire ce qu'il faut mettre en œuvre sur nos cartes D1 mini ou ESP.

Étape 2 - Mise en œuvre sur nos petites cartes

Il existe plusieurs bibliothèques Arduino permettent de gérer des messages MQTT. Pour notre part, on utilise celle-ci (à aller chercher dans le gestionnaire de bibliothèque) :


Bibliothèque MQTT



Gestion du MQTT
Avant le Setup Importation de la bibliothèque #include <MQTT.h>
Création de l’objet MQTTClient myMQTTClient;
Dans le Setup (ou le loop) Initialisation myMQTTClient.begin(@IP Broker, Port Broker, Client Wifi) ;
Se préparer à la réception de messages myMQTTClient.onMessage(référence de la fonction à appeler sur réception d'un message) ;
Connexion au broker MQTT myMQTTClient.connect(ID unique)
Souscrire à un "topic" particulier myMQTTClient.subscribe(topic) ;
Publier un message myMQTTClient.publish(topic, message) ;
Dans le Loop Activation régulière obligatoire : myMQTTClient.loop() ;

Pour connaître toutes les autres possibilités de cette bibliothèque, voir sa référence, ici.

Code minimal :


Dans cet exemple, notre carte est à la fois émettrice (elle va envoyer des "Pings") et réceptrice sur le topic "PING_PONG". Elle va aussi répondre "Pong" sur réception d'un "Ping". En règle générale, dans les vraies applications, une carte est souvent émettrice (envoi de données d'un capteur de pollution, par exemple), et il peut y avoir une seule autre carte chargée d'exploiter les données remontées par plusieurs capteurs.
  1 /* =========================================================================================================
  2  * 
  3  *                              CODE MINIMAL RESEAU - ETAPE 6 : Messages MQTT
  4  *          
  5  * ---------------------------------------------------------------------------------------------------------
  6  * Les petits Débrouillards - décembre 2022 - CC-By-Sa http://creativecommons.org/licenses/by-nc-sa/3.0/
  7  * ========================================================================================================= */
  8 
  9 // Bibliothèques requises
 10 // ATTENTION AUX MAJUSCULES & MINUSCULES ! Sinon d'autres bibliothèques, plus ou moins valides, seraient utilisées.
 11 
 12 #include <WiFiManager.h>                          // Gestion de la connexion Wi-Fi (recherche de points d'accès)  
 13 #include <WiFiClientSecure.h>                     // Gestion de la connexion à un serveur de données
 14 #include <MQTT.h>                                 // Gestion des requêtes MQTT
 15 
 16 
 17 // Variables globales
 18 
 19 WiFiManager myWiFiManager;                        // Manager Wi-Fi
 20 WiFiClient myWiFiClient ;                         // Client WiFi
 21 const char* mySSID   = "AP_PetitDeb" ;            // Nom de la carte en mode Point d'Accès.
 22 const char* mySecKey = "PSWD1234" ;               // Mot de passe associé, 8 caractères au minimum.
 23 
 24 
 25 #define MQTT_BROKER_IP "debrouillards.ddns.net"   // Serveur sur lequel est installé le Broker MQTT.
 26 #define MQTT_BROKER_PORT 1883                     // Port sur lequel écoute le broker MQTT
 27 
 28 char MY_MQTT_ID[20] ;                             // Id unique de notre objet, basé sur ESP.getChipId()
 29 const char MY_MQTT_TOPIC[] = "PING_PONG" ;        // Nom de notre topic (sujet) MQTT
 30 
 31 MQTTClient myMQTTClient;                          // Client MQTT
 32 
 33 bool IHaveToAnswer = false ;                      // Passe à 'true' si on doit répondre.
 34 
 35 #define TEN_SECONDS 10000                         // On enverra un message au broker toutes les 10000 ms = 10 secondes.
 36 unsigned long myWakeUp ;                          // Timer mis en place pour limiter le nombre d'envois au broker.
 37 
 38 /* --------------------------------------------------------------------------------------------------------------
 39  * MQTT_Received : réception d'un message MQTT
 40  * ------------------------------------------------------------------------------------------------------------- */
 41 void MQTT_Received(String &topic, String &payload) {
 42 
 43     char myTrace[80] ;
 44 
 45     sprintf(myTrace, "Réception sur le topic \"%s\" du message MQTT \"%s\".", topic, payload) ;
 46     Serial.println(myTrace) ;
 47 
 48     // Comme indiqué dans la documentation, il ne faut pas renvoyer de messages dans cette fonction,
 49     // ça risque de mal se passer (blocages, ...). Si on souhaite répondre au message reçu, il vaut
 50     // mieux mettre à jour une variable globale, qui sera vérifiée dans la partie loop().
 51 
 52     if (payload == String("Ping")) {
 53         IHaveToAnswer = true ;
 54     }
 55   
 56 }
 57 
 58 /* --------------------------------------------------------------------------------------------------------------
 59  *  MQTT_Connect : Connexion - ou reconnexion - au broker MQTT.
 60  * ------------------------------------------------------------------------------------------------------------- */
 61 void MQTT_Connect() {
 62 
 63     // Vérification WiFi OK.
 64     
 65     int nbTries = 0 ;
 66     while (WiFi.status() != WL_CONNECTED) {
 67         if (nbTries++ > 10) {
 68             Serial.println("Connexion WiFi KO :-(") ;
 69             return ;
 70         }
 71         delay(500);
 72     }
 73 
 74     // Connexion au broker.
 75     
 76     Serial.println("--- Connexion MQTT, Id unique \"" + String(MY_MQTT_ID) + "\" ") ;
 77     nbTries = 0 ;
 78     while (!myMQTTClient.connect(MY_MQTT_ID)) {                                       
 79         Serial.print(".") ; 
 80         if (nbTries++ > 10) {
 81             Serial.println(" KO :-(") ;
 82             return ;
 83         }
 84         delay(500);
 85     }
 86 
 87     // Abonnement au topic.
 88     
 89     Serial.println("--- Abonnement au sujet \"" + String(MY_MQTT_TOPIC) + "\"") ;   
 90     myMQTTClient.subscribe(MY_MQTT_TOPIC);  
 91     
 92 }
 93 /* --------------------------------------------------------------------------------------------------------
 94  *  SETUP : Initialisation
 95  * -------------------------------------------------------------------------------------------------------- */
 96 void setup() {
 97 
 98     // Initialisation de la liaison série, affichage 1er message
 99 
100     Serial.begin(115200);
101     delay(100) ;
102     Serial.println(); 
103     Serial.println("---------------------") ;
104     Serial.println("Exemple messages MQTT") ;
105     Serial.println("---------------------") ;
106 
107     // Tentative de connexion au Wi-Fi. Si la carte n'a pas réussi  se connecter au dernier Point d'Accès connu,
108     // alors elle va se positionner en mode Point d'Accès, demandera sur l'adresse 192.168.4.1 quel nouveau
109     // Point d'Accès choisir. Par défaut, on restera bloqué tant que l'utilisateur n'aura pas fait de choix.
110     
111     Serial.println("Connexion au Wi-Fi ...");
112     if (myWiFiManager.autoConnect(mySSID, mySecKey)) {
113         Serial.println(); Serial.print("Connecté ! Adresse IP : ");
114         Serial.println(WiFi.localIP());
115     }
116     else {
117         Serial.println("Connexion Wi-Fi KO :-(");     
118     }
119 
120     // Initialisation du MQTT
121 
122     Serial.println("Initialisation MQTT ...");
123     myMQTTClient.begin(MQTT_BROKER_IP, MQTT_BROKER_PORT, myWiFiClient);               // lancement du client MQTT ...
124     myMQTTClient.onMessage(MQTT_Received);                                            // ... qui appelera la fonction MQTT_Received si un message est reçu.
125 
126     strncpy(MY_MQTT_ID, String(ESP.getChipId()).c_str(),sizeof(MY_MQTT_ID)) ;         // Fabrication de mon ID unique, sur la base du n° de puce
127     MY_MQTT_ID[sizeof(MY_MQTT_ID)-1] = '\0' ;
128 
129     // Connexion au broker 
130 
131     MQTT_Connect() ;
132     
133     // Initialisation du timer qui sera testé dans loop() - pour faire appel au serveur seulement toutes les 10 secondes 
134     // millis() est une fonction système donnant le nombre de ms depuis le lancement ou la réinitialisation de la carte.
135 
136     unsigned long myWakeUp = millis() + TEN_SECONDS ;
137 
138 }
139 
140 /* --------------------------------------------------------------------------------------------------------------
141  *  LOOP : fonction appelée régulièrement par le système
142  *  ------------------------------------------------------------------------------------------------------------- */
143 void loop() { 
144 
145     // Réactivation du client MQTT
146 
147     myMQTTClient.loop() ;
148     delay(10) ;             // Problèmes de stabilité Wi-Fi ? (Cf. doc MQTT)
149 
150     // Reconnexion au broker MQTT si nécessaire ...
151 
152     if (!myMQTTClient.connected()) {
153         MQTT_Connect();
154     }
155 
156     // Si on a précédemment reçu un 'Ping', on va répondre 'Pong'
157 
158     if (IHaveToAnswer) {
159         IHaveToAnswer = false ;
160         Serial.println("Envoi de la réponse \"Pong\" sur le topic \"" + String(MY_MQTT_TOPIC) + "\".") ;
161         myMQTTClient.publish(MY_MQTT_TOPIC, "Pong") ;
162     }
163 
164     // Envoi d'un message toutes les 10 secondew.
165    
166     unsigned long myNow = millis() ;
167     if (myNow >= myWakeUp) {
168         Serial.println("Wake Up ! envoi du message \"Ping\" sur le topic \"" + String(MY_MQTT_TOPIC) + "\".") ;
169         myMQTTClient.publish(MY_MQTT_TOPIC, "Ping") ;
170         myWakeUp = myNow + TEN_SECONDS ;         
171     }
172 
173 
174 }

Étape 3 - La suite, la suite ... à vous de jouer !

... Si vous avez suivi tous les épisodes ... :-)


Les exemples de code "minimal" fournis peuvent servir de base pour vos futures réalisations, ou pour gagner un temps précieux pendant un hackathon. Tous les codes sont regroupés dans un dossier compressé, accessible dans la rubrique "Fichiers" en début de cette page.


Pour aller plus loin, n'hésitez pas à copier ces programmes minimaux, et à les modifier en douceur pour obtenir autre chose que des traces dans le moniteur série Arduino. Juste quelques idées ...



Dernière modification 1/02/2023 par user:Philby.

Commentaires

Published