Testing RF links


I'm trying to get the 315MHz 4800bps RF links (WRL-08947 & WRL-08945) from Sparkfun to work. If I hook up the TX of one Arduino straight to the RX of the other Arduino with wire, my tests work. After I've attached the TX to a transmitter and the RX to a receiver, my test does nothing, zip.

I've tried all the examples that I could find, including those linked from the product page and a few using SoftwareSerial to free up the Serial port for printing via USB to a computer.

I've tested with antennae, both 23.5cm long, and without antennae. The Arduinos - one Mega one Duemilanove - are sitting next to each other on the table, so antennae shouldn't be needed. I've also tried making both antennae into loops, putting one loop inside the other as a comment on the product page suggested.

I can't even get any garbled input to show up. I'm trying to pick up the signal on the Mega's Serial1 port (pin 19), and printing it to its Serial port, so that I can see anything that comes through, garbled or not.

So, I'm thinking that maybe one of the RF components isn't working properly, but how could I test that? I have a multimeter, no scope.

Hmmm. It's been a long day :')

I have a multimeter, no scope

You could try putting the Rx onto an analogue pin, and try graphing the result using Processing.

Interesting, thanks. Would that graph anything even if there is nothing being transmitted, i.e. interference? That'd help in case my Tx is broken.

Any way to test the receiver? Possibly errr, sending some signal straight to the antenna? ;')

Would that graph anything even if there is nothing being transmitted

Of course - you're just repeatedly measuring the voltage on a pin. If there's data there, then you'll see nice regular square-ish waves.

You could even feed it with the Tx pin from the other Arduino without using the RF, just to see what good data should look like.

Any way to test the receiver?

You mean the transmitter?

No, not really with this sort of setup (though an RF engineer will probably prove me wrong with a diode and some caps!)

Have you try the VirtualWire lib in the playground?



I have the same exact RF set and notice the receiver is inverted. Also, the data sheet shows 20ms at VCC turn on time but I have needed some dummy bytes at each transmission start along with a CRC byte at the end.

It's rock solid after that but I use a software method so it's more flexible to filter noise. I connect everything straight pin to pin with no pull up/down resistors.

I went from almost smashing it with a hammer to being extremely pleased within an hour so just stick with it.

Have you try the VirtualWire lib in the playground?

Yes, I've tried VirtualWire and get no data on the receiver. If I try VirtualWire with an actual wire connection, it works.

I have the same exact RF set and notice the receiver is inverted

How did you find that out and remedy it, if I may ask? And did it mean that you weren't getting Serial.available() at the receiving end until you figured it out?

I use software to transmit with a 4 byte protocol. It uses longer start/stop bits so the RX knows when it has the full signal. To check it on the receiver side you can just use the pulseIn to capture an array of LOW pulses and see long and short for 0 and 1. Decrease the timing in the bit_tx function until it becomes unstable then you can figure out the maximum reliable rate for your application. Keep in mind the inverted signal so with the data on the HIGH TX side it will be LOW on the RX.

This transmits MSB first, I had a reason for that but I can’t remember what it was. It acts as a beacon that pings every 500ms and the receiver can listen at any random window and get the full data stream. I use the UART for something else so this is all in software.

int tx=6;//TX pin
byte tx_val[4]={B10001001,B11010001,B11011111,B1111111};//4 data bytes
unsigned long tx_time;

void setup()
pinMode(tx, OUTPUT);
digitalWrite(tx, LOW);


