ESP32 cierra la conexión con LabVIEW

Estoy creando un código para conectar un ESP32 con LabVIEW a través del protocolo TCP/IP y así enviar información desde el controlador y también recibirla. Mi programa funciona correctamente por 2 minutos aproximadamente pero luego me aparece un error en LabVIEW (error 66), donde dice que la conexión ha sido cerrada por el otro nodo, es decir por el controlador, según entiendo. Por esto supongo que el error está en mi código de Arduino IDE, pero la verdad no he podido encontrar en problema y tampoco he logrado hacer que el programa avise por el puerto serial cuando el cliente se desconectó o que al menos vuelva a hacer la conexión cuando esta se pierde con el cliente de LabVIEW. Agradecería mucho si alguien me pudiera indicar si hay algún error con mi programa.

//Se incluye librería para el WiFi
#include <WiFi.h>
//Se definen nombre de red y contraseña a la que se va a conectar el controlador
const char* ssid = "";
const char* pass = "";

//Se configura el servidor con el puerto 8000
WiFiServer server(8000);
IPAddress local_IP();

//Se conectan los sensores a los pines 36, 39, 34 y 35
int sensor2 = 36;
int sensor3 = 39;
int sensor4 = 34;
int sensor5 = 35;

//Se conectan los relé a los pines 23, 22, 21 y 19
int led1 = 23;
int led2 = 22;
int led3 = 21;
int led4 = 19;

//char labview = 0;

void setup() {

  Serial.begin(115200);

  //Se inicia la conexión a la red WiFi definida
  WiFi.begin(ssid, pass);
  delay(2000);

  //Mostrar asteriscos mientras se realiza la conexión
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print("*");
  }

  //Se anuncia cuando ya se haya conectado a la red WiFi y se muestra la dirección IP que será usada para el código en LabVIEW
  Serial.println("");
  Serial.println("Se ha conectado a la red WiFi");
  Serial.println("Dirección IP: ");
  Serial.println(WiFi.localIP());

  //Se inicia el ESP32 como servidor
  server.begin();

  // Se establecen los sensores como entrada
  pinMode(sensor2, INPUT);
  pinMode(sensor3, INPUT);
  pinMode(sensor4, INPUT);
  pinMode(sensor5, INPUT);

  //Se establecen los relé como salida
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
}

void loop() {

// Mostrar al cliente que el ESP32 como servidor está disponible
  WiFiClient client = server.available();

//Mostrar en el puerto serial cuando el cliente se haya conectado
  if (client) {
    Serial.println("Cliente conectado");

//Ejecutar mientras el cliente esté conectado
    while (client.connected()) {
      //Calibración del sensor 2********************************
      int humedad2 = analogRead(sensor2);
      //int humedad1=334*humedad-81;
      int porcentaje2 = map(humedad2, 579, 252, 0, 100);

      //Calibración del sensor 3**********************************
      int humedad3 = analogRead(sensor3);
      //int humedad1=334*humedad-81;
      int porcentaje3 = map(humedad3, 579, 252, 0, 100);

      //Calibración del sensor 4**********************************
      int humedad4 = analogRead(sensor4);
      //int humedad1=334*humedad-81;
      int porcentaje4 = map(humedad4, 579, 252, 0, 100);

      //Calibración del sensor 5**********************************
      int humedad5 = analogRead(sensor5);
      //int humedad1=334*humedad-81;
      int porcentaje5 = map(humedad5, 579, 252, 0, 100);

      if (client.available() > 0) {

        //Se define si se enciende o apaga LED1**************************************
        int labview = client.read();
        if (labview == '0') {
          digitalWrite(led1, LOW);
        }
        if (labview == '1') {
          digitalWrite(led1, HIGH);
        }

        //Se define si se enciende o apaga LED2****************************************
        //int labview=Serial.read();
        if (labview == '2') {
          digitalWrite(led2, LOW);
        }
        if (labview == '3') {
          digitalWrite(led2, HIGH);
        }

        //Se define si se enciende o apaga LED3****************************************
        //int labview=Serial.read();
        if (labview == '4') {
          digitalWrite(led3, LOW);
        }
        if (labview == '5') {
          digitalWrite(led3, HIGH);
        }

        //Se define si se enciende o apaga LED4****************************************
        //int labview=Serial.read();
        if (labview == '6') {
          digitalWrite(led4, LOW);
        }
        if (labview == '7') {
          digitalWrite(led4, HIGH);
        }
      }

//Mostrar en el puerto serial el valor obtenido por el sensor
//Enviar al cliente el valor obtenido por el sensor
      Serial.println(porcentaje2);
      client.println(porcentaje2);

      Serial.println(porcentaje3);
      client.println(porcentaje3);

      Serial.println(porcentaje4);
      client.println(porcentaje4);

      Serial.println(porcentaje5);
      client.println(porcentaje5);

      delay(1000);
    }
  
  //Verificar si el servidor tiene un cliente conectado
  if(server.hasClient()){
  
  //Si no hay cliente salir del loop y esperar otro cliente
  return;
  }  
      
  }      
}

Como es tu programa en Labview estas utilizando un while, ya que ese puede ser el error ya que tu código en el ESP32 abre y cierra la conexión TCP/IP, también puedes utilizar "probe" en labview para verificar en donde acontece el error en especifico

