BLE demo for the Cycling Speed and Cadence service.

Dependencies:   BLE_API mbed nRF51822

Committer:
p3miya
Date:
Thu Mar 10 13:09:47 2016 +0000
Revision:
0:ea0fa3076efd
BLE demo for the Cycling Speed and Cadence service.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
p3miya 0:ea0fa3076efd 1 /*
p3miya 0:ea0fa3076efd 2 Copyright (c) 2016 Y. Miyakawa
p3miya 0:ea0fa3076efd 3
p3miya 0:ea0fa3076efd 4 Permission is hereby granted, free of charge, to any person obtaining a copy of this software
p3miya 0:ea0fa3076efd 5 and associated documentation files (the "Software"), to deal in the Software without restriction,
p3miya 0:ea0fa3076efd 6 including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
p3miya 0:ea0fa3076efd 7 and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
p3miya 0:ea0fa3076efd 8 subject to the following conditions:
p3miya 0:ea0fa3076efd 9 The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
p3miya 0:ea0fa3076efd 10
p3miya 0:ea0fa3076efd 11 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
p3miya 0:ea0fa3076efd 12 INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
p3miya 0:ea0fa3076efd 13 PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
p3miya 0:ea0fa3076efd 14 FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
p3miya 0:ea0fa3076efd 15 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
p3miya 0:ea0fa3076efd 16 */
p3miya 0:ea0fa3076efd 17
p3miya 0:ea0fa3076efd 18 #include "mbed.h"
p3miya 0:ea0fa3076efd 19 #include "ble/BLE.h"
p3miya 0:ea0fa3076efd 20 #include "CyclingSpeedAndCadenceService.h"
p3miya 0:ea0fa3076efd 21 #include "ble/services/DeviceInformationService.h"
p3miya 0:ea0fa3076efd 22
p3miya 0:ea0fa3076efd 23 DigitalOut led1(LED1);
p3miya 0:ea0fa3076efd 24
p3miya 0:ea0fa3076efd 25 const static char DEVICE_NAME[] = "CSC1";
p3miya 0:ea0fa3076efd 26 static const uint16_t uuid16_list[] = {GattService::UUID_CYCLING_SPEED_AND_CADENCE,
p3miya 0:ea0fa3076efd 27 GattService::UUID_DEVICE_INFORMATION_SERVICE};
p3miya 0:ea0fa3076efd 28
p3miya 0:ea0fa3076efd 29 static volatile bool triggerSensorPolling = false;
p3miya 0:ea0fa3076efd 30
p3miya 0:ea0fa3076efd 31 CyclingSpeedAndCadenceService *cyclingSpeedAndCadenceService;
p3miya 0:ea0fa3076efd 32 DeviceInformationService *deviceInfo;
p3miya 0:ea0fa3076efd 33
p3miya 0:ea0fa3076efd 34 uint16_t feature = CyclingSpeedAndCadenceService::FEATURE_WHEEL_REVOLUTION_DATA
p3miya 0:ea0fa3076efd 35 + CyclingSpeedAndCadenceService::FEATURE_CRANK_REVOLUTION_DATA;
p3miya 0:ea0fa3076efd 36
p3miya 0:ea0fa3076efd 37 uint8_t flags = CyclingSpeedAndCadenceService::FLAG_WHEEL_REVOLUTION_DATA_PRESENT
p3miya 0:ea0fa3076efd 38 + CyclingSpeedAndCadenceService::FLAG_CRANK_REVOLUTION_DATA_PRESENT;
p3miya 0:ea0fa3076efd 39
p3miya 0:ea0fa3076efd 40 uint8_t location = CyclingSpeedAndCadenceService::LOCATION_CHAINSTAY;
p3miya 0:ea0fa3076efd 41
p3miya 0:ea0fa3076efd 42 void connectionCallback(const Gap::ConnectionCallbackParams_t *params)
p3miya 0:ea0fa3076efd 43 {
p3miya 0:ea0fa3076efd 44 }
p3miya 0:ea0fa3076efd 45
p3miya 0:ea0fa3076efd 46 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
p3miya 0:ea0fa3076efd 47 {
p3miya 0:ea0fa3076efd 48 triggerSensorPolling = false;
p3miya 0:ea0fa3076efd 49 BLE::Instance(BLE::DEFAULT_INSTANCE).gap().startAdvertising(); // restart advertising
p3miya 0:ea0fa3076efd 50 }
p3miya 0:ea0fa3076efd 51
p3miya 0:ea0fa3076efd 52 void confirmationRcvCallBack(Gap::Handle_t handle)
p3miya 0:ea0fa3076efd 53 {
p3miya 0:ea0fa3076efd 54 }
p3miya 0:ea0fa3076efd 55
p3miya 0:ea0fa3076efd 56 void periodicCallback(void)
p3miya 0:ea0fa3076efd 57 {
p3miya 0:ea0fa3076efd 58 led1 = !led1; /* Do blinky on LED1 while we're waiting for BLE events */
p3miya 0:ea0fa3076efd 59
p3miya 0:ea0fa3076efd 60 /* Note that the periodicCallback() executes in interrupt context, so it is safer to do
p3miya 0:ea0fa3076efd 61 * heavy-weight sensor polling from the main thread. */
p3miya 0:ea0fa3076efd 62 triggerSensorPolling = true;
p3miya 0:ea0fa3076efd 63 }
p3miya 0:ea0fa3076efd 64
p3miya 0:ea0fa3076efd 65 void bleInitComplete(BLE::InitializationCompleteCallbackContext *params)
p3miya 0:ea0fa3076efd 66 {
p3miya 0:ea0fa3076efd 67 BLE &ble = params->ble;
p3miya 0:ea0fa3076efd 68 ble_error_t error = params->error;
p3miya 0:ea0fa3076efd 69
p3miya 0:ea0fa3076efd 70 if (error != BLE_ERROR_NONE) {
p3miya 0:ea0fa3076efd 71 return;
p3miya 0:ea0fa3076efd 72 }
p3miya 0:ea0fa3076efd 73
p3miya 0:ea0fa3076efd 74 ble.gap().onConnection(connectionCallback);
p3miya 0:ea0fa3076efd 75 ble.gap().onDisconnection(disconnectionCallback);
p3miya 0:ea0fa3076efd 76 ble.onConfirmationReceived(confirmationRcvCallBack);
p3miya 0:ea0fa3076efd 77
p3miya 0:ea0fa3076efd 78 /* Setup primary service. */
p3miya 0:ea0fa3076efd 79 cyclingSpeedAndCadenceService = new CyclingSpeedAndCadenceService(ble, feature, location);
p3miya 0:ea0fa3076efd 80
p3miya 0:ea0fa3076efd 81 /* Setup auxiliary service. */
p3miya 0:ea0fa3076efd 82 deviceInfo = new DeviceInformationService(ble, "ARM", "Model1", "SN1", "hw-rev1", "fw-rev1", "soft-rev1");
p3miya 0:ea0fa3076efd 83
p3miya 0:ea0fa3076efd 84 /* Setup advertising. */
p3miya 0:ea0fa3076efd 85 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
p3miya 0:ea0fa3076efd 86 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list));
p3miya 0:ea0fa3076efd 87 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_HEART_RATE_SENSOR);
p3miya 0:ea0fa3076efd 88 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
p3miya 0:ea0fa3076efd 89 ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
p3miya 0:ea0fa3076efd 90 ble.gap().setAdvertisingInterval(1000); /* 1000ms */
p3miya 0:ea0fa3076efd 91 ble.gap().startAdvertising();
p3miya 0:ea0fa3076efd 92 }
p3miya 0:ea0fa3076efd 93
p3miya 0:ea0fa3076efd 94 int main(void)
p3miya 0:ea0fa3076efd 95 {
p3miya 0:ea0fa3076efd 96 uint16_t dCumulativeWheelRev = 4;
p3miya 0:ea0fa3076efd 97 uint16_t dLastWheelEventTime = 1024;
p3miya 0:ea0fa3076efd 98 uint16_t dCumulativeCrankRev = 1;
p3miya 0:ea0fa3076efd 99 uint16_t dLastCrankEventTime = 1024;
p3miya 0:ea0fa3076efd 100
p3miya 0:ea0fa3076efd 101 led1 = 1;
p3miya 0:ea0fa3076efd 102
p3miya 0:ea0fa3076efd 103 Ticker ticker;
p3miya 0:ea0fa3076efd 104 ticker.attach(periodicCallback, 1); // blink LED every second
p3miya 0:ea0fa3076efd 105
p3miya 0:ea0fa3076efd 106 BLE& ble = BLE::Instance(BLE::DEFAULT_INSTANCE);
p3miya 0:ea0fa3076efd 107 ble.init(bleInitComplete);
p3miya 0:ea0fa3076efd 108
p3miya 0:ea0fa3076efd 109 /* SpinWait for initialization to complete. This is necessary because the
p3miya 0:ea0fa3076efd 110 * BLE object is used in the main loop below. */
p3miya 0:ea0fa3076efd 111 while (ble.hasInitialized() == false) { /* spin loop */ }
p3miya 0:ea0fa3076efd 112
p3miya 0:ea0fa3076efd 113 // infinite loop
p3miya 0:ea0fa3076efd 114 while(1) {
p3miya 0:ea0fa3076efd 115 if (triggerSensorPolling && ble.getGapState().connected) {
p3miya 0:ea0fa3076efd 116 triggerSensorPolling = false;
p3miya 0:ea0fa3076efd 117 dLastWheelEventTime -= 32;
p3miya 0:ea0fa3076efd 118 dLastCrankEventTime -= 32;
p3miya 0:ea0fa3076efd 119 if (dLastWheelEventTime < 512) {
p3miya 0:ea0fa3076efd 120 dLastWheelEventTime = 1024;
p3miya 0:ea0fa3076efd 121 dLastCrankEventTime = 1024;
p3miya 0:ea0fa3076efd 122 }
p3miya 0:ea0fa3076efd 123 cyclingSpeedAndCadenceService->updateCyclingSpeedAndCadence(flags,
p3miya 0:ea0fa3076efd 124 dCumulativeWheelRev, dLastWheelEventTime, dCumulativeCrankRev, dLastCrankEventTime);
p3miya 0:ea0fa3076efd 125 } else {
p3miya 0:ea0fa3076efd 126 ble.waitForEvent(); // low power wait for event
p3miya 0:ea0fa3076efd 127 }
p3miya 0:ea0fa3076efd 128 }
p3miya 0:ea0fa3076efd 129 }