void loop()
tx_val[3]=tx_val[0]^tx_val[1]^tx_val[2];//store CRC in 4th byte
if(millis()-tx_time>500)//send TX pulse every 500ms
//start bits
//start data
for(int i=0;i<4;i++)//cycle 4 bytes
for(int j=7;j>=0;j–)//cycle 8 bits
if((tx_val*>>j)&B00000001==1)bit_tx(1);//check for 1 and transmit 1*

  • else bit_tx(0);//transmit 0*
  • }*
  • }*
  • //stop bits*
  • bit_tx(2);*
  • bit_tx(2);*
  • }*
    //transmit function
    void bit_tx(int num)
  • switch(num)*
  • {*
  • case 0://0 pulse*
  • digitalWrite(tx, LOW);*
  • delayMicroseconds(500);*
  • digitalWrite(tx, HIGH);*
  • delayMicroseconds(500);*
  • break;*
  • case 1://1 pulse*
  • digitalWrite(tx, LOW);*
  • delayMicroseconds(500);*
  • digitalWrite(tx, HIGH);*
  • delayMicroseconds(1500);*
  • break;*
  • case 2://start-stop pulse*
  • digitalWrite(tx, LOW);*
  • delay(10);*
  • digitalWrite(tx, HIGH);*
  • delay(10);*
  • break;*
  • }*
    The RX code isn’t optimized yet because it’s hacked together from my IR receiver code.
    > int rx=7;//RX pin
    > int rx_val;
    > int rx_decode[128];
    > byte rx_byte[4];
    > unsigned int rx_key=0;
    > int rx_keyC = 99;
    > int rx_keyC_last = 99;
    > unsigned long rx_time=millis();
    > int rx_count=0;
    > int rx_index=0;
    > int rx_endmark=0;
    > int rx_stream_last=0;
    > byte rx_CRC=0;
    > void setup()
    > {
    > pinMode(rx, INPUT);
    > }
    > void loop()
    > {
    > rx_keyC = 99;//set null
    > if(digitalRead(rx)==0)//check for data
    > {
    > delay(15);
    > if(digitalRead(rx)==1)//check data stream valid
    > {
    > dig_count=0;
    > digitscan(display_val, 4, dot_val);
    > rxscan();
    > }
    > }
    > if(rx_keyC==0)//do if valid data stored
    > {
    > }
    > }
    > void rxscan()
    > {
    > for(int i=0;i<4;i++)rx_byte*=0;
    _> * for(int i=0;i<=48;i++)
    > * {*
    > rx_decode*=0;
    > _ }_
    > rx_keyC_last = rx_keyC;
    > rx_key=0;
    > rx_count=0;
    > rx_index=0;
    > rx_endmark=0;
    > rx_CRC=0;
    > _ for(int i=0;i<=1024;i++)//caputre data stream*
    > * {*
    > * rx_stream_last=rx_val;
    > rx_val = digitalRead(rx);
    > if(rx_val==0 && rx_stream_last==0)rx_count++;//count low pulse*

    > * if(rx_val==1 && rx_stream_last==1)rx_count++;//count high pulse*
    > * if(rx_val==0 && rx_stream_last==1){rx_count++;rx_decode[rx_index]=rx_count;rx_index++;rx_count=0;}//store pulse count*
    > * if(rx_index>48)goto RX_ENDMARK;//break if overflow*
    > * delayMicroseconds(250);//half of low pulse timing*
    > * }*
    > RX_ENDMARK:;
    > for(int i=1;i<48;i++)
    > * {*
    > if(rx_decode>70&&rx_decode*<100&&rx_decode[i-1]>0&&rx_decode[i-1]<10)rx_endmark=i;//verify stop bit and set end*
    > * }_
    > if(rx_endmark<16){rx_key=0;rx_keyC=98;}//data stream too short to be valid*

    > * rx_count=0;
    > rx_key=0;
    > _//add up long pulses as 2^ for 4 bytes*
    > * if(rx_decode[rx_endmark-1]>5&&rx_decode[rx_endmark-1]<10){rx_byte[3]+=pow(2,0);}
    > if(rx_decode[rx_endmark-2]>5&&rx_decode[rx_endmark-2]<10){rx_byte[3]+=pow(2,1);}
    > if(rx_decode[rx_endmark-3]>5&&rx_decode[rx_endmark-3]<10){rx_byte[3]+=pow(2,2);}
    > if(rx_decode[rx_endmark-4]>5&&rx_decode[rx_endmark-4]<10){rx_byte[3]+=pow(2,3);}
    > if(rx_decode[rx_endmark-5]>5&&rx_decode[rx_endmark-5]<10){rx_byte[3]+=pow(2,4);}
    > if(rx_decode[rx_endmark-6]>5&&rx_decode[rx_endmark-6]<10){rx_byte[3]+=pow(2,5);}
    > if(rx_decode[rx_endmark-7]>5&&rx_decode[rx_endmark-7]<10){rx_byte[3]+=pow(2,6);}
    > if(rx_decode[rx_endmark-8]>5&&rx_decode[rx_endmark-8]<10){rx_byte[3]+=pow(2,7);}
    > if(rx_decode[rx_endmark-9]>5&&rx_decode[rx_endmark-9]<10){rx_byte[2]+=pow(2,0);}
    > if(rx_decode[rx_endmark-10]>5&&rx_decode[rx_endmark-10]<10){rx_byte[2]+=pow(2,1);}
    > if(rx_decode[rx_endmark-11]>5&&rx_decode[rx_endmark-11]<10){rx_byte[2]+=pow(2,2);}
    > if(rx_decode[rx_endmark-12]>5&&rx_decode[rx_endmark-12]<10){rx_byte[2]+=pow(2,3);}
    > if(rx_decode[rx_endmark-13]>5&&rx_decode[rx_endmark-13]<10){rx_byte[2]+=pow(2,4);}
    > if(rx_decode[rx_endmark-14]>5&&rx_decode[rx_endmark-14]<10){rx_byte[2]+=pow(2,5);}
    > if(rx_decode[rx_endmark-15]>5&&rx_decode[rx_endmark-15]<10){rx_byte[2]+=pow(2,6);}
    > if(rx_decode[rx_endmark-16]>5&&rx_decode[rx_endmark-16]<10){rx_byte[2]+=pow(2,7);}
    > if(rx_decode[rx_endmark-17]>5&&rx_decode[rx_endmark-17]<10){rx_byte[1]+=pow(2,0);}
    > if(rx_decode[rx_endmark-18]>5&&rx_decode[rx_endmark-18]<10){rx_byte[1]+=pow(2,1);}
    > if(rx_decode[rx_endmark-19]>5&&rx_decode[rx_endmark-19]<10){rx_byte[1]+=pow(2,2);}
    > if(rx_decode[rx_endmark-20]>5&&rx_decode[rx_endmark-20]<10){rx_byte[1]+=pow(2,3);}
    > if(rx_decode[rx_endmark-21]>5&&rx_decode[rx_endmark-21]<10){rx_byte[1]+=pow(2,4);}
    > if(rx_decode[rx_endmark-22]>5&&rx_decode[rx_endmark-22]<10){rx_byte[1]+=pow(2,5);}
    > if(rx_decode[rx_endmark-23]>5&&rx_decode[rx_endmark-23]<10){rx_byte[1]+=pow(2,6);}
    > if(rx_decode[rx_endmark-24]>5&&rx_decode[rx_endmark-24]<10){rx_byte[1]+=pow(2,7);}
    > if(rx_decode[rx_endmark-25]>5&&rx_decode[rx_endmark-25]<10){rx_byte[0]+=pow(2,0);}
    > if(rx_decode[rx_endmark-26]>5&&rx_decode[rx_endmark-26]<10){rx_byte[0]+=pow(2,1);}
    > if(rx_decode[rx_endmark-27]>5&&rx_decode[rx_endmark-27]<10){rx_byte[0]+=pow(2,2);}
    > if(rx_decode[rx_endmark-28]>5&&rx_decode[rx_endmark-28]<10){rx_byte[0]+=pow(2,3);}
    > if(rx_decode[rx_endmark-29]>5&&rx_decode[rx_endmark-29]<10){rx_byte[0]+=pow(2,4);}
    > if(rx_decode[rx_endmark-30]>5&&rx_decode[rx_endmark-30]<10){rx_byte[0]+=pow(2,5);}
    > if(rx_decode[rx_endmark-31]>5&&rx_decode[rx_endmark-31]<10){rx_byte[0]+=pow(2,6);}
    > if(rx_decode[rx_endmark-32]>5&&rx_decode[rx_endmark-32]<10){rx_byte[0]+=pow(2,7);}
    > rx_CRC=rx_byte[0]^rx_byte[1]^rx_byte[2];
    > if(rx_byte[3]==rx_CRC&&rx_byte[3]!=0)//check CRC and valid data*

    > * {_
    > rx_keyC=0;//valid rx_byte data stored*

    > * }*
    > }
    > [/quote]

