Download PDF Parts List View on YouTube Download Code


Arduinos are great for many reasons, one of them being their ability to wire up to almost anything.  But there are times when you want to connect to your Arduino without using any wires, and when you do get the desire to go wireless there are several methods to choose from.

In this article (and in the corresponding video) I will examine one method of Arduino wireless communications, the nRF24L01+ module.  This is an inexpensive module that provides 2-way communications using the 2.4 GHz band. This band is free to use for low power devices without a license and in some cases can be useful up to a kilometer (although you should expect much shorter ranges without a special antenna).

The nRF24L01+ is available in a number of different configurations, in this article I’ll look at a couple of the more popular ones. We’ll hook them up and use a very extensive library to facilitate communications between them.

Robot Car with Wireless Joystick

After we get them working we will use them to build something fun – a wireless joystick control for the Robot Car Base that we worked on earlier.

Before we begin let’s examine the nRF24L01+ and some of the factore you need to take into account when designing wireless devices.

Wireless Communications

We have been sending information wirelessly since the late 1880’s, Thomas Edison used a system of Electromagnetic Induction to send telegraph signals from a moving train to a set of wires beside the track. Wireless devices are pretty well a part of our lives and most work using one of the following methods:

  • Signals are sent on beams of infrared light
  • Signals are sent using radio waves

Radio waves have a number of advantages over beams of infrared light, the most obvious is that radio waves can travel (to a degree) through walls and most other obstructions.

Radio waves are by no means a perfect method of communication, they are subject to interference from a number of sources and can be obstructed by metal or thick walls. But they do serve their purpose in a number of low-speed data applications and are thus perfect or Arduino and Raspberry Pi experimenters who want to build remote controlled devices or who need to send data without wires.

Radio signals are based upon the concept of changing or “modulating” a “carrier wave” that is transmitted wirelessly to a receiver. On the receiving end the carrier wave is stripped off and the signal is “demodulated” to extract the original information from it.

Since these carrier waves can interfere with one another the allotment of them is strictly controlled, and every nation has a government department responsible for regulating them. In the United States it’s the Federal Communications Commission (FCC), in Canada it’s the Canadian Radio and Television Commission (CRTC) and in the UK the radio waves are regulated by the Office of Communications (Ofcom). Using radio carrier frequencies illegally can result in a very stiff fine and is also pretty rude, so just don’t do it.

There are plenty of frequencies available to experimenters like us, one of the most popular is the 2.4 GHz Band.

The 2.4 GHz Band

The 2.4 GHz Industrial, Scientific and Medical (ISM) band has been reserved for unlicensed low-powered devices and this makes it perfect for building remotely controlled Arduino devices. Of course it also makes it perfect for a number of other devices in your house like wireless routers, cordless phones, Bluetooth gizmos and other wireless dodadds.

The band in question runs from 2.400.0 GHz to 2.483.5 GHz and in order to make it possible for multiple devices to coexist it’s broken down into channels. Although there are 14 channels available not every one is legal in every area. Channels 1 to 11 are legal in most every part of the world so you’d be advised to contain your experimenting to those channels.

As communicating on the 2.4 GHz band is a pretty common function there are a number of modules made for exactly that purpose. The one we will be playing with today is possibly the most popular, it’s available for a couple of dollars or less on eBay and Amazon.

The nRF24L01+

The nRF24L01+ is the part number of a common chip used to construct 2.4 GHz transmitters and receivers, or “transceivers”. This chip has been used to create some simple and inexpensive modules that can be used to transmit and receive data using the 2.4 GHz band.

There are a variety of modules available based upon the nRF24L01, I’m going to use two very common ones in this article. If you have a different module it should work fine, just be sure to observe the wiring and especially the power supply requirements.


The two modules I’m using are quite similar and are interchangeable, the difference between them is that one of them has a built in Low Noise Amplifier (LNA) and an external antenna connection.  I tend to prefer that one even though it’s a bit more expensive as it can be used for reliable data communications over a pretty fair distance. Unless you live in a castle it will probably be more than sufficient to cover your entire house.

All of the experiments, including the wireless joystick, may be built with either module (they share the same pinouts) but you’ll achieve better range with the model with the external antenna.

nRF24L01 Connections

The nRF24L01 has an 8-pin connector that interfaces it with the outside world.  This connector is common between both styles of nRF24L01 modules. Although the nRF24L01 is powered by a 1.9 to 3.9 volt supply the logic pins are 5-volt tolerant so they can be used directly with an Arduino or other 5-volt logic microcontroller.


The nRF24L01 communicates using the Serial Peripheral Interface or SPI bus.  This is a standard bus that is used by many microcontrollers and microcomputers including the Arduino and the Raspberry Pi.

The SPI bus uses a concept of a Master and Slave, in most common applications the microcontroller or microcomputer is the Master and the nRF24L01 is the Slave.  Unlike the I2C bus the number of slaves on the SPI bus is limited, on the Arduino Uno you can use a maximum of two SPI slaves.

The SPI bus is a bidirectional bus, meaning that the master and slave can transmit and receive simultaneously, however the library we will be using with the nRF24L01 doesn’t do that.

Each slave device needs to be selected by the master in order for it to communicate. Only one slave can communicate at any given time. The nRF24L01 and other slave devices have an Interrupt pin that can alert the master when they need to communicate but the library we will be using today ignores that so in our applications we won’t be connecting the interrupt pin to the Arduino.

Module Connections

The connections to the nRF24L01 module are as follows:

