Código persiana y millis

Buenas tardes, estoy intentando depurar el código para controlar una persiana por android (web) a través de dos relés, con órdenes de subir, bajar mientras se pulsa el botón de la aplicación del móvil, y subir y bajar toda de una, que tarda 40seg en subir o bajar completamente. En éstas últimas tuve problemas, puesto que con un delay de tanto tiempo se reiniciaba la placa, con lo cual tuve que estudiar como funcionaba el tema de los millis, hice varias pruebas hasta que lo conseguí, pero al controlar por web, si no deshabilito la función siguiente función, lo para de bajar o subir.

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

 // Serial.print("IP:");
 // Serial.println(ip);
 // Serial.println("new client");
 // while(!client.available()){
 //  delay(1);
 // }

El problema ahora es que tarda mucho desde que pulso el botón en la aplicación hasta que reacciona, varios segundos…

A ver si tenéis alguna idea de como modificarlo para que funcione al 100%?

Os dejo el código:

#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>


const char* ssid = "***";
const char* password = "*********";
IPAddress ip(192,168,1,227);
IPAddress gateway(192,168,1,1);
IPAddress subnet(255,255,255,0);
const int rele1 = 13;
const int rele2 = 12; 
int val1 = 0; 
int val2 = 0; 
int periodo = 40000;  
byte temp = 0; 
unsigned long tiempoAnterior = 0;  
int periodo2 = 40000;  
byte temp2 = 0; 
unsigned long tiempoAnterior2 = 0;  


WiFiServer server(1088);

void setup() {
 
 
 Serial.begin(115200);
 delay(10);
 pinMode(rele1, OUTPUT);
 pinMode(rele2, OUTPUT);
 digitalWrite(rele1, HIGH);
 digitalWrite(rele2, HIGH);
 pinMode(4,INPUT);
 
 WiFi.begin(ssid, password);
 WiFi.config(ip, gateway, subnet);

 ArduinoOTA.setPassword((const char *)"****");
 Serial.println();
 Serial.println();
 Serial.print("Conectado a ");
 Serial.println(ssid);
 Serial.print("IP:");
 Serial.println(ip);
 Serial.printf("MAC Address = %s\n", WiFi.softAPmacAddress().c_str());
 Serial.print("Puerto: 1088");
 Serial.println();
 Serial.print("Ordenes: arriba/abajo");
 Serial.println();
 Serial.print("Ordenes: arribatodo/abajotodo");
 Serial.println();
 
 ArduinoOTA.begin();
 server.begin(); 
 }

void loop() {
ArduinoOTA.handle();
ESP.wdtDisable();


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

 // Serial.print("IP:");
 // Serial.println(ip);
 // Serial.println("new client");
 // while(!client.available()){
 //  delay(1);
 // }
 

 String request = client.readStringUntil('\r');
 client.flush();
 client.println("HTTP/1.1 200 OK");
 client.println("Content-Type: text/html");
 client.println("");
 
   int val1 = digitalRead(rele1);
 if (request.indexOf("/arribaon") != -1)  {
   digitalWrite(rele1, LOW);
   digitalWrite(rele2,HIGH);
   Serial.println("Subiendo");
   temp = 0;
   temp2 = 0;
  }
  if (request.indexOf("/arribaoff") != -1)  {
   digitalWrite(rele1, HIGH);
   Serial.println(".");
  }
  
 int val2 = digitalRead(rele2);
 if (request.indexOf("/abajoon") != -1)  {
   digitalWrite(rele2, LOW);
   digitalWrite(rele1,HIGH);
   Serial.println("Bajando");
   temp = 0;
   temp2 = 0;
  }
 if (request.indexOf("/abajooff") != -1)  {
   digitalWrite(rele2, HIGH);
   Serial.println("Stop");
  }
  
  if (request.indexOf("/abajotodo") != -1)  { 
      tiempoAnterior=millis();  
      temp =1;
      digitalWrite(rele2,LOW);  
      digitalWrite(rele1,HIGH);
      Serial.println("Bajando persiana");
      }
      
  if((millis()>tiempoAnterior+periodo)&&temp==1){  
      digitalWrite(rele2,HIGH); 
            temp = 0; 
      Serial.println("Persiana completamente bajada");
      }
      
  if (request.indexOf("/tiempo") != -1)  {
      Serial.println(millis());
      Serial.println(tiempoAnterior);
      }
       if (request.indexOf("/arribatodo") != -1)  { 
      tiempoAnterior2=millis();  
      temp2 =1;
      digitalWrite(rele1,LOW); 
      digitalWrite(rele2,HIGH);
      Serial.println("Subiendo persiana");
      }
      
  if((millis()>tiempoAnterior2+periodo2)&&temp2==1){  
      digitalWrite(rele1,HIGH);  
      temp2 = 0;  
      Serial.println("Persiana completamente subida");
      }
      
        
}

