Skip to content

Commit 2ca4a44

Browse files
committed
Merge pull request ARMmbed#17 from andresag01/master
Bring useful examples from oob-oct15 branch
2 parents de9fe7d + e813108 commit 2ca4a44

File tree

15 files changed

+885
-0
lines changed

15 files changed

+885
-0
lines changed

Diff for: BLE_BatteryLevel/module.json

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"name": "ble-batterylevel",
3+
"version": "0.0.1",
4+
"description": "An example of creating and updating a simple GATT Service using the BLE_API",
5+
"licenses": [
6+
{
7+
"url": "https://spdx.org/licenses/Apache-2.0",
8+
"type": "Apache-2.0"
9+
}
10+
],
11+
"dependencies": {
12+
"ble": "^2.0.0"
13+
},
14+
"targetDependencies": {},
15+
"bin": "./source"
16+
}

Diff for: BLE_BatteryLevel/readme.md

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
This example creates and updates a standard Battery Level service containing a single
2+
GATT characteristic.
3+
4+
Checking for Success
5+
====================
6+
7+
Your BatteryLevel peripheral should be detectable by BLE scanners (e.g. a
8+
smartphone). To use your phone as a BLE scanner simply install one of the
9+
following apps:
10+
11+
- For Android, you can get [nRF Master Control Panel](https://play.google.com/store/apps/details?id=no.nordicsemi.android.mcp).
12+
13+
- For iPhone, you can get [LightBlue](https://itunes.apple.com/gb/app/lightblue-bluetooth-low-energy/id557428110?mt=8).
14+
15+
Using the phone app you can connect to the peripheral and observe how the
16+
battery level characteristic changes.

Diff for: BLE_BatteryLevel/source/main.cpp

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

Diff for: BLE_Button/module.json

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"name": "ble-button",
3+
"version": "0.0.1",
4+
"description": "The *input service template* demonstrates the use of a simple input (boolean values) from a read-only characteristic.",
5+
"licenses": [
6+
{
7+
"url": "https://spdx.org/licenses/Apache-2.0",
8+
"type": "Apache-2.0"
9+
}
10+
],
11+
"bin": "./source",
12+
"dependencies": {
13+
"ble": "^2.0.0"
14+
}
15+
}

Diff for: BLE_Button/readme.md

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
To help you create your own BLE services, we've created this demo application.
2+
The BLE_Button demonstrates the use of a simple input (boolean values) from a read-only characteristic.
3+
4+
The template covers:
5+
6+
1. Setting up advertising and connection states.
7+
8+
2. Assigning UUIDs to the service and its characteristic.
9+
10+
3. Creating an input characteristic: read-only, boolean, with notifications. This characteristic is updated according to the button's state.
11+
12+
4. Constructing a service class and adding it to the BLE stack.
13+
14+
Checking for Success
15+
====================
16+
17+
Your Button peripheral should be detectable by BLE scanners (e.g. a smartphone).
18+
To use your phone as a BLE scanner simply install one of the following apps:
19+
20+
- For Android, you can get [nRF Master Control Panel](https://play.google.com/store/apps/details?id=no.nordicsemi.android.mcp).
21+
22+
- For iPhone, you can get [LightBlue](https://itunes.apple.com/gb/app/lightblue-bluetooth-low-energy/id557428110?mt=8).
23+
24+
Using the phone app you can connect to the peripheral and observe how the
25+
read-only characteristic is automatically updated when you press the button
26+
in your MCU (e.g NRF51-DK). The updates occur because your peripheral is pushing
27+
notifications to the smartphone when it detects a change in the button.

Diff for: BLE_Button/source/ButtonService.h

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/* mbed Microcontroller Library
2+
* Copyright (c) 2006-2013 ARM Limited
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#ifndef __BLE_BUTTON_SERVICE_H__
18+
#define __BLE_BUTTON_SERVICE_H__
19+
20+
class ButtonService {
21+
public:
22+
const static uint16_t BUTTON_SERVICE_UUID = 0xA000;
23+
const static uint16_t BUTTON_STATE_CHARACTERISTIC_UUID = 0xA001;
24+
25+
ButtonService(BLE &_ble, bool buttonPressedInitial) :
26+
ble(_ble), buttonState(BUTTON_STATE_CHARACTERISTIC_UUID, &buttonPressedInitial, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY)
27+
{
28+
GattCharacteristic *charTable[] = {&buttonState};
29+
GattService buttonService(ButtonService::BUTTON_SERVICE_UUID, charTable, sizeof(charTable) / sizeof(GattCharacteristic *));
30+
ble.gattServer().addService(buttonService);
31+
}
32+
33+
void updateButtonState(bool newState) {
34+
ble.gattServer().write(buttonState.getValueHandle(), (uint8_t *)&newState, sizeof(bool));
35+
}
36+
37+
private:
38+
BLE &ble;
39+
ReadOnlyGattCharacteristic<bool> buttonState;
40+
};
41+
42+
#endif /* #ifndef __BLE_BUTTON_SERVICE_H__ */

Diff for: BLE_Button/source/main.cpp

+94
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/* mbed Microcontroller Library
2+
* Copyright (c) 2006-2013 ARM Limited
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#include "mbed-drivers/mbed.h"
18+
#include "ble/BLE.h"
19+
#include "ble/Gap.h"
20+
#include "ButtonService.h"
21+
22+
DigitalOut led1(LED1, 1);
23+
InterruptIn button(BUTTON1);
24+
25+
const static char DEVICE_NAME[] = "Button";
26+
static const uint16_t uuid16_list[] = {ButtonService::BUTTON_SERVICE_UUID};
27+
28+
ButtonService *buttonServicePtr;
29+
30+
void buttonPressedCallback(void)
31+
{
32+
minar::Scheduler::postCallback(mbed::util::FunctionPointer1<void, bool>(buttonServicePtr, &ButtonService::updateButtonState).bind(true));
33+
}
34+
35+
void buttonReleasedCallback(void)
36+
{
37+
minar::Scheduler::postCallback(mbed::util::FunctionPointer1<void, bool>(buttonServicePtr, &ButtonService::updateButtonState).bind(false));
38+
}
39+
40+
void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
41+
{
42+
BLE::Instance().gap().startAdvertising(); // restart advertising
43+
}
44+
45+
void blinkCallback(void)
46+
{
47+
led1 = !led1; /* Do blinky on LED1 to indicate system aliveness. */
48+
}
49+
50+
void onBleInitError(BLE &ble, ble_error_t error)
51+
{
52+
/* Initialization error handling should go here */
53+
}
54+
55+
void bleInitComplete(BLE::InitializationCompleteCallbackContext *params)
56+
{
57+
BLE& ble = params->ble;
58+
ble_error_t error = params->error;
59+
60+
if (error != BLE_ERROR_NONE) {
61+
/* In case of error, forward the error handling to onBleInitError */
62+
onBleInitError(ble, error);
63+
return;
64+
}
65+
66+
/* Ensure that it is the default instance of BLE */
67+
if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) {
68+
return;
69+
}
70+
71+
ble.gap().onDisconnection(disconnectionCallback);
72+
73+
button.fall(buttonPressedCallback);
74+
button.rise(buttonReleasedCallback);
75+
76+
/* Setup primary service. */
77+
buttonServicePtr = new ButtonService(ble, false /* initial value for button pressed */);
78+
79+
/* setup advertising */
80+
ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
81+
ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list));
82+
ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
83+
ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
84+
ble.gap().setAdvertisingInterval(1000); /* 1000ms. */
85+
ble.gap().startAdvertising();
86+
}
87+
88+
void app_start(int, char**)
89+
{
90+
minar::Scheduler::postCallback(blinkCallback).period(minar::milliseconds(500));
91+
92+
BLE &ble = BLE::Instance();
93+
ble.init(bleInitComplete);
94+
}

