NRF24L01 and Ethernet Shield

Has any progress been made in this field? I’ve looked at several post of similar problems using both the NRF24L01 and Ethernet shield together and couldn’t find anything that seemed like a consistent solution. I’ve tried a few suggestions, like using pin 53 as the CSN for the radio, and nothing has worked so far. I monitored the CS pins while the program ran and every time the radio was selected, it never released the line, causing the server to become non-responsive. I concluded that it wasn’t receiving an ack and so continuously retried, tying up the line. I switched from the radio.write command to the radio.writeFast command and the server stopped freezing but nothing is transmitted from the radio. I’m using an Arduino Mega 2560, the Wiznet 5100 Ethernet shield, and of course the NRF24L01. I use the same code for both the NRF24L01 and the Ethernet shield in other projects and they work fine, but this is the first time I’ve tried to mesh the networks.

Any ideas?

Code:

#include <nRF24L01.h>
#include <RF24.h>
#include <SPI.h>
#include <Ethernet.h>

#define   ethernet_cs   10
#define   nrf24_ce       6
#define   nrf24_csn      7

RF24 radio(nrf24_ce, nrf24_csn);
EthernetServer server(80); //server port

byte mac[] = { 0xAA, 0xBB, 0xCC, 0xDD, 0xEF, 0x01 }; //physical mac address
byte ip[] = { 192, 168, 1, 13 }; // ip in lan
byte gateway[] = { 192, 168, 1, 1 }; // internet access via router
byte subnet[] = { 255, 255, 255, 0 }; //subnet mask

const int light_off = 0;
const int light_on  = 1;

String readString; 

void setup(){

const byte  addresses[][6]     = {"00001", "00002"};

  radio.begin();
  radio.openWritingPipe(addresses[1]); // 00001
  radio.openReadingPipe(1, addresses[0]); // 00002
  radio.setPALevel(RF24_PA_MIN); // MIN, LOW, HIGH, or MAX
  radio.stopListening();
  radio.enableDynamicAck();

  //start Ethernet
  Ethernet.begin(mac, ip, gateway, gateway, subnet);
  server.begin();

  //enable serial data print 
  Serial.begin(9600); 
}

void loop(){
  // Create a client connection
  EthernetClient client = server.available();
  if (client) {
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();

        //read char by char HTTP request
        if (readString.length() < 100) {

          //store characters to string 
          readString += c; 
        } 

        //if HTTP request has ended
        if (c == '\n') {

          Serial.println(readString); //print to serial monitor for debuging 

          client.println("HTTP/1.1 200 OK"); //send new page
          client.println("Content-Type: text/html");
          client.println();

          client.println("<HTML>");
          client.println("<HEAD>");
          client.println("<TITLE>Command Module Test Page</TITLE>");
          client.println("</HEAD>");
          client.println("<BODY>");

          client.println("<H1>Light Control</H1>");
          
          client.print("<input type=submit value=ON style=width:100px;height:45px onClick=location.href='/?on2'>");
          client.print("<input type=submit value=OFF style=width:100px;height:45px onClick=location.href='/?off3'>");

          client.println("</BODY>");
          client.println("</HTML>");

          delay(1);
          //stopping client
          client.stop();
          
          // control arduino
          if(readString.indexOf('2') >0)//checks for 2
          {
            radio.writeFast(&light_on,sizeof(light_on),0);
            Serial.println("Light ON sent");
          }
          if(readString.indexOf('3') >0)//checks for 3
          {
            radio.writeFast(&light_off,sizeof(light_off),0);
            Serial.println("Light OFF sent");
          }
                    
          //clearing string for next read
          readString="";

        }
      }
    }
  }
}

I put together a test module with an Arduino Nano and another NRF24L01 and use this very simple code (nothing is ever printed to the monitor):

#include <nRF24L01.h>
#include <RF24.h>
#include <SPI.h>