Te olvidaste de mencionar que frameword Android estas usando: blink ?

DJuan:
El problema ahora es que tarda mucho desde que pulso el botón en la aplicación hasta que reacciona, varios segundos…

Dices que tarda mucho, pero supongo que lo logra finalmente verdad ?

He verificado tu código y encontré algunas discrepancias.
Yo empecé de 0 y esto funciona bien

/*
 *  This sketch demonstrates how to set up a simple HTTP-like server.
 *  The server will set a GPIO pin depending on the request
 *    http://server_ip/gpio/0 will set the GPIO2 low,
 *    http://server_ip/gpio/1 will set the GPIO2 high
 *  server_ip is the IP address of the ESP8266 module, will be 
 *  printed to Serial when the module is connected.
 */

#include <ESP8266WiFi.h>
#include <ArduinoOTA.h>


const char* ssid     = "Surbyte";
const char* password = "password";

IPAddress ip(192,168,1,227);
IPAddress gateway(192,168,1,1);
IPAddress subnet(255,255,255,0);

const int rele1 = 13;
const int rele2 = 12; 
int val, val1 = 0, val2 = 0; 
int periodo = 40000;  
byte temp = 0; 
unsigned long tiempoAnterior = 0;  
int periodo2 = 40000;  
byte temp2 = 0; 
unsigned long tiempoAnterior2 = 0;  


// Create an instance of the server
// specify the port to listen on as an argument
WiFiServer server(1088);

void setup() {
  Serial.begin(115200);
  delay(10);

  // prepare GPIO2
  pinMode(2, OUTPUT);
  digitalWrite(2, 0);
  pinMode(rele1, OUTPUT);
  pinMode(rele2, OUTPUT);
  digitalWrite(rele1, HIGH);
  digitalWrite(rele2, HIGH);
  pinMode(4,INPUT);
  
  // Connect to WiFi network
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  WiFi.config(ip, gateway, subnet);
  
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  ArduinoOTA.setPassword((const char *)"1234");
  Serial.println();
  Serial.println();
  Serial.print("Conectado a ");
  Serial.println(ssid);
  Serial.print("IP:");
  Serial.println(ip);
  Serial.printf("MAC Address = %s\n", WiFi.softAPmacAddress().c_str());
  Serial.print("Puerto: 1088");
  Serial.println();
  Serial.print("Ordenes: arriba/abajo");
  Serial.println();
  Serial.print("Ordenes: arribatodo/abajotodo");
  Serial.println();
 
  ArduinoOTA.begin();
  // Start the server
  server.begin();
  Serial.println("Server started");

  // Print the IP address
  Serial.println(WiFi.localIP());
}

