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 Torbjørn
    I have PCA10040, 1.2.4, 2018.12, 682351679 printed on the white sticker on the dev board chip.
    BR Martin
  • Hi Martin

    That's newer than both my kits, so I guess the old kit theory goes out the window ;)

    Do you have the log enabled while running the example?
    It would be interesting to know if the command is actually received or not. 

    With the log running you should see a message whenever the LED is turned on or off. 

    Best regards
    Torbjørn

  • 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

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

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

Related