BLE_Button is a BLE service template. It handles a read-only characteristic with a simple input (boolean values). The input's source is the button on the board itself - the characteristic's value changes when the button is pressed or released. The canonical source for this example lives at https://github.com/ARMmbed/mbed-os-example-ble/tree/master/BLE_Button

BLE_Button is a BLE service template. It handles a read-only characteristic with a simple input (boolean values). The input's source is the button on the board itself - the characteristic's value changes when the button is pressed or released.

The template covers:

  • Setting up advertising and connection modes.
  • Creating an input characteristic: read-only, boolean, with notifications.
  • Constructing a service class and adding it to the BLE stack.
  • Assigning UUIDs to the service and its characteristic.
  • Pushing notifications when the characteristic's value changes.

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-Button/raw-file/3fe9d5124576/img/start_scan.png

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

  • Find your device; it should appear with the name `Button` in the scanner.

https://developer.mbed.org/teams/mbed-os-examples/code/mbed-os-example-ble-Button/raw-file/3fe9d5124576/img/scan_results.png

figure 2 Scan results using nRF Master Control Panel 4.0.5

  • Establish a connection with the device.

https://developer.mbed.org/teams/mbed-os-examples/code/mbed-os-example-ble-Button/raw-file/3fe9d5124576/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 Button service has the UUID `0xA000` and includes the Button state characteristic which has the UUID `0xA001`. Depending on your scanner, non standard 16-bit UUID's can be displayed as 128-bit UUID's. If it is the case the following format will be used: `0000XXXX-0000-1000-8000-00805F9B34FB` where `XXXX` is the hexadecimal representation of the 16-bit UUID value.

https://developer.mbed.org/teams/mbed-os-examples/code/mbed-os-example-ble-Button/raw-file/3fe9d5124576/img/discovery.png

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

  • Register for the notifications sent by the button state characteristic then the scanner will automatically receive a notification containing the new state of the button every time the state of the button changes.

https://developer.mbed.org/teams/mbed-os-examples/code/mbed-os-example-ble-Button/raw-file/3fe9d5124576/img/register_to_notifications.png

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

  • Pressing Button 1 on your board updates the state of the button and sends a notification to the scanner. The new state of the button characteristic value should be equal to 0x01.

https://developer.mbed.org/teams/mbed-os-examples/code/mbed-os-example-ble-Button/raw-file/3fe9d5124576/img/button_pressed.png

figure 6 Notification of button pressed using Master Control Panel 4.0.5

  • Releasing Button 1 on your board updates the state of the button and sends a notification to the scanner. The new state of the button characteristic value should be equal to 0x00.

https://developer.mbed.org/teams/mbed-os-examples/code/mbed-os-example-ble-Button/raw-file/3fe9d5124576/img/button_depressed.png

figure 7 Notification of button depressed using Master Control Panel 4.0.5

