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

Advertise two services at the same time?

EDIT: I have added the battery data in percentage to scan response manufacturer specific data. Is that the only possible way?

Hello,

I am working on a beacon application that updates the advertisement every second.

I have a "time counter", so to say, that is stored in the manufacturer specific data. Additionally, I have a "temperature" or "rotation speed" service. It depends on the hardware of the node.

I would like to advertise a second service for seeing the battery percentage status but cannot figure out how to do it. I tried to do this but obviously it seems I just overwrite first temperature advdata with battery data and then I advertise only battery service. I would like to see both temperature and battery data on the nRF Connect app.

uint8_t rotation_data[] = {value_0,value_1,value_2,value_3};
rotation.data.p_data = rotation_data;
rotation.data.size = sizeof(rotation_data);
rotation.service_uuid = 0x1815; //Official SIG temperature service
init.advdata.p_service_data_array = &rotation;
    
uint8_t battery_data[] = {percentage_batt_lvl};
battery.data.p_data = battery_data;
battery.data.size = sizeof(battery_data);
battery.service_uuid = 0x180F; //official SIG battery service
init.advdata.p_service_data_array = &battery;

Parents
  • What you are doing now is to just overwrite the old data (as you mentioned). What you need to do is the following:

    #define SIG_TEMP_SERVICE_UUID 0x1815 //Official SIG temperature service
    #define SIG_BAT_SERVICE_UUID 0x180F  //official SIG battery service
    
    ble_advdata_service_data_t service_data[2] = {};
    
    //Creating data structure for temperature
    uint8_t rotation_data[] = {1, 2, 3, 4, 5};
    uint8_array_t rotation;
    rotation.size = sizeof(rotation_data);
    rotation.p_data = rotation_data;
    
    // Adding temperature "service" to service_data array
    service_data[0].service_uuid = SIG_TEMP_SERVICE_UUID; 
    service_data[0].data = rotation;
    
    
    //Creating data structure for battery
    uint8_t battery_data[] = {6, 7, 8, 9, 10};
    uint8_array_t battery;
    battery.size = sizeof(battery_data);
    battery.p_data = battery_data;
    
    // Adding temperature "service" to service_data array
    service_data[1].service_uuid = SIG_BAT_SERVICE_UUID; 
    service_data[1].data = battery;
    
    init.advdata.service_data_count = 2;
    init.advdata.p_service_data_array = service_data;

    The changes I made from your code was roughly:

    • Created an array of type ble_advdata_service_data_t and assigned the temperature info to field 0 and the battery info to field 1
    •  Set the field init.advdata.service_count to 2
    • Excluded the & sign when assigning service_data to the init structure, since the variable is turned in to pointer when declared as array

    The reason for these changes can be found in the function advertising_init()->ble_advdata_encode(..)->service_data_encode(..)

    service_data_encode(..){
    .
    .
    for (i = 0; i < p_advdata->service_data_count; i++)
    {
        ble_advdata_service_data_t * p_service_data;
        uint32_t                     data_size;
    
        p_service_data = &p_advdata->p_service_data_array[i];
    .
    .

    As you can see, it will only encode as may GAP data types of "Service Data" as specified by service_data_count. 

    Best regards, Simon

Reply
  • What you are doing now is to just overwrite the old data (as you mentioned). What you need to do is the following:

    #define SIG_TEMP_SERVICE_UUID 0x1815 //Official SIG temperature service
    #define SIG_BAT_SERVICE_UUID 0x180F  //official SIG battery service
    
    ble_advdata_service_data_t service_data[2] = {};
    
    //Creating data structure for temperature
    uint8_t rotation_data[] = {1, 2, 3, 4, 5};
    uint8_array_t rotation;
    rotation.size = sizeof(rotation_data);
    rotation.p_data = rotation_data;
    
    // Adding temperature "service" to service_data array
    service_data[0].service_uuid = SIG_TEMP_SERVICE_UUID; 
    service_data[0].data = rotation;
    
    
    //Creating data structure for battery
    uint8_t battery_data[] = {6, 7, 8, 9, 10};
    uint8_array_t battery;
    battery.size = sizeof(battery_data);
    battery.p_data = battery_data;
    
    // Adding temperature "service" to service_data array
    service_data[1].service_uuid = SIG_BAT_SERVICE_UUID; 
    service_data[1].data = battery;
    
    init.advdata.service_data_count = 2;
    init.advdata.p_service_data_array = service_data;

    The changes I made from your code was roughly:

    • Created an array of type ble_advdata_service_data_t and assigned the temperature info to field 0 and the battery info to field 1
    •  Set the field init.advdata.service_count to 2
    • Excluded the & sign when assigning service_data to the init structure, since the variable is turned in to pointer when declared as array

    The reason for these changes can be found in the function advertising_init()->ble_advdata_encode(..)->service_data_encode(..)

    service_data_encode(..){
    .
    .
    for (i = 0; i < p_advdata->service_data_count; i++)
    {
        ble_advdata_service_data_t * p_service_data;
        uint32_t                     data_size;
    
        p_service_data = &p_advdata->p_service_data_array[i];
    .
    .

    As you can see, it will only encode as may GAP data types of "Service Data" as specified by service_data_count. 

    Best regards, Simon

Children
Related