NRF24L01+ and Auto Ack

Thread Starter

Futurist

Joined Apr 8, 2025
721
I have a working setup with a transmitter and two receivers running my code, each board is a Nucleo and has an attached NRF24L01+ device.

This is working, the mode is basic no fancy acks or "shockburst" stuff, the transmitter and receivers each get an interrupt as one would expect after sending or receiving data packets. I have a test xmit app and a test rx app on the other two boards, the transmitter loops sending a message on channel 100, wait 250 ms send one on channel 110, wait 250 ms and repeat.

Each receiver is identical but one listens on channel 100 and the other on channel 110 so each receiver sees a message every 500 ms, the board briefly flashes the onboard green led every time it receives a message.

I want to now explore auto acks and began by simply enabling the auto ack feature in the receiver for the data pipe it is listening on.

I figured that this should have no effect, the transmitter isn't expecting any ack and the receiver will simply automatically send one, a waste but the working boards should continue to work.

They don't, changing the receiver by just enabling auto ack for the pipe it is using, seems to break it and no messages are received and no interrupts are generated any more.

Disabling the auto ack again, makes it work again.

So why would enabling auto ack on a receiver cause the working code to stop working? how can simply enabling the transmission of an ack message, stop the receiver from working?

I enable the auto ack by setting the bit ENAA_P1 in this NRF register:

1746049952065.png

This is the complete manual.
 
Last edited:

Thread Starter

Futurist

Joined Apr 8, 2025
721
As is often the case, documentation is key. I studied numerous articles and blogs last night and gradually concluded that all NRF24 radio comms is either using Shockburst protocol or Enhanced Shockburst, period.

I had formed the impression that these were optional and without using either, the device operated in a more basic mode.

I now think I was wrong, unless one is operating in ESB, then one is operating in SB and the data packet format is quite different, therefore by enabling Auto Ack on my receiver (only available in ESB) the receiver expects ESB packets and simply will never recognize SB packets and therefore will never trigger a RX_DR interrupt unless the transmitter also operates in ESB.

I think this explains my observations, I will verify later...
 

MrChips

Joined Oct 2, 2009
34,629
I have yet to locate my written notes. I believe I am using ESB with AutoAck.

C:
//---------------------------------------------------------------
// Initialization
//---------------------------------------------------------------


void InitRF(void)
{
   // initialize rf parameters
  
  /*******************************
  // CONFIG register
  #define RF24_MASK_RX_DR  BIT6
  #define RF24_MASK_TX_DS  BIT5
  #define RF24_MASK_MAX_RT BIT4
  #define RF24_EN_CRC      BIT3
  #define RF24_CRCO        BIT2
  #define RF24_PWR_UP      BIT1
  #define RF24_PRIM_RX     BIT0
  ********************************

  /* Private library variables */
  // uint8_t rf_feature;  
  // declared in nrf24.c
  // Used to track which features have been enabled

  uint8_t rf_config;
  uint8_t rf_addr_width;
  uint8_t rf_speed_power;
  uint8_t rf_channel;

  // config in TX mode, all IRQ masked
  rf_config      = RF24_TX_CONFIG;
  rf_addr_width  = 5;   // 5 bytes
  rf_speed_power = RF24_SPEED_2MBPS | RF24_POWER_0DBM;
  rf_channel     = CHANNEL;  //2400MHz + CHANNEL
  
// speed settings
// RF24_SPEED_250KBPS    0x20
// RF24_SPEED_1MBPS      0x00
// RF24_SPEED_2MBPS      0x08

// power settings
// RF24_POWER_0DBM        0x06
// RF24_POWER_MINUS6DBM   0x04
// RF24_POWER_MINUS12DBM  0x02
// RF24_POWER_MINUS18DBM  0x00

  msprf24_enable_feature(RF24_EN_DPL);      // Dynamic payload size capability (set with msprf24_set_pipe_packetsize(x, 0))
  msprf24_enable_feature(RF24_EN_DYN_ACK);  // Ability to use w_tx_payload_noack()
  
  msprf24_set_config(rf_config);
  msprf24_set_speed_power(rf_speed_power);
  msprf24_set_channel(rf_channel);
  msprf24_set_address_width(rf_addr_width);
  
  msprf24_open_pipe(0,1);     // AutoAck enabled
  msprf24_set_pipe_packetsize(0,0);
  
  // setup TX and RX address
  w_tx_addr(My_Addr);
  w_rx_addr(0, My_Addr);  //pipe0 address
  
  w_reg(RF24_SETUP_RETR, 0x3F);  // ARD_ARC

  w_reg(RF24_EN_AA, 0x01);  // Auto Ack on pipe 0
  w_reg(RF24_DYNPD, 0x01);  // enable Dynamic Payload on pipe 0
  
}
 

