Nordic nRF51 basic device information, battery & temperature services example.

Dependencies:   BLE_API mbed nRF51822

You can use for example in Nexus4 BLE Device Monitor application to look each Service characteristics.

Committer:
MetaMika
Date:
Mon Jun 08 10:03:31 2015 +0000
Revision:
2:8f2c349db7dd
Parent:
1:ddb24c21ea52
Re-Updated libraries, no more warnings.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
MetaMika 0:aa97837202d2 1 /* mbed Microcontroller Library
MetaMika 0:aa97837202d2 2 * Copyright (c) 2006-2013 ARM Limited
MetaMika 0:aa97837202d2 3 *
MetaMika 0:aa97837202d2 4 * Licensed under the Apache License, Version 2.0 (the "License");
MetaMika 0:aa97837202d2 5 * you may not use this file except in compliance with the License.
MetaMika 0:aa97837202d2 6 * You may obtain a copy of the License at
MetaMika 0:aa97837202d2 7 *
MetaMika 0:aa97837202d2 8 * http://www.apache.org/licenses/LICENSE-2.0
MetaMika 0:aa97837202d2 9 *
MetaMika 0:aa97837202d2 10 * Unless required by applicable law or agreed to in writing, software
MetaMika 0:aa97837202d2 11 * distributed under the License is distributed on an "AS IS" BASIS,
MetaMika 0:aa97837202d2 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
MetaMika 0:aa97837202d2 13 * See the License for the specific language governing permissions and
MetaMika 0:aa97837202d2 14 * limitations under the License.
MetaMika 0:aa97837202d2 15 *
MetaMika 0:aa97837202d2 16 * Author: Mika Karaila, Metso Automation Inc.
MetaMika 0:aa97837202d2 17 *
MetaMika 0:aa97837202d2 18 * This Bluetooth LE example contains all basic device characteristics.
MetaMika 0:aa97837202d2 19 * Measurement services are simulated for battery & temperature.
MetaMika 0:aa97837202d2 20 *
MetaMika 0:aa97837202d2 21 */
MetaMika 0:aa97837202d2 22
MetaMika 0:aa97837202d2 23 #include "mbed.h"
MetaMika 0:aa97837202d2 24 #include "BLEDevice.h"
MetaMika 0:aa97837202d2 25
MetaMika 0:aa97837202d2 26 BLEDevice ble;
MetaMika 0:aa97837202d2 27 DigitalOut led1(LED1);
MetaMika 0:aa97837202d2 28
MetaMika 0:aa97837202d2 29 #define NEED_CONSOLE_OUTPUT 0 /* Set this if you need debug messages on the console;
MetaMika 0:aa97837202d2 30 * it will have an impact on code-size and power consumption. */
MetaMika 0:aa97837202d2 31
MetaMika 0:aa97837202d2 32 #if NEED_CONSOLE_OUTPUT
MetaMika 0:aa97837202d2 33 Serial pc(USBTX, USBRX);
MetaMika 0:aa97837202d2 34 #define DEBUG(...) { pc.printf(__VA_ARGS__); }
MetaMika 0:aa97837202d2 35 #else
MetaMika 0:aa97837202d2 36 #define DEBUG(...) /* nothing */
MetaMika 0:aa97837202d2 37 #endif /* #if NEED_CONSOLE_OUTPUT */
MetaMika 0:aa97837202d2 38
MetaMika 0:aa97837202d2 39 // DEVICE_NAME_UUID = '2A00'; // Nordic fixed this to nRF5, can be written
MetaMika 0:aa97837202d2 40
MetaMika 0:aa97837202d2 41 // Temperature 0-100 C, simulated
MetaMika 0:aa97837202d2 42 static uint8_t temperature = 32;
MetaMika 0:aa97837202d2 43 GattCharacteristic tempMeas(GattCharacteristic::UUID_TEMPERATURE_MEASUREMENT_CHAR, (uint8_t *)temperature, sizeof(temperature), sizeof(temperature),
MetaMika 0:aa97837202d2 44 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY);
MetaMika 0:aa97837202d2 45 GattCharacteristic *temperatureChars[] = {&tempMeas };
MetaMika 0:aa97837202d2 46 // TODO add custom service instead of Heart rate
MetaMika 0:aa97837202d2 47 GattService temperatureService(GattService::UUID_HEART_RATE_SERVICE, temperatureChars, sizeof(temperatureChars) / sizeof(GattCharacteristic *));
MetaMika 0:aa97837202d2 48
MetaMika 0:aa97837202d2 49 // SYSTEM
MetaMika 0:aa97837202d2 50 static char systemId = 'A';
MetaMika 0:aa97837202d2 51 GattCharacteristic systemID(GattCharacteristic::UUID_SYSTEM_ID_CHAR, (uint8_t *)systemId, sizeof(systemId), sizeof(systemId),
MetaMika 0:aa97837202d2 52 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ);
MetaMika 0:aa97837202d2 53 GattCharacteristic *systemChars[] = {&systemID };
MetaMika 0:aa97837202d2 54 GattService systemService(GattService::UUID_DEVICE_INFORMATION_SERVICE, systemChars, sizeof(systemChars) / sizeof(GattCharacteristic *));
MetaMika 0:aa97837202d2 55
MetaMika 0:aa97837202d2 56 // MODEL
MetaMika 0:aa97837202d2 57 static char model[31] = "Test sensor";
MetaMika 0:aa97837202d2 58 GattCharacteristic modelID(GattCharacteristic::UUID_MODEL_NUMBER_STRING_CHAR, (uint8_t *)model, sizeof(model), sizeof(model),
MetaMika 0:aa97837202d2 59 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ);
MetaMika 0:aa97837202d2 60 GattCharacteristic *modelChars[] = {&modelID };
MetaMika 0:aa97837202d2 61 GattService modelService(GattService::UUID_DEVICE_INFORMATION_SERVICE, modelChars, sizeof(modelChars) / sizeof(GattCharacteristic *));
MetaMika 0:aa97837202d2 62
MetaMika 0:aa97837202d2 63 // Firmware
MetaMika 0:aa97837202d2 64 static char fwversion[31] = "Firmware: 0216";
MetaMika 0:aa97837202d2 65 GattCharacteristic fwChars(GattCharacteristic::UUID_FIRMWARE_REVISION_STRING_CHAR, (uint8_t *)fwversion, sizeof(fwversion), sizeof(fwversion),
MetaMika 0:aa97837202d2 66 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ);
MetaMika 0:aa97837202d2 67 GattCharacteristic *firmwareChars[] = {&fwChars };
MetaMika 0:aa97837202d2 68 GattService firmwareService(GattService::UUID_DEVICE_INFORMATION_SERVICE, firmwareChars, sizeof(firmwareChars) / sizeof(GattCharacteristic *));
MetaMika 0:aa97837202d2 69
MetaMika 0:aa97837202d2 70 // Software
MetaMika 0:aa97837202d2 71 static char swversion[31] = "Sensor build (0001)";
MetaMika 0:aa97837202d2 72 GattCharacteristic swChars(GattCharacteristic::UUID_SOFTWARE_REVISION_STRING_CHAR, (uint8_t *)swversion, sizeof(swversion), sizeof(swversion),
MetaMika 0:aa97837202d2 73 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ);
MetaMika 0:aa97837202d2 74 GattCharacteristic *softwareChars[] = {&swChars };
MetaMika 0:aa97837202d2 75 GattService softwareService(GattService::UUID_DEVICE_INFORMATION_SERVICE, softwareChars, sizeof(softwareChars) / sizeof(GattCharacteristic *));
MetaMika 0:aa97837202d2 76 // Hardware
MetaMika 0:aa97837202d2 77 static char hwversion[31] = "Sensor hw proto 0";
MetaMika 0:aa97837202d2 78 GattCharacteristic hwChars(GattCharacteristic::UUID_HARDWARE_REVISION_STRING_CHAR, (uint8_t *)hwversion, sizeof(hwversion), sizeof(hwversion),
MetaMika 0:aa97837202d2 79 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ);
MetaMika 0:aa97837202d2 80 GattCharacteristic *hardwareChars[] = {&hwChars };
MetaMika 0:aa97837202d2 81 GattService hardwareService(GattService::UUID_DEVICE_INFORMATION_SERVICE, hardwareChars, sizeof(hardwareChars) / sizeof(GattCharacteristic *));
MetaMika 0:aa97837202d2 82 // Manufacturer
MetaMika 0:aa97837202d2 83 static char vendor[31] = "Test Company Inc.";
MetaMika 0:aa97837202d2 84 GattCharacteristic vendorChars(GattCharacteristic::UUID_MANUFACTURER_NAME_STRING_CHAR, (uint8_t *)vendor, sizeof(vendor), sizeof(vendor),
MetaMika 0:aa97837202d2 85 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ);
MetaMika 0:aa97837202d2 86 GattCharacteristic *manufacturerChars[] = {&vendorChars };
MetaMika 0:aa97837202d2 87 GattService manufacturerService(GattService::UUID_DEVICE_INFORMATION_SERVICE, manufacturerChars, sizeof(manufacturerChars) / sizeof(GattCharacteristic *));
MetaMika 0:aa97837202d2 88 // Serial number
MetaMika 0:aa97837202d2 89 static char serial[31] = "1234567890";
MetaMika 0:aa97837202d2 90 GattCharacteristic serialChars(GattCharacteristic::UUID_SERIAL_NUMBER_STRING_CHAR, (uint8_t *)serial, sizeof(serial), sizeof(serial),
MetaMika 0:aa97837202d2 91 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ);
MetaMika 0:aa97837202d2 92 GattCharacteristic *serialNumberChars[] = {&serialChars };
MetaMika 0:aa97837202d2 93 GattService serialNumberService(GattService::UUID_DEVICE_INFORMATION_SERVICE, serialNumberChars, sizeof(serialNumberChars) / sizeof(GattCharacteristic *));
MetaMika 0:aa97837202d2 94
MetaMika 0:aa97837202d2 95 static uint8_t batteryLevel = 100;
MetaMika 0:aa97837202d2 96 GattCharacteristic batteryPercentage(GattCharacteristic::UUID_BATTERY_LEVEL_CHAR, (uint8_t *)batteryLevel, sizeof(batteryLevel), sizeof(batteryLevel),
MetaMika 0:aa97837202d2 97 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY);
MetaMika 0:aa97837202d2 98 GattCharacteristic *batteryChars[] = {&batteryPercentage };
MetaMika 0:aa97837202d2 99 GattService batteryService(GattService::UUID_BATTERY_SERVICE, batteryChars, sizeof(batteryChars) / sizeof(GattCharacteristic *));
MetaMika 0:aa97837202d2 100
MetaMika 1:ddb24c21ea52 101 void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason)
MetaMika 0:aa97837202d2 102 {
MetaMika 1:ddb24c21ea52 103 printf("Disconnected handle %u!\n\r", handle);
MetaMika 1:ddb24c21ea52 104 printf("Restarting the advertising process\n\r");
MetaMika 0:aa97837202d2 105 ble.startAdvertising();
MetaMika 0:aa97837202d2 106 }
MetaMika 0:aa97837202d2 107
MetaMika 0:aa97837202d2 108 /**
MetaMika 0:aa97837202d2 109 * Triggered periodically by the 'ticker' interrupt; updates hrmCounter.
MetaMika 0:aa97837202d2 110 */
MetaMika 0:aa97837202d2 111 void periodicCallback(void)
MetaMika 0:aa97837202d2 112 {
MetaMika 0:aa97837202d2 113 led1 = !led1; /* Do blinky on LED1 while we're waiting for BLE events */
MetaMika 0:aa97837202d2 114
MetaMika 0:aa97837202d2 115 if (ble.getGapState().connected) {
MetaMika 0:aa97837202d2 116 /* Update the battery measurement */
MetaMika 0:aa97837202d2 117 batteryLevel--;
MetaMika 0:aa97837202d2 118 if (batteryLevel == 1) {
MetaMika 0:aa97837202d2 119 batteryLevel = 100;
MetaMika 0:aa97837202d2 120 }
MetaMika 1:ddb24c21ea52 121 ble.updateCharacteristicValue(batteryPercentage.getValueAttribute().getHandle(), &batteryLevel, sizeof(batteryLevel));
MetaMika 0:aa97837202d2 122
MetaMika 0:aa97837202d2 123 /* Update the temperature measurement */
MetaMika 0:aa97837202d2 124 temperature++;
MetaMika 0:aa97837202d2 125 if (temperature == 50) {
MetaMika 0:aa97837202d2 126 temperature = 10;
MetaMika 0:aa97837202d2 127 }
MetaMika 1:ddb24c21ea52 128 ble.updateCharacteristicValue(tempMeas.getValueAttribute().getHandle(), &temperature, sizeof(temperature));
MetaMika 0:aa97837202d2 129 }
MetaMika 0:aa97837202d2 130 }
MetaMika 0:aa97837202d2 131
MetaMika 0:aa97837202d2 132 int main(void)
MetaMika 0:aa97837202d2 133 {
MetaMika 0:aa97837202d2 134 led1 = 1;
MetaMika 0:aa97837202d2 135 Ticker ticker;
MetaMika 0:aa97837202d2 136 ticker.attach(periodicCallback, 1);
MetaMika 0:aa97837202d2 137
MetaMika 0:aa97837202d2 138 DEBUG("Initialising the nRF51822\n\r");
MetaMika 0:aa97837202d2 139 ble.init();
MetaMika 0:aa97837202d2 140 ble.onDisconnection(disconnectionCallback);
MetaMika 0:aa97837202d2 141
MetaMika 0:aa97837202d2 142 /* setup advertising */
MetaMika 0:aa97837202d2 143 ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED);
MetaMika 0:aa97837202d2 144 ble.accumulateAdvertisingPayload(GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
MetaMika 0:aa97837202d2 145 ble.accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_THERMOMETER);
MetaMika 0:aa97837202d2 146
MetaMika 0:aa97837202d2 147 ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
MetaMika 0:aa97837202d2 148 ble.setAdvertisingInterval(160); /* 1000ms; in multiples of 0.625ms. */
MetaMika 0:aa97837202d2 149 ble.startAdvertising();
MetaMika 0:aa97837202d2 150
MetaMika 0:aa97837202d2 151 ble.addService(batteryService);
MetaMika 0:aa97837202d2 152 ble.addService(firmwareService);
MetaMika 0:aa97837202d2 153 ble.addService(softwareService);
MetaMika 0:aa97837202d2 154 ble.addService(hardwareService);
MetaMika 0:aa97837202d2 155 ble.addService(modelService);
MetaMika 0:aa97837202d2 156 ble.addService(temperatureService);
MetaMika 0:aa97837202d2 157
MetaMika 0:aa97837202d2 158 while (true) {
MetaMika 0:aa97837202d2 159 ble.waitForEvent();
MetaMika 0:aa97837202d2 160 }
MetaMika 0:aa97837202d2 161 }