[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 

    Thanks, I was now able to access the file. 

    I can't really see any obvious issues with the code, but if you can share the corresponding trace for the PRX also that would be interesting. 

    If you can, please include the IRQ  and CE lines in the trace as well. 

    One odd thing is that there seems to be two configuration phases, about 5ms apart, but possibly this is just how the library is designed. 

    If the PRX trace doesn't show anything interesting either I will try to hook up some nRF24L01+ modules here and see if I can reproduce the issue. 

    Best regards
    Torbjørn

  • Hello,

    I've added 2 trace files in my drive for which I granted you access with a message. One for the TX with the CE from the start, one for the RX with the CE from the start.

    Could you also provide me with some manufacturers.

    I found the manufacturer Wellman and the product WPI322. Is it worth to buy 2 devices?

    Best regards,

    Pascal

  • 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

Reply
  • 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

Children
  • 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

  • Hello,

    I wrote the code based on the above sequence for the PRX and PTX. I only add the reading of the received frame in the PRX sequence.

    It works fine.

    The PTX sends the frame every 500ms and then the PRX receives it perfectly at the same rate.

    Do you want to get SPI captures, from PRX, from PTX?

    What are the next steps?

    Best regards,

    Pascal

  • Hello,

    Today, I got some errors during the auto ACK.

    I share with you the capture file with CE from the start : https://drive.google.com/file/d/1qYhx9URnSculNCKtLedLqEY8i-KrhAHp/view?usp=sharing

    Best regards,

    Pascal

  • Hello,

    I share with you a capture file with CEs of SPI for both PTX and PRX from the start : https://drive.google.com/file/d/1mi6D-tu33AO6Ovo6XV2cg7CNmShpeRCI/view?usp=sharing

    At 16s141ms800, there is a fail of the auto ACK (last status equals to 0x1E).
    Just before, at 16s141ms100, this is the TX data packet corresponding to the fail auto ACK. The last byte of this data is 0x19 and can be used to search in the PRX capture if the corresponding data has been received.
    The last byte of the TX data packet is increased by 1 at each transfer, so that this last byte is different from one transfer to the previous/next one.
    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.

    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?

    Best regards,

    Pascal

Related