Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

I am almost desperate: How to add battery service to UART sample correctly?

Dear Sir/Madam,

I tried to add battery service to the sample "ble_app_uart", but the code doesn't send notifications to cell phone. I struggled for several days and try compare the code with "ble_app_hrs", but still fail to find a solution. Could you tell me what I missed?  

Here is what I did to "ble_app_uart", and I also attached the code:

I worked on Keil MDK5.12, using SDK12.2,  S130,  and using the DK board (PCA10028).

1)Firstly I added the ble_bas.c to the project. I also added the path "components\ble\ble_services\ble_bas"to the project path ,so that the compiler could find the ble_bas.h file. 

2) I then defined an instance for battery service, and added the init code for battery service in services_ini() function:  Here is the services_init().

#include "ble_bas.h"

static ble_bas_t                        m_bas; 

static void services_init(void)
{
uint32_t err_code;
ble_nus_init_t nus_init;


memset(&nus_init, 0, sizeof(nus_init));
nus_init.data_handler = nus_data_handler;
err_code = ble_nus_init(&m_nus, &nus_init);
APP_ERROR_CHECK(err_code);

ble_bas_init_t bas_init;
memset(&bas_init, 0, sizeof(bas_init));
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&bas_init.battery_level_char_attr_md.cccd_write_perm);
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&bas_init.battery_level_char_attr_md.read_perm);
BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&bas_init.battery_level_char_attr_md.write_perm);

BLE_GAP_CONN_SEC_MODE_SET_OPEN(&bas_init.battery_level_report_read_perm);

bas_init.evt_handler = NULL;
bas_init.support_notification = true;
bas_init.p_report_ref = NULL;
bas_init.initial_batt_level = 100;

err_code = ble_bas_init(&m_bas,&bas_init);
APP_ERROR_CHECK(err_code);

}

3)Because I want care whether battery level changes or not. I commented the line of  "if (battery_level != p_bas->battery_level_last)"  in ble_bas_battery_level_update() function, so that I always get notification for each updates.

4)  I modified the main() so that the battery service could send out notifications by its battery level characteristic notification. The following is the main()

int main(void)
{
uint32_t err_code;
bool erase_bonds;

// Initialize.
APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_OP_QUEUE_SIZE, false);
uart_init();

buttons_leds_init(&erase_bonds);
ble_stack_init();
gap_params_init();
services_init();
advertising_init();
conn_params_init();

printf("\r\nUART Start!\r\n");
err_code = ble_advertising_start(BLE_ADV_MODE_FAST);
APP_ERROR_CHECK(err_code);

// Enter main loop.
for (;;)
{
    power_manage();
    int t;    
    for(t=0; t< 100; t++){
        ble_bas_battery_level_update(&m_bas, t);

        APP_ERROR_CHECK(err_code);
        for(int i=0; i<1000; i++) ;   //for some delay
    }

  }

}

4) Then I compiled, and load it to DK board. 

The board then starts flashing. I then run Android App "BLE Reader", the App found the "Nordic_UART" device, and connected. It then listed the service it found. There was the battery service and battery level characteristic with "Read".  When I click on the battery level characteristic, the App display "Listening", but nothing came out.  If I click "Read" button, I could see the battery level reading is always "C", and the battery level seems never changed.

Could you help me fix this problem? I guess I have missed something, but I don't know where it is. I even checked the ble_app_hrs code, and still didn't get it.

Thanks,

Jacky