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

Notify more than 20bytes using sd_ble_gatts_hvx with SDK16 - s140 - nRF52840

Hi everyone,

I want to send packets via notifications to a central. While searching through the forum I found some posts saying that the maximum data size per notification using the sd_ble_gatts_hvx() is limited to 20bytes...

After searching a little bit a found that I was able to change both the NRF_SDH_BLE_GATT_MAX_MTU_SIZE and the NRF_SDH_BLE_GAP_DATA_LENGTH. After changing the prementioned variables with NRF_SDH_BLE_GATT_MAX_MTU_SIZE = 247 and NRF_SDH_BLE_GAP_DATA_LENGTH = 251 respectively and re-adjusting the RAM memory size, I was able to transmit more than 20bytes with a single notification and receive at both nRF Connect for Desktop & Mobile without any problem (actually I transmitted 34bytes, that is my current payload). 

I changed both variables from the sdk_config.h file. Also, the reason I set NRF_SDH_BLE_GAP_DATA_LENGTH = 251 was to avoid data fragmentation.

So, my questions are:

1. Is this approach correct and robust? Do I have to take any other parameter into consideration?

2. In ble_gatt.h there is also a variable BLE_GATT_ATT_MTU_DEFAULT which default size is 23. I've noticed that my firmware runs without changing this variable. What is its purpose? Do I have to set BLE_GATT_ATT_MTU_DEFAULT  = NRF_SDH_BLE_GATT_MAX_MTU_SIZE ?

3. My payload at the moment is 34 bytes but I preferred to set MTU=247 and DLE=251 because I may need to increase the payload in the near future. Is there any drawback in terms of energy consumption by setting MTU and DLE to its maximum value since I design a low power application?

Thanks in advance

Nick

Parents
  • Hello Nick,

    1. There are a lot of different defines that have different roles in the SDK. If your implementation works, it would be robust. Just make sure that your application handles the case that it may connect to something that doesn't support MTU > 23, in which case you would not be able to send more than 20 bytes (sd_ble_gatts_hvx() would return an error).

    2. This value is used as the default MTU upon every connection. First after the connection, the devices will negotiate what MTU size they will use. If both supports higher MTU and data length, they will use that, which is the case in your situation. So you should have some variable saying what the current MTU is. Please check out how this is handled in the ble_app_uart example from the SDK.

    See how m_ble_nus_max_data_len is first set to BLE_GATT_ATT_MTU_DEFAULT, and then in the gatt_evt_handler() callback it will be set to the negotiated MTU. Later this is used to check the incoming UART bytes. If the number of bytes reaches m_ble_nus_max_data_len, it will send the data using ble_nus_data_send(). This is done to prevent the application to send a notification with more payload than the agreed MTU.

    3. There is no energy consumption disadvantage by increasing the MTU size. Of course, sending data costs energy, and increasing all the parameters and sending the data will draw power. E.g. a device sending 1.4MBPS of data (theoretical maximum of BLE with 2MBPS PHY) will use more energy than a device sending a couple of bytes every 10 minutes.

    That being said, if you have to send N bytes, and N is larger than the default MTU, increasing the MTU is never a bad idea. If you need to split up the packet it means that you need to send two packets instead of one, and this means that you need to send the header bytes two times. So in fact, increasing the MTU will save power.

    BR,

    Edvin

Reply
  • Hello Nick,

    1. There are a lot of different defines that have different roles in the SDK. If your implementation works, it would be robust. Just make sure that your application handles the case that it may connect to something that doesn't support MTU > 23, in which case you would not be able to send more than 20 bytes (sd_ble_gatts_hvx() would return an error).

    2. This value is used as the default MTU upon every connection. First after the connection, the devices will negotiate what MTU size they will use. If both supports higher MTU and data length, they will use that, which is the case in your situation. So you should have some variable saying what the current MTU is. Please check out how this is handled in the ble_app_uart example from the SDK.

    See how m_ble_nus_max_data_len is first set to BLE_GATT_ATT_MTU_DEFAULT, and then in the gatt_evt_handler() callback it will be set to the negotiated MTU. Later this is used to check the incoming UART bytes. If the number of bytes reaches m_ble_nus_max_data_len, it will send the data using ble_nus_data_send(). This is done to prevent the application to send a notification with more payload than the agreed MTU.

    3. There is no energy consumption disadvantage by increasing the MTU size. Of course, sending data costs energy, and increasing all the parameters and sending the data will draw power. E.g. a device sending 1.4MBPS of data (theoretical maximum of BLE with 2MBPS PHY) will use more energy than a device sending a couple of bytes every 10 minutes.

    That being said, if you have to send N bytes, and N is larger than the default MTU, increasing the MTU is never a bad idea. If you need to split up the packet it means that you need to send two packets instead of one, and this means that you need to send the header bytes two times. So in fact, increasing the MTU will save power.

    BR,

    Edvin

Children
No Data
Related