You guys are THE BEST!

AWOL's Arduino+Processing oscilloscope idea was a great one. It showed lots of static coming through the receiver pin while I wasn't transmitting.

Then once I started using savitch's transmitting code, the static turned into nice regular patterns.

It's alive. Alive! Thank you.

Hi again, I’ve gotten further. I’ve now gone back to VirtualWire and it does indeed work just fine with these modules. Thanks Mike McCauley for making this awesome library!

I had commented out the following line in the receiver.pde and transmitter.pde files:

vw_set_ptt_inverted(true); // Required for DR3100

But in fact this line was very important :slight_smile: The signal is indeed inverted on the receiver as savitch pointed out.

So yes. VirtualWire examples are all go. You have to add this though (assuming Arduino software version 0016):

#include <WProgram.h>

And that’s before the “include <VirtualWire.h>” line. Then you can set the pin numbers in the setup() function for transmitter and receiver respectively like this:


Hope this helps :slight_smile:

Hi editkid Is there anything else you changed from the examples given. I'm using the jaycar rf tx and rf rx given as examples in the pdf for virtualwire and though it compiles and seems to run nothing is coming through on the receiver. I think I've got the wiring right I used the default pins for vw_set_XXX_pin. I put an LED in for pin 13 and it goes on and off like the example code says it should but nothing on the receiver side. Bit at a loss on how to debug it. Thanks

