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

Sending more than 20 bytes via notification

I am making a simple device based on nrf5240 - I want to control the servo from a smartphone. I used the WART and Blinky examples as a starting point. The data exchange algorithm is this - the smartphone sends a command (writes data to the characteristic) and expects a response from nrf52840.
The response is implemented through a notification (as in the UART example) and through another characteristic.

Everything works, but I wanted to send a 48-byte packet in response to the command, and I didn’t succeed. I can’t send more than 20 bytes through a notification. I saw similar questions on the forum, and if I understood correctly, then there is a limit on the size of the data sent through the notification.
How to fix the code so that you can send more than 20 bytes through a notification?

SDK version: nRF5_SDK_16.0.0

Platform: nRF52840 

SoftDevice: s140

  • Hi, 

    There's a constant in the SDK which gives the maximum length for fixed and variable length characteristics. 

    You can notify them but you'll only get MTU-3 bytes in the notification and if the client wants the rest it will have to read the characteristic afterwards with a long read. Notifications have a max payload of MTU-3 bytes and MTU is currently 23 so 20 is the max (in the Blinky example). 

    If you set the ATT_MTU to 51 (3 bytes for header, 48 bytes for attribute data) in the sdk_config.h you can send a single 48-byte notification to the SoftDevice, and the link-layer will automatically do the fragmentation and re-assembly for you, so it looks like the notification is being sent in a single operation. Different iOS and Android phones could have their own limits for ATT_MTUs. 

    // <o> NRF_SDH_BLE_GATT_MAX_MTU_SIZE - Static maximum MTU size. 
    #ifndef NRF_SDH_BLE_GATT_MAX_MTU_SIZE
    #define NRF_SDH_BLE_GATT_MAX_MTU_SIZE 51
    #endif

     

    -Amanda H.

     

  • Thanks, Amanda!

    I changed the NRF_SDH_BLE_GATT_MAX_MTU_SIZE parameter, but then I had to change the RAM allocation, otherwise I could not run the code - there was an error: the stack pointer was out of range.

    I checked the work with iOS 13.2.3 (iPhone 7) and Android 9 (Xiaomi Mi A2) - it works stably. But if I understand you correctly - are there problems on older versions of the OS and smartphones?

  • Hi, 

    uchar said:
    but then I had to change the RAM allocation, otherwise I could not run the code - there was an error: the stack pointer was out of range.

    When you change your MTU size you should also change the RAM allocation since the RAM usage for the stack will depend on certain things, like the GATT table size, MTU and TX-buffering settings, and similar.

    If you modify NRF_SDH_BLE_GATT_MAX_MTU_SIZE you should adjust RAM start and RAM size for your project. 

    Please see this post

    uchar said:
    are there problems on older versions of the OS and smartphones?

    ATT_MTU has to be negotiated between the two peers, and the minimum supported value for the two peers will set the limit. It seems fine in your use cases. 

    -Amanda H.  

  • I think I'm having a similar issue! How did you change the RAM allocation? I'm not getting any errors on startup but the code will crash if I try to send too many bytes.

Related