Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Speeding up ESB on nrf52

I have to stream packets from an nrf52 to an nrf24 at a 30 kHz rate using ESB. But when I try to do this, the receiver only receives some of the packets. I don't believe the problem is with the receiver, as I have verified with a logic analyzer that when I try to read the FIFO_STATUS register, the RX_EMPTY bit is set. This leads me to believe that the packets are not being sent by the transmitter. If I set the transmission rate to 2 kHz, the receiver will receive every packet. Faster data rates, some packets will never arrive.

My attention has turned to the nrf_esb library. Is there any limitation of the software ESB implementation that would prevent me from sending packets at 30 kHz? This is how I configure the nrf52:

    uint8_t base_addr_0[4] = {0xE7, 0xE7, 0xE7, 0xE7};
    uint8_t base_addr_1[4] = {0xC2, 0xC2, 0xC2, 0xC2};
    uint8_t addr_prefix[6] = {0xE7, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6}; // nrf24 has 6 pipes

    nrf_esb_config_t nrf_esb_config         = NRF_ESB_LEGACY_CONFIG;
    nrf_esb_config.protocol                 = NRF_ESB_PROTOCOL_ESB_DPL;
    nrf_esb_config.retransmit_delay         = 500;
    nrf_esb_config.mode                     = NRF_ESB_MODE_PTX;
    nrf_esb_config.event_handler            = handler;
    nrf_esb_config.retransmit_count         = 3;
    
    nrf_esb_init(&nrf_esb_config);
    nrf_esb_set_base_address_0(base_addr_0);
    nrf_esb_set_base_address_1(base_addr_1);
    nrf_esb_set_prefixes(addr_prefix, 6); // 6 pipes

    uint8_t pipe_mask = 1;//0x21; // enable pipes 0 and 5

    nrf_esb_enable_pipes(pipe_mask);

This configuration works fine sending packets less often. I am considering if I need to use the radio directly, and skip the ESB library, if there is some overhead. I found that the GPIO library is significantly slower than controlling GPIO pins directly through registers. That's why I'm suspicious of the efficiency of this library. Thank you!

Edit: I've found that it takes about 350 us between when nrf_esb_write_payload is called, and when NRF_ESB_EVENT_TX_SUCCESS is received. That would suggest a maximum packet rate of 2.85 kHz, right?

Edit 2: These packets are sent with setting noack=true on the transmitter, but there is a heartbeat packet that requires an ACK at 1 Hz

  • Hi,

    These packets are sent with setting noack=true on the transmitter, but there is a heartbeat packet that requires an ACK at 1 Hz

    NRF_ESB_LEGACY_CONFIG sets selective_auto_ack=false, so noack is ignored, and all packets are therefore acked.

    Edit: I've found that it takes about 350 us between when nrf_esb_write_payload is called, and when NRF_ESB_EVENT_TX_SUCCESS is received. That would suggest a maximum packet rate of 2.85 kHz, right?

    Yes, that sounds about right with your configuration and the ESB implementation in the nRF 5SDK.

    The time it takes to transmit, receive and process a packet can be broken down as follows:

    - Radio ramp up
    - The on-air time of the packet
    - The transmission delay of the packet (negligible at short range since the radio waves move at the speed of light)
    - The processing delay in the receiver

    For compatibility reasons the default radio ramp up time is 130us, which is identical with older ESB radios such as the nRF24L01+. In the nRF52 and later radios there is a faster ramp up available taking the ramp up time down to 40us, but you need to enable it explicitly in order to take advantage of it.  As far as I can see, the ESB library in the nRF5 SDK always disables the radio after a packet is transmitted, so the radio needs to ramp-up for each packet sent. In the old SB(Shockburst) mode you might be able to send several packets back-to-back (which means you don't have to use 130 us powering up the radio), but at least on the nRF24LE1 you still need to enter standby mode at least every 4ms, or the TX could stop working due to PLL drift (from page 19 in the nRF24LE1 PS).

    sending packets at 30 kHz

    So that means a new packet each 33.33333 us...

    Let's take the smallest possible ShockBurst packet(SB only supports 1Mbps): (ESB also have a 9 bit packet control field)
    1 byte preamble, 3 byte address, 1 byte payload ,1 byte CRC = 6 byte -> 6*8 = 48 bits.
    Time to transmit packet = 48 bits / 1 Mbps = 48 us..... this is with a 1 byte payload...+ you will spend a couple of us on processing as well.

    We can also take an Enhanced ShockBurst example, as an example, if you use 1 byte preamble, 5 byte address, 9-bit PCF field, 8 byte payload and 2 byte CRC in 2Mbps bitrate mode you get a total on-air time of about 70us. 

Related