DOSSIER complet sur le ESP8266 WIFI / Nodemcu / La domotique et IoT pour tous

 

Découverte des ESP8266 : le microcontrôleur connecté par Wifi pour 2€ au potentiel phénoménal avec Constellation

Ce dossier a été initialement publié dans le magazine Programmez! n°190 en novembre 2015.

Programmez! n°190 - Novembre 2015 Article Programmez!

Arrivé à l’été 2014, l’ESP8266 est un microcontrôleur produit par la société chinoise Espressif intégrant un module Wifi.

Avec un prix avoisinant les 2€, il a très vite séduit les foules qui se sont empressées de créer une communauté dans laquelle on retrouve maintenant beaucoup de documentation, de bouts de codes, des firmwares et projets en tout genre.

Initialement cette puce était un « simple » module Wifi permettant à un microcontrôleur équipé d’une liaison série, tel un Arduino, de disposer d’une connectivité Wifi pour un prix dérisoire. Mais en Octobre 2014, Espressif publié un kit de développement (SDK) permettant de reprogrammer la puce supprimant ainsi la nécessité d’un microcontrôleur séparé. Comme nous allons le découvrir dans cet article, les possibilités sont immenses !

 

Les caractéristiques

Ce microcontrôleur est cadencé à 80Mhz par un processeur 32bits RISC avec 96K de RAM et une mémoire flash de 512Ko à 4Mo selon les modèles.

Il dispose d’une connectivité Wifi 802.11 b/g/n supportant le WEP, WPA/2/WPS et réseau ouvert et 16 GPIO dont le support du SPI, I²C, UART et un port ADC (pour les I/O analogiques).

Le module Wifi peut être également utilisé en tant que « soft-AP », c’est-à-dire configuré en tant que point d’accès Wifi.

Il est alimenté en 3,3V est consomme entre 60mA et 200mA avec le Wifi activé.

ESP8266

Il existe plusieurs modules d’ESP8266, les plus connus étant ceux produits par AI-Thinkers, les ESP-XX : l’ESP-01 (le plus répandu), l’ESP-02, 03, … jusqu’au 13 :

Différents modèles de l'ESP8266 par AI-Thinker

Gardez à l’esprit que tous ces modèles sont animés par le même contrôleur: l’ESP8266. Les différences sont principalement liées à la taille, au nombre de PIN « accessibles », à l’antenne (PCB, céramique ou socket RP-SMA), à la présence ou non d’un blindage électromagnétique ou encore à présence de LED.

Pour ma part je travaille essentiellement avec l’ESP-01 et l’ESP-07.

ESP8266 - ESP-01

L’ESP-01 à l’avantage d’avoir des pins sur un pas standard de 2,54mm très pratique pour le prototypage. Il dispose d’une antenne intégrée sur la carte pour une dimension totale de 1,4cm sur 2,4cm avec 8 PINs : Vcc/Gnd, Tx/Rx, Rst/Ch_Pd (activation du Wifi) et deux GPIO : GPIO0 et GPIO2. Notez toutefois que les PIN Tx/Rx peuvent être également utilisées comme des GPIO (respectivement GPIO1 et GPIO3).

L’ESP-07 quant à lui mesure 2cm x 1.6cm avec un blindage électromagnétique, une antenne céramique et un port RP-SMA pour y connecter une antenne externe et dispose de 16 PINs : Vcc/Gnd, Tx/Rx et Rst/Ch_Pd comme sur l’ESP-01 mais avec 10 GPIO disponibles dont un port ADC pour les entrées analogiques. L’inconvénient est que les PINs ne sont pas espacées avec un pas standard, il faudra directement souder sur les connections de la carte (moins pratique pour le prototypage) ou bien créer/acheter une plaque-adaptateur (adapter plate expansion).

ESP-07

A noter qu’il existe d’autre société créant des cartes animées par l’ESP8266 à l’image d’Olimex qui propose une carte de prototypage orientée « développement » pour 5€ avec 22 PINs exposant tout du microcontrôleur, la carte de SparkFun qui intègre un connecteur USB pour l’alimentation avec un régulateur 3,3V et un chargeur LiPo pour y connecter une batterie et sans oublier la ESP-WROOM-02 directement produite par Expressif.

Olimex ESP8266 DEV

Développer avec l’ESP

Avec la libération du SDK par Expressif fin d’année dernière est apparue plusieurs façons de développer avec l’ESP8266.

Flasher le firmware de l’ESP8266

Mais avant de démarrer nous allons aborder la façon de flasher le firmware de la puce pour la reprogrammer.

Pour la suite de l’article nous allons nous baser sur l’ESP-01, le plus simple pour prototyper.

Pinout sur l'ESP-01

Comme nous l’avons dit il dispose de 8 PINs : deux pour l’alimentation en 3,3V (Vcc et Gnd), deux pour la connexion série (Tx/Rx), un « RST » (reset) pour réinitialiser la puce en le connectant à la masse, le « CH_PD » (chip power-down) qui doit être alimenté en 3,3V pour activer le Wifi et enfin deux GPIO pour vos I/O.

Le GPIO0 a un double rôle : il sert également à entrer dans le « Flash mode ». Pour cela il faut le connecter à la masse. Ainsi l’ESP8266 ne démarrera pas son programme mais entrera dans le « UART download mode », c’est-à-dire qu’il écrira tout ce qu’il reçoit sur la liaison série dans sa mémoire. De ce fait, pour programmer la puce, il faut redémarrer l’ESP en « Flash mode » afin de pouvoir écrire un nouveau firmware.

