Arduino-Arduino RF Communication, la tecla debe presionarse varias veces

-1

Estoy comunicando dos Arduino, es decir, Arduio UNO como remitente & Arduino Mega como receptor a través del módulo transiver RF-433 MHz. La comunicación está funcionando, pero hay un problema. Si quiero enviar un mensaje, digamos, un número o un carácter, tengo que enviar ese número o carácter varias veces utilizando el monitor de serie Arduino. En otras palabras, tengo que presionar esa tecla y enviar varias veces antes de que el receptor pueda recibir el mensaje y actuar en consecuencia.

Pregunta: ¿Qué debo hacer para que mi receptor reciba el mensaje con solo presionar una tecla?

Mis códigos:

Código del transmisor:

/* Bomb Displacing and Disposing Robot
Transmitter Code (Arduino UNO)  */

#include <VirtualWire.h>
int wrongSignal = 8;
void setup()
{
  Serial.begin(9600);
  vw_setup(2400);
  vw_set_tx_pin(7);
  pinMode(wrongSignal,OUTPUT);
}
void loop()
{
 if(Serial.available())
{ 
  char c= Serial.read();

  if(c == '8')              //To move foreward
  {
    vw_send((uint8_t *)c, 1);    //send one bit i.e. 8
  }
  else if(c=='4')                //To move left
  {
    vw_send((uint8_t *)c, 1);    //send one bit i.e. 4
  }
  else if (c=='6')                //To move right
  {
  vw_send((uint8_t *)c, 1);        //send only one bit i.e. 6
  }
  else if(c=='2')                  // To move reverse
  {
  vw_send((uint8_t *)c, 1);        // send only one bit i.e. 2
  }
 else if(c=='5')                  // To stop
  {
  vw_send((uint8_t *)c, 1);        // send only one bit i.e. 5
  }

  else if(c=='0')                  // To stop
  {
  vw_send((uint8_t *)c, 1);        // send only one bit i.e. 5
  }
       Serial.println(c);
}
      else
            digitalWrite(wrongSignal, HIGH);

}

Código del receptor:

//Receiver Code (Arduino Mega ADK 2560)


#include <VirtualWire.h>
// extra pins --------------------------------      
const int wrongSignal = 8;      // for indication that user sending invalid command
const int enablePin = 12;       // enable of the ICs used in circuit
//---------------------------------------------

// base controling pins -------------------

    // Front Left motor M1
    const int frontLeft1 = 30;
    const int frontLeft2 = 31;

    // Front Right motor M2
    const int frontRight1 = 32;
    const int frontRight2 = 33;

    //Back Left motor M3
    const int backLeft1 = 34;
    const int backLeft2 = 35;

    //Back Right motor M4    
    const int backRight1 = 36;
    const int backRight2 = 37;
//------------------------------------------

