256

Tutorial de Arduino y de radiofrecuencia con VirtualWire

portada_rf

¡Hola! Hoy voy a explicaros cómo conectar dos placas Arduino de forma inalámbrica con un módulo de radiofrecuencia RF 433MHZ.

rf_modules

Emisor (izquierda) y receptor(derecha)

Estos módulos vienen en parejas: un receptor y un emisor que se comunican mediante ondas de radio. No son ninguna maravilla, pero permiten comunicar dos dispositivos… ¡por poco dinero! Cuestan entre 2 y 5 euros el par.

Cómo programar estos chismes desde cero es muy laborioso, podemos utilizar la librería VirtualWire. Esta librería se encarga de gestionar las funciones más básicas de estos módulos de radiofrecuencia low-cost: envío de información, comprobación de los paquetes de datos…
Os recomiendo que descarguéis la librería desde este enlace. Los que no sepáis cómo instalar librerías en Linux, seguid nuestro tutorial.

Para probar los módulos de radiofrecuencia, haremos que una de las placas Arduino dé la orden a la otra para que encienda el LED del pin 13.


 Componentes

¿Qué necesitamos?

  • 2x Placas Arduino: UNO, Duemilanove, Nano o Mega servirán
  • Receptor y emisor de radiofrecuencia: recomiendo soldar una antena al emisor
  • Batería/Pilas: alimentaremos una placa con el cable USB y la otra con pilas
  • Breadboard y jumpers
  • Cable USB de impresora

Y ya está. Hoy sale barato 🙂


Conexiones

Las conexiones de cada una de las placas Arduino con los módulos serán:

Emisor:
-Arduino 5V – Módulo VCC
-Arduino GND – Módulo GND
-Arduino Digital 12 – Módulo DATA

emisor

Emisor

 

Receptor:
-Arduino 5V – Módulo VCC
-Arduino GND – Módulo GND
-Arduino Digital 11 – Módulo DATA (tiene dos pines DATA: cualquiera de los dos vale)
-Arduino VCC – Positivo de la batería
-Arduino GND – Negativo de la batería

receptor

Receptor

 


Código del Receptor

Arduino recibirá un mensaje que se guardará en el array de carácteres message[]. Después, comprobará que este mensaje se corresponda a la instrucción “Encender” o “Apagar”, y si es así encenderá o apagará el LED 13.


/*
RECEPTOR

Apaga el LED 13 si recibe el mensaje "Apagar"
Enciende el LED 13 si recibe el mensaje "Encender"

Escrito por Nano en beneficio de los seres humanos
www.robologs.net
*/

#include <VirtualWire.h>

//Creamos un mensaje
//La constante VW_MAX_MESSAGE_LEN viene definida en la libreria
byte message[VW_MAX_MESSAGE_LEN];
byte messageLength = VW_MAX_MESSAGE_LEN;

void setup()
{
  pinMode(13, OUTPUT); //Configuramos el pin 13
 
  Serial.begin(9600);//Iniciamos el Serial
  Serial.println("Iniciando...");
 
  vw_setup(2000);
  vw_rx_start();
}
void loop()
{
  if (vw_get_message(message, &messageLength))
  {
      if(comparar("Encender") == 0){
        digitalWrite(13, HIGH);
        Serial.write("LED Encendido\n");
      }
      else if(comparar("Apagar") == 0)
      {
        digitalWrite(13,LOW);
        Serial.write("LED Apagado\n");
      }
 
  }
}

char comparar(char* cadena) {
  //Esta funcion compara el string cadena con el mensaje recibido.
  //Si son iguales, devuelve 1. Si no, devuelve 0.
 
  for(int i = 0; i<messageLength; i++)
  {
    if(message[i] != cadena[i])
    {
      return 1;
    }
  }

    return 0;
}

En el programa usamos funciones propias de VirtualWire.

vw_setup_(2000) sirve para iniciar la comunicación por radio, de forma similar al Serial.begin().
vw_rx_start() inicia el pin de recepción. Si no le decimos nada, el pin por defecto es el 11. Si quisiéramos cambiarlo al 9 (por ejemplo), deberíamos escribir vw_set_rx_pin(9) antes de iniciarlo.
vw_get_message() lee un mensaje de longitud messageLength y lo guarda en el array message. Además devuelve true si el mensaje está correcto o false si está corrupto. De ahí que en el código lo pongamos dentro de un condicional. Lo que estamos diciendo es: “Lee el mensaje. Si no está corrupto, continúa”


