[Solved] how come delay() interferes with nRF24L01 sending?


The problem went away when I changed the RF24 library. Instead of using Maniacbug's RF24, I used G. Copeland's fork of RF24.

Just for kicks, I deleted the RF24 library and replaced it with the latest from maniacbug's github. The problem reappeared. Went back to the Copeland forked RF24, problem went away. And that was just with recompiling and uploading on the sender Arduino.

I don't understand why. But it fixed my issue.


I ran into an odd issue with an example sketch for the nRF24L01. It's a simple sender/receiver sketch. It works fine as is. I see the data coming from sender to receiver. But, if I add a delay(xx) before sending, the receiver never sees the packet.

Here's the code. Peter made a great point below, so I modified the sender with a millis counter, to give me an idea of how fast the sender is actually sending and if it's retrying. I tried adjusting the delay ms and found out something interesting.

delay(10) or less: receiver scrolls fast, more than 20 transmissions per second, faster than I can count certainly.
delay(11): receiver now only gets one transmission every 2 or 3 seconds. It's inconsistent, but I see it scroll at least
delay(12) or greater: major issues with transmission. No transmissions received after 1 minute.

These delays are only ms apart. And I kept the setup the same (no touching or moving the radios) during these tests. After testing higher delay() values, I went to down to delay(5) and the receiver started scrolling through the data again. So, there's something weird going on, and I've done as much as I can think to do not to shoot myself in the foot.

Sender. If I comment out the delay(xx), it works fine. Or make the delay < 10ms, it works.

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#define CE_PIN   8
#define CSN_PIN 7

const uint64_t pipe = 0xE8E8F0F0E1LL; // Define the transmit pipe


RF24 radio(CE_PIN, CSN_PIN);

typedef struct 
{
     int DevID;
     float DevVal;
     int DevSig;
} twoInts;


twoInts SensorNode;
   
   
int mytime = 0;
void setup()   /****** SETUP: RUNS ONCE ******/
{
  Serial.begin(9600);
  radio.begin();
  radio.openWritingPipe(pipe);
  mytime = millis();
}//--(end setup )---


void loop()   /****** LOOP: RUNS CONSTANTLY ******/
{
  int timeleft = millis() - mytime;

  delay(12);    // <<<---------------- change delay to see what happens
  SensorNode.DevID = 3;
  SensorNode.DevVal = timeleft;
  radio.write( &SensorNode, sizeof(SensorNode) );
  Serial.println("done sending");
  
  if (timeleft > 6000)
  {
    mytime = millis();
    
  }
}

Receiver...this doesn't matter very much since it's not causing the problem, but just in case I'm wrong I'm including it.

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

#define CE_PIN   8
#define CSN_PIN 7

const uint64_t pipe = 0xE8E8F0F0E1LL; // Define the transmit pipe

typedef struct 
{
     int DevID;
     float DevVal;
     int DevSig;
} twoInts;


twoInts SensorNode;

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


void setup()   /****** SETUP: RUNS ONCE ******/
{
  Serial.begin(9600);
  delay(1000);
  Serial.println("Nrf24L01 Receiver Starting");
  radio.begin();
  radio.openReadingPipe(1,pipe);
  radio.startListening();;
}//--(end setup )---





void loop()
{
  if ( radio.available() )
  {
    // Read the data payload until we've received everything
    bool done = false;
    while (!done)
    {
      // Fetch the data payload
      done = radio.read( &SensorNode, sizeof(SensorNode) );
      Serial.print("X = ");
      Serial.print(SensorNode.DevID);
      Serial.print(" Y = ");      
      Serial.println(SensorNode.DevVal);
    }
  }
  else
  {    
      //Serial.println("No radio available");
  }

}

I haven't compared that code to a conventional sender/receiver pair, but nothing jumps out at me as being wrong. The only effect I'd expect from removing the delay is that the sender sends far more frequently. Perhaps you have a high failure rate and need the retransmissions to get through. You can increase the retry interval and count to make the transmission more robust. It's also possible to query the radio and find out how many retries were necessary, if you really want to look into the detailed behaviour. The example sketches that come with the RF24 show you how to change the retry configuration.

The problem went away after I replaced the RF24 library. Was using Maniacbug's. Copeland's fork of the RF24 library seems to work better for my code. Not sure why.

I confirm that this solved my problem too. Experienced that the nRF sent inconsistent and "jumping" signals, and then came across this post. Changed the library to Copeland's and everything worked perfect.