void setup() {

  //Extra pins
  pinMode(enablePin, OUTPUT);   // initialize the enable pin as an output
  pinMode(wrongSignal, OUTPUT);   //initialize wrongSignal pin as output pin

  // for Motor drive IC pins
  pinMode(frontLeft1, OUTPUT);
  pinMode(frontLeft2, OUTPUT);

  pinMode(frontRight1, OUTPUT);
  pinMode(frontRight2, OUTPUT);

  pinMode(backLeft1, OUTPUT);
  pinMode(backLeft2, OUTPUT);

  pinMode(backRight1, OUTPUT);
  pinMode(backRight2, OUTPUT);

  digitalWrite(enablePin, HIGH);
  Serial.begin(9600);   // initialize serial communications:
   vw_setup(2400);      // baud rate is 2400
   vw_set_rx_pin(7);    // Receiver pin is pin 7
   vw_rx_start();        // start receiving
}
void loop()
{

  uint8_t buflen = VW_MAX_MESSAGE_LEN;
  uint8_t buf[buflen];

  if(vw_get_message(buf, &buflen))
  {

    for (int i = 0; i < buflen; i++)
    {
      if (buf[i] == '8')                  // move forward, all motors uni-direction
      { 
        digitalWrite(frontLeft1, HIGH);
        digitalWrite(frontLeft2, LOW);
        digitalWrite(frontRight1, HIGH);
        digitalWrite(frontRight2, LOW);
        digitalWrite(backLeft1, HIGH);
        digitalWrite(backLeft2, LOW);
        digitalWrite(backRight1, HIGH);
        digitalWrite(backRight2, LOW);
        }  

        else if (buf[i] == '4')              // move left, M1 >, M4 <
        {
        digitalWrite(frontLeft1, HIGH);    //M1
        digitalWrite(frontLeft2, LOW);
        digitalWrite(frontRight1, LOW);     //M2
        digitalWrite(frontRight2, LOW);
        digitalWrite(backLeft1, LOW);      //M3
        digitalWrite(backLeft2, LOW);
        digitalWrite(backRight1, LOW);      //M4
        digitalWrite(backRight2, HIGH);
      }

  // If the input is '0', turn off the ledPin i.e. send a low signal

  else if (buf[i] == '6')                // move right, M2>, M3<
  {
        digitalWrite(frontLeft1, LOW);      //M1
        digitalWrite(frontLeft2, LOW);
        digitalWrite(frontRight1, HIGH);      //M2
        digitalWrite(frontRight2, LOW);
        digitalWrite(backLeft1, LOW);      //M3
        digitalWrite(backLeft2, HIGH);
        digitalWrite(backRight1, LOW);      //M4
        digitalWrite(backRight2, LOW);
  }

    else if (buf[i] == '2')                // reverse
    {
        digitalWrite(frontLeft1, LOW);
        digitalWrite(frontLeft2, HIGH);
        digitalWrite(frontRight1, LOW);
        digitalWrite(frontRight2, HIGH);
        digitalWrite(backLeft1, LOW);
        digitalWrite(backLeft2, HIGH);
        digitalWrite(backRight1, LOW);
        digitalWrite(backRight2, HIGH);
  }    

    else if (buf[i] == '5')                  // all motors stop
    {
        digitalWrite(frontLeft1, LOW);
        digitalWrite(frontLeft2, LOW);
        digitalWrite(frontRight1, LOW);
        digitalWrite(frontRight2, LOW);
        digitalWrite(backLeft1, LOW);
        digitalWrite(backLeft2, LOW);
        digitalWrite(backRight1, LOW);
        digitalWrite(backRight2, LOW);
  }        

    else if (buf[i] == '0')                  // all motors stop
    {
        digitalWrite(frontLeft1, LOW);
        digitalWrite(frontLeft2, LOW);
        digitalWrite(frontRight1, LOW);
        digitalWrite(frontRight2, LOW);
        digitalWrite(backLeft1, LOW);
        digitalWrite(backLeft2, LOW);
        digitalWrite(backRight1, LOW);
        digitalWrite(backRight2, LOW);
  }        
       else
          digitalWrite(wrongSignal, HIGH);



  }
 }
}
    
pregunta Muhammad Hayat

2 respuestas

0

Para mí, a su receptor le pueden faltar algunos de los paquetes transmitidos. Tal vez el transmisor y el receptor estén demasiado alejados o las antenas estén mal.

Otra razón común para perder paquetes es una mala programación en el receptor. Por ejemplo, su receptor puede estar en una llamada de demora () cuando llega el paquete y lo pierde. Pero no puedo identificar tales problemas en su código, ya que siempre está comprobando si han llegado paquetes. En cualquier caso, para eliminar esa posibilidad, puede quitar los módulos del transmisor y el receptor (si es posible en su configuración) y colocar un cable entre TX y RX del transmisor y el receptor, respectivamente. Además, conecte los terrenos de ambos tableros juntos. Luego ve si aún pierdes paquetes en el proceso. Consulte este enlace para obtener más información sobre el proceso.

