Problema al querer iniciar en el paso 0

Buenas, como va? Mi problema es el siguiente:
Mientras se ejecuta la funcion ejecutarSecuenciaReles(), si inicio el modo de control desde el cliente remoto (es para testear cada electrovalvula) y luego ejecuto el comando "continuar riego" deberia volver a la ejecucion del loop principal, pero el problema es que inicia donde la funcion fue interrumpida y yo necesito que reinicie desde el paso 0. IntentΓ© cambiar el valor de la variable "static unsigned long tiempoInicioPaso = 0;" pero no tuvo efecto.

#include <ESP8266WiFi.h>
int contactor = 5;
int sensor_d = 16;
int sensor_a = A0;
int led = 15;
int bomba_p = 2;
int trafo = 14;
int valvL = 12; 
int valvC = 13;
int valvR = 0;

//Ajuste de Reles
const int RON = 0;
const int ROFF = 1;

unsigned long secuenciaStartTime = 0;
unsigned long delayTime = 0;
int estadoSecuencia = 0; 

const int grupoValv[] = {0, 12, 13, 14}; 

const int numValves = 3;
int valvePins[numValves] = {12, 13, 0};
int activeValve = -1;

bool modoTesteo = false;
bool salida = false;


const char *ssid = "ESP8266"; 
const char *password = "juan1234"; 
WiFiServer server(80);
WiFiClient client;

String command = "";
String message;
unsigned long tiempoInicioLED = 0; 
bool estadoLED = LOW;  

unsigned long tiempoInicio;
unsigned long tiempoActual;
unsigned long tiempoCliente;

static int paso = 0; 
static unsigned long tiempoInicioPaso = 0;  

void setup() {
  Serial.begin(115200);
  pinMode(trafo, OUTPUT);
  pinMode(valvL, OUTPUT);
  pinMode(valvC, OUTPUT);
  pinMode(valvR, OUTPUT);
  pinMode(contactor, OUTPUT);
  pinMode(sensor_d, OUTPUT);
  pinMode(led, OUTPUT);
  pinMode(LED_BUILTIN, OUTPUT);
  
  digitalWrite(trafo, ROFF);
  digitalWrite(valvL, ROFF);
  digitalWrite(valvC, ROFF);
  digitalWrite(valvR, ROFF);
  digitalWrite(contactor, LOW);
  digitalWrite(led, HIGH);
  digitalWrite(LED_BUILTIN, LOW);


  for (int i = 0; i < 5; i++) {
    digitalWrite(led, HIGH);
    delay(250);
    digitalWrite(led, LOW);
    delay(1000);
  }

  digitalWrite(led, HIGH);

  for (int i = 0; i < numValves; i++) {
    pinMode(valvePins[i], OUTPUT);
    digitalWrite(valvePins[i], ROFF);
  }

  
  WiFi.softAP(ssid, password);
  IPAddress IP = WiFi.softAPIP();
  delay(4000);
  Serial.print("IP Address: ");
  Serial.println(IP);

  server.begin();
  delay(10000);

  Serial.println("Esperando instrucciones...");
  tiempoInicio = millis();
  tiempoCliente = millis();

  while (millis() - tiempoInicio < 10000) { 
    if (Serial.available() > 0) { 
      String mensaje = Serial.readStringUntil('\n');
      if (mensaje.equals("inicio testeo")) { 
        ejecutarModoTesteo();
        break;
      }
    }
  }

}

void loop() {
  if (!client.connected()) {
    client = server.available();
  }
  if (client.connected() && client.available() > 0) {
    String command = client.readStringUntil('\n');
    command.trim();
    message = "Comando Recibido:  " + String(command);
    print(message);      
    if (command.equals("Control")) {
      interacc_client();     
      goto salida1;
      }
    }
  while (Serial.available() > 0) {
    String input = Serial.readStringUntil('\n');
    if (input.equals("inicio testeo")) {
      modoTesteo = true;
      ejecutarModoTesteo();
      }
    }

  salida1:
  if (salida == true){
  static int paso = 0; 
  static int tiempoInicioPaso = 0;

  const unsigned long tiemposEspera[] = {1000, 500, 5000, 2000, 5000, 2000, 5000, 1000};
  unsigned long tiempoActual = millis(); 
  message = "Variables reestablecidas";
  tiempoInicio = millis();
  while (millis() - tiempoInicio < 500) {}
  ejecutarSecuenciaReles();
  }
}


void interacc_client(){
    message = "-------------->CONTROL<-------------";
    print(message);
    tiempoInicio = millis();
    while (millis() - tiempoInicio < 500) {}
    message = "inicio testeo";
    print(message);
    message = "continuar riego";
    print(message);
  
    digitalWrite(contactor, LOW);
    tiempoInicio = millis();
    while (millis() - tiempoInicio < 500) {}    
    desact_grupo();

    tiempoInicio = millis();
    while (millis() - tiempoInicio < 500) {}
    
    while (client.connected()) {
      if (client.available()) {
        String command = client.readStringUntil('\n');
        command.trim();
        message = "Comando Recibido:  " + String(command);
        print(message);

        if (command.equals("inicio testeo")) {
          ejecutarModoTesteo();
          return;
        } 
        if (command.equals("continuar riego")) {  
            salida = true;
            delay(10);
            modoTesteo = false;     
            return;
        }
        else {
          client.println("Comando Desconocido");
        }
        if (salida == true){
          static int paso = 0;
          static int tiempoInicioPaso = 0;
          tiempoInicio = millis();
          while (millis() - tiempoInicio < 100) {} 
          message = "Yendo a Salida2";
          print(message);         
          goto salida2;
        }
      salida2:
      return;
      }
    }
}

