Introduction: Arduino and NRF24L01

About: I am a contract software developer, mainly web based these days. My hobbies are fixing stuff that wasn't broken until I got my hands on it, electronics, Arduino and Modern Jive Dancing.

The reason behind this short learning curve:

My son likes to be shut away in his room away from the rest of the noisy family. His mum needs his presence from time to time to help with his autistic brother and meals etc. He asked me about having something in his room that would save his mum going up and down the stairs to get him and I suggested a wi-fi doorbell. Easy solution. He wanted something that was two way. No more details than that, like audio or visual. I had heard that the NRF24L01 was a very cost effective and yet effective little radio device, so I decided to do some research and see what I could come up with.

There are a number of Instructables available that show how to use the NRF24L01 radio module with an Arduino. I found that it was difficult to find a simple setup where two Arduino's could communicate in the exact same way. I wanted both setups to each transmit and receive in the same way and that would define the most simplest way of doing both things on two Arduinos. Once I have two Arduinos communicating back and forth, I then have the basic framework to extend them to do other things.

This Instructable does not produce the product that my son wants, but does produce the framework for it and many other simple two-way applications.

Step 1: The NRF24L01 Module

The main features for the NRF24L01 are as follows:

Operates in the 2.4HGz ISM band Supply voltage is 3.3V (very important to remember this) The SPI pins are 5V tolerant which is useful for Arduino applications It has 126 selectable channels (frequencies), having channels can help to avoid any possible interference with nearby devices that are using the same frequency. Can be trial and error. Channels selectable in 1MHz increments

Modules dimensions (approx): Small board with built in antenna:- 30mm X 16mm Small with vertical antenna mount:- 30mm X 16mm Large with horizontal antenna mount:- 41mm X 16mm (antenna mount protrudes another 7mm)

The boards are not breadboard friendly so need to be connected with female dupont leads. There is also an adapter plate, which is still not breadboard friendly, but breaks out the pins to a single row with Vcc and GND on their own. Another advantage of the adapter plate is that it has an on-board 3.3v regulator (and bypass capacitors) which means that you can use a 5v supply.

There have been problems noted with just using the 3.3v supply from the Arduino in that you have to solder capacitors onto the board to help with current surges etc. I went for the easier option and used the adapter plate and ran everything from 5v. Adapter plate dimensions:- 27mm X 19mm. Adds approx 17mm to the length of each board and obviously a bit of depth too. It is possible to de-solder the male and female pin headers and just solder the boards together. It would give you a smaller footprint but not for the faint hearted.

Step 2: Putting It Together

Parts list:

  • 2 X Arduinos
  • 2 X Breadboards
  • 2 X NRF24L01
  • [optional] 2 X YL-105 breakout boards for the NRF24L01. This allows for 5v connection and easier wiring
  • 2 X Momentary switches
  • 2 X Red LEDs
  • 2 X Yellow LEDs
  • 4 X 220 ohm resistors
  • Jumper wires

I use AliExpress for nearly all of my cheap components especially if I require more than one item.

They are cheap components from China mainly, but I have not yet had a single bad component.

I love using the Arduino and therefore everything I do is low voltage and cheap components are up to the job. However, if I ever moved to something more critical or high voltages etc, then I would most likely source my components from somewhere else.

Connections:

The module communicates using SPI protocol. Serial Peripheral Interface bus

The pin arrangement that was used here was:

NRF24L01 Arduino pin

VCC 3.3 V If you use the YL-105 breakout board, the Vcc lead can go to the 5v Arduino pin

GND GND

CS 8 (Can be any unused pin but is defined in the code)

CE 7 (Can be any unused pin but is defined in the code)

MOSI 11 (Must be the SPI MOSI pin 11 or ICSP pin 4)

MISO 12 (Must be the SPI MISO pin 12 or ICSP pin 1)

SCK 13 (Must be the SPI SCK pin 13 or ICSP pin 3)

Wiring for LEDs and switch:

  • Arduino pin 2 to Yellow LED long lead - anode
  • Yellow short lead - cathode to 220ohm resistor, then second resistor lead to GND
  • Arduino pin 3 to Red LED long lead - anode
  • Red short lead - cathode to 220ohm resistor, then second resistor lead to GND
  • Arduino pin 4 to switch, other side of switch to GND

The physical build of the two boards are identical.

There are minor software differences for the reading and writing pipes for the respective boards.

Step 3: The Code

The code that I created for both Arduinos is almost identical so I'll only show one of them.

All code files are available for download.

#include //comes with Arduino

#include "RF24.h"//can be found through the IDE: Sketch/Include Library/Manage Libraries/ Search for RF24 and locate RF24 by TMRh20/ more info / Install

//set up the button and LEDs

#define button 4

#define confirmLed 2

#define led 3

RF24 NRF24L01 (7, 8);//create object called NRF24L01. specifying the CE and CSN pins to be used on the Arduino

byte address[] [6] = {"pipe1", "pipe2"};//set addresses of the 2 pipes for read and write

boolean buttonState = false;//used for both transmission and receive

