Je suis sur un projet de gestion de clignotement d'une guirlande led 5v, j'ai repris un code existant et je l'ai modifier pour mes besoins.
Pour l'instant je teste juste sur la led interne d'esp01.
Mais je ne comprend pas pourquoi dans ma boucle void loop mes tests :
if (request.indexOf("/Mode=0") != -1)
et
if (request.indexOf("/Mode=1") != -1)
ne sont pas testé à chaque tour de boucle.
Il n'y a que quand ma page web s'actualise avec un mode (0 ou1) différent que les tests sont utilisé, et je ne comprends pas pourquoi.
Voici mon code :
#include <ESP8266WiFi.h>
#include <ConnexParams.h>
// WiFi Router Login - change these to your router settings
// Setup GPIO2
int pinGPIO2 = 2; //To control LED
int downLed = 1000; //Temps de led non allumé
int upLed = 1000; //Temps de led allumé
int modeClignotement = 0; //Selection du mode de clignotement 0=pas de clignotement
// Create the ESP Web Server on port 80
WiFiServer WebServer(80);
// Web Client
WiFiClient client;
void setup() {
Serial.begin(115200);
delay(10);
Serial.println();
Serial.println();
Serial.println(codeVersion);
// Setup the GPIO2 LED Pin - this demo also uses PWM to dim the LED.
pinMode(pinGPIO2, OUTPUT);
digitalWrite(pinGPIO2, LOW);
// Connect to WiFi network
Serial.println();
WiFi.disconnect();
WiFi.mode(WIFI_STA);
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("Connected to WiFi");
// Start the Web Server
WebServer.begin();
Serial.println("Web Server started");
// Print the IP address
Serial.print("You can connect to the ESP8266 at this URL: ");
Serial.print("http://");
Serial.print(WiFi.localIP());
Serial.println("/");
}
void loop() {
// Check if a user has connected
client = WebServer.available();
// Read the first line of the request
String request = client.readStringUntil('\r\n');
Serial.println(request);
client.flush();
// Process the request:
if (request.indexOf("/Mode=0") != -1) {
analogWrite(pinGPIO2, LOW);
analogWrite(pinGPIO2, HIGH);
modeClignotement = 0;
Serial.println("mode0");
}
if (request.indexOf("/Mode=1") != -1) {
//downLed = 1000;
//upLed = 1000;
analogWrite(pinGPIO2, 1023);
delay (upLed);
analogWrite(pinGPIO2, 0);
delay (downLed);
modeClignotement = 1;
Serial.println("mode1");
}
Serial.println(modeClignotement);
// Return the response
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html; charset=UTF-8");
client.println("");
client.println("<!DOCTYPE HTML>");
client.println("<html>");
client.println("<head>");
client.println("<title>ESP8266 Demo</title>");
client.println("</head>");
client.println("<body>");
client.println("<a href=\"/\">Refresh Status</a>");
client.println("</br></br>");
//Serial.println(modeClignotement);
if (modeClignotement == 0) {
client.print("Pas de clignotement</br>");
client.println("Choisir clignotement <a href=\"/Mode=1\">1</a></br>");
Serial.println("mode0a");
} else if (modeClignotement == 1) {
client.print("Clignotement</br>");
client.println("Choisir pas de clignotement <a href=\"/Mode=0\">0</a></br>");
Serial.println("mode1a");
}
client.println("</br>");
client.println("</body>");
client.println("</html>");
}
C'est assez étrange que tes conditions te donne vrai uniquement lorsque pour toi elles sont fausse.
Le soucis, c'est que l'on a que ta version ou ce que tu pense avoir.
Il faudrait que tu nous donne la sortie série dans un premier temps.
il faut mettre des guillemets quand il y a plusieurs caractères client.readStringUntil("\r\n");
ensuite
il faudrait peut être testé si vous avez un client avant d'appeler client.readStringUntil('\r\n');
➜ if (client) { ...}
sinon votre requête sera sans doute vide (vous avez de la chance si ça ne plante) et donc les if ne passent pas..
et bien sûr si vous faites le clignotement (qui bloque le code 2 secondes) lors de la réception d'une requête ce n'est pas surprenant que ça ne clignote que quand vous mettez à jour la page web...
il faut séparer la gestion de la requête du clignotement
dans le if (client) { ...} vous mettez à jour la variable modeClignotement
et séparément, en dehors de ce if vous traitez l'état
if (modeClignotement == 0) {
...
} else {
...
}
bien sûr il faut clignoter sans utiliser delay()...
c'est typiquement une définition de programme qui se prête bien à la programmation par machine à états (cf mon tuto éventuellement)
J-M-L, je pensais avoir compris, mais après avoir modifier mon code et regarder ton tuto, je n'obtient pas de clignotement.
Pourtant je pensais avoir suivi tes recommandations.
Voici le code :
#include <ESP8266WiFi.h>
#include <ConnexParams.h>
String codeVersion = "Version 1.0 Aug 2016 by TonesB";
// WiFi Router Login - change these to your router settings
// Setup GPIO2
int pinGPIO2 = 2; //To control LED
unsigned long currentTime;
boolean clignoLed = 0; //
int modeClignotement = 0; //Selection du mode de clignotement 0=pas de clignotement
// Create the ESP Web Server on port 80
WiFiServer WebServer(80);
// Web Client
WiFiClient client;
void setup() {
Serial.begin(115200);
delay(10);
Serial.println();
Serial.println();
Serial.println(codeVersion);
// Setup the GPIO2 LED Pin - this demo also uses PWM to dim the LED.
pinMode(pinGPIO2, OUTPUT);
digitalWrite(pinGPIO2, LOW);
// Connect to WiFi network
Serial.println();
WiFi.disconnect();
WiFi.mode(WIFI_STA);
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("Connected to WiFi");
// Start the Web Server
WebServer.begin();
Serial.println("Web Server started");
// Print the IP address
Serial.print("You can connect to the ESP8266 at this URL: ");
Serial.print("http://");
Serial.print(WiFi.localIP());
Serial.println("/");
}
void loop() {
// Check if a user has connected
client = WebServer.available();
if (client) {
String request = client.readStringUntil('\r\n');
Serial.println(request);
client.flush();
// Process the request:
if (request.indexOf("/Mode=0") != -1) {
analogWrite(pinGPIO2, 0);
analogWrite(pinGPIO2, 1);
modeClignotement = 0;
Serial.println("mode0");
}
if (request.indexOf("/Mode=1") != -1) {
Serial.println("mode1");
if (millis() - currentTime > 1000)
{
currentTime = millis();
clignoLed=!clignoLed;
digitalWrite(pinGPIO2, clignoLed);
}
modeClignotement = 1;
}
}
// Read the first line of the request
Serial.println(modeClignotement);
// Return the response
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html; charset=UTF-8");
client.println("");
client.println("<!DOCTYPE HTML>");
client.println("<html>");
client.println("<head>");
client.println("<title>ESP8266 Demo</title>");
client.println("</head>");
client.println("<body>");
client.println("<a href=\"/\">Refresh Status</a>");
client.println("</br></br>");
//Serial.println(modeClignotement);
//check the LED status
if (modeClignotement == 0) {
client.print("Pas de clignotement</br>");
client.println("Choisir clignotement <a href=\"/Mode=1\">1</a></br>");
Serial.println("mode0a");
} else if (modeClignotement == 1) {
client.print("Clignotement</br>");
client.println("Choisir pas de clignotement <a href=\"/Mode=0\">0</a></br>");
Serial.println("mode1a");
}
client.println("</br>");
client.println("</body>");
client.println("</html>");
}
Code non indenté je ne peux pas voir sur mon iPhone si vous êtes dans les bons blocs
Ça doit ressembler à cela
void loop() {
// ON GERE LA REQUÊTE S’IL Y EN A UNE EN ATTENTE
client = WebServer.available();
if (client) {
// on a reçu une requête, la lire
…
// analyser le type de requête
…
// faire la réponse
…
// terminer la réponse
client.stop();
}
// ===================================
// ON GERE LE CLIGNOTEMENT SI NÉCESSAIRE
if (modeClignotement == 0) {
…
}
else if (modeClignotement == 1) {
…
} else {
…
}
}
Avec un peu plus d'analyse et de réflexion c'est bon merci !
Quand aux ", terwal, si je les mets ça me met une erreur, et comme cela fonctionne avec les ', j'ai laissé comme ça.
Voici le code :
#include <ESP8266WiFi.h>
#include <ConnexParams.h>
String codeVersion = "Version 1.0 Aug 2016 by TonesB";
// WiFi Router Login - change these to your router settings
// Setup GPIO2
int pinGPIO2 = 2; //To control LED
unsigned long currentTime;
boolean clignoLed = 0; //
int modeClignotement = 0; //Selection du mode de clignotement 0=pas de clignotement
// Create the ESP Web Server on port 80
WiFiServer WebServer(80);
// Web Client
WiFiClient client;
void setup() {
Serial.begin(115200);
delay(10);
Serial.println();
Serial.println();
Serial.println(codeVersion);
// Setup the GPIO2 LED Pin - this demo also uses PWM to dim the LED.
pinMode(pinGPIO2, OUTPUT);
digitalWrite(pinGPIO2, LOW);
// Connect to WiFi network
Serial.println();
WiFi.disconnect();
WiFi.mode(WIFI_STA);
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("Connected to WiFi");
// Start the Web Server
WebServer.begin();
Serial.println("Web Server started");
// Print the IP address
Serial.print("You can connect to the ESP8266 at this URL: ");
Serial.print("http://");
Serial.print(WiFi.localIP());
Serial.println("/");
}
void loop() {
// Check if a user has connected
client = WebServer.available();
if (client) {
String request = client.readStringUntil('\r\n');
Serial.println(request);
client.flush();
// Process the request:
if (request.indexOf("/Mode=0") != -1) {
modeClignotement = 0;
Serial.println("mode0");
}
if (request.indexOf("/Mode=1") != -1) {
Serial.println("mode1");
modeClignotement = 1;
}
}
// Read the first line of the request
Serial.println(modeClignotement);
// Return the response
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html; charset=UTF-8");
client.println("");
client.println("<!DOCTYPE HTML>");
client.println("<html>");
client.println("<head>");
client.println("<title>ESP8266 Demo</title>");
client.println("</head>");
client.println("<body>");
client.println("<a href=\"/\">Refresh Status</a>");
client.println("</br></br>");
//Serial.println(modeClignotement);
//check the LED status
if (modeClignotement == 0) {
analogWrite(pinGPIO2, 0);
analogWrite(pinGPIO2, 1);
client.print("Pas de clignotement</br>");
client.println("Choisir clignotement <a href=\"/Mode=1\">1</a></br>");
Serial.println("mode0a");
} else if (modeClignotement == 1) {
if (millis() - currentTime > 1000)
{
currentTime = millis();
clignoLed=!clignoLed;
digitalWrite(pinGPIO2, clignoLed);
}
client.print("Clignotement</br>");
client.println("Choisir pas de clignotement <a href=\"/Mode=0\">0</a></br>");
Serial.println("mode1a");
}
client.println("</br>");
client.println("</body>");
client.println("</html>");
}
readStringUntil() n'accepte qu'un seul caractère comme terminateur. Donc il faut écrire String request = client.readStringUntil('\r');
Les ' ' servent à délimiter 1 caractère.
les " " servent à délimiter une chaine de caractères.
Lorsque tu écris ça: String request = client.readStringUntil('\r\n'); en fait seul le premier dernier caractère et pris.
ça c'est ce dont faut se souvenir pour ne pas avoir de souci
avec notre compilateur ce sera en fait le '\n' qui sera pris en compte
explication ci dessous
pour ceux qui veulent frimer lors de leur prochain dîner mondain, la raison est un peu compliquée.
Le C++ autorise de manière conditionnelle ce qu'on appelle les "Ordinary multicharacter literal", c'est à dire la possibilité de mettre plusieurs caractères entre simple quotes.
GCC le supporte, donc dans notre environnement on a le droit d'écrire 'xyz' mais il faut savoir que le type associé à un multicharacter literal est int, ce n'est plus un char et sa valeur dépend du compilateur. On est donc hors des sentiers battus.
GCC est assez brut il considère que ce que vous fournissez c'est le remplissage des octets de cet int donc si vous êtes sur une plate-forme 8 bits où les int sont sur 2 octets, pour fabriquer cet entier il va conserver les 2 derniers octets de la chaine de caractère, et si vous êtes sur une plateforme 32 bits où les int sont sur 4 octets, pour fabriquer cet entier il va conserver les 4 derniers octets de la chaine de caractère,
pour vous en convaincre, essayez ce code sur UNO et ESP32
void setup() {
Serial.begin(115200);
// LES CODES ASCII DE 123456 sont 0x31 0x32 0x33 0x34 0x35 0x36
Serial.println('123456', HEX); // 3536 sur MCU 8 bits et 33343536 sur MCU 32 bits (taille d'un int)
char d = '123456'; // ici le fait d'allouer dans un char va tronquer à l'octet de poids faible
Serial.println(d, HEX); // affichage en HEXA donc on voit 36 (le code ASCII de 6, le dernier caractère)
Serial.println(d); // affichage du caractère ASCII donc on voit 6
}
void loop() {}