NRF24L01+ Multiceiver Network

72K9144

Intro: NRF24L01+ Multiceiver Network

If you're here, you probably know basically what a NRF24L01+ device is. If you have a bunch of them, and get them hooked up properly, you can theoretically create a wireless network of Arduinos (or other MC devices). Sounds easy, right? Well, I hope it will be much easier with the help of this Instructable.

If you've been trying to figure this device out, you can pretty well assume that any Sketches prior to 2014 won't work -- that is, they won't verify/ compile due to changes in the Arduino IDE. There's also a paucity of examples that actually demonstrate a network of more than two devices!

Having said that, here are some internet resources that I found exceptionally helpful in my own quest to build a NRF24L01+ multiceiver network:
(Giving all due credit)

http://arduino-info.wikispaces.com/Nrf24L01-2.4GHz-HowTo
This wiki is affiliated with Yourduino.com and has terrific general info on the NRF24L01+. This is the place to go to learn how to make all the proper hardware connections.

http://yourduino.com/sunshop2/index.php?l=product_detail&p=429
You can get your hardware here, of course! The wiki (first link) makes clear that the NRF24L01+ needs good 3.3 V power -- more than what most off the shelf arduinos are designed to provide. The YourDuino RoboRed has a robust power supply that can handle these requirements. With a good voltage regulator and some capacitors, however, you can probably make most MCs work for you (also well described in the wiki).

http://www.nordicsemi.com/eng/content/download/2726/34069/file/nRF24L01P_Product_Specification_1_0.pdf
Spec sheet for the NRF24L01+

https://github.com/TMRh20/RF24
You'll need to install the RF24 Library from this site. The examples with the library which are copyright 2014 by TMRh20 are good.


http://forcetronic.blogspot.com/2015/05/creating-nrf24l01-transceiver-network.html
This forcetronic site has code for a three device network. My code draws very heavily from this example.

STEP 1: Hardware, Software and Connections

For this network you'll need:

1. 3 - 7 MC devices (e.g. Arduino, Leonardo, etc.)

2. same number of NRF24L01+ RF devices

3. jumper wires for the connections

4. sufficient USB ports or other power source for above

5. the RF24 library from the fourth link on the prior page installed in the Arduino IDE

6. 0.1 uf capacitors recommended

The connections are laid out in detail in the first link on the prior page. Basically, the pins in the lower right corners of the diagrams above must be connected to the corresponding Arduino pins. VCC must be 3.3V and CE and CSN from the NRF24L01+ connect to pins 7 and 8, respectively, on the Arduino. The IRQ pin is unnecessary in this application. Soldering a 0.1 uf capacitor between the VCC and ground pins of the NRF24L01+ is a good idea.

STEP 2: The Meat - May Be Tough and Dry

This diagram is the key to understanding how this network works. I've tried to capture the essence of it in the following paragraphs. The next paragraph is by far the most important, as well as being the easiest to follow :) The following step of the Instructable includes code that will also help clarify how this network works.

The defining multiceiver capability is having up to 6 channels (pipes) of radio communication open in a receiving (RX, or "read") mode simultaneously. This takes the form of a hub receiver (PRX - primary receiver) and up to six transmitter nodes ( PTX1 - PTX6 primary transmitters). To simplify the above diagram, six reading (Data) pipes are opened in the primary receiver hub (PRX). Each PTX node links to one of these pipes to use both in transmitting and receiving (TX toward the hub being the primary direction of data flow, but the PTX nodes are RX capable as well). Note that the hub can also "stop listening" and act as a TX, transmitting (or writing) to the PTX nodes -- but this can only be done one pipe/ node at a time.


The addresses/ pipes must have a distinct pattern of bytes: only the fifth byte is entirely unique among all the pipes and is known as the least significant byte (LSB) . Pipe 0 is assigned all five bytes independently. Pipe 1 is also assigned all five bytes independently, but then the first four bytes ( the MSB) of pipe 1 also become the first four bytes of pipes 2 - 5 (if they exist).

Given the design of the hardware and lower level software (libraries), the TX -> RX sequence follows a simple pattern within a sketch. Data payloads can be of static or dynamic length (bytes) and may also be attached to ACK (acknowledge) packets that are routinely returned from receiver back to transmitter to confirm successful transmission (ACK packets, incidentally, are more efficient than repeatedly switching between transmission and reception for two way communication). User management of network traffic largely boils down to restricting transmissions to levels that don't overwhelm RX capabilities (my very simplistic understanding). Error trapping to account for dropped or corrupt data packets, buffer overruns, etc. may also be needed to ensure data integrity.

STEP 3: The Code

This example is a frivolous game in which the PRX generates a random number and the nodes try to guess the number. Its real purpose is to demonstrate the network in action.

The files in this step contain code for the PRX primary receiver (hub) and for the PTX primary transmitters (nodes)

The #define WHICH_NODE statement needs to be altered for each node. Otherwise, the node code is the same.

When running, I suggest powering the PRX first and starting the serial monitor for it. Otherwise you might miss the action!

