ESP01 Contrôle des diodes WS2812 à l’aide de l’IDE Arduino-Part2


Niveau:3

Introduction:

Dans ce chapitre, nous allons modifier le programme pour ajouter quelques options supplémentaires. Par exemple sauvegarde de la configuration des paramètres WIFI, de l’état du bandeau LED et des informations sur l’esp01 via la liaison série.

Sauvegarde des paramètres du bandeau LED:

Pour la sauvegarde des paramètres du bandeau LED, nous allons utiliser la bibliothèque permettant de lire et écrire dans l’EEPROM. Pour cela, ajouter en début de programme l’instruction suivante: #include <EEPROM.h>

Dans la partie  » setup » du programme, nous allons réserver une zone pour la sauvegarde dans EEPROM d’une taille de 512Bytes via l’instruction :EEPROM.begin(512);

Nous allons définir les adresses de départ de la zone mémoire pour la sauvegarde des paramètres du bandeau LED via l’instruction :

#define ADRESS_LED_LUM 0 // Adresse pour le stokage dans EEPROM de la Luminosité
#define ADRESS_LED_MOD 1 // Adresse pour le stockage dans EEPROM du Mode
#define ADRESS_LED_VIT 2 // Adresse pour le stockage dans EEPROM de la vitesse sur 2 mots (2 et 3)
#define ADRESS_LED_COL 4 // Adresse pour le stockage dans EEPROM de la couleur sur 4 mots (4 à 7)

Lors de l’initialisation du programme, nous chargerons les valeurs de l’EEPROM dans les variables du bandeau LED:

 ws2812fx.setBrightness(EEPROM.read(ADRESS_LED_LUM)); // Lecture valeur Mémoire luminosité 
 ws2812fx.setSpeed(EEPROMReadlong(ADRESS_LED_VIT,2)); // Lecture valeur Mémoire vitesse
 ws2812fx.setMode(EEPROM.read(ADRESS_LED_MOD)); // Lecture valeur Mémoire mode
 ws2812fx.setColor(EEPROMReadlong(ADRESS_LED_COL,4)); // Lecture valeur Mémoire couleur

Pour la lecture de la couleur, qui est sur quatre mots, nous allons utiliser un sous programme de lecture/écriture sur 4 Bytes et pour la vitesse 2 Bytes

/*Fonction pour ecrire dans l'EEPROM des valeurs en 32 bits (4 mots) ou 16 bits (2 mots)
* nbit=2 en 16 bits nbit=4 en 32 bits
*/
void EEPROMWritelong(int address, long value,int nbit) 
 {
 //Decomposition from a long to 4 bytes by using bitshift.
 //One = Most significant -> Four = Least significant byte
 byte four = (value & 0xFF);
 byte three = ((value >> 8) & 0xFF);
 byte two = ((value >> 16) & 0xFF);
 byte one = ((value >> 24) & 0xFF);

//Write the 4 bytes into the eeprom memory.
 EEPROM.write(address, four);
 EEPROM.write(address + 1, three);
 if (nbit==4){
 EEPROM.write(address + 2, two);
 EEPROM.write(address + 3, one); 
 }

EEPROM.commit();
 }

/*Fonction pour lire dans l'EEPROM des valeurs en 32 bits (4 mots) ou 16 bits (2 mots)
 * nbit=2 en 16 bits nbit=4 en 32 bits
*/
long EEPROMReadlong(long address,int nbit) 
 {
 //Read the 4 bytes from the eeprom memory.
 long four = EEPROM.read(address);
 long three = EEPROM.read(address + 1);
 long two = EEPROM.read(address + 2);
 long one = EEPROM.read(address + 3);

//Return the recomposed long by using bitshift.
 if (nbit==4) return long((four << 0) & 0xFF) + ((three << 8) & 0xFFFF) + ((two << 16) & 0xFFFFFF) + ((one << 24) & 0xFFFFFFFF);
 if (nbit==2) return uint16_t(((four << 0) & 0xFF) + ((three << 8) & 0xFFFF)); 
 }

Le sous-programme sera placé hors du programme loop et setup.

Nous allons insérer les sauvegardes dans l’EEPROM lors d’un changement de couleur,vitesse et luminosité.

