Interfacing NRF24L01+ with Arduino

Hi all:

I got couple of NRF24L01+ – but I cant seem to make it talk to each other after trying different things for two days.
The actual links to the modules are
http://www.ebay.com/itm/231240845376?_trksid=p2059210.m2749.l2649&ssPageName=STRK%3AMEBIDX%3AIT

I initially tried to make an Arduino Nano talk with my Raspberry Pi, but the sender and receiver are not able to talk with each other. To further debug the issues, I decided to print the status of one module every 10 seconds. It seems like the module is not able to hold its addresses.

My connections to the NANO are as follows:
IRQ → Blank
VCC/Gnd → External power supply
MISO → D12
MOSI ->D11
CSN → D8
CE → D7
SCK → D13

For power, I tried multiple things:
A radio shack DC adapter 3V
CR2450 3.3V batteries

I am using DuPont connectors to connect the power supply to the module. Will that make a difference?
I also added 1 and 10 micro farad capacitors across the power supply (Hard to do it across the module as I am using a bread board), but that doesn’t seem to help.

Here is my program and its output. Any help is appreciated. I am so disappointed that I am not able to make these things work when so many people have had success.

Rick

Program:

#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
#include <printf.h>  // Printf is used for debug 

//
// Hardware configuration


// Set up nRF24L01 radio on SPI bus plus pins 7 & 8

RF24 radio(7,8);
bool radioNumber = 0;

byte addresses[][6] = {"1Node","2Node"};              // Radio pipe addresses for the 2 nodes to communicate.

// Role management: Set up role.  This sketch uses the same software for all the nodes
// in this system.  Doing so greatly simplifies testing.  
typedef enum { role_ping_out = 1, role_pong_back } role_e;                 // The various roles supported by this sketch
const char* role_friendly_name[] = { "invalid", "Ping out", "Pong back"};  // The debug-friendly names of those roles
role_e role = role_pong_back;                                              // The role of the current running sketch

byte counter = 1;                                                          // A single byte to keep track of the data being sent back and forth


void setup() {
   Serial.begin(115200);
   Serial.println("Starting..");
   printf_begin();
   radio.begin();
   radio.enableAckPayload();                     // Allow optional ack payloads
  radio.enableDynamicPayloads();                // Ack payloads are dynamic payloads
  
  if(radioNumber){
    radio.openWritingPipe(addresses[1]);        // Both radios listen on the same pipes by default, but opposite addresses
    radio.openReadingPipe(1,addresses[0]);      // Open a reading pipe on address 0, pipe 1
  }else{
    radio.openWritingPipe(addresses[0]);
    radio.openReadingPipe(1,addresses[1]);
  }
  radio.startListening();                       // Start listening  
  
  radio.writeAckPayload(1,&counter,1);          // Pre-load an ack-paylod into the FIFO buffer for pipe 1
  
}

void loop() {
  printf("----------------------------------------------\n");
  radio.printDetails();
  printf("----------------------------------------------\n");
  delay(5000);
}

Output when using the battery:

