1.  ESPèce de 8266

L'ESP8266 est un microcontrôleur avec une puce Wi-fi comportant une pile TCP-IP. Il est donc possible de l'utiliser comme un module Wi-fi avec un arduino par exemple. Il peut également héberger une application et agir de façon autonome. Vu son faible coût et ses capacités cela permet de l'utiliser dans le cadre de l'internet des objets. Nous allons essayer de passer cela en revue.

Tout d'abord il existe une famille d'ESP8266.


Les différents ESP

Trois en particulier me semblent intéressants :

  • ESP-01. C'est l'un des plus utilisés. Il a l'avantage d'être petit (24.75mm x 14.5mm) et peu cher. Si vous n'êtes pas pressé vous pouvez l'acheter pour 2€69. Il possède 2 broches GPIO et comporte de base le firmware AT. Un des inconvénients est qu'il est allergique à la platine d'expérimentation du fait de l'espacement des broches.
  • ESP-07. On peut lui rajouter une antenne Wi-fi et il a plus de 2 broches GPIO. Je l'ai vu à 2€22.
  • ESP-12 Il a 11 broches GPIO, et une broche ADC avec une résolution de 10 bits. On peut également le mettre en mode veille profonde, ce qui peut être intéressant pour instrumenter.

2.  Premières utilisations

Je vous propose de tester dans un premier temps votre ESP8266 en vous connectant au Wi-fi. Les ESP sont programmables et vous pouvez si vous le souhaitez écrire votre propre firmware et le téléverser dans votre module. Nous allons nous contenter pour commencer du firmware par défaut qui fournit une communication série que l'on peut utiliser en envoyant des commandes AT. Cela permet déjà de se connecter à un routeur Wi-fi par exemple et envoyer et recevoir des données.

Comme nous l'avons déjà indiqué, il existe plusieurs ESP, cependant ils fonctionnent globalement sur le même principe. Ils doivent être alimentés en 3,3 v et en entrée sur les broches ils doivent recevoir du 3,3 v sous peine de passer de vie à trépas.


Brochage de l'ESP-1 source

L'ESP-1 à 6 broches, dont deux GPIO. Dans le principe il faut relier l’alimentation (Vcc et GND) de l'ESP8266 à l’alimentation externe. La broche CH_PD de l’ESP à l’alimentation externe 3.3 v. Pour communiquer avec l'ESP on utilise une liaison série dans un premier temps puis éventuellement le Wi-fi ensuite. Il faut donc relier RX et TX au convertisseur ou à un Arduino (Uno par exemple) avec les broches TX et RX en respectant les tensions. Il faut également relier la masse de votre convertisseur série ou de l'Uno à la masse de l’alimentation externe.

Pour commencer nous allons décrire la connexion entre l'ESP et un convertisseur USB série, puis entre l'ESP et un Uno.

2.1  Connexion au Wi-fi avec un convertisseur USB série

Il nous faut :

  • 1 platine d'expérience ;
  • 1 FTDI ;
  • 1 ESP8266-1 ;

Le convertisseur permet de dialoguer avec tout appareil possédant une liaison série et ce n'est pas ce qui manque (ESP, une puce ATMEGA, un switch ....). C'est donc un équipement utile et il est important pour se faciliter la vie d'avoir un commutateur 3,3v/5v. Le prix est modique de l'ordre de 2€.


Convertisseur

J'utilise également une alimentation externe bien pratique pour me faciliter la vie qui s'enfiche sur la platine et permet de choisir entre 5v et 3.3v. Elle m'a coûté 1 €.


Alimentation 5/3,3 v

Il faut maintenant cabler l'ESP avec le FTDI.


Le schéma de montage

Lorsque vous cablez votre ESP, je ne peux que vous conseiller de noter les couleurs des fils associés aux broches car ce n'est pas toujours facile à repérer, l'ESP ne venant pas s'enficher sur la platine.

