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

notification_timeout_handler no longer working when NRF_SDH_BLE_OBSERVERS() is used (SDK v15)

Hi in my original code when notifications is turned on for custom characteristic the characteristic value would increment every second. However after I add  NRF_SDH_BLE_OBSERVERS() so I can add multiple custom services, I notice the characteristic value no longer increments every second when notifications is turned on. 

If I switch back to NRF_SDH_BLE_OBSERVER() and turn on notifications the characteristic value increments every second again. 

/*
#define BLE_CUS_DEF(_name)                                                                          \
static ble_cus_t _name;                                                                             \
NRF_SDH_BLE_OBSERVER(_name ## _obs,                                                                 \
                     BLE_HRS_BLE_OBSERVER_PRIO,                                                     \
                     ble_cus_on_ble_evt, &_name)
                     */

#define BLE_CUS_DEF(_name)                                                                          \
static ble_cus_t _name;                                                                               
#define BLE_CUS_DEF2(_name2)                                                                          \
static ble_cus_t _name2;                                                                               //\
#define ble_cus_t* cus_array[] = {&_name, &_name2};                                                            \
NRF_SDH_BLE_OBSERVERS(_name ## _obs,                                                                 \
                     BLE_HRS_BLE_OBSERVER_PRIO,                                                     \
                     ble_cus_on_ble_evt, cus_array, 2)

In the code, 'notification_timeout_handler' is called when the repeated app timer 'm_notification_timer_id' expires. The 'notification_timeout_handler' increments the value of integer variable 'm_custom_value' each time the app_timer event handler is called. 

APP_TIMER_DEF(m_notification_timer_id);

static uint8_t m_custom_value = 0;
static uint8_t notif_bool = 0;


static void notification_timeout_handler(void * p_context)
{
    UNUSED_PARAMETER(p_context);
    ret_code_t err_code;
    
    // Increment the value of m_custom_value before nortifing it.
    m_custom_value++;

    if(notif_bool == 1){
       err_code = ble_cus_custom_value_update(&m_cus, m_custom_value);
       //APP_ERROR_CHECK(err_code);
    }
}

static void timers_init(void)
{
    // Initialize timer module.
    ret_code_t err_code = app_timer_init();
    APP_ERROR_CHECK(err_code);

    // Create timers.
    err_code = app_timer_create(&m_notification_timer_id, APP_TIMER_MODE_REPEATED, notification_timeout_handler);
    APP_ERROR_CHECK(err_code);

}