----------------------------------------------
STATUS = 0x00 RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=0 TX_FULL=0
RX_ADDR_P0-1 a = 0x0000800f00 0x00f8030000
RX_ADDR_P2-5 a = 0x00 0x00 0x00 0x00
TX_ADDR = 0x0300c00360
RX_PW_P0-6 a = 0x00 0x60 0x00 0x60 0x00 0x60
EN_AA = 0x00
EN_RXADDR a = 0x60
RF_CH = 0x00
RF_SETUP a = 0x60
CONFIG = 0x60
DYNPD/FEATURE a = 0x00 0x00
Data Rate = 250KBPS
Model = nRF24L01
CRC Length = Disabled
PA Power = PA_MIN
----------------------------------------------
----------------------------------------------
STATUS = 0x00 RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=0 TX_FULL=0
RX_ADDR_P0-1 a = 0x0000c01f00 0x0000f80100
RX_ADDR_P2-5 a = 0x00 0x00 0x00 0x00
TX_ADDR = 0x0000e00360
RX_PW_P0-6 a = 0x00 0x60 0x00 0x60 0x00 0x60
EN_AA = 0x00
EN_RXADDR a = 0x60
RF_CH = 0x00
RF_SETUP a = 0x60
CONFIG = 0xe0
DYNPD/FEATURE a = 0x00 0x00
Data Rate = 250KBPS
Model = nRF24L01
CRC Length = Disabled
PA Power = PA_MIN
----------------------------------------------
----------------------------------------------
STATUS = 0x00 RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=0 TX_FULL=0
RX_ADDR_P0-1 a = 0x0000800f00 0x0000f80300
RX_ADDR_P2-5 a = 0x00 0x00 0x00 0x00
TX_ADDR = 0x0000e00360
RX_PW_P0-6 a = 0x00 0x60 0x00 0x60 0x00 0x60
EN_AA = 0x00
EN_RXADDR a = 0x60
RF_CH = 0x00
RF_SETUP a = 0x60
CONFIG = 0xe0
DYNPD/FEATURE a = 0x00 0x00
Data Rate = 250KBPS
Model = nRF24L01
CRC Length = Disabled
PA Power = PA_MIN
----------------------------------------------
----------------------------------------------
STATUS = 0x00 RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=0 TX_FULL=0
RX_ADDR_P0-1 a = 0x0000c00f00 0x0000fc0100
RX_ADDR_P2-5 a = 0x00 0x00 0x00 0x00
TX_ADDR = 0x0300c00360
RX_PW_P0-6 a = 0x00 0x60 0x00 0x60 0x00 0x60
EN_AA = 0x00
EN_RXADDR a = 0x60
RF_CH = 0x00
RF_SETUP a = 0x60
CONFIG = 0x60
DYNPD/FEATURE a = 0x00 0x00
Data Rate = 250KBPS
Model = nRF24L01
CRC Length = Disabled
PA Power = PA_MIN
----------------------------------------------
----------------------------------------------
STATUS = 0x00 RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=0 TX_FULL=0
RX_ADDR_P0-1 a = 0x0000c00f00 0x00f8010000
RX_ADDR_P2-5 a = 0x00 0x00 0x00 0x00
TX_ADDR = 0x0000e00360
RX_PW_P0-6 a = 0x00 0x60 0x00 0x60 0x00 0x60
EN_AA = 0x00
EN_RXADDR a = 0x60
RF_CH = 0x00
RF_SETUP a = 0x60
CONFIG = 0x60
DYNPD/FEATURE a = 0x00 0x00
Data Rate = 250KBPS
Model = nRF24L01
CRC Length = Disabled
PA Power = PA_MIN
----------------------------------------------

I am using this RF24 Library: https://github.com/TMRh20/RF24

And here is the output when using a 3V Power Supply

----------------------------------------------
STATUS = 0x00 RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=0 TX_FULL=0
RX_ADDR_P0-1 a = 0xe7e7e7e7e7 0xc2c2c2c2c2
RX_ADDR_P2-5 a = 0xc3 0xc4 0xc5 0xc6
TX_ADDR = 0xe7e7e7e7e7
RX_PW_P0-6 a = 0xff 0x7f 0xff 0x7f 0xff 0x7f
EN_AA = 0xff
EN_RXADDR a = 0x03
RF_CH = 0x02
RF_SETUP a = 0x0f
CONFIG = 0x08
DYNPD/FEATURE a = 0x00 0x00
Data Rate = 2MBPS
Model = nRF24L01
CRC Length = 8 bits
PA Power = PA_MIN
----------------------------------------------
----------------------------------------------
STATUS = 0x00 RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=0 TX_FULL=0
RX_ADDR_P0-1 a = 0xe7e7e7e7e7 0xc2c2c2c2c2
RX_ADDR_P2-5 a = 0xc3 0xc4 0xc5 0xc6
TX_ADDR = 0xe7e7e7e7e7
RX_PW_P0-6 a = 0x00 0x00 0x00 0x00 0x00 0x00
EN_AA = 0x00
EN_RXADDR a = 0x00
RF_CH = 0x02
RF_SETUP a = 0x0f
CONFIG = 0x08
DYNPD/FEATURE a = 0x00 0x00
Data Rate = 2MBPS
Model = nRF24L01
CRC Length = 8 bits
PA Power = PA_MAX
----------------------------------------------
----------------------------------------------
STATUS = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0-1 a = 0x0000000000 0xc2c2c2c2c2
RX_ADDR_P2-5 a = 0xc3 0xc4 0xc5 0xc6
TX_ADDR = 0xe7e7e7e7e7
RX_PW_P0-6 a = 0x00 0x00 0x00 0x00 0x00 0x00
EN_AA = 0x00
EN_RXADDR a = 0x00
RF_CH = 0x00
RF_SETUP a = 0x0f
CONFIG = 0x08
DYNPD/FEATURE a = 0x00 0x00
Data Rate = 2MBPS
Model = nRF24L01
CRC Length = 8 bits
PA Power = PA_MAX
----------------------------------------------
----------------------------------------------
STATUS = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0-1 a = 0x0000000000 0x0000000000
RX_ADDR_P2-5 a = 0xc3 0xc4 0xc5 0xc6
TX_ADDR = 0xe7e7e7e7e7
RX_PW_P0-6 a = 0x00 0x00 0x00 0x00 0x00 0x00
EN_AA = 0x3f
EN_RXADDR a = 0x03
RF_CH = 0x00
RF_SETUP a = 0x00
CONFIG = 0x00
DYNPD/FEATURE a = 0x00 0x00
Data Rate = 2MBPS
Model = nRF24L01
CRC Length = 8 bits
PA Power = PA_MAX
----------------------------------------------
----------------------------------------------
STATUS = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0-1 a = 0xe7e7e7e7e7 0x0000000000
RX_ADDR_P2-5 a = 0x00 0x00 0xc5 0xc6
TX_ADDR = 0xe7e7e7e7e7
RX_PW_P0-6 a = 0x00 0x00 0x00 0x00 0x00 0x00
EN_AA = 0x3f
EN_RXADDR a = 0x03
RF_CH = 0x02
RF_SETUP a = 0x00
CONFIG = 0x00
DYNPD/FEATURE a = 0x00 0x00
Data Rate = 2MBPS
Model = nRF24L01
CRC Length = 8 bits
PA Power = PA_MAX
----------------------------------------------
----------------------------------------------
STATUS = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0-1 a = 0xe7e7e7e7e7 0xc2c2c2c2c2
RX_ADDR_P2-5 a = 0x00 0x00 0x00 0x00
TX_ADDR = 0x0000000000
RX_PW_P0-6 a = 0x00 0x00 0x00 0x00 0x00 0x00
EN_AA = 0x3f
EN_RXADDR a = 0x03
RF_CH = 0x02
RF_SETUP a = 0x0f
CONFIG = 0x08
DYNPD/FEATURE a = 0x00 0x00
Data Rate = 1MBPS
Model = nRF24L01
CRC Length = 8 bits
PA Power = PA_MAX
----------------------------------------------

