Let's Make Robots!

Arduino RF Communication using RX & TX link Modules

RF communication link between two Arduinos
  • Control method:

This Tip/Walk-Through will guide you through a simple one way communication link between two Arduinos.

The Project uses these RX/TX Radio Frequency (RF) Link Modules.

Edit :- Links updated - old ones where retired .Boooooo

(Thanks to Fritsl for bringing these cool babies to my attention ,i just had to try them out on my arduino and i am well impressed with thier performance )

Both Transmitter and Receiver together cost less than two tin cans with a piece of long string connected between !!!!!!!

You will have to download the Virtualwire.h library and install it to your arduinos  hardware/libraries folder

More info on the Virtualwire communications library can be found http://www.open.com.au as pdf file


Receiver :- Basic link Arduino Mega using a  RF Link Receiver - 315Mhz


Only Four wires are required, i have used a audio cable from a cd drive which i rewired to accept the cables (neat).

Yellow is the Antenna - approx 30cm long (other end connected to thin air)

Red is connected to 5 Volts

White is the Received data (in my case connected to pin 23 on the mega - can be easily assigned to another pin)

Black is Ground (it has three separate ground pins all connected together!!!!!!)


 // Receiver Code     (as the code is very short i post direct here, its adapted from Mike McCauleys pdf file above)


// RF Link using VirtualWire to receive messages
// simplex (one-way) receiver with a 315MHz RF Link Receiver module
// rx pin 23 on mega


#include <VirtualWire.h>  // you must download and install the VirtualWire.h to your hardware/libraries folder
#undef int
#undef abs
#undef double
#undef float
#undef round
void setup()
{
    Serial.begin(9600);    

// Initialise the IO and ISR
    vw_set_ptt_inverted(true);    // Required for RX Link Module
    vw_setup(2000);                   // Bits per sec
    vw_set_rx_pin(23);           // We will be receiving on pin 23 (Mega) ie the RX pin from the module connects to this pin.
    vw_rx_start();                      // Start the receiver
}

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

    if (vw_get_message(buf, &buflen)) // check to see if anything has been received
    {
    int i;
     // Message with a good checksum received.
        
    for (i = 0; i < buflen; i++)
    {
        Serial.print(buf[i]);  // the received data is stored in buffer
        }
    Serial.println("");
     }
}


 

 

 


 Transmitter :- Basic link using an  Arduino Duemilanova and a  RF Link Transmitter - 315Mhz


 

This also has 4 wires and the same trick with the cd audio socket to make neat connection.

Black connected to Ground

White is the transmit data cable connected to pin 3 on the Arduino (however this is easy to re-assign to suit your needs)

Red is the power supply connected to 5 Volt pin on Arduino (actually you can apply anywhere between 2 Volts and 12 Volts - the higher the voltage the stronger the RF signal)

Grey (sticking out of the Top is the Antenna - around 30cm long


// Transmitter Code


 

// RF Link using VirtualWire to Transmit messages
// simplex (one-way) receiver with a 315MHz RF Link Transmitter module
// tx pin 3 on Duemilanova (arduino)

 
#include <VirtualWire.h>  // you must download and install the VirtualWire.h to your hardware/libraries folder
#undef int
#undef abs
#undef double
#undef float
#undef round
void setup()
{
     // Initialise the IO and ISR
    vw_set_ptt_inverted(true); // Required for RF Link module
    vw_setup(2000);                 // Bits per sec
    vw_set_tx_pin(3);                // pin 3 is used as the transmit data out into the TX Link module, change this to suit your needs.
}

void loop()
{
    const char *msg = "LMR-II Rocks";       // this is your message to send

   vw_send((uint8_t *)msg, strlen(msg));
   vw_wait_tx();                                          // Wait for message to finish
   delay(200);
}


 


Power them both up and switch on the Serial monitor to 2400 Baud on the receiving Arduino (mega in our case)

 

Then Hey Presto Communication link established......... up to 152.4 Meters (thats 500 feet in old currency)

I tested (Tx at 5 Volts) from my Basement to roof (5 stories) no problem ( Mega impressed)

Ending Side Mystery :- Why did i use pin 23 as the Rx pin on the Arduino Mega ?

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Gareth:

 

I've run into trouble using the VirtualWire.h and Servo.h or MegaServo.h.

Seems like there are some conflicts using both those libaries at the same time.
 

C:\Users\Stig\AppData\Local\Temp\untitled30508.tmp\sketch_jan21a\applet\VirtualWire\VirtualWire.cpp.o:E:\Programming\Arduino\hardware\libraries\VirtualWire/VirtualWire.cpp:412: first defined here 

Sketch works fine, but when I add  #include <Servo.h> I get that error.

Virtualwire.h Servo.h and MegaServo.h dont mix

Basically because they all try to use Timer1 and thats what causes the conflicts.....

.... to get around this try using ServoTimer2.h   as its name suggest it uses Timer2 hence no conflicts.

i have used this library in all of my current sketches - i find it more accurate as you send the millisecond values to it (and not degrees).

Hope this helps - let me know how you get on...

I was using virtualwire.h and servo.h in two arduinos with two pairs of RF links (434 & 315mhz) ,to form a full duplex setup. I had run into the same problem - " multiple definition of `__vector_11' "

Looks like Servotimer2.h is the workaround. Tested with virtualwire v1.5 and works fine. :)

 

