Il y a encore peu de temps, pour offrir des capacités de connexion Wi-Fi à nos Arduinos, il nous fallait acquérir un shield dédié. Il nous en coûtait quelques dizaines d'euros. Ce tarif prohibitif en a calmé plus d'un.
Mais ça, c'était avant. Courant 2014, un nouveau venu dans le monde des micro-controlleurs a complètement changé la donne. Il s'agit de l'ESP8266. L'ESP8266 est un module Wi-Fi qui peut être utilisée de deux manières :
Cet article est une présentation générale de l'ESP8266. Pour aller plus loin et commencer à en tirer vraiment partie, vous pouvez consultez les autes articles de ce site qui lui sont consacrés, notamment:
Il existe plus de 10 versions différentes de l'ESP8266. Toutes ces versions utilisent en réalité le même microcontroleur. Ce qui les différencie c'est le nombre de PINs accessibles, le type d'antenne, ou encore la quantité de mémoire Flash. Nous nous focalisons ici sur 2 des ces modules : l'ESP-01 et l'ESP-12.
Voici les principales différences entre les deux :
ESP8266 ESP-01 |
ESP8266 ESP-012 |
|
---|---|---|
Nombre de GPIO | 2 | 12 |
Entrée analogique (ADC) | Aucune | 1 |
Dimensions | 24.75mm x 14.5mm | 24mm x 16mm |
Prix | 1,81€ | 2,35€ |
Les caractéristiques communes à toutes les versions :
Notre préférence va nettement à la version ESP-12 en raison du nombre de GPIOs disponibles, ainsi que pour la présence d'une entrée analogique ADC. Par contre il vous faudra jouer du fer à souder avec cette version car les connecteurs ne respectent pas l'espacement standard de 2,54mm. Deux solutions : soit vous gravez votre PCB avec les espacements qui vont bien, soit vous utilisez un adaptateur comme celui là : adaptateur pins ESP8266 ESP-12.
Comme nous l'avons vu en introduction, l'ESP8266 peut s'utiliser de différentes façons. À sa sortie, la puce ne pouvait être utilisée que comme module Wi-Fi "périphérique", associé à autre microcontrôleur. Fin 2014, Espressif (le constructeur à l'origine du module) a mis à disposition de la communauté un SDK, qui a rendu possible l'utilisation de l'ESP8266 comme microcontrolleur totalement autonôme. Intéressons-nous d'abord au premier cas. Nous n'y consacrerons qu'une brêve introduction car ce n'est à notre sens clairement pas ce qui est le plus intéressant à faire avec l'ESP8266. Si vous voulez passer cette étape et apprendre directement à programmer l'ESP8266 sans passer par un Arduino, consultez cet article: Programmer l'ESP8266 avec l'IDE Arduino.
Pour illustrer nos propos, nous allons utiliser un ESP8266 en version ESP-01, et un Arduino Nano. L'Arduino et l'ESP8266 communiqueront par liaison série.
La seule difficultée ici est liée au fait que notre Arduino fonctionne en 5v, alors que l'ESP8266 fonctionne lui en 3.3v. On réalisera les branchements suivants :
Pin Arduino | Pin ESP8266 | Remarque | |
---|---|---|---|
3.3v | VCC | - | |
GND | GND | - | |
D10 | RX | L'ESP8266 ne doit pas recevoir de 5v sur ses pins. Nous devons donc ici convertir le signal 5v en 3.3v. |
|
D11 | TX | L'ESP8266 va envoyer un signal 3.3v à l'Arduino, qui lui est sensé recevoir du 5v. Dans la pratique il semble que l'Arduino considère le 3.3v comme un niveau haut, donc cela fonctionne, même si ce n'est pas très propre. |
|
3.3v | CH_PD | La pin CH_PD doit être au niveau haut pour que le module fonctionne |
Pour convertir le signal 5v sortant de la pin TX de l'Arduino en 3.3v, nous allons faire au plus simple en utilisant deux résistances pour créer un diviseur de tension.
Diviseur de tension 5v - 3.3v
En utilisant une résistance R1 de 10kOhm et une résitance R2 de 20kOhm, nous obtenons :
Vin x R2 / (R1 + R2) = 5 x 20000 / (20000 + 10000) = 3.3v
Voilà ce que ça donne sur une platine d'essais:
Reste à écrire le programme Arduino qui va envoyer des commandes à notre ESP8266.
Pour communiquer avec l'ESP8266, nous devons utiliser un jeu de commandes Hayes, encore appelées commandes AT. C'est un langage développé à l'origine pour le modem Hayes Smartmodem 300, qui a ensuite été utilisé par presque tous les modems du marché.
Commençons par faire quelques tests grâce au programme suivant:
#include <SoftwareSerial.h>
// On crée une communication série software pour l'ESP8266
SoftwareSerial espSerial(10, 11); // RX, TX
void setup() {
// On ouvre une communication serie hardware pour les messages destines au moniteur série
Serial.begin(57600);
// On ouvre la communication serie software pour l'ESP8266
espSerial.begin(57600);
Sleep(1000);
Serial.println("Pret.");
}
void loop() {
// si l'ESP8266 a quelque chose a nous dire, on ecrit son message sur le moniteur série
if (espSerial.available()) {
Serial.write(espSerial.read());
}
// si quelque chose a été saisi dans le moniteur série, on l'envoie à l'ESP8266
if (Serial.available()) {
espSerial.write(Serial.read());
}
}
Avec ce programme, l'Arduino va servir de relai entre le moniteur série de notre IDE et l'ESP8266. Tout ce que nous saisirons dans le moniteur série sera transmis au module Wi-Fi, et toutes les réponses du module Wi-Fi seront affichées dans le moniteur série. Vous noterez qu'on utilise ici 2 liaisons série : une pour la communication moniteur série - Arduino, et une autre pour la communication Arduino - ESP8266. L'Arduino Nano ne disposant que d'une seule interface série hardware, nous utilisons la librairie SoftwareSerial, qui permet de créer des interfaces série en utilisant les GPIOs.
Faisons un premier test. Uploadez le programme, puis ouvrez le moniteur série de l'IDE Arduino. Dans la zone de saisie, entrez la commande suivante:
AT
Vous devriez avoir la réponse suivante :
OK
Cette commande "AT" permet de vérifier que nous arrivons à communiquer avec le module. Essayons autre chose, tappez :
AT+GMR
Vous devriez obtenir quelque chose ressemblant à ça :
00200.9.5(b1)
Ce "AT+GMR" renvoie la version du firmware installé sur le module.
Voici un tableau récapitulatif des principales commandes AT:
Commande | Description |
---|---|
AT | Ne fait rien, à part renvoyer "OK" |
AT+GMR | Retourne la version du firmware |
AT+RST | Redémarre le module |
AT+CWMODE | Permet de choisir le mode Wi-Fi à utiliser:
|
AT+CWLAP | Retourne la liste des réseaux Wi-Fi à portée |
AT+CWJAP | Connection à un réseau Wi-Fi. Cette commande prend deux paramètres : le SSID du réseau, et le mot de passe. Par exemple: AT+CWJAP="Livebox-1234","MonMotDePasseWifi" |
AT+CIFSR | Une fois la module connecté à un réseau, cette commande permet de récupérer son adresse IP |
Avec tout ça on est en mesure de se connecter à un réseau Wi-Fi, ou même d'en créer un. L'étape suivante est d'utiliser cette connexion pour envoyer et/ou recevoir des données. Pour ça, on utilisera les commandes suivantes :
Commande | Description |
---|---|
AT+CIPSTART | Initialise une connexion. |
AT+CIPMUX | Permet de choisir si on veut pouvoir gérer plusieurs connexions simultanément ou pas:
|
AT+CIPSTART | Initialise une connexion. Deux cas, en fonction de ce que vous avez choisi pour AP+CIPMUX:
|
AT+CIPSEND | Démarre l'envoie de données sur une connexion. Ici aussi, deux cas, en fonction de ce que vous avez choisi pour AP+CIPMUX:
|
AT+CIPCLOSE | Ferme une connexion. Si CIPMUX=0, ne prend pas de paramètre. Si CIPMUX=1, prend en paramètre le numéro de connexion à fermer. Par exemple: AP+CIPCLOSE=1 |
#include <SoftwareSerial.h>
SoftwareSerial softSerial(10, 11); // RX, TX
String SSID = "Livebox-1234"; // SSID du réseau Wi-Fi
String PASS = "MonMotDePasseWiFi"; // Mot de passe Wi-Fi
void setup() {
softSerial.begin(115200); // baudrate par défaut de l'ESP8266
delay(100);
// on demande à utiliser un baudrate inférieur
// (notre esp8266 s'est montrer plus stable ainsi)
softSerial.println("AT+CIOBAUD=9600");
delay(200);
softSerial.begin(9600);
}
void loop() {
String temperatureSalon = String(20.12); // dans la vraie vie on utiliserait la valeur retournée par un capteur
sendValue("MQmGBUiuXg3JNgCk", "temperature-salon", temperatureSalon);
}
void sendValue(String token, String metric, String value) {
String host = "www.fais-le-toi-meme.fr";
delay(100);
// on va se connecter à un réseau existant, donc on passe en mode station
softSerial.println("AT+CWMODE=1");
delay(1000);
// on se connecte au réseau
softSerial.println("AT+CWJAP=\""+SSID+"\",\""+PASS+"\"");
delay(10000);
// mode "connexions multiples"
softSerial.println("AT+CIPMUX=1");
delay(3000);
// on se connecte à notre serveur en TCP sur le port 80
softSerial.println("AT+CIPSTART=4,\"TCP\",\""+host+"\",80");
delay(1000);
String request = "GET /iot-dashboard/write/"+token+"/"+metric+"/"+value+ " HTTP/1.0\r\n";
request += "Host:"+host+"\r\n";
// on donne la taille de la requête qu'on va envoyer, en ajoutant 2 car
// println ajouter 2 caractères à la fin "\r" et "\n"
softSerial.println("AT+CIPSEND=4,"+String(request.length()+2));
delay(500);
// on envoie la requete
softSerial.println(request);
delay(3000);
// on ferme la connexion
softSerial.println("AT+CIPCLOSE=4");
}
Bon. Vous aurez remarqué le nombre important d'appels à la fonction delay(). Ça pique un peu les yeux, mais nous avons remarqué que plus on laisse de temps au module, moins on rencontre d'erreurs. L'utilisation des commandes AT envoyées en série rendent le code assez moche. Vous verez par la suite qu'en flashant le module pour y mettre nos propres programmes, on peut faire les choses de manière bien plus élégante.
Pour découvrir comment programmer l'ESP8266, consultez cet article : Programmer l'ESP8266 avec l'IDE Arduino. Attention, vous risquez d'utiliser votre Arduino beaucoup moins souvent après avoir découvert ce que l'ont peut faire avec l'ESP8266 ! :).