Not able to get NRF24L01 wireless transceiver modules to communicate

Hello, I am having trouble getting two NRF24L01 wireless transceiver modules to communicate using the code I have written. I am using the RF24 library for the transceivers, and I am able to run the "Getting Started" example code included in the library with no issues.

I have tried various configurations of the code, using different power settings, channels, and pipe settings. I also have a 10 uF capacitor across VCC and GND of the tranceivers as reccomended by this website (hyperlinked).

Perhaps an experienced user of the NRF24L01 wireless transceiver can critique my code. I am using a Nano to transmit data from a moisture sensor ten times once a minute, and then sleeping the MCU using the "LowPower" library. I am having no problems sending out the data , according to the Serial Monitor. I am using an Uno to receive the data from the Nano. Please note the has incomplete code within it, since the project is not yet complete. Here is the code:

Nano (Transmitter):

/*---------------LIBRARIES---------------*/
#include "LowPower.h"          //For sleep cycle
#include <SPI.h>               //For RF comms
#include "nRF24L01.h"          //For RF comms
#include "RF24.h"              //For RF comms
#include "printf.h"            //For RF comms

/*---------------PIN SETUP---------------*/
const int MoistureAnalog = A0;
const int MoisturePower = 2;
RF24 RFComms (9, 10);
/*------------VARIABLES & OBJECTS------------*/
int MoistureValue;
byte SleepCycle = 0;
byte RFCommsCycle = 0;
const uint64_t pipe = 0xE6E6E6E6E6E6;

/*------------------SETUP------------------*/
void setup() {
  //RF Comms Initialization
  RFComms.begin(); 
  RFComms.setChannel(69);
  RFComms.setPALevel(RF24_PA_LOW);
  RFComms.openWritingPipe(pipe);
  RFComms.stopListening();
  //Moisture Sensor
  pinMode(MoisturePower, OUTPUT);
  digitalWrite(MoisturePower, LOW);
  //Serial for testing
  Serial.begin(115200);
}

/*------------------MAIN BODY------------------*/
void loop() {

  while (SleepCycle < 5) {
    SleepCycle++;
    LowPower.powerDown(SLEEP_1S, ADC_OFF, BOD_OFF);
  }
  while (SleepCycle >= 5) {
    Serial.println("Turning on Sensor...");
    digitalWrite(MoisturePower, HIGH);
    delay(250);
    Serial.println("Reading Moisture...");
    MoistureValue = analogRead(MoistureAnalog);
    Serial.println(MoistureValue, DEC);
    delay(250);
    while (RFCommsCycle < 10) {
      RFCommsCycle++;
      Serial.println("BROADCASTING DATA");
      RFComms.write( &MoistureValue, sizeof(MoistureValue) );
      delay(500);
    }
    while (RFCommsCycle >= 10) {
      RFCommsCycle = 0;
      SleepCycle = 0;
    }
  }
}

Uno (Receiver):

/*---------------LIBRARIES---------------*/
#include <Wire.h>              //For LCD, RTC
#include <LiquidCrystal_I2C.h> //For LCD
#include <NewPing.h>           //For Ultrasonic Sensor
#include "RTClib.h"            //For RTC
#include <SPI.h>               //For RF comms
#include "nRF24L01.h"          //For RF comms
#include "RF24.h"              //For RF comms
#include "printf.h"            //For RF comms

/*---------------PIN SETUP---------------*/
const int Relay = 2;
NewPing WaterLevel(3, 4, 80); //Water level ultrasonic sensor: 3 trig pin, 4 echo pin, 200 max distance in cm
const int Beeper = 5;
LiquidCrystal_I2C lcd(0x27, 20, 4); //LCD Display: A4 - SDA, A5 - SCL
RTC_DS3231 rtc; //RTC on corresponding SDA and SCL pins
RF24 RFComms (9, 10);

