ESP8266 Module WiFi programmable

De Centre de Ressources Numériques - Labomedia
Révision de 5 avril 2017 à 13:36 par Gaziel (discussion | contributions)

(diff) ← Version précédente | Voir la version actuelle (diff) | Version suivante → (diff)
Aller à : navigation, rechercher
ESP8266 Module WiFi programmable
ESP8266.jpg


Pour modifier la page utiliser l'onglet Modifier avec formulaire.

Résumé C'est un petit chip (24x16 mm) pas cher (moins de 6€), programmable, qui gère le WiFi en mode client ou serveur
Auteur(s) Dom
Licence CC-BY-SA 3
Date de création 02 mars 2016


Intentions / Contexte

Transmettre ou recevoir des données (mesures, commandes,...)

Principe de fonctionnement

Entièrement programmable (IDE Arduino ou commandes AT ou langage Lua), gére aussi les GPIO

Besoins / Compétences

Soudure très fine, connaissance communications et programmation

Documentation

Premiers tests

Attention : le chip ne supporte que du 3,3V, y compris sur les GPIO et la communication (Rx Tx)!

Le shield est au pas de 2mm et il faut donc souder finement des fils rigides pour faire des pattes qui s'adaptent à une breadboard (pas de 2,54mm) Il y a plusieurs modèles, les plus récents comportant 16 ou 22 pins dont convertisseur A/D et SPI (modèle 12E). Les premiers tests de téléchargement de programmes ont été fait avec l'IDE Arduino (Version ≥ 1.6)

Il faut :un convertisseur USB/Série en version 3,3V (FTDI Basic de Sparkfun)

2 poussoirs une résistance de 2,2k une alimentation 3,3V

Schéma :
VCC---------- +3,3V
Gnd----------- -3,3V
EN (ou CH-PD)----------2,2K----------+3,3V
GPIO15----------Gnd (pourquoi?) GPIO0-----------Poussoir----------Gnd(fonction Load)
RST----------Poussoir----------Gnd (fonction Reset)
Rx----------Tx FTDI
Tx----------Rx FTDI
Gnd FTDI----------- -3,3V

