Accueil | ESP8266 - ESP32 | ESP8266 : comprendre la programmation Web Server (code Arduino)

ESP8266 : comprendre la programmation Web Server (code Arduino)

L’ESP8266 peut se programme comme un Arduino classique mais son principal intérêt reste sa connexion Wi-Fi qui lui permet de publier des données sur un serveur ou un Dashboard en ligne (ThingSpeak, Freeboard.io), ou de créer facilement des objets connectés que l’on pourra piloter depuis un serveur domotique ou une application mobile (développée avec Blink ou Cayenne par exemple). Dans ce tutoriel, nous allons apprendre comment programmer l’ESP8266 pour qu’il se comporte comme un serveur web. C’est à dire qu’on pourra interagir avec le programme, le GPIO… depuis une interface web accessible depuis un navigateur internet.

Installer les cartes et librairies nécessaires

Avant de commencer, il est nécessaire de vérifier que toutes les librairies nécessaires sont installées.

IDE Arduino 1.6.8 esp8266 package

Vous pouvez regarder (par curiosité) les cartes gérées par la librairie ESP8266 et collant l’URL précédente dans un navigateur. En janvier 2017 (version 2.3.0), les cartes suivantes sont gérées :

  • Generic ESP8266 Module
  • Olimex MOD-WIFI-ESP8266(-DEV)
  • NodeMCU 0.9 (ESP-12 Module)
  • NodeMCU 1.0 (ESP-12E Module)
  • Adafruit HUZZAH ESP8266 (ESP-12)
  • ESPresso Lite 1.0
  • ESPresso Lite 2.0
  • Phoenix 1.0
  • Phoenix 2.0
  • SparkFun Thing
  • SweetPea ESP-210
  • WeMos D1
  • WeMos D1 mini
  • ESPino (ESP-12 Module)
  • ESPino (WROOM-02 Module)
  • WifInfo
  • ESPDuino

Allez dans le gestionnaire de carte et cherchez esp8266, puis cliquez sur installer.

IDE Arduino 1.6.x ajouter carte esp8266

En même temps que les cartes, toutes les librairies nécessaires ainsi que de nombreux exemples sont installés. Si les exemples ne sont pas visibles dans le menu Fichier -> Exemples -> Exemples for WeMos D1, quittez et relancez l’IDE Arduino.

Un programme simple pour commencer

Nous allons avancer par étapes pour comprendre comment créer un serveur web sur un ESP8266. Ouvrez l’exemple WiFiWebServer.

On a besoin au minium de la librairie ESP8266WiFi.h pour créer un serveur Web. Comme toutes les librairies, il faut pas mal fouiller pour connaître les méthodes disponibles, voici un petit aperçu pour mieux appréhender ce qu’on peut faire avec. le code source de la librairie est disponible ici. Cette librairie est une adaptation de l’ensemble des librairie développées pour l’Arduino. Vous pourrez également trouver pas mal d’infos ici

  • WiFiClient
    • uint8_t status()
    • int connect(IPAddress ip, uint16_t port)
    • int connect(const char *host, uint16_t port)
    • size_t write(uint8_t)
    • size_t write(const uint8_t *buf, size_t size)
    • size_t write_P(PGM_P buf, size_t size)
    • size_t write(Stream& stream)
    • int available()
    • read(uint8_t *buf, size_t size)
    • int peek()
    • size_t peekBytes(uint8_t *buffer, size_t length)
    • size_t peekBytes(char *buffer, size_t length)
    • void flush()
    • void stop()
    • uint8_t connected()
    • IPAddress remoteIP()
    • uint16_t remotePort()
    • IPAddress localIP()
    • uint16_t localPort()
    • bool getNoDelay()
    • void setNoDelay(bool nodelay)
    • void setLocalPortStart(uint16_t port)
    • static void stopAll();
    • static void stopAllExcept(WiFiClient * c)
  • WiFiServer
    • WiFiServer(IPAddress addr, uint16_t port)
    • WiFiServer(uint16_t port)
    • WiFiClient available(uint8_t* status = NULL)
    • bool hasClient()
    • void begin()
    • void setNoDelay(bool nodelay)
    • bool getNoDelay()
    • virtual size_t write(uint8_t)
    • uint8_t status()
    • void close()
    • void stop()
  • WiFiUDP
  • WiFiClientSecure

