How to achieve NRF52840 ESB Maximum data rate

As part of a university project I am trying to read an analog signal and transmit it at the maximum data rate over ESB. But I cant seem to get above 1700kbps without any of my payload writes failing. I have disabled acking, I am using the highest bitrate, lowest CRC and fast ramp up. Are there specific timing settings that I am missing or does anyone else have any experience trying to achieve this feat. (at the moment my timing settings are linked to ADC acquisition rate and increasing the rate above a certain amount causes payload_write issues). Aplogies if this has been properly answered before but I have tried searching.I am using the NRF Connect SDK. I am looking to get as close to 2000kbps with minimal latency.

Included is my ESB config and conf settings.

config.protocol = ESB_PROTOCOL_ESB_DPL;
config.retransmit_delay = 10;
config.retransmit_count = 1; // Default retransmit count
config.tx_output_power = ESB_TX_POWER_8DBM;
config.bitrate = ESB_BITRATE_2MBPS; // Fixed bitrate
config.event_handler = event_handler;
config.mode = ESB_MODE_PTX;
config.selective_auto_ack = true;
config.payload_length = 252
config.crc = ESB_CRC_8BIT; // NRF_ESB_CRC_OFF
config.use_fast_ramp_up = true;

CONFIG_NCS_SAMPLES_DEFAULTS=y
CONFIG_ESB=y
CONFIG_DK_LIBRARY=y
CONFIG_CLOCK_CONTROL=y

CONFIG_ESB_NEVER_DISABLE_TX=n
CONFIG_ESB_RX_FIFO_SIZE=256
CONFIG_ESB_TX_FIFO_SIZE=256
CONFIG_ESB_MAX_PAYLOAD_LENGTH=252

# Enable logging subsystem
CONFIG_LOG=y


# Enable logging for the ESB module
CONFIG_ESB_LOG_LEVEL_DBG=y
# Enable heap memory pool for dynamic memory allocation
CONFIG_HEAP_MEM_POOL_SIZE=16384

CONFIG_NRFX_SAADC=y
CONFIG_NRFX_PPI=y
CONFIG_NRFX_TIMER0=y
CONFIG_NRFX_TIMER2=y
Parents
  • Hi,

     

    You will never reach the throughput equal to the on-air data rate, as there will be overhead in general (addressing, ramp-up etc).

    When you setup your ESB configuration, this needs to match on both PRX and PTX.

    Have you set the .noack member to the struct esb_payload variable that you're using? To enable noack, you need to set this in the tx_payload variable:

    tx_payload.noack = true;
    err = esb_write_payload(&tx_payload);
    ...

     

    Kind regards,

    Håkon

  • Hi Hakon, thanks for your reply. I set .noack equal to 1 before each esb write and I have selective auto ack enabled on the PRX aswell, when i was troubleshooting the issue i tried using 32 byte packets and sending them faster, a friend has been able to achieve rates of 1650kbps using an NRF24L01 and an FPGA with 32 byte packets, but I could only send around 900kbps with that packet size so I'm wondering if the issues are with my configuration/code or if it is just the difference in overhead between the old and new devices. Please let me know if there is any information i can give you to help. 

    Doing some quick maths, 252 payload + crc byte + 4 prefix/address bytes = 257bytes

    at 2000kbps on air time = 1010.5us, with 40us ramp up, this becomes 1050.5us period or 0.952khz

    0.952*252*8=1919.2 kbits per second theoretically, I am just trying to see where i could find the extra 200 or 100kbps to squeeze every last bit out of the protocol. Again I appreicate your help, I am an embedded novice so I could easily be doing something very simple wrong.

    My code is based on the PRX and PTX examples and has addresses as follows so maybe I am just making the addresses too long?

    	uint8_t base_addr_0[4] = {0xE7, 0xE7, 0xE7, 0xE7};
    	uint8_t base_addr_1[4] = {0xC2, 0xC2, 0xC2, 0xC2};
    	uint8_t addr_prefix[8] = {0xE7, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8};

  • Hi Hakon, I dont currently have a way to measure the dynamic current, using a regular multimeter and a chopped up usb c able with the XIAO nrf52840 ptx board, i get a current of 19mA at a DC voltage of 5.12V, but i will look into the oscilloscope method listed in the docs, at the moment the maximum data rate is 1727.7kbps when the DK and SEED XIAO nrf52840 are quite close together 5cm? At 1m the data rate drops below 1500kbps. This is still using a 4 byte address.

  • Hi,

     

    Remember that there is processing that is required here as well, in terms of executing ISRs/setting up timers, etc.

    I setup a test, with a 1 second timer interrupt, where I count the amount of bytes sent.

    I am seeing 219240 byte per second, which is 1753920 bit/s (1712 kBit/s).

     

    A bit less than you report.

     

    Kind regards,

    Håkon

  • Thanks Hakon, at least I have a sanity check on my results. I have ordered an NRF54L15 which I hope will give me faster rates.

  • Hi,

     

    Happy to help out!

    nRF54L15 can do 4 MBit, so this should help wrt. the overall throughput you need.

     

    Kind regards,

    Håkon

  • Just to follow this up, after some very quick testing on the new boards with 4MBIT  i could achieve 3224 kbps

