L'objectif de cet atelier va être de faire communiquer plusieurs ESP ensemble. L'intérêt va être de se passer d'ordinateur (par rapport à l'atelier précédent). Les applications sont nombreuses: piloter à distance un moteur, une led, récupérer à distance les données d'un capteur pour les afficher sur un petit écran oled, bref, pouvoir connecter des choses, à peu de frais, et avec une consommation électrique très faible.
Rappel de l'épisode précédent
Pour transmettre des infos à l'ESP et piloter le relais (ou une LED, le code serait identique), nous utilisions précédemment l'URL du navigateur pour transmettre des requêtes au serveur web de l'ESP, qui les analyse et en déduit les actions à effectuer.
Nous allons garder exactement le même comportement, mais cette fois, c'est l'ESP qui enverra cette chaîne de caractère au serveur, de manière très simple, via une commande:
`client.println(“off1\r”);`
Mais commençons par le commencement:
#1-Le serveur Le code est en tous points identiques à l'exercice précédent, à ceci près que nous allons connecter à ce serveur central plusieurs clients au lieu d'un seul. Plusieurs requêtes différentes devront donc être analysées pour des effets différents. Ici une LED RVB permettra d'affecter une couleur séparée à chaque client.
Les requêtes, une fois interceptée, seront analysées ainsi:
``` On attends que le serveur reçoive des données d'un client. while (!client.available()) { delay(1); On lit la première ligne de la requête
String req = client.readStringUntil('\r'); Serial.println(req); client.println("Vous avez bien été connecté \r"); // On analyse cette requête et on allume ou éteint une couleur de led en fonction if (req == "on1") { digitalWrite(2, HIGH); } else if (req == "off1") { digitalWrite(2, LOW); } else if (req == "on2") { digitalWrite(4, HIGH); } else if(req == "off2") { digitalWrite(4, LOW); } else { client.println("requête invalide"); digitalWrite(5,HIGH); delay(300); digitalWrite(5,LOW); }
client.stop(); } ``` On voit ici que le serveur attends des chaînes de caractères de type “on1” ou “off1”, “on2” ou “off2”. C'est donc cette syntaxe que nous enverrons avec le client.
Il va sans dire que si nous voulons allumer les différentes couleurs de la LED RVB, nous aurons, dans le setup, déclaré nos pin et éteint toutes les LEDs.
``` LED RVB pinMode(2, OUTPUT); bleu pinMode(4, OUTPUT); rouge pinMode(5, OUTPUT); vert digitalWrite(2, LOW); digitalWrite(4, LOW); digitalWrite(5, LOW); ``` #2-Les clients
Nous décidons d'envoyer nos infos à l'aide d'un bouton. Rien d'exotique, si ce n'est que nous allons analyser les changements d'états du bouton pour ne pas envoyer l'info en permanence. On aura donc besoin, avant la fonction setup(), de déclarer:
``` boolean button = HIGH; boolean lastbutton = HIGH; int pin = 0; ``` Mais surtout nous allons avoir besoin de définir l'adresse IP du serveur que nous voulons toucher, et un objet Client, qui sera l'émetteur du message.
``` IPAddress server(192, 168, 0, 2); WiFiClient client ; ``` Vous noterez les virgules pour séparer les quatre entiers de l'adresse IP (pas de points).
Dans le setup, on se connecte au réseau wifi comme précédemment, et on connecte le bouton:
`pinMode(0, INPUT_PULLUP);`
INPUT_PULLUP permet de s'affranchir de la résistance pour brancher le bouton en activant une résistance interne au microcontrôleur, très pratique.
Voici maintenant à quoi va ressembler notre boucle loop(), les commentaires vont décortiquer les différentes étapes, mais le principal réside dans :
La connexion au serveur: `client.connect(server, 80);`
L'envoi de la chaîne de caractère: `client.println(“off1\r”);`
``` void loop() {
// lecture de l'état actuel du bouton button = digitalRead(pin); // Si son état a changé if (button != lastbutton) { // le client se connecte au serveur... client.connect(server, 80); if (button == HIGH) { // ... et lui envoie la chaîne de caractère nécessaire client.println("off1\r"); Serial.println("off1"); } else { client.println("on1\r"); Serial.println("on1"); } // on met à jour le dernier état du bouton pour détecter le prochain changement. lastbutton = button; } delay(20); client.flush();
} ```
3-Fichiers d'exemple, le client et le serveur