Delay between sending radio messages using ESB

Hello everyone,

I am using 2 nRF52840 of nRF9160 DK to send large bulks of data (like 2MB) . My problem is that this communication have to be necesseraly delayed or it can't be completed, because at some point the TX board cannot receive the ACK from RX board and cannot complete the transmission of information. If i remove the 6ms delay after esb_write_payload the TX cannot even send the 2nd message. Could you help me ? I want to remove this delay as much as i can

I am using Enhanced Shockburst to send and receive, sending 252 bytes per package. Configured ESB to send Fixed payload length. Great part of the code came from the ESB PTX example code.

Here is the code:

typedef struct {
        uint32_t contador;
        uint8_t dados[248];
}DadosTeste;

void event_handler(struct esb_evt const *event)
{
    switch (event->evt_id) {
    case ESB_EVENT_TX_SUCCESS:
        LOG_DBG("TX SUCCESS EVENT");
        break;
    case ESB_EVENT_TX_FAILED:
        LOG_DBG("TX FAILED EVENT");
        break;
    case ESB_EVENT_RX_RECEIVED:
        if (esb_read_rx_payload(&rx_payload) == 0) {
            memcpy(&rx_Contador, rx_payload.data, 4);
        
            LOG_DBG("%d : %d", rx_payload.length, rx_Contador);
            /*
            LOG_DBG("Packet received, len %d : "
                "0x%02x, 0x%02x, 0x%02x, 0x%02x, "
                "0x%02x, 0x%02x, 0x%02x, 0x%02x",
                rx_payload.length, rx_payload.data[0],
                rx_payload.data[1], rx_payload.data[2],
                rx_payload.data[3], rx_payload.data[4],
                rx_payload.data[5], rx_payload.data[6],
                rx_payload.data[7]);
                */

            leds_update(rx_payload.data[1]);
        } else {
            LOG_ERR("Error while reading rx packet");
        }
        break;
    }
}


uint16_t qtdPacotesRecebidos = 0;

DadosTeste variavel;

int esb_initialize(void)
{
        int err;
        /* These are arbitrary default addresses. In end user products
         * different addresses should be used for each set of devices.
         */
        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};

        struct esb_config config = ESB_DEFAULT_CONFIG;

        config.protocol = ESB_PROTOCOL_ESB;
        config.payload_length = 252;
        config.bitrate = ESB_BITRATE_2MBPS;
        config.event_handler = event_handler;
        config.mode = ESB_MODE_PTX;
        config.selective_auto_ack = false;

        err = esb_init(&config);

        if (err) {
                return err;
        }

        err = esb_set_base_address_0(base_addr_0);
        if (err) {
                return err;
        }

        err = esb_set_base_address_1(base_addr_1);
        if (err) {
                return err;
        }

        err = esb_set_prefixes(addr_prefix, ARRAY_SIZE(addr_prefix));
        if (err) {
                return err;
        }

        return 0;
}

int main(void)
{
        int err;


        memset(&variavel, 0x0, sizeof(DadosTeste) );
        
        tx_payload.pipe = 0;
        tx_payload.length = sizeof(variavel) ;
        tx_payload.noack = true;

        LOG_INF("Enhanced ShockBurst ptx sample");

        err = clocks_start();
        if (err) {
                return 0;
        }

        err = esb_initialize();
        if (err) {
                LOG_ERR("ESB initialization failed, err %d", err);
                return 0;
        }

        LOG_INF("Initialization complete");
        LOG_INF("Sending test packet");

        memset(variavel.dados, 0x31, sizeof(variavel.dados));

        while (variavel.contador < 1000) {
                if (ready) {
                        printf("envia\n");
                        ready = false;
                        esb_flush_tx();

                        variavel.contador++;
                        
                        memcpy(tx_payload.data, &variavel, tx_payload.length);

                        err = esb_write_payload(&tx_payload);
                        if (err) {
                                LOG_ERR("Payload write failed, err %d", err);
                        }
                        
                        k_sleep(K_MSEC(6));
                }
        }

  • Hello,

    So I assume you have set CONFIG_ESB_MAX_PAYLOAD_LENGTH=252 here on both sides of the link.

    I can't see where the ready flag is set to true?

    Are you sure the problem is on the PTX and not the PRX?

    Kenneth

  • Hi Kenneth, thanks for replying.

    Unfortunately, this code that i posted is missing the "ready = true", at the end of the event_handler function. But the problem of the necessity of putting the delay after esb_write_payload(&tx_payload); persists

    But i managed to reduce to 3ms delay, by putting the following configuration of ESB:


    config.protocol = ESB_PROTOCOL_ESB;
    config.payload_length = ESB_MAX_PAYLOAD_LENGTH;
    config.bitrate = ESB_BITRATE_2MBPS;
    config.event_handler = event_handler;
    config.mode = ESB_MODE_PTX;
    config.selective_auto_ack = false;
    config.crc = ESB_CRC_16BIT;
    config.use_fast_ramp_up = true;

  • I think you will just have to take a step back and look at your implementation vs. the reference code also, for instance it does look that you are using .noack = true (meaning you do not want ack), are you sure you are using .noack intentionally? You are clearing the ready flag in the event_handler(), but you should ideally do this depending on the actual event, e.g. is it ESB_EVENT_TX_SUCCESS or ESB_EVENT_TX_FAILED. If it's *_FAILED, maybe you should consider resending the esb packet (not just sending the next etc). For test you can also check if 1MBPS works the same and whether using 100bytes instead of 252bytes makes any difference. Are you sending any data in reverse direction here?

    Kenneth

  • Hello Kenneth, goood morning.

    So,

    look at your implementation vs. the reference code

    I copied great part of sample ESB ptx code. Just changed to test if it gets any faster to transmit.

    are you sure you are using .noack intentionally?

    I just leaved it there to test but it is not doing anything because i'm using "config.selective_auto_ack = false" and the ESB library says that "When this feature is disabled, all packets will be acknowledged ignoring the noack field."

    You are clearing the ready flag in the event_handler()

    Yes, because now i evaluating the highest speed of transmission of the packet.

    if 1MBPS works

    It does works, but i had to increase the delay.

    100bytes instead of 252bytes

    It doens't.

    Are you sending any data in reverse direction here?

    No, i copied the code from ESB prx sample code, just changed the configuration of ESB to match with the TX board.

  • I suggest to follow the intended flow of sending a packet and wait for irq, and ensure the correct event trigger and take appropriate steps (e.g on failed (flush + send new) and on sent (send new)). 

    Kenneth

Related