Reply Children
  • Hi,

     

    Great to hear!

    I see approx. the same throughput with 4 MBit mode.

     

    Kind regards,

    Håkon

  • Hi,

    could you please provide the prj.conf for those tests? I am using a nRF54L15dk, sending 66 bytes every 320µs and this is pretty much all I can achieve.

    This is my prj.conf:

    CONFIG_NCS_SAMPLES_DEFAULTS=y
    CONFIG_ESB=y
    CONFIG_DK_LIBRARY=y
    CONFIG_CLOCK_CONTROL=y
    CONFIG_ESB_MAX_PAYLOAD_LENGTH=252
    CONFIG_ESB_TX_FIFO_SIZE=2
    CONFIG_ESB_RX_FIFO_SIZE=0
    #CONFIG_ESB_NEVER_DISABLE_TX=y

    # Gdb related configs
    CONFIG_DEBUG_INFO=y
    CONFIG_DEBUG_THREAD_INFO=y

    # gcc setting
    CONFIG_DEBUG_OPTIMIZATIONS=y

    CONFIG_LOG_MODE_DEFERRED=y
    CONFIG_ESB_MAX_PAYLOAD_LENGTH=66

    When I enable CONFIG_ESB_NEVER_DISABLE_TX=y the transmission crashes immediately.

    This is my esb_init

        struct esb_config esb_config = ESB_DEFAULT_CONFIG;

        /* PTX Mode, only send. */
        esb_config.protocol = ESB_PROTOCOL_ESB_DPL;
        esb_config.mode = ESB_MODE_PTX;
        esb_config.bitrate = ESB_BITRATE_4MBPS;
        esb_config.crc = ESB_CRC_OFF;
        esb_config.use_fast_ramp_up = true;
        esb_config.payload_length = sizeof(audio_message_t);

        /* No Ack, no retransmit. */
        esb_config.retransmit_count = 0;
        esb_config.retransmit_delay = 0;
        esb_config.selective_auto_ack = true;

        /* TX mode. */
        esb_config.tx_mode = ESB_TXMODE_AUTO;

        esb_config.event_handler = event_handler;

        rc = esb_init(&esb_config);

    and this is the feeding of data into the esb:

            k_sem_take(&tx_sem, K_FOREVER);

            /* Send package. */
            memcpy(tx_payload.data, &message, sizeof(audio_message_t));
            int rc = esb_write_payload(&tx_payload);
            if (rc) {
                dk_set_led(PACKET_HANDOVER_ERROR, 1);
            } else {
                if (packets_handed_over % 2) {
                    dk_set_led(PACKET_HANDOVER, 0);
                } else {
                    dk_set_led(PACKET_HANDOVER, 1);
                }
            }
            packets_handed_over++;

    Can you see anything stupid here?

    Best regards

    Stefan

  • Hi Stefan,

     

    Looks like you are using auto-ACKing, which will be a TX->RX transition, which will take a bit more time on-air.

    TX timing is approx. 40 + 2*(66 + ~10 bytes overhead) -> 192 us, so 320 us in total is not that farfetched, especially if you are using ACK payload as well.

    Try testing with a larger on-air payload, ie. 66*3 bytes, and see if you get a more acceptable overall throughput.

     

    PS: you have posted in a older thread. If you still see issues, I would recommend that you create a dedicated thread on this matter.

    Kind regards,

    Håkon 

  • Hi Håkon,

     thank you for your response. I chose to extend this thread as it fitted perfectly to what I was looking for. I hate to jump from post to post (sometimes they are not even linked) to find an answer.

    I tried to enable TX only by setting

        esb_config.mode = ESB_MODE_PTX;

    in the configuration. What else should I do to disable any RX and acknowledging?

    Best regards

    Stefan

  • Hi,

     

    Please see the very first response on how to setup the .noack functionality:

     RE: How to achieve NRF52840 ESB Maximum data rate  

     

    Kind regards,

    Håkon

Related