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

How to collect value from multiple characteristics in the client?

Hi, 

I am working on the client program to retrieve the value from 4 characteristics at the same time using notifications. I have already done with the server program. Using nrf connect to connect with my program, it looks like this:

I would like to collect the value from these four characteristics using notifications. Here' s the code to update 4 characteristic data on server:

void ble_eeg_update_4ch(ble_eeg_t *p_eeg) {
  //packet 1:
  uint32_t err_code;
  if (p_eeg->conn_handle != BLE_CONN_HANDLE_INVALID && p_eeg->ads1299_current_configuration[4] != 0xE1) {
    uint16_t hvx_len = EEG_PACKET_LENGTH;//The length is 60
    ble_gatts_hvx_params_t const hvx_params = {
        .handle = p_eeg->eeg_ch1_handles.value_handle,
        .type = BLE_GATT_HVX_NOTIFICATION,
        .offset = 0,
        .p_len = &hvx_len,
        .p_data = p_eeg->eeg_ch1_buffer,
    };
    err_code = sd_ble_gatts_hvx(p_eeg->conn_handle, &hvx_params);
  }
  if (err_code == NRF_ERROR_RESOURCES) {
    NRF_LOG_INFO("sd_ble_gatts_hvx() ERR/RES: 0x%x\r\n", err_code);
  }
  //Packet 2
  if (p_eeg->conn_handle != BLE_CONN_HANDLE_INVALID && p_eeg->ads1299_current_configuration[5] != 0xE1) {
    uint16_t hvx_len = EEG_PACKET_LENGTH;//The length is 60
    ble_gatts_hvx_params_t const hvx_params = {
        .handle = p_eeg->eeg_ch2_handles.value_handle,
        .type = BLE_GATT_HVX_NOTIFICATION,
        .offset = 0,
        .p_len = &hvx_len,
        .p_data = p_eeg->eeg_ch2_buffer,
    };
    err_code = sd_ble_gatts_hvx(p_eeg->conn_handle, &hvx_params);
  }
  if (err_code == NRF_ERROR_RESOURCES) {
    NRF_LOG_INFO("sd_ble_gatts_hvx() ERR/RES: 0x%x\r\n", err_code);
  }

  //Packet 3
  if (p_eeg->conn_handle != BLE_CONN_HANDLE_INVALID && p_eeg->ads1299_current_configuration[6] != 0xE1) {
    uint16_t hvx_len = EEG_PACKET_LENGTH;//The length is 60
    ble_gatts_hvx_params_t const hvx_params = {
        .handle = p_eeg->eeg_ch3_handles.value_handle,
        .type = BLE_GATT_HVX_NOTIFICATION,
        .offset = 0,
        .p_len = &hvx_len,
        .p_data = p_eeg->eeg_ch3_buffer,
    };
    err_code = sd_ble_gatts_hvx(p_eeg->conn_handle, &hvx_params);
  }
  if (err_code == NRF_ERROR_RESOURCES) {
    NRF_LOG_INFO("sd_ble_gatts_hvx() ERR/RES: 0x%x\r\n", err_code);
  }

  //Packet 4
  if (p_eeg->conn_handle != BLE_CONN_HANDLE_INVALID && p_eeg->ads1299_current_configuration[7] != 0xE1) {
    uint16_t hvx_len = EEG_PACKET_LENGTH;//The length is 60
    ble_gatts_hvx_params_t const hvx_params = {
        .handle = p_eeg->eeg_ch4_handles.value_handle,
        .type = BLE_GATT_HVX_NOTIFICATION,
        .offset = 0,
        .p_len = &hvx_len,
        .p_data = p_eeg->eeg_ch4_buffer,
    };
    err_code = sd_ble_gatts_hvx(p_eeg->conn_handle, &hvx_params);
  }
  if (err_code == NRF_ERROR_RESOURCES) {
    NRF_LOG_INFO("sd_ble_gatts_hvx() ERR/RES: 0x%x\r\n", err_code);
  }
}

 

Question:

1. Do you have examples that have multiple characteristics that need notifications in one service? I read the code of ble_app_hrs_c, but this program is not what I want.

2. If I can get retrieve these 4 characteristics data on the client, how to differentiate them?

Parents
  • Hi,

    In the ble event, the handle in the ble_gattc_evt_hvx_t data structure is the attribute handle which identifies the characteristic. (Not to be confused with the connection handle, which is found in the ble_gattc_evt_t structure that holds the ble_gattc_evt_hvx_t structure in its params.hvx field.)

    For examples on how to handle this, please have a look at the client service implementations in <sdk folder>/components/ble/ble_services (the folders ending in "_c"). Typically there is an on_hvx() function that checks the handle, e.g. for the battery service client in ble_bas_c.c:

    /**@brief     Function for handling Handle Value Notification received from the SoftDevice.
     *
     * @details   This function handles the Handle Value Notification received from the SoftDevice
     *            and checks whether it is a notification of the Battery Level measurement from the peer. If
     *            it is, this function decodes the battery level measurement and sends it to the
     *            application.
     *
     * @param[in] p_ble_bas_c Pointer to the Battery Service Client structure.
     * @param[in] p_ble_evt   Pointer to the BLE event received.
     */
    static void on_hvx(ble_bas_c_t * p_ble_bas_c, ble_evt_t const * p_ble_evt)
    {
        // Check if the event is on the link for this instance.
        if (p_ble_bas_c->conn_handle != p_ble_evt->evt.gattc_evt.conn_handle)
        {
            return;
        }
        // Check if this notification is a battery level notification.
        if (p_ble_evt->evt.gattc_evt.params.hvx.handle == p_ble_bas_c->peer_bas_db.bl_handle)
        {
            if (p_ble_evt->evt.gattc_evt.params.hvx.len == 1)
            {
                ble_bas_c_evt_t ble_bas_c_evt;
                ble_bas_c_evt.conn_handle = p_ble_evt->evt.gattc_evt.conn_handle;
                ble_bas_c_evt.evt_type    = BLE_BAS_C_EVT_BATT_NOTIFICATION;
    
                ble_bas_c_evt.params.battery_level = p_ble_evt->evt.gattc_evt.params.hvx.data[0];
    
                p_ble_bas_c->evt_handler(p_ble_bas_c, &ble_bas_c_evt);
            }
        }
    }

    Regards,
    Terje

  • Thank you for your help!

     I noticed that the glucose sensor peripheral example ble_app_gls have two characteristics that need notification/indication in one service. However, I can't find the central example of it. Do you have the central example of it?

  • Hi,

    I am afraid we only have a peripheral example for the Glucose Service, and we also only provide a library for the server (ble_gls) and not for the client.

    Regards,
    Terje

Reply Children
No Data
Related