Le montage fait et connecté à votre ordinateur par l'USB il reste à utiliser une console série pour envoyer les commandes AT à l'ESP. Le plus simple est d'utiliser celle de l'IDE Arduino. Il faut déterminer votre device /dev/ttyUSB0 pour ce qui me concerne et régler la vitesse de communication (9600 ou 115200) ainsi que la fin de ligne (NL et CR). Vous pouvez ensuite utiliser les commandes AT pour dialoguer avec votre ESP. Si vous être allergique à l'IDE vous pouvez utiliser screen.

Pour cela il faut configurer le device

 %  stty -F /dev/ttyUSB0 cs8 115200 ignbrk -brkint -imaxbel -opost -onlcr -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke noflsh -ixon -crtsct

et ensuite lancer screen. Les commandes sont validées par ctrl m puis ctrl j.

 % screen /dev/ttyUSB0 115200

Les commandes AT ont été écrites pour les modems hayes, il y a quelques temps. Vous pouvez aller voir ici une liste détaillée des commandes. Essayons en quelques unes maintenant.

 AT

 OK

AT seule permet de vérifier que la communication est bien établie.

 AT+GMR

 AT version:0.40.0.0(Aug  8 2015 14:45:58)
 SDK version:1.3.0
 Ai-Thinker Technology Co.,Ltd.
 Build:1.3.0.2 Sep 11 2015 11:48:04
 OK

On détermine le firmware.

Vous avez le droit d'être impatient, en vous demandant quand allons nous utiliser le wi-fi. L’ESP peut être en mode client (1), en mode point d’accès (2) ou les 2 (3). On fixe le mode avec AT+CWMODE=x avec x = 1, 2 ou 3. On choisit le mode mixte.

 AT+CWMODE=3

 OK

On peut alors déterminer les réseaux accessibles avec AT+CWLAP :

 AT+CWLAP

 +CWLAP:(1,"OudAne",-64,"xx:xx:xx:xx:xx:xx",1,-34)
 +CWLAP:(0,"FreeWifi",-65,"xx:xx:xx:xx:xx:xx",1,-36)
 +CWLAP:(0,"FreeWifi_secure",-65,"xx:xx:xx:xx:xx:xx",1,-34)
 +CWLAP:(3,"AndroidHotspot3647",-30,"xx:xx:xx:xx:xx:xx",6,-14)

Vous avez obtenu, la liste des réseaux détectés avec le mode de protection, le nom du réseau, la puissance du signal, l'adresse MAC. Le mode de protection est codé à l'aide d'un entier :

  • 1 ouvert, pas de protection ;
  • 2 WEP ;
  • 3 WPA_PSK ;
  • 4 WPA2_PSK ;
  • 5 WPA_WPA2_PSK ;

Ok je vous le concède ce n'est pas très sur chez moi. Ensuite pour se connecter :

 AT+CWJAP="AndroidHotspot3647","hjjkqsduUUUUiii"

 WIFI CONNECTED
 WIFI GOT IP

Pour connaître l'adresse IP

 AT+CIFSR

 +CIFSR:STAIP,"192.168.43.145"
 +CIFSR:STAMAC,"xx:xx:xx:xx:xx:xx"

 OK

On peut essayer de recupérer une page sur internet, pour cela on va passer en mode TCP client à l'aide de AT+CIPMUX=x avec x = 1 connexion multiple, x = 0 connexion simple.

 AT+CIPMUX=1

 OK

On ouvre ensuite une connexion vers un serveur, ici celui de mon université sur le port 80, on précise le numéro de la connexion (entre 0 et 4).

 AT+CIPSTART=4,"TCP","univ-lehavre.fr",80

 4,CONNECT

 OK

Il faut ensuite préciser le nombre d'octets que vous allez envoyer au niveau du > (GET / HTTP/1.0 et 2 fois entrée \r\n\r\n)

 AT+CIPSEND=4,18


 OK
 > 
 Recv 18 bytes

 SEND OK

 +IPD,4,471:HTTP/1.1 301 Moved Permanently
 Date: Tue, 29 Mar 2016 17:48:20 GMT
 Server: Apache
 Location: https://www.univ-lehavre.fr/
 Vary: Accept-Encoding
 Content-Length: 236
 Connection: close
 Content-Type: text/html; charset=iso-8859-1

 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
 <html><head>
 <title>301 Moved Permanently</title>
 </head><body>
 <h1>Moved Permanently</h1>
 <p>The document has moved <a href="https://www.univ-lehavre.fr/">here</a>.  </p>
 </body></html>
 4,CLOSED
