After much searching, and much experimenting, I finally found a workaround that seems to be working reliably for me. The solution was to use ‘software’ or ‘bit-banged’ SPI. This allows the Ethernet shield to happily commandeer the hardware SPI pins, while the nrf24l01 (or any other peripheral, I suppose) to operate on a separate, emulated SPI bus.

The credit for this goes to a user on the Arduino forums, nicoverduin, who suggested using some software SPI libraries already available and modifying maniacbug’s nrf24 library to use the software spi interface.

Here is the step by step:

1.) Download the modified maniacbug library and softSPI libraries here.
2.) Copy the libraries to your Arduino libraries folder.
3.) Configure your Arduino/Ethernet-shield/nrf24l01 like this (you can also modify the pin configuration if needed. Instructions are in the readme file on the linked github repository):

Once you have completed the above steps, you can upload your sketch to the Arduino and you should be able to browse to the IP of your Arduino with Ethernet shield and you will see a web page that tells you the last message received over the nrf24l01.

There is one major caveat to all of this, however. I have found that sometimes when I am working with the softSPI version of the nrf24 library and then I switch back to the regular/hardware version (e.g. when I work on the sending device, which in this case has no ethernet shield, after I upload a sketch to the one with the ethernet shield), the hardware-based SPI nrf24l01 breaks. This seems to be happening because the Arduino IDE is holding on to the softSPI version of the rf24 library. I am just speculating on that, but it kind of makes sense since the internal naming is identical between the libraries.

The fix for this problem is simple, if a bit inconvenient. I have been removing my modified version of the rf24 library from the Arduino libraries folder before working with the hardware-SPI version. I am sure there is a smarter way of fixing this, and if someone could point it out to me, I would be glad to post the solution here.

16 thoughts on “How to use an nrf24l01 (rf24) with an Arduino Ethernet Shield”

Quick question: maniacbug has a “sensor-network” on his blog. I am struggling with compiling it on the latest beta version running on Mac OS.
Have you ever tried to use the network-library to implement more than 5 senders?

Hi Shane,
really appreciated this guide. I got my two nrf’s working together with your previous guide on making them communicate, but I can not seem to get them working when I add an ethernet shield (W1500) to the sender. Here is my code http://paste.ubuntu.com/7811292/ can you see anything wrong?

Hi. I am trying to control my house lights in three different ways same time. One by building diy remotecontrol with nrf24l01 sendind different chars to the receiving end ( master arduino) to control light state .

Second way is control lights via internet browser writing very easy html lines in master arduino code. And using get_ function to turn lights on and off and also writing the light state on those hmtl sites.

Third way is just simple lightswitch on the wall like normally. This uses basic digitalRead function.

I am still building remotecontol circuit. First I tried rf433 mhz transmitter but range trough wall was really poor so I have to select this nrf24l01 chip.

Thanks for sharing solution to this problem! Founding this page saves lots of time and head ake. Thanks! I really preciate!

actually i have a problem and i hope that you could help me
i want send a char from labview to arduino ethernet shield then to send it through the nrf24l01 to the other arduino uno to turn led on , i do every thing as u say ,i change the library and i connect in the same way as mention .
it dos not take the two order :S
take the first and stay in .

Hi, i tried your codes for ethernet shield for a long time. But its not work, on the net page just appear “The last message we got was:” . there is no “hello there”. what am i missing?

—transmitter code—-
#include
#include
#include
#include

/*
This sketch sends a string to a corresponding Arduino
with nrf24 attached. It appends a specific value
(2 in this case) to the end to signify the end of the
message.
*/

int msg[1];
RF24 radio(8,9);
const uint64_t pipe = 0xE8E8F0F0E1LL;
void setup(void){
Serial.begin(9600);
radio.begin();
radio.openWritingPipe(pipe);}
void loop(void){
String theMessage = “Hello there!”;
int messageSize = theMessage.length();
for (int i = 0; i < messageSize; i++) {
int charToSend[1];
charToSend[0] = theMessage.charAt(i);
radio.write(charToSend,1);
}
//send the 'terminate string' value…
msg[0] = 2;
radio.write(msg,sizeof(msg));
/*delay sending for a short period of time. radio.powerDown()/radio.powerupp
//with a delay in between have worked well for this purpose(just using delay seems to
//interrupt the transmission start). However, this method could still be improved
as I still get the first character 'cut-off' sometimes. I have a 'checksum' function
on the receiver to verify the message was successfully sent.
*/
radio.powerDown();
delay(1000);
radio.powerUp();
}

/*
This sketch receives strings from sending unit via nrf24
and prints them out via serial. The sketch waits until
it receives a specific value (2 in this case), then it
prints the complete message and clears the message buffer.

The sketch serves the result to a webpage.
*/
int messageLength = 12; //message checksum, Make sure to
// change it if your string is a different length

Thanks for sharing this code was crucial to run a HTTP server that receives requests through my network and transmits them to a receiver robot, so I can manage my robot over the Internet! Thank you, thank you, thank you!!!

Im working on a project on these 2 modules too. And getting into dead end. So pls i need some explanation. Why did you connect those 3 pin 5, 6, 7 of nrf24l01 to analog pin A0, A1, A2? I know that since the ethernet shield use ISCP connection, so we have to move those 3 pins to another place, but which part of the code tell A0, A1, A2?

I haven’t looked at this in a very long time, but I think that it has to do with the defaults for the library. Please see here: https://github.com/shnae/rf24_plus_softSPI
for more info. remember that pins A0-A5 correspond to pins 14-19.