Pour faciliter les opérations, je vous recommande de vous fabriquer une plaque de « programmation » : il s’agit de faire une carte avec un réceptacle dans lequel on pourra déposer notre ESP-01. Cette carte disposera de quelques headers pour y connecter l’interface FTDI/USB et deux boutons poussoirs pour respectivement faire un reset de la puce et l’autre pour démarrer en « Flash mode ». Cela vous évitera de vous perdre dans les câbles à chaque manipulation/programmation de l’ESP. Pour ma part j’ai également ajouté un connecteur DC pour y connecter une alimentation externe avec un régulateur LM1117 3,3V (me permettant d’utiliser une source d’alimentation jusque 15V).

Pour résumer, le schéma de notre carte de programmation :

FlashBoardRev2_thumb2

Cette carte disposera de :

  • 4x PINs pour y connecter l’interface FTDI/USB facilement (Vcc/Gnd/Rx/Rx)
  • 1x connecteur DC et 3x PINs (Vin, 3,3V et Gnd) pour alimentation + un régulateur LM1117 pour pouvoir utiliser une source d’alimentation externe de 5 à 15V
  • 2x PINs pour les GPIO 0 et 2
  • 1x bouton poussoir pour faire un reset de l’ESP sans avoir à débrancher le Vcc
  • 1x autre bouton poussoir pour entrer dans le “Flash mode” afin de charger le nouveau firmware de votre ESP

Pour la réalisation, découpez une plaque époxy et placez-y les différents composants :

Découpe de la plaque epoxy

Installation des composants

Il ne reste plus qu’à connecter le tout en suivant le schéma ci-dessus :

Soudures

Et voilà, il ne me reste plus qu’à connecter une alimentation (dans mon cas 5V) et mon interface FTDI (Gnd/Rx/Tx) connecté en USB sur mon PC puis de déposer un ESP-01 :

Carte de programmation pour ESP-01

Le Switch n°1 me permet d’alimenter l’ESP (On/Off) et le Switch n°2 me permet d’activer ou non le Wifi (CH_PD). Le bouton poussoir du milieu me permet de faire un reset de l’ESP quant au 2ème bouton poussoir, il me permet, d’entrer dans “Flash mode” (il suffit d’appuyer sur ce bouton et de faire un reset).

Ainsi il est devient très facile de jongler avec plusieurs ESP et développer avec.

Côté software, il existe plusieurs outils pour flasher un ESP. Personnellement j’utilise par habitude « ESP Flasher Tool » :

ESP Flash Download Tool

Il suffit de sélectionner les binaires en précisant à quelles adresses ils doivent être écrit sur la mémoire de votre ESP. L’outil garde en mémoire les fichiers et adresses, il suffit donc de cocher/décocher les fichiers que l’on souhaite flasher, très pratique pour switcher entre différents firmwares !

Par exemple pour tester le firmware « AT », je vais écrire l’image « boot_v1.2+.bin » à l’adresse 0x0000, « user1.1024.new.bin » à 0x10000 et « blank.bin » à 0x7e000.

L’adresse 0x0000 est l’adresse du boot loader (début de la mémoire), à partir de 0x1000 on retrouve le programme utilisateur (firmware) et les données utilisateurs. A la fin de la mémoire, à l’adresse 0x7c0000 on retrouve la configuration de la puce, là où est stoker la configuration Wifi notamment et à 0x7e0000 d’autre paramètres système.

Vous pouvez donc avec cet outil, et après avoir démarré votre ESP en « Flash mode », changer de firmware à souhait.

Le firmware original « AT »

Pour démarrer notre découverte des ESP, commençons par le firmware d’origine installé par Expressif.

L’idée ici est de se servir de l’ESP comme d’un simple module Wifi qu’on exploitera depuis un autre microcontrôleur comme un Arduino en liaison série. Une fois la communication série établie on dialogue avec l’ESP en utilisant des commandes Hayes, qu’on appelle aussi « commandes AT ».

Pour expérimenter ce firmware vous pouvez utiliser Putty pour vous connecter directement sur la puce ou Esplorer bien plus pratique.

Pour tester la connexion, envoyez la commande « AT » et vous devriez recevoir « OK » de la part de l’ESP pour vous indiquer que la connexion série est opérationnelle. La commande « AT+GMR » vous renverra les informations de version (ici le firmware AT 0.21 basé sur le SDK 0.9.5) :

OK AT+GMR AT version:0.21.0.0 SDK version:0.9.5 OK

Vous pouvez ensuite configurer le mode Wifi : Station (client Wifi), AP (Access Point) ou les deux. Pour être client Wifi, entrez la commande « AT+CWMODE=1 ».

Puis pour lister les réseaux Wifi, entrez « AT+CWLAP ». Vous obtiendrez en réponse la liste des AP avec le SSID, l’adresse MAC et le canal utilisé.

AT+CWMODE=1 OK AT+CWLAP +CWLAP:(4,"NUMERICABLE-7610",-80,"c0:d9:62:68:41:89",1) +CWLAP:(3,"CARRE_NOIR",-73,"a8:9d:21:be:56:b6",6) +CWLAP:(4,"Livebox-55c0",-85,"00:1d:6a:61:0b:ec",6) +CWLAP:(3,"ETO-WEB2",-87,"a8:9d:21:43:ce:14",11) OK

Pour se connecter, utilisez la commande « AT+CWJAP= »MYSSID », »MYPASSWD » ». Si la commande retourne « OK » c’est que vous êtes connecté. Vous pouvez ensuite utiliser la commande « AT+CIFSR » pour connaitre votre adresse IP.

Une fois connecté, vous pouvez utiliser les commandes « AT+CIPSTART » et « AT+CIPSEND » pour initialiser et envoyer des données dans une connexion TCP ou UDP.

De ce fait, il devient alors possible de connecter n’importe quel contrôleur équipé d’une liaison série.

ESP8266 comme module Wifi

 

Sur un Arduino, connectez votre ESP sur le port RX/TX (UART) de votre Arduino et alimenter l’ESP en 3,3V (sans oublier le CH_PD pour activer le Wifi).