void ejecutarModoTesteo() {
  message = "--------------Test Mode-------------";
  print(message);  
  modoTesteo = true; 
  digitalWrite(contactor, LOW);
  
  tiempoInicio = millis();
  while (millis() - tiempoInicio < 500) {}
  desact_grupo();
  digitalWrite(trafo, RON);

  message = "VΓ‘lvula L = 1";
  print(message);
  tiempoInicio = millis();
  while (millis() - tiempoInicio < 100) {}
  message = "VΓ‘lvula C = 2";
  print(message);
  tiempoInicio = millis();
  while (millis() - tiempoInicio < 100) {}
  message = "VΓ‘lvula R = 3";
  print(message);
  tiempoInicio = millis();
  while (millis() - tiempoInicio < 100) {}

  unsigned long tiempoInicioLED = millis(); 
  bool estadoLED = LOW;   
  
  while (modoTesteo) {
    tiempoActual = millis();
    while (millis() - tiempoInicio < 100) {}

    if (tiempoActual - tiempoInicioLED >= 500) {
      estadoLED = !estadoLED; 
      digitalWrite(15, estadoLED);
      tiempoInicioLED = tiempoActual; 
    }
    tiempoActual = millis();
    while (millis() - tiempoInicio < 100) {}

    if (client.available()) {
        String valveNumberStr = client.readStringUntil('\n');
        int valveNumber = valveNumberStr.toInt();
        valveNumberStr.trim();

      if (valveNumberStr.equals("Continuar Riego")) {
        modoTesteo = false;
        salida = true;
        message = "------------Fin Test Mode------------";
        print(message);
        return;
        }   

      if (valveNumber >= 1 && valveNumber <= numValves) {
        digitalWrite(trafo, RON);
        tiempoInicio = millis();
        while (millis() - tiempoInicio < 500) {}
        message = "->VΓ‘lvula " + String(valveNumber) + " ON<-";
        print(message);   
        activateValve(valveNumber);
        tiempoInicio = millis();
        while (millis() - tiempoInicio < 500) {} 
        digitalWrite(contactor, HIGH);
        }
      if (valveNumberStr.equals("fin testeo")) {
        secuencia_FnTst();
        break;
       }
    }

    if (Serial.available() > 0) {
      String valveNumberStr = Serial.readStringUntil('\n');
      int valveNumber = valveNumberStr.toInt();
      if (valveNumber >= 1 && valveNumber <= numValves) {
        digitalWrite(trafo, RON);
        tiempoInicio = millis();
        while (millis() - tiempoInicio < 500) {} // Esperar 500 milisegundos
        activateValve(valveNumber);
        message = "->VΓ‘lvula " + String(valveNumber) + " ON<-";
        print(message);           
        digitalWrite(contactor, HIGH);
      }
      if (valveNumberStr.equals("fin testeo")) {
        secuencia_FnTst();
        break;
      }
    }
  }
} 
void secuencia_FnTst() {
        message = "Apagando Bombas...";
        print(message);          
        tiempoInicio = millis();
        while (millis() - tiempoInicio < 500) {}
        digitalWrite(contactor, LOW);

        tiempoInicio = millis();
        while (millis() - tiempoInicio < 500) {}
        message = "Apagando Electrovalvulas...";
        print(message);

        tiempoInicio = millis();
        while (millis() - tiempoInicio < 500) {}            
        desact_grupo();

        message = "Aguarde 10s para reiniciar...";
        print(message);

        tiempoInicio = millis();
        while (millis() - tiempoInicio < 500) {}
        message = "------------Fin Test Mode------------";
        print(message);
        delay(10000);    
        modoTesteo = false;
        ESP.restart();
}
void config_grupo() {
  for (int i = 0; i < sizeof(grupoValv) / sizeof(grupoValv[0]); i++) {
    pinMode(grupoValv[i], OUTPUT);
  }
}
void activar_grupo() {
  for (int i = 0; i < sizeof(grupoValv) / sizeof(grupoValv[0]); i++) {
    digitalWrite(grupoValv[i], RON);
  }
}
void desact_grupo() {
  for (int i = 0; i < sizeof(grupoValv) / sizeof(grupoValv[0]); i++) {
    digitalWrite(grupoValv[i], ROFF);
  }
}
void ejecutarSecuenciaReles() {
  static unsigned long tiempoInicioPaso = 0;
  const unsigned long tiemposEspera[] = {1000, 500, 5000, 2000, 5000, 2000, 5000, 1000};
  unsigned long tiempoActual = millis(); 


  if (tiempoActual < tiempoInicioPaso) {
    paso = 0;
  }
  if (tiempoActual - tiempoInicioPaso >= tiemposEspera[paso]) {
    switch (paso) {
      case 0:
        message = "-----------Iniciando Riego----------";
        print(message);           
        desact_grupo();
        digitalWrite(trafo, RON);
        break;
      case 1:
        digitalWrite(valvL, RON);
        digitalWrite(contactor, HIGH);
        message = "->Trafo ON // VΓ‘lv. L ON // Bombas ON<-";
        print(message);            
        break;
      case 2:
        message = "->VΓ‘lv. C ON<-";
        print(message);    
        digitalWrite(valvC, RON);
        break;
      case 3:
        digitalWrite(valvL, ROFF);
        break;
      case 4:
        message = "->VΓ‘lv. R ON<-";
        print(message);        
        digitalWrite(valvR, RON);
        break;
      case 5:
        digitalWrite(valvC, ROFF);
        break;
      case 6:
        message = "->Bombas OFF<-";
        print(message);
        digitalWrite(contactor, LOW);
        break;
      case 7:
        desact_grupo();
        message = "-----------Riego Finalizado---------";
        print(message);
        digitalWrite(led, LOW);
        break;
    }
    paso++;
    tiempoInicioPaso = tiempoActual;
    if (paso > 7) {
      paso = 0;
    }
  }
}

void print(String message) {
  Serial.println(message);
  client.println(message);
  delay(10);
  message = "";
}
void activateValve(int valveNumber) {
  if (valveNumber != activeValve) {
    if (activeValve != -1) {
      digitalWrite(valvePins[valveNumber - 1], RON);
      message = "Cambiando VΓ‘lv.";
      print(message);

      client.println("Aqui");
      tiempoInicio = millis();
      while (millis() - tiempoInicio < 1000) {}

      digitalWrite(valvePins[activeValve - 1], ROFF);
      message = "->VΓ‘lv. " + String(activeValve) + " OFF<-";
      print(message);
      
      tiempoInicio = millis();
      while (millis() - tiempoInicio < 1000) {}
    }
    digitalWrite(valvePins[valveNumber - 1], RON);
    activeValve = valveNumber;
    }
}

Bueno, si a alguien le sirve, encontrΓ© la soluciΓ³n. Agregar una variable global y rastrear en que modo estaba y cambiarla al detectar el modo control y modo test. SI bien antes lo habia intentado, claramente en algΓΊn lugar metΓ­ la pata.

#include <ESP8266WiFi.h>
int contactor = 5;
int sensor_d = 16;
int sensor_a = A0;
int led = 15;
int bomba_p = 2;
int trafo = 14;
int valvL = 12; 
int valvC = 13;
int valvR = 0;

//Ajuste de Reles
const int RON = 0;
const int ROFF = 1;

unsigned long secuenciaStartTime = 0;
unsigned long delayTime = 0;
int estadoSecuencia = 0; 

const int grupoValv[] = {0, 12, 13, 14}; 

const int numValves = 3;
int valvePins[numValves] = {12, 13, 0};
int activeValve = -1;

bool modoControl = false;
bool modoTesteo = false;
bool salida = false;


const char *ssid = "ESP8266"; 
const char *password = "juan1234"; 
WiFiServer server(80);
WiFiClient client;

String command = "";
String message;
unsigned long tiempoInicioLED = 0; 
bool estadoLED = LOW;  

unsigned long tiempoInicio;
unsigned long tiempoActual;
unsigned long tiempoCliente;

static int paso = 0; 
static unsigned long tiempoInicioPaso = 0;  

void setup() {
  Serial.begin(115200);
  pinMode(trafo, OUTPUT);
  pinMode(valvL, OUTPUT);
  pinMode(valvC, OUTPUT);
  pinMode(valvR, OUTPUT);
  pinMode(contactor, OUTPUT);
  pinMode(sensor_d, OUTPUT);
  pinMode(led, OUTPUT);
  pinMode(LED_BUILTIN, OUTPUT);
  
  digitalWrite(trafo, ROFF);
  digitalWrite(valvL, ROFF);
  digitalWrite(valvC, ROFF);
  digitalWrite(valvR, ROFF);
  digitalWrite(contactor, LOW);
  digitalWrite(led, HIGH);
  digitalWrite(LED_BUILTIN, LOW);


  for (int i = 0; i < 5; i++) {
    digitalWrite(led, HIGH);
    delay(250);
    digitalWrite(led, LOW);
    delay(1000);
  }

  digitalWrite(led, HIGH);

  for (int i = 0; i < numValves; i++) {
    pinMode(valvePins[i], OUTPUT);
    digitalWrite(valvePins[i], ROFF);
  }

  
  WiFi.softAP(ssid, password);
  IPAddress IP = WiFi.softAPIP();
  delay(4000);
  Serial.print("IP Address: ");
  Serial.println(IP);

  server.begin();
  delay(10000);

  Serial.println("Esperando instrucciones...");
  tiempoInicio = millis();
  tiempoCliente = millis();

  while (millis() - tiempoInicio < 10000) { 
    if (Serial.available() > 0) { 
      String mensaje = Serial.readStringUntil('\n');
      if (mensaje.equals("inicio testeo")) { 
        ejecutarModoTesteo();
        break;
      }
    }
  }

}

void loop() {
  if (!client.connected()) {
    client = server.available();
  }
  if (client.connected() && client.available() > 0) {
    String command = client.readStringUntil('\n');
    command.trim();
    message = "Comando Recibido:  " + String(command);
    print(message);      
    if (command.equals("Control")) {
      modoControl = true;
      interacc_client(); 
      modoControl = false;
      paso = 0;
      tiempoInicioPaso = 0;  
      goto salida1;
      }
    }
  while (Serial.available() > 0) {
    String input = Serial.readStringUntil('\n');
    if (input.equals("inicio testeo")) {
      modoTesteo = true;
      ejecutarModoTesteo();
      modoTesteo = false;
      paso = 0;
      tiempoInicioPaso = 0;
      }
    }

  salida1:
  tiempoInicio = millis();
  while (millis() - tiempoInicio < 500) {}
  ejecutarSecuenciaReles();

}


void interacc_client(){
    message = "-------------->CONTROL<-------------";
    print(message);
    tiempoInicio = millis();
    while (millis() - tiempoInicio < 500) {}
    message = "inicio testeo";
    print(message);
    message = "continuar riego";
    print(message);
  
    digitalWrite(contactor, LOW);
    tiempoInicio = millis();
    while (millis() - tiempoInicio < 500) {}    
    desact_grupo();

    tiempoInicio = millis();
    while (millis() - tiempoInicio < 500) {}
    
    while (client.connected()) {
      if (client.available()) {
        String command = client.readStringUntil('\n');
        command.trim();
        message = "Comando Recibido:  " + String(command);
        print(message);

        if (command.equals("inicio testeo")) {
          ejecutarModoTesteo();
          return;
        } 
        if (command.equals("continuar riego")) {  
            salida = true;
            delay(10);
            modoTesteo = false;     
            return;
        }
        else {
          client.println("Comando Desconocido");
        }
        if (salida == true){
          static int paso = 0;
          static int tiempoInicioPaso = 0;
          tiempoInicio = millis();
          while (millis() - tiempoInicio < 100) {} 
          message = "Yendo a Salida2";
          print(message);         
          goto salida2;
        }
      salida2:
      return;
      }
    }
}

void ejecutarModoTesteo() {
  message = "--------------Test Mode-------------";
  print(message);  
  modoTesteo = true; 
  digitalWrite(contactor, LOW);
  
  tiempoInicio = millis();
  while (millis() - tiempoInicio < 500) {}
  desact_grupo();
  digitalWrite(trafo, RON);

  message = "VΓ‘lvula L = 1";
  print(message);
  tiempoInicio = millis();
  while (millis() - tiempoInicio < 100) {}
  message = "VΓ‘lvula C = 2";
  print(message);
  tiempoInicio = millis();
  while (millis() - tiempoInicio < 100) {}
  message = "VΓ‘lvula R = 3";
  print(message);
  tiempoInicio = millis();
  while (millis() - tiempoInicio < 100) {}

  unsigned long tiempoInicioLED = millis(); 
  bool estadoLED = LOW;   
  
  while (modoTesteo) {
    tiempoActual = millis();
    while (millis() - tiempoInicio < 100) {}

    if (tiempoActual - tiempoInicioLED >= 500) {
      estadoLED = !estadoLED; 
      digitalWrite(15, estadoLED);
      tiempoInicioLED = tiempoActual; 
    }
    tiempoActual = millis();
    while (millis() - tiempoInicio < 100) {}

    if (client.available()) {
        String valveNumberStr = client.readStringUntil('\n');
        int valveNumber = valveNumberStr.toInt();
        valveNumberStr.trim();

      if (valveNumberStr.equals("Continuar Riego")) {
        modoTesteo = false;
        salida = true;
        message = "------------Fin Test Mode------------";
        print(message);
        return;
        }   

      if (valveNumber >= 1 && valveNumber <= numValves) {
        digitalWrite(trafo, RON);
        tiempoInicio = millis();
        while (millis() - tiempoInicio < 500) {}
        message = "->VΓ‘lvula " + String(valveNumber) + " ON<-";
        print(message);   
        activateValve(valveNumber);
        tiempoInicio = millis();
        while (millis() - tiempoInicio < 500) {} 
        digitalWrite(contactor, HIGH);
        }
      if (valveNumberStr.equals("fin testeo")) {
        secuencia_FnTst();
        break;
       }
    }

    if (Serial.available() > 0) {
      String valveNumberStr = Serial.readStringUntil('\n');
      int valveNumber = valveNumberStr.toInt();
      if (valveNumber >= 1 && valveNumber <= numValves) {
        digitalWrite(trafo, RON);
        tiempoInicio = millis();
        while (millis() - tiempoInicio < 500) {} // Esperar 500 milisegundos
        activateValve(valveNumber);
        message = "->VΓ‘lvula " + String(valveNumber) + " ON<-";
        print(message);           
        digitalWrite(contactor, HIGH);
      }
      if (valveNumberStr.equals("fin testeo")) {
        secuencia_FnTst();
        break;
      }
    }
  }
} 
void secuencia_FnTst() {
        message = "Apagando Bombas...";
        print(message);          
        tiempoInicio = millis();
        while (millis() - tiempoInicio < 500) {}
        digitalWrite(contactor, LOW);

        tiempoInicio = millis();
        while (millis() - tiempoInicio < 500) {}
        message = "Apagando Electrovalvulas...";
        print(message);

        tiempoInicio = millis();
        while (millis() - tiempoInicio < 500) {}            
        desact_grupo();

        message = "Aguarde 10s para reiniciar...";
        print(message);

        tiempoInicio = millis();
        while (millis() - tiempoInicio < 500) {}
        message = "------------Fin Test Mode------------";
        print(message);
        delay(10000);    
        modoTesteo = false;
        ESP.restart();
}
void config_grupo() {
  for (int i = 0; i < sizeof(grupoValv) / sizeof(grupoValv[0]); i++) {
    pinMode(grupoValv[i], OUTPUT);
  }
}
void activar_grupo() {
  for (int i = 0; i < sizeof(grupoValv) / sizeof(grupoValv[0]); i++) {
    digitalWrite(grupoValv[i], RON);
  }
}
void desact_grupo() {
  for (int i = 0; i < sizeof(grupoValv) / sizeof(grupoValv[0]); i++) {
    digitalWrite(grupoValv[i], ROFF);
  }
}
void ejecutarSecuenciaReles() {
  if (modoControl || modoTesteo) {
    paso = 0;
    tiempoInicioPaso = 0;
    return;
  }

  static unsigned long tiempoInicioPaso = 0;
  const unsigned long tiemposEspera[] = {1000, 500, 5000, 2000, 5000, 2000, 5000, 1000};
  unsigned long tiempoActual = millis(); 


  if (tiempoActual < tiempoInicioPaso) {
    paso = 0;
  }
  if (tiempoActual - tiempoInicioPaso >= tiemposEspera[paso]) {
    switch (paso) {
      case 0:
        message = "-----------Iniciando Riego----------";
        print(message);           
        desact_grupo();
        digitalWrite(trafo, RON);
        break;
      case 1:
        digitalWrite(valvL, RON);
        digitalWrite(contactor, HIGH);
        message = "->Trafo ON // VΓ‘lv. L ON // Bombas ON<-";
        print(message);            
        break;
      case 2:
        message = "->VΓ‘lv. C ON<-";
        print(message);    
        digitalWrite(valvC, RON);
        break;
      case 3:
        digitalWrite(valvL, ROFF);
        break;
      case 4:
        message = "->VΓ‘lv. R ON<-";
        print(message);        
        digitalWrite(valvR, RON);
        break;
      case 5:
        digitalWrite(valvC, ROFF);
        break;
      case 6:
        message = "->Bombas OFF<-";
        print(message);
        digitalWrite(contactor, LOW);
        break;
      case 7:
        desact_grupo();
        message = "-----------Riego Finalizado---------";
        print(message);
        digitalWrite(led, LOW);
        break;
    }
    paso++;
    tiempoInicioPaso = tiempoActual;
    if (paso > 7) {
      paso = 0;
    }
  }
}

void print(String message) {
  Serial.println(message);
  client.println(message);
  delay(10);
  message = "";
}
void activateValve(int valveNumber) {
  if (valveNumber != activeValve) {
    if (activeValve != -1) {
      digitalWrite(valvePins[valveNumber - 1], RON);
      message = "Cambiando VΓ‘lv.";
      print(message);

      tiempoInicio = millis();
      while (millis() - tiempoInicio < 1000) {}

      digitalWrite(valvePins[activeValve - 1], ROFF);
      message = "->VΓ‘lv. " + String(activeValve) + " OFF<-";
      print(message);
      
      tiempoInicio = millis();
      while (millis() - tiempoInicio < 1000) {}
    }
    digitalWrite(valvePins[valveNumber - 1], RON);
    activeValve = valveNumber;
    }
}

Hola. Mas allΓ‘ que encontras la soluciΓ³n aprende a programar sin usar estas cosas

        goto salida2;
      }
salida2:
      return;

eso lo reemplazas directamente colocando el return en lugar del goto salida2:

Hay mas para sugerirte, no se si te interesa.

Muchas gracias por la sugerencia, una redundancia que pasΓ© por alto el uso de la salida2. Me interesa recibir mΓ‘s opiniones y disculpe la demora en responder.
Saludos.

He actualizado bastante el codigo, te adjunto la ultima versiΓ³n.

/*
Incluye configuracion de RTC y temporizador
*/
#include <ESP8266WiFi.h>
#include <Wire.h>
#include <RTClib.h>

int contactor = 16;
int sensor_a = A0;
int led = 15;
int trafo = 14;
int valvL = 12; 
int valvC = 13;
int valvR = 0;

//Ajuste de Reles
const int RON = 0;
const int ROFF = 1;

unsigned long secuenciaStartTime = 0;
unsigned long delayTime = 0;
int estadoSecuencia = 0; 

const int grupoValv[] = {0, 12, 13, 14}; 
const int numValves = 3;
int valvePins[numValves] = {12, 13, 0};
int activeValve = -1;

bool modoControl = false;
bool modoTesteo = false;
bool salida = false;
bool exit_control = false;

const char *ssid = "ESP8266"; 
const char *password = "juan1234"; 
WiFiServer server(80);
WiFiClient client;

String command = "";
String message;
String mensajeCliente = "";
unsigned long tiempoInicioLED = 0; 
bool estadoLED = LOW;  

unsigned long tiempoInicio;
unsigned long tiempoActual;
unsigned long tiempoCliente;

static int paso = 0; 
static unsigned long tiempoInicioPaso = 0;  

RTC_DS1307 rtc;

int ciclos = 0;
int riegos_diarios = 0;
unsigned long tiempoUltimoReinicio = 0;
const unsigned long periodoReinicio = 2592000000UL; 

void setup() {
  Serial.begin(115200);
  pinMode(trafo, OUTPUT);
  pinMode(valvL, OUTPUT);
  pinMode(valvC, OUTPUT);
  pinMode(valvR, OUTPUT);
  pinMode(contactor, OUTPUT);
//  pinMode(sensor_d, OUTPUT);
  pinMode(led, OUTPUT);
  pinMode(LED_BUILTIN, OUTPUT);

  digitalWrite(contactor, LOW); 
  digitalWrite(trafo, ROFF);
  digitalWrite(valvL, ROFF);
  digitalWrite(valvC, ROFF);
  digitalWrite(valvR, ROFF);
  digitalWrite(led, HIGH);
  digitalWrite(LED_BUILTIN, LOW);

  tiempoUltimoReinicio = millis(); // Guardar el tiempo del ΓΊltimo reinicio 

  Wire.begin(D4, D1); //D4 (SDA) y D1 (SCL)
  rtc.begin();

  if (! rtc.begin()) {
    Serial.println("Modulo RTC no detectado -X-");
    Serial.flush();
    while (1) delay(10);
  }

  for (int i = 0; i < 5; i++) {
    digitalWrite(led, HIGH);
    delay(250);
    digitalWrite(led, LOW);
    delay(1000);
  }

  digitalWrite(led, HIGH);

  for (int i = 0; i < numValves; i++) {
    pinMode(valvePins[i], OUTPUT);
    digitalWrite(valvePins[i], ROFF);
  }

  
  WiFi.softAP(ssid, password);
  IPAddress IP = WiFi.softAPIP();
  delay(4000);
  Serial.print("IP Address: ");
  Serial.println(IP);
  server.begin();
  delay(10000);

  Serial.println("Esperando instrucciones...");
  tiempoInicio = millis();
  tiempoCliente = millis();

  while (millis() - tiempoInicio < 10000) { 
    if (Serial.available() > 0) { 
      String mensaje = Serial.readStringUntil('\n');
      if (mensaje.equals("inicio testeo")) { 
        ejecutarModoTesteo();
        break;
      }
    }
  }
    
  ciclos = 0;
  riegos_diarios = 0;
  exit_control = false;
  salida = false;

}

void loop() {
/*
message = "╔══════════ Iniciando Riego ══════════";
*/
  DateTime now = rtc.now();
  digitalWrite(LED_BUILTIN, LOW);

//----------------REINICIO PROGRAMADO----------------
  unsigned long tiempoActual = millis();
  if (tiempoActual - tiempoUltimoReinicio >= periodoReinicio) {
    ESP.restart();
  }
//----------------REINICIO PROGRAMADO----------------

  if (!client.connected()) {
    client = server.available();
  }
  if (client.connected() && client.available() > 0) {
    String command = client.readStringUntil('\n');
    command.trim();
    message = "Loop principal-Comando Recibido:  " + String(command);
    print(message);      
    if (command.equals("Control")) {
      modoControl = true;
      interacc_client(); 
      modoControl = false;
      paso = 0;
      tiempoInicioPaso = 0;  
      goto salida1;
      }
    enviarMensajesCliente();
    }

  while (Serial.available() > 0) {
    String input = Serial.readStringUntil('\n');
    if (input.equals("inicio testeo")) {
      modoTesteo = true;
      ejecutarModoTesteo();
      modoTesteo = false;
      paso = 0;
      tiempoInicioPaso = 0;
      }
    }

  salida1:
  if (ciclos < 1 && now.hour() != 18) {
    message = "╔════════════════════════════════════╗";
    print(message);
    message = "β•‘        ESPERANDO HASTA 18HS        β•‘";
    print(message);
    message = "β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•";
    print(message);
    printRTC();
  }
  if (now.hour() == 18 && now.minute() >=0 && now.minute() <=5 && riegos_diarios <1) { 
    ejecutarSecuenciaReles();
  }
  else {
    ciclos++;
  }
  if (now.hour() == 0 && now.minute() == 0 && now.second() == 0){
    riegos_diarios = 0;
  }
}


void interacc_client(){
    message = "╔══════════════ CONTROL ══════════════";
    print(message);
    message = "╠══> Inicio Testeo";
    print(message);    
    message = "╠══> Continuar Riego";
    print(message);
    message = "╠══> Hora RTC";
    print(message);    
    message = "╠══> set_time";
    print(message);
    message = "β•‘      β•šβ•>Ejemplo de comando: set_time 15:30:00";
    print(message);  
    message = "╠══> set_date";
    print(message);
    message = "β•‘      β•šβ•>Ejemplo de comando: set_date 10/03/2024";
    print(message); 
    message = "╠══> Estado";
    print(message);

    digitalWrite(contactor, LOW);
    tiempoInicio = millis();
    while (millis() - tiempoInicio < 500) {}    
    desact_grupo();
    tiempoInicio = millis();
    while (millis() - tiempoInicio < 500) {}
    
    while (client.connected()) {
      if (client.available()) {
        String command = client.readStringUntil('\n');
        command.trim();
        //message = "Control-Comando Recibido:  " + String(command);
        //print(message);

        if (command.startsWith("set_time")) {
          message = "╠══════════════<SET TIME>══════════════";
          print(message);
          DateTime now = rtc.now();
          //Ejemplo de comando: set_time 15:30:00
          String timeString = command.substring(9);
          int hour = timeString.substring(0, 2).toInt(); //  recordar que timeString.substring(from, to), from a partir 
          int minute = timeString.substring(3, 5).toInt();// y to es un digito despues del ultimo que me interesa
          int second = timeString.substring(6, 8).toInt();
          
          if (hour >= 0 && hour<= 23 && minute >= 0 && minute <= 59 && second >= 0 && second <= 59) {
            rtc.adjust(DateTime(now.year(), now.month(), now.day(), hour, minute, second));
            message = "β•‘    β•šβ•> " + String(now.hour()) + ':' + String(now.minute()) + ':' + String(now.second());
            print(message);
            printRTC();
          } else {
            message = "β•‘      β•šβ•>Error: Formato de hora invΓ‘lido.";
            print(message);
          }
        }

        if (command.startsWith("set_date")) {
          DateTime now = rtc.now();
          message = "╠═════════════<SET DATE>══════════════";
          print(message);
          //Ejemplo de comando: set_date 10/03/2024
          String timeString = command.substring(9);
          int day = timeString.substring(0, 2).toInt(); 
          int month = timeString.substring(3, 5).toInt();
          int year = timeString.substring(6, 10).toInt();

          
          if (year > 2010 && month > 0 && month <= 12 && day > 0 && day <= 31) {
            rtc.adjust(DateTime(year, month, day, now.hour(), now.minute(), now.second()));
            message = "β•‘    β•šβ•> " + String(now.year()) + '/' + String(now.month()) + '/' + String(now.day());;
            print(message);
            printRTC();
          } else {
            message = "β•‘      β•šβ•>Error: Formato de fecha invΓ‘lido.";
            print(message);
          }
        }        

        if (command.equals("Hora RTC")){
          printRTC();
        }

        if (command.equals("inicio testeo")) {
          ejecutarModoTesteo();
          exit_control = true;               
        } 

        if (command.equals("continuar riego")) {  
          salida = true;
          modoTesteo = false;
          exit_control = true;     
        }
        if (command.equals("estado")) {
          message = "╠══════════════<ESTADO>═══════════════";


          print(message);
          printRTC();

          if (riegos_diarios == 1){
            message = "β•‘    β•šβ•β•>Riego Diario Realizado";
            print(message);
          }
          else {
            message = "β•‘    β•šβ•β•>Riego Diario Pendiente";
            print(message);
            message = "β•‘    β•šβ•β•>ESPERANDO HASTA 18HS";
            print(message);
          }

        }        

        if (salida == true){
          static int paso = 0;
          static int tiempoInicioPaso = 0;
          tiempoInicio = millis();
          while (millis() - tiempoInicio < 100) {} 
          message = "β•šβ•β•β•β•β•β•β•β•β• FIN CONTROL MODE ══════════";
          print(message);   
          exit_control = true;     
        }
        if (exit_control == true){
          exit_control = false;
          salida = false;
          return;
        }
      }
    }
}

void ejecutarModoTesteo() {
  message = "╠═════════════<TEST MODE>═════════════";
  print(message);  
  modoTesteo = true; 
  digitalWrite(contactor, LOW);
  
  tiempoInicio = millis();
  while (millis() - tiempoInicio < 500) {}
  desact_grupo();
  digitalWrite(trafo, RON);


  message = "╠══> VΓ‘lvula L = 1";
  print(message);
  tiempoInicio = millis();
  message = "╠══> VΓ‘lvula C = 2";
  print(message);
  tiempoInicio = millis();
  message = "╠══> VΓ‘lvula R = 3";
  print(message);
  message = "╠══> Continuar Riego";
  print(message);
  message = "╠══>Fin Testeo";
  print(message);
  tiempoInicio = millis();

  unsigned long tiempoInicioLED = millis(); 
  bool estadoLED = LOW;   
  
  while (modoTesteo) {
    tiempoActual = millis();
    while (millis() - tiempoInicio < 100) {}

    if (tiempoActual - tiempoInicioLED >= 500) {
      estadoLED = !estadoLED; 
      digitalWrite(15, estadoLED);
      tiempoInicioLED = tiempoActual; 
    }
    tiempoActual = millis();
    while (millis() - tiempoInicio < 100) {}

    if (client.available()) {
        String valveNumberStr = client.readStringUntil('\n');
        int valveNumber = valveNumberStr.toInt();
        valveNumberStr.trim();

      if (valveNumberStr.equals("continuar riego")) {
        modoTesteo = false;
        salida = true;
        message = "╠══════════<END TEST MODE>════════════";
        print(message);
        return;
        }   

      if (valveNumber >= 1 && valveNumber <= numValves) {
        digitalWrite(trafo, RON);
        tiempoInicio = millis();
        while (millis() - tiempoInicio < 500) {}
        message = "β•‘    ╠══>VΓ‘lvula " + String(valveNumber) + " ON";
        print(message);   
        activateValve(valveNumber);
        tiempoInicio = millis();
        while (millis() - tiempoInicio < 500) {} 
        digitalWrite(contactor, HIGH);
        }
      if (valveNumberStr.equals("fin testeo")) {
        message = "╠══════════<END TEST MODE>════════════";
        print(message);        
        secuencia_FnTst();
        break;
       }
    }

    if (Serial.available() > 0) {
      String valveNumberStr = Serial.readStringUntil('\n');
      int valveNumber = valveNumberStr.toInt();
      if (valveNumber >= 1 && valveNumber <= numValves) {
        digitalWrite(trafo, RON);
        tiempoInicio = millis();
        while (millis() - tiempoInicio < 500) {} // Esperar 500 milisegundos
        activateValve(valveNumber);
        message = "β•‘    ╠══>VΓ‘lvula " + String(valveNumber) + " ON";
        print(message);           
        digitalWrite(contactor, HIGH);
      }
      if (valveNumberStr.equals("fin testeo")) {
        message = "╠══════════<END TEST MODE>════════════";
        print(message);        
        secuencia_FnTst();
        break;
      }
    }
  }
}

void ejecutarSecuenciaReles() {
  if (modoControl || modoTesteo) {
    paso = 0;
    tiempoInicioPaso = 0;
    return;
  }

  static unsigned long tiempoInicioPaso = 0;
  const unsigned long tiemposEspera[] = {1000, 1000, 20*60*1000, 1000, 20*60*1000, 1000, 20*60*1000, 1000};
  unsigned long tiempoActual = millis(); 


  if (tiempoActual < tiempoInicioPaso) {
    paso = 0;
  }
  if (tiempoActual - tiempoInicioPaso >= tiemposEspera[paso]) {
    switch (paso) {
      case 0:
        message = "╔══════════ INICIANDO RIEGO ══════════";        
        print(message);           
        desact_grupo();
        digitalWrite(trafo, RON);
        digitalWrite(valvL, RON);     
        break;
      case 1:
        digitalWrite(contactor, HIGH);                 
        message = "╠══> Trafo ON // VΓ‘lv. L ON // Bombas ON";
        print(message);            
        break;
      case 2:
        message = "╠══> VΓ‘lv. C ON";
        print(message);    
        digitalWrite(valvC, RON);
        break;
      case 3:
        digitalWrite(valvL, ROFF);
        break;
      case 4:
        message = "╠══> VΓ‘lv. R ON";
        print(message);        
        digitalWrite(valvR, RON);
        break;
      case 5:
        digitalWrite(valvC, ROFF);
        break;
      case 6:
        message = "╠══> Bombas OFF";
        print(message);
        digitalWrite(contactor, LOW);
        break;
      case 7:
        desact_grupo();
        message = "β•šβ•β•β•β•β•β•β•β•β•β• RIEGO FINALIZADO ═════════";
        print(message);
        ciclos = 0;
        digitalWrite(led, LOW);
        riegos_diarios++;
        break;
    }
    paso++;
    tiempoInicioPaso = tiempoActual;
    if (paso > 7) {
      paso = 0;
    }
  }
}

void secuencia_FnTst() {
        message = "β•‘    ╠══>Apagando Bombas...";
        print(message);          
        tiempoInicio = millis();
        while (millis() - tiempoInicio < 500) {}
        digitalWrite(contactor, LOW);

        tiempoInicio = millis();
        while (millis() - tiempoInicio < 500) {}
        message = "β•‘    ╠══>Apagando Electrovalvulas...";
        print(message);

        tiempoInicio = millis();
        while (millis() - tiempoInicio < 500) {}            
        desact_grupo();

        message = "β•‘    β•šβ•β•>Aguarde 10s para reiniciar...";
        print(message);

        tiempoInicio = millis();
        while (millis() - tiempoInicio < 500) {}
        message = "β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•<REBOOTING>═════════════";
        print(message);
        delay(10000);    
        ESP.restart();
}
void config_grupo() {
  for (int i = 0; i < sizeof(grupoValv) / sizeof(grupoValv[0]); i++) {
    pinMode(grupoValv[i], OUTPUT);
  }
}
void activar_grupo() {
  for (int i = 0; i < sizeof(grupoValv) / sizeof(grupoValv[0]); i++) {
    digitalWrite(grupoValv[i], RON);
  }
}
void desact_grupo() {
  for (int i = 0; i < sizeof(grupoValv) / sizeof(grupoValv[0]); i++) {
    digitalWrite(grupoValv[i], ROFF);
  }
}
void print(String message) {
  Serial.println(message);
  agregarMensajeCliente(message);
  enviarMensajesCliente();
  message = "";
}
void agregarMensajeCliente(String mensaje) {
  mensajeCliente += mensaje + "\n"; 
}
void enviarMensajesCliente() {
  if (!mensajeCliente.isEmpty()) { 
    client.print(mensajeCliente);
    mensajeCliente = ""; 
  }
}
void activateValve(int valveNumber) {
  if (valveNumber != activeValve) {
    if (activeValve != -1) {
      digitalWrite(valvePins[valveNumber - 1], RON);
      message = "β•‘    ╠══>Cambiando VΓ‘lv.";
      print(message);

      tiempoInicio = millis();
      while (millis() - tiempoInicio < 1000) {}

      digitalWrite(valvePins[activeValve - 1], ROFF);
      message = "β•‘    ╠══>VΓ‘lvula " + String(activeValve) + " OFF";
      print(message);
      
      tiempoInicio = millis();
      while (millis() - tiempoInicio < 1000) {}
    }
    digitalWrite(valvePins[valveNumber - 1], RON);
    activeValve = valveNumber;
    }
}
void printRTC() {
  DateTime now = rtc.now();
  Serial.print("╠══════> ");
  if (now.day() < 10){
    Serial.print("0");
  }    
  Serial.print(now.day());
  Serial.print('/');
  if (now.month() < 10){
    Serial.print("0");
  }    
  Serial.print(now.month());
  Serial.print('/');
  Serial.print(now.year());
  Serial.print(" - ");  
  if (now.hour() < 10){
    Serial.print("0");
  }  
  Serial.print(now.hour());
  Serial.print(':');
  if (now.minute() < 10){
    Serial.print("0");
  }    
  Serial.print(now.minute());
  Serial.print(':');
  if (now.second() < 10){
    Serial.print("0");
  }    
  Serial.print(now.second());
  Serial.println();
  client.print("╠══════> ");
  if (now.day() < 10){
    client.print("0");
  }    
  client.print(now.day());
  client.print('/');
  if (now.month() < 10){
    client.print("0");
  }    
  client.print(now.month());
  client.print('/');
  client.print(now.year());
  client.print(" - ");  
  if (now.hour() < 10){
    client.print("0");
  }  
  client.print(now.hour());
  client.print(':');
  if (now.minute() < 10){
    client.print("0");
  }    
  client.print(now.minute());
  client.print(':');
  if (now.second() < 10){
    client.print("0");
  }    
  client.print(now.second());
  client.println();
}
    while (millis() - tiempoInicio < 500) {}    

Este es un mal uso de millis() y en un ESP8266 te va a provocar reinicios por el watchdog.
En este caso es mejor usar delay().

Te recomiendo que leas la documentaciΓ³n del core

DocumentaciΓ³n de ESP8266 Arduino Core

1 Like

Gracias por la correcciΓ³n. En vez de usar delays() para no trabar la ejecuciΓ³n del programa, una buena alternativa seria comparar con millis el tiempo transcurrido entre dos puntos del codigo usando un if?

Por si no lo entendiste usar millis() en un while del modo que lo has hecho exactamente igual que usar delay(500)

Entonces si, debes hacer un cΓ³digo que no bloquea... como una comparaciΓ³n de cosas y cuando se da la condiciΓ³n que incluye millis() y el momento anterior entonces si haces algo y luego liberas y el codigo fluye.
Toda la rutina

void ejecutarModoTesteo() {

comete el mismo error una y otra vez. Reemplazas delay() por otro delay de modo idΓ©ntico que usa millis().

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.