#define   nrf24_ce      19
#define   nrf24_csn      3

RF24 radio(nrf24_ce, nrf24_csn);

int data_packet = 0;

void setup() {
  
const byte  addresses[][6]     = {"00001", "00002"};

  radio.begin();
  radio.openWritingPipe(addresses[0]); // 00001
  radio.openReadingPipe(1, addresses[1]); // 00002
  radio.setPALevel(RF24_PA_MIN); // MIN, LOW, HIGH, or MAX
  radio.startListening();
  radio.enableDynamicAck();

  Serial.begin(9600); 
  Serial.println(data_packet);

}

void loop() {
  
    if (radio.available()){
      radio.read(&data_packet,sizeof(data_packet));
      Serial.println(data_packet);
    }
}

kengel:
I use the same code for both the NRF24L01 and the Ethernet shield in other projects and they work fine, but this is the first time I've tried to mesh the networks.

Your description of the problem is not at all clear. I was nearly at the bottom of your text before I came across this piece.

Have you got the nRF24 and the Ethernet shield working with an identical Arduino? In that case what is the nRF24 talking to and what is the Ethernet shield talking to?

What is the difference between the working and the non-working code? Ideally post the two programs so we can compare them side by side.

...R

I apologize. I use sensors to trigger lights, hence the RF24 network. I want to add remote functionality, so I’m implementing a web server on the Arduino Mega via the Ethernet shield. The server works fine when I’m switching on/off an LED that’s directly connected to it, but fails when I try to implement the RF24 radio network. The radio portion of the code I posted earlier is the exact same as the code I currently use for the sensors. I’ve disconnected everything except the light controller and the server to ensure that there isn’t more than one device trying to talk at once.

To answer your question, this code works:

#include <Ethernet.h>

#define   ethernet_cs   10
#define   led           46

EthernetServer server(80); //server port

byte mac[] = { 0xAA, 0xBB, 0xCC, 0xDD, 0xEF, 0x01 }; //physical mac address
byte ip[] = { 192, 168, 1, 13 }; // ip in lan
byte gateway[] = { 192, 168, 1, 1 }; // internet access via router
byte subnet[] = { 255, 255, 255, 0 }; //subnet mask

const byte  addresses[][6] = {"00001", "00002"};

String readString; 

void setup(){

  //start Ethernet
  Ethernet.begin(mac, ip, gateway, gateway, subnet);
  server.begin();

  //enable serial data print 
  Serial.begin(9600); 
}

void loop(){
  // Create a client connection
  EthernetClient client = server.available();
  if (client) {
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();

        //read char by char HTTP request
        if (readString.length() < 100) {

          //store characters to string 
          readString += c; 
        } 

        //if HTTP request has ended
        if (c == '\n') {

          Serial.println(readString); //print to serial monitor for debuging 

          client.println("HTTP/1.1 200 OK"); //send new page
          client.println("Content-Type: text/html");
          client.println();

          client.println("<HTML>");
          client.println("<HEAD>");
          client.println("<TITLE>Command Module Test Page</TITLE>");
          client.println("</HEAD>");
          client.println("<BODY>");

          client.println("<H1>Light Control</H1>");
          
          client.print("<input type=submit value=ON style=width:100px;height:45px onClick=location.href='/?on2'>");
          client.print("<input type=submit value=OFF style=width:100px;height:45px onClick=location.href='/?off3'>");

          client.println("</BODY>");
          client.println("</HTML>");

          delay(1);
          //stopping client
          client.stop();
          
          // control arduino
          if(readString.indexOf('2') >0)//checks for 2
          {
            digitalWrite(led,HIGH);
            Serial.println("LED ON sent");
          }
          if(readString.indexOf('3') >0)//checks for 3
          {
            digitalWrite(led,LOW);
            Serial.println("LED OFF sent");
          }
                    
          //clearing string for next read
          readString="";

        }
      }
    }
  }
}

This code does not:

#include <nRF24L01.h>
#include <RF24.h>
#include <SPI.h>
#include <Ethernet.h>

#define   ethernet_cs   10
#define   nrf24_ce       6
#define   nrf24_csn      7

RF24 radio(nrf24_ce, nrf24_csn);
EthernetServer server(80); //server port

byte mac[] = { 0xAA, 0xBB, 0xCC, 0xDD, 0xEF, 0x01 }; //physical mac address
byte ip[] = { 192, 168, 1, 13 }; // ip in lan
byte gateway[] = { 192, 168, 1, 1 }; // internet access via router
byte subnet[] = { 255, 255, 255, 0 }; //subnet mask

const int   light_off      = 0;
const int   light_on       = 1;
const byte  addresses[][6] = {"00001", "00002"};

String readString; 

void setup(){

  radio.begin();
  radio.openWritingPipe(addresses[1]); // 00001
  radio.openReadingPipe(1, addresses[0]); // 00002
  radio.setPALevel(RF24_PA_MIN); // MIN, LOW, HIGH, or MAX
  radio.stopListening();
  radio.enableDynamicAck();

  //start Ethernet
  Ethernet.begin(mac, ip, gateway, gateway, subnet);
  server.begin();

  //enable serial data print 
  Serial.begin(9600); 
}

void loop(){
  // Create a client connection
  EthernetClient client = server.available();
  if (client) {
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();

        //read char by char HTTP request
        if (readString.length() < 100) {

          //store characters to string 
          readString += c; 
        } 

        //if HTTP request has ended
        if (c == '\n') {

          Serial.println(readString); //print to serial monitor for debuging 

          client.println("HTTP/1.1 200 OK"); //send new page
          client.println("Content-Type: text/html");
          client.println();

          client.println("<HTML>");
          client.println("<HEAD>");
          client.println("<TITLE>Command Module Test Page</TITLE>");
          client.println("</HEAD>");
          client.println("<BODY>");

          client.println("<H1>Light Control</H1>");
          
          client.print("<input type=submit value=ON style=width:100px;height:45px onClick=location.href='/?on2'>");
          client.print("<input type=submit value=OFF style=width:100px;height:45px onClick=location.href='/?off3'>");

          client.println("</BODY>");
          client.println("</HTML>");

          delay(1);
          //stopping client
          client.stop();
          
          // control arduino
          if(readString.indexOf('2') >0)//checks for 2
          {
            radio.writeFast(&light_on,sizeof(light_on),0);
            Serial.println("Light ON sent");
          }
          if(readString.indexOf('3') >0)//checks for 3
          {
            radio.writeFast(&light_off,sizeof(light_off),0);
            Serial.println("Light OFF sent");
          }
                    
          //clearing string for next read
          readString="";

        }
      }
    }
  }
}

IF the nRF24 and the Ethernet card are in close proximity, try putting a grounded sheet of aluminum foil between them, but not touching them.

Paul

kengel:
To answer your question, this code works:

So you don't actually have a working program with both devices (as you said in your Original Post)

I use the same code for both the NRF24L01 and the Ethernet shield in other projects and they work fine,

Can you list the I/O pins that the Ethernet shield uses? Maybe it also needs one the pins that you have allocated to the nRF24?

...R

I think there was a misunderstanding. :confused: I have programs that use the RF24 that work. I have also made a program that works with the Ethernet shield to remotely turn on/off an LED. I have not; however, successfully made a program that works with both the RF24 and Ethernet shield.

Robin2:
So you don't actually have a working program with both devices (as you said in your Original Post)

The Ethernet shield uses pins 11, 12, and 13 (SPI) and pin 10 for the CS. The RF24 likewise uses pins 11, 12, and 13 for SPI and I currently have the CE pin attached to pin 6 of the Arduino and the CSN pin attached to pin 7 of the Arduino.