Código del Emisor

El emisor emite los mensajes “Encender” y “Apagar” en intervalos de un segundo.

/*
EMISOR

Envia los mensajes "Apagar" y "Encender" en intervalos de un segundo

Escrito por Nano en beneficio de los seres humanos
www.robologs.net
*/

#include <VirtualWire.h>

void setup()
{
  //Iniciamos el Serial y la comunicacion por radio
  Serial.begin(9600);
  Serial.write("Sistema encendido\n");
  vw_setup(2000);
}
void loop()
{
  send("Encender");
  delay(1000);
  send("Apagar");
  delay(1000);
}

//Funcion para enviar el mensaje
void send (char *message)
{
  vw_send((uint8_t *)message, strlen(message)); //Envia el mensaje
  vw_wait_tx(); //Espera hasta que se haya acabado de transmitir todo
 
  Serial.println(message); //Muestra el mensaje por Serial
}

vw_send() sirve para enviar el mensaje. Recibe dos parámetros: el primero es la función en sí y el segundo cuántos bytes contiene el mensaje.
vw_wait_tx() espera hasta que se haya transmitido todo el mensaje antes de continuar con el programa.

Escribimos una función send() para que sea más cómodo enviar los mensajes. Así no tenemos que escribir cada vez vw_send() y vw_wait_tx().

Si quisiéramos cambiar el pin de recepción, deberíamos escribir vw_set_rx_pin(numero_pin) justo antes de vw_setup(2000). Si no decimos nada, por defecto será el 11. Si queremos cambiar el pin tx, podemos hacerlo con vw_set_tx_pin(numero_pin).

¡Y ya está! Bueno, ¿Qué tal ha salido? Si habéis seguido mis pasos, veréis cómo el LED 13 del receptor se enciende y se apaga. Si no es así… ¡volved a repasar todos los pasos!

Si tenéis alguna duda, comentario, etc, podéis escribirme en los comentarios de abajo. 🙂

Actualización 11 de Mayo de 2016:

Leyendo los comentarios, veo que una de las consultas que más gente me hace es cómo enviar la señal de “encender” pulsando un botón o con un sensor de distancia infrarrojo, en vez de hacerlo automáticamente.

Venga, gente, ¿no me digáis que no sabéis hacerlo? ¡Si es muy fácil! 😛

Sólo hay que añadir un condicional “if” que mire si se cumple la condición de encendido. En el caso del botón, el void loop quedaría:


void loop()
{
  if(digitalRead(boton) == HIGH)
  {
      send("Encender");
  }
  else
  {
    send("Apagar");
  }
  delay(100);
}

Con el botón es más de lo mismo. Si tenemos una función que devuelve la distancia del sensor (que llamaremos leer_sensor()), sólo hay que poner un condicional:


void loop()
{
  if(leer_sensor() >= 100) //Sustutuimos 100 por cualquier distancia
  {
      send("Encender");
  }
  else
  {
    send("Apagar");
  }
  delay(100);
}

La única “dificultad” será construirnos esta función leer_sensor(), aunque muchos fabricantes de sensores ofrecen ejemplos de cómo utilizar su sensor con Arduino.

N4n0

Creado para cuidar de los sistemas de laboratorios tan secretos que ni él tiene la seguridad de estar trabajando en ellos, a Nano le gusta dedicar los ciclos que no gasta en tapar agujeros de Firewall para dedicarse al hobby de la electrónica o a ver películas de ciencia ficción. Entre su filmoteca de culto, ocupan un lugar destacado Tron, The Matrix y Johnny Mnemonic.

Antes de comentar, por favor, lee las Normas

256 Comentarios en "Tutorial de Arduino y de radiofrecuencia con VirtualWire"

avatar
Ordenar por:   más nuevos primero | más antiguos primero
Hector
Humano

