240

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

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

avatar
Ordenar por:   más nuevos primero | más antiguos primero
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

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!!!

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

kenn
Humano

hola q tal,buen aporte, una consula siquiero utilzar varios radio control. como hago para que no hage cruse de señales.donde puedo poner el codigo en la programacion para q cada uno sea independiente en su señal,gracias

Camila
Humano

Hola, muy buen post. Me funciono bien la transmisión, pero tengo un conflicto cuando quiero controlar servomotores con la libreria Servo.h
Al parecer es un conflicto común, se podrá resolver?

Camila
Humano

Hola, perdón por la molestia, ya encontré la forma de resolverlo utilizando otra librería que ocupa un timer distinto, y no genera conflictos. Igualmente gracias, buen post..
La librería se llama ServoTimer2, es muy similar a la Servo, solo cambia el parámetro para la posición, va de 740 a 2260, eso corresponde a los 180 de recorrido del servo.

Saya maurys
Humano

hola camila, ando trabajando en un proyecto similar… podrias ayudarme con eso?

Jordi
Humano

Buenas!
Donde puedo encontrar el VirtualWire?

Gracias

PEDRO NOFRE ROMERA
Humano

Hola!como puedo hacer para poner un interruptor en el emisor y que encienda el led del receptor?gracias

Edel Avila
Humano

Amigo lograste que encendiera el led con el puch botton?

erasmus
Humano

me parece uqe fue porque no declaraste el pin como entrada, o nose si me equivoco podrias corregirme, mas bien me gustaria saber como puedo trabajar con servos nose si me podrias ayudar

Nirvana
Humano

Hola, quiero saber si hay una forma de restringir al modulo que solo transmita y reciba a un metro o 30 cm. muchas gracias 🙂

erasmus
Humano

me parece uqe fue porque no declaraste el pin como entrada, o nose si me equivoco podrias corregirme, mas bien me gustaria saber como puedo trabajar con servos nose si me podrias ayudar

Pedro Nofre Romera
Humano

Te lo agradezco muchoo!!a la tarde miro si me funciona y te digo algo!!muchas gracias! Es parte de mi trabajo final de curso y estoy atascado 🙁

PIPE
Humano

Buenas tardes
Transmitir un mensaje, y en su caso datos con rf con los modulos convencionales, sin problemas.
El problema viene cuando paso al modulo Long Range, con el emisor PCF20 y receptor R08A. El led interno me dice que esta emitiendo y recibiendo, leyendo en monitor serial el emisor me dice transmitiendo y el receptor listo para recibir.
No recibo nada. Si pongo interrupciones en los codigos todo corre perfectamente, pero no se transmiten mensajes. He probado con las 4 IN/OUT D0 D1 D2 y D3 y no hace nada.
Cual es mi error?

wpDiscuz