Comunicación entre arduinos

Hola, tengo un problema.
Estoy enviando tramas por medio de un Arduino Nano a un Arduino Mega; utilizando la librería SoftwareSerial.h rx pin 3 y tx pin 4 del Nano y en el Mega utilizo utilizo el Serial 2. El problema es que llega un segundo (más o menos) después de la trama de ser enviada al Arduino Mega. Pensé que era porque estaba utilizando Serial.flush en el enviado de las tramas, se lo quite (leí que retardaba un poco el enviado por que verifica que si se envía los datos) y aún así no se tardaba un segundo en llegar. La trama contiene la detección de unos sensores de movimientos, ya veces el cambio de sensor es menor a un segundo, entonces no logro visualizar el movimiento, aunque en el Arduino Nano si lo detecta (por medio puerto Serial del arduino), y ya no llega se visualiza en el Arduino Mega, además envía una trama a cada minuto siempre .
Lo que busco es saber si en mi forma de enviar datos lo estoy haciendo mal, o en la recepción, o alguna técnica para poder agilizar el envió de las tramas
Partes del código en el Arduino nano

#include <SoftwareSerial.h>

#define rxPin 3
#define txPin 4

SoftwareSerial PlacaDos(rxPin,txPin);
// esto en el setup
  PlacaDos.begin(9600);

// esto va en el void loop
  //Envio de trama cada 1 minuto
  if((tiempoT1-tiempoT0 >= 60000)&&(envtu == 0)){
    PlacaDos.print("T");      //Inicia la trama de telemetria
    PlacaDos.write(",");
    PlacaDos.print(rpm);    //revoluciones por minuto
    PlacaDos.write(",");
    PlacaDos.print(Diesel,1); //valor del sensor de Disel de 0 a 1023
    PlacaDos.write(",");
    PlacaDos.print(carga,1);  //Carga de la bateria
    PlacaDos.write(",");
    PlacaDos.print(rpmdos);   
    PlacaDos.write(",");
    PlacaDos.print(adc_carga);  
    PlacaDos.write(",");
    PlacaDos.print(presion);    
    PlacaDos.write(",");
    PlacaDos.println("#");
    //Serial.println("");
    PlacaDos.flush();           //Limpia el buffer serial
    
    Serial.print("T");      //Inicia la trama de telemetria
    Serial.write(",");
    Serial.print(rpm);    //revoluciones por minuto
    Serial.write(",");
    Serial.print(Diesel,1); //valor del sensor de Disel de 0 a 1023
    Serial.write(",");
    Serial.print(valorDisel); //valor del sensor de Disel de 0 a 1023
    Serial.write(",");
    Serial.print(carga,1);  //Carga de la bateria
    Serial.write(",");
    Serial.print(contadorRev);   
    Serial.write(",");
    Serial.print(adc_carga);  
    Serial.write(",");
    Serial.print(presion);   
    Serial.write(",");
    Serial.println("#");
    //Serial.println("");
    //Serial.flush();           //Limpia el buffer serial
    tiempoT0=millis();        
  }
// sendet lo asigna el sensor que detecta el movimiento
  if((envtmov == 1)&&((envtu == 0)||(sendet=='o'))){
    if(elijeson ==1 ){
      sionotm ='S';
    }
    else{
      sionotm ='N';
    }
    tiempoTM1=millis();
    if(tiempoTM1-tiempoTM0 >= 1050){
      PlacaDos.print("M");    //Inicia trama de movimientos
      PlacaDos.write(",");
      PlacaDos.print(sendet); // Sensor detectado
      PlacaDos.write(",");
      PlacaDos.print(sionotm); // Confirma con S que si está en el estado correcto y con una N que no 
      PlacaDos.write(",");    
      PlacaDos.println("#");
      PlacaDos.flush();
      Serial.print("M");    //Inicia trama de movimientos
      Serial.write(",");
      Serial.print(sendet); // Sensor detectado
      Serial.write(",");
      Serial.print(sionotm); // Confirma con S que si está en el estado correcto y con una N que no 
      Serial.write(",");          
      Serial.println("#");      //Final de la trama 
      envtmov=0;
      elijeson=0;
      tiempoTM0=millis();  
    }
  }