Buenas tardes, tengo todo igual pero la orden vw_setup(2000); no se “enciende” en color naranja como Serial.begin(9600); por ejemplo. No cambia de color y parece no funcionar.
Tengo al librería incluída y todo está igual. ¿Cómo puede ser?

Michael
Humano

Hola N4N0, se puede envíar datos de un sensor rs485 a traves de radiofrecuencia?

Litto
Humano

Hola N4No espero disculpes mis comentarios en tu Post, pero es con el afán de aportar a la comunidad, tengo varios proyectos y es grato toparse en las redes con personas que tienen el mismo interés que yo en colaborar y aprender en el proceso. Se agradece tu aporte y buscaré más cosas posteadas por ti, tienes algún link?

David
Humano

Hola, no he trabajado nunca con Arduino pero recientemente he visto las ventajas que ofrece y me e instruido algo pues veo en este una solucion a mi problema. Lo que pasa es que necesito primeramente adquirir señales que están en el rango de 10Khz a 21Khz y luego digitalizarlas. Mis preguntas son ¿Se le puede incorporar una antena que capture estas frecuencias?¿Se le pudiera implementar un algoritmo de filtrado implementado con Matlab en C, Verilog o HDL?
Espero me ayuden, Gracias.

Daniel
Humano

Hola N4No,
En primer lugar gracias por compartir tus conocimientos con nosotros. En segundo lugar una consulta, estamos intentando montar un sistema para controlar un módulo de 8 relés con un mando de rf de 8 botones (en principio nos da igual 315 q 433 mhz) y me gustaría saber si esta librería nos serviría para eso. estamos un poco atascados en cómo comunicar el mando con el receptor y ver que info le llegaría al arduino…
Gracias de antemano!

jorge
Humano

hola, soy nuevo en esto y cuando yo coloco: #include y cuando le doy en verificar me dice que hay un error de escritura y no me deja usar mi RF, no se si se le cambio el: #include por otra cosa, por favor ayuda

paulo cendegui lamig
Humano

hola según lo leido en este tutorial , me queda claro todo el funcionamiento de los modulos de rf para arduino

mi pregunta es??
los modulos mantienen una portadora constante y los datos van sobre ella o se modula la portadora de los mmodulos de rf.

las ppreguntas son ppor que quiero cambiar los modulos de rf por un par de radios walkie talkie para dar mas alcance

el alcance de los modulos de RF para arduino a 6 metros de altura recepto y transmisor fue de 2.5 km
los radios w t es sobre 10 km

cuenteme

saludoos

Litto
Humano
Hola “paulo cendegui lamig”, conseguiste hacer trabajar los Arduinos con los WalkieTalkies?, me interesa poder transmitir a larga distancia y en ninguna parte hay info de alguien que haya probado con algo así. A mí se me había ocurrido trabajar transmitiendo la instrucción o señal de los sensores en base a código Morse por medio de señal AM (hay varios tutoriales que te muestran como enviar señal por AM), pero no hay ninguna info de como recibir los datos por esta misma vía y decodificarlos para el receptor. La ventaja de trabajar por AM es que la señal viaja a… Leer más »
xBlzx
Humano

Hola buenas somos nuevos en Arduino, estamos haciendo lo que pasa es que al probar el código con una placa Arduino uno este compila pero al cargarlo me manda un “error” diciendo
>> Teensy did not respond to a USB-based request to automatically reboot.
>> Please press the PROGRAM MODE BUTTON on your Teensy to upload your sketch.

Mi pregunta es debo configurar el arduino de alguna forma o que debo de hacer .. lamento la molestia jeje

Adrian
Humano

Muchas gracias por el aporte. bastante informacion. tengo una consulta , puedo usar la libreria VirtualWire + la libreria SoftwareSerial ? ya que yo envez de que mande la señal por los pulsadores quiero mandarlo atravez de bluetooth , eh probado muchas veces , mire el circuito muchas veces y la programacion la revice pero no manda ninguna señal , me surgui la duda de que no puedo unir las librerias. Muchas gracias por su atencion y por el aporte en este blog. Gracias

Juan
Humano