void setup() {

//setup the Arduino pins

pinMode(button, INPUT_PULLUP);

pinMode(confirmLed, OUTPUT);//yellow LED

pinMode(led, OUTPUT);//red LED

NRF24L01.begin(); //open the pipes to read and write from board 1

NRF24L01.openWritingPipe(address[0]);//open writing pipe to address pipe 1

NRF24L01.openReadingPipe(1, address[1]);//open reading pipe from address pipe 2

//this is the only difference in the two sketches required

//the two lines below are for board two, notice how the reading and writing pipes are reversed

//NRF24L01.openReadingPipe(1, address[0]);//open reading pipe from address pipe 1

//NRF24L01.openWritingPipe(address[1]);//open writing pipe to address pipe 2

NRF24L01.setPALevel(RF24_PA_MAX);//set RF power output to minimum, RF24_PA_MIN (change to RF24_PA_MAX if required)

NRF24L01.setDataRate(RF24_250KBPS);//set data rate to 250kbps

//If the frequency of 110 below is a problem with other wi-fi for you increment by 1 until it is ok

//Don't forget that both sets of code must have the same frequency

NRF24L01.setChannel(110);//set frequency to channel 110.

}

void loop() {

//Transmit button change TO the other Arduino

delay(10);

NRF24L01.stopListening();

buttonState = digitalRead(button);//test for button press on THIS board

if (buttonState == LOW)//button is pulled up so test for LOW

{

NRF24L01.write(&buttonState, sizeof(buttonState));//send LOW state to other Arduino board

//flash the yellow LED to show progress

digitalWrite(confirmLed, HIGH);

delay(100);

digitalWrite(confirmLed, LOW);

}

buttonState = HIGH;//reset the button state variable


//Receive button change FROM the other Arduino

delay(10);

NRF24L01.startListening();

if (NRF24L01.available())//do we have transmission from other Arduino board

{

NRF24L01.read(&buttonState, sizeof(buttonState));//update the variable with new state

NRF24L01.stopListening();

}

if (buttonState == HIGH)//test the other Arduino's button state

{

digitalWrite(led, LOW);

}

else

{

flashLed();//indicate that the button was pressed on the other board

}

buttonState = HIGH;//reset the button state variable

}

//flash the red LED five times

void flashLed()

{

for (int i = 0; i < 5; i++)

{

digitalWrite(led, HIGH);

delay(200);

digitalWrite(led, LOW);

delay(200);

}

}

Step 4: Arduino Code and Fritzing Files

Unless you upload the code onto the two Arduinos at separate times make sure that you have two different COM ports selected otherwise you will have exactly the same code on both.

I hope that this may be of interest to you and help a beginner with their first implementation of an NRF24L01.

If nothing else, it will give you a working framework that you can build upon.

Step 5: Update Based on Possible Problems

I have had a couple of comments from Tony in Italia and Andrea where they are both having trouble wiring this circuit up to an Arduino Nano.

About a year ago I bought two Nanos but never got around to using them, so I took this opportunity to solder them up and put them to use.

I had taken the original build apart, so I recreated it from the Instructable with an Arduino UNO as before, just to make certain that everything worked.

I have added a couple of images of this build.

It shows the wiring slightly different and may be easier to see.

I did have a slight glitch/delay on one of the NRF24L01 boards, but it seemed to sort itself out.

I swapped out the UNOs and replaced them with the Nanos, uploaded one sketch to one Nano and the other sketch to the other Nano, and I was expecting problems, but it all worked with no changes to the code.

It is important that the different sketches are uploaded onto the two Arduinos.

The differences are only slight but very important.

I have added a couple of images for this build as well.

That leads me to think that there may be either a bad connection or my instructions were ambiguous.

I have used YL-105 breakout boards for the NRF24L01s so that I can use 5v.

If you are not using the breakout boards then you must use 3.3v.

If you push 5v into the NRF24L01, it will most likely die.

There seven wires in use on the NRF24L01 board

  • GND
  • Positive 3.3v
  • CS to Arduino pin 8 (defined in the code)
  • CE to Arduino pin 7 (defined in the code)
  • MOSI to Arduino pin 11 (mandatory)
  • MISO to Arduino pin 12 (mandatory)
  • SCK to Arduino pin 13 (mandatory)
  • IRQ is not used
  • Yellow LED long lead - anode, to Arduino pin 2
  • Yellow short lead - cathode, to 220ohm resistor, then second resistor lead to GND
  • Red LED long lead - anode, to Arduino pin 3 Red short lead - cathode, to 220ohm resistor, then second resistor lead to GND
  • Arduino pin 4 to switch, other side of switch to GND

If I ever have a build that does not seem to work, I take it apart and start again, especially with a build that is quite small, that way I eliminate any previous mistakes.

The only thing that I can think that may be incorrect on Tony's and Andrea's board is that the MOSI and MISO may have been swapped around.

Hope this helps them and anyone else who may be having problems.

Step 6: Video Demonstration Added

Video uploaded to give a quick demonstration of the setup and use.

Wireless Contest

Participated in the
Wireless Contest