Comunicación Inalámbrica con módulos de RF de 433Mhz Deja un comentario

En este tutorial vamos a realizar una comunicación inalámbrica entre dos Arduino usando módulos de radiofrecuencia de bajo costo.

Los módulos RF de 433Mhz son muy populares por su bajo costo y fácil uso. Vienen en pareja, emisor (FS1000A) y receptor (XY-MK-5V), el tipo de comunicación es simplex, es decir en un solo canal y unidireccional, son de baja velocidad de transmisión pero para  aplicaciones básicas son muy útiles.

Módulo RF 433MHz TX y RX

La frecuencia de trabajo es de 433MHz, debido a que es una banda de libre uso. Para utilizar estos módulos basta con alimentarlos y conectar el pin de datos por un lado del Transmisor (TX) y en otro el Receptor (RX). Para la programación no es necesario agregar ningún tipo de librería, ya que es un proceso “transparente”, por lo que el programa sería igual a usar una comunicación serial (UART) entre 2 MCUs , sin embargo existen algunas librerías que nos ofrecen ciertas ventajas como: verificación de errores, mejor transmisión, Direccionamiento, Enrutamiento, mallas, etc.

La antena tiene una gran influencia sobre todo en el módulo receptor, por lo que se recomienda conectar un cable de cobre de unos 17cm de largo para alcanzar la frecuencia de 433MHz.Tambien son muy comunes y eficientes antenas helicoidales de 5mm de diámetro y 3.4cm de longitud. La posición de la antena también afecta la recepción de datos.

medidas de antena modulo RF 433Mz

Para este tutorial se está usando antenas helicoidales.

Antena elicoidal

Para este tipo de comunicación solo basta con conectar el módulo RF al  Pin RX o TX del Arduino dependiendo si es transmisor y receptor.

Para este ejemplo usaremos un Arduino el cual transmitirá seriamente información a través del RF transmisor, el módulo receptor está conectado a un conversor USB serial (Puedes usar otro Arduino en lugar del conversor) y visualizaremos los datos des de la pc.

La conexión es la siguiente:

Conexiones del emisor:

Conexion RF emisor Serial

Conexiones del receptor

Conexion receptor rf conversor usb serialCon respecto al programa se trabaja como si se tratase de una comunicación serial (UART) normal, con el inconveniente que no existe validación o seguridad para saber si los datos son transmitidos correctamente. Pero se puede usar para visualizar mensajes o datos que sean redundantes o que no sean necesarios validar.

Para lograr  una mejor transferencia se recomienda usar velocidades de 1200 o 2400 baudios o inferiores.

A continuación se muestra un código de ejemplo para testear nuestros módulos.

void setup() {
   // Inicializamos la comunicación serial a 2400 baudios
  Serial.begin(2400);

}

void loop() {
  Serial.print("Hola mundo ... ");
  Serial.print(millis()); // enviamos  los ms transcurridos
  Serial.println("ms");
  delay(10);    
}

Para visualizar los datos recibidos, en herramientas cambiamos al puerto COM al del conversor,  abrimos el Monitor serial y cambiamos la velocidad a 2400 baudios, debemos recibir los datos como se muestra en la siguiente imagen

comunicacion serial RF

Existen varios métodos para validar información, una de las más fácil de implementar es en enviar el mismo dato varias veces, por ejemplo 3 veces y en el receptor se debe validar verificando que se reciba 3 veces el mismo dato. Otros métodos son la paridad, agregar tramas de validación, sumar los bytes trasmitidos, etc.

Comunicación inalámbrica RF entre Arduinos usando librerías

Una de las librería más comunes y eficientes es la VirtualWire desarrollado por Mike McCauley, con esta librería vamos a trabajar los proximos ejemplos del tutorial

Necesitamos descargar la librera VirtualWire e importarla a nuestro IDE Arduino.

A continuación explicamos  las funciones principales  de la librería:

void vw_setup(uint16_t speed)

Inicializar el software VirtualWire, como parámetro hay que indicarle la velocidad de operación, que representa los bits por segundo para la transmisión RF

void vw_set_tx_pin(uint8_t pin)

Estable el pin IO digital por donde se va a transmitir los datos

void vw_set_rx_pin(uint8_t pin)

Estable el pin digital IO por donde se va a recibir datos.

void vw_rx_start()