Note : il existe un shield qui réalise tout cela (mais c'est plus cher!) ou on peut en faire un….

Installer la bibliothèque Arduino ESP8266 Voir les sites :
http://esp8266.github.io/Arduino/versions/2.0.0/doc/installing.html
http://www.instructables.com/id/Programming-the-ESP8266-12E-using-Arduino-software/?ALLSTEPS
Le lien de la bibliothèque installée dans les préférences de l'IDE est :
http://arduino.esp8266.com/stable/package_esp8266com_index.json
Choisir le type de carte : ESP8266-12E Vitesse : 115200 (si ça ne marche pas essayer 9600) Télécharger le programme Arduino minimum (Setup et Loop vides) : 1-appuyer sur Load, maintenir 2-faire une impulsion Reset brève 3-relâcher le poussoir Load : l'ESP se met en mode téléchargement 4-compiler et télécharger avec l'IDE Arduino

Exemples de programmes Arduino :

Led clignotantes : (les leds sont à brancher sur les GPIO avec une résistance de 330 Ohms)

astuce ESP12 pour l'I2C : Wire.begin(4,5); // SDA on D2, SCL on D1 // Start up I2C, required for communication


const short int BUILTIN_LED1 = 2; //GPIO2
const short int BUILTIN_LED2 = 16; //GPIO16

void setup() {
pinMode(BUILTIN_LED1, OUTPUT); // Initialize the BUILTIN_LED1 pin as an output
pinMode(BUILTIN_LED2, OUTPUT); // Initialize the BUILTIN_LED2 pin as an output
}

void loop() {
digitalWrite(BUILTIN_LED1, LOW); // Turn the LED off by making the voltage LOW 
digitalWrite(BUILTIN_LED2, HIGH); // Turn the LED off by making the voltage HIGH
delay(1000);
digitalWrite(BUILTIN_LED1, HIGH); // Turn the LED off by making the voltage HIGH
digitalWrite(BUILTIN_LED2, LOW); // Turn the LED ON by making the voltage LOW
delay(2000); 
}

Serveur WiFi en mode AP (Acces Point) pour mesurer une température et allumer une lampe :

<nowiki>#include <ESP8266WiFi.h>

#include <OneWire.h>

#define DS18B20 0x28     // Adresse 1-Wire du DS18B20
#define BROCHE_ONEWIRE 2 // Broche utilisée pour le bus 1-Wire

static const uint8_t BUZ_PIN = 14; // Pin Buzzer
static const uint8_t LED_PIN = 5; // Pin Led

WiFiServer server(80); //Initialize the server on Port 80
 
OneWire ds(BROCHE_ONEWIRE); // Création de l'objet OneWire ds
 
boolean getTemperature(float *temp) // Fonction récupérant la température depuis le DS18B20
                                    // Retourne true si tout va bien, ou false en cas d'erreur
{ byte data[9], addr[8];
  // data : Données lues depuis le scratchpad
  // addr : adresse du module 1-Wire détecté
 
  if (!ds.search(addr)) { // Recherche un module 1-Wire
    ds.reset_search();    // Réinitialise la recherche de module
    return false;         // Retourne une erreur
  }
   
  if (OneWire::crc8(addr, 7) != addr[7]) // Vérifie que l'adresse a été correctement reçue
    return false;                        // Si le message est corrompu on retourne une erreur
 
  if (addr[0] != DS18B20) // Vérifie qu'il s'agit bien d'un DS18B20
    return false;         // Si ce n'est pas le cas on retourne une erreur
 
  ds.reset();             // On reset le bus 1-Wire
  ds.select(addr);        // On sélectionne le DS18B20
   
  ds.write(0x44, 1);      // On lance une prise de mesure de température
  delay(800);             // Et on attend la fin de la mesure
   
  ds.reset();             // On reset le bus 1-Wire
  ds.select(addr);        // On sélectionne le DS18B20
  ds.write(0xBE);         // On envoie une demande de lecture du scratchpad

  for (byte i = 0; i < 9; i++)  // On lit le scratchpad
    data[i] = ds.read();       // Et on stock les octets reçus
   
  
  *temp = ((data[1] << 8) | data[0]) * 0.0625;  // Calcul de la température en degré Celsius
  
  // En fait la température est dans les deux premiers octets du scratchpad (en complément à 2)
  // Le premier [0] est la température (<256) en 1/16 de degré (1/16 = 0.0625)
  // Dans le deuxième [1], on décale de 8 bits pour avoir le signe (négatif=1) 

 
  return true;  // Pas d'erreur
}

void bip() {
  
  for (int i=0; i <= 400; i++){
      digitalWrite(BUZ_PIN,HIGH);
      delayMicroseconds(400);
      digitalWrite(BUZ_PIN,LOW);
      delayMicroseconds(400);
   }  
}

void setup()
{
  pinMode(BUZ_PIN, OUTPUT);
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, LOW);
  
  WiFi.mode(WIFI_AP); //Our ESP8266-12E is an AccessPoint
  WiFi.softAP("SSID", "PASSWORD");
  // A priori stocké définitivement en eeprom

  server.begin(); // Start the HTTP Server (192.168.4.1)

  IPAddress HTTPS_ServerIP = WiFi.softAPIP();
  Serial.begin(115200);
  Serial.println(" ");
  Serial.print("Server IP is: ");
  Serial.println(HTTPS_ServerIP);

  bip();  // Indiquer qu'on est connecté en WiFi
}