Hey Wolfgang,

No, I didn't change anything else. Mind you that I did have conflicts with a Wii Nunchuck library at some point, and it took me a fair amount of time to realise that.

Some good things to do when debugging are:

  • set up a test file with nothing in it but the TX/RX code, so as to not cause any conflicts
  • try savitch's code he posted in this thread together with a graphing solution, like the Graph example that comes with Arduino - if you look at the receiving end in Processing, you should see steady patterns when you are transmitting - then you'll know that at least your RF links are working - when you stop transmitting you should see a very noisy graph
  • put a blinking LED on the receiver side when something is received, rather than debugging to the Serial monitor - that's the most basic and most reliable way to debug - once that works, you can try Serial monitoring

Hmm that's all I can think of for now. You're not in the vicinity of Wellington, NZ are you? Because if so I could possibly give you a hand in person.

I had some issues with the 433Mhz RF TX/RX..

Could not get anything across the VirtualWire library using the example Transmitter and Receiver sketch...

I m using some other brand of 433Mhz and found the pinout below:- TX : http://www.alibaba.com/product-gs/298268955/NT_T02B_RF_transmitter.html

RX : http://www.alibaba.com/product-gs/296907836/NT_R03C_RF_receiver.html

I hv the Arduino/Processing Graphing and confirm that the Transmitter is working... the high/low signals ( 1 & 0 ) output from the TX pin is also received on the antenna hole in the Transmitter..

On the receiver side, I'm a bit clueless on how to troubleshoot...

Got a lot of signal from the RX pin but the pattern does not match the TX and with some noise ( some half wave instead of square wave digital shape )

Could NOT get one matching message from the VirtualWire...

Tried all speed, from the default 200, 4800, 9600... nothing works..

Both running Arduino 328 with IDE 019..

Any idea how to Troubleshoot the Receiver ??

Thank you