Any help, guys? Please let me know if you need any more info… Or any tips on troubleshooting this problem is welcome…

The debug output is wrong in every case, so that indicates that there is a problem with basic SPI communication.

The most likely cause of that is incorrect pin assignments, bad connections, etc, so the first step would be to verify all of your connections and pins. CE and CS can be set to any pin on the Arduino by modifying RF24 radio(7,8);

http://nathan.chantrell.net/blog/wp-content/uploads/2013/08/nrf24l01.jpg

http://arduino.cc/en/Reference/SPI

Thank you very much for responding. The pin assignments are definitely correct and the connectivity seems okay to when I tested it. Can you please post why my debug output is wrong? (Which fields?) - Also how will a correct debug output look like? So that I can recognize it when I see it? Thanks again.

Sure, if you have the code loaded onto the Arduinos, power cycle them to reset the radios, then the debug output should look exactly like this:

Radio 0:

STATUS = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0-1  = 0x65646f4e31 0x65646f4e32
RX_ADDR_P2-5  = 0xc3 0xc4 0xc5 0xc6
TX_ADDR = 0x65646f4e31
RX_PW_P0-6  = 0x20 0x20 0x00 0x00 0x00 0x00
EN_AA = 0x3f
EN_RXADDR  = 0x02
RF_CH = 0x4c
RF_SETUP  = 0x07
CONFIG = 0x0f
DYNPD/FEATURE  = 0x3f 0x06
Data Rate = 1MBPS
Model = nRF24L01+
CRC Length = 16 bits
PA Power = PA_MAX
----------------------------------------------

Radio 1:

STATUS = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0-1  = 0x65646f4e32 0x65646f4e31
RX_ADDR_P2-5  = 0xc3 0xc4 0xc5 0xc6
TX_ADDR = 0x65646f4e32
RX_PW_P0-6  = 0x20 0x20 0x00 0x00 0x00 0x00
EN_AA = 0x3f
EN_RXADDR  = 0x02
RF_CH = 0x4c
RF_SETUP  = 0x07
CONFIG = 0x0f
DYNPD/FEATURE  = 0x3f 0x06
Data Rate = 1MBPS
Model = nRF24L01+
CRC Length = 16 bits
PA Power = PA_MAX
----------------------------------------------

One of the easiest parts of the debug output to verify is the addresses (RX_ADDR_P0-1), but the catch is they are printed out via the old address format.

65 64 6f 4e 32 becomes 32 4e 6f 64 65 by reversing all of the hex digits, then convert to ASCII here

The result: 2Node

In order to 'decode' the debug output further, you generaly need to convert the hex values to binary and compare them against the registers listed in the datasheet.

