This example creates and updates a standard Battery Level service containing a single GATT characteristic. The battery service transmits a device's battery level in percentage, with 100% being a fully charged battery and 0% being a fully drained battery. The canonical source for this example lives at https://github.com/ARMmbed/mbed-os-example-ble/tree/master/BLE_BatteryLevel

This example creates and updates a standard Battery Level service containing a single GATT characteristic.

The battery service transmits a device's battery level in percentage, with 100% being a fully charged battery and 0% being a fully drained battery.

Although the sample application runs on a BLE device, it doesn't show the device's real battery level (because that changes very slowly and will make for a dull example). Instead, it transmits a fake battery level that starts at 50% (half charged). Every half second, it increments the battery level, going in single increments until reaching 100% (as if the battery is charging). It then drops down to 20% to start incrementing again.

Running the application

Requirements

The sample application can be seen on any BLE scanner on a smartphone. If you don't have a scanner on your phone, please install :

- nRF Master Control Panel for Android.

- LightBlue for iPhone.

Hardware requirements are in the main readme.

Building instructions

Building with mbed CLI

If you'd like to use mbed CLI to build this, then you should refer to the main readme. The instructions here relate to using the developer.mbed.org Online Compiler

In order to build this example in the mbed Online Compiler, first import the example using the ‘Import’ button on the right hand side.

Next, select a platform to build for. This must either be a platform that supports BLE, for example the NRF51-DK, or one of the following:

List of platforms supporting Bluetooth Low Energy

Or you must also add a piece of hardware and the supporting library that includes a Bluetooth Low Energy driver for that hardware, for example the K64F or NUCLEO_F401RE with the X-NUCLEO-IDB05A1

List of components supporting Bluetooth Low Energy.

Once you have selected your platform, compile the example and drag and drop the resulting binary onto your board.

For general instructions on using the mbed Online Compiler, please see the mbed Handbook

Checking for success

Note: Screens captures depicted below show what is expected from this example if the scanner used is nRF Master Control Panel version 4.0.5. If you encounter any difficulties consider trying another scanner or another version of nRF Master Control Panel. Alternative scanners may require reference to their manuals.

  • Build the application and install it on your board as explained in the building instructions.
  • Open the BLE scanner on your phone.
  • Start a scan.

https://developer.mbed.org/teams/mbed-os-examples/code/mbed-os-example-ble-BatteryLevel/raw-file/a5ac4bf2e468/img/start_scan.png

figure 1 How to start scan using nRF Master Control Panel 4.0.5

  • Find your device; it should be named `BATTERY`.

https://developer.mbed.org/teams/mbed-os-examples/code/mbed-os-example-ble-BatteryLevel/raw-file/a5ac4bf2e468/img/scan_result.png

figure 2 Scan results using nRF Master Control Panel 4.0.5

  • Establish a connection with your device.

https://developer.mbed.org/teams/mbed-os-examples/code/mbed-os-example-ble-BatteryLevel/raw-file/a5ac4bf2e468/img/connection.png

figure 3 How to establish a connection using Master Control Panel 4.0.5

  • Discover the services and the characteristics on the device. The *Battery service* has the UUID 0x180F and includes the *Battery level* characteristic which has the UUID 0x2A19.

https://developer.mbed.org/teams/mbed-os-examples/code/mbed-os-example-ble-BatteryLevel/raw-file/a5ac4bf2e468/img/discovery.png

figure 4 Representation of the Battery service using Master Control Panel 4.0.5

  • Register for the notifications sent by the *Battery level* characteristic.

https://developer.mbed.org/teams/mbed-os-examples/code/mbed-os-example-ble-BatteryLevel/raw-file/a5ac4bf2e468/img/register_to_notifications.png

figure 5 How to register to notifications using Master Control Panel 4.0.5

  • You should see the battery level value change every half second. It begins at 50, goes up to 100 (in steps of 1), resets to 20 and so on.

https://developer.mbed.org/teams/mbed-os-examples/code/mbed-os-example-ble-BatteryLevel/raw-file/a5ac4bf2e468/img/notifications.png

figure 6 Notifications view using Master Control Panel 4.0.5

If you can see the characteristic, and if its value is incrementing correctly, the application is working properly.

Committer:
mbed_official
Date:
Fri Jul 29 22:45:21 2016 +0100
Revision:
4:52bffaff7f0b
Parent:
3:488ecd009a27
Child:
13:eaa1343657a8
Merge branch 'master' of https://github.com/ARMmbed/mbed-os-example-ble


Commit copied from https://github.com/ARMmbed/mbed-os-example-ble

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 4:52bffaff7f0b 1 /* mbed Microcontroller Library
mbed_official 4:52bffaff7f0b 2 * Copyright (c) 2006-2014 ARM Limited
mbed_official 4:52bffaff7f0b 3 *
mbed_official 4:52bffaff7f0b 4 * Licensed under the Apache License, Version 2.0 (the "License");
mbed_official 4:52bffaff7f0b 5 * you may not use this file except in compliance with the License.
mbed_official 4:52bffaff7f0b 6 * You may obtain a copy of the License at
mbed_official 4:52bffaff7f0b 7 *
mbed_official 4:52bffaff7f0b 8 * http://www.apache.org/licenses/LICENSE-2.0
mbed_official 4:52bffaff7f0b 9 *
mbed_official 4:52bffaff7f0b 10 * Unless required by applicable law or agreed to in writing, software
mbed_official 4:52bffaff7f0b 11 * distributed under the License is distributed on an "AS IS" BASIS,
mbed_official 4:52bffaff7f0b 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
mbed_official 4:52bffaff7f0b 13 * See the License for the specific language governing permissions and
mbed_official 4:52bffaff7f0b 14 * limitations under the License.
mbed_official 4:52bffaff7f0b 15 */
mbed_official 4:52bffaff7f0b 16
mbed_official 4:52bffaff7f0b 17 #include <mbed-events/events.h>
mbed_official 4:52bffaff7f0b 18 #include <mbed.h>
mbed_official 4:52bffaff7f0b 19 #include "ble/BLE.h"
mbed_official 4:52bffaff7f0b 20 #include "ble/Gap.h"
mbed_official 4:52bffaff7f0b 21 #include "ble/services/BatteryService.h"
mbed_official 4:52bffaff7f0b 22
mbed_official 4:52bffaff7f0b 23 DigitalOut led1(LED1, 1);
mbed_official 4:52bffaff7f0b 24
mbed_official 4:52bffaff7f0b 25 const static char DEVICE_NAME[] = "BATTERY";
mbed_official 4:52bffaff7f0b 26 static const uint16_t uuid16_list[] = {GattService::UUID_BATTERY_SERVICE};
mbed_official 4:52bffaff7f0b 27
mbed_official 4:52bffaff7f0b 28 static uint8_t batteryLevel = 50;
mbed_official 4:52bffaff7f0b 29 static BatteryService* batteryServicePtr;
mbed_official 4:52bffaff7f0b 30
mbed_official 4:52bffaff7f0b 31 static EventQueue eventQueue(
mbed_official 4:52bffaff7f0b 32 /* event count */ 16 * /* event size */ 32
mbed_official 4:52bffaff7f0b 33 );
mbed_official 4:52bffaff7f0b 34
mbed_official 4:52bffaff7f0b 35 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
mbed_official 4:52bffaff7f0b 36 {
mbed_official 4:52bffaff7f0b 37 BLE::Instance().gap().startAdvertising();
mbed_official 4:52bffaff7f0b 38 }
mbed_official 4:52bffaff7f0b 39
mbed_official 4:52bffaff7f0b 40 void updateSensorValue() {
mbed_official 4:52bffaff7f0b 41 batteryLevel++;
mbed_official 4:52bffaff7f0b 42 if (batteryLevel > 100) {
mbed_official 4:52bffaff7f0b 43 batteryLevel = 20;
mbed_official 4:52bffaff7f0b 44 }
mbed_official 4:52bffaff7f0b 45
mbed_official 4:52bffaff7f0b 46 batteryServicePtr->updateBatteryLevel(batteryLevel);
mbed_official 4:52bffaff7f0b 47 }
mbed_official 4:52bffaff7f0b 48
mbed_official 4:52bffaff7f0b 49 void blinkCallback(void)
mbed_official 4:52bffaff7f0b 50 {
mbed_official 4:52bffaff7f0b 51 led1 = !led1; /* Do blinky on LED1 while we're waiting for BLE events */
mbed_official 4:52bffaff7f0b 52
mbed_official 4:52bffaff7f0b 53 BLE &ble = BLE::Instance();
mbed_official 4:52bffaff7f0b 54 if (ble.gap().getState().connected) {
mbed_official 4:52bffaff7f0b 55 eventQueue.post(updateSensorValue);
mbed_official 4:52bffaff7f0b 56 }
mbed_official 4:52bffaff7f0b 57 }
mbed_official 4:52bffaff7f0b 58
mbed_official 4:52bffaff7f0b 59 /**
mbed_official 4:52bffaff7f0b 60 * This function is called when the ble initialization process has failled
mbed_official 4:52bffaff7f0b 61 */
mbed_official 4:52bffaff7f0b 62 void onBleInitError(BLE &ble, ble_error_t error)
mbed_official 4:52bffaff7f0b 63 {
mbed_official 4:52bffaff7f0b 64 /* Initialization error handling should go here */
mbed_official 4:52bffaff7f0b 65 }
mbed_official 4:52bffaff7f0b 66
mbed_official 4:52bffaff7f0b 67 /**
mbed_official 4:52bffaff7f0b 68 * Callback triggered when the ble initialization process has finished
mbed_official 4:52bffaff7f0b 69 */
mbed_official 4:52bffaff7f0b 70 void bleInitComplete(BLE::InitializationCompleteCallbackContext *params)
mbed_official 4:52bffaff7f0b 71 {
mbed_official 4:52bffaff7f0b 72 BLE& ble = params->ble;
mbed_official 4:52bffaff7f0b 73 ble_error_t error = params->error;
mbed_official 4:52bffaff7f0b 74
mbed_official 4:52bffaff7f0b 75 if (error != BLE_ERROR_NONE) {
mbed_official 4:52bffaff7f0b 76 /* In case of error, forward the error handling to onBleInitError */
mbed_official 4:52bffaff7f0b 77 onBleInitError(ble, error);
mbed_official 4:52bffaff7f0b 78 return;
mbed_official 4:52bffaff7f0b 79 }
mbed_official 4:52bffaff7f0b 80
mbed_official 4:52bffaff7f0b 81 /* Ensure that it is the default instance of BLE */
mbed_official 4:52bffaff7f0b 82 if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) {
mbed_official 4:52bffaff7f0b 83 return;
mbed_official 4:52bffaff7f0b 84 }
mbed_official 4:52bffaff7f0b 85
mbed_official 4:52bffaff7f0b 86 ble.gap().onDisconnection(disconnectionCallback);
mbed_official 4:52bffaff7f0b 87
mbed_official 4:52bffaff7f0b 88 /* Setup primary service */
mbed_official 4:52bffaff7f0b 89 batteryServicePtr = new BatteryService(ble, batteryLevel);
mbed_official 4:52bffaff7f0b 90
mbed_official 4:52bffaff7f0b 91 /* Setup advertising */
mbed_official 4:52bffaff7f0b 92 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
mbed_official 4:52bffaff7f0b 93 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *) uuid16_list, sizeof(uuid16_list));
mbed_official 4:52bffaff7f0b 94 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *) DEVICE_NAME, sizeof(DEVICE_NAME));
mbed_official 4:52bffaff7f0b 95 ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
mbed_official 4:52bffaff7f0b 96 ble.gap().setAdvertisingInterval(1000); /* 1000ms */
mbed_official 4:52bffaff7f0b 97 ble.gap().startAdvertising();
mbed_official 4:52bffaff7f0b 98 }
mbed_official 4:52bffaff7f0b 99
mbed_official 4:52bffaff7f0b 100 void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) {
mbed_official 4:52bffaff7f0b 101 BLE &ble = BLE::Instance();
mbed_official 4:52bffaff7f0b 102 eventQueue.post(Callback<void()>(&ble, &BLE::processEvents));
mbed_official 4:52bffaff7f0b 103 }
mbed_official 4:52bffaff7f0b 104
mbed_official 4:52bffaff7f0b 105 int main()
mbed_official 4:52bffaff7f0b 106 {
mbed_official 4:52bffaff7f0b 107 eventQueue.post_every(500, blinkCallback);
mbed_official 4:52bffaff7f0b 108
mbed_official 4:52bffaff7f0b 109 BLE &ble = BLE::Instance();
mbed_official 4:52bffaff7f0b 110 ble.onEventsToProcess(scheduleBleEventsProcessing);
mbed_official 4:52bffaff7f0b 111 ble.init(bleInitComplete);
mbed_official 4:52bffaff7f0b 112
mbed_official 4:52bffaff7f0b 113 while (true) {
mbed_official 4:52bffaff7f0b 114 eventQueue.dispatch();
mbed_official 4:52bffaff7f0b 115 }
mbed_official 4:52bffaff7f0b 116
mbed_official 4:52bffaff7f0b 117 return 0;
mbed_official 4:52bffaff7f0b 118 }