void loop() {
  // Check if a client has connected
  WiFiClient client = server.available();
  if (!client) {
    return;
  }
  
  // Wait until the client sends some data
  Serial.println("new client");
  while(!client.available()){
    delay(1);
  }
  
  // Read the first line of the request
  String req = client.readStringUntil('\r');
  Serial.println(req);
  client.flush();
  
  // Match the request
  int val1 = digitalRead(rele1);
  if (req.indexOf("/arribaon") != -1)  {
      digitalWrite(rele1, LOW);
      digitalWrite(rele2,HIGH);
      Serial.println("Subiendo");
      temp = 0;
      temp2 = 0;
  } 
  if (req.indexOf("/arribaoff") != -1)  {
      digitalWrite(rele1, HIGH);
      Serial.println(".");
  }
  
  int val2 = digitalRead(rele2);
  if (req.indexOf("/abajoon") != -1)  {
      digitalWrite(rele2, LOW);
      digitalWrite(rele1,HIGH);
      Serial.println("Bajando");
      temp = 0;
      temp2 = 0;
  }
  if (req.indexOf("/abajooff") != -1)  {
      digitalWrite(rele2, HIGH);
      Serial.println("Stop");
  }

  if (req.indexOf("/abajotodo") != -1)  { 
      tiempoAnterior=millis();  
      temp =1;
      digitalWrite(rele2,LOW);  
      digitalWrite(rele1,HIGH);
      Serial.println("Bajando persiana");
  }

  if ((millis()>tiempoAnterior+periodo)&&temp==1){  
      digitalWrite(rele2,HIGH); 
      temp = 0; 
      Serial.println("Persiana completamente bajada");
  }

  if (req.indexOf("/tiempo") != -1)  {
      Serial.println(millis());
      Serial.println(tiempoAnterior);
  }
  if (req.indexOf("/arribatodo") != -1)  { 
      tiempoAnterior2 = millis();  
      temp2 = 1;
      digitalWrite(rele1,LOW); 
      digitalWrite(rele2,HIGH);
      Serial.println("Subiendo persiana");
  }

  if ((millis()>tiempoAnterior2+periodo2)&&temp2==1){  
      digitalWrite(rele1,HIGH);  
      temp2 = 0;  
      Serial.println("Persiana completamente subida");
  }

  // Set GPIO2 according to the request
  val = val1;
  digitalWrite(2, val1);

  // Prepare the response
  String s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n";
  s += "<html><p>GPIO is now :";
  s += (val)?"high":"low";
  s += "</p>";
  s += "<p>Rele 1      :"; 
  s += digitalRead(rele1)?"OFF":"ON";
  s += "</p>";
  s += "<p>Rele 2      :"; 
  s += digitalRead(rele2)?"OFF":"ON";
  s += "</p></html>";

  // Send the response to the client
  client.print(s);
  delay(1);
  Serial.println("Client disonnected");

  // The client will actually be disconnected 
  // when the function returns and 'client' object is detroyed
}

Kike_GL:
Te olvidaste de mencionar que frameword Android estas usando: blink ?

Dices que tarda mucho, pero supongo que lo logra finalmente verdad ?

Utilizo una aplicación hecha por mi con app inventor, y si, funciona perfectamente, pero con retraso.

surbyte:
He verificado tu código y encontré algunas discrepancias.
Yo empecé de 0 y esto funciona bien

Gracias surbyte, en cuanto pueda lo pruebo y te digo, pero crees que sabes cuál es el problema? Quiero entenderlo bien para poder aprender.

Los problemas son que las funciones que te señalé requieren parámetros.
Si las pones () te da error, debe ir algún factor numérico para cada caso.
Ve a la librería y estudia que necesitas poner en cada situación.

surbyte, ocurre el mismo problema que ocurría con el mío, cuando le das a "bajartodo" o "subirtodo", empieza a bajar o subir, y cuando pasan los segundos que le tenemos programado, hasta que no vuelves a enviarle una petición por web, no "despierta" y entonces desconecta el relé, por eso tuve que anular esta parte del código:

// if (!client) {
 //  return;
 // }

 // Serial.print("IP:");
 // Serial.println(ip);
 // Serial.println("new client");
 // while(!client.available()){
 //  delay(1);
 // }

