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

Multiple TX characteristics ble_uart PCA10028

I am working with the ble_app_uart example in SDK 12.3.0 for the pca10028 board, and want to add a second tx characteristic (the one which receives from the nRF Connect app). I tried adding a second call of tx_char_add, and the characteristic appears in the app, but nothing I send through it appears on the other end, while the initial one still sends and receives fine. What do I need to change to allow a second characteristic to communicate?

Parents
  • Hi,

    ble_nus.c::on_write() will be called when you write to the new characteristic, but the event will not be forwarded to the application since p_evt_write->handle != p_nus->tx_handles.value_handle. 

    I would suggest something like this: 

    1. Add new characteristic handle to the NUS service structure. Eg.

    struct ble_nus_s
    {
        uint8_t                  uuid_type;               /**< UUID type for Nordic UART Service Base UUID. */
        uint16_t                 service_handle;          /**< Handle of Nordic UART Service (as provided by the SoftDevice). */
        ble_gatts_char_handles_t tx_handles;              /**< Handles related to the TX characteristic (as provided by the SoftDevice). */
        ble_gatts_char_handles_t new_handles;  <--
        ble_gatts_char_handles_t rx_handles;              /**< Handles related to the RX characteristic (as provided by the SoftDevice). */
        uint16_t                 conn_handle;             /**< Handle of the current connection (as provided by the SoftDevice). BLE_CONN_HANDLE_INVALID if not in a connection. */
        bool                     is_notification_enabled; /**< Variable to indicate if the peer has enabled notification of the RX characteristic.*/
        ble_nus_data_handler_t   data_handler;            /**< Event handler to be called for handling received data. */
    };

    2. Use "new_handles" when adding the characteristic

        return sd_ble_gatts_characteristic_add(p_nus->service_handle,
                                               &char_md,
                                               &attr_char_value,
                                               &p_nus->new_handles);

    3. Modify on_write function to forward write events for both "new_handles.value_handle" and "tx_handles.value_handle"

    4. Add an extra argument to the "ble_nus_data_handler_t" callback telling which characteristic the write belongs to. This is so the app can check which characteristic the write came. Alternatively, you can create a separate callback.

Reply
  • Hi,

    ble_nus.c::on_write() will be called when you write to the new characteristic, but the event will not be forwarded to the application since p_evt_write->handle != p_nus->tx_handles.value_handle. 

    I would suggest something like this: 

    1. Add new characteristic handle to the NUS service structure. Eg.

    struct ble_nus_s
    {
        uint8_t                  uuid_type;               /**< UUID type for Nordic UART Service Base UUID. */
        uint16_t                 service_handle;          /**< Handle of Nordic UART Service (as provided by the SoftDevice). */
        ble_gatts_char_handles_t tx_handles;              /**< Handles related to the TX characteristic (as provided by the SoftDevice). */
        ble_gatts_char_handles_t new_handles;  <--
        ble_gatts_char_handles_t rx_handles;              /**< Handles related to the RX characteristic (as provided by the SoftDevice). */
        uint16_t                 conn_handle;             /**< Handle of the current connection (as provided by the SoftDevice). BLE_CONN_HANDLE_INVALID if not in a connection. */
        bool                     is_notification_enabled; /**< Variable to indicate if the peer has enabled notification of the RX characteristic.*/
        ble_nus_data_handler_t   data_handler;            /**< Event handler to be called for handling received data. */
    };

    2. Use "new_handles" when adding the characteristic

        return sd_ble_gatts_characteristic_add(p_nus->service_handle,
                                               &char_md,
                                               &attr_char_value,
                                               &p_nus->new_handles);

    3. Modify on_write function to forward write events for both "new_handles.value_handle" and "tx_handles.value_handle"

    4. Add an extra argument to the "ble_nus_data_handler_t" callback telling which characteristic the write belongs to. This is so the app can check which characteristic the write came. Alternatively, you can create a separate callback.

Children
  • Why will p_evt_write->handle != p_nus->tx_handles.value_handle, if tx_char_add passes p_nus->tx_handles to sd_ble_gatts_characteristic_add? I also can't find the callback for ble_nus_data_handler_t/don't quite understand 4.

  • ZacMid said:
    Why will p_evt_write->handle != p_nus->tx_handles.value_handle, if tx_char_add passes p_nus->tx_handles to sd_ble_gatts_characteristic_add?

     I meant if you write data to the new characteristic, p_evt_write->handle will be equal tx_handles.value_handle if you write to the original tx handle. 

    ZacMid said:
    I also can't find the callback for ble_nus_data_handler_t/don't quite understand 4.

     The "ble_nus_data_handler_t" callback is registered by the app when it initializes the service: 

        nus_init.data_handler = nus_data_handler; // nus_data_handler() is called when data is written to the tx characteristic.

        err_code = ble_nus_init(&m_nus, &nus_init);
        APP_ERROR_CHECK(err_code);

Related