/*------------VARIABLES & OBJECTS------------*/
//Water Level Sensor
#define PingSpeed 35 //Frequency to ping the ultrasonic sensor (ms)
unsigned long PingWaterLevel; 
int WaterLevelDistance;
//Moisture Sensor
int MoistureValue;
const  char  *MoistureString[]  =
{
  "   Soil: Very Dry",
  "     Soil: Dry",
  "    Soil: Moist",
  "  Soil: Very Moist",
};
//RTC
unsigned long LCDPrintTime;
unsigned long currentLCDPrintTime;
//RF Comms
const uint64_t pipe = 0xE6E6E6E6E6E6;
/*------------------SETUP------------------*/
void setup() {

  Serial.begin(115200);
  
  //Pin Initialization
  pinMode(Relay, OUTPUT);
  pinMode(Beeper, OUTPUT);

   //RTC Initialization
  rtc.begin();
  rtc.adjust(DateTime(__DATE__,  __TIME__));
  currentLCDPrintTime = millis();

  //RF Comms Initialization
  RFComms.begin(); 
  RFComms.setChannel(69);
  RFComms.setPALevel(RF24_PA_LOW);
  RFComms.openReadingPipe(0, pipe);
  RFComms.startListening();
  RFComms.enableDynamicPayloads();

  
  //LCD Initialization
  lcd.init();
  lcd.backlight();
  lcd.setCursor ( 0, 0 );
  lcd.print("   BEAR Automation  ");
  lcd.setCursor ( 0, 1 );
  lcd.print("     AGWS v 1.0     ");
  lcd.setCursor ( 0, 2 );
  lcd.print("                    ");
  lcd.setCursor ( 0, 3 );
  lcd.print("   Initializing...  ");
  
  delay(4000);

  lcd.setCursor ( 0, 0 );
  lcd.print("                    ");
  lcd.setCursor ( 0, 1 );
  lcd.print("                    ");
  lcd.setCursor ( 0, 2 );
  lcd.print("                    ");
  lcd.setCursor ( 0, 3 );
  lcd.print("                    ");
}
/*------------------MAIN BODY------------------*/
void loop() {
  
  //LCD Display
  DateTime now = rtc.now();
  
  currentLCDPrintTime = millis();
  if ((millis() - LCDPrintTime) > 1000){
    //Time of day
    lcd.setCursor ( 0, 0 );
    lcd.print("                    ");
    lcd.setCursor ( 0, 0 );
    lcd.print("      ");
    char dateBuffer[12];
    sprintf(dateBuffer,"%02u:%02u:%02u ",now.hour(),now.minute(),now.second());
    lcd.print(dateBuffer);
    //Moisture level
    lcd.setCursor ( 0, 1 );
    lcd.print("                    ");
    lcd.setCursor ( 0, 1 );
    lcd.print(MoistureValue);
    LCDPrintTime = currentLCDPrintTime;
  }
  //RF Comms (Listening)
  if ( RFComms.available()) {
    while (RFComms.available())
    {
      Serial.println("Reading data...");
      RFComms.read( &MoistureValue, sizeof(MoistureValue) );
      Serial.println(MoistureValue);
    }
  }
}

Have a look at this Simple nRF24L01+ Tutorial.

The examples do work and I have tried to keep everything as obvious as possible.

...R

It would be a good idea to get rid of everything except the RF communications and try again. Also, what do the serial messages say?

It would be a good idea to get rid of all delay() calls.

That kind of "programming" is not suited for communications.

I collected a pair of new NRF24L01 devices. I ran the following simple codes taken from IDE examples. My modules work once a while. You may try these simple codes just to see that the modules are healthy. My setup was: UNO to UNO. If your modules keep sending/receiving the Hello World message at 1-sec interval, let us know the exact setup you have made (jumper length between UNO and NRF and etc.)

A: Transmitter Codes

/*
* Arduino Wireless Communication Tutorial
*     Example 1 - Transmitter Code
*                
* by Dejan Nedelkovski, www.HowToMechatronics.com
* 
* Library: TMRh20/RF24, https://github.com/tmrh20/RF24/
*/
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(7, 8); // CE, CSN
const byte address[6] = {"00001"};
void setup() 
{
  //pinMode(13, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  
  Serial.begin(9600);
  radio.begin();
  radio.openWritingPipe(address);
  radio.setPALevel(RF24_PA_MIN);
  radio.stopListening();
}
void loop() 
{
  Serial.println("Sending Hello");
  //digitalWrite(13, !digitalRead(3));
  const char text[] = "Hello World";;
  radio.write(&text, sizeof(text));
  delay(1000);
  //while(1);
}