ENJOY! And please do comment on any way in which this Instructable might be improved.

29 Comments

Big Thank You! - saved me DAYS of hacking those troublesome pipe addresses! (modified receiver code for Python / Pi so that two outdoor Arduinos (Pro Micro and ATtiny841) could send to indoor Pi). Comments in your code were very helpful.
First, thanks for this good instructable.
In the receiver code, the lines below, what indexes the pipe number from 0, 1, 2, etc?
It seems that it should be checking each of the 6 pipes, but to me (a total noob) it looks like it will always be stuck on pipe 0.

while(radio.available(&pipeNum)){
radio.read( &gotByte, 1 );
how can i use this for AVR instead of Arduino ? I added the library to codevision avr, but there was an error, if I had to change something?
sir i need to develop a mesh network using nrf24l01 module can you help me?
Your guide is very helpful but I have some questions:
1 / addresses, whether these addresses are in a number system, how to generate other addresses if I need more nodes.
2 / how are the addresses assigned? otherwise it is in the receiver and differently in the transmitters. I'm guessing that 0 is the first address, 1 is the second, 2 is the third ...
3 / why the transmitter must start with the receiver switched on for communication?

im a little confused, how can i assign a unique identity for each transmitter so that when they are within the range of the receiver, the receiver will be able to determine which of the following transmitter send the dataor signal? pls help im just starting in this field

Please download and read the code. Generally one transmitter uses one data pipe (with a unique address). The receiver knows the identity of the transmitter by the identity of the data pipe on which the data is received.

It is not clear to me if the other pins (SCK,MO,MI) should be connected

The mostly red and black diagram lists the 8 pins of the NRF24l01 and the corresponding pins on the Arduino to which they must be connected. Only the IRQ pin is safe to ignore.

i have modified your code a little for my purpose. now i have a doubt. if all the transmitters are simultaneously sending data how it will be received by the receiver?/ whether there will be some order or so.??

thanks. it will be grateful if u reply.

The chances of the transmitters all sending within 30 us intervals is low, and the transmitter hardware does try to resend packets for which an ACK hasn't been received (as long as you haven't disabled this feature). It is possible, however, to overload the receiver -- packets get dropped. Make sure the transmitters have delays that allow the receiver to receive all packets.

I apologize for not replying sooner.

Are you using multiple usb ports on the same pc for your rx and ptx? If so, I think that could be causing your difficulties. A test would be to use separate computers/ power sources. There should be a way to work around it, but I'm afraid I don't have an easy solution. In general, the rx should be able to continuously receive data without resetting the ptx -- as you said.

Sir, my code is stuck like this

The number they are trying to guess is: 2

when i press the reset button of all ptx ,prx starts to receive data.why is it how can i get the data without resetting arduino

My best guess, if I understand the question, is the ptx will stop transmitting once it has guessed correctly ("done = true;"). As written, the only way to resume guessing is to reset the ptx Arduino.

actually i want to design a system containing 6 tx and 1 receiver connected to net .Each tx is connected to different sensor that continuously read data and transmit this data to cloud through central rx.if i am running your code ,whether the rx will continously receive data without resetting the arduino of ptx.?ii think my previous qtn is not clear to you .In your code i need to reset arduino of ptx or i need to open its com port to get data in rx port.why is it?

Hi, thanks for the instructable.

The primary receiver PRX is
able to listen *simultaneously* to all PTXs because the Arduino clock
is higher than 6*2.4 = 14.4Mhz, right???

The delay in the code for the transmitters is critical. I'm not sure of the exact figures for the time it takes the PRX to receive (and acknowledge) a message, but you have to "throttle back" the transmitters with that delay so as to not overwhelm the PRX. If it takes 30 ms for one message for the PRX, it would take 180 ms for 6 PTXs. The delay factor should be substantially longer than this so the PTXs aren't "talking over one another" and the PRX is able to receive all, or nearly all, transmissions.

Once again, thanks for the answer. Yes, that is exactly i want to do. but nevertheless i have made a code and it doesnt work. This code is simple and its based in yours. Is there any way you can see the code? Because i dont know any person that can help me and i need that it works. If you cant, there isnt any problem.

Well, im from Buenos Aires, its not so far away.

Thanks, again.

I hope I understand what you're asking.
The example code basically works like this:
PRX: Listens, Gets msg and replies, Back to Listening
PTX: Sends msg, waits for reply, Delays prior to sending next msg

What you want to do:
PRX: Sends msg to PTX0, waits for reply, sends to next PTX ... loop
PTX: Listens, Gets msg and replies, Back to Listening
If that's correct, the your PTX code will be almost the same as the example PRX code -- and you'll have to write new code to make the master act more like a transmitter, sending to each node in turn.
I lived in Acassuso outside of Buenos Aires

Hi, very good! Im from Argentina, and i hope you can understund my English. I have a question about the diagram. I have made a similar code, but it doesnt work. Is the pipe to transmit from the master to the node0 the same that the pipe to transmit from the node0 to the master?

More Comments