Look Ma, No Wires!

Reliable high speed wireless connectivity between two or more Arduino boards is something that everyone wanting to get rid of a tabletop tangle of wires will eventually need to implement. As part of my ongoing ERP project, I have decided to modify the ERP chassis to carry a GPS and an array of ultrasonic rangefinders. By establishing a wireless datalink, I hope to be able to build an outdoor mapping robot that would be able to map its surroundings and transmit a 3D image back to a base station.

3d Mapping

3d Mapping by a robot. Image from http://rrt.fh-wels.at/sites/robocup/mapping.html

 

The first step in implementing this project is to be able to set up a reliable high speed wireless datalink between my ERP and a base station (laptop). Zigbee radios are very popular but they are terribly expensive (US$ 40 for a pair). Instead, I chose the NRF24L01+ radio transceivers from Nordic Semiconductor. These amazing little radios cost under US$ 5 (for a pair), operate at 2.4Ghz, and can establish data transfer rates of upto 2 MBPS between two nodes. They have a range of about 50m outdoors and whats more, they even support Auto Acknowledgement, automatic CRC checking, and they can even be configured to form a wireless network. Now thats amazing!

I bought a pair of NRF24L01+ radios and to extend my RF ranges, a pair of NRF24L01+ with a Low Noise Amp and a Power Amp built in. The LNA + PA versions have an advertised range of about 1km and cost a bit more – about US$12 each, but I figured it was worth the investment. If not in this project, I guess they’ll come in handy when I build my first quadcopter.

NRF24L01 Variants

NRF24L01 Variants

These radios are controlled using the SPI protocol and they run on 3.3V DC. After a bit of research on the internet, the first thing I did was solder a 10 uF capacitor between the Vcc and GND pins of the NRF radios. Apparently the voltage regulators on the cheap Chinese clone Arduinos are not quite perfect and there is a lot of ripple on the 3.3 VDC pin. In the image above, you can see my radio with the 10uF capacitor soldered in place. The pinout diagram for thse chips is shown below. Before starting with the RF24 library, make sure that you have the pins connected properly, otherwise there might be plenty of frustration ahead!

NRF24L01 Pinout Diagram

NRF24L01 Pinout Diagram

To drive these radios, I used manaicbug’s awesome RF24 library. For most people, this library seemed to work out-of-the-box and most articles on the net and videos on youtube that use this library demonstrate the GettingStarted.pde example at work. Unfortunately for me, I had a terrible time getting this library to work at first and so I downloaded the NRF24L01 Datasheet from Nordic Semiconductor to try and figure out what was going wrong.

After nearly a week of struggling to understand how these radios were controlled with the RF24 library, I finally determined that there was some sort of timeout error that was preventing my data from going through, but now that I have it working perfectly, I thought I would upload my work so that other people who are having problems might be able to fix their setup.

The first thing is to run maniacbug’s getting started sketch. It can be found in the Arduino Examples->RF24 menu. When you start each sketch (one for tx and another for rx) and open the serial monitor, check to see that the radio details are printed out correctly. If you see a whole bunch of zeros then your pins are probably mixed up. Once you are sure that your radios are both connected properly, you can go ahead with building a basic tx-rx pair.

Radio Status on Serial Monitor. The Radio details look fine, but the datalink is always failing

Radio Status on Serial Monitor. The Radio details look fine, but the datalink is always failing

Debugging the RF24 library can be quite daunting for an inexperienced programmer and like me, if all you need is way to transmit an array of data, then read on. The two examples below are (1) a basic transmitter that sends two values across the RF link and (2) a receiver that receives the two values. Both these sketches can be downloaded from my github repo and they form a nice skeleton from which to build on. I have tried to cull out all but the absolute essentials from maniacbug’s GettingStarted.pde and wrapped them around some very simple function calls.

First, the transmitter sketch. You can download the whole sketch by clicking this link…….

Lets start with the transmitter setup call.

