====== ESP-Serveur web ====== * Porteur du projet : reso-nance Laurent * Date : 05/02/2020 * Licence : libre ! * Contexte : INIT' * Lien : [[https://github.com/reso-nance/INITs | repo github]] {{ :ateliers:esp-serveur-web:dsc00202.jpg?direct&400 |}} ===== Préparation ===== ==== installation de l'IDE ==== * Télécharger et installer l'[[https://www.arduino.cc/fr/Main/Software | IDE d'arduino]] * Activer l'affichage des numéros de lignes (fichier -> préférences) ==== bibliothèques ESP8266 ==== L'ESP8266 n'est pas un arduino comme les autre : il n'utilise pas de processeur atmel. Il est donc nécessaire de télécharger les bibliothèques ESP pour pouvoir l'utiliser avec l'IDE d'arduino. * Dans //fichier -> préférences -> URL de gestionnaire de carte supplémentaire// ajouter le lien suivant : %%http://arduino.esp8266.com/stable/package_esp8266com_index.json%% * Dans //outils -> type de carte -> gestionnaire de carte// attendre qu'il se mette à jour puis rechercher //ESP// en haut à droite et installer //esp8266 by ESP8266 Community// * redémarrer Arduino Dans //outils -> type de carte// de nouveaux modèles de cartes à base d'ESP8266 sont maintenant disponible. Pour le Lolin D1 mini utilisé dans cet INIT, choisir //LOLIN(WEMOS) D1 R2 & mini// Vérifier que l'ensemble de la chaîne fonctionne en ouvrant l'exemple **Blink** qui fait clignoter la LED intégrée : //fichier -> exemples -> 01.Basics -> Blink// puis cliquer sur la petite flèche **->** pour téléverser. ===== Servir une page web ===== ==== en pratique ==== Ouvrir l'exemple **HelloServer** dans //fichier -> exemples -> ESP8266WebServer -> HelloServer// Cet exemple contient tout le code nécessaire pour se connecter à un réseau WIFI, servir une page sommaire et afficher un GIF à l'arrière plan aléatoire. Pour qu'il puisse se connecter au réseau wifi, modifier les lignes 7 et 8 en remplaçant //your-ssid// par le nom du réseau wifi auquel vous êtes connectés et //your-password// par son mot de passe. Les deux sont sensibles à la casse. Téléverser ensuite le programme et ouvrir le moniteur série. Une fois l'ESP8266 connecté, il y affiche son adresse IP. {{ :ateliers:esp-serveur-web:ip.png?direct&400 |}} Dans un navigateur web, taper cette même adresse (ici **%%http://10.0.120.43%%**) et vous devriez voir s'afficher une page contenant le texte //hello from esp8266!//. L'adresse **%%http://10.0.120.43/gif%%** affichera un tout petit GIF représentant un smiley. Si l'exemple HelloServer venait à disparaître, une copie est disponible sur [[ https://github.com/reso-nance/INITs/tree/master/ESP8266-ServeurWeb/HelloServer | le git de cet INIT ]] {{ :ateliers:esp-serveur-web:helloserver.png?direct&400 |}} ==== comment ça marche ? ==== On peut voir dans le code qu'à chaque adresse définie dans le //setup// correspond une fonction : server.on("/", handleRoot); exécutera la fonction //handleRoot// lorsqu'un tentera de se connecter à l'adresse//%%/%%// qui correspond à la racine du serveur : c'est ce qu'on appelle une **route**. Les routes doivent toutes être déclarées dans le //setup// et ne peuvent être ajoutées dynamiquement. Les fonctions appelées par les routes contiennent toutes un server.send(CODE, MIME, VALEUR) permettant au serveur de répondre. En effet, lorsqu'on tente d'accéder à une page web notre navigateur envoie une //requête GET// au serveur qui lui réponds en lui renvoyant la page html désirée. Dans ce cas, le CODE de la réponse est //200 (success)//, le type MIME des données sera //text/html// et sa VALEUR contiendra tout le code HTML nécessaire pour afficher la page. En l'absence de réponse au bout d'un certain temps, le navigateur considérera que le serveur est hors ligne et affichera une page d'erreur. Le type MIME permet au navigateur de savoir comment interpréter les données reçues (est-ce un texte, une vidéo, du code javascript ?) Pour info, voici la liste des [[https://fr.wikipedia.org/wiki/Liste_des_codes_HTTP | codes HTTP]] et celle des [[https://fr.wikipedia.org/wiki/Type_de_m%C3%A9dias | types MIME]] existants. ===== contrôler une LED ===== On cherche à présent à allumer la LED intégrée à l'ESP8266 en se connectant à l'adresse **/on** puis à l'éteindre en visitant **/off** Il nous suffit donc de créer deux fonctions, une pour l'allumer et une pour l'éteindre, que l'on insérera au début du code, avant le //setup// : void handleLedON() { digitalWrite(led, LOW); // allumage de la led embarquée sur l'ESP8266 server.send(200, "text/plain", "led allumee"); // le serveur doit toujours répondre quelque chose (ici requête 200=success) } void handleLedOFF() { digitalWrite(led, HIGH);// extinction de la led server.send(200, "text/plain", "led eteinte"); } Ces fonctions doivent être à présent attachées aux URL souhaitées, on ajoute donc deux routes dans le //setup// : server.on("/on", handleLedON); server.on("/off", handleLedOFF); et le tour est joué. [[https://github.com/reso-nance/INITs/tree/master/ESP8266-ServeurWeb/HelloServerLED | télécharger le code]] ===== lire un potentiomètre ===== ==== page statique ==== On a vu comment afficher du texte, il semble donc assez simple d'afficher la valeur d'un potentiomètre sur une page web : on crée une fonction qui lit le port analogique et renvoie la valeur du potentiomètre sous forme d'une chaîne de caractère : void handlePotentiometer() { unsigned int potValue = analogRead(A0); server.send(200, "text/plain", "valeur du potentiometre :" + String(potValue)); } puis on ajoute une route au //setup// : server.on("/pot", handlePotentiometer); et on visite la page **%%/pot%%** qui nous affiche la valeur du potentiomètre. En revanche, cette valeur n'est mise à jour que lorsque qu'on la demande à nouveau au serveur en rafraîchissant la page. Pour qu'elle soit régulièrement mise à jour, il faut que le navigateur la demande régulièrement. Pour ce faire, on aura besoin d'un code javascript que le navigateur exécutera. Ce code javascript peut être directement écrit sous forme d'une chaîne de caractères dans le sketch arduino, mais il est plus commode de le stocker dans un fichier séparé. Mais comment téléverser un fichier sur l'ESP8266 ? [[https://github.com/reso-nance/INITs/tree/master/ESP8266-ServeurWeb/HelloServerPOT | télécharger ce code]] ==== page dynamique ==== === le SPIFFS === Le **SPIFFS** ou //SPI FileSystem// est un moyen de stocker des fichiers et dossiers sur l'ESP8266 et de les téléverser depuis l'IDE d'arduino. Il nécessite un plugin dont l'installation est détaillée sur la page wiki d'un [[projets:serveurwebsurbatterie:accueil| précédent projet ]] Une fois le plugin installé, créer un dossier **data** dans le dossier du sketch arduino qui contiendra tous les fichier à téléverser. === HTML === Le code javascript peut être intégré à une page HTML qui permet d'afficher la valeur du potentiomètre. Dans le dossier data, créer un fichier texte qui contiendra le code suivant : potentiomètre

