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

Best way to send larger chunks of data through BLE UART?

Right now i have based myself on the BLE UART example where it is UART over BLE.

So naturally I use ble_nus_string_send to send data. After some digging I saw that this takes max 20 bytes of data. Also there seems to be a fixed queue size, so anything after a filled queue will be disregarded with an error returned from this function. The qeue size by the looks of it is 6, right?

So, how do I send bigger chunks (all the data is one big chunk which is treated as one entity)? First I tried to just retry if ble_nus_string_send returned an error with a nrf_delay_ms(20) in a loop with 100 retries. It does work, but it can't be an elegant solution. Also on the 2nd chunk of data sent over, it seems to struggle a lot more when sent over. It comes in small portions of 3 chunks over time. I am testing on android with the NRF UART app.

Thanks!

  • @Emil: You can just keep calling sd_ble_gatts_hvx() until you receive BLE_ERROR_NO_TX_BUFFERS error code back then it's when the buffer is full.

    What do you mean by "pure GATT server" ?

  • Thanks! By "Pure GATT server" I mean to send bluetooth data without the usage of the BLE UART service. Just a pure sd_ble_gatts_hvx send. Is there such an example anywhere? Like, send a data packet, and define it's size instead of UART. ble_nus_string_send uses that function internally, I guess I can still use this? Or not? It seems to be UART specific (ble_nus.c).

    Also, I need to change the UART example to display itself as a non-uart service.

  • @Emil: NUS service is simply a proprietary that we created to show how you can have your own proprietary services and characteristics. You can modify it as you wish. sd_ble_gatts_hvx() requires a notifiable characteristic. You can use other characteristic not the UART one, but still need a notifiable characteristic/attribute. If you plan to have access to lower layer with no attribute, you would need to use the L2CAP api provided by the softdevice.

  • Thank you so much! Is there an example on setting up a basic, notifyable characteristic with a send? I guess the UART is a custom implementation based on this (Since you can only send 20 bytes). I suppose "long reads" are something the receiving end has to poll?

  • @Emil: No, the UART example is actually the basic example for this. Note that the 20 byte limit is the maximum payload size for the BLE att packet. You can declare your characteristics with longer size but when notifying only first 20 bytes is notified. You would need to use long write or long read to transfer long characteristics. And on air it's also splited in to 20 bytes trunks.

    There is also a good application note that you can follow is the nAN36. However, it's a little bit outdated since it's was written about 1.5 year ago.

Related