Simple nRF24L01+ 2.4GHz transceiver demo

After a solid couple of days working with this, I'm still not receiving any information. I see the Tx light blinking once a second on the transmitter, but nothing happens at the Rx end. I've added a bit of code just so it says, "nope" when it doesn't have any new data, and the result is a solid string of "nope"s.

I know that these modules can't take more than 3.3v, but mine came without numbered pins and I plugged them in backward, misreading which side of the board the diagram was representing. Could the 5v signal have blown the radio board? How could I confirm that?

I'm using a Nano for both Tx and Rx. Could I maybe have them plugged into the wrong pins? I've corrected my pin order so many times that I have no faith in the order they're in now. Nonetheless, I've listed the order I'm currently using in the comment at the top of the code, just so I have a reference to work from as I go.

Tx code

/*
Transmitter for nRF24L01

nRF24L01 pin    Nano pin    Color (arbitrary)
CE   03         9(any)      orange
CS/N 04         10(any)     yellow
SCK  05         13          green
MOSI 06         11          blue
MISO 07         12          purple
IRQ  08         (none)      grey

Nano pins, in order   color
9                     orange
10                    yellow
11                    blue
12                    purple
13                    green

*/

// SimpleTx - the master or the transmitter

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


#define CE_PIN   9
#define CSN_PIN 10

const byte slaveAddress[5] = {'R','x','A','A','A'};


RF24 radio(CE_PIN, CSN_PIN); // Create a Radio

char dataToSend[10] = "Message 0";
char txNum = '0';


unsigned long currentMillis;
unsigned long prevMillis;
unsigned long txIntervalMillis = 1000; // send once per second


void setup() {

    Serial.begin(9600);
    
    digitalWrite(10, HIGH); //sets it to master mode?

    Serial.println("SimpleTx Starting");

    radio.begin();
    radio.setDataRate( RF24_250KBPS );
    radio.setRetries(3,5); // delay, count
    radio.openWritingPipe(slaveAddress);
}

//====================

void loop() {
    currentMillis = millis();
    if (currentMillis - prevMillis >= txIntervalMillis) {
        send();
        prevMillis = millis();
    }
}

//====================

void send() {

    bool rslt;
    rslt = radio.write( &dataToSend, sizeof(dataToSend) );
        // Always use sizeof() as it gives the size as the number of bytes.
        // For example if dataToSend was an int sizeof() would correctly return 2

    Serial.print("Data Sent ");
    Serial.print(dataToSend);
    if (rslt) {
        Serial.println("  Acknowledge received");
        updateMessage();
    }
    else {
        Serial.println("  Tx failed");
    }
}

//================

void updateMessage() {
        // so you can see that new data is being sent
    txNum += 1;
    if (txNum > '9') {
        txNum = '0';
    }
    dataToSend[8] = txNum;
}

Rx Code

/*
Receiver for nRF24L01

nRF24L01 pin    Nano pin    Color (arbitrary)
CE   03         9           orange
CS/N 04         10          yellow
SCK  05         13          green
MOSI 06         11          blue
MISO 07         12          purple
IRQ  08         (none)      grey

Nano pins, in order   Color
9                     orange
10                    yellow
11                    blue
12                    purple
13                    green

*/

// SimpleRx - the slave or the receiver

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

#define CE_PIN   9
#define CSN_PIN 10

const byte thisSlaveAddress[5] = {'R','x','A','A','A'};

RF24 radio(CE_PIN, CSN_PIN);

char dataReceived[10]; // this must match dataToSend in the TX
bool newData = false;

//===========

void setup() {
    digitalWrite(10, HIGH); //Sets to Master mode? I don't understand how it can only work in Master mode.
    Serial.begin(9600);

    Serial.println("SimpleRx Starting");
    radio.begin();
    radio.setDataRate( RF24_250KBPS );
    radio.openReadingPipe(1, thisSlaveAddress);
    radio.startListening();
}

//=============

void loop() {
    getData();
    showData();
}

//==============

void getData() {
    if ( radio.available() ) {
        radio.read( &dataReceived, sizeof(dataReceived) );
        newData = true;
    }else{
      Serial.println("nope");
    }
}

void showData() {
    if (newData == true) {
        Serial.print("Data received ");
        Serial.println(dataReceived);
        newData = false;
    }
}

This is like a steering wheel stuck on a pirate's crotch.

Hi Robin2

Thank's a lot for your clear explanation, and your example about simple one way transmission using NFR24L01

I Tried it with my NRF24l01 + PA + LNA
and that's work fine, i just modified a little configuration, adapt it to the hardware connection