nrf24l01 Module Connections

  1. GND. This is the Ground Pin. It is usually marked by encasing the pin in a square so it can be used as a reference for identifying the other pins.
  2. VCC. The positive voltage. This can be anywhere from 1.9 to 3.9 volts. It os NOT 5-volt tolerant!
  3. CE. Chip Enable, an active-high pin. When selected the nRF24L01 will either transmit or receive, depending upon which mode it is currently in.
  4. CSN. Chip Select Not. Thi is an active-low pin, it is the pin that the SPI bus uses to select the nRF24L01 slave.
  5. SCK. The Clock pin, an external clock source provided by the SPI bus Master.
  6. MOSI. Master Out Slave In. The input to the nRF24L01.
  7. MISO. Master In Slave Out. The output from the nRF24L01.
  8. IRQ. The Interrupt output pin.

The style of nRF24L01 that uses an external antenna also has an SMA connector for attaching the antenna.

Power Supply Considerations

Because the nRF24L01 has a power supply range of 1.9 – 3.9 volts it can be battery powered. It is also common to power the module with a 3.3 volt power supply.

When selecting a power supply it should be noted that the nRF24L01 can consume a fair amount of current when transmitting at its highest power. Your power supply should be capable of providing at least 300 mA of current.

Noise on the power supply can also cause problems with the nRF24L01. It is advised to place a filter capacitor (100 microfarads is ideal) across the power supply lines as physically close to the nRF24L01 module as possible to eliminate power supply noise.

Another way to resolve the power supply issues, and the one I suggest you employ, is to use an Adapter Module for your nRF24L01.

nRF24L01 Adapter Module

The nRF24L01 Adapter Module is a very inexpensive prototyping board that simplifies working with the nRF24L01. I recommend you use one and I show it in all the schematics included in this article.

The adapter module has an 8-pin female connector to allow you to plug in an nRF24L01, it can accommodate either the module with the =integrated or external antenna.  It also has a 6-pin male connector for the SPI and Interrupt connections and a 2-pin connector for power input.

The adapter module has its own 3.3 volt voltage regulator and a set of filter capacitors, so you can power it with a 5-volt power supply. Assuming your power supply has the required current capability the adapter module will resolve all of the power supply considerations mentioned above.

Since these modules are available for about a dollar a piece there is no real reason why you shouldn’t use one. They can make the difference between success and failure with your nRF24L01 design.

nRF24L01+ and Arduino

In our experiments we will be using two nRF24L01 modules with a couple of Arduino Unos. You could of course use another model of Arduino, if you do however you may need to change the pinouts as different Arduino models use different pins for the SPI bus.

I’ll describe the pinouts for both the Arduino Uno and the Arduino Mega 2560 here. Going forward (in in the schematics) I’ll only be using an Arduino Uno so if you are using a Mega 2560 you’ll need to substitute pin numbers accordingly. Our Robot Car project was based around an Arduino Uno, this is the project that we will be modifying to use the wireless joystick with.

Arduino Libraries and Connections

As with other radio modules there are a number of libraries available for the nRf24l)1. Using a library will really simplify creating projects with these modules.  

The following libraries will all work with the nRF24L01+ modules:

  • TMRh20 – This library has been around for several years.  It is great for creating secure wireless communications devices. You can read more on the TMRh20 Project Blog and get the latest version on the TMRh20 GitHub repository fork for Arduino devices.
  • RF24 – This is an old standard and has been used in many nRF24L01 projects. It has been superseded by the RadioHead and TMRh20 libraries.
  • Mirf Library – Based on the Tinkerer library. This is a much older library so you won’t find too many projects based upon it anymore.
  • RadioHead – This is a modern library with many advanced features, capable of supporting many RF modules.

In the experiments we will be performing and for our wireless joystick project we will be using the RadioHead library.

Please note that not all of the libraries listed above use the came connections to the Arduino, and that the connections differ depending upon which type of Arduino you are using.

RadioHead Library

RadioHead is a library written by Mike McCauley for the Airspayce company.  I used it in a previous article, Using Inexpensive 433MHz Transmit and Receive Modules with Arduino.

This is an advanced library which allows many methods of packet radio communications between RF modules like the nRF24L01.  It contains many different drivers for different RF modules, the driver for the nRF24L01 is the RH_NRF24 driver.

You can learn more about the RadioHead library and download the ZIP file that you will need to install in in your Arduino IDE on the RadioHead website.  Look for the link to the ZIP file near the top of the description on the page.

Once you download the ZIP file you will need to install it in your Arduino IDE.  This is a very simple process:

  1. Open the Arduino IDE.
  2. Select Sketch from the top menu bar,
  3. Select Include Library from the Sketch menu drop-down.
  4. Select Add .ZIP Library from the Include Library sub-menu.
  5. Use the dialog box to select the ZIP file you have downloaded.
  6. The RadioHead library will be installed.

After you have the RadioHead library installed in your Arduino IDE you are ready to begin the experiments with the nRF24L01.

Hooking up the Arduinos

The RadioHead library comes with a number of sample sketches that illustrate its use. We will begin our experiments with a few of these sketches, then we’ll modify a couple of them for our joystick project.

Here are the connections you will need to make for an Arduino Uno:

nRF24L01 Arduino Demo Hookup

Note that you will need to make two of these circuits! We will refer to one of the circuits as the Server and one as the Client. The wiring for both is identical.

Also note that I’m illustrating the schematic using a nRF24L01 Adapter Module which has its own voltage regulator to supply the 3.3 volts to the nRF24L01.  You can wire directly to the nRF24L01 itself if you wish but you’ll need to use the 3.3 volt output from your Arduino and not the 5 volt output (which will likely destroy your nRF24L01 module).

Note that many Arduino clones don’t have sufficient current on the 3.3 volt output for the nRF24L01. Even if yours does it’s advisable to use a filter capacitor across the power supply lines. But again your best bet is to simply use the nRF24L01 Adapter Module and save yourself a lot of grief and frustration!

