nRF24l01 - Problems with Arduino Mega

Hello everyone,
I'm having an issue with a particular off-brand Arduino Mega. On an official Arduino Mega, the code runs just fine, with the radio module working perfectly.
However, when I run the EXACT SAME CODE with the EXACT SAME WIRING on the off-brand Mega, the program crashes / freezes at radio.printDetails().

I experimentally tried the following code to set up the radio:

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <printf.h>
RF24 radio(7, 8); // CE, CSN

void setup() {
  Serial.begin(9600);
  radio.begin();
}

void loop() {
  Serial.println("Test");
  radio.printDetails();
  delay(1000);
}

When run on the official Mega, the Serial Monitor says "Test" and then prints all the details as normal, every second.

On the off-brand Mega however, the Serial Monitor says "Test" once and then nothing else. This leads me to believe that radio.printDetails() is getting stuck in a loop, or crashing the Arduino, and somehow stopping the entire program.

If I delete the line, the radio begins spamming zeros into the Serial Monitor (what it's receiving), but only if I rest my fingers on the ICSP header (?!)

I am trying to create a remote control system, but this problem with the off-brand Mega has me confused.
This Mega has had no problems in the past.
The code isn't the problem, since I used the same code for both and it worked fine on the official Mega.

Without a

printf_begin();

there is no output from printDetails here.

Thanks, this fixed it. Now there's a new problem to deal with.
My code:

/*
 *   Getting Started example sketch for nRF24L01+ radios
  This is a very basic example of how to send data from one node to another
  but modified to include failure handling.
  The nrf24l01+ radios are fairly reliable devices, but on breadboards etc, with inconsistent wiring, failures may
  occur randomly after many hours to days or weeks. This sketch demonstrates how to handle the various failures and
  keep the radio operational.
  The three main failure modes of the radio include:
  Writing to radio: Radio unresponsive - Fixed internally by adding a timeout to the internal write functions in RF24 (failure handling)
  Reading from radio: Available returns true always - Fixed by adding a timeout to available functions by the user. This is implemented internally in  RF24Network.
  Radio configuration settings are lost - Fixed by monitoring a value that is different from the default, and re-configuring the radio if this setting reverts to the default.
  The printDetails output should appear as follows for 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       = 0x03
  CONFIG         = 0x0f
  DYNPD/FEATURE  = 0x00 0x00
  Data Rate      = 1MBPS
  Model          = nRF24L01+
  CRC Length     = 16 bits
  PA Power       = PA_LOW
  Users can use this sketch to troubleshoot radio module wiring etc. as it makes the radios hot-swapable
  Updated: 2019 by TMRh20
*/

#include "RF24.h"
#include "printf.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;


/**********************************************************/
//Function to configure the radio
void configureRadio() {

  radio.begin();
  radio.setChannel(120);
  radio.setDataRate(RF24_250KBPS);

  // 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();
  radio.printDetails();
}


/**********************************************************/

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

  printf_begin();

  configureRadio();
}

uint32_t configTimer =  millis();