Committer:
mbed_official
Date:
Wed Nov 01 15:30:37 2017 +0000
Revision:
47:6aa590a64e1e
Parent:
30:84797119c14a
Child:
78:f06ac76a8f6d
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
Vincent Coubard 0:3fe9d5124576 1 /* mbed Microcontroller Library
Vincent Coubard 0:3fe9d5124576 2 * Copyright (c) 2006-2013 ARM Limited
Vincent Coubard 0:3fe9d5124576 3 *
Vincent Coubard 0:3fe9d5124576 4 * Licensed under the Apache License, Version 2.0 (the "License");
Vincent Coubard 0:3fe9d5124576 5 * you may not use this file except in compliance with the License.
Vincent Coubard 0:3fe9d5124576 6 * You may obtain a copy of the License at
Vincent Coubard 0:3fe9d5124576 7 *
Vincent Coubard 0:3fe9d5124576 8 * http://www.apache.org/licenses/LICENSE-2.0
Vincent Coubard 0:3fe9d5124576 9 *
Vincent Coubard 0:3fe9d5124576 10 * Unless required by applicable law or agreed to in writing, software
Vincent Coubard 0:3fe9d5124576 11 * distributed under the License is distributed on an "AS IS" BASIS,
Vincent Coubard 0:3fe9d5124576 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Vincent Coubard 0:3fe9d5124576 13 * See the License for the specific language governing permissions and
Vincent Coubard 0:3fe9d5124576 14 * limitations under the License.
Vincent Coubard 0:3fe9d5124576 15 */
mbed_official 14:014670ad5e18 16 #include <events/mbed_events.h>
Vincent Coubard 0:3fe9d5124576 17
Vincent Coubard 0:3fe9d5124576 18 #include <mbed.h>
Vincent Coubard 0:3fe9d5124576 19 #include "ble/BLE.h"
Vincent Coubard 0:3fe9d5124576 20 #include "ble/Gap.h"
Vincent Coubard 0:3fe9d5124576 21 #include "ButtonService.h"
Vincent Coubard 0:3fe9d5124576 22
Vincent Coubard 0:3fe9d5124576 23 DigitalOut led1(LED1, 1);
mbed_official 5:b630d2a88c51 24 InterruptIn button(BLE_BUTTON_PIN_NAME);
Vincent Coubard 0:3fe9d5124576 25
mbed_official 30:84797119c14a 26 static EventQueue eventQueue(/* event count */ 10 * EVENTS_EVENT_SIZE);
Vincent Coubard 0:3fe9d5124576 27
Vincent Coubard 0:3fe9d5124576 28 const static char DEVICE_NAME[] = "Button";
Vincent Coubard 0:3fe9d5124576 29 static const uint16_t uuid16_list[] = {ButtonService::BUTTON_SERVICE_UUID};
Vincent Coubard 0:3fe9d5124576 30
Vincent Coubard 0:3fe9d5124576 31 ButtonService *buttonServicePtr;
Vincent Coubard 0:3fe9d5124576 32
Vincent Coubard 0:3fe9d5124576 33 void buttonPressedCallback(void)
Vincent Coubard 0:3fe9d5124576 34 {
mbed_official 14:014670ad5e18 35 eventQueue.call(Callback<void(bool)>(buttonServicePtr, &ButtonService::updateButtonState), true);
Vincent Coubard 0:3fe9d5124576 36 }
Vincent Coubard 0:3fe9d5124576 37
Vincent Coubard 0:3fe9d5124576 38 void buttonReleasedCallback(void)
Vincent Coubard 0:3fe9d5124576 39 {
mbed_official 14:014670ad5e18 40 eventQueue.call(Callback<void(bool)>(buttonServicePtr, &ButtonService::updateButtonState), false);
Vincent Coubard 0:3fe9d5124576 41 }
Vincent Coubard 0:3fe9d5124576 42
Vincent Coubard 0:3fe9d5124576 43 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
Vincent Coubard 0:3fe9d5124576 44 {
Vincent Coubard 0:3fe9d5124576 45 BLE::Instance().gap().startAdvertising(); // restart advertising
Vincent Coubard 0:3fe9d5124576 46 }
Vincent Coubard 0:3fe9d5124576 47
Vincent Coubard 0:3fe9d5124576 48 void blinkCallback(void)
Vincent Coubard 0:3fe9d5124576 49 {
Vincent Coubard 0:3fe9d5124576 50 led1 = !led1; /* Do blinky on LED1 to indicate system aliveness. */
Vincent Coubard 0:3fe9d5124576 51 }
Vincent Coubard 0:3fe9d5124576 52
Vincent Coubard 0:3fe9d5124576 53 void onBleInitError(BLE &ble, ble_error_t error)
Vincent Coubard 0:3fe9d5124576 54 {
Vincent Coubard 0:3fe9d5124576 55 /* Initialization error handling should go here */
Vincent Coubard 0:3fe9d5124576 56 }
Vincent Coubard 0:3fe9d5124576 57
mbed_official 47:6aa590a64e1e 58 void printMacAddress()
mbed_official 47:6aa590a64e1e 59 {
mbed_official 47:6aa590a64e1e 60 /* Print out device MAC address to the console*/
mbed_official 47:6aa590a64e1e 61 Gap::AddressType_t addr_type;
mbed_official 47:6aa590a64e1e 62 Gap::Address_t address;
mbed_official 47:6aa590a64e1e 63 BLE::Instance().gap().getAddress(&addr_type, address);
mbed_official 47:6aa590a64e1e 64 printf("DEVICE MAC ADDRESS: ");
mbed_official 47:6aa590a64e1e 65 for (int i = 5; i >= 1; i--){
mbed_official 47:6aa590a64e1e 66 printf("%02x:", address[i]);
mbed_official 47:6aa590a64e1e 67 }
mbed_official 47:6aa590a64e1e 68 printf("%02x\r\n", address[0]);
mbed_official 47:6aa590a64e1e 69 }
mbed_official 47:6aa590a64e1e 70
Vincent Coubard 0:3fe9d5124576 71 void bleInitComplete(BLE::InitializationCompleteCallbackContext *params)
Vincent Coubard 0:3fe9d5124576 72 {
Vincent Coubard 0:3fe9d5124576 73 BLE& ble = params->ble;
Vincent Coubard 0:3fe9d5124576 74 ble_error_t error = params->error;
Vincent Coubard 0:3fe9d5124576 75
Vincent Coubard 0:3fe9d5124576 76 if (error != BLE_ERROR_NONE) {
Vincent Coubard 0:3fe9d5124576 77 /* In case of error, forward the error handling to onBleInitError */
Vincent Coubard 0:3fe9d5124576 78 onBleInitError(ble, error);
Vincent Coubard 0:3fe9d5124576 79 return;
Vincent Coubard 0:3fe9d5124576 80 }
Vincent Coubard 0:3fe9d5124576 81
Vincent Coubard 0:3fe9d5124576 82 /* Ensure that it is the default instance of BLE */
Vincent Coubard 0:3fe9d5124576 83 if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) {
Vincent Coubard 0:3fe9d5124576 84 return;
Vincent Coubard 0:3fe9d5124576 85 }
Vincent Coubard 0:3fe9d5124576 86
Vincent Coubard 0:3fe9d5124576 87 ble.gap().onDisconnection(disconnectionCallback);
Vincent Coubard 0:3fe9d5124576 88
Vincent Coubard 0:3fe9d5124576 89 button.fall(buttonPressedCallback);
Vincent Coubard 0:3fe9d5124576 90 button.rise(buttonReleasedCallback);
Vincent Coubard 0:3fe9d5124576 91
Vincent Coubard 0:3fe9d5124576 92 /* Setup primary service. */
Vincent Coubard 0:3fe9d5124576 93 buttonServicePtr = new ButtonService(ble, false /* initial value for button pressed */);
Vincent Coubard 0:3fe9d5124576 94
Vincent Coubard 0:3fe9d5124576 95 /* setup advertising */
Vincent Coubard 0:3fe9d5124576 96 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
Vincent Coubard 0:3fe9d5124576 97 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list));
Vincent Coubard 0:3fe9d5124576 98 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
Vincent Coubard 0:3fe9d5124576 99 ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
Vincent Coubard 0:3fe9d5124576 100 ble.gap().setAdvertisingInterval(1000); /* 1000ms. */
Vincent Coubard 0:3fe9d5124576 101 ble.gap().startAdvertising();
mbed_official 47:6aa590a64e1e 102
mbed_official 47:6aa590a64e1e 103 printMacAddress();
Vincent Coubard 0:3fe9d5124576 104 }
Vincent Coubard 0:3fe9d5124576 105
Vincent Coubard 0:3fe9d5124576 106 void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) {
Vincent Coubard 0:3fe9d5124576 107 BLE &ble = BLE::Instance();
mbed_official 14:014670ad5e18 108 eventQueue.call(Callback<void()>(&ble, &BLE::processEvents));
Vincent Coubard 0:3fe9d5124576 109 }
Vincent Coubard 0:3fe9d5124576 110
Vincent Coubard 0:3fe9d5124576 111 int main()
Vincent Coubard 0:3fe9d5124576 112 {
mbed_official 14:014670ad5e18 113 eventQueue.call_every(500, blinkCallback);
Vincent Coubard 0:3fe9d5124576 114
Vincent Coubard 0:3fe9d5124576 115 BLE &ble = BLE::Instance();
Vincent Coubard 0:3fe9d5124576 116 ble.onEventsToProcess(scheduleBleEventsProcessing);
Vincent Coubard 0:3fe9d5124576 117 ble.init(bleInitComplete);
Vincent Coubard 0:3fe9d5124576 118
mbed_official 14:014670ad5e18 119 eventQueue.dispatch_forever();
Vincent Coubard 0:3fe9d5124576 120
Vincent Coubard 0:3fe9d5124576 121 return 0;
Vincent Coubard 0:3fe9d5124576 122 }