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

nRF52 Ble Peripheral Example - ble_app_blinky not showing led/button service

Hi I have run a few peripheral examples ok and now move to evaluation of ble_peripheral also.

I'm using this version of the SDK....

If I program the softdevice and then the application hex file into board using the files shown below the led 1 turns on as expected. 

Using rfConnect I can connect to "Nordic Blinky" and the led 2 turns on and led 1 turns off. However in the list of services I see there is not one showing for the Led/Button.

Using the blinky app for Android to connect I get a message indicating the "Device does not have the required services".

I checked the code in sdk_config.h to see if the service was enabled and this looks ok...

Looking at the help for the application at this link http://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.sdk%2Fdita%2Fsdk%2Fnrf5_sdk.html

I think I have done things correctly so I am now looking for some ideas/support to move forward please.

Regards MPH

Parents
  • Hi Martin

    It's quite peculiar that the example advertises and connects, but doesn't show the normal services. 

    Which services do you see when you connect through nRF Connect?

    Are you using nRF Connect for Android, iOS or desktop?

    Can you let me know which model and version of the kit you have, as printed on the white sticker?

    How are you flashing the kit? 
    Are you using nrfjprog, or one of the supported IDE's?

    Best regards
    Torbjørn

  • Hi Torbjørn

    I see these services using nRF Connect for Android..

    Generic Access, Generic Attribute, Blood pressure, Battery Service, Device Information.

    White sticker shows..

    PCA10040

    1.2.4

    2018.12

    682351679

    Flashing the kit by dragging and dropping the hex files onto the on-board drive.

    Also have Segger IDE installed and can build & program the project ok from there also.

    BR MPH

  • Hi Martin

    That's an interesting find!

    I double checked it myself and see the same issue here. For some reason I only ever click it, and I guess the same goes for the developer ;)

    I reported it to the apps guys, and they opened an issue on the github:
    https://github.com/NordicSemiconductor/Android-nRF-Blinky/issues/13

    Knowing their turnaround time we should have a fix out pretty soon Slight smile

    Best regards
    Torbjørn

  • Hi Again

    I now have a real requirement to build a demo app which uses the nRF52 kit. So I have revisited this Blinky example again and have been able to build in additional funcionality like handling more buttons and leds. In fact this modified Blinky already does >60% of what I expect to need for the demo. However, this is ok for boolean types but I need to add some more variables (say 6) like integer and possibly float. These would typically just need to be sent from the embedded end.

    I was contemplating adding more functionalty to accomplish this but would like to know your recommendations. For example is it easy to add this to the Blinky example or should I be looking at another example. Of course I have a "Thingy" (nice job) but that is doing a lot and it could me quite sometime to figure out how to extract what I need. So I am trying to work with efficiency in mind and coming from the fact I am not a regular user of the underlying BLE software just now.

    BR Martin

  • Hi Martin

    If you take a look at the ble_lbs_init(..) function in ble_lbs.c you can see how the characteristics are set up. As long as you change the UUID to something different you can change the service and characteristic configuration any way you like, and change the size of the services. 

    As an example, to add a new characteristic that supports float just add the following lines of code:

    // Add float characteristic.
    memset(&add_char_params, 0, sizeof(add_char_params));
    add_char_params.uuid              = ADD_UNIQUE_16BIT_UUID_HERE;
    add_char_params.uuid_type         = p_lbs->uuid_type;
    add_char_params.init_len          = sizeof(float);
    add_char_params.max_len           = sizeof(float);
    // Read and Notify is typically set when the data flow is from the server (nrf52) to the client (phone)
    add_char_params.char_props.read   = 1;
    add_char_params.char_props.notify = 1; 
    
    add_char_params.read_access       = SEC_OPEN;
    add_char_params.cccd_write_access = SEC_OPEN;
    
    // You need to extend the p_lbs service type to include char handles for your new characteristic
    err_code = characteristic_add(p_lbs->service_handle,
                                  &add_char_params,
                                  &p_lbs->float_char_handles);
    if (err_code != NRF_SUCCESS)
    {
        return err_code;
    }

    If you have a lot of smaller values you want to send together it makes sense to define them as a struct, and set up your characteristic to send the entire struct in one go. Then you can more effectively send a lot of smaller values at once:

    typedef struct
    {
        int int_var;
        float a_float;
        bool and_a_bool;
    }compound_type_t;
    
    // Add compound characteristic.
    memset(&add_char_params, 0, sizeof(add_char_params));
    add_char_params.uuid              = COMPOUND_CHAR_UUID;
    add_char_params.uuid_type         = p_lbs->uuid_type;
    add_char_params.init_len          = sizeof(compound_type_t);
    add_char_params.max_len           = sizeof(compound_type_t);
    add_char_params.char_props.read   = 1;
    add_char_params.char_props.notify = 1;
    
    add_char_params.read_access       = SEC_OPEN;
    add_char_params.cccd_write_access = SEC_OPEN;
    
    err_code = characteristic_add(p_lbs->service_handle,
                                  &add_char_params,
                                  &p_lbs->compound_char_handles);
    if (err_code != NRF_SUCCESS)
    {
        return err_code;
    }

    After you change this on the peripheral side you also have to change your app code to read/write the characteristics properly. In Java this is a bit fiddly as you have to convert byte buffers to float/int/bool etc, but nothing a google search won't tell you how to do ;)

    To generate your own unique 128-bit base UUID you can use this site:
    https://www.uuidgenerator.net/

    Just remember to pick a version 4 UUID (random), not version 1. 

    Best regards
    Torbjørn

  • Thanks a lot Torbjørn I have added this to my short term list. I'll feedback how I get on.

    BR Martin

  • Hi Martin

    Sound good, just let me know if you have more questions Slight smile

    Best regards
    Torbjørn

