[SOLUCIONADO] Problema con millis()

Buenas tardes, soy nuevo en el foro y de antemano os quiero agradecer vuestro tiempo y ayuda.

A partir del trabajo de otro forero, he creado un sketch para controlar una persiana con 6 comandos muy simples (via web):

Arriba
Arriba off
Abajo
Abajo off
Arriba todo
Abajo todo

La placa es una wemos D1 (Arduino UNO con wifi integrada), no adjunto las librerías porque son las conocidas ESP8266WiFi.h

El error se produce al enviar el comando abajotodo y/o arribatodo, que debería activar el relé durante 3 segundos y luego desactivarlo. La primera vez que se lanza el comando despues de cargar el sketch, suele hacerlo bien (pero no siempre), en cambio, las siguientes veces que lanzas el comando, se activa el relé pero ya no se desactiva a los 3 segundos hasta que se reinicia el arduino.

He puesto flags en el código para comprobar el valor de las variables, pareciendo siempre correcto, pero el caso es que a veces se ejecutan correctamente las acciones y a veces no.

Resumiendo: los comandos Arriba, Arriba off, Abajo y Abajo off, siempre se ejecutan correctamente, el problema es exclusivo de Arriba todo y Abajo todo.

Adjunto el código por si alguien puede echarle un ojo y ve algo que se me haya pasado.

/*  Listado de comandos
 *  http://192.168.1.227/gpio/abajoon
 *  http://192.168.1.227/gpio/abajooff
 *  http://192.168.1.227/gpio/arribaon
 *  http://192.168.1.227/gpio/arribaoff
 *  http://192.168.1.227/gpio/arribatodo
 *  http://192.168.1.227/gpio/abajotodo
 */

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

const char* ssid     = "WLAN_FB94";
const char* password = "pitch";

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

byte persiana = 0;
byte subiendo = 0;
byte bajando = 0;

const byte rele1 = 0;   //arriba
const byte rele2 = 12;  //abajo

unsigned long periodo_bajada = 3000; 
unsigned long periodo_subida = 3000;

unsigned long startMillis_bajada; 
unsigned long startMillis_subida;  
unsigned long currentMillis_bajando;
unsigned long currentMillis_subiendo;

String req;

WiFiServer server(80);

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

  pinMode(rele1, OUTPUT);
  pinMode(rele2, OUTPUT);
  digitalWrite(rele1, LOW);
  digitalWrite(rele2, LOW);
  pinMode(4,INPUT);
  
  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: 80");
  Serial.println();
 
  ArduinoOTA.begin();
  server.begin();
  Serial.println("Server started");
  Serial.println(WiFi.localIP());
}

void loop() {
  
  WiFiClient client = server.available();
  if (client) {
    while (client.connected()) {
      
      if (client.available()) {
        char c = client.read();
       
        if (req.length() < 100) {
          req += c;
          Serial.print(c);
        }

        
        if (c == '\n') {
                     
          if (req.indexOf('?') >=0) { 
              Serial.println("HTTP/1.1 204 192.168.1.127");
              Serial.println();
              Serial.println(); 
            }
          else {
              String s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n";
              Serial.println(s);
              client.print(s);
              client.stop();
              Serial.println("Client disonnected");

              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("/arribatodo") != -1) 
                  persiana = 6;
                  
              req = "";

          }
        }
      }
    }
  }
   
   switch(persiana) {
    
      case 1: // arribaon
              digitalWrite(rele2, LOW);
              digitalWrite(rele1, HIGH);
              Serial.println("Subiendo");              
              break;
              
      case 2: // arribaoff
              digitalWrite(rele1, LOW);
              Serial.println("Arriba Stop");              
              break;
              
      case 3: // abajoon
              digitalWrite(rele1, LOW);
              digitalWrite(rele2, HIGH);              
              Serial.println("Bajando");              
              break;
              
      case 4: // abajooff
              digitalWrite(rele2, LOW);
              Serial.println("Abajo Stop");
              break;

      case 5: // abajotodo    
              digitalWrite(rele1, LOW);
              digitalWrite(rele2, HIGH);
              Serial.println("Bajando todo");
              startMillis_bajada = millis();
              bajando = 1;
              break;

      case 6: // arribatodo
              digitalWrite(rele2, LOW);
              digitalWrite(rele1, HIGH);
              Serial.println("Subiendo todo");
              startMillis_subida = millis();
              subiendo = 1;
              break;
  }
  persiana = 0;

              //maniobras subir y bajar todo

              if (bajando == 1){
                
                  currentMillis_bajando = millis();                     

                if (currentMillis_bajando - startMillis_bajada >= periodo_bajada) {
                  digitalWrite(rele2, LOW);
                  bajando = 0;                  
                  Serial.println("TIEMPO!");
                  }
                }

              if (subiendo == 1){
                
                  currentMillis_subiendo = millis();
                                            
                if (currentMillis_subiendo - startMillis_subida >= periodo_subida) {
                  digitalWrite(rele1, LOW); 
                  subiendo = 0;
                  Serial.println("TIEMPO!!");                    
                  }
                }
}

