1

I want to control one device in three ways : turn on / turn off / turn off with delay. To do that i use an ESP8266 web server + android phone app. The problem is that turn off with delay wont work. It works with delay() but i dont want to use delay() as it stops other functions. I would be grateful if you could help me. here is my code :

#include <ESP8266WiFi.h>       
const int device1 = 14;
unsigned long previousMillis = 0;
const long interval = 5000;
const char* ssid     = "****";         
const char* password = "****";     
#include <Arduino.h>
WiFiServer server(80);
String data = "";

void setup() {
 pinMode(device1, OUTPUT);
Serial.begin(115200, SERIAL_8N1, SERIAL_TX_ONLY);
WiFi.begin(ssid, password);
IPAddress ip(*,*,*,*);   
IPAddress gateway(*,*,*,*);   
IPAddress subnet(*,*,*,*);   
WiFi.config(ip, gateway, subnet);
 while (WiFi.status() != WL_CONNECTED) {
   delay(500);
   Serial.print(".");
 }
 Serial.println("");
 Serial.println("WiFi connected");
 
 server.begin();

 Serial.println(WiFi.localIP());
 }

void loop() {
    unsigned long currentMillis = millis();

  WiFiClient client = server.available();
 if (!client) {
   return;
 }
 
 while(!client.available()){
 }
 
 String req = client.readStringUntil('\r');
 client.flush();
 if (req.indexOf("/on") != -1)
   { digitalWrite(device1, HIGH);}
 if (req.indexOf("/off") != -1)
   { digitalWrite(device1, LOW);}

 if (req.indexOf("/delay") != -1)
 {
  unsigned long currentMillis = millis();
  unsigned long previousMillis = millis();
if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;

   
    digitalWrite(device1, LOW);

}
}
1
  • separate out the command decoding and the resulting action .... reception of /on should set a flag ... reception of /off and /delay should clear the flag and set turnoff time ... the device control is done after the if statements have completed – jsotola Jun 20 '20 at 16:24
0

You have various logic problems:

You block until WiFiClient has bytes available. Everything comes to a stop. So if you send a "/delay" command, it will receive and parse that command, turn on the device, then block again, indefinitely, until you send another command. Once you send another command, it will check the interval ONCE, and then lock up again. You need to rewrite your loop to check for bytes, read them if found, and do other work (like checking your time interval) if no bytes are available.

Next, your timing code is a mess. You only ever set currentMillis and previousMillis at the same time, so they will never be different. And you only ever check the times once when you first detect a "/delay" command.

Instead, refactor your logic. Only set previousMillis when you first detect the delay command, and then only compare if previousMillis to currentMillis if previousMillis is not 0:

if (req.indexOf("/delay") != -1)
{
    previousMillis = millis();
}

if (previousMillis != 0 && millis() - previousMillis >= interval) {
    digitalWrite(device1, LOW);
    previousMillis = 0;
}

(Also note that you were declaring a second, independent variable previousMillis inside your if statement, which only exists inside the curly braces for that if statement. Don't do that. Use the existing global variable you defined, as I show in my edited code.)

2
  • Good point. Fixed. – Duncan C Jun 20 '20 at 17:30
  • 1
    its not working. im confused.could anyone write the whole sketch in correct way for me please – hamidreza hosseine Jun 25 '20 at 10:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.