Other things I have observed:
The RF24 will not transmit if the usb is attached to the Arduino. This is true for all of my Arduinos and RF24's across all of my projects. (Meaning the Serial Monitor can't be utilized and power must come from a power supply.) This hasn't presented a problem, other than making troubleshooting interesting, however, I wonder if it could be related?

That suggests you are powering the NRF24s from the Arduino board. Don't do that!

Paul

kengel:
Other things I have observed:
The RF24 will not transmit if the usb is attached to the Arduino. This is true for all of my Arduinos and RF24's across all of my projects.

Exactly what Arduinos are you using?

My nRF24s work fine with my genuine Uno and Mega and Leonardo when the USB cable is connected and when the nRF24 is powered from the 3.3v pin.

I have a Mega clone that cannot power the nRF24 from its 3.3v pin - but it works fine if the nRF24 is powered from a separate 3.3v supply or a pair of AA alkaline cells.

Try the connection test program in my Simple nRF24L01+ Tutorial

I wonder if it would be useful to do an SPI.begin() before switching to a different SPI device.

...R

@Paul,

No luck with the grounded foil shield.

I have about 20 Nano clones and one Arduino Mega. I haven’t tried on the Mega, but all of the nano clones seem to not transmit at all when the usb is plugged in. I recently got a new batch from a different supplier. I will have to test one of them.

@Paul I haven’t had any problems powering the radios from the Arduino. I have one with the PA set to HIGH although I did solder a 1uF electrolytic cap across the power and ground pins. That radio resides in a 2"x3" steel box and manages to get enough of a signal out to be heard. Kinda proud of that one…

But now you have added the ethernet shield. Are you powering it from the same 3.3 volt source?

Paul

kengel:
I have about 20 Nano clones

Are you using the Ethernet Shield with a Nano? I thought all shields needed an Uno?

...R

@Robin There is a shield for the Nano that I looked into getting, but this is the one part of my project that isn't constrained for space so I opted for a regular shield and am using it with the Mega. It uses the same pins as the Uno.

@Paul Good point. I'll try putting another supply on the radio.

I've done a bit more testing and it seems that the radios all transmit fine when plugged into usb (all the ones I've tested so far,) but none will receive. I have a program that repeatedly blinks an led when a message is received and the led won't start blinking until I unplug the usb. I did find one Nano that the led would blink very occasionally when plugged in....hmmm. Need to test more of them. This looks like it may turn out to be a hardware issue with these clones, although the problem I'm concerned about is with the Mega. Shouldn't they both (RF24 and Ethernet shield) be able to use the SPI bus?

The NRF24L01 is now on a separate power supply and the Ethernet shield is still being powered from the Arduino. No joy. Still no communication on the RF24 network.

kengel:
I've done a bit more testing and it seems that the radios all transmit fine when plugged into usb (all the ones I've tested so far,) but none will receive.

I think it is time to go back to the basics. Get the first example in my nRF24 tutorial working properly. There is no point trying anything more complicated if that does not work.

...R

All the tutorials work fine. I can control a servo on one from a thumbstick on another while controlling an LED on the second with a button on the first. (2 way communication.) Is anyone familiar with the supposed hardware flaw on the Ethernet adapter? It's mentioned in several posts here and there's a youtube video.

I don't want to start hacking apart my Ethernet shield before knowing if this is legitimate.

I've read the W5100 datasheet and I see nothing that leads me to believe that there should be a problem with the CS/SS circuit, but when I search "NRF24L01" and "Ethernet shield" together it returns several Arduino forum posts raising compatibility concerns. Has anyone else used the Ethernet shield Rev 5 with another SPI device successfully?

Here’s the code I’m using to test the transmission functions of the server (Mega):

#include <nRF24L01.h>
#include <RF24.h>
#include <SPI.h>

#define   nrf24_ce      19
#define   nrf24_csn      3
#define   led           16
#define   rx             0
#define   tx             1
#define   button         2

RF24 radio(nrf24_ce, nrf24_csn);