Generally, adding capacitors etc, won't make much of a difference until you attempt to send and receive.

The debug output will usually work, even if the radios are not functioning 100%.

You might want to try the 3.3v output of the Nano, or with batteries up to about 4v.

Thanks. I have made some more progress. Now, I get the debug output exactly as you suggested.

However, I still am not able to send data packets across. I got a new Uno, So now I am trying out communication between Uno and a Nano. I am trying the pingpair_ack example. Code below:

/*
  // March 2014 - TMRh20 - Updated along with High Speed RF24 Library fork
  // Parts derived from examples by J. Coliz <maniacbug@ymail.com>
*/
/**
 * Example for efficient call-response using ack-payloads 
 *
 * This example continues to make use of all the normal functionality of the radios including
 * the auto-ack and auto-retry features, but allows ack-payloads to be written optionlly as well.
 * This allows very fast call-response communication, with the responding radio never having to 
 * switch out of Primary Receiver mode to send back a payload, but having the option to if wanting
 * to initiate communication instead of respond to a commmunication.
 */
 


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

// Hardware configuration: Set up nRF24L01 radio on SPI bus plus pins 7 & 8 
RF24 radio(9,10);

// Topology
const uint64_t pipes[2] = { 0xABCDABCD71LL, 0x544d52687CLL };              // Radio pipe addresses for the 2 nodes to communicate.

// Role management: Set up role.  This sketch uses the same software for all the nodes
// in this system.  Doing so greatly simplifies testing.  

typedef enum { role_ping_out = 1, role_pong_back } role_e;                 // The various roles supported by this sketch
const char* role_friendly_name[] = { "invalid", "Ping out", "Pong back"};  // The debug-friendly names of those roles
role_e role = role_pong_back;                                              // The role of the current running sketch

// A single byte to keep track of the data being sent back and forth
byte counter = 1;

void setup(){

  Serial.begin(57600);
  printf_begin();
  printf("\n\rRF24/examples/GettingStarted/\n\r");
  printf("ROLE: %s\n\r",role_friendly_name[role]);
  printf("*** PRESS 'T' to begin transmitting to the other node\n\r");

  // Setup and configure rf radio

  radio.begin();
  radio.setPALevel(RF24_PA_LOW);
  radio.setAutoAck(1);                    // Ensure autoACK is enabled
  radio.enableAckPayload();               // Allow optional ack payloads
  radio.setRetries(0,15);                 // Smallest time between retries, max no. of retries
  radio.setPayloadSize(1);                // Here we are sending 1-byte payloads to test the call-response speed
  radio.openWritingPipe(pipes[1]);        // Both radios listen on the same pipes by default, and switch when writing
  radio.openReadingPipe(1,pipes[0]);
  radio.startListening();                 // Start listening
  radio.printDetails();                   // Dump the configuration of the rf unit for debugging
}

void loop(void) {

  if (role == role_ping_out){
    
    radio.stopListening();                                  // First, stop listening so we can talk.
        
    printf("Now sending %d as payload. ",counter);
    byte gotByte;  
    unsigned long time = micros();                          // Take the time, and send it.  This will block until complete   
                                                            //Called when STANDBY-I mode is engaged (User is finished sending)
    if (!radio.write( &counter, 1 )){
      printf("failed.\n\r");      
    }else{

      if(!radio.available()){ 
        printf("Blank Payload Received\n\r"); 
      }else{
        while(radio.available() ){
          unsigned long tim = micros();
          radio.read( &gotByte, 1 );
          printf("Got response %d, round-trip delay: %lu microseconds\n\r",gotByte,tim-time);
          counter++;
        }
      }

    }
    // Try again later
    delay(1000);
  }

  // Pong back role.  Receive each packet, dump it out, and send it back

  if ( role == role_pong_back ) {
    byte pipeNo;
    byte gotByte;                                       // Dump the payloads until we've gotten everything
    while( radio.available(&pipeNo)){
      radio.read( &gotByte, 1 );
      printf("Got byte %d\n\r",gotByte);
      radio.writeAckPayload(pipeNo,&gotByte, 1 );    
   }
 }

  // Change roles

  if ( Serial.available() )
  {
    char c = toupper(Serial.read());
    if ( c == 'T' && role == role_pong_back )
    {
      printf("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK\n\r");

      role = role_ping_out;                  // Become the primary transmitter (ping out)
      radio.openWritingPipe(pipes[0]);
      radio.openReadingPipe(1,pipes[1]);
      radio.printDetails();
    }
    else if ( c == 'R' && role == role_ping_out )
    {
      printf("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK\n\r");
      
       role = role_pong_back;                // Become the primary receiver (pong back)
       radio.openWritingPipe(pipes[1]);
       radio.openReadingPipe(1,pipes[0]);
       radio.startListening();
       radio.printDetails();       
    }
  }
}

