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

  • Don't forget I had the observation that nRF Connect App works. Meaning toggling the LED works every time. So I suspect the nRF Blinky App is at fault somehow.

    BR Martin

  • Hi Martin

    Apparently there is a trick to getting more logging info from the Blinky app. 

    In the BlinkyManager.java file, please add the following function to the BlinkyManager class:

    @Override
    public void log(int level, @NonNull String message) {
    super.log(level, message);
    Log.d("BlinkyManager", message);
    }

    Then you should see log messages when the app sends data to the peripheral, and when the writeCharacteristic callback is triggered, which means the data was successfully sent. 

    The log should look something like this if everything works correctly:

    10-09 11:03:33.038 21893-21893/no.nordicsemi.android.nrfblinky D/BlinkyManager: Turning LED OFF...
    10-09 11:03:33.290 21893-21925/no.nordicsemi.android.nrfblinky D/BlinkyManager: LED OFF
    10-09 11:03:33.928 21893-21893/no.nordicsemi.android.nrfblinky D/BlinkyManager: Turning LED ON...
    10-09 11:03:34.263 21893-21907/no.nordicsemi.android.nrfblinky D/BlinkyManager: LED ON
    10-09 11:03:34.582 21893-21893/no.nordicsemi.android.nrfblinky D/BlinkyManager: Turning LED OFF...
    10-09 11:03:34.849 21893-21907/no.nordicsemi.android.nrfblinky D/BlinkyManager: LED OFF

    Can you give this a try and see if the results are similar?

    Best regards
    Torbjørn

  • Hi Torbjørn

    I think this has helped uncover the issue. What I notice is if I put my finger on the LED slider control and move from left to right or right to left, I don't see the LED status change. If I tap the slider at either end I see the LED toggle ON/OFF ok ;-)

    You can see these two types of behaviour in the log below. Firstly I tap the slider and you see LED OFF response and then I tap the other end of the slider and the response is LED ON. After that I slide my finger across the slider and then the status does not change, only the ViewPosttime pointer 0 or 1 message is shown.

    It's quite a small slider on my phone and of course it gives the impression that toggle LED ON/OFFcommand is handled through ok through visual feedback on the slider object.

    D/BlinkyManager: Turning LED OFF...
                     Writing characteristic 00001525-1212-efde-1523-785feabcd123 (WRITE REQUEST)
                     gatt.writeCharacteristic(00001525-1212-efde-1523-785feabcd123)
    D/BlinkyManager: Data written to 00001525-1212-efde-1523-785feabcd123, value: (0x) 00
                     LED OFF
    D/ViewRootImpl@1cda049[BlinkyActivity]: ViewPostIme pointer 0
    D/ViewRootImpl@1cda049[BlinkyActivity]: ViewPostIme pointer 1
    D/BlinkyManager: Turning LED ON...
                     Writing characteristic 00001525-1212-efde-1523-785feabcd123 (WRITE REQUEST)
                     gatt.writeCharacteristic(00001525-1212-efde-1523-785feabcd123)
    D/BlinkyManager: Data written to 00001525-1212-efde-1523-785feabcd123, value: (0x) 01
                     LED ON
    D/ViewRootImpl@1cda049[BlinkyActivity]: ViewPostIme pointer 0
    D/ViewRootImpl@1cda049[BlinkyActivity]: ViewPostIme pointer 1
    D/ViewRootImpl@1cda049[BlinkyActivity]: ViewPostIme pointer 0
    D/ViewRootImpl@1cda049[BlinkyActivity]: ViewPostIme pointer 1
    D/ViewRootImpl@1cda049[BlinkyActivity]: ViewPostIme pointer 0
    D/ViewRootImpl@1cda049[BlinkyActivity]: ViewPostIme pointer 1
    D/ViewRootImpl@1cda049[BlinkyActivity]: ViewPostIme pointer 0

    Thanks for this I will now move forward and add some customisations to the App and embedded control.

    BR Martin

  • 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

Reply
  • 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

Children
  • 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

  • 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

Related