Tu código no funcionaba al menos con mi compilador.
El mio responde a cada comando y con velocidad.

Ahora lo que tu planteas es un problema de tu programación. Yo eso no lo he visto. Porque al intentar ver tu programa me daba errores y al superarlos no respondia a las peticiones.
Cuando logré que todo funcione fue lo que te postee.

Veré lo que comentas.

O sea que acá esta tu problema

if (req.indexOf("/abajotodo") != -1)  { 
      tiempoAnterior=millis();  
      temp =1;
      digitalWrite(rele2,LOW);  
      digitalWrite(rele1,HIGH);
      Serial.println("Bajando persiana");
  }

  if ((millis()>tiempoAnterior+periodo)&&temp==1){  
      digitalWrite(rele2,HIGH); 
      temp = 0; 
      Serial.println("Persiana completamente bajada");
  }

  if (req.indexOf("/tiempo") != -1)  {
      Serial.println(millis());
      Serial.println(tiempoAnterior);
  }
  if (req.indexOf("/arribatodo") != -1)  { 
      tiempoAnterior2 = millis();  
      temp2 = 1;
      digitalWrite(rele1,LOW); 
      digitalWrite(rele2,HIGH);
      Serial.println("Subiendo persiana");
  }

  if ((millis()>tiempoAnterior2+periodo2)&&temp2==1){  
      digitalWrite(rele1,HIGH);  
      temp2 = 0;  
      Serial.println("Persiana completamente subida");
  }

Dices que sin quitar lo que tu comentastes eso desconecta el relé1 o 2 según corresponda.
No lo comprendo por ahora.

Ya veo que esto es el problema.. se queda esperando aca sin hacer nada

// Wait until the client sends some data
  Serial.println("new client");
  while(!client.available()){
    delay(1);
  }

surbyte:
Ya veo que esto es el problema.. se queda esperando aca sin hacer nada

// Wait until the client sends some data

Serial.println("new client");
  while(!client.available()){
    delay(1);
  }

Si, ahí está el problema, todo lo demás me funciona perfectamente.

Sugiero que mires este hilo en como se resolvió esa parte

Codigo Persiana y millis()

Esta es la versión donde mezclo tu código y el que te indiqué.

Finalmente era como te dije. No puedes esperar a que las cosas se hagan dentro de las peticiones http
Usa eso para dar órdenes a tu sistema y luego que éste procese lo que deba

Esta es la versión mezclada

/*
 *  This sketch demonstrates how to set up a simple HTTP-like server.
 *  The server will set a GPIO pin depending on the request
 *    http://server_ip/gpio/0 will set the GPIO2 low,
 *    http://server_ip/gpio/1 will set the GPIO2 high
 *  server_ip is the IP address of the ESP8266 module, will be 
 *  printed to Serial when the module is connected.
 */

#include <ESP8266WiFi.h>
#include <ArduinoOTA.h>


const char* ssid     = "Surbyte";
const char* password = "ricardohns493";

IPAddress ip(192,168,1,227);
IPAddress gateway(192,168,1,1);
IPAddress subnet(255,255,255,0);

const int rele1 = 13;
const int rele2 = 12; 
int val, val1 = 0, val2 = 0; 
int periodo = 40000;  
byte temp = 0; 
unsigned long tiempoAnterior = 0;  
int periodo2 = 40000;  
byte temp2 = 0; 
unsigned long tiempoAnterior2, start;
String req;
byte persiana = 0;
// Create an instance of the server
// specify the port to listen on as an argument
WiFiServer server(1088);

