Contents

Establishing a Wireless Connection with Arduino and NRF24l01

Overview

Nowadays, establishing a wireless connection and creating a wireless network is very important in communication and IOT projects. In this tutorial, you’ll learn how to establish a wireless connection between two Arduino boards and create a network using the NRF24L01 module. 

What You Will Learn

What Is the NRF24L01 Module and How Does It Work?

There are different ways for wireless communication such as Bluetooth, WiFi, and etc. Using the NRF24L01 module is one of the most affordable, simple, and practical ways. 
NRF24L01 Module is a transceiver module, which means it can both send and receive data. NRF24L01 works in 2.4 GHz frequency and uses GFSK modulation. The maximum speed of data transmission of this module is up to 2Mbps and the maximum board is 100 meters (for models with an external antenna the board can be 1 km) in free space.
parameter ResponseTypical value
Working voltage 3.3 v
Current usage in send mode 11.3 mA
Current usage in receive mode 12.3 mA
Current usage in sleep mode 900 nA
Temareture range -40 to +85 C
price 2.5 $
Capability to create a network is one of the NRF module advantages; each NRF module can be connected to 6 other modules.  Therefore, the affordable price, being easy to use, small size, networking capabilities, high board and suitable data transfer speeds make the NRF24l01 module a great option for wireless and IOT projects.  NRF24L01 module interface microcontrollers in SPI protocol and has 8 pins: 
Pin Operation
GND Circuit ground
Vcc Circuit supply voltage(3.3V)
CE Chip Enable
CSN SPI Chip Select
SCK Connection CLK
MOSI Receiving data from Master
MISO Sending data to Master
IRQ Intrupt pin

Required Materials

Hardware Components

Arduino UNO R3 × 2
NRF24L01 × 2

Software Apps

Arduino IDE

Connecting Two Arduino Boards to Establish a Wireless Connection

In order to connect two Arduino boards, you need two NRF24L01 modules, one as master and another as slave. In this example, using a volume on the master side, we control the servo motor on the slave side.

Circuit

Tip
You can connect CSN and CE to any digital pins. 
Tip
Connect SPI pins of the module to SPI pins on board.

Code

You need the RF24 library to use NRF24L01 module. Download the library from the following link:

Rf24 Library Download 

Tip
You need two different codes for slave and master to establish a connection. 

Master 

Upload the following code on your master board.

/*
  NRF24L01 - Controle a servo motor wirelessly
  Master
  modified on 8 Apr 2019
  by Saeed Hosseini @ Electropeak
  
Home
*/ #include <SPI.h> #include <nRF24L01.h> #include <RF24.h> RF24 radio(7, 8); // CE, CSN const byte address[][6] = {"Node1"}; const int potpin = A0; int val = 0; void setup() { radio.begin(); radio.openWritingPipe(address); radio.setPALevel(RF24_PA_MIN); radio.stopListening(); } void loop() { val = analogRead(potpin); val = map(val, 0, 1023, 0, 179); radio.write(&val, sizeof(val)); delay(5);

Slave 

Upload the following code on your slave board.

/*
  NRF24L01 - Controle a servo motor wirelessly

  Master
  modified on 8 Apr 2019
  by Saeed Hosseini @ Electropeak
  
Home
*/ #include <SPI.h> #include <nRF24L01.h> #include <RF24.h> #include <Servo.h> Servo myservo; RF24 radio(7, 8); // CE, CSN const byte address[][6] = {"Node1"}; const int servo = 9; int val = 0; void setup() { Serial.begin(9600); myservo.attach(servo); radio.begin(); radio.openReadingPipe(0, address); radio.setPALevel(RF24_PA_MIN); radio.startListening(); } void loop() { delay(5); radio.startListening(); if ( radio.available()) { while (radio.available()) { radio.read(&val, sizeof(val)); myservo.write(val); Serial.print("Servo position = "); Serial.println(val); } } }
Let’s take a closer look to the code:
RF24 radio(CS, CSN);
Create the required object for module by specifing CS and CSN pins.
const byte address[][6] = {"addr"};
Specify the address for the nodes. Be careful, the sender and receiver addresses must be the same in order to communicate.
radio.openWritingPipe(address);
Determine the receiver for transmitter.
radio.openReadingPipe(0, address);
Determine the transmitter for receiver.
radio.setPALevel(RF24_PA_MIN);
Determine the amount of power consumption for the module, this value must be determined according to the transmitter and receiver distance.
radio.stopListening();
Set the module in transmitter mode.
radio.startListening();
Set the module in receiver mode.
radio.write(&data, sizeof(data));
Sends the data by specifying its size. 
radio.available();
If the receiver receives a data, it returns the value of 1.
radio.read(&data, sizeof(text));
Receives the data by specifying its size, and stores it in data variable.