Yes, libraries fighting to use the same timers leads to all sorts of unexpected bugs..... Its a right pain to know which timers are being used with out jumping into the actual library code ....

..... it would be helpful if library developers would declare at least in some of thier example codes which timers are being "Hi_Jacked" 

Well i can do this. But i am trying to send the analog value of a joystick, the x and y axis. Here is my forum and captain obvious's code and suggestions. WE got the first bit of code to work to send a single value but  we still cant do 2 values. We think this would help people out. Must say that this is a great blog but it seems to be a bit fuzzy around on how to do values. http://letsmakerobots.com/node/14000

 This is my current way of sending multiple variables, any ideas on slim-line_ing the code are Welcomed.

Its highly likely that a lot of the pre-code can be cut out - it was a nightmare to get it all working.

Yes i know my buffers are oversized...........

// www.letsmakerobots.com   (Gareth) Node 12336
// How to transmit more than one variable on a RF Serial Link
// Basic idea is So :- send a prefix character ie. "X" in front of your "Stringed" value
//                     Your next value will have a different prefix ie "Y" plus "stringed" value etc.etc.
//               This way the RX end can just sit and wait for incoming variables (even from multiple TX sources)

//                All the RX side needs to do is look at the prefix to see which variable it is .....easy.........

int X=0;   //First Variable
int Y=0;   //Second Variable

int ii=0;  int jj=0;

#include "Wire.h"
#include <VirtualWire.h> // library for RF RX/TX
#undef int
#undef abs
#undef double
#undef float
#undef round

char charnum[10];

int bz=0;
void setup() {
  // debug Serial.begin(9600);
  // Set up TX Link
  vw_set_tx_pin(8);   // adjust this value to point to your tx pin of module
  vw_set_ptt_inverted(true); // Required for DR3100
  vw_setup(2000);     // Bits per sec
}

void loop() {
char bufferX[5] ; memset(bufferX, '\0', sizeof(bufferX));  // reset and zero buffer for first variable prefix
char numX[5]   ; memset(numX, '\0', sizeof(numX));      // reset and zero buffer for first variable Value
char bufferY[5] ; memset(bufferY, '\0', sizeof(bufferY));  // reset and zero buffer for Second variable prefix
char numY[5]   ; memset(numY, '\0', sizeof(numY));      // reset and zero buffer for Second variable Value
    
//-------------------First Variable Transmit ----------------------------------------------     
 X = (int)chuck.readRoll();      // read your first variable here.....mine was wiichuck data
  strcat(bufferX,"X");     // place an "X" as the first part of string
  ii=byte(X);                // Here i convert to a single byte - because for my applications value range (0-255)ie one byte
  itoa(ii,numX,10);       // convert the number to a string
  strcat(bufferX,numX); // Join the "X" and the string together
                                 //Debug  Serial.println(bufferX);
  vw_send((uint8_t *)bufferX, strlen(bufferX));  //actually send on RF
  vw_wait_tx();             // Wait until the whole message is TXed
  delay(20);                // found i need a short delay before second TX
//-------------------Second Variable Transmit ----------------------------------------------
 Y = (int)chuck.readPitch();     // read your second variable here
  strcat(bufferY,"Y");    // place an "Y" as the first part of string
  jj=byte(Y);                // Here i convert to a single byte - because for my applications value range (0-255)ie one byte
  itoa(jj,numY,10);       // convert the number to a string
  strcat(bufferY,numY); // Join the "Y" and the string together
                                 // Debug Serial.println(bufferY);
  vw_send((uint8_t *)bufferY, strlen(bufferY)); //actually send on RF
  vw_wait_tx();             // Wait until the whole message is gone
  delay(20);
//---------------------------------------------------------------------------------------------  
  }

 I have used this code in "Wiieasy rider"

Basically i TX either "P"or "R" plus the servoposition ie"213" as string...............eg "P213"

Then on the RX side split the "P" or "R"  and extract the number into an integer variable

(i have highlighted the important bits)

RX Loop coding is approx so :-

{
     uint8_t buf[VW_MAX_MESSAGE_LEN];
    uint8_t buflen = VW_MAX_MESSAGE_LEN;
  if (vw_get_message(buf, &buflen)) // Non-blocking
    {
      char val[buflen];
      memset(val, '\0', sizeof(val));   // Zero buffer

      strncpy(val, (char *)buf + 1, buflen - 1);  // extract value out of the string ie buf[1]+buf[2]+buf[3]

      int VAL = atoi ( val );  // then convert it to interger ie "213" to 213

      switch (buf[0]) {   // buf[0] is the first position of the RX string
               
        case 'P':
            Serial.print("Servo Pitch ");
            servopitch.write(VAL);            // ie buf[1]+buf[2]+buf[3]                  
            break;
        case 'R':
            Serial.print("Servo Roll ");
            servoroll.write(VAL);
             break;
        default:
            break;
      }
    }
   

What if you want to recieve a value? like a servo position ?
can be deleted (sorry admin)

hi Gareth!!

Please help me, i've already put the two arduino to talk each other. But i don't know how i can identify what message is coming. Like sending 0 or 1 to turn on the RED LED or the BLUE LED from my project, respectively. Can you put the code and explain it to me? i'm starting.

Congratulations for the post!

Thanks a lot!!

Renke