B: Receiver codes

/*
  Arduino Wireless Communication Tutorial
        Example 1 - Receiver Code

  by Dejan Nedelkovski, www.HowToMechatronics.com

  Library: TMRh20/RF24, https://github.com/tmrh20/RF24/
*/
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(7, 8); // CE, CSN
const byte address[6] = {"00001"};
void setup()
{
  Serial.begin(9600);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  //pinMode(13, OUTPUT);
  radio.begin();
  radio.openReadingPipe(0, address);
  radio.setPALevel(RF24_PA_MIN);
  radio.startListening();
}

void loop()
{
  Serial.println("Waiting to Receive Hello");
  //digitalWrite(13, !digitalRead(3));
  delay(1000);
  if (radio.available())
  {
    char text[32] = "";
    radio.read(&text, sizeof(text));
    Serial.println(text);
   // while(1);
  }
}

GolamMostafa:
I collected a pair of new NRF24L01 devices. I ran the following simple codes taken from IDE examples. My modules work once a while. You may try these simple codes just to see that the modules are healthy. My setup was: UNO to UNO. If your modules keep sending/receiving the Hello World message at 1-sec interval, let us know the exact setup you have made (jumper length between UNO and NRF and etc.)

The modules are sitting atop my workbench about 18 inches apart. I have successfully run more complicated code, for example, the "Getting Started" sketch of the RF24 library. I was not able to get communications with the "Hello World" sketch.

/*
* Getting Started example sketch for nRF24L01+ radios
* This is a very basic example of how to send data from one node to another
* Updated: Dec 2014 by TMRh20
*/

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

/****************** User Config ***************************/
/***      Set this radio as radio number 0 or 1         ***/
bool radioNumber = 0;

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

byte addresses[][6] = {"1Node","2Node"};

// Used to control whether this node is sending or receiving
bool role = 0;

void setup() {
 Serial.begin(115200);
 Serial.println(F("RF24/examples/GettingStarted"));
 Serial.println(F("*** PRESS 'T' to begin transmitting to the other node"));
 
 radio.begin();

 // Set the PA Level low to prevent power supply related issues since this is a
// getting_started sketch, and the likelihood of close proximity of the devices. RF24_PA_MAX is default.
 radio.setPALevel(RF24_PA_LOW);
 
 // Open a writing and reading pipe on each radio, with opposite addresses
 if(radioNumber){
   radio.openWritingPipe(addresses[1]);
   radio.openReadingPipe(1,addresses[0]);
 }else{
   radio.openWritingPipe(addresses[0]);
   radio.openReadingPipe(1,addresses[1]);
 }
 
 // Start the radio listening for data
 radio.startListening();
}

void loop() {
 
 
/****************** Ping Out Role ***************************/  
if (role == 1)  {
   
   radio.stopListening();                                    // First, stop listening so we can talk.
   
   
   Serial.println(F("Now sending"));

   unsigned long start_time = micros();                             // Take the time, and send it.  This will block until complete
    if (!radio.write( &start_time, sizeof(unsigned long) )){
      Serial.println(F("failed"));
    }
       
   radio.startListening();                                    // Now, continue listening
   
   unsigned long started_waiting_at = micros();               // Set up a timeout period, get the current microseconds
   boolean timeout = false;                                   // Set up a variable to indicate if a response was received or not
   
   while ( ! radio.available() ){                             // While nothing is received
     if (micros() - started_waiting_at > 200000 ){            // If waited longer than 200ms, indicate timeout and exit while loop
         timeout = true;
         break;
     }      
   }
       
   if ( timeout ){                                             // Describe the results
       Serial.println(F("Failed, response timed out."));
   }else{
       unsigned long got_time;                                 // Grab the response, compare, and send to debugging spew
       radio.read( &got_time, sizeof(unsigned long) );
       unsigned long end_time = micros();
       
       // Spew it
       Serial.print(F("Sent "));
       Serial.print(start_time);
       Serial.print(F(", Got response "));
       Serial.print(got_time);
       Serial.print(F(", Round-trip delay "));
       Serial.print(end_time-start_time);
       Serial.println(F(" microseconds"));
   }

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



/****************** Pong Back Role ***************************/

 if ( role == 0 )
 {
   unsigned long got_time;
   
   if( radio.available()){
                                                                   // Variable for the received timestamp
     while (radio.available()) {                                   // While there is data ready
       radio.read( &got_time, sizeof(unsigned long) );             // Get the payload
     }
    
     radio.stopListening();                                        // First, stop listening so we can talk   
     radio.write( &got_time, sizeof(unsigned long) );              // Send the final one back.      
     radio.startListening();                                       // Now, resume listening so we catch the next packets.     
     Serial.print(F("Sent response "));
     Serial.println(got_time);  
  }
}




/****************** Change Roles via Serial Commands ***************************/

 if ( Serial.available() )
 {
   char c = toupper(Serial.read());
   if ( c == 'T' && role == 0 ){      
     Serial.println(F("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK"));
     role = 1;                  // Become the primary transmitter (ping out)
   
  }else
   if ( c == 'R' && role == 1 ){
     Serial.println(F("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK"));      
      role = 0;                // Become the primary receiver (pong back)
      radio.startListening();
      
   }
 }


} // Loop

In the meantime, I will look at the other suggestions and examples posted. Thank you for the replies. As for my code, the Serial Monitor shows that the Nano-side of the code is transmitting correctly, however there is no response on the receiving Uno-side.

After a Sunday spent troubleshooting, I think I'm going to chalk this up to power-supply related issues. I've loaded in pingpair_sleepy.ino, and can get a response inconsistently as I move the modules around my desk. As mentioned before, the only modification I have added are 10 uF capacitors across V+ and GND. I will likely invest in base modules for the modules as suggested by the wikispaces page that has been so helpful.

GolamMostafa:
I collected a pair of new NRF24L01 devices. I ran the following simple codes taken from IDE examples. My modules work once a while.

With the example code in my tutorial my modules work all the time every time

...R

Hi,
Welcome to the forum.

Can you please post a copy of your circuits, in CAD or a picture of a hand drawn circuit in jpg, png?

How have you got the NRF modules powered?

Thanks.. Tom... :slight_smile:

Robin2:
With the example code in my tutorial my modules work all the time every time

...R

Just out of curiosity, are you using the base modules that claim to solve power supply related issues, or an external power supply? I just ordered the base modules after inconsistent performance with the RF24 library example code. Only in very specific positions would the modules communicate. My setup was Arduino Uno 3.3 V to V+, and an Arduino Nano 3.3 V to V+. The V+ and GND of the transceiver modules also have 10 uF capacitors across them, as well/

I don't have any of the base modules.

Some of my nRF24s (and associated Atmega MCUs) work from a pair of AA alkaline cells (3v). And some of the work from a 1S LiPo with a diode between the battery and the nRF24 to reduce the voltage.

I have used others that worked fine just powered from the 3.3v pin of a genuine Uno or Mega. I also have a Mega clone whose 3.3v pin will not power the nRF24 and in that case I draw the 3.3v power from the 5v pin with an LD1117 / LD33 voltage regulator.

I recommend attaching a 10µF capacitor across Vcc and GND for the nRF24, although my Uno works fine without it.

All of these comments are about the low-power nRF24 with the PCB antenna. I have not needed the high-power version with the external antenna and I believe they require more current than the Arduino 3.3v pin can provide.

...R

Robin2:
All of these comments are about the low-power nRF24 with the PCB antenna. I have not needed the high-power version with the external antenna and I believe they require more current than the Arduino 3.3v pin can provide.

That would make so much sense. I think I have the high-powered version with the external antenna. Thank you. I'll bet when I receive those base modules they'll have no problems.