A simple demo that directly uses BLE library to define service and characteristics
Dependencies: BLE_API mbed nRF51822
Fork of BLE_HeartRate by
Diff: main.cpp
- Revision:
- 48:908b4ec086ba
- Parent:
- 47:430545f41113
- Child:
- 49:14b2df099dfc
--- a/main.cpp Tue Sep 30 02:14:27 2014 +0000 +++ b/main.cpp Wed Oct 22 05:39:38 2014 +0000 @@ -1,86 +1,84 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - #include "mbed.h" #include "BLEDevice.h" -#include "HeartRateService.h" -#include "BatteryService.h" -#include "DeviceInformationService.h" BLEDevice ble; DigitalOut led1(LED1); const static char DEVICE_NAME[] = "Nordic_HRM"; -static const uint16_t uuid16_list[] = {GattService::UUID_HEART_RATE_SERVICE, - GattService::UUID_BATTERY_SERVICE, - GattService::UUID_DEVICE_INFORMATION_SERVICE}; -static volatile bool triggerSensorPolling = false; +static const uint16_t uuid16_list[] = {0xFEDB}; +static volatile bool is_button_pressed = false; +static volatile uint16_t led1_handler; + +uint8_t led_state, button_state; void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason) { ble.startAdvertising(); // restart advertising } -void periodicCallback(void) -{ - led1 = !led1; /* Do blinky on LED1 while we're waiting for BLE events */ +// eventDataP->charHandle is just uint16_t +void changeLED(const GattCharacteristicWriteCBParams *eventDataP) { + if (eventDataP->charHandle == led1_handler) { + led1 = eventDataP->data[0] % 2; + } +} - /* Note that the periodicCallback() executes in interrupt context, so it is safer to do - * heavy-weight sensor polling from the main thread. */ - triggerSensorPolling = true; +void button1Pressed() { + button_state = 1; + is_button_pressed = true; +} +void button2Pressed() { + button_state = 2; + is_button_pressed = true; } int main(void) { - led1 = 1; - Ticker ticker; - ticker.attach(periodicCallback, 1); - - ble.init(); - ble.onDisconnection(disconnectionCallback); + // button initialization + InterruptIn button1(BUTTON1); + InterruptIn button2(BUTTON2); + button1.mode(PullUp); + button2.mode(PullUp); + button1.rise(&button1Pressed); + button2.rise(&button2Pressed); + led1 = 0; - /* Setup primary service. */ - uint8_t hrmCounter = 100; - HeartRateService hrService(ble, hrmCounter, HeartRateService::LOCATION_FINGER); + // just a simple service example + // o led1 characteristics, you can write from the phone to control led1 + // o button characteristics, you can read and get notified + GattCharacteristic led1_characteristics( + 0xFF00, &led_state, sizeof(led_state), sizeof(led_state), + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE); + led1_handler = led1_characteristics.getValueAttribute().getHandle(); - /* Setup auxiliary services. */ - BatteryService battery(ble); - DeviceInformationService deviceInfo(ble, "ARM", "Model1", "SN1", "hw-rev1", "fw-rev1", "soft-rev1"); - - /* Setup advertising. */ + GattCharacteristic button_characteristics( + 0xFF01, &button_state, sizeof(button_state), sizeof(button_state), + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY); + + GattCharacteristic *charTable[] = {&led1_characteristics, &button_characteristics}; + GattService testService(0xFFFF, charTable, sizeof(charTable) / sizeof(GattCharacteristic *)); + + // BLE setup, mainly we add service and callbacks + ble.init(); + ble.addService(testService); + ble.onDataWritten(&changeLED); + ble.onDisconnection(disconnectionCallback); + + // setup advertising ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list)); - ble.accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_HEART_RATE_SENSOR); ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); ble.setAdvertisingInterval(1600); /* 1000ms; in multiples of 0.625ms. */ ble.startAdvertising(); while (true) { - if (triggerSensorPolling) { - triggerSensorPolling = false; - - /* Do blocking calls or whatever is necessary for sensor polling. */ - /* In our case, we simply update the dummy HRM measurement. */ - hrmCounter++; - if (hrmCounter == 175) { - hrmCounter = 100; - } - - hrService.updateHeartRate(hrmCounter); + if (is_button_pressed) { + is_button_pressed = false; + ble.updateCharacteristicValue(button_characteristics.getValueAttribute().getHandle(), + &button_state, sizeof(button_state)); } else { ble.waitForEvent(); }