tatic void on_cus_evt(ble_cus_t     * p_cus_service,
                       ble_cus_evt_t * p_evt)
{
    ret_code_t err_code;
    
    switch(p_evt->evt_type)
    {
        case BLE_CUS_EVT_NOTIFICATION_ENABLED:
             
             notif_bool = 1;
             break;

        case BLE_CUS_EVT_NOTIFICATION_DISABLED:

            break;
}

I also attached the project files below.

multiple_cus_app_timer.zip

Why does calling NRF_SDH_BLE_OBSERVERS() to register multiple custom services cause the event handler call from the repeated app timer to not work? Is there a way to fix this if I want to have multiple custom services and the app_timer event handler?

Parents
  • Hi,

    I do not see why the event handler should cause a problem with the app timer. However, I am not able to test your application since it is missing sdk_config.h, and also there is a problem with the paths. Can you upload an example that I can just drop into a specified folder in the SDK and test? Does it run on the DK?

  • ble_app_template_app_timer.zip

    Hi you can try this above. It contains the sdk_config.h files and you should be able to drop it into the examples subfolder of the SDK folder  to run. The code compiles and runs on the DK.

    If I use this in the ble_cus.h code below and turn on notifications for the custom characteristic, the characteristic value will not increment as the repeated app_timer keeps incrementing m_custom_value. I do not know why this happens.

    /*
    #define BLE_CUS_DEF(_name)                                                                          \
    static ble_cus_t _name;                                                                             \
    NRF_SDH_BLE_OBSERVER(_name ## _obs,                                                                 \
                         BLE_HRS_BLE_OBSERVER_PRIO,                                                     \
                         ble_cus_on_ble_evt, &_name)
                         */
    
    #define BLE_CUS_DEF(_name)                                                                          \
    static ble_cus_t _name;                                                                               
    #define BLE_CUS_DEF2(_name2)                                                                          \
    static ble_cus_t _name2;                                                                               //\
    #define ble_cus_t* cus_array[] = {&_name, &_name2};                                                            \
    NRF_SDH_BLE_OBSERVERS(_name ## _obs,                                                                 \
                         BLE_HRS_BLE_OBSERVER_PRIO,                                                     \
                         ble_cus_on_ble_evt, cus_array, 2)

    If I use this in the ble_cus.h code below (I comment out the NRF_SDH_BLE_OBSERVERS() code and use NRF_SDH_BLE_OBSERVER() instead) and then turn on notifications for the custom characteristic, the characteristic value will work again. As in the characteristic value will now increment as the repeated app_timer keeps incrementing m_custom_value.

    #define BLE_CUS_DEF(_name)                                                                          \
    static ble_cus_t _name;                                                                             \
    NRF_SDH_BLE_OBSERVER(_name ## _obs,                                                                 \
                         BLE_HRS_BLE_OBSERVER_PRIO,                                                     \
                         ble_cus_on_ble_evt, &_name)
                         
    /*
    #define BLE_CUS_DEF(_name)                                                                          \
    static ble_cus_t _name;                                                                               
    #define BLE_CUS_DEF2(_name2)                                                                          \
    static ble_cus_t _name2;                                                                               //\
    #define ble_cus_t* cus_array[] = {&_name, &_name2};                                                            \
    NRF_SDH_BLE_OBSERVERS(_name ## _obs,                                                                 \
                         BLE_HRS_BLE_OBSERVER_PRIO,                                                     \
                         ble_cus_on_ble_evt, cus_array, 2)
                         */

Reply
  • ble_app_template_app_timer.zip

    Hi you can try this above. It contains the sdk_config.h files and you should be able to drop it into the examples subfolder of the SDK folder  to run. The code compiles and runs on the DK.

    If I use this in the ble_cus.h code below and turn on notifications for the custom characteristic, the characteristic value will not increment as the repeated app_timer keeps incrementing m_custom_value. I do not know why this happens.

    /*
    #define BLE_CUS_DEF(_name)                                                                          \
    static ble_cus_t _name;                                                                             \
    NRF_SDH_BLE_OBSERVER(_name ## _obs,                                                                 \
                         BLE_HRS_BLE_OBSERVER_PRIO,                                                     \
                         ble_cus_on_ble_evt, &_name)
                         */
    
    #define BLE_CUS_DEF(_name)                                                                          \
    static ble_cus_t _name;                                                                               
    #define BLE_CUS_DEF2(_name2)                                                                          \
    static ble_cus_t _name2;                                                                               //\
    #define ble_cus_t* cus_array[] = {&_name, &_name2};                                                            \
    NRF_SDH_BLE_OBSERVERS(_name ## _obs,                                                                 \
                         BLE_HRS_BLE_OBSERVER_PRIO,                                                     \
                         ble_cus_on_ble_evt, cus_array, 2)

    If I use this in the ble_cus.h code below (I comment out the NRF_SDH_BLE_OBSERVERS() code and use NRF_SDH_BLE_OBSERVER() instead) and then turn on notifications for the custom characteristic, the characteristic value will work again. As in the characteristic value will now increment as the repeated app_timer keeps incrementing m_custom_value.

    #define BLE_CUS_DEF(_name)                                                                          \
    static ble_cus_t _name;                                                                             \
    NRF_SDH_BLE_OBSERVER(_name ## _obs,                                                                 \
                         BLE_HRS_BLE_OBSERVER_PRIO,                                                     \
                         ble_cus_on_ble_evt, &_name)
                         
    /*
    #define BLE_CUS_DEF(_name)                                                                          \
    static ble_cus_t _name;                                                                               
    #define BLE_CUS_DEF2(_name2)                                                                          \
    static ble_cus_t _name2;                                                                               //\
    #define ble_cus_t* cus_array[] = {&_name, &_name2};                                                            \
    NRF_SDH_BLE_OBSERVERS(_name ## _obs,                                                                 \
                         BLE_HRS_BLE_OBSERVER_PRIO,                                                     \
                         ble_cus_on_ble_evt, cus_array, 2)
                         */

Children
  • Hi,

    I had to adjust your sdk_config.h file and SES project settings to make the project run (ble_cus.c was not added to the project, NRF_SDH_BLE_VS_UUID_COUNT in sdk_config.h was 0 but should be 1, and adjusting that requires the RAM start address and size to be adjusted). Once I did I reproduced the error. Then I looked at your code, and the error is in fact quite obvious.

    Looking at the first code snippet in your last post (the one with problems), there is no wonder things are not working. The only two lines that are actually relevant (meaning is ever executed) is 9-10, so the only thing you do is make a static variable _name. You ever call NRF_SDH_BLE_OBSERVERS(), since you never call BLE_CUS_DEF2(). And in fact that would not have worked either since you have commented out the backslash on line 12 (still in the first code snippet.

    So to break it down, the actual definition of BLE_CUS_DEF() in your code is:

    #define BLE_CUS_DEF(_name)                                                                          \
    static ble_cus_t _name;                                                                               

    And the actual definition of BLE_CUS_DEF2() is:

    #define BLE_CUS_DEF2(_name2)                                                                          \
    static ble_cus_t _name2;                                                                              

    So you will never actually call NRF_SDH_BLE_OBSERVERS() this way. I suggest you copy the approach from the other SDK service implementations if you want a macro to make multiple instances (you can look at line 98-102 in <SDK15.3>\components\ble\ble_services\ble_dis_c\ble_dis_c.h, or any of the other services in the SDK).

  • Hi Einar,

    I had previously wrote the code to include the second custom service that did call BLE_CUS_DEF2() as well as BLE_CUS_DEF(). Even when that code called the second custom service the characteristic value for the first custom characteristic did not increment after I turned on notifications.

    And in fact that would not have worked either since you have commented out the backslash on line 12 (still in the first code snippet.

    Also note that when I do not uncomment out the backslash I get errors after I call BLE_CUS_DEF2(_name2);

    I've attached the code that does add the second custom service (after the code below is flashed to DK you will see two custom services now).

    So will the code below actually not call NRF_SDH_BLE_OBSERVERS() either?

    nordic_multiple_cus.zip

     

  • I suggest you copy the approach from the other SDK service implementations if you want a macro to make multiple instances (you can look at line 98-102 in <SDK15.3>\components\ble\ble_services\ble_dis_c\ble_dis_c.h, or any of the other services in the SDK).

    I also checked this and the macro #define BLE_DIS_C_ARRAY_DEF(_name,_cnt) is identical to the Nordic documentation for NRF_SDH_BLE_OBSERVERS(). I know you are supposed to pass in the number of custom services you want to register to the _cnt argument of the macro.

    But (like the Nordic documentation) it doesn't show or explain how to register the array of event handlers for the multiple custom services or create the array of multiple nrf_sdh_ble_evt_observer_t that can be passed in to  NRF_SDH_BLE_OBSERVERS().

    #define BLE_DIS_C_ARRAY_DEF(_name, _cnt)                 \
        static ble_dis_c_t  _name[_cnt];                     \
        NRF_SDH_BLE_OBSERVERS(_name ## _obs,                 \
                            BLE_DIS_C_BLE_OBSERVER_PRIO,     \
                            ble_dis_c_on_ble_evt, &_name, _cnt)

  • thoric_fish said:
    Also note that when I do not uncomment out the backslash I get errors after I call BLE_CUS_DEF2(_name2);

    That may be, but C preprocessor macros are by definition always on one line. I can explain by showing an intermediate step in addition to the one from my previous post. Let's put everything on one line like the preprocessor does (when you escape the newline with \), but also let's keep the comments as the intermediate step.

    When it comes to BLE_CUS_DEF() that is straightforward. "#define BLE_CUS_DEF(_name)" expands to:

    static ble_cus_t _name;

    For "#define BLE_CUS_DEF2(_name2)" we first get (just removing the newlines and additional whitespaces):

    static ble_cus_t _name2; // #define ble_cus_t* cus_array[] = {&_name, &_name2}; NRF_SDH_BLE_OBSERVERS(_name ## _obs, BLE_HRS_BLE_OBSERVER_PRIO, ble_cus_on_ble_evt, cus_array, 2)

    As you can see everything after // is commented out, so it really ends up with:

    static ble_cus_t _name2;

    ...and this is clearly not what you want.

  • Hi Einar,

    Is there also an available example of how to set up the array of custom service instances to pass into the '_name' parameter of the macro BLE_DIS_C_ARRAY_DEF() or NRF_SDH_BLE_OBSERVERS()?  

Related