Mais attention : l’ESP8266 fonctionne sur une tension de 3,3V alors que la plupart des Arduino sont en 5V. SI vous utiliser la sortie 3,3V de votre Arduino n’oubliez de mettre un condensateur car cette sortie est généralement limité à 50mA alors que l’ESP peut consommer jusqu’à 250mA. Privilégiez une d’alimentation externe avec un régulateur 3,3V (type LM1117). De plus la liaison série (Rx/Tx) doit être également convertie en 3,3V. Sachez que pour un prototype le port RX de l’ESP à une protection intégrée mais il est préférable de la protéger soit même avec des résistances ou diode. Pour le TX, le signal 3,3V de l’ESP ne sera pas bien reçu côté Arduino (qui attend du 5V). Je vous recommande donc d’utiliser un convertisseur de niveau (Logic Level Converter) pour connecter le Rx et Tx de votre Arduino à l’ESP.

Une fois la liaison série opérationnelle, il vous suffira d’échanger en envoyant les commandes AT.

Serial1.begin(115200); // Définir le mode Wifi "Station" Serial1.println("AT+CWMODE=1"); // Se connecter au SSID avec le password String cmd = "AT+CWJAP=\"" + SSID + "\",\"" + PASS + "\""; Serial1.println(cmd); delay(2000);   // On doit lire "OK" if (Serial1.find("OK")) { Serial.println("OK, WiFi Connected.");   delay(5000); // Afficher l'adresse IP Serial1.println("AT+CIFSR"); Serial.println("ip address:"); while (Serial1.available()) Serial.write(Serial1.read()); } else { Serial.println("Can not connect to WiFi."); }

Vous aurez compris le principe, libre à vous d’implémenter l’ensemble des commandes AT pour pouvoir connecter tout type de microcontrôleur en exploitant une liaison série.

Développer son propre firmware avec le SDK Expressif

Jusqu’au mois d’Octobre 2014 le firmware AT était la seule méthode d’exploiter les ESP8266. Mais à partir de cette date la société Expressif a ouvert le SDK nous permettant de développer nos propres firmwares. Par ailleurs le code du firmware AT a été ouvert en guise d’exemple. Vous pouvez retrouver le code source de ce firmware sur le compte Github d’Expressif.

Pour développer nativement je vous pouvez utiliser Eclipse ou Visual Studio. Personnellement j’utilise ce dernier configuré correctement avec le bon « tool chain » (MinGW, Extensa, PySerial pour flasher le firmware).

Il existe aussi des produits tels que VisualGDB, un plugin Visual Studio permettant de développer des firmwares pour plateformes embarquées, modules du kernel Linux, etc… en bénéficiant de toute la puissance de Visual Studio pour l’édition de code, le débogage et le déploiement. Et à ce titre, il permet de créer très facilement des projets pour ESP8266.

VisualGDB

Il est alors possible de déployer et déboguer son code en temps réel en mettant des points d’arrêt, analysant le contenu de vos variables Il est même possible d’explorer le contenu de la mémoire RAM.

Il faut savoir qu’il existe actuellement 3 SDK pour développer nativement sur les ESP8266: l’ « ESP IoT SDK », l’ « ESP IoT RTOS SDK » et l’ « ESP Open RTOS ».

Le premier est fourni par Expressif et est le plus utilisé. C’est le SDK « principal » qui ne repose pas sur un OS, on l’appelle le « non-OS SDK ». Il est mono-thread bien que vous pouvez utiliser un timer pour orchestrer des « taches » (sans que celle-ci occupe trop le CPU sous peine d’avoir un reset). En parallèle, Expressif maintient sur Github un deuxième SDK, celui-ci basé sur FreeRTOS, un OS temps réel permettant de bénéfice de véritables threads.

Enfin le dernier est un projet alternatif open-source, non supporté par Expressif, visant à créer un framework ouvert pour l’ESP8266 en se basant également sur FreeRTOS.

C’est grâce à la libération de ce SDK qu’il est désormais possible de créer soit un « software » permettant d’exploiter toute la puissance du microcontrôleur 80Mhz en toute autonomie ou soit un « middleware » qui nous permettra par exemple de développer des applications autonomes dans un autre langage avec un framework de plus haut niveau !

Developper en Lua avec NodeMCU

Développer des applications natives sur ESP est assez compliqué pour celui qui ne connait pas le développement bas niveau !

 nodemcu-style5-150px.png_150x150

NodeMCU a eu l’idée de créer un firmware ESP8266 embarquant eLua, un interpréteur Lua très minimaliste pour système embarqué. Grace à ce firmware vous pouvez développer des programmes pour votre ESP très facilement en Lua.

Concrètement il faut commencer par flasher votre ESP avec le firmware NodeMCU en utilisant un outil comme ESP Flash Download présenté ci-dessus. Vous pouvez télécharger le binaire du firmware directement sur le GitHub de NodeMCU. La dernière release en date est la « 20150704 » du 04 juillet basée sur le SDK IoT 0.9.6 d’Expressif (c’est une vieille version !!).

Vous trouverez également le lien vers le site de frightanic.com qui permet de compiler son firmware à la demande en personnalisant différentes options (branche à compiler, modules à inclure, support ou non du SSL, activation du mode debug, etc..).

Update Juillet 2016 :

  • la dernière version à ce jour est la “20160603” du 3 Juin 2016 basée sur le SDK IoT 1.5.1 d’Expressif.
  • le site de build “custom” est http://nodemcu-build.com/

Une fois installé utilisez l’outil Esplorer, une application Java (compatible Linux/Windows et Mac OS) qui permet d’éditer et uploader des fichiers Lua dans le file system de votre ESP.

NodeMCU via Esplorer

A gauche vous retrouverez l’éditeur, à droite la sortie de votre ESP. Chaque fichier est enregistré dans le file system de votre ESP avant d’être exécuté.