void SetupTransmitter()
{

// Setup and configure rf radio

radio.begin();//this must be called first

radio.setDataRate(RF24_2MBPS);//data rate options

radio.setPALevel(RF24_PA_HIGH); //txn power output

radio.setRetries(15,15);//max 15 retries allowed

radio.setPayloadSize(32);//max payload size is 32 bytes

radio.setChannel(100); //set the channel to use (0 - 125)

radio.openWritingingPipe(pipe);

radio.startListening();

}

SetupTransmitter() must be called from inside the Arduino setup() function and it sets up all the parameters needed to get a NRF24L01+ up and running as a transmitter unit.

In my sketch, the transmitted data consists of 2 floating point values. These are just counters that record the number of successful packets that have been passed over the wireless link.

txData[0] -> the number of successful packets
txData[1] -> the number of failed packets

The can be transmitted over the RF link by calling TransmitData() which transmits the data array and then waits for an acknowledgement from the receiver. TransmitData() returns TRUE if the data was acknowledged correctly by the receiving NRF24L01+ and FALSE if the data was lost.

——————————————————————————————————————–

Now for the Receiver sketch. You can download the whole sketch by clicking this link…

We first call SetupReceiver() from inside Arduino’s setup() to initialise the NRF24L01+ as a receiver.

void SetupReceiver()
{
// Setup and configure rf radio

radio.begin();//this must be called first

radio.setDataRate(RF24_2MBPS);//data rate

radio.setPALevel(RF24_PA_HIGH); //txn power output

radio.setRetries(15,15);//max retries allowed = 15

radio.setPayloadSize(32);//max payload = 32 bytes

radio.setChannel(100);//set the channel to use (0 - 125)

radio.openReadingPipe(1,pipe);

radio.startListening();

}

Just like SetupTransmitter() in the transmitter sketch, we can set all the needed parameters in this function to get the receiver up and running. Now inside loop() we periodically call NewIncomingData() which returns TRUE if any new data has been received. I use the rxData[] array to hold the incoming data. The receiver unit automatically acknowledges receipt to the transmitter.


boolean NewIncomingData()
{
boolean done = false;

if(radio.available())
{
while(!done)
{
done = radio.read(rxData,sizeof(rxData));

}
}

return done;
}

Thats it!! A pair of simple tx-rx sketches that provide reliable and cheap wireless data transfer between two Arduinos using Nordic Semiconductor’s NRF24L01 chips.

Here is a screenshot of my transmitter serial interface showing how reliable the data transfer really is. And of course, many thanks to maniacbug for creating such a superb library for the NRF24L01!!

Perfect Wireless Data Transfer

Here is a small video showing how I used these sketches to send motor commands from a joystick…

Advertisements

4 thoughts on “Look Ma, No Wires!

  1. when I try to verify a receiver code it gives error:

    RF_24_Basic_Rxn.ino: In function ‘boolean NewIncomingData()’:
    RF_24_Basic_Rxn:68: error: void value not ignored as it ought to be
    void value not ignored as it ought to be

    Any solution for that?

    • hmm… I have never seen that error before. I am in the middle of moving house right now…all my stuff is packed in boxes and I can’t help you right now. I’ll need to rig up a basic tx-rx circuit before I can try anything so it may take some time till I have all my stuff unpacked!!

  2. I’m completely new to Arduino and zero experience programming. do you have a wiring diagram that I may use to ensure ive properly connected all the pieces to include the LED. Thanks

    • This project may be a little daunting for someone who is completely new to Arduino, C++, and the SPI library. You will need a little experience before trying this out. I only say this because, in case you don’t get it right the first time, with no experience in these matters, you will find it very difficult to find out what is wrong. This link will show you the connections needed by I strongly recommend you spend some time learning Arduino, c++ and have a basic understanding of how the SPI library works before you attempt this project….

      http://arduino-info.wikispaces.com/Nrf24L01-2.4GHz-HowTo

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s