TransWikia.com

3 input (on/off/off with delay) to control 1device using ESP8266 as Web Server

Arduino Asked by hamidreza hosseine on September 25, 2021

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);

}
}

One Answer

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.)

Answered by Duncan C on September 25, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP