nRF24L01 heating/cooling system automation

Hello to all,

First of all this is my first post and hopefully i did not mess up from the beginning by posting in the wrong topic.

Back to the subject, i'm working on a project with it's purpose to control my heating/cooling system in my house. The project includes a few temperature/humidity sensors which are using nRF24L01 to communicate with a master receiver.
The sensors are sending data every 5 seconds to the receiver where the receiver decide which actuator to turn on/off.

The problem
I use an LED to indicate a successful data transmission.
1 flash - data sent ok
2 flashes - data sent nok

I defined a variable to check if the transmission has been successful or not. The problem is that even when the transmission is successful the LED flashes 2 times.
On the serial monitor data is received every 5 seconds without problems.
This happens randomly, let's say 70% nok and 30% ok.
Being on development phase the distance between sensor and receiver is max 2 meters, range problems is excluded.

Any kind of advice is welcome.

/************************************************************************
 *                                                    nRF SEND DATA                                                    *
 ************************************************************************/
  void nRFSendData()
    {

      nRF24_SEND_DATA[0] = SENSOR_DATA_TEMPERATURE;
      nRF24_SEND_DATA[1] = SENSOR_DATA_HUMIDITY;

   
      bool RADIO_DATA_SENT_FLAG = radio.write(&nRF24_SEND_DATA, sizeof(nRF24_SEND_DATA));

      if (RADIO_DATA_SENT_FLAG == true){
        digitalWrite (7, LOW);
        delay(10);
        digitalWrite (7, HIGH);        
      }      
      else{

        for (int i=0; i<=3; i++){
          delayMicroseconds(random(200, 500));      
          radio.write(&nRF24_SEND_DATA, sizeof(nRF24_SEND_DATA));
          if (RADIO_DATA_SENT_FLAG == true){break;}
        }
        
      digitalWrite (7, LOW);
      delay(10);
      digitalWrite (7, HIGH);
      delay(200);
      digitalWrite (7, LOW);
      delay(10);
      digitalWrite (7, HIGH);
        
      }
  
    }

Your code is written so that if the transmission fails on the first attempt here:

      bool RADIO_DATA_SENT_FLAG = radio.write(&nRF24_SEND_DATA, sizeof(nRF24_SEND_DATA));

it tries sending four more times here:

        for (int i=0; i<=3; i++){
          delayMicroseconds(random(200, 500));     
          radio.write(&nRF24_SEND_DATA, sizeof(nRF24_SEND_DATA));

This statement:

          if (RADIO_DATA_SENT_FLAG == true){break;}

will never evaluate to true, since the else block would not have been entered if RADIO_DATA_SENT_FLAG == true, and you don't change the value of RADIO_DATA_SENT_FLAG after that, maybe you meant to do this:

          RADIO_DATA_SENT_FLAG = radio.write(&nRF24_SEND_DATA, sizeof(nRF24_SEND_DATA));
          if (RADIO_DATA_SENT_FLAG == true){break;}

Either way, what happens is if the first transmission attempt fails, then the retransmission attempts succeed, you will still get the double blink that you expect to indicate a failed transmission.

Hi pert,

Thank you for your advice.
On the last part of the code i deliberately let the LED to double flash if the first transmission failed, even if the second retry succeeded.
In mean time i have changed the code, i remove the "1 flash" part because it's not really important for me.

During the tests i found that if on the "void setup" part of the code i use "radio.setRetries(1, 3);" the code does not run as expected.
Looks like the first transmission fails every time. If i remove "radio.setRetries(1, 3);" everything is fine.
I don't get it, clearly i miss something here...

Here is my setup code

/***************************************************
 *                                    GENERAL SETUP                             *
 ***************************************************/ 
  void setup()
    {
      
      Wire.begin();
      Wire.setClock(1000000);
      
      radio.begin();
      radio.openWritingPipe(address);
      radio.setPALevel(RF24_PA_MAX);
      radio.setDataRate(RF24_250KBPS);
      radio.setChannel(0xFF);  
      //radio.setRetries(1, 3);                             
      radio.stopListening();
      
      attachInterrupt(digitalPinToInterrupt(3), EXTERNAL_TRIGGER_INTERRUPT, FALLING);


      delay(1000);  
    }

And the radio part

/***************************************************
 *                                    nRF SEND DATA                              *
 ***************************************************/
  void nRFSendData()
    {

      nRF24_SEND_DATA[0] = SENSOR_DATA_TEMPERATURE;
      nRF24_SEND_DATA[1] = SENSOR_DATA_HUMIDITY;
    
      if (!radio.write(&nRF24_SEND_DATA, sizeof(nRF24_SEND_DATA))){
        for (int i=0; i<=3; i++){
          delayMicroseconds(random(200, 500));
          radio.write(&nRF24_SEND_DATA, sizeof(nRF24_SEND_DATA));
        }
        digitalWrite (7, LOW);
        delay(10);
        digitalWrite (7, HIGH); 
        delay(200);
        digitalWrite (7, LOW);
        delay(10);
        digitalWrite (7, HIGH);               
      }
      
    }

You are not missing it by much.

If you see the datasheet for nrf24l01+ you will find the following on page 59:

"In 250kbps mode (even when the payload is not in ACK) the ARD must be 500us or more."

This means you must use at least radio.setRetries(2,n); in 250kbps mode.