void loop() {

  if (radio.failureDetected) {
    radio.failureDetected = false;
    delay(250);
    Serial.println("Radio failure detected, restarting radio");
    configureRadio();
  }
  // Every 5 seconds, verify the configuration of the radio. This can be
  // done using any setting that is different from the radio defaults.
  if (millis() - configTimer > 5000) {
    configTimer = millis();
    if (radio.getDataRate() != RF24_250KBPS) {
      radio.failureDetected = true;
      Serial.print("Radio configuration error detected");
    }
  }


  /****************** 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
    bool 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 {
      // Grab the response, compare, and send to debugging spew

      unsigned long got_time;                                  // Variable for the received timestamp

      // Failure Handling
      uint32_t failTimer = millis();
      while (radio.available())                                // If available() always returns true, there is a problem
      {
        if (millis() - failTimer > 250) {
          radio.failureDetected = true;
          Serial.println("Radio available failure detected");
          break;
        }
        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"));
    }

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


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

  if (role == 0) {
    unsigned long got_time;                                    // Variable for the received timestamp

    if (radio.available()) {
      uint32_t failTimer = millis();

      while (radio.available())                                // While there is data ready
      {
        if (millis() - failTimer > 500) {
          Serial.println("Radio available failure detected");
          radio.failureDetected = true;
          break;
        }
        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

The RF24 module on the official Arduino keeps restarting itself.
Output from Serial Monitor:

Now sending
failed
Failed, response timed out.
Radio failure detected, restarting radio
SPI Speedz	= 10 Mhz
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 0x20 0x20 0x20 0x20
EN_AA		= 0x3f
EN_RXADDR	= 0x02
RF_CH		= 0x78
RF_SETUP	= 0x23
CONFIG		= 0x0f
DYNPD/FEATURE	= 0x00 0x00
Data Rate	= 250 KBPS
Model		= nRF24L01+
CRC Length	= 16 bits
PA Power	= PA_LOW
ARC		= 0
Now sending
failed
Failed, response timed out.
Radio failure detected, restarting radio
SPI Speedz	= 10 Mhz
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 0x20 0x20 0x20 0x20
EN_AA		= 0x3f
EN_RXADDR	= 0x02
RF_CH		= 0x78
RF_SETUP	= 0x23
CONFIG		= 0x0f
DYNPD/FEATURE	= 0x00 0x00
Data Rate	= 250 KBPS
Model		= nRF24L01+
CRC Length	= 16 bits
PA Power	= PA_LOW
ARC		= 0
Now sending
failed
Failed, response timed out.

It keeps repeating this, over and over and over. The offbrand Mega just says

Now sending
failed
Failed, response timed out.

Over and over.

Two senders won't work very well with each other, will they?

These are the Serial monitor prints when in Transmit mode.
The two serial monitor snippets aren't from at the same time. One radio is set to transmit, the other to receive.
For both, the receiving radio and arduino do nothing. They aren't even getting a signal.

Give the modules a decent power supply, the 3.3V of Megas are not sufficient.
Sometimes it may work, high power modules never work.
A small capacitor (1 to 10 uF) directly on the power pins of the NRF modules helps sometimes.

I am using the 5v step down base module along with the radio, it looks like this:
image

So the supply is ok, maybe you have bad/cloned NRFs?

Do the modules work with Nanos?

For a Mega a

pinMode(53, OUTPUT);

should be added to the sketches, but I don't think this is the problem here.

I tested with two Nanos. Now, both radios reset themselves when transmitting. I know the wiring is correct because with any other wiring the Serial Monitor repeats,

Radio configuration error detectedRadio available failure detected
Sent response 0
Radio failure detected, restarting radio
SPI Speedz	= 10 Mhz
STATUS		= 0x00 RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=0 TX_FULL=0
RX_ADDR_P0-1	= 0x0000000000 0x0000000000
RX_ADDR_P2-5	= 0x00 0x00 0x00 0x00
TX_ADDR		= 0x0000000000
RX_PW_P0-6	= 0x00 0x00 0x00 0x00 0x00 0x00
EN_AA		= 0x00
EN_RXADDR	= 0x00
RF_CH		= 0x00
RF_SETUP	= 0x00
CONFIG		= 0x00
DYNPD/FEATURE	= 0x00 0x00
Data Rate	= 1 MBPS
Model		= nRF24L01+
CRC Length	= Disabled
PA Power	= PA_MIN
ARC		= 0
Sent response 0

Over and over.
I know that all the 0's mean the radio isn't connected to the Arduino at all.

I added pinMode(53, OUTPUT); to void setup() {}, that didn't change anything at all.

I thought I should probably attach the modules in question here.
The modules are nRF24l01+PA+LNA modules (Link)

The official Mega is a board bought from Amazon, confirmed to be sold by Arduino and has their unique golden infinity component next to the USB port.

The offbrand Mega is an unbranded board that just says "Mega 2560". There is no company name anywhere on it.

The nRFs are definitely working, as they are sending data back and forth to their respective Arduinos. They just won't connect to one another.

Here is some technical info relayed by

radio.printDetails();
radio.printPrettyDetails();

Radio 1 (Original Arduino):

SPI Speedz	= 10 Mhz
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 0x40
TX_ADDR		= 0x65646f4e31
RX_PW_P0-6	= 0x20 0x20 0x20 0x20 0x20 0x20
EN_AA		= 0x3f
EN_RXADDR	= 0x02
RF_CH		= 0x78
RF_SETUP	= 0x23
CONFIG		= 0x0f
DYNPD/FEATURE	= 0x00 0x00
Data Rate	= 250 KBPS
Model		= nRF24L01+
CRC Length	= 16 bits
PA Power	= PA_LOW
ARC		= 0
SPI Frequency		= 10 Mhz
Channel			= 120 (~ 2520 MHz)
RF Data Rate		= 250 KBPS
RF Power Amplifier	= PA_LOW
RF Low Noise Amplifier	= Enabled
CRC Length		= 16 bits
Address Length		= 5 bytes
Static Payload Length	= 32 bytes
Auto Retry Delay	= 1500 microseconds
Auto Retry Attempts	= 15 maximum
Packets lost on
    current channel	= 0
Retry attempts made for
    last transmission	= 0
Multicast		= Disabled
Custom ACK Payload	= Disabled
Dynamic Payloads	= Disabled
Auto Acknowledgment	= Enabled
Primary Mode		= RX
TX address		= 0x65646f4e31
pipe 0 (closed) bound	= 0x65646f4e31
pipe 1 ( open ) bound	= 0x65646f4e32
pipe 2 (closed) bound	= 0xc3
pipe 3 (closed) bound	= 0xc4
pipe 4 (closed) bound	= 0xc5
pipe 5 (closed) bound	= 0x40

And Radio 2 (offbrand Mega)

SPI Speedz	= 10 Mhz
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 0x20 0x20 0x20 0x20
EN_AA		= 0x3f
EN_RXADDR	= 0x02
RF_CH		= 0x78
RF_SETUP	= 0x23
CONFIG		= 0x0f
DYNPD/FEATURE	= 0x00 0x00
Data Rate	= 250 KBPS
Model		= nRF24L01+
CRC Length	= 16 bits
PA Power	= PA_LOW
ARC		= 0
SPI Frequency		= 10 Mhz
Channel			= 120 (~ 2520 MHz)
RF Data Rate		= 250 KBPS
RF Power Amplifier	= PA_LOW
RF Low Noise Amplifier	= Enabled
CRC Length		= 16 bits
Address Length		= 5 bytes
Static Payload Length	= 32 bytes
Auto Retry Delay	= 1500 microseconds
Auto Retry Attempts	= 15 maximum
Packets lost on
    current channel	= 0
Retry attempts made for
    last transmission	= 0
Multicast		= Disabled
Custom ACK Payload	= Disabled
Dynamic Payloads	= Disabled
Auto Acknowledgment	= Enabled
Primary Mode		= RX
TX address		= 0x65646f4e32
pipe 0 (closed) bound	= 0x65646f4e32
pipe 1 ( open ) bound	= 0x65646f4e31
pipe 2 (closed) bound	= 0xc3
pipe 3 (closed) bound	= 0xc4
pipe 4 (closed) bound	= 0xc5
pipe 5 (closed) bound	= 0xc6

Update: I swapped which radios were connected to which Arduinos, and the misbehaving Arduinos swapped places. So, I guess I got a bad NRF.

I ended up buying some new nRF24l01's online, and they came today. They work perfectly, and the two Megas talk to each other without any issues.

SOLVED - The problem: defective radio modules

1 Like

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.