void srv_handle_set() {
 for (uint8_t i=0; i < server.args(); i++){
 if(server.argName(i) == "c") {
 uint32_t tmp = (uint32_t) strtol(&server.arg(i)[0], NULL, 16);
 if(tmp >= 0x000000 && tmp <= 0xFFFFFF) {
 ws2812fx.setColor(tmp);
 EEPROMWritelong(ADRESS_LED_COL,tmp,4); // Sauvegarde de la couleur
 EEPROM.commit();
 }
 }

if(server.argName(i) == "m") {
 uint8_t tmp = (uint8_t) strtol(&server.arg(i)[0], NULL, 10);
 ws2812fx.setMode(tmp % ws2812fx.getModeCount());
 Serial.print("mode is "); Serial.println(ws2812fx.getModeName(ws2812fx.getMode()));
 EEPROM.write(ADRESS_LED_MOD,ws2812fx.getMode()); // Sauvegarde du mode 
 EEPROM.commit();
 }

if(server.argName(i) == "b") {
 if(server.arg(i)[0] == '-') {
 ws2812fx.setBrightness(max((int)(ws2812fx.getBrightness() * 0.8), 5));
 } else {
 ws2812fx.setBrightness(min((int)(ws2812fx.getBrightness() * 1.2), 255));
 }
 Serial.print("brightness is "); Serial.println(ws2812fx.getBrightness());
 EEPROM.write(ADRESS_LED_LUM,ws2812fx.getBrightness()); // Sauvegarde de la luminosité
 EEPROM.commit();
 }

if(server.argName(i) == "s") {
 if(server.arg(i)[0] == '-') {
 ws2812fx.setSpeed(ws2812fx.getSpeed() * 0.8);
 } else {
 ws2812fx.setSpeed(ws2812fx.getSpeed() * 1.2);
 }
 Serial.print("speed is "); Serial.println(ws2812fx.getSpeed());
 EEPROMWritelong(ADRESS_LED_VIT,ws2812fx.getSpeed(),2); // Sauvegarde de la vitesse
 EEPROM.commit();
 }

if(server.argName(i) == "a") {
 if(server.arg(i)[0] == '-') {
 auto_cycle = false;
 } else {
 auto_cycle = true;
 auto_last_change = 0;
 }
 }
 }
 server.send(200, "text/plain", "OK");
}

Et supprimer les lignes suivantes du programme:

#define DEFAULT_COLOR 0xFF5900
#define DEFAULT_BRIGHTNESS 255
#define DEFAULT_SPEED 1000
#define DEFAULT_MODE FX_MODE_STATIC
 ws2812fx.setMode(DEFAULT_MODE);
 ws2812fx.setColor(DEFAULT_COLOR);
 ws2812fx.setSpeed(DEFAULT_SPEED);
 ws2812fx.setBrightness(DEFAULT_BRIGHTNESS);*/

Voici le programme modifié esp8266_webinterface_1.1.0.zip

Charger le programme, et vérifier que les paramètres sont bien enregistrés après un reset ou une coupure électrique.

Configuration du réseau via le port série et sauvegarde:

Nous allons créer la possibilité de configurer les paramètres réseau depuis la liaison série de l’ESP01. Bien sur cette modification sera effectuée depuis la version précédente ci -dessus.

Les paramètres seront: Le mot de passe du réseau WIFI, le SSID du réseau, et l’adresse IP fixe ou DHCP. Pour les paramètres WIFI nous allons utiliser 96 mots et 6 mots pour les paramètres réseau( Pas de configuration du masque réseau car 255,255,255,0 et adresse IP commencera par l’IP de la passerelle).

Paramètres WIFI:

Définition des Adresses mémoire dans EEPROM:

#define ADRESS_WIFI 8 // Adresse de départ paramètres WIFI Mot de passe et SSID (Fin ADRESS_WIFI + 96 mots)8-103
#define ADRESS_RESEAU 104 // Adresse de départ paramètres Reseau DHCP=0 Fixe=1, IP passerelle,Fin IP statique (Fin ADRESS_RESEAU + 6 mots)104-109

Création du sous programme pour l’écriture/lecture des paramètres WIFI.

// Effacement de la zone mémoire avant écriture
void EffaceWifiEeprom() {
 for (int i =ADRESS_WIFI ; i < ADRESS_WIFI + 96; ++i) {
 EEPROM.write(i, 0);
 }
 EEPROM.commit();
}

// Ecriture des paramètres WIFI
void EcitureWifiEeprom(String ssid,String password) {
 EffaceWifiEeprom();
 //Ecriture du SSID Max 32 caractères
 for (int i = 0; i < ssid.length(); ++i)
 {
 EEPROM.write(i + ADRESS_WIFI, ssid[i]);
 }
 //Ecriture du mot de passe Max 64 caractères
 for (int i = 0; i < password.length(); ++i)
 {
 EEPROM.write(32 + ADRESS_WIFI + i, password[i]);
 }
 EEPROM.commit();
}