void loop() {

    float temp;
    char buf[5];
   
  if(getTemperature(&temp)) // Lit la température ambiante à ~1Hz
  {
    Serial.print("Temperature "); // Affiche la température
    Serial.println(temp);
    dtostrf(temp,5,1,buf);  // Convertir en chaine de caractère
  }

  WiFiClient client = server.available();
  if (!client) {
   return;
  }

  Serial.println("Somebody has connected :-)"); // Indiquer une connexion

  bip();
  
  String request = client.readString();
  Serial.println(request);

  String Subrequest = request.substring(0, 18); // Trimmed to just the first 17 char.

  if (Subrequest.indexOf("/TMP") != -1) // Test for /TEMP substring
  {
    Serial.println("Bouton TEMPERATURE");
    digitalWrite(LED_PIN, LOW);
    if(getTemperature(&temp)) // Lit la température
      {
      Serial.print("Temperature "); // Affiche la température
      Serial.println(temp);
      dtostrf(temp,5,1,buf);  // Convertir en chaine de caractère
      }
   }
   else if (Subrequest.indexOf("/LED") != -1) // Test for /LED substring
   {
    Serial.println("Bouton Allumer LED");
    digitalWrite(LED_PIN, HIGH);
    }

    // Code HTML du serveur 
    String s = "HTTP/1.1 200 OK\r\n";
    s += "Content-Type:  text/html\r\n\r\n";
    s += "<!DOCTYPE HTML>\r\n<html>\r\n";
    s += "<head>\r\n";
    s += "<style>\r\n";
    s += "h1{white-space: pre-wrap;}\r\n";
    s += "</style>";
    s += "</head>";
    s += "<body>";

    s += "<br><h1>TEMPERATURE MESUREE:   ";
    s += buf;
    s += "</h1><br><br>";
    s += "<br><input style=\"font-size:300%;\" type=\"button\" name=\"b1\"";
    s += "value=\" TEMPERATURE \" onclick=\"location.href='/TMP'\">";
    s += "<br><br><br>";
    s += "<br><input style=\"font-size:300%;\" type=\"button\" name=\"b1\"";
    s += "value=\"     LED     \" onclick=\"location.href='/LED'\">";

    s += "</body>";
    s += "</html>\n";
    
  client.flush();   //clear stream
  client.print(s);  //send response (html code)
  delay(1);
  Serial.println("Client disconnected");

}

Sur un téléphone portable ou un PC on peut se connecter sur le réseau wifi de l'ESP (192.168.4.1).

Avec un logiciel de type OSC ou Blynk on pourrait aussi créer sur ce portable une application qui envoie ou reçoit des données en mode de communication série (UDP?).

En tout cas, l'ESP se comporte comme un (petit) Arduino, avec une fonction Wifi intégrée !

Problème : le SSID et la PSK sont conservés en EEProm de manière définitive (l'adresse Mac aussi mais c'est normal!) et on ne peut plus les changer, même si on change le sketch (pas trouvé comment contourner malgré des recherches sur internet et des analyses mémoire - bug ?)


Tests plus complets

Les premiers tests n'étant pas complets et suite au problème de programmation du SSID, l'idée est de charger un autre type d'application qu'un sketch Arduino en espérant que cela efface la mémoire.
Il s'agit de l'application NodeMcu, qui permet de programmer en Lua (genre de langage C), à priori en mode interactif sur le port série de L'ESP.

Pour télécharger il faut un programme de téléchargement sur le port série.

Installer sur le PC (/usr/local/esptool) le programme python de téléchargement esptool :

https://github.com/themadinventor/esptool

Dans le répertoire de esptool :

> sudo python esptool.py --port /dev/ttyUSB0 write_flash 0x00000 nodemcu_integer_0.9.6-dev_20150704.bin

Au redémarrage de l'ESP, le SSID est ESP-XXXXXX et il n'y a pas de PSK.

XXXXXX sont les 6 derniers caractères de l'adresse Mac, ce qui est sympa si on a plusieurs ESP en service (les 6 premiers caractères sont propres au constructeur).

Même si on recharge après un firmware Arduino ce SSID ne change pas (il doit être bien caché!).

Note : esptool permet aussi de communiquer avec l'ESP (read_mac, erase_flash, etc...)

Pas essayé de programmer en Lua, bien que ce ne soit pas bien difficile vu la ressemblance

Finalement, il faut de la persévérance pour approfondir le côté firmware et trouver ce très bon site qui explique bien comment se retrouver dans la jungle dans ce domaine et aussi pour aussi avoir le fimware des commandes AT qui n'a jamais marché sur aucun module mais qui pourrait servir....