Create a Network of NRF Modules

Using the NRF24L01 module, you can create a wireless connection and transfer data in your network.  In this example, we want to create a network with three slaves and perform a specific operation in the slaves based on the temperature data, the volume value and the key status sent from the master.  There are two ways to build the network, the simpler way is to act as in the previous example and to have a maximum of 6 separate addresses to send information to the master through 6 slaves.  In the second way, the tree method is used for networking. As a result, the main master is only associated with its subset, and each subset is expanded as a tree. Consequently, we can construct a network containing a maximum of 3125 NRF24L01 modules, so this method is more effective from the first one. 

Circuit

Code

To use this method, you need the RF Network library. You can download it from the following link: 

RF24Network Library Download

Master 

/*
  NRF24L01 - Network
  Master
  modified on 8 Apr 2019
  by Saeed Hosseini @ Electropeak
  
Home
*/ #include <RF24Network.h> #include <RF24.h> #include <SPI.h> #include "dht.h" RF24 radio(7, 8); // nRF24L01 (CE,CSN) RF24Network network(radio); dht DHT; const uint16_t this_node = 00; const uint16_t node01 = 01; const uint16_t node02 = 02; const uint16_t node03 = 03; const int butpin = 3; const int potpin = A0; const int dhtpin = 4; void setup() { SPI.begin(); radio.begin(); network.begin(90, this_node); //(channel, node address) radio.setDataRate(RF24_2MBPS); pinMode(butpin, INPUT); Serial.begin(9600); } void loop() { // Send to Node 01 int potValue = analogRead(potpin); int angleValue = map(potValue, 0, 1023, 0, 179); RF24NetworkHeader header2(node01); bool ok = network.write(header2, &angleValue, sizeof(angleValue)); // Send to Node 02 int buttonState = digitalRead(butpin); RF24NetworkHeader header3(node02); bool ok2 = network.write(header3, &buttonState, sizeof(buttonState)); // LEDs control at Node 022 unsigned long pot2Value = analogRead(A1); RF24NetworkHeader header4(node03); DHT.read11(dhtpin); bool ok3 = network.write(header4, &DHT.temperature, sizeof(DHT.temperature)); }

Node01 

/*
  NRF24L01 - Network
  Node01
  modified on 8 Apr 2019
  by Saeed Hosseini @ Electropeak
  
Home
*/ #include <RF24Network.h> #include <RF24.h> #include <SPI.h> #include <Servo.h> RF24 radio(7, 8); // nRF24L01 (CE,CSN) Servo myservo; RF24Network network(radio); // Include the radio in the network const uint16_t this_node = 01; // Address of our node in Octal format ( 04,031, etc) const uint16_t master00 = 00; // Address of the other node in Octal format const int servopin = 9; void setup() { SPI.begin(); radio.begin(); network.begin(90, this_node); //(channel, node address) radio.setDataRate(RF24_2MBPS); myservo.attach(servopin); } void loop() { network.update(); while ( network.available() ) { RF24NetworkHeader header; int data; network.read(header, &data, sizeof(data)); // Read the incoming data myservo.write(data); } delay(5); }

Node02