// Lecture des paramètres WIFI si a=1 => SSID si a=2 => mot de passe
String LectureWifiEeprom(int a)
{
 // Lecture du SSID 
 String ssid = "";
 for (int i = 0; i < 32; ++i)
 {
 ssid += char(EEPROM.read(i+ADRESS_WIFI));
 }
 // Lecture du mot de passe
 String password = "";
 for (int i = 32; i < 96; ++i)
 {
 password += char(EEPROM.read(i + ADRESS_WIFI));
 } 
 EEPROM.commit();
 if (a==1) return String(ssid);
 if (a==2) return String(password);
}

Lecture des paramètres WIFI.

Ajouter les lignes ci dessous après void wifi_setup() {

 WIFI_SSID=(LectureWifiEeprom(1));
 WIFI_PASSWORD=(LectureWifiEeprom(2));

Et supprimer les lignes ci dessous dans le programme.

#define WIFI_SSID "YOURSSID"
#define WIFI_PASSWORD "YOURPASSWORD"

Déclarer les variables globales.

String WIFI_SSID;
String WIFI_PASSWORD;

Dans le sous-programme loop, ajout de la fonction paramétrage du WIFI depuis la liaison série. Pour entrer en mode paramétrage du WIFI : taper wifi.

// Lecture port série
String valeur; // Déclaration de la variable
while(Serial.available()) {

valeur= Serial.readString();// Lecture des données sur la liaison série
if (valeur=="wifi"){
 Serial.println("Modification des paramètres wifi");

Serial.println("Entrer le SSID du wifi: "); //Information de la saisie 
 while (Serial.available()==0) { //Attendre la saisie
 }
 WIFI_SSID=Serial.readString(); //Lecture et enregistrement dans la variable
 Serial.println("Entrer le mot de passe du wifi: "); //Information de la saisie
 while (Serial.available()==0) { //Attendre la saisie
 }
 WIFI_PASSWORD=Serial.readString(); //Lecture et enregistrement dans la variable
 EcitureWifiEeprom(WIFI_SSID,WIFI_PASSWORD);
 Serial.println("Vérification des paramètres de sauvegarde: "); //Information
 Serial.println(LectureWifiEeprom(1));
 Serial.println(LectureWifiEeprom(2));
 ESP.reset(); // Rest du module ESP01
}
}

Ajouter le code ci dessus dans le sous programme loop après unsigned long now = millis();

Dans le sous programme loop modifier les lignes ci dessous. Traduction en français et suppression du setup.wifi.

 if(now - last_wifi_check_time > WIFI_TIMEOUT) {
 Serial.print("Vérification du WiFi... ");
 if(WiFi.status() != WL_CONNECTED) {
 Serial.println("Erreur de connexion WIFI ...");
 Serial.println("Taper wifi pour modifier les paramètres du WIFI");
 } else {
 Serial.println("OK");
 }
 last_wifi_check_time = now;
 }

Puis pour finir modifier le sous programme wifi_setup() comme ci dessous.

if(millis() - connect_start > WIFI_TIMEOUT) {
 Serial.println();
 Serial.print("Erreur de connexion WIFI. Vérifier vos paramètres WIFI");
 Serial.print(WIFI_TIMEOUT);
 return;
 }
 }

Serial.println("");
 Serial.println("WiFi est connecté"); 
 Serial.print("Addresse IP: ");
 Serial.println(WiFi.localIP());
 Serial.println();
}

Et remplacer la ligne

WiFi.begin(WIFI_SSID, WIFI_PASSWORD);

par

WiFi.begin(WIFI_SSID.c_str(), WIFI_PASSWORD.c_str());

Maintenant vous pouvez compiler et transférer le programme pour faire un test.

Voici le programme modifié esp8266_webinterface_1.2.0.zip

Paramètres réseau:

Voici le principe de fonctionnement du programme de sauvegarde des paramètres réseau, nous allons sauvegarder la passerelle, la fin de l’adresse IP et laisser le masque réseau à 255.255.225.0. Le premier octet sera la sauvegarde du mode de l’adresse IP DHCP=0 IP FIXE=1.

Suppression du #define STATIC_IP qui permettait de choisir IP statique ou DHCP.

//#define STATIC_IP // uncomment for static IP, set IP below
#ifdef STATIC_IP
 IPAddress ip(192,168,0,123);
 IPAddress gateway(192,168,0,1);
 IPAddress subnet(255,255,255,0);
#endif

Création du programme de conversion de l’adresse IP en chaîne de caractère (String) en entier (int).

