[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
  • Hi 

    Is anything received by the ESP32 board?

    The nRF24L01+ is rated to 3.6V maximum, so I think the first order of business would be to test this on boards that support a lower supply voltage. Correct behavior can not be guaranteed when you're running the nRF device at 5V, and it might damage the module over time. 

    Best regards
    Torbjørn

  • Hello,

    First, the nRF24L01+ is not supplied with the 5V of transmitter Arduino, but with 3.3V.

    Second, with the channel set to 125, the receiver ESP32 is not receiving at all. If I remove the call to setChannel, the ESP32 is receiving around 20% of the frame and in that case, the Arduino is getting the ACK.
    So, 80% of frame are lost with no ACK.

    As an information, there is a 10µF capacitor at the pin GND/3.3V of the receiver nRF24L01+ and a 100µF capacitor for the transmitter nRF24L01+.

    Best regards.

  • Hi Pascal

    Do you have a link to the WPI322 module? 

    Sparkfun made a module called WRL-00691 which can be had from mouser (and maybe others), and there is also the official Nordic module which can be found some places (such as here). 

    I was able to download your traces. I need some more time to look into it, but will do my best to provide an update by the end of the week. 

    Best regards
    Torbjørn

  • Hello,

    I bought the official Nordic module (NRF24L01P-MODULE-PCB).

    I got the same result : no ACK received by the transmitter from the receiver, and receiver losing frames.

    Best regards,

    Pascal

  • Hi Pascal

    Do you have the capability to send raw SPI commands to the module, bypassing the L01+ library? 

    It should be possible to enable the module and send packets with ACK using only a handful of SPI commands. If you are able to bypass the library and control the SPI and GPIO directly I can suggest a short test sequence that can verify that the hardware is OK. Then we have to figure out what is different when using the library, and (ideally) how to make the library work correctly. 

    Best regards
    Torbjørn

  • Hello,

    I agree with your proposal.

    Let me know the data you want me to send/receive on the SPI as a test sequence and what result to provide to you.

    Best regards,

    Pascal

  • Hi Pascal

    Probably the most stripped down sequence for establishing communication goes something like this:

    PTX

    Set CONFIG register to 0x0E  (PRWUP = 1, CRC 16 bit, PRIM_RX 0)
    Write 0x20, 0x0E

    Add a 2ms delay

    Now the transmitter should be ready. To send a packet, start by uploading a packet
    Write 0xA0, 0x01, 0x02, 0x03, 0x04 (only the first byte is important, the remaining bytes can be whatever you like)

    Pulse the CE line for 100us in order to start the transmission

    In a loop, read the STATUS register and wait for bit 4 or 5 to be set
    Write 0x07, 0x00 and check the return value. If nothing happened the return value should be 0x0E. Once you get an interrupt it should be 0x2E (TX successful) or 0x1E (TX failed). 

    To prepare for another packet, clear the IRQ bits by writing 0x70 to the STATUS register:
    Write 0x27, 0x70

    PRX

    Set CONFIG register to 0x0F  (PRWUP = 1, CRC 16 bit, PRIM_RX 1)
    Write 0x20, 0x0F

    Add a 2ms delay

    Configure the payload length on pipe 0 to 4 bytes (or whichever number of bytes you plan to send from the PTX side)
    Write 0x31, 0x04

    Set the CE line high permanently to enable the receiver

    In a loop, read the STATUS register and wait for bit  6 to be set
    Write 0x07, 0x00 and check the return value. If nothing happened the return value should be 0x0E. Once you receive a packet it should be 0x40.

    To prepare for another packet, clear the IRQ bits by writing 0x70 to the STATUS register:
    Write 0x27, 0x70

    Would you be able to follow this procedure and see if the status register changes on either side, indicating a successful transaction? 

    There is a bit more work if you want ot read out the payload on the RX side, but the main point at the moment is to verify that your hardware works properly. 

    Best regards
    Torbjørn

Reply
  • Hi Pascal

    Probably the most stripped down sequence for establishing communication goes something like this:

    PTX

    Set CONFIG register to 0x0E  (PRWUP = 1, CRC 16 bit, PRIM_RX 0)
    Write 0x20, 0x0E

    Add a 2ms delay

    Now the transmitter should be ready. To send a packet, start by uploading a packet
    Write 0xA0, 0x01, 0x02, 0x03, 0x04 (only the first byte is important, the remaining bytes can be whatever you like)

    Pulse the CE line for 100us in order to start the transmission

    In a loop, read the STATUS register and wait for bit 4 or 5 to be set
    Write 0x07, 0x00 and check the return value. If nothing happened the return value should be 0x0E. Once you get an interrupt it should be 0x2E (TX successful) or 0x1E (TX failed). 

    To prepare for another packet, clear the IRQ bits by writing 0x70 to the STATUS register:
    Write 0x27, 0x70

    PRX

    Set CONFIG register to 0x0F  (PRWUP = 1, CRC 16 bit, PRIM_RX 1)
    Write 0x20, 0x0F

    Add a 2ms delay

    Configure the payload length on pipe 0 to 4 bytes (or whichever number of bytes you plan to send from the PTX side)
    Write 0x31, 0x04

    Set the CE line high permanently to enable the receiver

    In a loop, read the STATUS register and wait for bit  6 to be set
    Write 0x07, 0x00 and check the return value. If nothing happened the return value should be 0x0E. Once you receive a packet it should be 0x40.

    To prepare for another packet, clear the IRQ bits by writing 0x70 to the STATUS register:
    Write 0x27, 0x70

    Would you be able to follow this procedure and see if the status register changes on either side, indicating a successful transaction? 

    There is a bit more work if you want ot read out the payload on the RX side, but the main point at the moment is to verify that your hardware works properly. 

    Best regards
    Torbjørn

Children
Related