On créé une instance, un objet qui contiendra le serveur web. On communiquera avec lui sur le port 80, le port classique des requêtes HTTP utilisées par les navigateurs internet.

La boucle setup.

Que se passe-t-il dans la boucle loop ?

On fait quelque chose uniquement si un client est connecté, c’est à dire qu’on réalise une requête HTTP sur l’ESP8266 depuis un navigateur internet

Lorsqu’un client se connecte, on l’indique sur le port série

On récupère la requête HTTP, ici l’URL saisie dans le navigateur tout simplement. On envoi sur le port série le contenu de la requête HTTP. On vide le tampon avec la méthode flush.

On recherche dans la requête HTTP ce que l’on doit faire. La méthode la plus simple est de passer les ordres à l’ESP8266 sous la forme d’une commande du type /gpio/etat_souhaite (0, 1 ou on/off). On ferra juste un test sur  une chaîne de caractères avec la commande indexOf sur la variable req. Ce type de stratégie convient pour de petits projets mais ça risque rapidement de devenir une source d’erreur avec l’empilage des if, else if.

On met à jour l’état du GPIO et on vide le tampon

On créé maintenant un page HTML qui contient l’état du GPIO. C’est une chaine texte qui contient le code HTML de la page. On intercale dans le code de la page, l’état du GPIO

On publie cette page au client avec la commande print, très facile !

Voilà, vous pouvez maintenant piloter à distance tout matériel relié au GPIO (un relai, une led, un moteur, un servomoteur….) à laide d’une simple requête HTTP. Vous pouvez par exemple très simplement exécuter une commande depuis un logiciel domotique. Voici deux exemples, le premier pour Domoticz, le second pour Jeedom.

Ajouter un interface graphique HTML à vos projets

Maintenant, vous voudriez certainement pouvoir réaliser une petite interface pour vos projets ESP8266. Pour cela, nous avons besoin de connaître quelques rudiments d’HTML. Nous n’allons pas aller très loin dans l’apprentissage de l’HTML, juste apprendre les éléments importants pour démarrer et avoir un projet fonctionnel. Si vous avez besoin de plus d’éléments d’interface, je vous conseille w3schools qui est une référence dans l’apprentissage de l’HTML. Le site est en anglais mais il est très clair et très simple d’accès.

Dans un projet ESP8266, on peut créer des pages HTML en dynamique, c’est à dire qu’on construit une chaine texte qui contient le code de la page qu’on va ensuite afficher. C’est ce que nous allons faire. Mais l’ESP8266 est capable également de fonctionner comme un vrai site internet, c’est à dire qu’on peut installer sur la mémoire flash les pages HTML, du code javascript, les feuilles de style CSS… Nous n’irons pas jusque là dans ce premier tutoriel.