Sé que el error en LabVIEW aparece en la función TCP read. No lo puedo subir por el formato pero es algo así. Si el error es por el while entonces debo cambiarlo?

Moderador
Tema movido a Microcontroladores.
todo lo que no sea Arduino, AVR o Microchip se mueve a esta sección.

Respuesta
En tu código veo cosas como esta

Has que la comunicación sea fluida sin usar cosas que detengan la comunicación.
Eso para toda comunicación por 1 segundo, dirás pero es nada, pues bien, por algo se queja el LABVIEW.
No se si será el responsable pero yo no lo usaría o prueba bajandolo a 100 mseg

Fijate en este link esta las referencias de la FUNCIÓN TCP, un usuario del FORO NI asevera que el error se puede solucionar si eliges el modo inmediato Solved TCP/IP error 66

En pocas palabras sugiere usar el modo Inmmediate en vez del CRLF que tu tienes en el VI.

Si el error persiste sugiero desactivar el firewall de windows

Ya se lo quité. Pero sigue desconectándose :frowning:

Gracias, lo cambié a Immediate y no me salen los datos de los sensores en LabVIEW, y estuve haciendo varias pruebas y al parecer el problema no está en el TCP read sino en TCP write. Mi programa funciona bien si borro todos los bloques de write. Pero al agregarlos no sé que sucede y se empieza a desconectar.

También desactivé el firewall pero sigue sin funcionar

Debes entender los modos del TCP READ:
0 Estándar (predeterminado): espera hasta que lleguen todos los bytes que especifique en bytes para leer o hasta que se agote el tiempo de espera. Devuelve el número de bytes leídos hasta el momento. Si llegan menos bytes que la cantidad de bytes que solicitó, devuelve la cantidad parcial de bytes e informa un error de tiempo de espera.
1 En búfer: espera hasta que lleguen todos los bytes que especifique en bytes para leer o hasta que se agote el tiempo de espera. Si llegan menos bytes que el número que solicitó, no devuelve bytes e informa un error de tiempo de espera.
2 CRLF: espera hasta que lleguen todos los bytes que especifique en bytes para leer o hasta que la función reciba un CR (retorno de carro) seguido de un LF (avance de línea) dentro del número de bytes que especifique en bytes para leer o hasta que se agote el tiempo de espera ms. La función devuelve los bytes hasta e incluyendo CR y LF si los encuentra en la cadena.
3 Inmediato: espera hasta que la función reciba cualquier byte de aquellos que especifique en bytes para leer. Espera el tiempo de espera completo solo si la función no recibe bytes. Devuelve el número de bytes hasta el momento. Informa un error de tiempo de espera si la función no recibe bytes.

No va a leer los datos de los sensores porque estas enviando en formato CRLF uno detras de otro

      Serial.println(porcentaje2);
      client.println(porcentaje2);

      Serial.println(porcentaje3);
      client.println(porcentaje3);

      Serial.println(porcentaje4);
      client.println(porcentaje4);

      Serial.println(porcentaje5);
      client.println(porcentaje5);

Y si el error es en el TCP write debe ser porque en el modo CRLF labview envia en formato ASCII los datos y el esp32 recibe los datos en uint8_t, referencia TCP WRITE
por ende deberias usar 5 tcp write en labview para enviar uno tras otro cada dato, te dejo lo que dice sobre la data IN del bloque TCP WRITE:

data in contiene los datos que desea escribir en la conexión.
Use una de las siguientes técnicas para manejar mensajes que pueden variar en tamaño:

  • Envíe mensajes que estén precedidos por un encabezado de tamaño fijo que describa el mensaje. Por ejemplo, podría contener un entero de comando que identifique qué tipo de mensaje sigue y un entero de longitud que identifique cuántos datos más hay en el mensaje. Tanto el servidor como el cliente reciben mensajes emitiendo una función de lectura de ocho bytes (suponiendo que cada uno sea un número entero de cuatro bytes), convirtiéndolos en los dos números enteros y usando el número entero de longitud para determinar el número de bytes que se pasan a una segunda función de lectura. por el resto del mensaje. Una vez que se completa esta segunda lectura, cada lado regresa a la función de lectura del encabezado de ocho bytes. Esta técnica es la más flexible, pero requiere dos lecturas para recibir cada mensaje.

  • En la práctica, la segunda lectura suele completarse inmediatamente si el mensaje se escribe con una sola función de escritura. Haz que cada mensaje tenga un tamaño fijo. Cuando el contenido de un mensaje es más pequeño que el tamaño fijo que especifica, rellene el mensaje al tamaño fijo. Esta técnica es marginalmente más eficiente porque solo se requiere una lectura para recibir un mensaje a expensas de enviar datos innecesarios a veces.

  • Envíe mensajes cuyo contenido sea estrictamente ASCII, donde cada mensaje termine con un retorno de carro y un par de caracteres de salto de línea. La función de lectura tiene una entrada de modo que, cuando se pasa CRLF, hace que lea hasta que vea una secuencia de retorno de carro y avance de línea. Esta técnica se vuelve más complicada cuando los datos del mensaje posiblemente pueden contener secuencias CRLF, pero es bastante común entre muchos protocolos de Internet, incluidos POP3, FTP y HTTP.

Solución