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

BLE nus slow transmitting after being connected for a while

Hi,

I have implemented BLE nus uart on my device and am getting some weird problems with the transfer speed.

When I connect to the device and transfer data via BLE nus to the mobile phone the data is transferred very quickly, however, if I keep the device connected for a while after connecting and then transferring data then the data is sent extremely slow. The same happens if I send data with BLE nus and then send again afterwards. I currently switch between slow and fast connection interval, could this be a problem? But, the weird thing is that when I connected to the device in the beginning and wait for a while it also happens when still on fast connection interval.

I currently am using sdk 15.0 with SD 6.0

  • Yes, the other processor which is sending the data is still alive and waiting for the nrf ble module to send an ack when it has sent everything to the mobile phone. Since the processor doesn't send any ack it times out after 20 seconds and restarts the ble as it seem to have been stuck/frozen.

    Exactly, my bad. The error is as you say NRF_ERRO_RESOURCES is what I get sometimes. However, the last thing I get when debugging and performing ble_nus_data_send() is this error:

    <info> app: Sending NUS data! 0x0
    <info> app: DONE!

    The connection intervals I change between are these:

    // Connection Interval and timeout for slow connection
    #define SLOW_MIN_CONN_INTERVAL MSEC_TO_UNITS(180, UNIT_1_25_MS)
    #define SLOW_MAX_CONN_INTERVAL MSEC_TO_UNITS(375, UNIT_1_25_MS) 
    #define SLOW_CONN_SUP_TIMEOUT  MSEC_TO_UNITS(6000, UNIT_10_MS)
    #define SLOW_SLAVE_LATENCY     4
    
    // Connection Interval and timeout for fast connection
    #define FAST_MIN_CONN_INTERVAL MSEC_TO_UNITS(7.5, UNIT_1_25_MS) 
    #define FAST_MAX_CONN_INTERVAL MSEC_TO_UNITS(15, UNIT_1_25_MS)
    #define FAST_CONN_SUP_TIMEOUT  MSEC_TO_UNITS(5000, UNIT_10_MS)
    #define FAST_SLAVE_LATENCY     4
    
    // Time from initiating event (connect or start of notification) to first time
    // sd_ble_gap_conn_param_update is called (20 seconds).
    #define FIRST_CONN_PARAMS_UPDATE_DELAY APP_TIMER_TICKS(20000)
    
    // Time between each call to sd_ble_gap_conn_param_update after the first call
    // (5 seconds).
    #define NEXT_CONN_PARAMS_UPDATE_DELAY  APP_TIMER_TICKS(5000)
    
    // Number of attemps before giving up connection parameter negotiation
    #define MAX_CONN_PARAMS_UPDATE_COUNT   3

    So normally I use slow, when there is a request from the mobile application, it switches to fast and wait for it to success and then start sending. 

    When the nrf device freezes, I seem to not get any more prints in any of the other places. It seem like it just locked itself somehow or maybe hard faulted I don't know what is actually happening, but seem like it just stops.

  • Try some debugging. Check how fast you can usually queue packets when you connect, and how many you can queue "after a while".

    Please note that the connection interval is decided by the central. You can ask for certain parameters on the peripheral, but it is the phone (iPhone) that decides. You may not use the connection interval that you think.

    It is very hard for me to say whats going on here. Try to print a message every time you successfully queue a packet, and print the length of the queued packet. What does it look like at first, and after a while? Does it look like it is slowing down?

  • Ok, I seem to have traced the error where it seem to be stuck. When checking the prints it seem to be stuck in a while loop which is trying to do app_uart_get() and is returning error 5 from app_fifo_get(), I assume that this error is NRF_ERROR_NOT_FOUND. Am I correct?

    app_uart_get is fetching uart from the second processor but is returning this error. What could be causing this problem? Why is it triggering this error?

    Also, sometimes I also receive APP_UART_COMMUNICATION_ERROR, what could cause this error? It seem like it is losing some packages which cause the data to be incomplete. Is there some way to fix this issue?

  • Hello,

    The app_uart and app_fifo get are open source, so you can check why it returns NRF_ERROR_NOT_FOUND:

    uint32_t app_fifo_get(app_fifo_t * p_fifo, uint8_t * p_byte)
    {
        if (FIFO_LENGTH() != 0)
        {
            fifo_get(p_fifo, p_byte);
            return NRF_SUCCESS;
        }
    
        return NRF_ERROR_NOT_FOUND;
    
    }

    And you can see that FIFO_LENGTH() is a macro:

    #define FIFO_LENGTH(F) fifo_length(&F)              /**< Macro to calculate length of a FIFO. */
    
    //where fifo_length(&F):
    
    static __INLINE uint32_t fifo_length(app_fifo_t * const fifo)
    {
      uint32_t tmp = fifo->read_pos;
      return fifo->write_pos - tmp;
    }

    So I believe you are trying to read out the UART data, when you haven't received any data yet (you have read out all you have received). You should wait for the uart_event_handle() event before you read out the next byte.

    BR,

    Edvin

Related