On the receiver (Nano), I get the following messages:

RF24/examples/GettingStarted/

ROLE: Pong back

*** PRESS 'T' to begin transmitting to the other node

STATUS = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0-1 a = 0x544d52687c 0xabcdabcd71
RX_ADDR_P2-5 a = 0xc3 0xc4 0xc5 0xc6
TX_ADDR = 0x544d52687c
RX_PW_P0-6 a = 0x01 0x01 0x00 0x00 0x00 0x00
EN_AA = 0x3f
EN_RXADDR a = 0x02
RF_CH = 0x4c
RF_SETUP a = 0x03
CONFIG = 0x0f
DYNPD/FEATURE a = 0x03 0x06
Data Rate = 1MBPS
Model = nRF24L01+
CRC Length = 16 bits
PA Power = PA_LOW
Got byte 1

Got byte 1

Got byte 1

On the sender though, it fails:

Arduino Uno

RF24/examples/GettingStarted/

ROLE: Pong back

*** PRESS 'T' to begin transmitting to the other node

STATUS = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0-1 a = 0x544d52687c 0xabcdabcd71
RX_ADDR_P2-5 a = 0xc3 0xc4 0xc5 0xc6
TX_ADDR = 0x544d52687c
RX_PW_P0-6 a = 0x01 0x01 0x00 0x00 0x00 0x00
EN_AA = 0x3f
EN_RXADDR a = 0x02
RF_CH = 0x4c
RF_SETUP a = 0x03
CONFIG = 0x0f
DYNPD/FEATURE a = 0x03 0x06
Data Rate = 1MBPS
Model = nRF24L01+
CRC Length = 16 bits
PA Power = PA_LOW
*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK

STATUS = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0-1 a = 0xabcdabcd71 0x544d52687c
RX_ADDR_P2-5 a = 0xc3 0xc4 0xc5 0xc6
TX_ADDR = 0xabcdabcd71
RX_PW_P0-6 a = 0x01 0x01 0x00 0x00 0x00 0x00
EN_AA = 0x3f
EN_RXADDR a = 0x02
RF_CH = 0x4c
RF_SETUP a = 0x03
CONFIG = 0x0f
DYNPD/FEATURE a = 0x03 0x06
Data Rate = 1MBPS
Model = nRF24L01+
CRC Length = 16 bits
PA Power = PA_LOW
Now sending 1 as payload. failed.

Now sending 1 as payload. failed.

Now sending 1 as payload. failed.

Just to find out if my modules are not defective, I switched the modules. I get the same results from the Nano and Uno as before.

When I try to send from the Nano, the sending fails, but the Uno does not receive anything (Unlike sending from the Uno where the Nano receives the byte, but the sender still shows as failed). Is it because I am not able to send from the Nano, but able to receive data on it?

I tried the 3V3 power supply on the Nano and an external power supply. Sending fails on both counts.

Note: I changed the CE and CSN pins to 9 and 10 respectively on both modules as shown in the code.

Finally, I was able to get this thing to work. It seems like one of the Arduino Uno was not able to receive data, but it is able to send the data. Not sure what the problem could be. Any ideas? When I used a different Uno everything worked fine.

Could this be a connection issue? The defective Uno is a clone DCCduino Uno from here http://www.ebay.com/itm/151467529472?_trksid=p2059210.m2749.l2649&ssPageName=STRK%3AMEBIDX%3AIT

Anything is possible, and that would explain a lot. I've even purchesed poor quality breadboard wires that break when inserted/removed from breadboards, and it can be really frustrating when one or more connections are intermittent etc.

I have now 7-8 modules working with maniacbug's lib.

Had the same problem as you had in the beginning; i think it's a power problem; seems the nrf's need a constant/stable 3V to work fine. I think the clone arduino versions might not be as stable as the regular boards (for power). I don't power my nrf's by the arduino directly; current passes throught a 100uF condensator on the input (+ from power source or arduino) of the 3V regulator , followed by a 3V regulator (the one mentioned earlier) and finally a 10uF condensator on the output (+ to the nrf's vcc) of that same regulator. Works like a charm with UNO and pro mini's (diff brand & clones).

I am sorry if i can't give you more explanation but i have allmost zero electronic skillz ... if you need more help with that condensator and regulator based stuff i am pretty sure someone will be able to give you a decent explanation or scheme to use :D