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

Read added custom characteristic value from peripheral

Hi, 

I am developing a central application that will connect to my custom made peripheral device and continuously read a characteristic available on the peripheral device . I have currently managed to find and connect to my peripheral device, and also request to read the device name characteristic without any problems. However, when I start reading the custom service that is added on the peripheral device, with the sd_ble_gattc_char_value_by_uuid_read function, it returns err_code 7, which I assume is invalid params. 

On the peripheral I can see that there are two characteristics that I can read through the nrf connect application.

I had my code in the following way when requesting to read the device name characteristic:

static void repeated_timer_handler(void * p_context)
{
    ret_code_t err_code;
    
    ble_uuid_t p_uuid = {.uuid = BLE_UUID_GAP_CHARACTERISTIC_DEVICE_NAME, .type = BLE_UUID_TYPE_BLE};
    ble_gattc_handle_range_t p_handle_range = {.start_handle = 0x0001, .end_handle = 0xFFFF};

    err_code = sd_ble_gattc_char_value_by_uuid_read(connection_handle, &p_uuid, &p_handle_range);
    if(err_code != NRF_SUCCESS)
    {
        NRF_LOG_INFO("Failed to send read request to peer error = %d", err_code);
    }
}

And when I now want to read my service characteristic I instead now changed the uuid and type to following:

static void repeated_timer_handler(void * p_context)
{
    ret_code_t err_code;
    
    ble_uuid_t p_uuid = {.uuid = 0xF011, .type = BLE_UUID_TYPE_VENDOR_BEGIN};
    ble_gattc_handle_range_t p_handle_range = {.start_handle = 0x0001, .end_handle = 0xFFFF};
    err_code = sd_ble_gattc_char_value_by_uuid_read(connection_handle, &p_uuid, &p_handle_range);
    if(err_code != NRF_SUCCESS)
    {
        NRF_LOG_INFO("Failed to send read request to peer error = %d", err_code);
    }
}

Am I calling the wrong function or do I have to perform some other function call in order to be able of requesting to read the following service?

I assume that I don't have to use the base uuid to call the specific service, or do I have to? I have seen that some examples perform a service discovery when initiating the connection, but if I know the characteristic uuid, do I still have to call this function? I tried adding this sd_ble_gattc_primary_services_discover function but didn't solve the problem.

Update: I have seen that some have used the sd_ble_gattc_read(connection_handle, 0xF011, 0) function. When I use this instead, I get no error but the value I get in the event handler has a length of 0.

 

Thanks in advance!

/Hadi

Parents
  • Hello,

    I recommend you look into the service discovery. I can also recommend that you read through this guide:

    https://devzone.nordicsemi.com/nordic/short-range-guides/b/bluetooth-low-energy/posts/ble-central-tutorial

    Although it is written for an older version of the SDK, the theory is still correct, and you should be able to figure out how to do it in the SDK you are using by looking at the ble_nus_c example. 

    Is there a reason why you are using sd_ble_gattc_ read instead of using notifications? I am mostly curious, but it may also be easier to set up, since most of our examples are using it. It is also a more efficient way of sending data from a peripheral to a central. 

    Best regards,

    Edvin

  • Hi,

    First of all thank you for the recommendations and guidance, I'll take a look on the guide.

    Secondly regarding the services, I was a bit unsure whether the central would send continuous requests since I need to read a characteristic on the peripheral until the central and peripheral are disconnected. If I use notifications is it possible to adjust how often I can request a value, I need to read a characteristic in an interval of 500ms?

    Another thing that I forgot to mention is that the peripheral device does not have nus implemented, is it necessary to implement nus on the peripheral too? I have only added the custom services on the peripheral and they work as expected but cant get the values.

    Best regards,

    Hadi

  • If the central doesn't use the nus service, then you don't need that on the peripheral either. But the peripheral and central needs to use the same type of service. NUS is just an example of that.

     

    Hadi Deknache said:
    Secondly regarding the services, I was a bit unsure whether the central would send continuous requests since I need to read a characteristic on the peripheral until the central and peripheral are disconnected. If I use notifications is it possible to adjust how often I can request a value, I need to read a characteristic in an interval of 500ms?

     Notifications work similar, but except for the central actively reading the peripheral's value, the periheral will push the value to the central, which will trigger an event. This way, you will have less delay from the value is updated until the central receives it.

    So if you want to update the value every 500ms, then you can send this notification every 500ms from the peripheral, and the central will receive this as an event. 

    If you use write and read, it may happen that the central reads the value, and right after, the peripheral updates this value, which will not be known by the central until the next time it decides to read it. 

Reply
  • If the central doesn't use the nus service, then you don't need that on the peripheral either. But the peripheral and central needs to use the same type of service. NUS is just an example of that.

     

    Hadi Deknache said:
    Secondly regarding the services, I was a bit unsure whether the central would send continuous requests since I need to read a characteristic on the peripheral until the central and peripheral are disconnected. If I use notifications is it possible to adjust how often I can request a value, I need to read a characteristic in an interval of 500ms?

     Notifications work similar, but except for the central actively reading the peripheral's value, the periheral will push the value to the central, which will trigger an event. This way, you will have less delay from the value is updated until the central receives it.

    So if you want to update the value every 500ms, then you can send this notification every 500ms from the peripheral, and the central will receive this as an event. 

    If you use write and read, it may happen that the central reads the value, and right after, the peripheral updates this value, which will not be known by the central until the next time it decides to read it. 

Children
No Data
Related