Un saludo y muchísimas gracias por vuestra ayuda.

No logro encontrar ningún error en tu código.

Al poner http://192.168.1.227/gpio/arribatodo obtienes los mensajes por consola:

  • Subiendo todo
  • TIEMPO!!

Aquí tienes un ejemplo donde delay() SI que te solucionaría la vida,

En todo caso te falta lo que te marco con <--------------------

void loop() {
  
  WiFiClient client = server.available();
  if (client) {
    while (client.connected()) {
      
      if (client.available()) {
        char c = client.read();
       
        if (req.length() < 100) {
          req += c;
          Serial.print(c);
        }

        
        if (c == '\n') {
                     
          if (req.indexOf('?') >=0) { 
              Serial.println("HTTP/1.1 204 192.168.1.127");
              Serial.println();
              Serial.println(); 
            }
          else {
              String s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n";
              Serial.println(s);
              client.print(s);
              client.stop();
              Serial.println("Client disonnected");

              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("/arribatodo") != -1) 
                  persiana = 6;
                  
              req = "";

          }
        }
      }
    }
  }
   
   switch(persiana) {
    
      case 1: // arribaon
              digitalWrite(rele2, LOW);
              digitalWrite(rele1, HIGH);
              Serial.println("Subiendo");              
              break;
              
      case 2: // arribaoff
              digitalWrite(rele1, LOW);
              Serial.println("Arriba Stop");              
              break;
              
      case 3: // abajoon
              digitalWrite(rele1, LOW);
              digitalWrite(rele2, HIGH);              
              Serial.println("Bajando");              
              break;
              
      case 4: // abajooff
              digitalWrite(rele2, LOW);
              Serial.println("Abajo Stop");
              break;

      case 5: // abajotodo    
              digitalWrite(rele1, LOW);
              digitalWrite(rele2, HIGH);
              Serial.println("Bajando todo");
              startMillis_bajada = millis();
             subiendo=0;     <--------------------------------------
              bajando = 1;
              break;

      case 6: // arribatodo
              digitalWrite(rele2, LOW);
              digitalWrite(rele1, HIGH);
              Serial.println("Subiendo todo");
              startMillis_subida = millis();
              bajando=0;     <-----------------------------
              subiendo = 1;
              break;
  }
  persiana = 0;

              //maniobras subir y bajar todo

              if (bajando == 1){
                
                  currentMillis_bajando = millis();                     

                if (currentMillis_bajando - startMillis_bajada >= periodo_bajada) {
                  digitalWrite(rele2, LOW);
                  bajando = 0;                  
                  Serial.println("TIEMPO!");
                  }
                }

              if (subiendo == 1){
                
                  currentMillis_subiendo = millis();
                                            
                if (currentMillis_subiendo - startMillis_subida >= periodo_subida) {
                  digitalWrite(rele1, LOW); 
                  subiendo = 0;
                  Serial.println("TIEMPO!!");                    
                  }
                }
}

Hola a todos y gracias por vuestros comentarios, parece ser un error ocasionado por la propia placa ya que he sustituido la misma por un Arduino UNO con shield ethernet y con el codigo adaptado al interfaz cableado todo va como la seda. Pediré un WiFi shield para UNO y probaré de nuevo.

Un saludo!