Para tratar de encontrar problemas de transmisión de RF (sin equipo profesional), puede cargar los programas a continuación en las tarjetas del transmisor y del receptor, respectivamente, y ver si hay paquetes perdidos. El transmisor enviará una secuencia de enteros. Solo tienes que comprobar si se dirigen al receptor en secuencia.

Programa de prueba para el transmisor:

#include <VirtualWire.h>

void setup()
{
    Serial.begin(9600);   // Debugging only
    Serial.println("setup");
    pinMode(13, OUTPUT);     

    // Initialise the IO and ISR
    //vw_set_ptt_inverted(true); // Required for DR3100
    vw_set_tx_pin(2);
    vw_setup(2000);  // Bits per sec
}

uint8_t buf[VW_MAX_MESSAGE_LEN];
uint8_t buflen = VW_MAX_MESSAGE_LEN;

int counter = 0;

void loop()
{
    digitalWrite(13, true); // Flash a light to show transmitting
    buf[0] = counter / 256;
    buf[1] = counter % 256;
    vw_send(buf, 2);
    vw_wait_tx(); // Wait until the whole message is gone
    counter++;
    digitalWrite(13, false);
    delay(100);
}

Programa de prueba para el receptor:

#include <VirtualWire.h>

void setup()
{
  Serial.begin(9600);   // Debugging only
  Serial.println("setup");
  pinMode(13, OUTPUT);     
  // Initialise the IO and ISR
  //vw_set_ptt_inverted(true); // Required for DR3100
  vw_set_rx_pin(2);
  vw_setup(2000);    // Bits per sec

  vw_rx_start();       // Start the receiver PLL running
}

void loop()
{
  uint8_t buf[VW_MAX_MESSAGE_LEN];
  uint8_t buflen = VW_MAX_MESSAGE_LEN;

  if (vw_get_message(buf, &buflen)) // Non-blocking
  {
    digitalWrite(13, true); // Flash a light to show received good message
    // Message with a good checksum received, dump it.
    Serial.print("Got: ");

    for (int i = 0; i < buflen; i++)
    {
      Serial.print(buf[i], HEX);
      Serial.print(" ");
    }
    Serial.println("");        
    digitalWrite(13, false);
  }
}
    
respondido por el Ricardo
3

He encontrado este problema antes. Se trató de no enviar un preámbulo suficientemente largo de 1 y 0 antes de que se transmitan los datos "reales". Los dispositivos de comunicación de RF como este necesitan enviar un preámbulo para permitir que el hardware receptor se bloquee en la transmisión. Es el cortador de datos de RX (que sigue al receptor de RF) el que debe arrastrarse y alinearse con la salida del demodulador antes de que funcione correctamente; esto es para la transmisión y recepción de tipo FM.

Para AM, hay una situación similar: el circuito de AGC del receptor se irá borrando alrededor del ruido hasta que se envíe la transmisión correcta. El AGC toma el tiempo para adquirir los ajustes correctos y evitar que se active el ruido.

La longitud del preámbulo debe ser de varios mili segundos, pero verifique la hoja de datos. Aquí está mi interpretación de lo que sucede en un sistema de FM: -

A la izquierda de la imagen no se transmite nada y el receptor está intentando bloquear el ruido de forma aleatoria (curva roja). La línea azul es un promedio de la línea roja: ambas señales alimentan un comparador de voltaje. Una vez que se está enviando una transmisión de datos real, el promediador comienza la alineación y después de algunos bits de preámbulo, se alinea y los bits genuinos comienzan a salir de la salida del cortador de datos. Una MCU conectada a la salida del seccionador de datos tiene que reconocer primero el preámbulo, luego, cuando llegan los datos de la carga útil, puede ver que no es un preámbulo porque tendrá un formato diferente (dos bits de parada son comunes para usar el lenguaje de un UART) .

Esto es solo una sugerencia basada en mis experiencias.

    
respondido por el Andy aka

Lea otras preguntas en las etiquetas