CommandeDescription
ATRenvoie OK
AT+GMRRetourne des information sur le firmware
AT+RSTRedémarre l'ESP
AT+CIOBAUD=xFixe la vitesse de communication en bauds x = 9600, 19200, 38400, 74880, 115200, 230400, 460800, et 921600
AT+CIOBAUD?Affiche la vitesse
AT+CWMODE=x x=1,2Choisit le mode Wi-Fi. AT+CWMODE=1 pour se connecter à un réseau Wi-Fi existant. AT+CWMODE=2 mode Access Point. AT+CWMODE=3 mode mixte
AT+CWLAPListe des réseaux Wi-Fi disponible
AT+CWJAP="SSID","MotDePasse"Connexion à un réseau Wi-Fi. Remplacer SSID et MotDePasse par ceux du réseau.
AT+CWJAP?Sur quel réseau êtes vous connecté
AT+CIFSRPermet de connaître l'IP
AT+CIPSTO=xFixe la valeur du time-out en seconde
AT+CIPMUX=x x=0,1Gestion d'une (0) ou plusieurs connexions simultanées (1)
AT+CIPSTART=type,ip,portInitialise la connexion Wi-Fi. Le type peut-être TCP ou UDP
AT+CIPSTART=num,type,ip,port num=0..4Initialise la connexion de numéro num
AT+CIPSEND=yDans le cas où CIPMUX=0. Envoi de données sur une connexion. y = nombre de caractères à envoyer.
AT+CIPSEND=x,yDans le cas où CIPMUX=1, x = numéro de la connexion à utiliser (entre 0 et 4)
AT+CIPCLOSEFermer la connexion

2.2  Connexion au Wi-fi avec un Arduino Uno

En cours de rédaction

Il nous faut :

  • 1 platine d'expérience ;
  • 1 arduino uno ;
  • 1 ESP8266-1 ;
  • 1 résistance de 2 {$k\Omega$} et 1 résistance de 4 {$k\Omega$}

Nous allons envoyer des commandes AT à l'ESP par l'intermédiaire de l'Uno en utilisant le moniteur série associé à l'IDE Arduino. Les commandes seront donc tapées dans la console et les réponses de l'ESP seront affichées dans cette même console.

Notre Uno fonctionne à un niveau logique de 5v alors que l'ESP fonctionne en 3,3 v. Il faut donc réaliser un diviseur de tension. Les tensions du diviseur sont reliées à la masse et les deux résistances R1 et R2 sont connectées en série.


Pont diviseur de tension

Une tension {$V_{cc}$} est appliquée en entrée sur ces deux résistances et la tension de sortie {$V_{out}$} est mesurée aux bornes de {$R_2$}. On a {$ V_{out} = V_{cc} \frac{R_2}{R_1 + R_2} $}. Donc si {$V_{cc} = 5 v$} avec {$R_1 = 2 k\Omega$} et {$R_2 = 4 k\Omega$}

{$ V_{out} = 5 \times \frac{4}{6} = 3,33 v $}

3.  Installation de l'ESP dans l'IDE Arduino

Vous trouverez les informations nécessaires dans le dépôt git. Il faut avoir installé l'IDE Arduino 1.6.8 ou supérieur. Lancer l'IDE et dans le menu fichier, choisir Préférences et ajouter l'URL suivante http://arduino.esp8266.com/stable/package_esp8266com_index.json dans URL de "gestion de cartes additionnelles".

Ensuite dans outils -> Type de carte -> Gestionnaire Recherchez ESP8266 et cliquez sur l'entrée correspondante puis sur install.

Une fois cela fait il vous reste à sélectionner la carte dans outils -> Type de carte -> Generic ESP8266 Module pour une ESP-1 de base. On peut maintenant téléverser un programme mais avant cela il faut vérifier que votre broche GPIO0 est branchée sur GND et que CH_PD est à 3,3 volts.