If you are using an Arduino Mega 2560 then the pinouts for the RadioHead library are a bit different:

  1. GND. This is still Ground of course so it goes to one of the Mega 2560 ground pins.
  2. VCC. Again this is still a power supply connection. See the notes above regarding which voltage to use.
  3. CE. This is the same as the Arduino Uno, it goes to pin 8 on the Mega 2560.
  4. CSN. Connect this to output pin 53 on the Mega 2560.
  5. SCK. Connect this to output pin 52 on the Mega 2560.
  6. MOSI. This goes to pin 51 on the Mega 2560.
  7. MISO. Finally this goes to pin 50 on the Mega 2560.

Note that the IRQ pin on the nRF24L01 is not used with either of the Arduino boards as it’s ignored by the RadioHead library.

Once you have everything hooked up you are ready to run the first sketches.  

RadioHead Sample Sketch – Client & Server

The first sketches we will be running are the basic client and server examples included with the RadioHead library. You can find and load them as follows:

  1. Open the Arduino IDE (you may have already done this).
  2. Open the File menu from the top menu bar.
  3. Select Examples. A sub-menu will be displayed.
  4. Scroll down the Examples sub-menu to the section at the bottom titled Examples from Custom Libraries.
  5. Select RadioHead from the menu. Another sub-menu will appear beside this one.
  6. Select nrf24 from the RadioHead sub-menu.
  7. A list of example sketches for the RadioHead RH_NRF24 Driver will be displayed.

There are two sketches we need to load, one on each Arduino. If you don’t have the luxury of having two computers then you can do these individually using one computer.

The sketches we need are as follows:

  • On the Server Arduino load the nrf24_server sketch.
  • On the Client computer load the nrf24_client sketch.

The sketches are very well commented so I’ll just go over some of the essential elements of the here.

Each sketch includes the RadioHead RH_NRF24 library as well as the Arduino SPI library. They both then declare an instance of the radio driver. If you want to change the wiring or use a different type of Arduino you can add optional parameters when declaring the driver.

After that they both move into the Setup routine, which begins by setting up the serial monitor and initializing the driver.  Afterwards the setChannel method is called to change the radio channel from the default channel (which is channel 2) to channel 1. You can experiment with different channels if you find any 2.4 GHz devices you have (i.e wireless mice) interfere with the experiment.

You can also add parameters to change the data rate and transmit power of the module. A slower data rate will result in a longer range of operation. Just be sure to keep the data rate and channel the same between the server and client.

We then proceed to the loop.

On the server side the loop starts by looking for a message from the client.  If it is received it is placed into a buffer and then printed to the serial monitor.  After that a reply “And hello back to you” is placed into an array and is sent to the client.

On the client side the loop begins in the opposite fashion. A message “Hello World” is placed into an array and is sent to the server.  We then wait to receive a message from the client (the “And hello back to you” message). If/when we receive the message it gets printed out to the serial monitor.

If you are lucky enough to have two computers you can open both serial monitor and observe the interaction between the server and client. If you only have one computer then I suggest you power one Arduino with a battery or USB power supply while you use your computer to power and monitor the other one.

While this is a very basic sketch it does illustrate how the RadioHead library makes it easy to work with the nRF24L01. And it also has a practical use – you can use it (with one Arduino battery powered) to determine the range you can achieve with your two modules. If you have both the modules with integrated antennas and the ones with external antennas you’ll soon see how vastly superior the external antenna modules really are.

RadioHead Sample Sketch – Reliable Datagram

The previous sketches work well and for many applications they are all you’ll ever need. But if you have a situation where you’re transmitting data that simply must be received without errors then you’ll want to look at another method.

This can be a requirement when you are breaking up a large file into several small bits. The transmitting end needs to make sure that the receiving end has received every bit intact. If it isn’t then the data needs to be resent.

Data transfer on the Internet works using this principle.

The RadioHead Reliable Datagram method of exchanging data also uses this method of verifying data integrity. It doesn’t require any special coding on either end as the Reliable Datagram library does it all for you in the background.  Let’s look at it now.

For this experiment you won’t need to make any wiring changes as the hookup is identical to the previous experiment.

Go back into the RadioHead Library Example sketches for nrf24 and select the following two sketches:

  • On the Server Arduino load the nrf24_reliable_datagram_server sketch.
  • On the Client Arduino load the nrf24_reliable_datagram_client sketch.

Again these sketches are well commented and they also have many similarities to the sketches we just looked at, so I’ll mostly discuss the differences here.

Aside from the two libraries loaded in the previous sketches these sketches also load the RadioHead RHReliableDatagram library.

Afterwards two constants are defined, a CLIENT_ADDRESS and SERVER_ADDRESS. These addresses are not radio channels, instead they are addresses used within the datagram packets exchanged between the server and client.

After creating an instance of the radio driver each sketch set up a datagram manager using one of the addresses defined above (this is where the server and client differ).

In the setup routine the serial monitor is setup and the datagram manager is initialized.

Outside of the setup routine and before the loop an array is defined with the data to be sent and a buffer is defined.

In the loop the operation is very similar to the previous sketches. The server waits for a message to be received from the client, prints it to the serial monitor and then sends a message of its own. The client does the same in reverse.

One thing you will notice in the serial monitor is that both sides print out the address contained in the received packet.

Try out the demo and see the results. At far range you’ll occasionally notice a slight delay in receiving data, this will occur when packets drop off and need to be resent.

As with the previous sketches this one works very well. We will modify this sketch now to send some joystick data and then use it to build our wireless joystick.

Joystick Demo

The two previous sets of sketches illustrated how to exchange text data like “Hello World” and “And hello back to you”, which in itself can be useful. But in many situations you’ll want to exchange numerical data wirelessly between two Arduinos. An example of this would be sending data from a remote sensor to a base station.

In our next experiment we will send data from a joystick to the remote receiver. Each axis of the joystick will be sent as as single byte along with a “dummy byte” whose use I will explain in due time. Depending upon the position of the joystick the values of the axis data wil range from 0 to 255.

You can of course use this sketch to send other sensor data, it doesn’t need to be from a joystick. Your imagination is the only limitation here.

