ESP01 y NANO Comunicacion por SERIAL no Funciona

Hola a todos y gracias de antemano a quienes puedan responder. Intentare ser lo mas claro posible.

EL PROBLEMA , con Arduino Nano, teniendo 2 DHT11 y un Modulo Rele5V, se intenta enviar los datos de los sensores via comunicacion SERIAL a un ESP8266-01, el ESP-01 a veces recibe otras veces no. El ESP-01 debe recibir la informacion y enviar una respuesta para activar o desactivar el RELE.

Estoy usando el ESP-01 conectado directamente al Serial del Nano, Rx a Tx y Tx a Rx (ESP-01 a Nano).

He intentado de varias formas y la mayoria de las veces, puedo enviar la informacion por serial desde el nano al esp-01 pero no recibo la respuesta del esp-01.

El ESP01, esta con un servidor asincronico.
Para enviar los datos de Nano a ESP-01, desde nano, envio un string (formato JSON). Uso un Serial.print("string de datos json \n"), luego un flush() para que espere a que la transmicion este enviada, el ESP-01 recibe por el Serial.Available().

Fragmento del Loop Nano()

  stamp2 = millis();
  diftim1 = stamp2-stamp1;
  if( (diftim1/1000)>10&&switchData==false ){
    switchData=true;
    stamp1=millis();
  } // Si pasan 60 seg sin respuesta, 
    // se envian datos nuevamente
  if(switchData){
    switchData = false;    
    delay(2000); // Esperamos 2 segundos para medir los sensores
    //Enviamos los datos de los sensores
    //Sensor 1
    h1 = dht1.readHumidity();
    t1 = dht1.readTemperature();
    //Sensor 2
    h2 = dht2.readHumidity();
    t2 = dht2.readTemperature();
    // Retornamos loop si hay problemas de los sensores  
    if (isnan(h1) || isnan(t1) || isnan(h2) || isnan(t2)) {
      //Serial.print("{'data':'esp8266','estado':1,'humedadA':0,'tempboxA':0,'humendadB':0,'tempboxB':0,'rele5v':2,'Error':'Sensores con problemas de lectura!'}\n");
      return;
    }
    // Datos a enviar
    Serial.print("{'data':'esp8266','estado':0,'humedadA':"+String(h1)+",'tempboxA':"+String(t1)+",'humendadB':"+String(h2)+",'tempboxB':"+String(t2)+",'rele5v':2,'Error':''}\n");
    Serial.flush();
    delay(200);

Desde el ESP-01 lo siguiente :

void loop(){
    if (!ejecutado)
    {
      MDNS.update();    
      if (modo_sta == 1) {
        EnviandoMail(ip_actual, new_ssid_station);
      }
    }
    Captura();
}
void Captura(){
  // Monitor serial communication
  if(Serial.available()>0){
    message = Serial.readStringUntil('\n');
    messageReady=true;
  }
  if(messageReady){
    messageReady=false;
    DeserializationError error = deserializeJson(doc, message);
    if(error){
    }else{
      if(doc["data"]=="esp8266"){
        if(doc["estado"]==0&&doc["tempboxA"].as<long>()>0&&doc["tempboxB"].as<long>()>0){
          Esp01.clear();
          sen="";
          Esp01["dht11_hum"] = doc["humedadA"];
          Esp01["dht11_tem"] = doc["tempboxA"];
          Esp01["ntc100_tem"] = doc["tempboxB"];
          // ----------------------------------
          dht11B_temp         = doc["tempboxB"].as<long>();
          dht11A_temp         = doc["tempboxA"].as<long>();
          ConsultaRele(val_sensor_main,dht11B_temp);
          ConsultaRele(val_sensor_box, dht11A_temp);
          if(new_rele!=rele5v){
            rele5v=new_rele;
          }
          generaJSON(); // Almacena datos en LittleFS
          delay(200);
          serializeJson(Esp01,sen);
          writeFile(sen, "/json/sensores.json");
          delay(200);
          Serial.print("{'data':'nano','estado':0,'dht11A_hum':0,'dht11A_tem':0,'dht11B_hum':0,'dth11B':0,'rele5v':"+String(rele5v)+",'Mensaje':'Recepcion OK'}\n");
          Serial.flush();
        }else{
          Serial.print("{'data':'nano','estado':0,'dht11A_hum':0,'dht11A_tem':0,'dht11B_hum':0,'dth11B':0,'rele5v':"+String(rele5v)+",'Mensaje':'Recepcion con problemas'}\n");
          Serial.flush();
        }
      }
    }
  }    
}

Generalmente , Nano envia los datos, ESP-01 los recibe, pero no recibo por serial la respuesta de ESP-01.

Ambos estan a 9600. Iniciando de forma individual (tanto ESP como Nano), funcionan bien y no existe bloqueos o lag. Juntos, el nano se bloquea algunas veces y el ESP-01 he tenido que volver a enviarlos los datos del LittleFS, ya que, despues de bloquearse deblo flash nuevamente.

Si alguien tiene una mejor de idea de comunicacion por serial, acepto ideas y consejos.
Saludos a todos.

He realizado algunos ajustes de código y estoy usando serialevent(), funciona mejor pero al final termina bloqueandose el puerto serial. Se, que en teoría puedo usar los dos dht11 en la Nano y usar el módulo rele en el esp01 , de esta forma el nano de encarga de enviar los datos y el esp de mostrarlos y activar rele. Pero me cuesta pensar sea tan complejo procesar datos en el puerto serial.
Saludos a todos.

Usar serialEvent() es exactamente lo mismo que chequear el puerto serie al final del loop()
El código oculto de arduino es

void main()
{
  setup();
  while (1)
  {
    loop();
    serialEvent();
  }
}

Como ves no hay ningún beneficio real, no usa interrupciones ni nada parecido. En mi opinión complica más las cosas usarla.

Prueba no usar flush().
En la documentación no queda muy claro si borra o no el buffer de entrada luego de enviar los datos (para sacarse la duda habría que revisar las librerías pero...).

De paso

Serial.flush(); 
delay(200);

Usas flush() para esperar que se envíen todos los caracteres y luego pones otra espera de 200 mseg.
¿Qué sentido tiene ese delay?
En todo caso pon un delay acorde a la cantidad máxima de caracteres a enviar, 1 mseg por c/u y listo.

Gracias gatul, probaré lo que me comentaste, aunque el problema real es enviar ,esperar a que esos datos estén leídos para nuevamente enviar y no enviar datos al serial mientras aún no se lean los anteriores , y no me queda claro si los siguientes datos de ponen a la cola o Arduino a la mitad de lo mitad de todo... Por lógica parece que el puerto serial es secuencial, es decir, va insertando al final de los datos que tiene ... O por lo menos es lo que parece.

Obvio, van en cola, es un buffer FIFO.
De cualquier modo resolver eso es fácil, esperas una respuesta de ESP y listo.

Ahora, supongamos que no fuese así, ¿de que te sirve flush() en el supuesto de que realmente borra el buffer de entrada y te hace perder datos?

Haz tu propio protocolo. Que el ESP reenvíe lo que recibió para comparar con lo enviado, o un checksum básico de lo enviado, o por lo menos que devuelva "OK", y recien entonces envías datos nuevos.
Es mucho más simple de lo que parece.

Directamente ya es un error. ESP trabaja a 3.3V y NANO a 5V asi que si no usas level shifter o adaptadores de nivel a la larga vas a dañar la comunicación en el receptor del ESP01
Lo que envias es otro tema.
La comunicación a probar es el primer paso.
Pones un serial en uno y un serial virtual en el otro y te comunicas de lado a lado.
Cables cruzados RX y TX mas GND. pasando por adaptador de nivel.
Lo que envias no importa.
Concéntrate en la comunicación serie.

Para que semejante código si la comunicaicón en un sentido no funciona?

#include <SoftwareSerial.h>
SoftwareSerial miSerial(2, 3);   //Rx, Tx

void setup() {
   Serial.begin(9600);
   miSerial.begin(9600);
}

void loop() {
  if (miSerial.available()) {
    Serial.write(miSerial.read());
  }
  if (Serial.available()) {
    miSerial.write(Serial.read());
  }
}

Asegurate que esto funciona de un lado para el otro. Luego se va aumentando la dificultad.

O sea que no sabes si el ESP-01 esta enviando y si el NANO lo esta recibiendo.
En este caso no necesitas adaptador de nivel. ya que el nivel del ESP-01 es suficiente para el RX del NANO.
Obviamente si el otro lado funciona tienes GND.

Cuando esto este probado aparece el otro problema y es el DHT.
Como estas obligado a poner un delay(2000) seria bueno que lo pusieras en una rutina usando millis() lo que mantenga las comunicaicones. Cuando el dato nuevo de los DHT se actualice podras transmitirlo

El problema, esta resuelto de la siguiente forma :

CODIGO NANO ( loop() )

void loop() {
  stamp2 = millis();
  diftim1 = stamp2-stamp1;

  if( (diftim1/1000)>10&&switchData==false ){
    switchData=true;
    stamp1=millis();
  }
  Sensores();
  if(stringComplete){
    message=inputString;
    inputString="";
    stringComplete=false;
    Serial.flush();
    DynamicJsonDocument datos(300);
    DeserializationError error = deserializeJson(datos, message);
    JsonObject root = datos.as<JsonObject>();
    if(root["data"]=="nano"){
      rele = root["rele5v"];
      if(rele!=switchRele){
        switchRele=rele;
        digitalWrite(RELE,switchRele);
      }//IF Rele
    }// data Nano
  }
}
void serialEvent() {
  while (Serial.available()&&!stringComplete) {
    char inChar = (char)Serial.read();
    inputString += inChar;
    if (inChar == '\n') {
      stringComplete = true;
    }//If inChar
  } // Fin While
  // *****************************************
}
void Sensores(){
  if(switchData){
    switchData = false;    
    delay(2000); // Esperamos 2 segundos para medir los sensores
    //Enviamos los datos de los sensores
    //Sensor 1
    h1 = dht1.readHumidity();
    t1 = dht1.readTemperature();
    //Sensor 2
    h2 = dht2.readHumidity();
    t2 = dht2.readTemperature();
    // Retornamos loop si hay problemas de los sensores  
    if (isnan(h1) || isnan(t1) || isnan(h2) || isnan(t2)) {
      return;
    }
    // Datos a enviar
    Serial.print("{'data':'esp8266','estado':0,'humedadA':"+String(h1)+",'tempboxA':"+String(t1)+",'humendadB':"+String(h2)+",'tempboxB':"+String(t2)+",'rele5v':2,'Mensaje':''}\n");
  }// IF switchData  
}

CODIGO ESP-01 ( loop() )

void loop(){
    if (!ejecutado)
    {
      MDNS.update();    
      if (modo_sta == 1) {
        EnviandoMail(ip_actual, new_ssid_station);
      }
    }
    if(stringComplete){
      message=inputString;
      inputString="";
      stringComplete=false;
      Serial.flush();
      DynamicJsonDocument doc(512);
      DeserializationError error = deserializeJson(doc, message);
      if (error){return;}
      if(doc["data"]=="esp8266"){
        if(doc["estado"]==0&&doc["tempboxA"].as<long>()>0&&doc["tempboxB"].as<long>()>0){
          DynamicJsonDocument Esp01(512);
          sen="";
          Esp01["dht11_hum"] = doc["humedadA"];
          Esp01["dht11_tem"] = doc["tempboxA"];
          Esp01["ntc100_tem"] = doc["tempboxB"];
          // ----------------------------------
          dht11B_temp         = doc["tempboxB"].as<long>();
          dht11A_temp         = doc["tempboxA"].as<long>();
          ConsultaRele(dht11B_temp,val_sensor_main);
          ConsultaRele(dht11A_temp,val_sensor_box);
          if(new_rele!=rele5v){
            rele5v=new_rele;
          }
          serializeJson(Esp01,sen);
          writeFile(sen, "/json/sensores.json");
          delay(100);
          Serial.print("{'data':'nano','estado':0,'dht11A_hum':0,'dht11A_tem':0,'dht11B_hum':0,'dth11B_tem':0,'rele5v':"+String(rele5v)+",'Mensaje':'Recepcion OK'}\n");
          generaJSON();
        }else{
          Serial.print("{'data':'nano','estado':0,'dht11A_hum':0,'dht11A_tem':0,'dht11B_hum':0,'dth11B_tem':0,'rele5v':"+String(rele5v)+",'Mensaje':'Recepcion con problemas'}\n");
        }
      }
      message="";
    }
}
void serialEvent() {
  while (Serial.available()) {
    char inChar = (char)Serial.read();
    inputString += inChar;
    if (inChar == '\n') {
      stringComplete = true;
    }
  }
  // ************************************************************
}

Con lo anterior, el Nano envia los datos, tomando 2 segundos para medir y espera siempre 10 segundos máximos para volver a enviar datos, esto asumiendo que pudiese existir algún retardo o perdida de datos retornados desde el ESP-01.

Con esto he logrado mantener de forma fluida el ESP-01 que lo tengo cargado con bootstrap, claro que, con webserver asyncronico.

He usado un flush() al final de cada lectura del serial y efectivamente mantiene limpio el buffer del serial.

También para evitar problemas en la serialización he usado la "as()" para castear el retorno del ESP, sin el, por alguna razón, el resultado de la deserialización daba error.

Gracias muchachos por la ayuda e ideas.

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