valeur du potentiomètre :

et le renommer en //index.html// On peut à présent afficher la page sur son navigateur en double cliquant dessus. === servir la page === Pour accéder à cette page depuis l'ESP8266, il nous faut toujours une fonction et une route associée. On commence par importer la librairie qui accède au SPIFFS en haut du sketch et on ajoute //SPIFFS.begin()// en fin de setup pour l'initialiser. #include ... void setup() { ... SPIFFS.begin() } La fonction qui sera appelée lorsqu'on visite la page **/pot** est cette fois un peu différente puisqu'elle va lire le contenu du fichier depuis le SPIFFS et l'envoyer directement depuis le serveur en //streaming// : void handleHTMLpage() { File file = SPIFFS.open("/index.html", "r"); size_t sent = server.streamFile(file, "text/html"); } Comme d'habitude, on ajoute une route vers cette fonction dans le //setup// : server.on("/html",handleHTMLpage); puis on téléverse le code, sans oublier d'envoyer au préalable le fichier contenu dans le dossier data : **outils -> ESP8266 Sketch Data Upload** La page /html affiche à présent notre page html depuis l'ESP8266 === le javascript === Pour mettre à jour la valeur du potentiomètre sans recharger la page, il nous faut envoyer régulièrement une requête au serveur et en récupérer la réponse. Pour ce faire, on utilisera la fonction **fetch** qui sera répétée toutes les 500ms par le navigateur grâce à la fonction **setInterval**. Enfin, on affiche la valeur en replaçant le texte du %%%% vide par la réponse du serveur : setInterval(function(){ // tout ce qui se trouve ici sera répété indéfiniment fetch("/pot") // on envoie une requête GET au serveur .then(response => response.text()) // on récupère le texte de la réponse .then((response) => { document.getElementById("potValue").textContent = response // on remplace le texte de l'élément dont l'id est potValue par celui de la réponse }) .catch(err => console.log(err)) // si une erreur se produit, on l'affiche dans la console }, 500) // à répéter toutes les 500 millisecondes (2x par seconde) On peut maintenant insérer ce code javascript entre deux balises //%%%%// dans la page html et la téléverser sur l'ESP8266. Il ne nous reste plus qu'à modifier la fonction //handlePotentiometer// pour qu'elle ne renvoie plus que la valeur sans aucun texte autour : void handlePotentiometer() { unsigned int potValue = analogRead(A0); server.send(200, "text/plain", String(potValue)); } La page **%%/html%%** est maintenant mise à jour automatiquement deux fois par secondes. Il est possible d'augmenter le taux de rafraîchissement selon la qualité du wifi. [[https://github.com/reso-nance/INITs/tree/master/ESP8266-ServeurWeb/HelloServerPOT_HTML|télécharger ce code]]