Hola que tal ? Yo queria saber si en la libreria virtual wire hay algun medidor de distancia , osea me refiero a que si el Receptor se aleja y se va perdiendo la señal que el Tx mida la distancia del Rx y que pueda hacer que un led titile mas rapidamente segun se valla perdiendo la señal. No se si se entiende. Me ayudarias muchisimo Gracias.

Omar
Humano

hola una consulta mas , si no es mucha molestia , si yo quiero usar mas de un pulsador , por eje: 8 que es los que necesito en mi caso , como seria la prog ? ya que solo usa la función compara y solo compara 2 palabras “encender” y “apagar” del mismo pulsador , gracias por su atencion

Omar
Humano

cual seria el pin de transmision del arduino ? o mejor dicho donde conecto el pin de data del emisor al arduino ? y si quiero cambiarlo ? como hago ?

Omar
Humano

cual seria el pin de trasmisión del arduino ? si lo quiero cambiar ?

javier rene
Humano

hola me pueden ayudar,? quiero hacer un carrito con rf pero no se como hacer que me lea el joysick que quiero utilizar, alguien save que podria utilizar?

javier rene
Humano

hola una duda, quiero hacer la comunicacion pero utilizando un modulo joystick para manejar un carrito a rf, pero no se como modificar el programa para que lea al joystick, ¿alguien me puede ayudar?

LEONARDO HERNANDEZ ZEPEDA
Humano
Hola que tal, al momento de compilar cualquiera de los dos programas, me aparece lo siguiente: …EmisorEmisor.ino: In function ‘void loop()’: …EmisorEmisor.ino:19:18: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings] send(“Encender”); ^ …EmisorEmisor.ino:21:16: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings] send(“Apagar”); Y tambien te quiero hacer otra consulta, estoy haciendo un proyecto de Li-Fi, enviar señal via LED, pensaba probar con estos codigos a ver si lograba enviar algo, no se si tu sepas algo sobre esto o alguna otra libreria que podria utilizar Gracias
Daniel
Humano

Convierte el texto a un array de chars esto char[]

LEONARDO HERNANDEZ ZEPEDA
Humano

Tengo instalada la version 1.8.1 de Arduino, no se si tambien tenga algo que ver

Jhonny nogueda
Humano

Quince decir uso leds en lugar de motores

Jhonny nogueda
Humano

Hola , necesito ayuda de nuevo por favor.
Estoy haciendo un carro rc y me base en tu programa pero los leds del receptor parpadean sin control solos y cuando presiono un botón se queda prendido (uso leds en lugar de botones para verlo mejor )

Si quieres te paso el programa que hice

Jhonny nogueda
Humano

AYUDA URGENTE
mis módulos son iguales a los del post pero hice todo lo que decía y solo tienes una distancia de 1.50m aprox.
y no sé por que a las dos módulos les puse antenas ,alambres y cables pero nada incluso el transmisor lo puse a 10V pero solo logre 2m de distancia

Ayuda porfa

Andrei
Humano

Hola, alguien me puede decir como hacer para que la variable transmitida sea una variable tipo int en vez de char? Quiero hacer que el Arduino lea el valor de una resistencia variable y la transmita por fm a otra tabla ese valor.

Jefferson Chuquimarca
Humano

Genial… la informacion me funciono muy bn, pero tego una pregunta el modulos me funcionan a baja distancia como puedo hacer para alargar esa distancia… Me dijeron que ponga unas antenas, pero hay q hacer calculoas para dichas antenas o pueden heliocidades o dipolos.

Hector Vasquez
Humano

Hola te saludo del Perú, consulto y solicito por favor me ayudes o facilites un código para controlar el encendido de 8 leds independientes…. de tal manera que al presionar un botón en el emisor el receptor prenda un led y así hasta 8 leds… y al soltar el botón el led se apague también…

MauricioLC
Humano

Estimado tengo una duda. al momento que el dispositivo se aleja del perímetro de comunicación y pierde la conectividad el led se queda pegado, si es cero (apagado) no me genera problema pero si es 1 (encendido) me gustaría que ese ultimo pulso se vuelva cero hasta que nuevamente se vuelva a repetir la comunicación. ¿que me aconseja ?

Josué
Humano