bool        mode      = 0;
int         new_data  = 0;
int         old_data  = 0;
const int   data0     = 0;
const int   data1     = 1;

void setup() {

const byte  addresses[][6]     = {"00001", "00002"};

  mode = digitalRead(button);

  if (mode == rx){
    radio.begin();
    radio.openWritingPipe(addresses[0]); // 00001
    radio.openReadingPipe(1, addresses[1]); // 00002
    radio.setPALevel(RF24_PA_MIN); // MIN, LOW, HIGH, or MAX
    radio.startListening();
    radio.enableDynamicAck();
  }
  else {
    radio.begin();
    radio.openWritingPipe(addresses[1]); // 00001
    radio.openReadingPipe(1, addresses[0]); // 00002
    radio.setPALevel(RF24_PA_MIN); // MIN, LOW, HIGH, or MAX
    radio.stopListening();
    radio.enableDynamicAck();
  }
}

void loop() {

  if (mode == rx){
    if (radio.available()){
      digitalWrite(led,HIGH);
      radio.read(&new_data,sizeof(new_data));
      if (new_data != old_data){
        old_data = new_data;
      }
    }
    else {
      digitalWrite(led,LOW);
    }
  }
  else {
    delay(250);
    radio.write(&data0,sizeof(data0),0);
    delay(250);
    radio.write(&data1,sizeof(data1),0);
  }
}

This code is loaded onto a Nano with an NRF24L01. The device was tested with another device that I knew to work, and it functioned as expected. (LED blinks when it detects a signal.) However; this device doesn’t detect any signals from the server. Can anyone recommend any troubleshooting tips?

kengel:
Here's the code I'm using to test the transmission functions of the server (Mega):

Maybe it's my slow brain but I am finding it impossible to get an overall picture of what you are doing.

You have posted a Nano program (as I understand it) that only has code for an nRF24. You say elsewhere that you have nRF24 transmission working perfectly. Please confirm that when it works it is using the EXACT SAME nano code as in Reply #16

Assuming it is working there is not a lot to be gained by posting working code and not posting the corresponding program that is not working. Wireless programs only make sense when we can see both parts of the pair.

It would also be a big help if you post a sample of the output of both the Mega and the Nano so that we can get a sense of the working (or not) interaction.

...R

I’m not sure where I lost you, so I’ll start at the beginning. It’s very simple. I currently have a working NRF24 network: a simple sensor(tx) and light controller(rx). I walk in the room and the light turns on, I walk out and the light turns off.

I would like to add the ability to turn the light on/off remotely, so I got an Ethernet shield. I can’t connect the Ethernet shield directly to the light controller because of space limitations, so my other option is to create a module that has both Ethernet access and access to the NRF24 network. The module would receive commands from the website via the Ethernet shield and relay them to the light controller via the NRF24 network.

First, I created a website that I could click buttons and turn on/off an LED, which works flawlessly. I thought I should be able to swap out the led code for radio code, but it’s not working so well. Any positive number received by the light controller on the NRF24 network should turn on the light and any negative number or zero should turn the light off. Since the light neither turns off nor on by action of the Ethernet/NRF24 module, I assume its radio is not transmitting at all.

Due to the location of the light controller, accessing it to experiment or change its code is all but impossible, so I created another module to help me test. The code for this module is LITERALLY cut and paste from the light controller’s code (IE identical). This is the code presented in post #16. This module also will not communicate with the Ethernet/NRF24 module; however it will communicate with both the light controller and its sensor. I am confident that if we can get this module to successfully communicate with the Ethernet/NRF24 module my problem will be fixed.

Please let me know if any of this is unclear.

P.S. Sample of the output?

#define rx 0
#define tx 1

No wonder that you can’t use both together.
Pin 0,1 are already used by the USB<>Serial chip, so avoid.

Use SoftwareSerial on two different pins for the nRF24.
Leo…