Each sketch is a modified version of the Reliable Datagram sketches we saw earlier, you’ll recognize a lot of the code.  No sense in reinventing the wheel!

Before we get started you’ll need to take one of the Arduinos and add a joystick to it. The hookup is shown below:

Joystick Demo with nRF24L01 & Arduino Hookup

As you can see the joystick hookup is very simple. If you don’t have a joystick just use two potentiometers as that’s really all that an analog joystick is – a pot for the x-axis and another one for the y-axis.  Each control is connected to one of the Arduino’s analog inputs.

On the other end just leave the Arduino and nRF24L01 wired as they are, the only thing you’ll need to change is the sketch.

Here is the sketch for the joystick side of things. Note that it is based upon the RadioHead Reliable Datagram Client sketch, that was just an arbitrary choice on my part as I could have just as easily used the server sketch.


The sketch starts in the same way as the RadioHead Reliable Datagram sketches, it loads the required libraries. We also define the inputs used by the joystick, as well as client and server addresses for the reliable datagram packets.

We then define an 8-bit unsigned integer array called “joystick” with three elements:

  • joystick[0] is the x-axis value.
  • joystick[1] is the y-axis value.
  • joystick[2] is the “dummy” value.

The only reason for sending the “dummy” value is to have a third byte as our final wireless joystick sketch will use this byte to indicate the motor direction. By defining it in this demonstration sketch we can use the receiver we build here to troubleshoot the final product if necessary.  

I assigned a value of 100 to the dummy value, you can assign pretty well any value between 0 and 255. It’s just there to test data integrity right now.

The setup routine is identical to the RadioHead Reliable Datagram example.

In the loop we start the serial monitor as we will use it to monitor joystick values.  We then proceed to get those joystick values using an Arduino analogRead function on each of the joystick analog inputs.

As the Arduino’s analog to digital converter is a 10-bit converter we will get a value of 0 to 1023 back from each joystick. We use the Arduino map command to convert this into a range of 0 to 255. Each of the hvalues is assigned to its respective element in the joystick array.

The remainder of the sketch is pretty well identical to the Reliable Datagram sketch. The array is sent to the server end and we wait to see if we get a reply. Then we do it all over again.

The other end (i.e. the “joystick receiver”) is even simpler.  Here is the sketch:


The only difference between this sketch and the RadioHead Reliable Datagram server sketch is that we are displaying numerical values in the received data array instead of text.  We label these as X, Y and Z:

  • X is the x-axis reading.
  • Y is the y-axis reading.
  • Z is the “dummy value”.

After loading bnoth sketches run them, with at least the receiver connected to a computer so you can observe the serial monitor. You should observe the values change as you move the joystick.

Robot Car Remote

So now we can see how we can send joystick values. It’s time to put it all together and create our Robot Car remote joystick.

On the joystick side you have already done the wiring, all you’ll need to change is the sketch. On the other end though you’ll need a robot car!

If you followed the instructions in the previous article “Build a Robot Car with Speed Sensors” then you already have a robot car. If not then go and see that article for instructions on putting together a robot car using an inexpensive kit.

As this project doesn’t use the speed sensors you can ignore that part. If you already have built the robot car then just leave it as it is, you don’t need to remove the speed sensors.

If you did build the original car there are some changes you will need to make, specifically in how the L298N H-Bridge motor controller is hooked up. The original design uses some of the pins required by the nRF24L01 so it needs to be required.

Here is the new Robot Car schematic:

Robot Car Arduino Hookup

The connections to the nRF24L01 module are exactly the same as they have been in our other experiments, no surprise there. You can use any type of nRF24L01 module but I strongly recommend using the model with the external antenna for improved performance, at least on the car side.

Using an Analog Pin as a Digital Pin

On the motor side you’ll notice that the pins for Motor A have been moved when compared to the original design. One of them might surprise you – the L289N H-Bridge IN1 pin is connected to the Arduino analog pin A0. Why an analog pin?

If you look at the specs of the ATMega328, which is the heart of the Arduino Uno, you’ll understand why I used A0. It turns out the the “analog” pins on an Arduino can also function quite well as digital I/O pins.

I needed an extra pin for my L298N motor controller and I had a few choices:

  • I didn’t  want to use pins 2 or 3 as the Robot Car uses these for the speed sensors. Even though the sensors are not part of this design I wanted to keep them free.
  • Pins 1 and 2 might look promising but they are also special pins – they are used as the RX and TX lines for the serial interface. I wanted to keep them free, also due to internal reasons they won’;t work very well in this application anyway.
  • I chose to use pin A0. Its and analog pin but it’s also digital I/O pin #14 on the Arduino Uno.

As long as the pin is defined as an output in code it will work fine.

Once you have the car wired up all that remains is to load the code. We will look at the joystick code first.

Joystick Transmitter Sketch

As you might expect the remote joystick sketch is very similar to the joystick demo sketch we looked at earlier. Her it is in all its glory:


Those of you who went through the “Controlling DC Motors with the L298N Dual H-Bridge and an Arduino” article may recognize some of the code here as it’s taken from the sketch I used to demo a joystick with a robot car (that one used a wire).

We start by defining our libraries as we did before. Then we define the analog pins used for the joystick inputs as well as a couple of variables that hold values of those inputs.

The real difference in this sketch is what we do with those values. We want the joystick to operate as follows:

  • If we push the joystick forward the car should go forward. The further we push it the faster it should go.
  • If we pull the joystick back towards us the car should run in reverse. The further we pull it back the faster it should go.
  • If we move it to the left the car should steer left.
  • If we move it to the right the car should steer right.
  • If we leave the joystick in the center position then the car should not move at all.

I established the “middle” of both the horizontal and vertical travel of the joystick to have values between 460 and 564. The exact middle would of course be 511.5 but we are using integers and we also have to consider that two dollar joysticks are not the most precision instruments available.