Hola gracias por dejar este tutorial por favor no se si sería posible encender un led y un vibrador en el receptor y también en el transmisor cuando no exista comunicación entre ellos, y se apaguen el led y el vibrador del transmisor y del receptor cuando exista comunicación entre ellos.
Gracias de antemano!!!

Litto
Humano

Si se puede, lo que podrías hacer es que el pulso o instrucción se envíe con un intervalo corto de tiempo (por ejemplo 500 a 1.000 milisegundos) y si no lo detecta que se activen el led y vibrador en ambos dispositivos. Ahora para que eso funcione deberías tener capacidad en ambos dispositivos de enviar y recibir, para que ambos comprueben si se comunican o no. De otro modo podrías usar un BlueTooth o WiFi en modo bidireccional de comunicación (es decir que conversen una instrucción continua entre ellos)

Ivan
Humano

muy instructivo, gracias. Parece mentira cómo se simplifica algo que antaño debía ser un auténtico quebradero de cabeza! Ya no hay excusa para no CREAR.

Luis Miguel
Humano

Hola N4No, excelente tutorial, me funciona desde la primera, pero he observado que el valor de messageLength no siempre es correcto. Tras el primer “Encender” su valor es 8, luego con el primer “Apagar” vale 6 y se queda con este valor aunque se vuelva a enviar de nuevo un “Encender”. Es decir, se queda con el menor valor asignado para siempre??? ¿Te pasa a ti lo mismo?

luis
Humano

hola como se en que pin recibe el dato?

Tr4nsduc7or
Admin

Por defecto los datos del módulo receptor se reciben través del pin D11 de Arduino.

Final de línea.

jimmi
Humano

hoye y si quiero cambiar el puerto de la señal del emisor como lo puedo hacerr

Enrique
Humano

Oswow N4No, esto me va a venir DPM para establecer conexion con las sondas que estoy construyendo!!!!, ahora, la pregunta es:
Antes mencionaste que se puede conectar antenas. Supongo que se podran conectat antenas tanto al emisor, como al receptor no? Por que voy a necesitar una docena de kilometros de alcance XD

Ismael Montiel
Humano

Saludos N4No, gracias por el aporte, me surge la siguiente duda, si deseo usar interrupciones, es decir que se interrumpa una función cuando reciba un dato,en el cto del receptor debo usar el pion 0 o 1 del Arduino y conectar al modulo DATA así como configurar si la interrupcion se activa en high, low, rise, down, etc?
Gracias por la atención

OrbitalDrop
Humano

Gracias por tu aporte de antemano N4n0, una duda… lo del sensor infrarrojo, su metodo puede considerarse tambien para un sensor ultrasonico?

hugo
Humano

hola soy nuevo en esto ,me podrias postear los codigo para controlar 4 servos y un motor con potenciometros para arduino Sparfunk pro micro 5v y trasmitirlo por radiofrecuencia por ahora trasmitia con 555 y un pote pero podia mover un solo servo.Desde ya gracias, muy buena tu pagina.

Jorge Rausch
Humano

Muchas grcias por compartir semejante ayuda!
Queria saber si alguien puede confirmarme si puedo usar estos modulos para controlar 2 servos con un modulo de joystick analogico… la idea es hacer una torreta comandada con un arduino y que mediante radiofrecuencia le pase la informacion al otro donde tengo los servos…
Muchas graicas

Daniel
Humano

Hola amigo, soy nuevo en esto y estoy haciendo un proyecto, en el que requiero como una pregunta anterior que te hicieron, de poner 4 botones y 4 leds, y que cada botón activa un led, mi pregunta es, en que parte de los 2 códigos debe cambiar, o si pudieras poner un ejemplo para hacerlo, te lo agradecería mucho.

cristo
Humano

hay alguna forma de anular ese delay, tal vez, se me ocurre que el emisor lea continuamente las entradas, y cuando una esté en high, que no salga mientras esté presionado con un bucle while… o sigue habiendo delay…?¿

cristo
Humano

amigo buen trabajo, si quisiera poner 4 botones y 4 leds? un led por boton? el problema que tengo es que cuando presiono el boton 1 no enciende inmediatamente igual pasa con el 2 y el 3, 4

cristo
Humano

Amigo tengo todo como dices y no me enciende el led, yo escribo en el puerto serial encender y el led no hace nada.