/*
  NRF24L01 - Network
  Node02
  modified on 8 Apr 2019
  by Saeed Hosseini @ Electropeak
  
Home
*/ #include <RF24Network.h> #include <RF24.h> #include <SPI.h> RF24 radio(7, 8); // nRF24L01 (CE,CSN) RF24Network network(radio); // Include the radio in the network const uint16_t this_node = 02; // Address of our node in Octal format ( 04,031, etc) const uint16_t master00 = 00; // Address of the other node in Octal format const int ledpin = 5; void setup() { SPI.begin(); radio.begin(); network.begin(90, this_node); //(channel, node address) radio.setDataRate(RF24_2MBPS); pinMode(ledpin,OUTPUT); } void loop() { network.update(); while ( network.available() ) { RF24NetworkHeader header; int data; network.read(header, &data, sizeof(data)); // Read the incoming data digitalWrite(ledpin, !data); } delay(5); }

Node03

/*
  NRF24L01 - Network
  Node03
  modified on 8 Apr 2019
  by Saeed Hosseini @ Electropeak
  
Home
*/ #include <RF24Network.h> #include <RF24.h> #include <SPI.h> RF24 radio(7, 8); // nRF24L01 (CE,CSN) RF24Network network(radio); // Include the radio in the network const uint16_t this_node = 03; // Address of our node in Octal format ( 04,031, etc) const uint16_t master00 = 00; // Address of the other node in Octal format const int fan = 5; //Red wire to pin 13,Black wire to pin GND void setup() { SPI.begin(); radio.begin(); network.begin(90, this_node); //(channel, node address) radio.setDataRate(RF24_2MBPS); pinMode(fan, OUTPUT); digitalWrite(fan, LOW); } void loop() { network.update(); while ( network.available() ) { RF24NetworkHeader header; int data; network.read(header, &data, sizeof(data)); // Read the incoming data if (data > 70) digitalWrite(fan, HIGH); else digitalWrite(fan, LOW); } delay(5); }

What’s Next?

Try to make a two-way connection with two NRF24L01 modules, which means that each module has the ability to send and receive data.
Liked What You See?​
Get Updates And Learn From The Best​