http://www.allaboutcircuits.com/projects/update-the-firmware-in-your-esp8266-wi-fi-module/

Les informations importantes :

Il y a un site du constructeur (Espressif) du processeur de l'ESP8266 qui ne s'occupe pas de l'intégration sur des circuits imprimés (modules), ni de leur vente, ni de leur programmation.

Par contre il propose les firmware standard de ses modules ESP8266 avec les règles de paramétrage et d'implantation en mémoire flash, un outil de téléchargement très complet qui respecte ces règles, un forum, etc....

http://espressif.com/

Autant dire qu'il est la référence fondamentale et que les vendeurs (Chinois) qui font l'intégration des ESP font ce qu'ils veulent (et parfois n'importe quoi !) .

Il y a aussi d'autres développeurs de firmware (comme Node-MCU) et d'autres forums plus ou moins utiles ou clairs.

Il importe donc d'avoir la patience de suivre cette piste, en anglais..... mais c'est mieux qu'en chinois

D'abord installer le programme Espressif Flash Download Tool(V2.3). C'est une interface graphique assez performante.

Il y a deux versions : une pour Windows (.exe), une pour les « autres » en Python.

Pas réussi à installer la version Python en Linux (Ubuntu 14.04), trop complexe et trop de dépendances non résolues.

A creuser plus tard, ce n'est pas la première fois qu'Ubuntu est à la traîne dans ce domaine.

Installé la version Windows sur un vieux PC (en XP) qui sert d'oscillosope, d'analyseur de signaux et pour ce genre de choses.

La première chose intéressante est d'analyser le module ESP.

Brancher le montage utilisé pour le téléchargement Arduino sur une liaison USB.

Se mettre en mode Load (voir plus haut, les deux boutons Load et Reset)

Il faut avoir installé le driver du convertisseur USB/Série (FTDI ou autre) et noté le port Com utilisé.

Lancer et paramétrer l'outil : port Com, vitesse 115200. Une fenêtre de log s'affiche en plus de la fenêtre graphique.

Surtout ne cocher aucune case sous le titre Download Path Config, ce n'est pas le moment !

Start : on doit avoir un voyant vert SYNC et on obtient plein d'informations sur le module :

- Vendeur (s'il est rempli!)

- Flash device id

- Taille mémoire flash (en bits, pas bytes)

- Vitesse horloge (pas du processeur)

- Et les adresses MAC en mode Acces Point (AP) et Station (STA)

Là, c'est la surprise, les 6 premiers caractères de l'adresse MAC ne correspond pas aux essais précédents. ?????

Maintenant il faut passer au téléchargement du dernier firmware et surtout, comprendre l'organisation de la mémoire:

Bien savoir ce qu'on charge et dans quelle partie de la mémoire (vérifier 3 fois, c'est dangereux!)

Donc lectures attentives, en anglais, de l'article cité et des documentations Espressif : Download tool et System Developpement Kit (firmwares).

Générer les .bin pour le module 16 pins cité :

Exécuter \esp_iot_sdk_v1.5.2\app\gen_misc.bat (génération des bin SDK)

1 ->1 (V2 loader)

2 ->2 (user2.bin)

3 ->2 (40Mhz)

4 ->0 (default)

5 ->2 (1024 KB)

Lancer le download Tool et se mettre en mode load:

esp_init_data_default.bin\esp_iot_sdk_v1.5.2\bin\ esp_init_data_default.bin----->0xFC000

blank.bin\esp_iot_sdk_v1.5.2\bin\blank.bin----->0xFE000

boot.bin\esp_iot_sdk_v1.5.2\bin\ boot.bin----->0x00000

user1.bin (commandes AT)\esp_iot_sdk_v1.5.2\bin\at\512+512\user1.1024.new.2.bin----->0x01000

Vérifier que les 4 cases sont bonnes et bien cochées.

Start

Tout marche bien, on a tous les logiciels voulus (Arduino, AT, Lua)

Suite plus tard.....

Liens divers