If you follow the sketch through you should see the logic in this. We determine if the vertical joystick is above 564 and if it is we are going to drive forward. So we set the motorcontrol[2] variable to a value of 0, which in this sketch means “forward”.

If our vertical joystick is below 460 then we set motorcontrol[2] to 1 to indicate we want to go backwards.

We then use the Arduino map function to map the joystick values to a value in the 0 to 255 range for the motor speeds, which are assigned to the motorcontrol[0] and motorcontrol[1] variables.

The horizontal control functions in the same manner, except it applies an offset to the speed values to make one motor spin faster than the other one.

We then send the three variables in the array off to the transmitter, just like we did in the joystick demo sketch.

Joystick Receiver Sketch

The receiver sketch, the one that runs on the car itself, is actually pretty simple. Here it is:


Essentially this is the same receiver sketch we have used in the last demo with the addition of variables to define the motor connections. Note that we use Arduino pin “14” for variable in1, this is of course the analog A0 pin. You could actually substitute an “A0” here if you wish and it will work just fine.

In the setup we define the motor controller pins as outputs. Note that the pins used for the two L298N enable lines need to be capable of PWM as that’s how the motor speed is regulated.

You may notice I have remarked out all of the serial monitor statements. They are not really necessary and just get in the way when the car is operating but you can “unremark” if you need to troubleshoot your car.

The buffer values correspond to the motor control values we used in the transmitter. So buf[2] contolas the motor direction and buf[0] and buf[1] handle the motor speeds.

The motors are controlled with PWM using the Arduino analogWrite function.

Load the sketches and fire everything up. You should now have a remote controlled robot car!


As you can see the nRF24L01 can be used to create some very useful wireless projects with very little code, thanks to the RadioHead library.  If building robot cars isn’t your thing you can still find a lot of use for this powerful combination, and I’ll be featuring some more projects using these devices very soon.

Until then enjoy your robot car and happy motoring!


Parts List

Here are some components that you might need to complete the experiments in this article. Please note that some of these links may be affiliate links, and the DroneBot Workshop may receive a commission on your purchases. This does not increase the cost to you and is a method of supporting this ad-free website.




Sketches for the Article.  All of the sketches used in this article in a very handy ZIP file, just for you!

RadioHead Library. You will need the RadioHead Library for Arduino to run the experiments in this article.

nRF24L01 How-To. This is an excellent resource from the Arduino Info blog that tells you a LOT about the nRF24L01.


Wireless Joystick for Arduino Robot Car with nRF24L01+
Remote Joystick for Robot Car with nRF25L01
Article Name
Remote Joystick for Robot Car with nRF25L01
Learn to use the nRF24L01 radio module to construct a remote joystick control for a robot car.
Publisher Name
DroneBot Workshop
Publisher Logo
Tagged on:     
Notify of

Inline Feedbacks
View all comments
6 years ago

How would the sketch be modified to use this joystick remote and nano shield. Both have CE and CSN wired to D9 and D10. Both use an Arduino Nano, and have a socket for the nRF24L01 module.

6 years ago

Hi, any idea why I copy and pasted the ” Joystick Receiver Sketch ” it compiles just fine. But when I try and add :
It says that it cannot compile error.
And I don’t know why.

6 years ago
Reply to  peter

That should be #include

Reply to  peter

Hi Peter, you don’t specify what file you’re trying to include, but I have the same problem when I add #include to a sketch that uses the radiohead library. I can remove all of the other code and it sitll will not work.Simply adding the Servo library stops the compiler. ???

Steve Tripoli
6 years ago

Hello, thanks for the great tutorial. I have one question what is a good way to stop the car in case the transmitter stops transmitting while the car is moving? I find when that happens I have to chase down the car and pull the power.

1 year ago
Reply to  Steve Tripoli

Are you using integrated antenna?

6 years ago

Hi, great tutorial. I got it working but I’m experiencing some pretty high latency, about 0.5-1 second between when I move the joystick to when my robot responds. Any idea why this might be happening? I’m using the nrf24 model with the external antenna, Arduino Uno for receiver and Arduino Nano for transmitter.



John Powell
6 years ago

Hi, These tutorials are by far the easiest to follow for a beginner like myself, so thank you.
I’m having the same problems as Austin. A 0.5 – 1 second lag using the joystick. I’ve removed the delay(100); command and that hasn’t made any difference. ( I didn’t think it would as it’s only one tenth of a second). Can channel choice make any difference? Can channels become slow if they are busy. Any help would be appreciated, I’m not lazy, I’m frustrated. I will try channel changing next.

Roger Bailey
6 years ago

This is a great tutorial. I was able to put it together without any problems. I did add some LEDS for headlights and tail lights. I would like to be able to turn them off with the switch on the joystick. I just meed to find the code and merge it with your program. I can come up with ideas, but I’m not a programmer. I don’t know if the redhaed library has anything in it or do I just need to write something else in the code. I hope someone can help me.

5 years ago

