What happens exactly after NRF24 gives up retrying and goes to sleep 2.3.x?

  • So this week, just for fun, I thought I would try and investigate why the occasional battery voltage (sent every 2 minutes) does not get through. I'd just like to understand the sequence of events a bit better as regards to node to gateway communication.

    I am running 2.3.2 on gateway and some nodes, 2.3.1 on others. A lot of posts I have found date back to 2016 so am unsure if they are still valid.

    Am I correct In thinking a node will retry 15 times before it gives up?
    At this point the message is lost as I have no code to try and resend.

    All my battery nodes sleep for 2 minutes or until they are woken by PIR in some cases. At what point after wake up will the node try and establish communication again? I ask this because sometimes a node seems to stay offline for a long time even though it may be close to the gateway and all other nodes are reporting in fine.

    is it still valid in 2.3.2 to use if(isTransportOK()) as seen in older posts to keep the node awake until it sends the message or is there a better way to do this?

  • Mod

    I'd say they are still valid. There haven't been much changes to MySensors during this time, especially not regarding resend.

    By default, a nrf24 node will retry sending a single message 15 times yes. Source: https://github.com/mysensors/MySensors/blob/dd91aeb9c30dbd658bd02c34445669a7cd996c0f/hal/transport/RF24/driver/RF24registers.h#L47

    The whole transport state machine is a whole lot more complex than that though; way beyond my knowledge. Hopefully someone with more insight can explain.

  • Mod

    @mfalkvidd the transport statemachine is not involved in retrying, as this is purely done by the nrf24 radio. The ARC and ARD values determine the amount of retries before giving up and the time in between retries.
    I did some experiments in the past and saw maximum retries of 2..3 times, or giving up after 15. This means retrying for more than 3 times nearly always fails, and doesn't make much sense.

  • Thanks for the replies and info.

    @Yveaux are you saying if the node did not achieve success after 2 or 3 attempts it would carry on and reach its limit of 15 attempts - then give up. i.e. it would never achieve a successful transmit at say attempt 10 or 11?

    I may have do do some testing and experiments myself with a node connected to a laptop in debug mode.

  • Mod

    @Yveaux sorry for being unclear. I know that the state machine is not involved in retrying sending a single message. But grumpazoid is asking "At what point after wake up will the node try and establish communication again" which does involve the state machine.

  • Mod

    @grumpazoid said in What happens exactly after NRF24 gives up retrying and goes to sleep 2.3.x?:

    it would never achieve a successful transmit at say attempt 10 or 11?

    No, I mean in practice I've seen that if it fails after 3 attempts it will keep failing until giving up.

  • @Yveaux Thanks. Yes behaviour is strange.
    PIR messages that wake via interrupt seem to kick a node back into life somehow. Maybe because they are keeping it awake for communication to establish again?

  • I have cobbled together a simple test sketch that sends alternating values to the gateway every x seconds - Attached below (feel free to correct bad coding).

    Are we saying that when I get a NACK response in the serial monitor such as :

    37315 !TSF:MSG:SEND,9-9-0-0,s=1,c=1,t=16,pt=2,l=2,sg=0,ft=0,st=NACK:20

    That the sending radio has attempted to send its message AND listened for, but not heard, a response from the gateway 15 times?

    I say this because what I observe is the code moving on to send the next message in the sequence.

    // Enable debug prints
    #define MY_DEBUG
    #define MY_PARENT_NODE_ID 0
    #define   MY_PARENT_NODE_IS_STATIC // dont allow search for repeater
    // Enable and select radio type attached
    #define MY_RADIO_RF24
    //#define MY_RADIO_NRF5_ESB
    //#define MY_RADIO_RFM69
    //#define MY_RADIO_RFM95
    #include <MySensors.h>
    #include <SPI.h>
    #define SENSOR_INFO "Test sensor"
    //#define NODE_ID 200
    #define CHILD_ID 1
    int STATE = 10;
    // Initialize motion message
    MyMessage msg(CHILD_ID, V_TRIPPED);
    void setup() 
      //begin(NULL, NODE_ID, false);
      sendSketchInfo(SENSOR_INFO, "1.1");
      present(CHILD_ID, S_DOOR); 
    void loop()
       if (isTransportReady())
            //  uplink OK
             Serial.println ("Tranport Ready");  
      #ifdef MY_DEBUG
    // Change state ready for next time
        if (STATE==10) { 
        else if (STATE==20){
        (STATE=10) ;
         delay(5000); // Wait 5 seconds

  • Mod

    @grumpazoid if you by ”response” mean the nrf24 hardware acknowledgement, then yes. Your description is correct.

    I’m asking because response could mean many things. For example, the gateway could have code in its receive() that sends a new MySensors message in response.

  • @mfalkvidd Thanks. Yes that is indeed what I mean. I just wanted to make sure my understanding was correct before going any further. I am over obsessing really but it is now a bit of a challenge. I went about 24hrs without a a single missed message then just a couple of hours ago started getting lots. I am of course guessing as some local interference being the most likely. Will try another channel number when I can. I have however found a couple of errors in my sketches that need changing - I have been using delay instead of wait and also I have been pointlessly sending some serial prints.

  • On my test node I have enabled Echo and am using if (message.isEcho())
    It is working.

    I have searched and searched and looked at the API docs but am still unclear :

    If the node sends a value, should it be able to read that same value back in the echoed message.

    I know I can use message.sender , message.type etc, but how would I print the whole echoed message and/or the echoed value.

Log in to reply

Suggested Topics