Empieza a escuchar los datos provenientes por el pin_rx, es necesario llamar a esta función para poder recibir los datos

uint8_t vw_send(uint8_t * buf,uint8_t len )

Enviar un mensaje con la longitud dada. La función termina rápido pero mensaje será enviado en el momento adecuado establecido por las interrupciones.  Dónde: buf , es el puntero al vector para trasmitir. Y len es el número de bytes a transmitir

void vw_wait_tx()

Hace una pausa hasta que se trasmitan todos los datos.

uint8_t vw_get_message(uint8_t * buf, uint8_t * len )             

Si un mensaje está disponible (con buena suma de comprobación o no), almacena el mensaje en buf , devuelve true si la comprobación es correcta. buf es puntero a la ubicación para guardar los datos de lectura y leng es un puntero a la cantidad de bytes disponibles de buf.

Antes de empezar a programar necesitamos hacer las siguientes conexiones:

Conexiones del Emisor:

Conexion RF emisor y arduino

Conexiones del receptor:

Conexion RF receptor y Arduino

En este ejemplo se encenderá un led conectado al pin 13 del Arduino, para apagar y prender se lo hará de forma remota desde otro Arduino, para enviar la orden lo haremos desde la PC pero se lo puede hacer a través de un pulsador.

El código del Emisor es el siguiente:

#include <VirtualWire.h>

void setup()
{
    Serial.begin(9600);	  
    Serial.println("Emisor RF");

    // Se inicializa el RF
    vw_setup(2000); // velocidad: Bits per segundo
    vw_set_tx_pin(2); //Pin 2 como salida para el RF 
}

void loop()
{

    
    while (Serial.available() > 0) 
    {
      char dato[1];
      dato[0] = Serial.read();
      //Enviamos el carácter recibido al RF
      vw_send((uint8_t*)dato,sizeof(dato));
      vw_wait_tx();         
    }
    delay(200);
}

Como se observa el programa envía inalámbricamente el dato que recibe por el puerto serie.

EL código del receptor se muestra a continuación:

#include <VirtualWire.h>

void setup()
{
    Serial.begin(9600);	// Debugging only
    Serial.println("setup");

    // Se inicializa el RF
    vw_setup(2000);	 // velocidad: Bits per segundo
    vw_set_rx_pin(2);  //Pin 2 como entrada del RF
    vw_rx_start();       // Se inicia como receptor
    
    pinMode(13, OUTPUT);    //Configuramos el pin del Led como entrada
    digitalWrite(13, false);
}

void loop()
{
    uint8_t dato;
    uint8_t datoleng=1;
    //verificamos si hay un dato valido en el RF
    if (vw_get_message(&dato,&datoleng))
    {
        if((char)dato=='a')
        {
            digitalWrite(13, true); //Encendemos el Led
        }
        else if((char)dato=='b')
        {
            digitalWrite(13, false); //Apagamos el Led
        }            
    }
}

Para encender el led es necesario abrir el monitor serial del trasmisor y enviar una “a” o “b” para encender o apagar el Led respectivamente

En este ejemplo un Arduino envía una mensaje  “Hola mundo” hacia otro Arduino receptor, para visualizar el mensaje recibido usaremos el monitor serial.

Código del Emisor:

#include <VirtualWire.h>

void setup()
{
    Serial.begin(9600);	
    Serial.println("Emisor: Setup");

    // Se inicializa el RF
    vw_setup(2000);	// velocidad: Bits per segundo
    vw_set_tx_pin(2); //Pin 2 como salida para el RF 
}

void loop()
{
    const char *msg = "Hola mundo";

    digitalWrite(13, true); // Parpadeamos  el led al enviar 
    vw_send((uint8_t *)msg, strlen(msg));
    vw_wait_tx(); //Esperamos hasta que el mensaje se envie
    digitalWrite(13, false);
    delay(200);
}

Código del receptor:

#include <VirtualWire.h>

void setup()
{
    Serial.begin(9600);	// Debugging only
    Serial.println("Emisor: Setup");

    // Se inicializa el RF
    vw_setup(2000);	 // velocidad: Bits per segundo
    vw_set_rx_pin(2);    //Pin 2 como entrada del RF
    vw_rx_start();       // Se inicia como receptor
}