I tried another type of simple one way transmission using push button to controll the transmiter

the main idea of the projcet is the transmitter will send "Hello World" message if we push the button on, if we do not push the button, nothing wil transmit

I use pin 7 as vcc for the push button so i set the pin become High

here is the code of Transmitter (using Arduino Mega 2560)

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(9, 53); // CE, CSN
const byte address[][6] = {"00001","00002"};
const int pinout = 7;
const int pinin = 4; //input from button to arduino

void setup() {
  Serial.begin(115200); 
  radio.begin();
  radio.openWritingPipe(address[1]);
  radio.setPALevel(RF24_PA_MIN); // it doesn't matter what power level we use (MIN, LOW, HIGH, MAX)it still works for my trial
  radio.stopListening();
  
  pinMode(pinin, INPUT);
  pinMode(pinout, OUTPUT);
}
void loop() {
  digitalWrite(pinout, HIGH);
  
  int tombol = digitalRead(pinin);
  
  if(tombol != LOW){
  txin();}
  else{
  Serial.println("Press the button to send data");
  delay(1000);}
}
void txin(){
  bool txan;
  const char data[] = "Hello World";
  txan = radio.write(&data, sizeof(data));
  delay(1000);
  if(txan)
    Serial.println("Data Sent");
  else
    Serial.println("Failed");
}

and this is the Receiver

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