Diff for: BLE_EddystoneBeaconConfigService/module.json

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"name": "ble-eddystonebeaconconfigservice",
3+
"version": "0.0.1",
4+
"description": "This example demonstrates how to set up and initialize a Eddystone Beacon.",
5+
"licenses": [
6+
{
7+
"url": "https://spdx.org/licenses/Apache-2.0",
8+
"type": "Apache-2.0"
9+
}
10+
],
11+
"dependencies": {
12+
"ble": "^2.0.0"
13+
},
14+
"targetDependencies": {},
15+
"bin": "./source"
16+
}

Diff for: BLE_EddystoneBeaconConfigService/readme.md

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
This is the EddystoneBeaconConfigService. This code starts up and for a user
2+
configured time period (default 30 seconds) will advertise the configuration
3+
service.
4+
5+
The configuration service allows for modifying various frames of the eddystone
6+
specification. For more details on the Configuration Service please check
7+
[here](https://github.com/google/eddystone/blob/master/eddystone-url/docs/config-service-spec.md).
8+
9+
Once the initial time period is up, the EddystoneBeaconConfigService will broadcast
10+
advertisement packets with the configured eddystone frames.
11+
12+
What You’ll Need
13+
================
14+
15+
To get this going, you’ll need:
16+
17+
- To see BLE devices and their advertisement or beacon information, get one of the following installed on your phone:
18+
19+
- The `physical web` app. You can get that app for [iOS](https://itunes.apple.com/us/app/physical-web/id927653608?mt=8) and for [Android](https://play.google.com/store/apps/details?id=physical_web.org.physicalweb).
20+
21+
- For Android, you can get [nRF Master Control Panel](https://play.google.com/store/apps/details?id=no.nordicsemi.android.mcp&hl=en).
22+
23+
- For iPhone, you can get [LightBlue](https://itunes.apple.com/gb/app/lightblue-bluetooth-low-energy/id557428110?mt=8).
24+
25+
- One of the BLE platforms listed in the README.md of this repository, for example a
26+
Nordic DK board.
27+
28+
Build Instructions
29+
==================
30+
31+
After cloning the parent repository, switch to the subfolder BLE_EddystoneBeaconConfigService, and
32+
execute the following:
33+
34+
```Shell
35+
yotta target <an_appropriate_target_such_as_mkit-gcc>
36+
yotta install
37+
yotta build
38+
```
39+
40+
Assuming that you're building for the nRF51 DK platform, available targets are
41+
`nrf51dk-armcc` and `nrf51dk-gcc`. You can pick either.
42+
43+
The resulting binaries would be under `build/<yotta_target_name>/source/`.
44+
Under that folder, the file called `ble-eddystonebeaconconfigservice-combined.hex` is the one which
45+
can be flashed to the target using mbed's DAP over USB; the file called `ble-eddystonebeaconconfigservice`
46+
is an ELF binary containing useful symbols; whereas `ble-eddystonebeaconconfigservice.hex`
47+
can be used for Firmware-over-the-Air.
48+
49+
If you're building for the `nrf51dk-armcc` target, copy
50+
`build/nrf51dk-armcc/source/ble-eddystonebeaconconfigservice-combined.hex` to your target hardware,
51+
and reset the device.
52+
53+
54+
Checking for Success
55+
====================
56+
57+
Your EddystoneBeaconConfigService should be detectable by BLE scanners (e.g. a smartphone) and by the
58+
Google Physical Web app.

0 commit comments

Comments
 (0)