Reply Children
  • Hi Torbjørn 

    I added each code and modified the structure ble_lbs_s.to include float or compound char handles but to start I made a mistake for the type (not using ble_gatts_char_handles) and the compiler gave a warning about an incompatible pointer. Then I compiled with empty callbacks for now. I ran this under debug and also the android end. I just wanted to see if the new UUID was being read ok which appears affirmative and the App runs as expected thereafter. I did not use a unique UUID rather for this test I appended as shown below.

    struct ble_lbs_s
    {
    uint16_t service_handle; /**< Handle of LED Button Service (as provided by the BLE stack). */
    ble_gatts_char_handles_t led_char_handles; /**< Handles related to the LED Characteristic. */
    ble_gatts_char_handles_t button_char_handles; /**< Handles related to the Button Characteristic. */
    uint8_t uuid_type; /**< UUID type for the LED Button Service. */
    ble_lbs_led_write_handler_t led_write_handler; /**< Event handler to be called when the LED Characteristic is written. */
    ble_gatts_char_handles_t compound_char_handles;
    };

    So the modified characteristic seems ok so far so next I'll make some event handling for the data etc.

    Thanks again but I would be pleased for you to comment. 

    BR Martin

    #define LBS_UUID_BASE {0x23, 0xD1, 0xBC, 0xEA, 0x5F, 0x78, 0x23, 0x15, \
    0xDE, 0xEF, 0x12, 0x12, 0x00, 0x00, 0x00, 0x00}
    #define LBS_UUID_SERVICE 0x1523
    #define LBS_UUID_BUTTON_CHAR 0x1524
    #define LBS_UUID_LED_CHAR 0x1525
    #define COMPOUND_CHAR_UUID 0x1526

  • Hi Martin

    This looks good to me. For clarity I would insert the compound_char_handles field in ble_lbs_s struct after the button_char_handles field, and before the event handler, but this has no practical impact on the code (it's just to bundle the char handles together). 

    Secondly you can also consider renaming the characteristic to something more relevant to the data that you want to send. 

    The UUID definition looks fine, the main point is to pick a unique 16-bit number for all the new characteristics. 

    Best regards
    Torbjørn

  • Hi Torbjørn

    I started to look for some tutorials on integrating application events/processing into the BLE framework but do you have any recommendations on this. I found something using a scheduler for example.

    BR Martin

  • Hi Martin

    There isn't that much to it, other than be a bit careful about the interrupt priorities you run your events at. 

    If your events run at priority 6 or 7 there isn't much to think about. Critical SoftDevice interrupts and event forwarding to the application will have priority, and will not be impacted. 

    If your events run a priority 2 or 3 you have to be a bit more careful, as you will supersede events coming from the SoftDevice, and you will not be able to call SoftDevice functions from your application event directly. 

    The remaining interrupt priorities (0, 1, 4 and 5) are unavailable when using a SoftDevice. 

    Best regards
    Torbjørn

Related