void loop()
{
    uint8_t buf[VW_MAX_MESSAGE_LEN];
    uint8_t buflen = VW_MAX_MESSAGE_LEN;
    //verificamos si hay un dato valido en el RF
    if (vw_get_message(buf, &buflen)) 
    {
	int i;

        digitalWrite(13, true); // Parpadeamos  el led al recibir
	//verificamos si hay un dato valido en el RF
	Serial.print("Mensaje: ");
	
	for (i = 0; i < buflen; i++)
	{
	    Serial.print((char)buf[i]);
	}
	Serial.println("");
        digitalWrite(13, false);
    }
}

Para visualizar los datos es necesario abrir el monitor serial del receptor.

Mensaje Hola mundo RF

La librería principalmente trasmite cadenas de bytes, que pueden ser una cadena de texto o un dato convertido en cadena, pero cuando se necesitan enviar varios datos hay dos formas de hacerlo, un método es empaquetar todo en una sola trama y enviarlo, el receptor debe de desempaquetar y obtener los datos.

Otra forma más sencilla es enviar un inicio de trama diferente para cada dato, el cual indicara al receptor que dato es el que se está enviando, el siguiente ejemplo lo hacemos de esta forma, enviaremos dos  datos, cada uno con un inicio de trama diferente.

Código del emisor:

#include <VirtualWire.h>

void setup()
{
    Serial.begin(9600);	  // Debugging only
    Serial.println("setup");

    // Se inicializa el RF
    vw_setup(2000); // velocidad: Bits per segundo
    vw_set_tx_pin(2); //Pin 2 como salida para el RF 
}

void loop()
{
    char buf[VW_MAX_MESSAGE_LEN]; // Cadena para enviar
    int dato1=millis()/1000; //variable con el tiempo en segundos
    float dato2=3.14;   //segundo dato para enviar
    String str="";  
    
    str="i"+String(dato1); //convertimos el entero a String y agramos un inicio de trama
    str.toCharArray(buf,sizeof(buf)); //convertimos el String en un array
    vw_send((uint8_t *)buf, strlen(buf)); //Enviamos el array
    vw_wait_tx(); //Esperamos hasta que el mensaje se envie
    
    str="f"+String(dato2); //convertimos el float a String y agramos un inicio de trama
    str.toCharArray(buf,sizeof(buf)); //convertimos el String en un array
    vw_send((uint8_t *)buf, strlen(buf)); ////Enviamos el array
    vw_wait_tx(); //Esperamos hasta que el mensaje se envie
    
    delay(200);
}

Código del Receptor

#include <VirtualWire.h>

void setup()
{
    Serial.begin(9600);	// Debugging only
    Serial.println("Receptor: setup");

    // Se inicializa el RF
    vw_setup(2000);	 // velocidad: Bits per segundo
    vw_set_rx_pin(2);    //Pin 2 como entrada del RF
    vw_rx_start();       // Se inicia como receptor
}

void loop()
{
    uint8_t buf[VW_MAX_MESSAGE_LEN];
    uint8_t buflen = VW_MAX_MESSAGE_LEN;
    int dato1=0;
    float dato2=0.0;
    //verificamos si hay un dato valido en el RF
    if (vw_get_message((uint8_t *)buf,&buflen))
    {
	int i;
	String  DatoCadena="";
        if((char)buf[0]=='i') //verificamos el inicio de trama
        {
            for (i = 1; i < buflen; i++)
            {
        	DatoCadena.concat((char)buf[i]);
            }
            dato1=DatoCadena.toInt();
            Serial.print("Dato1 recivido: ");
            Serial.println(dato1);
        }
        else if((char)buf[0]=='f') //verificamos el inicio de trama
        {
            for (i = 1; i < buflen; i++)
            {
        	DatoCadena.concat((char)buf[i]);
            }
            dato2=DatoCadena.toFloat();
            Serial.print("Dato2 recivido: ");
            Serial.println(dato2);
        }
    }
}

Los datos lo visualizaremos  en el monitor serial del receptor

Transmision de datos por RF

Pueden adquirir los materiales usados en este tutorial en nuestra tienda

– Arduino Uno R3

– Módulo RF 433MHz TX y RX

– Cable Dupont, hembra a macho 20cm x 20Und

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

0
    0
    Tu Carrito
    Tu carrito esta vacíoVolver a la tienda
    Enviar Whatsapp
    Hola 👋
    ¿En qué podemos ayudarte?