Vous pouvez maintenant tester avec un exemple. J'ai choisi Wifiscan qui ne nécessite pas de modifier le câblage !

  1. /*
  2.  *  This sketch demonstrates how to scan WiFi networks.
  3.  *  The API is almost the same as with the WiFi Shield library,
  4.  *  the most obvious difference being the different file you need to include:
  5.  */
  6. #include "ESP8266WiFi.h"
  7.  
  8. void setup() {
  9.   Serial.begin(115200);
  10.  
  11.   // Set WiFi to station mode and disconnect from an AP if it was previously connected
  12.   WiFi.mode(WIFI_STA);
  13.   WiFi.disconnect();
  14.   delay(100);
  15.  
  16.   Serial.println("Setup done");
  17. }
  18.  
  19. void loop() {
  20.   Serial.println("scan start");
  21.  
  22.   // WiFi.scanNetworks will return the number of networks found
  23.   int n = WiFi.scanNetworks();
  24.   Serial.println("scan done");
  25.   if (n == 0)
  26.     Serial.println("no networks found");
  27.   else
  28.   {
  29.     Serial.print(n);
  30.     Serial.println(" networks found");
  31.     for (int i = 0; i < n; ++i)
  32.     {
  33.       // Print SSID and RSSI for each network found
  34.       Serial.print(i + 1);
  35.       Serial.print(": ");
  36.       Serial.print(WiFi.SSID(i));
  37.       Serial.print(" (");
  38.       Serial.print(WiFi.RSSI(i));
  39.       Serial.print(")");
  40.       Serial.println((WiFi.encryptionType(i) == ENC_TYPE_NONE)?" ":"*");
  41.       delay(10);
  42.     }
  43.   }
  44.   Serial.println("");
  45.  
  46.   // Wait a bit before scanning again
  47.   delay(5000);
  48. }

Bonne nouvelle cela fonctionne.

 scan start
 scan done
 3 networks found
 1: OudAne (-70)*
 2: FreeWifi (-70) 
 3: FreeWifi_secure (-70) 

4.  Y fait ti cho

L'application visée consiste à suivre la température et l'hygrométrie dans la serre qui a donné satisfaction l'année dernière. Le contrôle et le pilotage de l'arrosage suivront.

Il nous faut :

  • 1 platine d'expérience ;
  • 1 FTDI 3,3v ;
  • 1 ESP8266-1 ;
  • 1 DHT22 (~4€) qui est un capteur de température et d'humidité qui communique avec un microcontrôleur via un port série. Il a les caractéristiques suivantes : entre 3 et 5V en entrée, lecture de l’humidité entre 0 et 100% avec une précision allant de 2% à 5%, lecture de la température de -40°C à 80°C avec une précision d’environ 0.5°C.
  • Un switch.
  • Un bouton poussoir.
  • Une résistance de 10 k{$\Omega$}.

4.1  Installer la librairie DHT22

Si vous ne l'avez pas déjà fait il faut installer une librairie pour gérer le capteur de température. La première chose à faire est de localiser le répertoire pour les sketchs. Il suffit d'aller dans Préférences qui vous donnera l'emplacement du carnet de croquis, /home/damien/Arduino pour ce qui me concerne. Dans ce répertoire vous avez libraries. Il faut alors cloner le dépôt git.

 % cd ~/Arduino/libraries
 % git clone https://github.com/adafruit/DHT-sensor-library

Relancez votre IDE et ensuite compilez un exemple de la nouvelle librairie pour vérifier que cela fonctionne. Pour plus d'information sur l'installation d'une librairie vous pouvez consulter : http://www.arduino.cc/en/Guide/Libraries .

4.2  Le montage

Le FTDI est cablé comme precedemment. L'ESP est relié intégralement à la plaque d'essai (des fils ne servent donc pas !). Pour téléverser le programme comme on l'a déjà vu la broche GPIO0 doit être mise à la masse GND c'est le rôle du bouton. CH_PD est à 3,3 volts. La sortie du DHT22 est sur le GPIO 2 de l'ESP.