Comments (19)

  • El Mik Reply

    Awesome simple great and rich article. Thank you!!!

    October 15, 2019 at 9:09 pm
    • Saeed Hosseini Reply

      We always try to do our best

      October 21, 2019 at 5:41 am
  • Kiran Mahapatra Reply

    Great project .. Thank You ……..
    Please help me
    in case of 3 transmitter & 1 receiver what to do. I want to make a project …………….. 3 nos transmitter with a push button on each & 1 receiver which have a LED bulb & a LCD display. When push button pressed from any transmitter the led on for a certain time & LCD display will show from which transmitter the switch is pressed . If I want to increase transmitter no what to do?

    January 8, 2020 at 2:40 am
    • Mehran Maleki Reply

      You will still need 4 Arduino Boards, three as masters and one as the slave. In that case, you can use a flag as the sign of each master and control that in your code. For example, take integers 1, 2 and 3 as the signs of your masters. Whenever the push bottom on each of the masters is pressed, it will send its flag sign to the slave. So the slave will know which master has sent the command.

      December 9, 2020 at 5:29 am
  • Ismaiel Reply

    Hello,
    How I can reach the two way connections tutorial ?

    April 5, 2020 at 12:47 pm
    • Amir Mogoeir Reply

      Hello,
      Two way communication is just exactly the as what described here. Use read and write commands in both master and slave boards and you it should be okay.

      May 30, 2020 at 1:28 pm
  • RICARDO BARBOSA Reply

    OTIMO

    May 27, 2020 at 4:02 pm
  • john kod Reply

    tanks
    i want When presing the button sending “50” or “40”
    can you help me

    July 13, 2020 at 4:30 pm
    • Mehran Maleki Reply

      Hi.
      You can use the “network.write()” function for that. Read the code for the master in the “Create a Network of NRF Modules” section for more information.

      December 9, 2020 at 5:40 am
  • Amir Reply

    Hi Saeed,
    If we have only one receiver and want to connect six transmitters, all of which do the same thing at six different nodes, to the receiver , how should be the program in loop section to determine which transmitter has communicated? mostly I would like to go through the simple way and not the “tree connection method”.

    July 14, 2020 at 5:51 am
    • Mehran Maleki Reply

      Hi.
      Just like an older comment of this article, you can use specific signs for your transmitters. For example take integers 1 to 6 as the signs of the masters- transmitters- and send the signs to the slave -receiver-. So the salve will know which transmitter has communicated.

      December 9, 2020 at 5:49 am
  • Marcin Reply

    Hi, I’m having trouble with the NRF24L01 modules working in the network. I wanted to disable the module when idle with the commands radio.powerDown() and radio.powerUP(),
    Unless the radio.powerDown () command works, but not after the radio.powerUP () command. For simplicity, I only made such a code and connected an ammeter. Without these commands there is communication between the modules and the whole program works. Only after sleeping, the module won’t get up.
    #include
    #include
    #include

    RF24 radio(9, 10); // nRF24L01 (CE,CSN)

    RF24Network network(radio); // Include the radio in the network

    const uint16_t this_node = 02; // Address of our node in Octal format ( 04,031, etc)
    const uint16_t master00 = 00; // Address of the other node in Octal format

    void setup() {

    SPI.begin();
    radio.begin();
    network.begin(90, this_node); //(channel, node address)
    radio.setDataRate(RF24_2MBPS);

    }
    void loop() {

    radio.powerDown();
    delay(5000);
    radio.powerUp();
    delay(5000);
    }

    July 15, 2020 at 7:01 am
    • Mehran Maleki Reply

      Hi.
      You’d also need to add “radio.begin()” after the command for powerUp() to get your module running.

      December 9, 2020 at 5:55 am
  • furkan Reply

    hi,

    thia tutorial is very impressive, and thank you for sharing. I want to ask a question. For tree connection, one module can communication with 6 node, and this each 6 node will communication another 6 node. Should all channel be the same? Your example: “network.begin(90, this_node); //(channel, node address)”. All channel value is 90? or should each node have a different channel value?

    Thank You

    January 4, 2021 at 8:22 pm
    • Mehran Maleki Reply

      Hi,
      Generally all channels are the same. But It also depends on the library you’re using, You can check the following link for complete information.
      “https://github.com/nRF24”

      January 6, 2021 at 2:22 pm
      • furkan Reply

        Thank you very much for reply. I did 2 level node, but i dont succeed. I did all software the same. Because, for each node, changing node ids would be enough. For example, all node id value and node id decimal, the code calculates itself. when i node id: 11, code calculate other node id and master id and all of them decimal value. for example, if node id=11, this node = 11, node1 = 111, node2= 211 vb. , this node decimal= 9, node2 decimal 25 vb. , master node = 1. But first level working very well, but 2.level not working. So, there is no problem between master and node1, node2, node3, node4, node5. But when i want to send to node11, not working. But I noticed something, when i want to send to node41, its working. when i want to send to node21, its not working. when i want to send to node42, its working. But when i want to send to node32, its not working. So, if 2.level node id 4X, its working, else not working. What is wrong, i dont know.
        Thank you for reply again.

        March 8, 2021 at 9:13 am
        • Mehran Maleki Reply

          You’re so welcome! And if I ever come up with an idea on how you can fix the problem, I’ll let you know.

          March 10, 2021 at 2:23 pm
  • Bernd Reply

    Hello,
    I hope so you made 2 way connections tutorial ?

    January 21, 2021 at 9:15 pm
    • Mehran Maleki Reply

      Hello.
      I’m afraid not. But that’s on our to-do list. Stay tuned!

      January 27, 2021 at 2:07 pm

Leave a Reply

Your email address will not be published. Required fields are marked *