void setup() {
  Serial.begin(115200);
  delay(10);

  // prepare GPIO2
  pinMode(2, OUTPUT);
  digitalWrite(2, 0);
  pinMode(rele1, OUTPUT);
  pinMode(rele2, OUTPUT);
  digitalWrite(rele1, HIGH);
  digitalWrite(rele2, HIGH);
  pinMode(4,INPUT);
  
  // Connect to WiFi network
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  WiFi.config(ip, gateway, subnet);
  
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  ArduinoOTA.setPassword((const char *)"1234");
  Serial.println();
  Serial.println();
  Serial.print("Conectado a ");
  Serial.println(ssid);
  Serial.print("IP:");
  Serial.println(ip);
  Serial.printf("MAC Address = %s\n", WiFi.softAPmacAddress().c_str());
  Serial.print("Puerto: 1088");
  Serial.println();
  Serial.print("Ordenes: arriba/abajo");
  Serial.println();
  Serial.print("Ordenes: arribatodo/abajotodo");
  Serial.println();
 
  ArduinoOTA.begin();
  // Start the server
  server.begin();
  Serial.println("Server started");

  // Print the IP address
  Serial.println(WiFi.localIP());
}

void loop() {
  
  WiFiClient client = server.available();
  if (client) {
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();

        //read char by char HTTP request
        if (req.length() < 100) {

          //store characters to string
          req += c;
          Serial.print(c);
        }

        //if HTTP request has ended
        if (c == '\n') {
            //now output HTML data header
            if (req.indexOf('?') >=0) { //don't send new page
                client.println("HTTP/1.1 204 192.168.1.127");
                client.println();
                client.println(); 
            }
            else {
              String s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n";
              s += "<html><p>GPIO is now :";
              s += (val)?"high":"low";
              s += "</p>";
              s += "<p>Rele 1      :"; 
              s += digitalRead(rele1)?"OFF":"ON";
              s += "</p>";
              s += "<p>Rele 2      :"; 
              s += digitalRead(rele2)?"OFF":"ON";
              s += "</p></html>";

              // Send the response to the client
              client.print(s);
              
              //stopping client
              client.stop();
              Serial.println("Client disonnected");
  
              // Match the request
              if (req.indexOf("/arribaon") != -1) 
                  persiana = 1;
            
              if (req.indexOf("/arribaoff") != -1)
                  persiana = 2;
              
              if (req.indexOf("/abajoon") != -1)  
                  persiana = 3;

              if (req.indexOf("/abajooff") != -1)  
                  persiana = 4;

              if (req.indexOf("/abajotodo") != -1)  
                  persiana = 5;
  
              if (req.indexOf("/tiempo") != -1)  
                  persiana = 6;

              if (req.indexOf("/arribatodo") != -1) 
                  persiana = 7;
              req = "";

            }
        } // if (c == '\n') {
      } // if (client.available()) {
    } // while
  } // The client will actually be disconnected 
  
  // Match the request
  int val1 = digitalRead(rele1);
  int val2 = digitalRead(rele2);
  switch(persiana) {
      case 1: // arribaon
              digitalWrite(rele1, LOW);
              digitalWrite(rele2,HIGH);
              Presentar("Subiendo");
              temp = 0;
              temp2 = 0;
              break;
      case 2: // arribaoff
              digitalWrite(rele1, HIGH);
              Presentar("Arriba Stop");
              break;
      case 3: // abajoon
              digitalWrite(rele2, LOW);
              digitalWrite(rele1,HIGH);
              Presentar("Bajando");
              temp = 0;
              temp2 = 0;
              break;
      case 4: // abajooff
              digitalWrite(rele2, HIGH);
              Presentar("Abajo Stop");
              break;
      case 5: // abajotodo    
              tiempoAnterior = millis();  
              temp = 1;
              digitalWrite(rele2,LOW);  
              digitalWrite(rele1,HIGH);
              Presentar("Bajando persiana");
              break;
      case 6: // tiempo
              if (millis()-start > 500UL) {
                  Serial.println(millis());
                  Serial.println(tiempoAnterior);
                  start = millis();
              }
              break;
      case 7: // arribatodo
              tiempoAnterior2 = millis();  
              temp2 = 1;
              digitalWrite(rele1,LOW); 
              digitalWrite(rele2,HIGH);
              Presentar("Subiendo persiana");
              break;
  }

  if ((millis()>tiempoAnterior+periodo)   && temp==1){  
      digitalWrite(rele2,HIGH); 
      temp = 0; 
      Presentar("Persiana completamente bajada");
  }
  if ((millis()>tiempoAnterior2+periodo2) && temp2==1) {  
      digitalWrite(rele1,HIGH);  
      temp2 = 0;  
      Presentar("Persiana completamente subida");
  }

  // Set GPIO2 according to the request
  //val = val1;
  //digitalWrite(2, val1);
}