4.3  Le programme

L'objectif est de récupérer les données dans thingspeak. La première chose à faire est de vous créer un compte si vous n'en avez pas. Vous devez ensuite créer un channel (tableau de bord) dans lequel vous spécifierez le nom des champs.

On a maintenant 3 courbes que l'on devra alimenter avec l'ESP et suivre "de l'extérieur" dans un navigateur.

Il faut ensuite récupérer la clé pour pouvoir mettre à jour. Il suffit pour cela de cliquer sur data import/export.

Noter les informations Update Channel Feed - GET du type :

 GET https://api.thingspeak.com/update?api_key=WYWHG3ZYBM7XZ7MN&field1=15

qui vous permettront d'envoyer des informations. Vous pouvez d'ailleurs essayer dans votre navigateur en mettant votre clef dans l'URL, vous verrez apparaître un nouveau point au niveau de la courbe 1 dans le tableau de bord correspondant.

Adafruit a également une plate-forme pour l'internet des objets. Il y a un excellent tuto qui vous explique tout.

Nous pouvons maintenant passer au code.

  1. /*
  2.  *  Ce programme pour ESP envoie des données à thingspeak toutes les DELAI minutes
  3.  *  Ces données sont issues d'un capteur DHT22
  4.  *  Le programme est basé sur WIFIScan, DHTtester
  5.  *  
  6.  */
  7.  
  8. #define DEBUG      // Si vous voulez une trace dans la console
  9.                    // A enlever également en mode standalone
  10.  
  11. #include <ESP8266WiFi.h>
  12. #include <WiFiClient.h>
  13. extern "C" {
  14.   #include <user_interface.h>
  15. }
  16. #include <DHT.h>
  17.  
  18. #ifdef DEBUG
  19.  #define DEBUG_PRINT(x)        Serial.print (x)
  20.  #define DEBUG_PRINTLN(x)      Serial.println (x)
  21. #else
  22.  #define DEBUG_PRINT(x)
  23.  #define DEBUG_PRINTLN(x)
  24. #endif
  25.  
  26. #define DELAI 10         // ~ 10 mn entre deux acquisitions et envois
  27. #define DECALAGE 780
  28. #define DHTTYPE DHT22  
  29. #define DHTPIN 2         // Le capteur est sur GPIO 2
  30.  
  31. // Connect pin 1 (on the left) of the sensor to +5V
  32. // NOTE: If using a board with 3.3V logic like an Arduino Due connect pin 1
  33. // to 3.3V instead of 5V!
  34. // Connect pin 2 of the sensor to whatever your DHTPIN is
  35. // Connect pin 4 (on the right) of the sensor to GROUND
  36. // Connect a 10K resistor from pin 2 (data) to pin 1 (power) of the sensor
  37.  
  38. // Initialize DHT sensor.
  39. // Note that older versions of this library took an optional third parameter to
  40. // tweak the timings for faster processors.  This parameter is no longer needed
  41. // as the current DHT reading algorithm adjusts itself to work on faster procs.
  42. // Initialize DHT sensor
  43. DHT dht(DHTPIN, DHTTYPE, 11);
  44.  
  45. const char* SSID     = "MonSSID";     // Remplacer par le nom de votre réseau
  46. const char* PASSWORD = "XXXXXXXXXXX"; // et son mot de passe.
  47.  
  48.  
  49. const char* host = "api.thingspeak.com";
  50. const char* thingspeak_cle = "6767678677FAAA"; // La clé récupérée sur thingspeak
  51.  
  52.  
  53. void turnOff(int broche) {
  54.   pinMode(broche, OUTPUT);
  55.   digitalWrite(broche, 1);
  56. }
  57.  
  58. void setup() {
  59. #ifdef DEBUG
  60.   Serial.begin(115200);
  61. #endif
  62.  
  63.   // Économie d'énergie
  64.   turnOff(0);
  65.   turnOff(2);
  66.   turnOff(4);
  67.   turnOff(5);
  68.   dht.begin();
  69.   delay(10);
  70.  
  71.  
  72.   // Connexion au Wi-fi
  73.   DEBUG_PRINTLN();
  74.   DEBUG_PRINTLN();
  75.   DEBUG_PRINT("Connexion à : ");
  76.   DEBUG_PRINTLN(SSID);
  77.  
  78.   WiFi.begin(SSID, PASSWORD);
  79.   DEBUG_PRINT("\n\r \n\rC'est en cours");
  80.  
  81.   while (WiFi.status() != WL_CONNECTED) {
  82.     delay(500);
  83.     DEBUG_PRINT(".");
  84.   }
  85.  
  86.   DEBUG_PRINTLN("");
  87.   DEBUG_PRINT("DHT connecté au Wi-fi ");
  88.   DEBUG_PRINTLN(SSID);  
  89.   DEBUG_PRINT("Adresse IP : ");
  90.   DEBUG_PRINTLN(WiFi.localIP());
  91. }
  92.  
  93.  
  94. void loop() {
  95.  
  96.   DEBUG_PRINTLN("Connexion à ");
  97.   DEBUG_PRINTLN(host);
  98.  
  99.   // Connexion en TCP sur api.thingspeak.com, port 80
  100.   WiFiClient client;
  101.   const int httpPort = 80;
  102.   if (!client.connect(host, httpPort)) {
  103.     DEBUG_PRINTLN("Echec connexion");
  104.     return;
  105.   }
  106.  
  107.   String temperature = String(dht.readTemperature());
  108.   String humidite    = String(dht.readHumidity());
  109.  
  110.   // Maj GET https://api.thingspeak.com/update?api_key=XXXXXXXXXXXXXXXX&field1=0
  111.   // On construit la requête
  112.   String url = "/update?key=";
  113.   url += thingspeak_cle;
  114.   url += "&field1=";
  115.   url += temperature;
  116.   url += "&field2=";
  117.   url += humidite;
  118.  
  119.   DEBUG_PRINT("Requête : ");
  120.   DEBUG_PRINTLN(url);
  121.  
  122.   // Envoi de la requête
  123.   client.print(String("GET ") + url + " HTTP/1.1\r\n" +
  124.                "Host: " + host + "\r\n" +
  125.                "Connection: close\r\n\r\n");
  126.   delay(10);
  127.  
  128.   // Lecture de la réponse du serveur et affichage éventuel dans la console
  129. #ifdef DEBUG
  130.   while(client.available()){
  131.     String line = client.readStringUntil('\r');
  132.     DEBUG_PRINT(line);
  133.   }
  134. #endif
  135.  
  136.   DEBUG_PRINTLN();
  137.   DEBUG_PRINTLN("Au lit ...");
  138.   wifi_set_sleep_type(LIGHT_SLEEP_T);
  139.   delay(60000*DELAI-DECALAGE);
  140. }