nsaspook

Joined Aug 27, 2009
16,255
This blog post from Nordic was helpful, gave me a 20,000 ft view of the land.

Intro to ShockBurst/Enhanced ShockBurst

and this article too that I only stumbled upon after weeks of working with this device, perhaps the most useful document of all that are out there:

Enhanced ShockBurst (ESB)
I love that name ShockBurst for mainly Plain Jane radio packet networking we used back in the 70's for stacom networks on old UHF birds that radio pirates are still using the transponders on.
https://www.globalsecurity.org/intell/library/reports/2001/compendium/SSIXS.htm

https://en.wikipedia.org/wiki/ALOHAnet

1746120498975.png
 
Last edited:

Thread Starter

Futurist

Joined Apr 8, 2025
721
Well I am now stumped so taking a break.

I have updated my library code to exploit ESB mode and my test transmitter sends data and my test receiver receives that data,

However despite me triple checking all of the settings at each end, I get a problem.

After the transmitter sends it gets an expected interrupt but the TX_DS flag is not set and the MAX_RT is set indicating that no Ack was received by the transmitter.

However the data was received by the receiver.

I checked all of the relevant registers and tried varying payload size, and power levels and data rates but see the same behavior, successful reception of data packets but not reception of corresponding Acks by the transmitter.
 

Thread Starter

Futurist

Joined Apr 8, 2025
721
I read about fake NRF24L01+ chips flooding the market, Boards that seems to work to some degree some of the time under some circumstances can nevertheless be clones, and not made by Nordic and not identical.

How true this is I can't say but if this is the explanation for me not seeing acks, then what's the point!
 

Thread Starter

Futurist

Joined Apr 8, 2025
721
I have a support function (several) that reads all registers into a large structure, this is useful for debugging, the register names and member field names are all the same as those in the documentation too (this is the receiver just FYI).

1746140592949.png

So I've studied every register on both the TX and RX and cannot see anything wrong, yet despite messages flowing nicely the TX is always being told that no ack was received even after 15 retries (that max allowed).
 

MrChips

Joined Oct 2, 2009
34,629
Ah, debug! Yes.
I had to do the same thing. I had to create a debug function that captured and displayed all the nRF24 registers.
I will see if I had the same problem.
 

nsaspook

Joined Aug 27, 2009
16,255
Well I am now stumped so taking a break.

I have updated my library code to exploit ESB mode and my test transmitter sends data and my test receiver receives that data,

However despite me triple checking all of the settings at each end, I get a problem.

After the transmitter sends it gets an expected interrupt but the TX_DS flag is not set and the MAX_RT is set indicating that no Ack was received by the transmitter.

However the data was received by the receiver.

I checked all of the relevant registers and tried varying payload size, and power levels and data rates but see the same behavior, successful reception of data packets but not reception of corresponding Acks by the transmitter.
I assume you do have the receiver in the mode to need and send Acks. There is the option for the receiver to be in stealth mode , emission control (no Acks after good packets received).

Broadcasting mode.
 

Thread Starter

Futurist

Joined Apr 8, 2025
721
I assume you do have the receiver in the mode to need and send Acks. There is the option for the receiver to be in stealth mode , emission control (no Acks after good packets received).

Broadcasting mode.
Yes one can disable auto ack when otherwise operating in ESB mode, but I have that register set to auto ack on the transmitter's address. Clearly the transmitter is expecting an ack because it is aware when it exceeds max retries, but as for the receiver...

I really don't want to piss about with wondering if the chip on the board is one of the notorious "fakes".

I either have one or more registers set incorrectly or a bug in the code (but the code is quite clean and was tidied and refactored before I tried to start using ESB, besides the ack management is completely invisible to the code, it is managed entirely by the chip) or a true hardware anomaly.

I've tried varying:

  • The RF channel
  • The RF power
  • The RF data rate
  • The max number of retries
  • The wait-for-ack interval
  • The length of the test data packets

None of the changes led to any change in observed behavior, data is always received and the transmitter always sees the MAX_RT status when the interrupt occurs.

I have two devices setup as receivers on their own dedicated Nucleo boards, I will swap it today and see if the other receiver behaves the same way, but that won't really tell me much.

I wish I had a way to see the RF being generated by these devices, but at 2.4 GHz a hobbyist like me has no such technology on his bench!

My instinct is telling me that the ack is truly not being generated but why...

I wonder if the devices have firmware that I can update...

Tick Tock, Tick Tock...

Nope, there is no concept of firmware on these devices and certainly no mechanism for altering its functionality.

I've learned a great deal about this device and in a position to really solidify and finalize my little library now, but this behavior is a showstopper.
 
Last edited:

Thread Starter

Futurist

Joined Apr 8, 2025
721
Nope, changing the address as mentioned in that post, did not lead to any improvement. But it is odd that he got it working just by changing the address...let me try some more addresses.
 

nsaspook

Joined Aug 27, 2009
16,255
Do you need ESB at this point in the development process? Premature optimization is the root of all evil, in programming.
 

Thread Starter

Futurist

Joined Apr 8, 2025
721
Do you need ESB at this point in the development process? Premature optimization is the root of all evil.
No, not in the sense this is a work commitment or anything, this is just me working to build my own library for personal playing around.

If I avoid ESB (and thus simply rely on SB) it works very well, I can send and receive data fine. But since ESB supports acks which is a significant capability to have, I wanted to ensure the library supported that and made it easy to use.

When something like this crops up I need to understand it, need to know if I'm doing something wrong (and hence have subtle bugs lurking in code or hardware setup) because if another weird issue comes up I won't know whether that is a true issue or some side effect of an existing yet undiscovered bug I have.

This should just work, it is a core aspect of the device.
 

nsaspook

Joined Aug 27, 2009
16,255
It would be odd if regular SB never used Acks in the physical level one protocol. I can see a, broadcast only, setting as an option but it's rarely the only option.
From what I can tell from a quick read, the API Acks are like level two types (unlikely the OEM NRF24L01+ API has the full ISO protocol): https://en.wikipedia.org/wiki/Data_link_layer

I've made sliding window protocols where you didn't need a ack for every on the wire/air packet. Both sides keep track with packet sequences and could send a single packet to ack all packets received with nacks for those missed as a request for retransmission.
https://en.wikipedia.org/wiki/Sliding_window_protocol#:~:text=By placing limits on the,using fixed-size sequence numbers.

I've no idea what the on the air protocol is for your device

I would need to use something like my RF hack 1 to take a look.
https://greatscottgadgets.com/hackrf/one/
 
Last edited:

Thread Starter

Futurist

Joined Apr 8, 2025
721
It would be odd if regular SB never used Acks in the protocol. I can see a, broadcast only, setting as an option but it's rarely the only option.

I've made sliding window protocols where you didn't need a ack for every packet. Both sides keep track with packet sequences and could send a single packet to ack all packets received with nacks for those missed as a request for retransmission.
https://en.wikipedia.org/wiki/Sliding_window_protocol#:~:text=By placing limits on the,using fixed-size sequence numbers.

I've no idea what the on the air protocol is for your device
Its discussed here by a Nordic engineer with some historical background, I think a guru like you'll find it interesting.

https://devzone.nordicsemi.com/nord.../posts/intro-to-shockburstenhanced-shockburst

I'm running a soak test, TX and RX looping sending messages at a rate of 20/second, TX and RX each briefly pulse the onboard LED once per msg, I have a breakpoint set so that if any transmission gets an ack it will break in debug.
 

Thread Starter

Futurist

Joined Apr 8, 2025
721
This is curious, my breakpoint (line 110 below) got hit - that is I got an interrupt and the MAX_RT flag was not set (expected if an ack was received).

However the TX_DS (data sent) flag was also not set, no status flags at all were set:

1746209546644.png

So I wonder under what circumstances the interrupt can be generated but no status flags are set...
 
Last edited:

nsaspook

Joined Aug 27, 2009
16,255
Its discussed here by a Nordic engineer with some historical background, I think a guru like you'll find it interesting.

https://devzone.nordicsemi.com/nord.../posts/intro-to-shockburstenhanced-shockburst

I'm running a soak test, TX and RX looping sending messages at a rate of 20/second, TX and RX each briefly pulse the onboard LED once per msg, I have a breakpoint set so that if any transmission gets an ack it will break in debug.
Looks like the main thing they did with ESB was adding sliding windows NAKS.
1746214352742.png

Don't know if you get a level 1 physical or level 2 logical Ack/Nak .
 
Last edited:
Top