En el arduino Mega está así la recepcción:

  Serial2.begin(9600); // Serial que le pertenece a la Recepción de Datos


  if (Serial2.available()>0){
    String option = Serial2.readString();
    elemento0   = s.separa(option, ',', 0);
    elemento1   = s.separa(option, ',', 1);
    elemento2   = s.separa(option, ',', 2);
    elemento3   = s.separa(option, ',', 3);
    elemento4   = s.separa(option, ',', 4);
    elemento5   = s.separa(option, ',', 5);
    elemento6   = s.separa(option, ',', 6);
    elemento7   = s.separa(option, ',', 7);
    elemento8   = s.separa(option, ',', 8);
    Serial2.flush();
    Serial2.end();

    if (elemento0=="T"){
        telemetria();
    }
    if (elemento0=="M"){
      movimientos();
    }

void movimientos(){

  String Sensor = elemento1;
  String Final  = elemento2;  

  Serial_E.begin(115200);
  Serial_E.print("M");      Serial_E.write(",");
  Serial_E.print(Sensor);   Serial_E.write(",");
  Serial_E.print(lati,7);   Serial_E.write(",");
  Serial_E.print(lon,7);    Serial_E.write(",");
  Serial_E.print("#"); 
  Serial_E.end();


  Serial.print("M");      Serial.print(",");
  Serial.print(Sensor);   Serial.print(",");
  Serial.print(lati,7);   Serial.print(",");
  Serial.print(lon,7);    Serial.print(",");
  Serial.print("#"); 
  Serial2.begin(9600);

  String LCD;

  if (Sensor=="d"){
    LCD = "Abajo";
    }
  if (Sensor=="u"){
    LCD = "Arriba";
    }
  if (Sensor=="c"){
    LCD = "Cerrado";
    }
  if (Sensor=="r"){
    LCD = "Derecha 1";
    }
  if (Sensor=="R"){
    LCD = "Derecha 2";
    }
  if (Sensor=="l"){
    LCD = "Izquierda 1";
    }
  if (Sensor=="L"){
    LCD = "Izquierda 2";
    }
  if (Sensor=="o"){
    LCD = "Abierto";
    }
  lcd.setCursor(0,1);
  lcd.print("                ");
  lcd.setCursor(0,1);
  lcd.print(LCD);
}

Cualquier aporte es bienvenido. Gracias

Sin ver los códigos completos es complicado, llamas a funciones que no se que hacen o si tienen delay.

Si te sirve de referencia, yo mando un GET vía web a un ESP8266, este analiza lo que hay dentro del GET y lo envía por puerto serie a un MEGA, y desde que hago el GET hasta que se activa el relé en MEGA no se percibe ningún retraso, es decir que es inferior a 200 ms

¿El problema no será esto?

if(tiempoTM1-tiempoTM0 >= 1050){

Hola krnlpanic Básicamente lo que hago es enviar tramas a cada cierto tiempo, una la envió cada minuto, y otra un segundo después de que lee el sensor, y en ambas las veo en el otro Arduino 1,3 segundos después más o menos. No uso ningún delay, soy un poco inexperto en esto, el get lo usas en recepción? Gracias por responder

Hola gatul, esto solo lo utilizo para enviar esa trama, un segundo luego de leer el sensor, pero llega siempre un segundo después que entre en el if. No se si me explicó. Gracias por responder

El GET viene de una web que tengo en el ESP8266, este le envía el comando al MEGA

Si pedimos el código completo es porque con lo que has subido no vemos el fallo ni podemos reproducirlo.

krnlpanic:
El GET viene de una web que tengo en el ESP8266, este le envía el comando al MEGA

Si pedimos el código completo es porque con lo que has subido no vemos el fallo ni podemos reproducirlo.

Adjunto los códigos completos, perdón la demora. Creo que el problema es en el código de recepción. Gracias por tu interés
Código de envió (Arduino Nano)
C_digo_de_envio_de_las_tramas.ino

Código de recepción(Arduino Mega)
codigo_de_recepcion.ino

tuve que adjuntarlo ya que por la cantidad de líneas de código no me dejo publicarlos

codigo_de_recepcion.ino (9.97 KB)

C_digo_de_envio_de_las_tramas.ino (16.8 KB)

No encuentro la librería Separador.h.

Las variables que imprime son diferentes supongo que no esperas enviar lo mismo que en consola.
También puedes ver que le ha tomado 35ms para hacer el envío de la trama.

21:28:07.205 -> ENVIO A MEGA   T,480,0.9,-3.9,0,0.00,14,#
21:28:07.240 -> CONSOLA SERIAL T,480,0.9,19.00,-3.9,19,0.00,14,#

He visto que usas interrupción para medir las rpm, yo no las he utilizado nunca y no se exactamente como funciona, creo que se saltan parte del código para atender esa "llamada", a ver si alguien nos lo aclara.
Prueba a desconectar el pin del sensor rpm a ver si sigue con el retardo.

Saludos
Estoy mirando tu código completo, veo que es una reinterpretación del trabajo de Llamas

Hay pocos comentarios aclaratorios, y una gran necesidad de sensores externos que dificultan que nadie más que tú pueda probarlo

¿Puedes aclararnos qué parte exacta del código crees que se relentiza?

Seguro que con eso podemos diseñarte una solución para hacer seguimiento y verificación, pero es imposible estar seguro porque no se puede probar por nadie que no tenga exactamente el mismo hardware.

Que tal krnlpanic, adjunto la librería separador.zip
Cómo puedo ver ese tiempo?, yo hice el cálculo del tiempo con temporizador externo
eso me confirma un poco más que el problema es en la recepción, además del serial que está con el arduino Nano, leo otros seriales con el Mega.
Fíjate que las pruebas que realice fue sin tener nada conectado al rpm y conectado ya con rpm de lectura, pero siempre se visualizo en la LCD o en el bluetooth un segundo después.

separador.zip (6.82 KB)

Hola TonyDiana, creo que mi poco experiencia con la librería SofwareSerial era el problema en la transmisión, no se si la estoy usando de la manera correcta, pensé que colocarle el .flush ralentizaba el envió pero lo quite y seguía tardándose. Entonces creo que el problema es en la recepción, como recibo los datos, y tal vez que esté leyendo varios seriales y no priorice el serial que va al Arduino Nano.

Moderador:
Por favor no repitas lo que otra persona te dice. Ya se lee en el post correspondiente.
Menciona a la persona por su nick y nada mas.
Usa quote o cita para indicar el párrafo no todo el post.
Edita todos los post donde repites por favor.

Item 14 de las normas del foro, último párrafo, si quieres leer al respecto.
Gracias.

Lo siento no he podido mirarlo todavía ando muy liado y lo tengo pendiente.

Prueba a imprimir por serial lo que ahora imprimes en el LCD a ver si te tarda tanto en mostrar la info.

Después de varias pruebas incluso subiendo a 115200 veo que la función Serial2.readString(); es la que causa el retardo, si usas Serial2.read(); desaparece y es instantáneo.

Para hacer la prueba lo he hecho así

  String option;
  byte fin = 0;
  if (Serial2.available() > 0) {
    char ch = Serial2.read();
    Serial.print(ch);
    option = option + String(ch);
    fin = 1;
  }
  if (fin) {
    fin = 0;
    elemento0   = s.separa(option, ',', 0);
    elemento1   = s.separa(option, ',', 1);
    elemento2   = s.separa(option, ',', 2);

Con esa función viene un timeout por defecto de 1000ms puedes ajustarlo, te dejo el link

krnlpanic hola, perdón por no responder antes. Agradezco mucho tu ayuda. Lo probaré

Saludos.

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