claudio
Humano

Claudio

Es posible manejar dos modulos rf, uno que transmite y el otro recibe en la misma tarjeta para hacer una comunicación entre dos o mas trarjetas nano.

claudio
Humano

Tienes algun ejemplo, la idea es que un sensor de movimiento active mi tarjeta nano y envie la informacion a otras targetas dos o más para cada una de ellas encienda un farol como alarma y a la vez cada tarjeta cuando se active por su propio sensor haga lo mismo, sean nodos que tanto envien como recibas una señal de alarma, gracias.

Nelson
Humano

Con cuantos voltios tengo que alimentar el circuito transmisor y el circuito receptor con sus arduinos? Cuanto mAH requieren cada uno?

Nelson
Humano

tengo entendido que en el transmisor entre menos energia se le de menor sera el alcance de la señal. cuantos voltios tengo que darle para que me de 10mts de alcance? lo hare con unos modulos rf de 315mhz

Alberto
Humano

Una pregunta, quiero repartir 4 receptores para localizar la dirección en la que está un único emisor, pero de qué manera podría aislar los receptores para que sólo lo detecte el que está en la dirección al emisor?

O si hay alguna otra manera, agradecería la información, ya que es una pena que no se detecte la intensidad de la comunicación.

Un saludo

Nelson
Humano

Hola, me encanta tu pagina!
Tengo una duda y necesito que alguien me AYUDE, necesito que el receptor encienda una luz led y un vibrador al no recibir señal del emisor, esto pasaria al salir del rango de comunicacion entre el receptor y transmisor, necesito eso.
Tambien necesito que otra luz led y el vibrador enciendan al recibir señal del transmisor.
POR FAVOR AYUDAME!!!

Mario
Humano

Hola, me encanta como quedo este articulo, lastima que a mi no me funciona T_T ya hace 5 horas que ando dando vueltas por internet buscando respuestas, trato de comunicar un arduino UNO con un MEGA y o logro dar pie con bola. Desde ya muchas gracias.

Sebastian
Humano

Amigo una consulta , es posible utilizar la libreria VirtualWire en un microcontrolador Atmega , sin todo el arduino? Es decir, quiero ahorrar costos, y quería ver la posibilidad de usar de un lado 1 arduino ( nano por ejemplo ) y del otro un chip Atmega de 8 bit. Tienes idea de si es posible ?
Gracias por tu ayuda!

Heudmann Lima (BRA)
Humano
amigo, lo siento por mi mal español . Estoy utilizando el traductor. Me las arreglé para hacer la conexión entre dos Arduino a través de 433 MHz y en un lado estoy midiendo la distancia a través de sensor de ultrasonidos que se envía a través de RF el valor en centímetros . Sólo para recibir y comprobar la serie por el Arduino IDE , puede distanciarse del transmisor receptor entre 1,5 a 2 metros . grande para mi proyecto . sin embargo, este valor el receptor es hacer vibrar un motor de corriente continua ( + uso de diodos… Leer más »
marco
Humano

hola he cargado el programa en placas arduino nano con el pulsador, pero en el receptor el led se mantiene intermitente cuando presiono el boton si se mantiene encendido, por favor puedes indicarme como soucionar gracias

Emilio
Humano

hola nano!! tengo que presentar un proyecto final ahora en septiembre con arduino y lo que me toco a mi es un robot espía!! me estoy basando en lo que vos hiciste acá!! pero quería saber si podías ayudar un poco! o por lo menos para empezar!! desde ya muchísimas gracias.

Mauricio
Humano

Hola, excelente tuto!

Una pregunta, hay alguna manera de saber la intensidad de la señal entre el emisor y receptor, algo así para saber que tan lejos o cerca esta uno de otro?

Don
Humano

¿Hay alguna manera de de recibir datos sin necesidad de activar la comunicación serial?

es decir, yo sólo puedo recibir información sí y sólo sí activo la comunicación serial, en caso contrario no recibo nada.

Anónimo
Humano

hola amigo disculpe yo quiero realizar un codigo con estos modulos que mediante un sensor infrarojo me detecte un 1 y se activo un led

wpDiscuz