Problems with nRF24L01

I was having some difficulties getting a pair of nRF24L01 talk reliably, I was using the 'Simple nRF24L01+ 2.4GHz transceiver demo'

Although I had tested the modules as working some time back, I was now having problems.

I noticed that touching the module appeared to make it work, I was getting the 'Data Sent Message 0 Acknowledge received' message, but I was getting this message when there was no receiver active.

I eventually found that if you connect MOSI and MISO, with no actual nRF24L01 or other SPI device connected you get the 'Acknowledge received' message, which does not seem likely when the is no nRF24L01 connected to receive it.

Same issue on 3 different types of Arduino Pro Mini and a Arduino DUE.

Is this known behaviour ?

I have never tried what you describe but I know that when the nRF24 is incorrectly connected the Arduino can show a series of "received" messages at a very high rate. If things are working properly they should appear once per second - the rate being dictated by the transmitting program. This behaviour is mentioned in my Tutorial.

I'm guessing that it is the SPI library that gets confused.

...R

Robin2:
I'm guessing that it is the SPI library that gets confused.

Well it might.

But as soon as I reliased I could ignore what the TX code is saying, since it does not seem to know if the TX was OK or not, I started making headway.

The receiver had been printing this repeatadly;

Data received Message 2
Data received Message 2

So the transmitter is sending the packet but is not apparently seeing a reply ?

It was difficult to see if anything was happening when the screen filled up, the same message all the time.

So I added some code to print the elapsed time in seconds before the 'Data received' message. I also turned on a LED at the beginning of the showData() function and off at the end, adding a 25mS delay so I could see the LED flash.

And lo ....... these mods turned my transmitter that was only reporting an acknowledge 3% of the time (measured over 1000 iterations) to a transmitter that was now reporting 100% acknowledge, no fails for over 17minutes.

Working out I had changed to make such a differance I found that if I added a delay to this bit;

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

The modules worked a great deal more relaibly as a receiver (I have 5 modules). However I found one of the modules worked 100% without the delay and only 2 of the modules worked reliably as transmitter.

A 'good' pair was error free for at least 1000 iterations.

I would suspect that most of my modules are fakes, but ocaisionally you get a good one, and they are reliable.

srnet:
The modules worked a great deal more relaibly as a receiver (I have 5 modules).

I had assumed your original question was mainly due to idle curiosity. I interpreted your "I was having ..." to mean that you had solved the problem.

As you seem to be having a problem with a project please post the Tx and Rx code that YOU have uploaded to your Arduinos and a sample of the output from each.

...R

Not a project as such, but I was testing a Mikrobus plug in board that could take a nRF24, so it seemed to make sense to test the board with some software to see if it was working as expected.

SimpleTx.ino

// 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);

    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;
}

SimpleRx.ino

// 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() {

    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;
    }
}

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

TX Output:

SimpleTx Starting
Data Sent Message 0 Tx failed
Data Sent Message 0 Tx failed
Data Sent Message 0 Tx failed
Data Sent Message 0 Tx failed
Data Sent Message 0 Tx failed
Data Sent Message 0 Tx failed
Data Sent Message 0 Tx failed
Data Sent Message 0 Tx failed
Data Sent Message 0 Tx failed
Data Sent Message 0 Tx failed

RX Output:

SimpleRx Starting
Data received Message 0
Data received Message 0
Data received Message 0
Data received Message 0
Data received Message 0
Data received Message 0
Data received Message 0
Data received Message 0
Data received Message 0
Data received Message 0

So now change the SimpleRx.ino by adding the delay mentioned, the SimpleTx.ino is not changed.

Modified SimpleRx.ino

// SimpleRx - the slave or the receiver

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

#define CE_PIN  10
#define CSN_PIN 6

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);

    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;
    }
}

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

TX Output:

SimpleTx Starting
Data Sent Message 0 Acknowledge received
Data Sent Message 1 Acknowledge received
Data Sent Message 2 Acknowledge received
Data Sent Message 3 Acknowledge received
Data Sent Message 4 Acknowledge received
Data Sent Message 5 Acknowledge received
Data Sent Message 6 Acknowledge received
Data Sent Message 7 Acknowledge received
Data Sent Message 8 Acknowledge received

RX Output:

SimpleRx Starting
Data received Message 0
Data received Message 1
Data received Message 2
Data received Message 3
Data received Message 4
Data received Message 5
Data received Message 6
Data received Message 7
Data received Message 8
Data received Message 9

I eventually worked out how the ‘GettingStarted’ example included with the NRF24 library itself works and and it looks like all 5 modules I have work with this ‘GettingStarted’ example as either transmitter or receiver.

srnet:
So now change the SimpleRx.ino by adding the delay mentioned, the SimpleTx.ino is not changed.

That's very strange. I must have tried about 20 nRF24s over the past few years and they all worked with my Tutorial code. I have had nRF24s working on Unos, Megas, a Leonardo, Atmega 328s on stripboard and Attiny 1634 and 84.

Are these messages arriving once per second?

RX Output:

SimpleRx Starting
Data received Message 0
Data received Message 0
Data received Message 0
Data received Message 0

...R

Robin2:
That's very strange. I must have tried about 20 nRF24s over the past few years and they all worked with my Tutorial code. I have had nRF24s working on Unos, Megas, a Leonardo, Atmega 328s on stripboard and Attiny 1634 and 84.

Are these messages arriving once per second?

RX Output:

SimpleRx Starting
Data received Message 0
Data received Message 0
Data received Message 0
Data received Message 0





.
..R

Yes.

The RX is receiving the packet from TX, but it would appear that the TX is not seeing the ACK, so it keeps sending the same message. The ACK does ocaisionaly get through so then you see;

Data received Message 1
Data received Message 1
Data received Message 1

Etc.

srnet:
The RX is receiving the packet from TX, but it would appear that the TX is not seeing the ACK,

I would suspect an inadequate 3.3v power supply for the Rx nRF24

...R

PS ... I assume you are using the low power nRF24s with the PCB antenna. And that you are using nRF24L01+ modules and not the earlier nRF24L01 version (which I have never had myself).

I was using the + ones with PCB antenna.

It could be power supply related, but the problems does not go away when the receiver module is on an ESP32 board which has a power supply good enough to withstand the infamous ESp32 WiFi switch on spike, or when its plugged into a DUE board.

And why does the NRF24 library example 'GettingStarted' seem to be not affected.

Mystery indeed.

srnet:
And why does the NRF24 library example ‘GettingStarted’ seem to be not affected.

Perhaps the way it swaps the roles between talking and listening has the same affect as your short delay()

IIRC I derived my code from that example by eliminating the swapping part to eliminate the possibility of confusion.

…R