Simple nRF24L01+ 2.4GHz transceiver demo

I don't know if the ack method is working well, but I advise you not to use it because as I know, when you send a request to a node(A,B or C) these have to reply immediately this will work just if you are sending requests sequentially, yet you have to use other method !!!

I have this type of radio, and I won't work with this example: https://www.aliexpress.com/store/product/10PCS-LOT-NRF24L01-PA-LNA-Onboard-Ceramic-Antenna-Wireless-Transmission-Module-905-CC1101/610196_2026712476.html

If i change this:

void getData() {
    if ( radio.available() ) {
        radio.read( &dataReceived, sizeof(dataReceived) );
        newData = true;
    }
}

to

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

I only get a serial console flooded with "No radio available" messages :(

CHEGGARI: I don't know if the ack method is working well, but I advise you not to use it because as I know, when you send a request to a node(A,B or C) these have to reply immediately this will work just if you are sending requests sequentially, yet you have to use other method !!!

I have been playing with it as it does work using the ack method.

The slave node builds an array of data it wants to send back. then it simply populates the buffer ready for the ACK with the first item in the array. The master polls it 5 times a second (will get faster), and collect the data via the ack method.

Because this is for racing gates and there are only up to 16 cars/drone on track, I am not limited by time, There are generally several seconds between items and / or laps. I am adding error correction so the master has to poll the slave 22 time to collect all 16 items in the array and check them off, and generally has 30+ seconds per lap to achieve this. Once up to speed I am planning to poll the slaves 9 times a second I have plenty of time to do this via acks.

I tried both having send and receive method on slaves and master, and using the ack and the ack version is much easier to code, and because i know only the master is talking and the rest are listening i can cut down on the timeouts and retries so make the process quicker.

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

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.

1 Like

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!