This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Unable to send 1kBps of data using ble nus service on SDK12.3

I am sending 6 packets of 20B each data using ble_nus_string_send() function at every 120ms using app timer. but the function returns error BLE_ERROR_NO_TX_PACKETS. So unable to find the exact issue that is causing this issue. As far as the calculations 1kB should not be an issue.

I am also confused that why the counter value always return as 1 of p_ble_evt->evt.common_evt.params.tx_complete.count. 

these are the connection interval values I have used

#define MIN_CONN_INTERVAL MSEC_TO_UNITS(7.5, UNIT_1_25_MS)
#define MAX_CONN_INTERVAL MSEC_TO_UNITS(15, UNIT_1_25_MS)

Parents
  • Hello,

    You can check the throughput on BLE with different connection settings here.

    Using SDK12.3.0, the throughput isn't great, because this was before BLE5 came, with higher throughput options, so the throughput you are looking at is GATT server - ATT_MTU 23 - 1MB Phy, so 192kbps  = 24kBps.

    6 * 20B every 120ms = 1kBps = 8 kbps, so you are within the limits.

    The issue is that this throughput limitation is continuous, while you are sending bursts of 120 bytes, which is too much for the softdevice to store away.

    Possible solutions:

    I see that you use the nRF52832. I suggest that you go to SDK15.2.0, the latest softdevice. Here the size of ble_nus_data_send() (the new name for ble_nus_string_send) string is up to ~240bytes, depending on what you are connected to. In addition you can use 2M phy, which is more power efficient.

    Alternative solution:

    Since the issue is that you are filling up the TX buffer, you have to spread out the packets. You can still have your timer firing every 120ms, and call ble_nus_data_send() until it returns BLE_ERROR_NO_TX_PACKETS. This means that the softdevice buffer is full, and the last packet that you tried to queue is not queued successfully. However, all the packets that returned NRF_SUCCESS is successfully queued, and will be sent.

    If you look inside ble_nus_string_send(), it is actually sd_ble_gatts_hvx() that returns BLE_ERROR_NO_TX_PACKETS. You should then wait for an event called BLE_EVT_TX_COMPLETE in on_ble_evt() in main.c (you have to add this event check. Just add it in between two other event cases).

    When this event occurs, it means that at least one packet has been transmitted successfully and the softdevice has received an ACK. This also means that some space in the softdevice TX queue is freed up, and you can try to queue more packets.

    Basically, you are looking for something like:

    volatile bool m_queue_full = false;
    volatile uint8_t m_packets_to_send = 0;
    
    on_ble_evt()
    {
        switch (p_ble_evt->header.evt_id)
        {
            case BLE_GAP_EVT_CONNECTED:
                ...
                break;
            ...
            
            case BLE_EVT_TX_COMPLETE:
                queue_full = false;
            
            default:
                break;
        }
    }
    
    
    void my_timeout_handler()
    {
        m_packets_to_send = 6;
    }
    
    
    int main()
    {
        ...
        for (;;)
        {
            while (packets_to_send && !m_queue_full)
            {
                err_code = ble_nus_string_send()
                {
                    if (err_code == NRF_SUCCESS)
                    {
                        packets_to_send--;
                    }
                    else if (err_code == NRF_ERROR_NO_TX_PACKETS)
                    {
                        m_queue_full = true;
                    }
                    else
                    {
                        APP_ERROR_CHECK(err_code);
                    }
                }
            }
        }
    
    }

    Best regards,

    Edvin

  • Thanks Edvin, after moving to the SDK15.2.0, I finally able to send 1kBps easily, also I have tried to send data at 4kBps without any issue.

Reply Children
No Data
Related