Hi Bob, great tutorial, but big problems. None of the sketches runs. As I fount out the sketch hangs here ” if (RadioManager.sendtoWait(motorcontrol, sizeof(motorcontrol), SERVER_ADDRESS))” on joystick site or here ” if (RadioManager.available())” on car site. Used the latest library. Othe the latest librarys are not .ino but .pde files (not big problems as just the extension. In your turorial you work with Arduino IDE and did not mention that, did they chance it recently. I double checked all the wiring it is as you printed out in the turorial. I am not a novice in arduino or electronics at… Read more »

5 years ago
Reply to  Rainer

Sorry to disturb you, got the adapters for the nrf24i01 today and the sketch works. Did not think the lack of the 3,3V power of the Arduino Clone is so severe. But did not think that this will hang the sketch totally, instead bring up an error message, what I assumed.

5 years ago

i am very new to adruino im tring to use a nrf24lo1 to send the readings from a pot to a easydriver using nanos can anyone help me out i need to see one then i could learn were im going wrong
nemo 17
10k pot

Akarsh Hegde
5 years ago

My joystick controlled robot is working flawlessly.
The code works perfectly,
thanks to you

5 years ago
Reply to  Akarsh Hegde

Can you share me your email id want to talk regarding this project as having some doubt

basant singh
3 years ago
Reply to  Akarsh Hegde

can u share ur email want to talk regarding this project i have some problem regarding receiver code.

5 years ago

Dear Sir, Can you explain how to transfer HC-SR04 data from one Ardiuno to another by using nRF24L01 module.

Norbert Odhiambo
5 years ago

I really enjoyed the video and appreciate you doing it, I only wish to request if you could help write the sketch code using the l293d chip for the motor control , rf 433mhz transceiver and a wii nunchuck for the joystick

Kenneth T
5 years ago

Great project and very informative. I have built a version with an UNO as receiver and a Nano in the transmitter. Did not have the adapters for my nRF’s but instead power them with a 3,3V step down regulator.
However, it is not working. The cimpiltation and upload works fine, the cables and connections are checked (many times). The serial monitor on the transmitter says ” sendtoWait failed”. The values from the joystick changes when moving it. What can be the problem?

Parashuram Kamble
5 years ago
Reply to  Kenneth T

Did you fixed this problem….
I am also getting the same sir…
If you fixed this problem… Please tell me how you was fixed the problem….?

3 years ago

Same problem here

3 years ago

Did you find a way to solve this?

İsa düzgün
5 years ago

Many thanks for your sharing.

5 years ago

Is it possible to connect two joysticks to one Arduino UNO? How will the code for such configuration look like?

5 years ago

I am making a wireless robot car with nRF24L01 modules as my university project. I have uploaded the codes given by you in project. But when I try to get readings from joystick it always shows ‘init failed’ in Serial monitor of Arduino IDE. I want to clarify that I am using Arduino NANO on transmitter side to make the remote compact and Arduino UNO on receiver side. Will it affect the process of interfacing? I have tried both transmitter and receiver setup on different computers. I have nRF24L01 modules with external antenna. I am following your method throughout the… Read more »

5 years ago
Reply to  Shyam

I have just looked up you prob on the Arduino website. this might help: Uno Connections: SPI: 10 (SS), 11 (MOSI), 12 (MISO), 13 (SCK). These pins support SPI communication, which, although provided by the underlying hardware, is not currently included in the Arduino language. Connect the CE to Digital pin 8. PS SS means Slave Select. If this doesn’t work then get back to me on my email address. you may also try to declare the CE (chip enable) and SS pins in your code as follows: RH_NRF24 RadioDriver(8,10);.You should not need to modify the Uno code. Hope this… Read more »

5 years ago
Reply to  Robert SPANTON

Thanks for your reply on website.
I have tried the connections you mentioned.
But I am still unable to interface between transmitter and receiver.
Following your instructions throughout the project I fill that you can help me.
Please reply if you find something helpful for me.

5 years ago
Reply to  Robert SPANTON

Hello again…Thanks for your help. I want to share something that finally I got success in the wireless interfacing with nRF24L01 modules. I would like to share the problem that I was facing. The labelling was wrong on both nRF24L01 modules. After trying all the different possibilities of error I concluded with this mistake made while production. So I had to be careful while purchasing these types of modules. By the way my robot driven by for motors is working efficiently. And I am happy with the range. I will recommend nRF modules with external antennas to get the batter… Read more »

4 years ago
Reply to  Shyam

what label? or pins? same problems here..need liitle help

1 year ago
Reply to  Robert SPANTON

@Robert SPANTON Thank You for the info to assign CE, the china copy has it hard wired to pin 9 on a rf nano (they put the imposter lgt8f328p processor on it too.

Rakshith C S
5 years ago
Reply to  Shyam

Same problem here..!!!

basant singh
3 years ago
Reply to  Shyam

can u share ur email want to talk regarding this project i have some problem regarding receiver code.

5 years ago

Tried to add the channel change and bitrate change methods (available in the nrf library) in the code using the reliable library. However its tells me that these are not supported in the reliable library, I would really like to change these. Please help.

5 years ago

Can i use cytron MDD10A in place of L298N

Parashuram Kamble
5 years ago

Hi sir…
I am doing arduino robot car +joystick +nRF24L01
I followed all instructions to building but after doing all connections correctly…
In transmitter side it showing messages “init failed” and “send to wait failed” but its reading joystick values when I am changing joystick position…. 😞
And in receiver side… It is showing message “init failed”…. 😞
So please tell me what is the problem to run the program correctly…
Please answer me to soon….what should I change in the circuit and program….

4 years ago

hello …,before ive tried your code..ive simple code…with use old library…, manual ce/csn pin and then..manual radio.write…,the only problem is they only can send 1…,your code seem can send multiple variable…,but without changing haedware or pins…except(9,10) ==>(8,10)..,your code returnt…”init failed”…,if it is not hardware or pins…maybe it on library or soft ware i dont know..,need your little help..very frustating..xixi

5 years ago

Can we use Arduino UNO on the client and Arduino Mega 2560 on the server??? Like not using Arduino UNO on both sides that will work right???

Gary H
5 years ago

Bob, you know how to explain everything with the right details . love your site .I built I legoo bulldozer scaled up 3 times and I’m trying to use your wireless car code to operate it. .My problem is when I push joystick forward or backward nothing happens . . when I push right it turns right in a circle and when I push left it turns left in a circle. I have checked wire hook ups many times and all appear to be as you explain in article. . I’ve checked the nrf24lo1 modules for wrong labeling also am… Read more »

4 years ago
Reply to  Gary H

TENGO EL MISMO PROBLEMA, LLegaste a solucionarlo?

1 year ago
Reply to  Gary H

int enA = 9; these turn it on
int in1 = 14; these control direction
int in2 = 4; these control direction

// Motor B Connections
int enB = 5; these turn it on
int in3 = 7; these control direction
int in4 = 6; these control direction

i think the en lines have to be on PWM pins

5 years ago

I was trying to do the basic experiment with the nRF2401 with the Breakout Adapter with On-board 3.3V Regulator and a Arduino Nano. I have it wired as per the diagram. I loaded up the RadioHead libraries and used the rf24_client and rf24_server. Both sketches loaded correctly. Only the rf24_client was running the monitor said that there was no server.The rf24_server gave an init fail message and the program was not running (no flashing red led). I swapped the client and server circuits and load the client and server sketches and had the same problem. The circuit that was running… Read more »

5 years ago
Reply to  MikeLib

I’m having the same problem. Did you ever fix this?

5 years ago
Reply to  joebo

FYI for anyone having the same issue. I was able to get it working by playing around with the Transmit Power parameter in the setRF method. My computer is close to my wireless router which was provided by my ISP. It handles the wifi in my house as well as provide signal to my set top boxes, I think it was interfering with the NRF module.

1 year ago
Reply to  joebo

Hello Joebo
would you share the the code section that sets the Transmit Power parameter in the setRF method. please.

Michael Mckinney
5 years ago

It’s really awesome that the time was taken to make this, but to not reply to one message is kinda crazy..

4 years ago

Thanks for this great tutorial. However I try to solve a problem of latency between the joystick and the Receiver… More or less 5′ of offset.
Do you have any idea to remove this problem?

4 years ago

First, thanks a lot for this tutorial which help me to introduce with Arduino.
However I have a problem to finalize this project.
I have a great latency between the joystick and the receiver. Maybe more or less 5 secondes.
Can you help me solve this problem please?
Best regards.

Alan Burdick
4 years ago

Great job.Are you planning any robot cars using the XOD software?

4 years ago

Real thanks
Great tutorial….

Derek McRiner
4 years ago

Would I be correct in thinking that the same principles used here to control vehicle motors could also be used to control robotic arm motors (or servos) wirelessly?

Hi Workshoppers, Anyone have this problem? When I add Servo.h (servo library) to a sketch that uses the Radiohead library the sketch will no longer compile, and there is no specific compiler error message. Just, “compiler error” Servo.h library works fine with other nRF24 libraries.

3 years ago

Hi Steve, I had this same error. It is because the servo and the radio head library use the same timer. Google and download the ServoTimer2 library to fix it. Note, the servo will need to have inputs written as PWM signals, not degrees when using servotimer2

4 years ago

Hello, Would someone please help me with modifying the code on the final project to run a Cytron MDD10A motor controller rather than the L298N? I’m stuck!

4 years ago

nrf24.init() returning false… Stuck after 2 days struggle 🙁 Using the Radiohead library AND the NRF24L01 Adapter Module (to avoid any powering issues as described above) I connected the NRF24L01 AND the Adapter Module to an Arduino Mega and loaded the Radiohead nrf24_client sketch : I get nrf24.init() returning false. Checked the wires, rechecked the wires, rechecked again… still the same. Using pins 8 and 50..53. Then I shortened the wires to about 10cm (see discussion above). Still the same problem. In the library init() function, I added some debug and the spiWriteRegister() methods return “strange” Status values. The spiReadRegister()… Read more »

4 years ago
Reply to  MArimont

Did some more debugging. It seems the value of the status returned by spiWriteRegister() is not always meaningfull, so I stopped looking at it. I added some more debug in the init() method, and it seems on the Mega the spiReadRegister() always returns 0, whatever register is read. It is clear the problem is there even before any data is sent over the NRF24, the writing/reading to the internal registers of the NRF24 already fails. Changed all the wires, changed the NR module between the Arduino Uno or Nano and the one connected to the Mega. It is always the… Read more »

4 years ago
Reply to  MArimont

Hi, I finally found the cause of the error (in the Radio Library) on the Arduino Mega, and a simple work around. @Bill : as the (excellent!!!) documentation above is impacted by this error, it is maybe worth mentioning it. It is all about the SPI pin for SS on the Arduino Mega (and maybe other boards). SS should (!) be connected to pin 10, even on the Arduino Mega, due to an error in the RadioHead library. You should then initialize the library as RH_NRF24 nrf24(8, 10); For more details, see Some other feedback that might help other… Read more »

4 years ago
Reply to  MArimont

I am currently facing the same problem. Anyways, thank you for the clear updates. I will follow the comments you have updated above.

Andre Breytenbach
4 years ago

Doing some homework for a possible future project.
Absolutely brilliant info presented clearly and understandably – I love it!
Just one problem:
When I click on the “RF24L01 How-To. This is an excellent resource from the Arduino Info blog that tells you a LOT about the nRF24L01.” link at the end of the article, it does not work.
Anybody with an updated link?
Thanks again

4 years ago

Great Tutorial ! I passed it on to my Ez-Robot / Synthiam friends,

thanks again

Wayne Starkey
4 years ago

Excellent tutorial, I am learning so much from these workshops. The Arduino is very new to me, but using the sketch I have managed to wire up the nRF2401 to the Elegroo robot car and it works amazingly good. had to rewire the L298n but eventually got it all working and it has a great range. I would like to add lights to the car and switch them on and off remotely, but I really haven’t a clue how to go about this, I have done loads of research but to no avail!! if anyone has any links that will… Read more »

4 years ago


Please help, I try to use Radio Head client with Radio Head server and is not working.
When I start serial monitor for server I get “init failed”. I try to use uno and nano, same problem, I change the nrf module, same problem.

Can you help me ?

Thank you

4 years ago

thanks so much for this tutorial it has helped me a lot. But I am still struggling with a big input delay and/or inconsistent connection between transmitters when using the car sketches and ive checked and made sure im getting the correct voltages for the transmitters and ive even tried other codes and they seem to transmit more reliable. So I was wondering is there a way to modify the joystick car code to make the transmitters more reliable. Thanks

Ian Greaves
4 years ago

Hi, this is a great tutorial, I’ve got it all working using Aduino Nanos. I need to control one motor for forward/backward and one motor for left/right. Can you guide me on the changes I need to make to the code to achieve this please? I have tried to change the code but have not had any success.

Hans Alleus
4 years ago

Hi and thanks for a great tutorial. I would like to send the same data from one transmitter to three receivers in a three way camera remote system. Is it possible to use the nRF2401´s this way? Is it possible to create three instances of the radio driver, each with its own CLIENT_ADDRESS and communicate sequentially with the three receivers? I would like to use the RHReliableDatagram but it is not critical.

Shoaib Aziz
4 years ago

A great tutorial but my server side serial monitor just throws a message ‘init failed’. Have tried many different things to troubleshoot. Used the nrf adapter, filter capacitors, checked wiring countless times, powered the module with a separate power source,searched the web for a solution, tried to use different libraries, swaped the client and server modules to check if any one of them is defective but always the client sends its message and the server side serial monitor throws a annoying statement ‘init failed’. Please suggest something to make it work.

basant singh
3 years ago
Reply to  Shoaib Aziz

can u share ur email want to talk regarding this project i have some problem regarding receiver code.

4 years ago

I love the way you teach amazing info. thanks

Malcolm Klein
3 years ago

Do not like the turns using reversal of motor directions. Would prefer turning while driving forward. I tried to modify the code for turning but got a long string of error messages when verifying code. Please provide code for turning while going forward.
Otherwise the code worked remarkably well except for lags in transmissions. For example on going forward there is a short delay before the car responds and continues to go forward for a short time after joystick released.

Jesper Kleemann
3 years ago
Reply to  Malcolm Klein

Swop the connections to driver pins 1 and 2 and pins 3 and 4 then the car/tank should run the right way.

3 years ago

Such a well presented description which clearly explains all aspects of this example. I have looked at a number of others and this demo is much superior.

Jesper Kleemann
3 years ago

Hi! I have build the Joystick Transmitter and the Car Receiver. I could at first not get nrf24l01-joy-rcv-car.ino to work, but after removing the comments in the lines 72 to 80 it worked fine.To low power and I experience latency and/or “run away” behaviour. Putting an 100uF Capacitor on the L298N Driver and/or on the nrf24l01 can help a lot. Good luck in life, everybody!

Harm Leyten
3 years ago

It works for me too but also with quite a bit of latency. I bought some new NRF24L01´s and i will try if something is wrong with my initial NRF24L01´s or not. Anybody else experiencing any lag or latency issues???

2 years ago
Reply to  Harm Leyten

I’m having big latency issues as well.. almost 4 seconds! Any fixes?

1 year ago
Reply to  Harm Leyten

I did. I wanted to try a different channel, data rate, gain but i need help, like an example in the radiohead language. can you help?

2 years ago

would An 100uF capacitor be placed on both of the nrf24l01 modules (transmitter and receiver) or just one of them (transmitter or receiver)?

1 year ago

I will try the cap. what did lines 72 – 80 fix? Latency?

3 years ago

Thanks for the grate video how would you set the nRF24 to a different channel

3 years ago

Shouldn’t server and client address be the same so thy can be connected to one another?

3 years ago
Reply to  Kazem

The server and client address are not what sets the actual radio frequency, so it’s okay that they are different

3 years ago

is there a possibility to use 2 channel pwm motor driver with encoder instead of using a normal DC motor, how to use them ?

Warren’s Corner
3 years ago

I cannot get this to work. I’ve double, triple checked my wiring. I tried flipping pins 11 and 12. All I get is init failed. What could I be doing wrong? I see some sketches on the Arduino web site projects use pins 9 and 10. I’m using Arduino Uno so why different PIN numbers? Does the library determine which pins to use or is it something built into the hardware?

Mathias Schneider
3 years ago

I actually tried this with two arduino unos and it work perfectly, but for a recent project I have to use an arduino mega for the receiver side. And now it does not work anymore, even though I changed the SPI pins to D52, D51, D50 (SCK, MOSI, MISO) and D8, D53 for CE, CSN pins. Does somebody have any resolutions, like changing the pins or changing the program? Additionally, I have to say that I have never used this library before. Thanks in advance for any help

1 year ago

define them in the beginning.
#define CE_PIN 9
#define CSN_PIN 10

Blue Wolf
3 years ago

“Init Failed”!! Aarrgh… Oops sorry. First I’d like to say “Legendary!!!” What a treasure this workshop is and “Thanks!!!”. So back to “AAAaarrghh! Init failed!!” again…again…and again. WTF is going wrong???? WHY??? … Tried decoupling and external power supplies and standing on my head in a bucket of vinegar…. *forehead slap to self*… So check your libraries and sketches. After a week of hair pulling I watched the vid from the beginning…and suddenly Helios dawned!! What, you may ask, was my problem? Duhhh…I was trying to use the RF24 code. Re-uploaded the NRF24 sketches (as opposed to the RF24 ones)… Read more »

Harm Leyten
3 years ago

Hello great tutorial!! everything works, but i do have a delay of like half a second or something. Is that normal? or can i do something about that? putting the antenna’s against to each other severaly reduces lag (not every sent instruction get’s received).

1 year ago
Reply to  Harm Leyten

mee tooo except for the antenna part. I was thinking different channel. wanna help?

Wout Vansteenkiste
3 years ago

Great website, do you have a version with a more low-level library because i would prefer not to use the RF_24 library?

William e Boyce
3 years ago

i’m new to adruino but i’m a builder and am really exited about what it can do. I have little code skill, but i’m trying. I would really like to see you hook up the WayinTop NRF24L01+PA+LNA RF 2.4 Ghz module up to your project and run thru the code and a couple of examples. I learn alot from your presentation and style. Thanks