void Presentar(const char* str) {
     static byte persianaAnt;
     if (persiana != persianaAnt)  {
         Serial.println(str);
         persianaAnt = persiana;
     }
}

Puede necesitar ajustes pero menores.

Muchas gracias surbyte, cuando tenga tiempo lo pruebo.

Nada surbyte, el mismo problema, no ejecuta la acción cuando trascurre el tiempo estipulado desde que se ejecuta “bajartodo” o “subirtodo” hasta que no recibe una orden del cliente.

Y cual es la accion que debe ejecutar.. tu hablas como si nosotros entendieramos tu código a la perfección.
Ahora las funciones estan fuera del código html y de un cliente asi que si no las cumple es porque algo no esta bien.

Presentar("Persiana completamente bajada");
Presentar("Persiana completamente subida");

estos dos comandos se cumple o no?

Se mas específico con que comandos envías, envias este comando, esperas tanto tiempo y debería ocurrir tal cosa.

Hola de nuevo, ejecuto esto:

if (req.indexOf("/abajotodo") != -1)  { 
      tiempoAnterior=millis();  
      temp =1;
      digitalWrite(rele2,LOW);  
      digitalWrite(rele1,HIGH);
      Serial.println("Bajando persiana");
  }

Y hace su función, empieza a bajar la persiana, pero al pasar los 40000 milisegundos no ejecuta esta otra acción:

if ((millis()>tiempoAnterior+periodo)&&temp==1){  
      digitalWrite(rele2,HIGH); 
      temp = 0; 
      Serial.println("Persiana completamente bajada");
  }

Se queda esperando cliente para ejecutarla.

En el código que yo te dí (ver post#8) o en el tuyo?

Ese ejemplo es del mío, pero con el tuyo pasa lo mismo.

No es posible yo lo vi con mis limitaciones y funcionaba
De hecho esta fuera del control del cliente asi que no me puedes decir que no se cumple. Cuando se activan temp1 y temp2 los tiempos funcionan.

Te dije que no podía funcionar mal, pero claro funciona mal y por qué?

Porque asi definiste los periodos

unsigned long tiempoAnterior = 0;  
int periodo = 40000;                    // <== MAL DEFINIDO
byte temp = 0; 
unsigned long tiempoAnterior2 = 0;  
int periodo2 = 40000;                 // <== MAL DEFINIDO

Deben ser siempre unsigned long para periodo y periodo2.

Había otro leve error que era mas importante que este… este lo arrastrabas de tu código y luego del switch debemos poner la variable persina = 0 para evitar que repita la secuencia.
En el caso de /arribatodo volvia a cargar millis() en la variable tiempoAnterior

Persiana.ino (6.91 KB)

Genial surbyte, ahora funciona de maravilla, llevo poco tiempo en esto y aún me queda mucho por aprender.

Muchísimas gracias compañero.

Bueno basicamente recuerda que controlar algo y que funcione no puede quedar supeditado al elemento con el que interactuas. Sea serial, un socket, I2C o lo que fuere.

Comunicación por un lado, control por otro, presentación en un lugar diferente.

Todos las preguntas del foro tienen siempre algun elemento de estos equivocado.
En tu caso todo ocurría por pretender controlar y esperar los comandos al mismo tiempo o mejor dicho dentro de las mismas condiciones, algo que esta claro no corresponde.