Pour téléverser votre programme. Coupez l’alimentation de l'ESP, appuyez sur le bouton poussoir et restez appuyé, remettez l'alimentation en service, relâchez le bouton poussoir. Téléversez ensuite, vérifiez dans la console que tout est OK.

 Connexion à : OudAne
 C'est en cours......
 DHT connecté au Wi-fi OudAne
 Adresse IP : 192.168.0.27
 Connexion à 
 api.thingspeak.com
 Requête : /update?key=17676761277XKEYIN&field1=18.50&field2=49.20

 Au lit ...

Il suffit de vérifier ensuite sur le channel correspondant de https://thingspeak.com que cela fonctionne. Vous pouvez ensuite tester en mode autonome.

5.  Sources

1. http://www.arduino.cc/en/Guide/Libraries
2. ESP8266 première partie : Généralités | Nicolas C. - Blog. Consulté le 7 mars 2016. http://blog.nicolasc.eu/esp8266-premiere-partie-generalites/.
3. Électronique en amateur: Module WiFi ESP8266: test et configuration avec Arduino Uno. Consulté le 26 mars 2016. http://electroniqueamateur.blogspot.fr/2015/08/module-wifi-esp8266-test-et.html.
4. Internet Controlled LED using ESP8266. Consulté le 29 mars 2016. http://blog.nyl.io/esp8266-led-arduino/.