Je vous propose de créer une petite station météo pour avoir des données à actualiser régulièrement et créer un bouton pour activer / désactiver une sortie GPIO (juste une Led, pour l’exemple. J’ai utilisé le matériel suivant

esp8266 Wemos D1 miniModule ESP8266 ESP-12 ou Wemos D1 Mini
BMP180Capteur de pression atmosphérique

BMP180

Broches DHT22Capteur de température et d’humidité

DHT11 ou DHT22

jumper dupontJumper Dupont
breadboardBreadboard

Câblage

Voici un tableau de repérage et de correspondance des broches entre Arduino et ESP8266.

ComposantBrochesEquivalence ESP8266 (Wemos D1 mini)
DHT22VCC5V
GNDG
DataG5
BMP180VCC5V
GNDG
SDAD2

On commence par déclarer les librairies nécessaires. N’oubliez pas d’installer les librairies depuis le gestionnaire de bibliothèques (DHT et BMP085).

Remarque. Vous risquez de rencontrez une erreur à la compilation adafruit_Sensor.h : No such file or directory. Dans ce cas téléchargez et décompressez la librairie manuellement depuis GitHub dans le dossier Arduino -> Librairie, puis relancez l’IDE pour quelle soit prise en compte.

On définit les variables du programme. Modifiez le réseau WiFi sur lequel vous allez vous connecter et le mot de passe de ce dernier.

On créé les objets dht, bmp et server

Cette première fonction permet de construire le code HTML de la page principale du programme. C’est une simple chaine de caractère. C’est un assemblage de chaînes. On peut facilement y inclure la valeur ou l’état d’une variable (par exemple l’état d’une sortie). En retour, la fonction renvoie une chaine contenant le code HTML de la page.

Voyons un peu mieux comment est construit le code

Code HTMLExplication
<html lang=fr-FR>

<head>

<meta http-equiv=’refresh’ content=’10’/>

<title>ESP8266 Demo – www.projetsdiy.fr</title>

<style> body { background-color: #fffff; font-family: Arial, Helvetica, Sans-Serif; Color: #000088; }</style>

</head>

lang : permet de définir la langue de la page

head : c’est l’entête de la page. Il contient différentes meta (paramètres)

  • http-equiv=’refresh’ : c’est une page que le navigateur devra rafraichir. Pour plus de types, allez ici
  • content=’10’ : toutes les 10 secondes

title : le titre de la page affiché dans la barre du navigateur

style : un style pour la page (couleur de fond, font à utiliser, couleur du texte

<body>C’est le contenu de la page affiché
<h1>ESP8266 Demo</h1>Un titre affiché en haut de la page
<h3>DHT22</h3>Un titre (h3, plus petit) pour le capteur DHT22
<ul>

<li>Température : xx°C</li>

<li>Humidité : xx%</li>

</ul>

Le bloc ul permet d’afficher sous forme de liste les informations. La même chose pour le BMP180
<form action=’/’ method=’POST’>

<ul>

<li>D3 (etat: xx)

<INPUT type=’radio’ name=’LED’ value=’1′>ON

<INPUT type=’radio’ name=’LED’ value=’0′>OFF

</li>

</ul>

<INPUT type=’submit’ value=’Actualiser’>

</form>

Pour actualiser le GPIO, on utilise un formulaire.

On utilise ici un bouton radio pour changer l’état (On/Off) puis on envoi (submit) le contenu du formulaire avec un bouton.

L’option name permet de nommer la variable qui contiendra l’état que l’on souhaite récupérer dans le code Arduino. Ici LED.

</body>Toute balise ouverte doit être refermée (c’est mieux !)

La fonction handleRoot permet de surveiller si on reçoit un demande d’actualisation du GPIO en surveillant si l’argument LED est renvoyé par la page. Si c’est le cas, on exécute la fonction handleSubmit. A nous de créer

La fonction handleSubmit traite l’actualisation du GPIO. On récupère l’état de la variable LED. Attention, c’est une chaine de caractère, on doit donc tester “1” et non pas 1. On en profite pour affecter l’état du GPIO dans la variable etatLed sous la forme d’une chaine, c’est plus sympa à lire. Enfin on actualise l’affichage de la page HTML avec server.send. On récupère la page actualisée en appelant la fonction getPage().

Maintenant que toutes les fonctions sont créées, on peut appeler la fonction setup(). Elle initialise le BMP180, la connexion WiFi, branche la fonction qui s’occupe de la page principale et enfin on lance le serveur web

Il ne reste plus qu’à exécuter la fonction loop() pour relever régulièrement les mesures sur les capteurs. Contrairement à l’exemple précédent basé sur la librairie ESP8266WiFi, ici la librairie ESP8266WebServer nécessite de brancher la fonction callback server.handleClient() qui surveille la présence d’un client et délivre la page HTML demandée.

Voici le code source assemblé du projet qu’il vous suffit de coller dans un nouveau projet puis le téléverser

Récupérez l’adresse IP de la Wemos en ouvrant le moniteur série puis connectez vous à celle-ci depuis un navigateur internet pour accéder à l’interface de la mini station météo.

 esp8266 wemos d1 mini serveur server web dht22 bmp180 gpio

Voilà, nous savons maintenant comment créer un serveur web à l’aide d’un ESP8266, piloter le GPIO et afficher des mesures en provenance de capteurs. Nous n’avons vu ici que les principaux rudiment pour débuter mais il couvrent déjà une grande partie de ce que l’on a besoin pour développer de petits objets connectés. Dans le prochain tutoriel, nous verrons comment avoir une plus belle interface graphique en utilisant Bootstrap, un framework développé par un développeur travaillant chez Tweeter qui permet de créer de plus belles interfaces graphiques en HTML.

Remarque. Tout le tutoriel a été développé sur l’IDE Arduino 1.8.1 installé sur un Orange Pi Plus 2e (présenté ici) fonctionnant sous Armbian (Ubuntu 16.04 LTS). Suivez ce tutoriel pour savoir comment installer l’IDE Arduino sur Linux (ARM ou x86).

  • visvic

    Hello,

    Bravo !! très bon tuto expliquer très clairement. Petite faute au W3scholls ^^

    Je te suis depuis un bon moment et je n’utilise pratiquement que tes tutos 😉

    A + tard 😀

    • Bonjour Visvic. Merci beaucoup, je suis très content si les tutos proposés conviennent à tes projets :D. La suite arrive avec Bootstrap. Merci pour la typo. A très bientôt.

  • Youcef Bouchekioua

    Salut,

    Merci beaucoup pour ce tuto.

    J aimerais savoir comment recevoir des donnees provenant d un accelerometre assez rapidement via wifi, d une carte Wemos (esp8266) vers un server Node.js (en utilisant express.js).

    Merci !

    • Bonjour Youcef, merci beaucoup. C’est un vrai projet ! Pas facile d’y répondre dans un commentaire. Voici quelques pistes :
      – En fonction de votre niveau en programmation, il y a des librairies plus accessibles que d’autres. Pour moi, la plus accessible est celle d’Adafruit pour le LSM9DS0 http://s.click.aliexpress.com/e/rje2NRF, et le tutoriel https://learn.adafruit.com/adafruit-lsm9ds0-accelerometer-gyro-magnetometer-9-dof-breakouts?view=all. Ensuite, il y a les MPU de Invensense qui sont beaucoup moins chers (environ 5€ http://s.click.aliexpress.com/e/AyJ23vr), mais les librairies sont plus difficiles à utiliser.
      – Pour communiquer en WiFi depuis un ESP8266 sous Node.js, j’ai serait tenter de dire que le plus facile d’utiliser Johnny-five. C’est une librairie javascript qui va parfaitement d’intégrer dans un projet express.js. Il faudra installer un firmware sur la Wemos qui va la transformer en passerelle série (via une liaison UDP), par exemple celui ci https://gist.github.com/ajfisher/5fe60fe7d8c49b3223f0. Ensuite pour récupérer (en temps réel ?) les mesures de l’accélèromètre, Johnny-Five propose une API complète (http://johnny-five.io/api/accelerometer/) et très simple (pitch, roll, acceleration, inclination, orientation…). Il n’y a ABSOLUMENT rien à programmer sur la Wemos !
      J’ai débuté une série d’articles sur Johnny-Five, vous devriez trouver quelques pistes. Bon courage pour votre projet. A très bientôt.

      • Youcef Bouchekioua

        Merci beaucoup pour cette reponse claire et rapide.

        Bonne continuation et a bientot !