Par exemple pour se connecter au Wifi de la maison :

print("Démarrage") wifi.setmode(wifi.STATION) print("set mode=STATION (mode="..wifi.getmode()..")") wifi.sta.config("MON RESEAU WIFI", "Ma clé Wifi")   tmr.alarm(0, 1000, 1, function() if wifi.sta.getip() == nil then print("Connecting to AP...") else print("Connected! IP: ",wifi.sta.getip()) tmr.stop(0) end)

On commence par définir le mode Wifi à Station (client) puis on se connecte en spécifiant le SSID et la clé Wifi. Ensuite on lance une tache qu’on exécute sur le timer « 0 » (vous pouvez aller de 0 à 6), à une seconde d’intervalle (1000ms) de façon répétitive afin de récupérer l’IP. Si la connexion n’est pas encore effective on affiche le message « Connecting » sinon on coupe le timer « 0 » et on affiche l’adresse IP de votre ESP.

Avec NodeMCU la gestion des connexions est basée sur des évènements. On va donc créer un socket puis s’abonner à l’évènement « connected » pour envoyer une requête http et sur l’évènement « receive » on affichera sur la sortie standard la réponse du serveur :

local sk = net.createConnection(net.TCP, 0) sk:on("disconnection", function(sck, c) print("Disconnected") end) sk:on("receive", function(sck, c) print("Receiving answer : " .. c) sck:close() end) sk:on("connection", function(sck, c) print("Connected") sck:send("GET / HTTP/1.1\r\n" sck:send("Host: " .. address .. "\r\n) sck:send(Connection: keep-alive\r\nAccept: */*\r\n\r\n") end) sk:connect(port, address) sk = nil

On peut bien sûr lire et écriture sur nos GPIO à la manière d’un Arduino :

gpio.mode(pin,gpio.OUTPUT) gpio.write(pin,gpio.HIGH) print(gpio.read(pin))

NodeMCU met à disposition plusieurs modules tel quel : i2c, pwm, spi, adc (pour les I/O analogiques), uart, donc de quoi s’interfacer avec tout type d’équipement.

Bien que NodeMCU soit une alternative très intéressante pour développer très rapidement sur ESP8266, la plateforme souffre de gros problème de mémoire. Chaque fonction créée occupe une place important dans la pile et dès que vous avez un projet un peu plus compliqué qu’une simple acquisition d’un capteur pour envoyer une requête http, ça devient critique. Il n’est pas rare d’avoir des plantages avec le message « Not enough memory ».

Je vous conseille d’ailleurs de compiler vos scripts Lua pour générer un fichier LC, vous gagnerez quelques ko de mémoire, privilégiez les variables locales, réduisez au maximum le nombre de fonction et de surveiller fréquemment la taille de la pile en invoquant la méthode « node.heap() ».

De ce fait, NodeMCU reste un détour incontournable dans la découverte de l’ESP8266, mais pour des créer des projets plus fiables, je vous conseille vivement de développer des sketches Arduino qui offre un bon compromis entre la fiabilité et performance du développement natif en C++ et la simplicité de NodeMCU.

Update Juillet 2016 : les dernières versions de NodeMCU (> 0.9.6) semblent beaucoup plus stables que ce que j’ai pu testé l’an passé !

Développez sur vos ESP8266 comme un Arduino

Le principe est très simple, avec l’IDE Arduino on ajoute simplement la board « ESP8266 » dans le « Additional Board Manager ».

ESP8266 dans l'Arduino IDE

Ensuite vous pouvez écrire votre sketche Arduino comme à votre habitude.

Par exemple pour se connecter à notre réseau Wifi :

#include <ESP8266WiFi.h>   void setup() { Serial.begin(115200);   WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); }   Serial.print("Connected ! IP address: "); Serial.println(WiFi.localIP()); }

Une fois connecté, exécutons une requête http avec affichage de la réponse sur l’interface série :

WiFiClient client; if (!client.connect(host, httpPort)) { Serial.println("connection failed"); return; } client.print(String("GET / HTTP/1.1\r\n" + "Host: " + host + "\r\n" + "Connection: close\r\n\r\n")); delay(10); while(client.available()) { String line = client.readStringUntil('\r'); Serial.print(line); }

Lors du télé-versement il faut penser à mettre votre ESP8266 en « Flash board » car votre sketche est compilé comme un véritable firmware autonome (sans middleware à la NodeMCU).

Comme un véritable Arduino vous pouvez accéder aux GPIO avec les classiques digitalRead/ digitalWrite. Pour les entrées analogiques (analogRead sur A0) il faudra obligatoirement la connecter sur le port ADC.

Vous pouvez également utiliser l’espace de stockage Flash de votre ESP grâce aux objets SPIFFS, Dir et File. Aussi il est possible d’utiliser les fonctions du SDK native depuis vos sketches Arduino.

On peut donc utiliser les nombreuses librairies Arduino que l’on retrouve sur Internet mais attention car certaines librairies ne sont pas compatibles si trop dépend du hardware. Par exemple certaines librairies Arduino utilisent l’ISR (Interrupt Service Routine) défini dans les librairies AVR spécifique aux ATmega. Or sur un ESP8266, les librairies de l’AVR ne sont pas compatibles.

Par exemple, la librairie Arduino « IRremote » permettant l’envoi et réception de signaux infrarouge ne compilera pas sur l’ESP8266. J’ai donc réécris le code de la librairie pour le rendre compatible avec l’ESP (vous retrouverez ce code sur mon Github).

Pour ce faire j’ai remplacé l’ISR de l’AVR par le système interruption propre au SDK de l’ESP8266. Pour inclure les headers souhaités du SDK de l’ESP8266 depuis dans votre librairie Arduino  :

extern "C" { #include "user_interface.h" #include "gpio.h" }

Puis je m’attache aux changements d’état de la GPIO :

 ETS_GPIO_INTR_DISABLE(); ETS_GPIO_INTR_ATTACH(gpio_intr, NULL); gpio_pin_intr_state_set(GPIO_ID_PIN(recvpin), GPIO_PIN_INTR_ANYEDGE); ETS_GPIO_INTR_ENABLE();

Ce qui me permet dans une fonction de callback, ici nommée « gpio_intr » de récupérer son état :

static void ICACHE_FLASH_ATTR gpio_intr(void *arg) { uint32_t gpio_status = GPIO_REG_READ(GPIO_STATUS_ADDRESS); GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, gpio_status); // ... }

Ainsi, grâce à l’accès aux fonctionnalités natives du SDK officiel d’Expressif, il est possible de porter des librairies trop spécifiques aux ATmega sur l’ESP dans la mesure du possible !

Mais rassurez-vous la majorité des librairies Arduino sont compatibles sur l’ESP in-fine !

Vous avez donc accès, pour à peine 2€ à un microcontrôleur compatible Arduino équipé d’une connexion IP en Wifi, le tout dans un environnement simple et familier avec un tas de librairies existantes !

Quelques autres firmwares

Dans la philosophie de NodeMCU : MicroPython, un moteur Python minimaliste pour système embarqué porté sur ESP8266. Il est possible d’exécuter du code Python sur l’ESP via un interpréteur accessible sur la liaison série. Cependant le file system n’est pas supporté, donc pas de possibilité d’enregistrer son code dans la mémoire Flash de la puce. Actuellement ce firmware est très expérimental et supporte le Wifi en mode client (station), l’accès aux GPIO avec quelques modules de base comme les array, collection, struct, network et io.

micropython

Dans la lignée du firmware AT il existe sur Github, le firmware « Frankenstein » beaucoup plus complet et « user-friendly » avec un jeu de commande digne d’un véritable shell. Par exemple pour scanner les réseaux Wifi on utilisera la commande « iwscan » :

frankenstein > iwscan BSSID b0:48:7a:d6:92:a8 channel 11 rssi -88 auth WPA2_PSK TP-LINK_D692A8 BSSID c0:4a:00:c7:9d:8e channel 11 rssi -80 auth WPA_WPA2_PSK Home_TP-LINK

Un classique “ifconfig” permettra d’afficher les interfaces réseaux avec le détail. Et tout comme shell qui se respecte, la commande « help » vous donnera la liste complète des commandes disponibles.

Pour finir évoquons également Espduino toujours sur Github. Il permet d’utiliser l’ESP8266 comme un module Wifi pour un Arduino en utilisant la liaison série. A la différence du firmware AT qui utilise un jeu de commande ASCII, Espduino utilise le protocole SLIP pour la communication Arduino<>ESP.

Le SLIP pour Serial Line Internet Protocol est un protocole (RFC 10551) de liaison internet en série qui encapsule le protocole IP. De ce fait, la liaison est plus performante et plus fiable qu’avec le firmware AT.

Connectez vos ESP8266 dans la Constellation et prenez de la puissance !

Comme nous l’avons vu les puces ESP8266 offrent beaucoup de possibilité dès lors qu’il est possible de les reprogrammer.

Fig1 - Model 1

La plateforme Constellation que je vous ai déjà présentée mainte fois, permet l’interconnexion des objets connectés et la création d’intelligence ambiante.

Aujourd’hui cette plateforme connecte ma domotique Z-Wave, mon thermostat Nest, mes média-centers Kodi, mes lampes Hue, mon alarme Paradox, ma station météo connectée, ma balance connectée, les TVs et amplis de la maison, mon agenda Exchange, etc… sans oublier tous mes projets DIY tel que S-Energy pour le comptage énergétique, S-Sound pour la diffusion audio multi-room, le miroir intelligent, ma porte de garage, etc…

Bien sûr, les ESP8266 n’échappent pas à cette règle ! Il existe deux librairies : une librairie Constellation pour NodeMCU, écrite en Lua et une autre Arduino écrite en C++. Au sujet de la libraire Constellation Arduino, elle est basée sur la classe de base « Client » ce qui lui permet d’être compatible avec n’importe quelle interface réseau Arduino (comme le module CC3000 ou les shields Ethernet pour Arduino).

Il suffit d’initialiser la connexion vers la Constellation en spécifiant l’URI de la Constellation, le nom de la sentinelle, du package et la clé d’accès que vous aurez défini dans la configuration de votre Constellation.

En C++/Arduino :

#include <Constellation.h> Constellation constellation(wifiClient, "192.168.205.105", 8088, "ESP8266", "LuxSensor", "123456789");

En Lua/NodeMCU :

local constellation = require("constellation") constellation.init("192.168.205.105", 8088, "ESP8266", " MyPackage", "access_token")

On peut ensuite publier des « StateObjects ». Par exemple un capteur de luminosité pourrait publier un StateObject contenant le nombre de Lux :

constellation.pushStateObject("Lux", value);

Ou même publier un objet complexe contenant plusieurs propriétés :

JsonObject& root = jsonBuffer.createObject(); root["Lux"] = lux; root["Broadband"] = full; root["IR"] = ir; constellation.pushStateObject("Lux", &root);

En Lua on écrirait :

constellation.push("Lux", cjson.encode({ Broadband=broadband, IR=ir, Lux= math.floor(lux) }))

Dès lors un autre package C#, Python, une page Web avec l’API JS de Constellation, un script Powershell, un Gadgeteer ou n’importe quoi connecté dans votre Constellation peut s’abonner à la mise à jour du StateObject poussé par votre ESP8266.

Par exemple en utilisant l’API Javascript de Constellation, on alimente un gauge dans une page HTML avec notre StateObject « Lux » :

StateObjects dans une page Web

On peut également envoyer un message dans la Constellation. Par exemple si je veux que mon ESP8266 baisse le thermostat de mon Nest, il me suffit d’envoyer un message « SetTargetTemperature » avec la température de consigne au package Constellation « Nest » :

 
constellation.sendMessage("Package", "Nest", "SetTargetTemperature", temperature);

On peut aussi recevoir des messages, par exemple, depuis une page Web exploitant l’API JavaSscript de Constellation, je peux envoyer un ordre de redémarrage.

Dans l’initialisation je vais m’abonner aux messages entrant et affecter un callback :

void messageReceive(JsonObject& json) { const char * key = json["Key"].asString(); if (stricmp (key, "Restart") == 0) { ESP.restart(); } } // Dans le setup :  constellation.setMessageReceiveCallback(messageReceive); constellation.subcribeToMessage();

Côté Web, un bouton HTML et une ligne de code pour envoyer le message « Restart » sans paramètre vers la sentinelle “ESP8266” :

$("#btnRestart").click(function() { constellation.sendMessage({ Scope: "Sentinel", Args: [ "ESP8266" ] }, "Restart", {}); });

Il suffit alors de cliquer sur le bouton HTML pour envoyer le message « Restart » qui sera reçu sur votre ESP, lequel redémarrera instantanément !

Une autre fonctionnalité très intéressante, les « StateObjectLink », c’est-à-dire la capacité depuis un Arduino/ESP à s’abonner aux changements des StateObjects publiés par d’autre package de ma Constellation. Par exemple je veux être informé de la T° de la chambre mesurée par mon capteur NetAtmo, ou bien savoir si la porte de garage est ouverte ou encore connaitre le volume de l’ampli, et tout cela en temps réel.

Prenons l’exemple de la consommation d’électricité poussé par le package S-Energy. L’idée est d’afficher le nombre de Watt par heure de la maison en temps réel dans la console de notre ESP/Arduino :

void soUpdate(JsonObject& json) { // On affiche la propriété 'WattPerHour' du StateObject Serial.print("Watt/heure : "); Serial.println(json["Value"]["WattPerHour"].asString()); }   // Dans le setup, on s'abonne au StateObject 'Electricity' du package 'SEnergy' constellation.setStateObjectUpdateCallback(soUpdate); constellation.subscribeToStateObjects("*", "SEnergy", "Electricity");

Tout comme les messages, il suffit d’affecter un callback et de préciser les StateObjects que l’on souhaite suivre ! Ainsi, à chaque variation de ma consommation électrique, mon Arduino/ESP a l’information en temps réel et l’enverra sur l’interface série !

Les librairies Constellation pour Arduino et Lua offrent également la possibilité d’envoyer des logs dans la Constellation et de récupérer les settings centralisés sur votre serveur.

Ainsi les possibilités sont immenses car vos petites puces peuvent accéder à toutes les données et fonctionnalités de vos autres objets ou services connectés en quelques lignes de code sans aucune complexité apparente. Baisser le chauffage, allumer des lumières, changer la chaine de votre TV, envoyer un SMS ou bien parler dans une pièce de la maison est accessible en une ligne de code depuis votre ESP/Arduino.

Et vice-versa, les données et fonctionnalités embarquées de vos objets connectées à base d’ESP8266 sont à leurs tours accessibles pour les autres objets et services connectés de votre Constellation.

La seule limite sera votre imagination.

Des projets ESP8266 dans toute la maison avec la Constellation

Article Programmez!

De par sa taille, ses spécifications et son prix, le microcontrôleur Wifi ESP8266 offre un tas de possibilité d’usage.

Couplé à une plateforme d’interconnexion des objets connectés tel que la plateforme Constellation, il devient possible en un rien de temps de faire des objets ultra connectés comme nous allons le découvrir.

Objet #1 : mieux piloter l’éclairage intérieure avec un capteur de luminosité

A la maison j’ai installé sur mon toit un capteur de luminosité TSL2561 dans une boite étanche. Ce capteur est relié en I²C à un Raspberry Pi lui-même connecté dans la Constellation. Le package « LuxSensor » écrit en Python avec l’API Python pour Constellation publie dans la Constellation un StateObject nommé « Lux » qui contient un objet JSON contenant le nombre de Lux mesuré !

Toujours dans ma Constellation, j’ai un package écrit en .NET nommé « MyBrain » qui est abonné à ce StateObject, et qui, en fonction d’un tas de condition liée à d’autre StateObjects (comme la présence ou non d’utilisateurs dans les pièces à vivre via les StateObjects des détecteurs de présence de l’alarme), pilote les luminaires de la maison.

Seulement comme le capteur est sur le toit je mesure les lux extérieurs ce qui n’est pas tout le temps corréler à la luminosité dans le salon (variable en fonction des nuages). Pour améliorer l’algorithme il me fallait un capteur de luminosité à l’intérieur.

J’ai donc acheté un boitier/prise 220V (10€), un transformateur 220V vers 3,3V (2€), un capteur TSL2561 (2€) et un ESP8266.

Schéma Lux Sensor

Vous trouverez sur Github la librairie Arduino pour le TSL2561 parfaitement compatible avec l’ESP. On connectera ce module I²C sur les GPIO0 et 2.

ESP Lux Sensor

Côté code, il suffit d’initialiser la librairie d’Adafruit pour lire les données du capteur TSL et calculer le nombre de lux courant :

uint32_t lum = tsl.getFullLuminosity(); uint16_t ir, full; ir = lum >> 16; full = lum & 0xFFFF; uint32_t lux = tsl.calculateLux(full, ir);

Il ne reste plus qu’à publier ces informations dans un StateObject vers Constellation :

// Push on Constellation JsonObject& stateObjectLux = jsonBuffer.createObject(); stateObjectLux["Lux"] = lux; stateObjectLux["Broadband"] = full; stateObjectLux["IR"] = ir; constellation.pushStateObject("Lux", &stateObjectLux, "LightSensor.Lux")

Maintenant pour visualiser en temps réel le capteur, on peut créer une simple page HTML et utiliser AngularJS et son module Constellation pour afficher les données de votre capteur en temps réel.

Pour cela il suffit de s’abonner au StateObject, celui produit par le package “LightSensor” de la sentinelle “ESPSalon” grâce à la ligne suivante :

constellation.requestSubscribeStateObjects("ESPSalon", "LightSensor", "*", "*");

Puis dans le code HTML, on peut ajouter trois gauges liées aux propriétés du StateObject produit par l’ESP :

<td><just-gage id="Lux" value="ESPSalon.Lux" min=0 max=40000 title="Lux Intérieur"></just-gage></td> <td><just-gage id="Broadband" value="ESPSalon.Broadband" min=0 max=65535 title="Broadband Intérieur"></just-gage></td> <td><just-gage id="IR" value="ESPSalon.IR" min=0 max=65535 title="IR Intérieur"></just-gage></td>

StateObject en temps réel dans une page Web

Et voilà comment, en quelque lignes d’HTML et JS, créer un Dashboard temps réel de votre capteur ESP.

Ce StateObject peut être  est également traqué par le package “GrayLog” que je vous ai déjà présenté dans cet article.  Ainsi dès que l’ESP publie une nouvelle mesure dans la Constellation, celle-ci est enregistrée dans ElasticSearch, permettant ensuite de faire de l’analyse depuis Kibana par exemple.

Ici l’évolution des 3 propriétés de notre StateObject sur les 7 derniers jours :

Analyse de la luminosité dans Kibana

Au-delà du Dashboard temps réel et de l’analytique, j’ai conçu ce capteur pour piloter de manière plus efficace mon éclairage intérieur et les volets.

Comme mon moteur de règle, le “cerveau” de la maison est écrit en C#,  il suffit d’ajouter l’attribut StateObjectLink sur une propriété .NET pour créer le lien avec le StateObject “Lux” publié par notre ESP :

[StateObjectLink("ESPSalon", "LightSensor", "Lux")] public StateObjectNotifier IndoorLuxSensor { get; set; }

 

this.IndoorLuxSensor.ValueChanged += (s, e) => { Console.WriteLine("Nouvelle valeur de Lux : {0}", e.NewState.DynamicValue.Lux); };

Ainsi, dès qu’une nouvelle mesure est publiée par l’ESP, un évènement se déclenche dans mon code .NET. En fonction de la nouvelle valeur du StateObject (contenant le nombre de Lux dans mon salon), et d’un tas d’autre information, le “cerveau” de la maison, allume ou éteins automatiquement les lumières ou encore ouvre ou ferme les volets compte tenu de la luminosité.

J’ai pu ainsi mettre à jour mon algorithme de gestion des lumières du salon en prenant en compte la luminosité intérieure.

Objet #2 : un anneau lumineux connecté

J’ai retrouvé dans mes cartons un NeoPixel Ring d’Adafruit, un anneau de 12 leds multi couleurs pilotable individuellement par PWM.

J’ai donc simplement alimenté l’anneau en 3.3V et connecté le « Data In » de l’anneau sur le GPIO 0 de l’ESP !

Schéma NeoPixel Ring

Côté code, j’ai utilisé la librairie Adafruit, là encore compatible ESP pour piloter mes LEDs. Par exemple pour éteindre la 1ère LED et allumer en rouge la 2ème, on écrira :

pixels.setPixelColor(0, pixels.Color(0, 0, 0)); // 1ère OFF pixels.setPixelColor(1, pixels.Color(150, 0, 0)); // 2ème en rouge

Maintenant l’idée est que lorsque notre ESP recevra un message de la Constellation nommé « ShowLed » il allumera le nombre de LED passé en paramètre du message via une méthode showLed(int) qui s’occupera de faire les setPixelColor.

void messageReceive(JsonObject& json) { const char * key = json["Key"].asString(); if (stricmp(key, "ShowLed") == 0) { showLed(json["Data"].as<int>()); } }   // Dans le setup() constellation.setMessageReceiveCallback(messageReceive); constellation.subscribeToMessage();

On peut par exemple, à partir d’une simple page Web et avec la librairie Constellation Javascript, piloter en temps réel l’anneau lumineux.

Par exemple avec un slider :

<input type="range" id="nbLed" min="0" max="12" />
$('#nbLed').on("slidestop", function( event, ui ) { constellation.sendMessage({ Scope: 'Sentinel', Args: [ 'ESP8266' ] }, 'ShowLed', $(this)[0].value); });

Contrôler l'anneau lumineux en Javascript

 

Et voilà comment une simple page Web peut contrôler en temps réel un ESP8266.

Objet #3 : un Hardware Monitor lumineux

Reprenons le même objet, un ESP8266 avec un anneau lumineux sauf que cette fois ci on ne va pas réagir au message reçu de la Constellation mais plutôt à des StateObjects.

Sur chaque machine Windows que je possède est déployé le package Constellation « HWMonitor » qui publie un tas de StateObject lié au hardware de la machine comme la consommation CPU, RAM, disque, réseau, etc…

Il suffit donc de s’abonner au StateObject du CPU d’une de mes machines et d’afficher le nombre de LED proportionnellement à la consommation du CPU.

void soUpdate(JsonObject& json) { int cpu = json["Value"]["Value"].as<int>(); showLed((cpu * ratio) + 1); // ratio = (nombre de LED / 100) } // Dans le setup() constellation.setStateObjectUpdateCallback(soUpdate); constellation.subscribeToStateObjects("SEB-PC", "HWMonitor", "/intelcpu/0/load/0");

Et voilà mon anneau lumineux réagit maintenant en temps réel à la consommation CPU de mon ordinateur !

Hardware Monitor

 

Objet #4 : l’indicateur de zone

Partant du principe que l’on peut s’abonner à la mise à jour de n’importe quel StateObject d’une Constellation, on peut par exemple faire un indicateur d’état d’ouverture d’une porte ou d’une fenêtre.

Dans ma Constellation je retrouve ce genre de StateObject avec mon système d’alarme (présenté dans cet article) ou mon système domotique (Z-Wave) également connecté à Constellation.

Pour l’affichage prenons une matrice de Led bi-couleur pilotée en I²C. Il suffit donc de connecter la matrice sur la GPIO 0 et 2 pour le SDA et SCL (I²C) et d’alimenter en 5V.

Schema du Led Matrix

Coté code, je récupère l’ID de la zone à surveiller depuis les settings Constellation :

JsonObject& settings = constellation.getSettings(); const char *zoneId = settings["ZoneId"].asString();

Grace à cela il me suffira depuis la console d’administration Constellation de changer le n° de la zone sans avoir à reprogrammer l’ESP.

Ensuite on va demander l’état du StateObject de la zone à surveiller et on s’abonne à toute modification de cette zone :

// Request JsonArray& zoneInfo = constellation.requestStateObjects("CEREBRUM", "Paradox", zoneId); soUpdate(zoneInfo[0]); // Subscribe constellation.setStateObjectUpdateCallback(soUpdate); constellation.subscribeToStateObjects("CEREBRUM", "Paradox", zoneId);

Dans les deux cas, on appellera la méthode “soUpdate” en passant en paramètre le StateObject de la zone. Ce StateObject publié par le package Constellation de l’alarme contient un objet JSON avec la propriété « IsOpen » qui nous renseignera sur l’état de la zone :

void soUpdate(JsonObject& json) { boolean isOpen = json["Value"]["IsOpen"].as<boolean>();   Serial.print("La zone est "); Serial.println(isOpen ? "ouverte" : "fermée"); }

Il ne reste plus qu’à piloter la matrice de LED. La librairie d’Adafruit est très simple. Il suffit d’appeler la méthode « drawBitmap » en passant en paramètre la couleur des LED et la matrice de point.

Dessinons alors un carré vert lorsque la zone est fermée et une croix rouge lorsque la zone est ouverte. Les deux matrices seront décrites dans des tableaux nommés « x_bmp » et « box_bmp ». Il ne reste donc plus qu’à dessiner en fonction de l’état du StateObject :

if (isOpen) { // display a red X matrix.clear(); matrix.drawBitmap(0, 0, x_bmp, 8, 8, LED_RED); matrix.writeDisplay(); } else { // display a green box matrix.clear(); matrix.drawBitmap(0, 0, box_bmp, 8, 8, LED_GREEN); matrix.writeDisplay(); }

Et voilà notre ESP pilotant une matrice de LED en indiquant en temps réel l’état d’une zone, par exemple, la porte de ma cuisine :

Zone ouverteZone fermée

Objet #5 : contrôler sa maison avec une télécommande infrarouge

Ce projet a été publié dans mon billet du 10 novembre 2015 : Contrôlez votre maison avec la télécommande de la TV–ou comment envoyer et recevoir des signaux infrarouges avec un ESP8266 et Constellation

Il s’agit de réaliser une passerelle infrarouge connectée à Constellation permettant à n’importe quel client connecté dans Constellation d’envoyer ou de recevoir des signaux infrarouge.

Schéma général

Pour l’envoi il suffit de piloter une LED infrarouge en PWM pour moduler le signal. En principe on devrait connecter cette LED sur la GPIO 0 ou 2, mais comme la diode est reliée à la masse, l’ESP entra en « Flash mode » au démarrage. Pour contrer cet effet, j’ai connecté la LED sur le GPIO1 (le RX) après l’avoir programmé.

Pour la réception, le récepteur IR 38kHz est alimenté en 3,3V et le signal reçu est envoyé sur la GPIO2.

J’ai donc packagé dans un petit boitier en plastique l’ESP8266 avec un régulateur LD33V, la LED et le récepteur IR. Il suffit de connecter une alimentation de 5 à 15V et l’installer dans votre salon par exemple.  

Passerelle IR pour Constellation

Personnellement j’intercepte les touches inutiles de la télécommande de la TV pour ^piloter différentes objets de ma Constellation tel que la domotique Z-Wave (volets, lumières, etc..), le media-center (Xbmc/Kodi), les lumières Hue ou encore le thermostat (Nest).

Affectation des touches de la télécommande

Pour plus d’info sur ce projet, je vous invite à lire l’article Contrôlez votre maison avec la télécommande de la TV qui vous détaillera en long et en large comment créer une passerelle IR pour Constellation.

 

 

Conclusion

A travers ces quelques projets basés sur des ESP8266 et grâce à la plateforme Constellation, le potentiel de ces petites puces sont immenses. Elles servent à la fois de capteur pour publier des données dans la Constellation qui seront utiles à d’autres programmes (comme par exemple un capteur de T°, de consommation, de mouvement, etc..), ou encore réagir à des messages pour pouvoir ajouter du contrôle à vos ESP (par exemple un robot, une prise commandée, etc..). Plus encore, ces petites puces peuvent réagir en fonction de l’état de vos autres objets ou services connectés dans la Constellation grâce aux StateObjects. Ainsi n’importe quel évènement se produisant dans votre maison ou au-delà et peu importe les technologies mis en œuvre, peut être « capté » par vos ESP.

Du moment qu’elles sont connectées à la Constellation, elles accèderont à toutes les fonctionnalités et données de votre Constellation ! Que ce soit votre agenda, votre domotique, vos objets connectés, vos projets maison, vos ordinateurs et même votre douche !

Leave a Reply

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *