Conexión de Cliente mientras ejecuta código

Buenas, cómo va? Quiero consultar como solucionar mi problema, es el siguiente: Logro crear el servidor e ingresar desde mi teléfono conectándome al punto de acceso, a la IP y al puerto necesario. Una vez que me conecto, el código queda escuchando el puerto serial y deja de ejecutar la función ejecutarSecuenciaReles(). Mi intención es que en todo momento esté escuchando tanto el puerto serial de Arduino IDE como el del WiFi pero que no interrumpa la ejecución del código si un cliente se conecta (si manda un comando si, sino no).

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

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

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

//Inicio de Riego Automático
unsigned long ultimaEjecucion = 0;
unsigned long intervaloEjecucion = 10000; 
bool atendiendoCliente = false;

void setup() {
  Serial.begin(9600);
  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...");

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

void loop() {
  client = server.available(); 
  if (client) {
    message = "Nuevo cliente conectado";
    print(message);
    digitalWrite(contactor, LOW);
    delay(2000);
    desact_grupo();
    delay(1000);
    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();
        } 
        else {
          client.println("Comando Desconocido");
        }
      }
    }
  }
  while (Serial.available() > 0) {
    String input = Serial.readStringUntil('\n');
    if (input.equals("inicio testeo")) {
      modoTesteo = true;
      ejecutarModoTesteo();
      }
    }
  ejecutarSecuenciaReles();
  delay(1000); 
}


void ejecutarModoTesteo() {
  message = "--------------Test Mode-------------";
  print(message);  
  modoTesteo = true; 
  desact_grupo();
  digitalWrite(contactor, LOW);
  digitalWrite(trafo, RON);

  message = "Válvula L = 1";
  print(message);
  delay(100);
  message = "Válvula C = 2";
  print(message);
  delay(100);
  message = "Válvula R = 3";
  print(message);      

  unsigned long tiempoInicioLED = millis(); 
  bool estadoLED = LOW; 
  while (modoTesteo) {
    unsigned long tiempoActual = millis();

    if (tiempoActual - tiempoInicioLED >= 500) {
      estadoLED = !estadoLED; 
      digitalWrite(15, estadoLED);
      tiempoInicioLED = tiempoActual; 
    }

    if (client.available()) {
        String valveNumberStr = client.readStringUntil('\n');
        int valveNumber = valveNumberStr.toInt();
        command.trim();
        Serial.println("Comando recibido: " + valveNumberStr);
        client.println("Comando recibido: " + valveNumberStr);

      
      if (valveNumber >= 1 && valveNumber <= numValves) {
        digitalWrite(trafo, RON);

        delay(500);
        message = "Válvula " + String(valveNumber) + " activada";
        print(message);   
        activateValve(valveNumber);

        delay(500);
        digitalWrite(contactor, HIGH);
        }
      if (valveNumberStr.equals("fin testeo")) {
        message = "Comando Recibido: " + command;
        print(message);  
        
        message = "Apagando Bombas...";
        print(message);          
        delay(500);
        digitalWrite(contactor, LOW);
        delay(5000);

        message = "Apagando Electrovalvulas...";
        print(message);          
        delay(500);
        desact_grupo();
       
        message = "Aguarde 10s para reiniciar...";
        print(message);          
        delay(10 * 1000);

        message = "------------Fin Test Mode------------";
        print(message);              
        modoTesteo = false; 
        digitalWrite(15, LOW);
        delay(500);
        ESP.restart();
       }
    }


    if (Serial.available() > 0) {
      String valveNumberStr = Serial.readStringUntil('\n');
      int valveNumber = valveNumberStr.toInt();
      if (valveNumber >= 1 && valveNumber <= numValves) {
        digitalWrite(trafo, RON);
        delay(500);

        message = "Válvula " + String(valveNumber) + " activada";
        print(message);   
        activateValve(valveNumber);
        delay(500);
        digitalWrite(contactor, HIGH);
      }
      if (valveNumberStr.equals("fin testeo")) {

        message = "Apagando Bombas...";
        print(message);          
        delay(500);
        digitalWrite(contactor, LOW);
        delay(5000);

        message = "Apagando Electrovalvulas...";
        print(message);            
        desact_grupo();

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

        message = "------------Fin Test Mode------------";
        print(message);      
        modoTesteo = false; 
        digitalWrite(15, LOW);
        delay(500);
        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 int paso = 0; estamos
  static unsigned long tiempoInicioPaso = 0;

  const unsigned long tiemposEspera[] = {1000, 500, 5000, 2000, 5000, 2000, 5000, 1000};

  unsigned long tiempoActual = millis();

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

void activateValve(int valveNumber) {
  if (valveNumber != activeValve) {
    if (activeValve != -1) {
      digitalWrite(valvePins[valveNumber - 1], RON);
      Serial.println("Transición, aguarde...");
      delay(5000); 
      digitalWrite(valvePins[activeValve - 1], ROFF);
      Serial.print("Válvula ");
      Serial.print(activeValve);
      Serial.println(" apagada");
    }
    digitalWrite(valvePins[valveNumber - 1], RON);
    activeValve = valveNumber;
    }
  }

Dos lineas de código y encuentro delay() y mas delay() sabes que provocan en el código? Justamente lo que reclamas. El microno hace nada durante 1 o 2 seg y tu quieres que siga prestantando atención a todo.
Ve a Documentación y lee sobre Máquinas de estado y millis().

1 Like

Aleluya a los millis()!!

Es que esa es la diferencia entre algo que puede funcionar y lo que no funciona.

También comentar que creo que usas ESP8266.
Éste tiene un único core.
Mira de paso ES32 que tienen dos cores y permiten ejecución 100% en paralelo.
En mi caso, por ejemplo, con un esp32 leo de un puerto serie y sobre el otro actúa el servidor web.
Saludos.

1 Like

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