// conversion IP chaine en en valeur numérique
int IPnum(String valeur,int a){
 int str_len = valeur.length() + 1; 
 char *str="255.255.255.255";

valeur.toCharArray(str, str_len); // Transfert chaîne dans tableau de caractère
 unsigned char value[4] = {0};
 size_t index = 0;
 while (*str) {
 if (isdigit((unsigned char)*str)) {
 value[index] *= 10;
 value[index] += *str - '0';
 } else {
 index++;
 }
 str++;
 }
 return int(value[a]);
}

Ajout de la saisie de la configuration et sauvegarde dans EEPROM après l’instruction  EcitureWifiEeprom(WIFI_SSID,WIFI_PASSWORD); 

Serial.println("DHCP=0 ou IP FIXE=1?: "); //Information de la saisie
 while (Serial.available()==0) { //Attendre la saisie
 }
 valeur=Serial.readString(); //Lecture et enregistrement dans la variable
 if (valeur=="0") {
 EEPROM.write(ADRESS_RESEAU,0); // DHCP valeur à 0
 }
 else
 {
 EEPROM.write(ADRESS_RESEAU,1); // IP statique à 1
 Serial.println("Adresse de la passerelle: "); //Information de la saisie
 while (Serial.available()==0) { //Attendre la saisie
 }
 valeur=Serial.readString(); //Lecture et enregistrement dans la variable 
 for (int i = 0; i <4; ++i)
 {
 EEPROM.write(i + ADRESS_RESEAU +1, IPnum(valeur,i));
 }
 Serial.println("IP Statique : "); //Information de la saisie
 while (Serial.available()==0) { //Attendre la saisie
 }
 valeur=Serial.readString(); //Lecture et enregistrement dans la variable 
 EEPROM.write(ADRESS_RESEAU +5, valeur.toInt());

}
EEPROM.commit();

Modification du sous programme wifi_setup en lieu et place de:

 #ifdef STATIC_IP 
 WiFi.config(ip, gateway, subnet);
 #endif

Remplacer par:

if (EEPROM.read(ADRESS_RESEAU)==1){
 IPAddress ip(EEPROM.read(ADRESS_RESEAU+1),EEPROM.read(ADRESS_RESEAU+2),EEPROM.read(ADRESS_RESEAU+3),EEPROM.read(ADRESS_RESEAU+5));
 IPAddress gateway(EEPROM.read(ADRESS_RESEAU+1),EEPROM.read(ADRESS_RESEAU+2),EEPROM.read(ADRESS_RESEAU+3),EEPROM.read(ADRESS_RESEAU+4));
 IPAddress subnet(255,255,255,0);
 WiFi.config(ip, gateway,gateway, subnet); //WiFi.config(ip, dns, gateway, subnet) dns=gateway
 }

Voila les grandes lignes de cette version 1.2.1. J’ai commencé à effectuer une traduction en français du texte. Bien sur, je n’ai pas effectuer de contrôle des valeurs de saisie, qui doivent être cohérente.

Voici le programme modifié esp8266_webinterface_1.2.1.zip

Le programme en image depuis la console:

Taper wifi dans la console.

Entrer les paramètres du réseau. Pour l’adresse IP statique ne taper que la fin de l’adresse IP.

 

Si vous avez entrer les mauvais paramètres attendre le redémarrage et le dépassement de connexion au réseau.

Information sur ESP01:

Nous allons afficher via la liaison série des informations sur l’ESP01, fréquence, mémoire libre, tension, version… Pour cela ajouter le code ci dessous dans le sous programme void setup(). Et ajouter en début de programme ADC_MODE(ADC_VCC); // utilisation de ESP.getVcc.

 Serial.println("**** Information ESP01 ****"); 
 Serial.print("Taille segment libre: "); Serial.print(ESP.getFreeHeap());Serial.println(" Octets");
 Serial.print("Version boot: "); Serial.println(ESP.getBootVersion());
 Serial.print("CPU: ");Serial.print(ESP.getCpuFreqMHz());Serial.println(" Mhz");
 Serial.print("Version SDK: "); Serial.println(ESP.getSdkVersion());
 Serial.print("ID de la puce: "); Serial.println(ESP.getChipId());
 Serial.print("ID de EEPROM: "); Serial.println(ESP.getFlashChipId());
 Serial.print("Taille de EEPROM: "); Serial.print(ESP.getFlashChipRealSize());Serial.println(" Octets");
 Serial.print("Alimentation Vcc: "); Serial.print((float)ESP.getVcc()/1024.0);Serial.println(" V");

Voici les informations affichées sur la liaison série.

Voici le programme modifié esp8266_webinterface_1.2.2.zip