[nRF24L01+] How to use Auto Acknowledge

Hello all,

1. I have a transmitter (Arduino Pro Mini 5V) connected to a nRF24L01+. I use the following code to set up the radio.

    radio.begin();
    radio.setChannel(125);
    radio.setPALevel(RF24_PA_LOW);
    radio.setDataRate(RF24_1MBPS);
    radio.setAddressWidth(5);
    radio.setAutoAck(true);
    radio.setRetries(5, 3);
    radio.setPayloadSize(sizeof(radio_data));
    radio.openWritingPipe(address);
    radio.stopListening();

2. I have a receiver (ESP32) coonecter to a nRF24L01+. I use the following code to set up the radio.

    radio.begin();
    radio.setChannel(125);
    radio.setPALevel(RF24_PA_LOW);
    radio.setDataRate(RF24_1MBPS);
    radio.setAddressWidth(5);
    radio.setAutoAck(true);
    radio.setRetries(5, 3);
    radio.setPayloadSize(sizeof(radio_data));
    radio.openReadingPipe(0, address);
    radio.startListening();

3. When I want to transmit data, I call the function write.

The return of the call to the function write is always false, meaning that auto acknowledgement goes wrong.

Have you any idea of what I did wrong ?

Thanks for your help.

Parents Reply Children
  • Hi Pascal

    _pascalh said:
    If you scrolls down to look at the RX SPI capture, you can see that the data packet with last byte equals to 0x19 is read from the nRF24L01 just before 16s141ms800.

    If I understand your question correctly you are wondering why the PTX is getting the MAX_RT (TX failed) interrupt even when the packet is received by the PRX?

    This can happen whenever the original packet from the PTX to the PRX is received by the PRX, but the ACK packet back to the PTX is lost. In this case the PRX will report an RX interrupt and the PTX will report the MAX_RT interrupt. The normal way to handle this is to retransmit the packet from the PTX, then the PRX will read it as a retransmission and simply ACK the packet again without adding it to the RX FIFO (or raising the RX interrupt again). 

    Figure 24 on page 48 of the datasheet shows a variant of this scenario, where neither of the ACK packets sent by the PRX are received by the PTX, and the PTX will report the MAX_RT interrupt even if the packet was received by the PRX. 

    Increasing the retransmit counter (ARC) in the SETUP_RETR register will reduce the chance of this happening, since the PTX will attempt more times before issuing the MAX_RT interrupt.

    Looking at your trace it doesn't seem like this register is set to a higher value. 

    _pascalh said:
    Additional question: do you know why at 4s612ms440 there is a status set to 0x0C on the RX MISO, which does not seem to correspond to something correct?

    Interesting, I have never seen this behavior before. It seems the STATUS register is being read just as a packet is received, and an intermediary value between 0x0E and 0x40 is returned. This might be a side effect of reading the STATUS register at such a high rate (when using the IRQ line you typically only read the STATUS register once IRQ goes low). 

    Either way it seems the library is using the second byte on MISO to determine status, so this shouldn't have a negative effect on the application.  

    Best regards
    Torbjørn

  • Hello,

    I modify the PTX software as follow:

     - set SETUP_RETR to 0x1A

    I modify the PRX software as follow:

     - use the IRQ instead of polling the status register to know if there is data in the RX FIFO

    I captured both SPI for PRX and PTX from the start:

    https://drive.google.com/file/d/1y1i61q-qweEQPORg_KDgUk9I_-D6kJQd/view?usp=drive_link

    Every thing seems to be ok.

    Let me know your analysis.

    Best regards,

    Pascal

  • Hi

    Using the IRQ line is a good idea, then you don't have to waste time and power checking the status register continuously. 

    If possible I would recommend doing it on the PTX side also. 

    One thing I noticed is that you don't check the status register or the length of the RX payload after the IRQ line goes low, before you read out the payload. This should work fine if you will only ever use a static payload length, but if you ever want to be able to send packets with a dynamic payload length then you need to add some code on the PRX side to check the length of the payload before you read it out. 

    Best regards
    Torbjørn

Related