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:
Wed Nov 01 15:30:21 2017 +0000
Revision:
46:6b66d08f304e
Parent:
29:7a6aff8c9468
Child:
76:e489712bcbcf
Merge pull request #112 from marcbonnici/master

Add MAC address printouts to examples
.
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 13:eaa1343657a8 17 #include <events/mbed_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 29:7a6aff8c9468 31 static EventQueue eventQueue(/* event count */ 16 * EVENTS_EVENT_SIZE);
mbed_official 4:52bffaff7f0b 32
mbed_official 4:52bffaff7f0b 33 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
mbed_official 4:52bffaff7f0b 34 {
mbed_official 4:52bffaff7f0b 35 BLE::Instance().gap().startAdvertising();
mbed_official 4:52bffaff7f0b 36 }
mbed_official 4:52bffaff7f0b 37
mbed_official 4:52bffaff7f0b 38 void updateSensorValue() {
mbed_official 4:52bffaff7f0b 39 batteryLevel++;
mbed_official 4:52bffaff7f0b 40 if (batteryLevel > 100) {
mbed_official 4:52bffaff7f0b 41 batteryLevel = 20;
mbed_official 4:52bffaff7f0b 42 }
mbed_official 4:52bffaff7f0b 43
mbed_official 4:52bffaff7f0b 44 batteryServicePtr->updateBatteryLevel(batteryLevel);
mbed_official 4:52bffaff7f0b 45 }
mbed_official 4:52bffaff7f0b 46
mbed_official 4:52bffaff7f0b 47 void blinkCallback(void)
mbed_official 4:52bffaff7f0b 48 {
mbed_official 4:52bffaff7f0b 49 led1 = !led1; /* Do blinky on LED1 while we're waiting for BLE events */
mbed_official 4:52bffaff7f0b 50
mbed_official 4:52bffaff7f0b 51 BLE &ble = BLE::Instance();
mbed_official 4:52bffaff7f0b 52 if (ble.gap().getState().connected) {
mbed_official 13:eaa1343657a8 53 eventQueue.call(updateSensorValue);
mbed_official 4:52bffaff7f0b 54 }
mbed_official 4:52bffaff7f0b 55 }
mbed_official 4:52bffaff7f0b 56
mbed_official 4:52bffaff7f0b 57 /**
mbed_official 4:52bffaff7f0b 58 * This function is called when the ble initialization process has failled
mbed_official 4:52bffaff7f0b 59 */
mbed_official 4:52bffaff7f0b 60 void onBleInitError(BLE &ble, ble_error_t error)
mbed_official 4:52bffaff7f0b 61 {
mbed_official 4:52bffaff7f0b 62 /* Initialization error handling should go here */
mbed_official 4:52bffaff7f0b 63 }
mbed_official 4:52bffaff7f0b 64
mbed_official 46:6b66d08f304e 65 void printMacAddress()
mbed_official 46:6b66d08f304e 66 {
mbed_official 46:6b66d08f304e 67 /* Print out device MAC address to the console*/
mbed_official 46:6b66d08f304e 68 Gap::AddressType_t addr_type;
mbed_official 46:6b66d08f304e 69 Gap::Address_t address;
mbed_official 46:6b66d08f304e 70 BLE::Instance().gap().getAddress(&addr_type, address);
mbed_official 46:6b66d08f304e 71 printf("DEVICE MAC ADDRESS: ");
mbed_official 46:6b66d08f304e 72 for (int i = 5; i >= 1; i--){
mbed_official 46:6b66d08f304e 73 printf("%02x:", address[i]);
mbed_official 46:6b66d08f304e 74 }
mbed_official 46:6b66d08f304e 75 printf("%02x\r\n", address[0]);
mbed_official 46:6b66d08f304e 76 }
mbed_official 46:6b66d08f304e 77
mbed_official 4:52bffaff7f0b 78 /**
mbed_official 4:52bffaff7f0b 79 * Callback triggered when the ble initialization process has finished
mbed_official 4:52bffaff7f0b 80 */
mbed_official 4:52bffaff7f0b 81 void bleInitComplete(BLE::InitializationCompleteCallbackContext *params)
mbed_official 4:52bffaff7f0b 82 {
mbed_official 4:52bffaff7f0b 83 BLE& ble = params->ble;
mbed_official 4:52bffaff7f0b 84 ble_error_t error = params->error;
mbed_official 4:52bffaff7f0b 85
mbed_official 4:52bffaff7f0b 86 if (error != BLE_ERROR_NONE) {
mbed_official 4:52bffaff7f0b 87 /* In case of error, forward the error handling to onBleInitError */
mbed_official 4:52bffaff7f0b 88 onBleInitError(ble, error);
mbed_official 4:52bffaff7f0b 89 return;
mbed_official 4:52bffaff7f0b 90 }
mbed_official 4:52bffaff7f0b 91
mbed_official 4:52bffaff7f0b 92 /* Ensure that it is the default instance of BLE */
mbed_official 4:52bffaff7f0b 93 if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) {
mbed_official 4:52bffaff7f0b 94 return;
mbed_official 4:52bffaff7f0b 95 }
mbed_official 4:52bffaff7f0b 96
mbed_official 4:52bffaff7f0b 97 ble.gap().onDisconnection(disconnectionCallback);
mbed_official 4:52bffaff7f0b 98
mbed_official 4:52bffaff7f0b 99 /* Setup primary service */
mbed_official 4:52bffaff7f0b 100 batteryServicePtr = new BatteryService(ble, batteryLevel);
mbed_official 4:52bffaff7f0b 101
mbed_official 4:52bffaff7f0b 102 /* Setup advertising */
mbed_official 4:52bffaff7f0b 103 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
mbed_official 4:52bffaff7f0b 104 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *) uuid16_list, sizeof(uuid16_list));
mbed_official 4:52bffaff7f0b 105 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *) DEVICE_NAME, sizeof(DEVICE_NAME));
mbed_official 4:52bffaff7f0b 106 ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
mbed_official 4:52bffaff7f0b 107 ble.gap().setAdvertisingInterval(1000); /* 1000ms */
mbed_official 4:52bffaff7f0b 108 ble.gap().startAdvertising();
mbed_official 46:6b66d08f304e 109
mbed_official 46:6b66d08f304e 110 printMacAddress();
mbed_official 4:52bffaff7f0b 111 }
mbed_official 4:52bffaff7f0b 112
mbed_official 4:52bffaff7f0b 113 void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) {
mbed_official 4:52bffaff7f0b 114 BLE &ble = BLE::Instance();
mbed_official 13:eaa1343657a8 115 eventQueue.call(Callback<void()>(&ble, &BLE::processEvents));
mbed_official 4:52bffaff7f0b 116 }
mbed_official 4:52bffaff7f0b 117
mbed_official 4:52bffaff7f0b 118 int main()
mbed_official 4:52bffaff7f0b 119 {
mbed_official 13:eaa1343657a8 120 eventQueue.call_every(500, blinkCallback);
mbed_official 4:52bffaff7f0b 121
mbed_official 4:52bffaff7f0b 122 BLE &ble = BLE::Instance();
mbed_official 4:52bffaff7f0b 123 ble.onEventsToProcess(scheduleBleEventsProcessing);
mbed_official 4:52bffaff7f0b 124 ble.init(bleInitComplete);
mbed_official 4:52bffaff7f0b 125
mbed_official 13:eaa1343657a8 126 eventQueue.dispatch_forever();
mbed_official 4:52bffaff7f0b 127
mbed_official 4:52bffaff7f0b 128 return 0;
mbed_official 4:52bffaff7f0b 129 }