RF24 radio(9, 10); // CNS, CE
const byte address[][6] = {"00001","00002"};
void setup() {
  Serial.begin(115200);
  radio.begin();
  radio.openReadingPipe(0, address[1]);
  radio.setPALevel(RF24_PA_MIN);
  radio.startListening();
  
}
void loop() {
  if (radio.available()) {
    char text[90] = "";
    radio.read(&text, sizeof(text));
    Serial.println(text);
  }

and it works Properly

my question is, i try to make two way transmission which the data is variable
but i try to make simple trial

the main ide is, when i push the button on arduino(1), the first arduino will stop listening and transmit the data (hello world for example) and if we push the button in arduino (2), the second arduino will stop listening and transmit the data

and i try this code for The Arduino(1) (using Arduino uno R3)

include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(9, 10); //CE,CSN
const byte address[][6] = {"00001","00002"};
const int pinout = 7;
const int pinin = 4;

void setup() 
{
  // put your setup code here, to run once:
 pinMode(pinin, INPUT);
 pinMode(pinout, OUTPUT);
 
 Serial.begin(115200); 
 radio.begin();
 radio.openWritingPipe(address[0]);
 radio.openReadingPipe(0,address[1]);
 radio.setPALevel(RF24_PA_MAX);
 radio.setDataRate(RF24_250KBPS);
 radio.startListening();
 
}

void loop() 
{
  // put your main code here, to run repeatedly:
  digitalWrite(pinout, HIGH);
  int button = digitalRead(pinin);

  if(button != LOW)
  {
    radio.stopListening();
    abc();
  }
  else
  {
    radio.startListening();
    Serial.println("Receiving Mode, Press button to send");
    delay(1000);
  }

  if( radio.available() && button == LOW )
  {
    while (radio.available()) 
    {
    char text[] = "";
    radio.read(&text, sizeof(text));
    Serial.println(text); 
    }
  }
}

void abc()
{
  bool txan;
  const char data[] = "Hello World1 ";
  txan = radio.write(&data, sizeof(data));
  delay(1000);
  if(txan)
    Serial.println("Data Sent");
  else
    Serial.println("Failed");
}

and this is the code for Arduino(2) (Using Arduino Mega 2560)

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(9, 53); //CE,CSN
const byte address[][6] = {"00001","00002"};
const int pinout = 7;
const int pinin = 4;

void setup() 
{
  // put your setup code here, to run once:
 pinMode(pinin, INPUT);
 pinMode(pinout, OUTPUT);
 
 Serial.begin(115200); 
 radio.begin();
 radio.openWritingPipe(address[1]);
 radio.openReadingPipe(0,address[0]);
 radio.setPALevel(RF24_PA_LOW);
 radio.setDataRate(RF24_250KBPS);
 radio.setRetries(15, 15);
 radio.startListening();
}

void loop() 
{
  // put your main code here, to run repeatedly:
  digitalWrite(pinout, HIGH);
  int button = digitalRead(pinin);

  if(button != LOW)
  {
    radio.stopListening();
    abc();
  }
  else
  {
    radio.startListening();
    Serial.println("Receiving Mode, Press button to send");
    delay(1000);
  }

  if((radio.available()) && (button == LOW))
  {
   while (radio.available()) 
    {
    char text[50] = "";
    radio.read(&text, sizeof(text));
    Serial.println(text); }
  }
}

void abc()
{
  bool txan;
  const char data[] = "Hello World 2";
  txan = radio.write(&data, sizeof(data));
  delay(1000);
  if(txan)
    Serial.println("Sent");
  else
    Serial.println("Failed");
}

done uploading but when i try the transmission, it always failed

I hope you can know and explain what is my mistake

thank's a Lot

"...it always failed" is not very helpful. What do your Serial.println(...) statements tell you?

Why oh why do you use delay(...) ?

the Serial println show that the transmission is failed, it can't send the data "Hello World" to the Receiver
so in the serial monitor the message shown is

failed
failed
failed

i use delay to make it send once after 1000ms

but for the details i think it is not failed at all but, i make a mistake about how to get notification when the data sent or failed, when i try the conde again this is what happen

when i used the first code, Mega as a transmitter and when i pressed the button, this happened

and when i looked out to the uno as the receiver, it happened

so i think that's work, for send simplex mode

but this happen when i press the button on my Mega and see the serial monitor

i notice, it means that the transmission is fail

now i try to make difference for the code so we can notice if the data sent from Mega or uno

in the Mega Code, i change the string from "Hello World " to "Hello world from Mega", so when we see in the uno Serial monitor as receiver, we can know that the data is coming from arduino mega, i do it for my uno too

when i press the button on my Mega(it means that my mega is tx), i see this in the serial monitor of my Uno (it means that my uno is Rx)

and when i press the button on my uno (uno as Tx), i see this in the serial monitor of my Mega (Mega as Rx)

i just modify my code, and now it is work
when i press the button, it will send the data, and if we do not push the button, it will stay listening

here is the code for Uno with input from button is in pin 4 and pin 7 is Vcc for the button

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(9, 10); //CE,CSN
const byte address[][6] = {"00001","00002"};
const int pinout = 7;
const int pinin = 4;

void setup() 
{
  // put your setup code here, to run once:
 pinMode(pinin, INPUT);
 pinMode(pinout, OUTPUT);
 
 Serial.begin(115200);
 Serial.println("Receiving Mode, Press button to send data");
 radio.begin();
 radio.openWritingPipe(address[0]);
 radio.openReadingPipe(1,address[1]);
 radio.setPALevel(RF24_PA_HIGH);
 radio.setDataRate(RF24_250KBPS);
 radio.setRetries(15, 15);
 radio.startListening();
 
}

void loop() 
{
  // put your main code here, to run repeatedly:
  digitalWrite(pinout, HIGH);
  int tombol = digitalRead(pinin);

  if(tombol != LOW)
  {
    radio.stopListening();
    abc();
  }
  else
  {
    radio.startListening();
  }

  if( radio.available() && tombol == LOW)
  {
    while (radio.available()) 
    {
    char text[50] = "";
    radio.read(&text, sizeof(text));
    Serial.println(text); 
    }
  }
}

void abc()
{
  bool txan;
  const char data[] = "Hello World from uno ";
  txan = radio.write(&data, sizeof(data));
  delay(1000);
  if(txan)
    Serial.println("Data Sent");
  else
    Serial.println("Failed");

here is the code for Mega with input from button is in pin 4 and pin 7 is Vcc for the button

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(9, 53); //CE,CSN
const byte address[][6] = {"00001","00002"};
const int pinout = 7;
const int pinin = 4;

void setup() 
{
  // put your setup code here, to run once:
 pinMode(pinin, INPUT);
 pinMode(pinout, OUTPUT);
 
 Serial.begin(115200); 
 Serial.println("Receiving Mode, Press button to send");
 radio.begin();
 radio.openWritingPipe(address[1]);
 radio.openReadingPipe(1,address[0]);
 radio.setPALevel(RF24_PA_HIGH);
 radio.setDataRate(RF24_250KBPS);
 radio.setRetries(15, 15);
 radio.startListening();
}

void loop() 
{
  // put your main code here, to run repeatedly:
  digitalWrite(pinout, HIGH);
  int tombol = digitalRead(pinin);

  if(tombol != LOW)
  {
    radio.stopListening();
    abc();
  }
  else
  {
    radio.startListening();
  }

  if(radio.available() && tombol == LOW)
  {
     while (radio.available()) 
    {
    char text[50] = "";
    radio.read(&text, sizeof(text));
    Serial.println(text); 
    }
  }
}

void abc()
{
  bool txan;
  const char data[] = "Hello World from mega ";
  txan = radio.write(&data, sizeof(data));
  delay(1000);
  if(txan)
    Serial.println("Sent");
  else
    Serial.println("Failed");
}

Sorry. I have not been monitoring this Thread - I had assumed it is locked. And I will now ask the Moderator to lock it.

If anyone reading this has a question please start your own Thread in the Networking section and I will see it.

...R

There have been several Threads in which people have reported problems with the SimpleRX program repeatedly printing Data Received very quickly even though it is obvious that data is not being received. When the communication is working properly messages should only be printed once per second.

As far as I can see the problem is caused by a poor connection between the Arduino and the nRF24 module. I can reproduce the symptom by disconnecting the CSN_PIN connection.

The following program may help to diagnose this sort of problem as it just tests the connection between the Arduino and its nRF24 without attempting to send or receive any data to / from another nRF24.

I hope the messages in the program are self-explanatory

CheckConnection.ino

// 18 Mar 2018 - simple program to verify connection between Arduino
//      and nRF24L01+
//  This program does NOT attempt any communication with another nRF24

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

#include <printf.h>

#define CE_PIN   9
#define CSN_PIN 10

const byte thisSlaveAddress[5] = {'R','x','A','A','A'};

RF24 radio(CE_PIN, CSN_PIN);

char dataReceived[10]; // this must match dataToSend in the TX
bool newData = false;


void setup() {
    Serial.begin(9600);
    printf_begin();

    Serial.println("CheckConnection Starting");
    Serial.println();
    Serial.println("FIRST WITH THE DEFAULT ADDRESSES after power on");
    Serial.println("  Note that RF24 does NOT reset when Arduino resets - only when power is removed");
    Serial.println("  If the numbers are mostly 0x00 or 0xff it means that the Arduino is not");
    Serial.println("     communicating with the nRF24");
    Serial.println();
    radio.begin();
    radio.printDetails();
    Serial.println();
    Serial.println();
    Serial.println("AND NOW WITH ADDRESS AAAxR  0x41 41 41 78 52   ON P1");
    Serial.println(" and 250KBPS data rate");
    Serial.println();
    radio.openReadingPipe(1, thisSlaveAddress);
    radio.setDataRate( RF24_250KBPS );
    radio.printDetails();
    Serial.println();
    Serial.println();
}


void loop() {

}

...R

1 Like

I wrote this Tutorial in 2016 when the current RF24 library version was 1.1.7. The Tutorial code has worked without problems until very recently when updates to the library code were made which were not backwards compatible. (To be honest until someone reported a problem with the Tutorial I was not even aware that any updates were being made to the library code - I am still using V1.1.7 for my own projects).

To access the Arduino Library Manager from the Arduino IDE go to Tools / Manage Libraries. After a short delay it wll display a list of all the possible libraries that can be installed. Scroll down to the RF24 library and you can then select the version you wish to install.

It is likely that the Tutorial will work with newer RF24 library versions than V1.1.7 but I don't know which is the first version that is not backwards compatible.

...R

@Robin2
the porting of some post in new forum had problems with code. It happened to yours.

All the content of #include went out.

Hi @zoomx. Thanks for the report.

We are told by the Discourse staff that there is an automated process working its way through the huge amount of posts and fixing this and the embedded images that went missing. I see that some of the posts in this thread were fixed, but others not.

I have now gone through and manually triggered the process for all the posts that had still not been processed. So it should be all fixed up now. If you spot any I missed, feel free to let me know.

2 Likes

Thanks @pert ,
I believe that is better to send you a note if I or someone find another old post error in porting since the author in this new forum is not allowed to modify very old post.

That will be fine. Thanks!

(Gateway or Routing Operation using NRF24 - #3 by juliabellan) is it possible ? and how i can do this ?

Hi all. I read this tutorial carefully, but also other materials on the internet, but I did not find an answer to my question. I am new to arduino and for the project I would need to transmit more float data with NRF24L01 modules. I saw that this module can transmit up to 32 bytes, that is, in my case up to 8 values, while I would need to transmit at least 11 values. Is it possible to transmit 2 consecutive data sets of 8 values each? If so, please tell me where I can learn how to do this. Thank you.

Wow, what a great tutorial! Everything explained so well.

I am a newbie as far as the nrf24L01 is concerned and am having issues with one Master sending data to two Receivers. But will try out your suggestions in post #18 and revert.

Thanks for the tutorial once again!

Hi all. I managed to make the transmission in 3 installments. Now I'm trying to arrange the received data in a single array. Can anyone help me with an idea?

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

RF24 radio(9, 10); // CE si CSN
float data[8]; 
float ax=0.79, ay=0.23, az=0.62, gx=0.2, gy=13, gz=54, mx=1234276, my=654, mz=4298, pr=9816, tm=24.6, um=46.83, ab=63.89, af=3.94, LA=87653454, LO=98234391, Vi=15.4;
float Matrice[17] = {ax, ay, az, gx, gy, gz, mx, my, mz, pr, tm, um, ab, af, LA, LO, Vi};

void setup(){
    radio.begin();                                
    radio.setChannel(124);                
    radio.setDataRate (RF24_250KBPS);             
    radio.setCRCLength(RF24_CRC_16);
    radio.setPALevel (RF24_PA_HIGH);              
    radio.openWritingPipe (0x1234567890LL);       
                     
    Serial.begin(9600);                                                   
}
 
void loop(){  
 for(int x=0; x < 17; x++) {
Serial.print(Matrice[x]);
Serial.print(" / ");
}
Serial.println(" ");
// Transmiterea datelor masurate
data[0] = 0.00; // ID 1
for(int x=0; x < 7; x++) {
data[x+1] = Matrice[x]; }
// Transmiterea datelor
radio.write(&data, sizeof(data));
data[0] = 1.11; // ID 2
for(int x=7; x < 14; x++) {
data[x-6] = Matrice[x]; }
// Transmiterea datelor
radio.write(&data, sizeof(data));
data[0] = 2.22; // ID 3
for(int x=14; x < 21; x++) {
data[x-13] = Matrice[x]; }
// Transmiterea datelor
radio.write(&data, sizeof(data));
delay(500);
}
//RECEPTOR
 
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

RF24 radio(9, 10);
float data[8];    
                               
void setup(){
     radio.begin();                                 
     radio.setChannel(124);                         
     radio.setDataRate (RF24_250KBPS);              
     radio.setCRCLength(RF24_CRC_16);
     radio.setPALevel (RF24_PA_HIGH);               
     radio.openReadingPipe (1, 0x1234567890LL);     
     radio.startListening ();                       
   Serial.begin(9600);                             
}
 
void loop(){  
    
    if (radio.available())                          
    {     
        radio.read(&data, sizeof(data));   
       for(int x=1; x<8; x++){          
            
        Serial.print(data[x]); 
        Serial.print("/");}
    
    Serial.println(" ");

    }
}
     

You can probably do something like this to test it. I used a struct instead of an array because you can mix data types but it would also work with an array. Important is to pad out the structure you are transferring and/or ensure that it is equal to the size you declare in the sending operation. If not, it will overwrite data on the receiving side.
The struct is treated as a byte array for transmission.

Transmitter:

struct Coord {
  float ax ;
  float ay ;
  float az ;
  // ...
  // pad out to 96 bytes ( 3 * 32)
};

Coord coord ;


void setup() {
  Serial.begin( 115200 ) ;
  //
}

void loop() {

  // load struct to send
  coord.ax = 1.5 ;
  coord.ay = 3.9 ;
  coord.az = 7.2 ;
  //etc.

  uint8_t * byteArray  ;
  byteArray = (uint8_t *) &coord ;  // treat struct as byte arraay

  radio.write( &byteArray[ 0 ] , 32 );
  delay( 100) ;

  radio.write( &byteArray[ 32 ] , 32 );
  delay( 100) ;

  radio.write( &byteArray[ 64 ] , 32 );
  delay( 500) ;
}

.
.
Receiver:

struct Coord {
  float ax ;
  float ay ;
  float az ;
  // ...
  // pad out to 96 bytes ( 3 * 32)
};

Coord coord ;


void setup() {
  Serial.begin( 115200 ) ;
  //
}

void loop() {


  uint8_t * byteArray  ;
  byteArray = (uint8_t *) &coord ;  // treat struct as byte arraay

  radio.read( &byteArray[ 0 ] , 32 );

  radio.read( &byteArray[ 32 ] , 32 );

  radio.read( &byteArray[ 64  ] , 32 );

  Serial.println( coord.ax ) ;
  Serial.println( coord.ay ) ;
  Serial.println( coord.az ) ;
  // etc.
}

Hello. Thank you for your response and help. I tried your codes, but it gives me a compilation error that I can't fix. I searched the internet for solutions, but new errors kept appearing and I was only getting worse. Do you know what the solution would be?