BLE demo for the Cycling Power service.

Dependencies:   BLE_API mbed nRF51822

Committer:
p3miya
Date:
Sat Feb 27 12:27:48 2016 +0000
Revision:
0:d9d7edb1ddfc
Child:
1:e2e4def8a6bb
BLE demo for the Cycling Power service.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
p3miya 0:d9d7edb1ddfc 1 /*
p3miya 0:d9d7edb1ddfc 2 Copyright (c) 2016 Y. Miyakawa
p3miya 0:d9d7edb1ddfc 3
p3miya 0:d9d7edb1ddfc 4 Permission is hereby granted, free of charge, to any person obtaining a copy of this software
p3miya 0:d9d7edb1ddfc 5 and associated documentation files (the "Software"), to deal in the Software without restriction,
p3miya 0:d9d7edb1ddfc 6 including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
p3miya 0:d9d7edb1ddfc 7 and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
p3miya 0:d9d7edb1ddfc 8 subject to the following conditions:
p3miya 0:d9d7edb1ddfc 9 The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
p3miya 0:d9d7edb1ddfc 10
p3miya 0:d9d7edb1ddfc 11 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
p3miya 0:d9d7edb1ddfc 12 INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
p3miya 0:d9d7edb1ddfc 13 PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
p3miya 0:d9d7edb1ddfc 14 FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
p3miya 0:d9d7edb1ddfc 15 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
p3miya 0:d9d7edb1ddfc 16 */
p3miya 0:d9d7edb1ddfc 17
p3miya 0:d9d7edb1ddfc 18 #ifndef __BLE_CYCLING_POWER_SERVICE_H__
p3miya 0:d9d7edb1ddfc 19 #define __BLE_CYCLING_POWER_SERVICE_H__
p3miya 0:d9d7edb1ddfc 20
p3miya 0:d9d7edb1ddfc 21 #include "ble/BLE.h"
p3miya 0:d9d7edb1ddfc 22
p3miya 0:d9d7edb1ddfc 23 #define UUID_CYCLING_POWER_SERVICE 0x1818
p3miya 0:d9d7edb1ddfc 24 #define UUID_SENSOR_LOCATION_CHAR 0x2A5D
p3miya 0:d9d7edb1ddfc 25 #define UUID_CYCLING_POWER_MEASUREMENT_CHAR 0x2A63
p3miya 0:d9d7edb1ddfc 26 #define UUID_CYCLING_POWER_FEATURE_CHAR 0x2A65
p3miya 0:d9d7edb1ddfc 27 #define UUID_CYCLING_POWER_VECTOR_CHAR 0x2A64
p3miya 0:d9d7edb1ddfc 28 #define UUID_CYCLING_POWER_CONTROL_POINT_CHAR 0x2A66
p3miya 0:d9d7edb1ddfc 29
p3miya 0:d9d7edb1ddfc 30
p3miya 0:d9d7edb1ddfc 31 /**
p3miya 0:d9d7edb1ddfc 32 * @class CyclingPowerService
p3miya 0:d9d7edb1ddfc 33 * @brief BLE Service for CyclingPower. <br>
p3miya 0:d9d7edb1ddfc 34 * Service: https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.cycling_power.xml <br>
p3miya 0:d9d7edb1ddfc 35 * CyclingPower Char: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.cycling_power_measurement.xml <br>
p3miya 0:d9d7edb1ddfc 36 * Location: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.sensor_location.xml
p3miya 0:d9d7edb1ddfc 37 */
p3miya 0:d9d7edb1ddfc 38 class CyclingPowerService {
p3miya 0:d9d7edb1ddfc 39 public:
p3miya 0:d9d7edb1ddfc 40 enum {
p3miya 0:d9d7edb1ddfc 41 LOCATION_OTHER = 0,
p3miya 0:d9d7edb1ddfc 42 LOCATION_TOP_OF_SHOE,
p3miya 0:d9d7edb1ddfc 43 LOCATION_IN_SHOE,
p3miya 0:d9d7edb1ddfc 44 LOCATION_HIP,
p3miya 0:d9d7edb1ddfc 45 LOCATION_FRONT_WHEEL,
p3miya 0:d9d7edb1ddfc 46 LOCATION_LEFT_CRANK,
p3miya 0:d9d7edb1ddfc 47 LOCATION_RIGHT_CRANK,
p3miya 0:d9d7edb1ddfc 48 LOCATION_LEFT_PEDAL,
p3miya 0:d9d7edb1ddfc 49 LOCATION_RIGHT_PEDAL,
p3miya 0:d9d7edb1ddfc 50 LOCATION_FRONT_HUB,
p3miya 0:d9d7edb1ddfc 51 LOCATION_REAR_DROPOUT,
p3miya 0:d9d7edb1ddfc 52 LOCATION_CHAINSTAY,
p3miya 0:d9d7edb1ddfc 53 LOCATION_REAR_WHEEL,
p3miya 0:d9d7edb1ddfc 54 LOCATION_REAR_HUB,
p3miya 0:d9d7edb1ddfc 55 LOCATION_CHEST,
p3miya 0:d9d7edb1ddfc 56 };
p3miya 0:d9d7edb1ddfc 57
p3miya 0:d9d7edb1ddfc 58 enum {
p3miya 0:d9d7edb1ddfc 59 FEATURE_PEDAL_POWER_BALANCE = 0x00000001,
p3miya 0:d9d7edb1ddfc 60 FEATURE_ACCUMULATED_TORQUE = 0x00000002,
p3miya 0:d9d7edb1ddfc 61 FEATURE_WHEEL_REVOLUTION_DATA = 0x00000004,
p3miya 0:d9d7edb1ddfc 62 FEATURE_CRANK_REVOLUTION_DATA = 0x00000008,
p3miya 0:d9d7edb1ddfc 63 FEATURE_EXTREME_MAGNITUDES = 0x00000010,
p3miya 0:d9d7edb1ddfc 64 FEATURE_EXTREME_ANGLES = 0x00000020,
p3miya 0:d9d7edb1ddfc 65 FEATURE_TOP_AND_BOTTOM_DEAD_SPOT_ANGLES = 0x00000040,
p3miya 0:d9d7edb1ddfc 66 FEATURE_ACCUMULATED_ENERGY = 0x00000080,
p3miya 0:d9d7edb1ddfc 67 FEATURE_OFFSET_COMPENSATION_INDICATOR = 0x00000100,
p3miya 0:d9d7edb1ddfc 68 FEATURE_OFFSET_COMPENSATION = 0x00000200,
p3miya 0:d9d7edb1ddfc 69 FEATURE_MEASUREMENT_CONTENT_MASKING = 0x00000400,
p3miya 0:d9d7edb1ddfc 70 FEATURE_MULTIPLE_SENSOR_LOCATIONS = 0x00000800,
p3miya 0:d9d7edb1ddfc 71 FEATURE_CRANK_LENGTH_ADJUSTMENT = 0x00001000,
p3miya 0:d9d7edb1ddfc 72 FEATURE_CHAIN_LENGTH_ADJUSTMENT = 0x00002000,
p3miya 0:d9d7edb1ddfc 73 FEATURE_CHAIN_WEIGHT_ADJUSTMENT = 0x00004000,
p3miya 0:d9d7edb1ddfc 74 FEATURE_SPAN_LENGTH_ADJUSTMENT = 0x00008000,
p3miya 0:d9d7edb1ddfc 75 FEATURE_SENSOR_MEASUREMENT_TORQUE_BASED = 0x00010000,
p3miya 0:d9d7edb1ddfc 76 FEATURE_INSTANTANEOUS_MEASUREMENT_DIRECTION = 0x00020000,
p3miya 0:d9d7edb1ddfc 77 FEATURE_FACTORY_CALIBRATION_DATE = 0x00040000,
p3miya 0:d9d7edb1ddfc 78 };
p3miya 0:d9d7edb1ddfc 79
p3miya 0:d9d7edb1ddfc 80 enum {
p3miya 0:d9d7edb1ddfc 81 FLAG_PEDAL_POWER_BALANCE_PRESENT = 0x0001,
p3miya 0:d9d7edb1ddfc 82 FLAG_PEDAL_POWER_BALANCE_REFERENCE_LEFT = 0x0002,
p3miya 0:d9d7edb1ddfc 83 FLAG_ACCUMULATED_TORQUE_PRESENT = 0x0004,
p3miya 0:d9d7edb1ddfc 84 FLAG_ACCUMULATED_TORQUE_SOURCE_CRANK_BASED = 0x0008,
p3miya 0:d9d7edb1ddfc 85 FLAG_WHEEL_REVOLUTION_DATA_PRESENT = 0x0010,
p3miya 0:d9d7edb1ddfc 86 FLAG_CRANK_REVOLUTION_DATA_PRESENT = 0x0020,
p3miya 0:d9d7edb1ddfc 87 FLAG_EXTREME_FORCE_MAGNITUDES_PRESENT = 0x0040,
p3miya 0:d9d7edb1ddfc 88 FLAG_EXTREME_TORQUE_MAGNITUDES_PRESENT = 0x0080,
p3miya 0:d9d7edb1ddfc 89 FLAG_EXTREME_ANGLES_PRESENT = 0x0100,
p3miya 0:d9d7edb1ddfc 90 FLAG_TOP_DEAD_SPOT_ANGLE_PRESENT = 0x0200,
p3miya 0:d9d7edb1ddfc 91 FLAG_BOTTOM_DEAD_SPOT_ANGLE_PRESENT = 0x0400,
p3miya 0:d9d7edb1ddfc 92 FLAG_ACCUMULATED_ENERGY_PRESENT = 0x0800,
p3miya 0:d9d7edb1ddfc 93 FLAG_OFFSET_COMPENSATION_INDICATOR = 0x1000,
p3miya 0:d9d7edb1ddfc 94 };
p3miya 0:d9d7edb1ddfc 95
p3miya 0:d9d7edb1ddfc 96 enum {
p3miya 0:d9d7edb1ddfc 97 OPCODE_SET_CUMULATIVE_VALUE = 1,
p3miya 0:d9d7edb1ddfc 98 OPCODE_UPDATE_SENSOR_LOCATION = 2,
p3miya 0:d9d7edb1ddfc 99 OPCODE_REQUEST_SUPPORTED_SENSOR_LOCATIONS = 3,
p3miya 0:d9d7edb1ddfc 100 OPCODE_SET_CRANK_LENGTH = 4,
p3miya 0:d9d7edb1ddfc 101 OPCODE_REQUEST_CRANK_LENGTH = 5,
p3miya 0:d9d7edb1ddfc 102 OPCODE_SET_CHAIN_LENGTH = 6,
p3miya 0:d9d7edb1ddfc 103 OPCODE_REQUEST_CHAIN_LENGTH = 7,
p3miya 0:d9d7edb1ddfc 104 OPCODE_SET_CHAIN_WEIGHT = 8,
p3miya 0:d9d7edb1ddfc 105 OPCODE_REQUEST_CHAIN_WEIGHT = 9,
p3miya 0:d9d7edb1ddfc 106 OPCODE_SET_SPAN_LENGTH = 10,
p3miya 0:d9d7edb1ddfc 107 OPCODE_REQUEST_SPAN_LENGTH = 11,
p3miya 0:d9d7edb1ddfc 108 OPCODE_START_OFFSET_COMPENSATION = 12,
p3miya 0:d9d7edb1ddfc 109 OPCODE_MASK_CYCLING_POWER_MEASUREMENT_CHARACTERISTIC_CONTENT = 13,
p3miya 0:d9d7edb1ddfc 110 OPCODE_REQUEST_SAMPLING_RATE = 14,
p3miya 0:d9d7edb1ddfc 111 OPCODE_REQUEST_FACTORY_CALIBRATION_DATE = 15,
p3miya 0:d9d7edb1ddfc 112 OPCODE_RESPONSE_CODE = 32,
p3miya 0:d9d7edb1ddfc 113 };
p3miya 0:d9d7edb1ddfc 114
p3miya 0:d9d7edb1ddfc 115 enum {
p3miya 0:d9d7edb1ddfc 116 RESPONSE_SUCCESS = 1,
p3miya 0:d9d7edb1ddfc 117 RESPONSE_OP_CODE_NOT_SUPPORTED,
p3miya 0:d9d7edb1ddfc 118 RESPONSE_INVALID_PARAMETER,
p3miya 0:d9d7edb1ddfc 119 RESPONSE_OPERATION_FAILED,
p3miya 0:d9d7edb1ddfc 120 };
p3miya 0:d9d7edb1ddfc 121
p3miya 0:d9d7edb1ddfc 122 public:
p3miya 0:d9d7edb1ddfc 123 CyclingPowerService(BLE &_ble, uint32_t feature, uint8_t location) :
p3miya 0:d9d7edb1ddfc 124 ble(_ble),
p3miya 0:d9d7edb1ddfc 125 cyclingPowerMeasurement(UUID_CYCLING_POWER_MEASUREMENT_CHAR, measureData,
p3miya 0:d9d7edb1ddfc 126 MAX_MEASURE_BYTES, MAX_MEASURE_BYTES,
p3miya 0:d9d7edb1ddfc 127 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY),
p3miya 0:d9d7edb1ddfc 128 cyclingPowerControlPoint(UUID_CYCLING_POWER_CONTROL_POINT_CHAR, controlData,
p3miya 0:d9d7edb1ddfc 129 MAX_CONTROL_BYTES, MAX_CONTROL_BYTES,
p3miya 0:d9d7edb1ddfc 130 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE),
p3miya 0:d9d7edb1ddfc 131 cyclingPowerFeature(UUID_CYCLING_POWER_FEATURE_CHAR, &feature),
p3miya 0:d9d7edb1ddfc 132 cyclingPowerLocation(UUID_SENSOR_LOCATION_CHAR, &location) {
p3miya 0:d9d7edb1ddfc 133 setupService();
p3miya 0:d9d7edb1ddfc 134 }
p3miya 0:d9d7edb1ddfc 135
p3miya 0:d9d7edb1ddfc 136 void updateCyclingPower(uint16_t flags, int16_t pwr, uint8_t bal, int16_t maxTorque, int16_t minTorque, uint16_t dnw, uint16_t dtw, uint16_t dnc, uint16_t dtc) {
p3miya 0:d9d7edb1ddfc 137 instantaneousPower = pwr;
p3miya 0:d9d7edb1ddfc 138 pedalPowerBalance = bal;
p3miya 0:d9d7edb1ddfc 139 maximumTorqueMagnitude = maxTorque;
p3miya 0:d9d7edb1ddfc 140 minimumTorqueMagnitude = minTorque;
p3miya 0:d9d7edb1ddfc 141
p3miya 0:d9d7edb1ddfc 142 cumulativeWheelRev += dnw;
p3miya 0:d9d7edb1ddfc 143 lastWheelEventTime += dtw;
p3miya 0:d9d7edb1ddfc 144 cumulativeCrankRev += dnc;
p3miya 0:d9d7edb1ddfc 145 lastCrankEventTime += dtc;
p3miya 0:d9d7edb1ddfc 146
p3miya 0:d9d7edb1ddfc 147 unsigned i = 0;
p3miya 0:d9d7edb1ddfc 148 measureData[i++] = (uint8_t)(flags & 0xFF);
p3miya 0:d9d7edb1ddfc 149 measureData[i++] = (uint8_t)(flags >> 8);
p3miya 0:d9d7edb1ddfc 150
p3miya 0:d9d7edb1ddfc 151 measureData[i++] = (uint8_t)(instantaneousPower & 0xFF);
p3miya 0:d9d7edb1ddfc 152 measureData[i++] = (uint8_t)(instantaneousPower >> 8);
p3miya 0:d9d7edb1ddfc 153
p3miya 0:d9d7edb1ddfc 154 if (flags & FLAG_PEDAL_POWER_BALANCE_PRESENT) {
p3miya 0:d9d7edb1ddfc 155 measureData[i++] = pedalPowerBalance;
p3miya 0:d9d7edb1ddfc 156 }
p3miya 0:d9d7edb1ddfc 157 if (flags & FLAG_WHEEL_REVOLUTION_DATA_PRESENT) {
p3miya 0:d9d7edb1ddfc 158 measureData[i++] = (uint8_t)(cumulativeWheelRev & 0xFF);
p3miya 0:d9d7edb1ddfc 159 measureData[i++] = (uint8_t)((cumulativeWheelRev >> 8) & 0xFF);
p3miya 0:d9d7edb1ddfc 160 measureData[i++] = (uint8_t)((cumulativeWheelRev >> 16) & 0xFF);
p3miya 0:d9d7edb1ddfc 161 measureData[i++] = (uint8_t)((cumulativeWheelRev >> 24) & 0xFF);
p3miya 0:d9d7edb1ddfc 162
p3miya 0:d9d7edb1ddfc 163 measureData[i++] = (uint8_t)(lastWheelEventTime & 0xFF);
p3miya 0:d9d7edb1ddfc 164 measureData[i++] = (uint8_t)(lastWheelEventTime >> 8);
p3miya 0:d9d7edb1ddfc 165 }
p3miya 0:d9d7edb1ddfc 166 if (flags & FLAG_CRANK_REVOLUTION_DATA_PRESENT) {
p3miya 0:d9d7edb1ddfc 167 measureData[i++] = (uint8_t)(cumulativeCrankRev & 0xFF);
p3miya 0:d9d7edb1ddfc 168 measureData[i++] = (uint8_t)(cumulativeCrankRev >> 8);
p3miya 0:d9d7edb1ddfc 169
p3miya 0:d9d7edb1ddfc 170 measureData[i++] = (uint8_t)(lastCrankEventTime & 0xFF);
p3miya 0:d9d7edb1ddfc 171 measureData[i++] = (uint8_t)(lastCrankEventTime >> 8);
p3miya 0:d9d7edb1ddfc 172 }
p3miya 0:d9d7edb1ddfc 173 if (flags & FLAG_EXTREME_TORQUE_MAGNITUDES_PRESENT) {
p3miya 0:d9d7edb1ddfc 174 measureData[i++] = (uint8_t)(maximumTorqueMagnitude & 0xFF);
p3miya 0:d9d7edb1ddfc 175 measureData[i++] = (uint8_t)(maximumTorqueMagnitude >> 8);
p3miya 0:d9d7edb1ddfc 176
p3miya 0:d9d7edb1ddfc 177 measureData[i++] = (uint8_t)(minimumTorqueMagnitude & 0xFF);
p3miya 0:d9d7edb1ddfc 178 measureData[i++] = (uint8_t)(minimumTorqueMagnitude >> 8);
p3miya 0:d9d7edb1ddfc 179 }
p3miya 0:d9d7edb1ddfc 180 unsigned nbyte = i;
p3miya 0:d9d7edb1ddfc 181 ble.updateCharacteristicValue(cyclingPowerMeasurement.getValueAttribute().getHandle(), measureData, nbyte);
p3miya 0:d9d7edb1ddfc 182 }
p3miya 0:d9d7edb1ddfc 183
p3miya 0:d9d7edb1ddfc 184 void indicateResponse(uint8_t opCode, uint8_t responseValue) {
p3miya 0:d9d7edb1ddfc 185 controlData[0] = 0x20; // Response Code
p3miya 0:d9d7edb1ddfc 186 controlData[1] = opCode;
p3miya 0:d9d7edb1ddfc 187 controlData[2] = responseValue;
p3miya 0:d9d7edb1ddfc 188 unsigned nbyte = 3;
p3miya 0:d9d7edb1ddfc 189 ble.updateCharacteristicValue(cyclingPowerControlPoint.getValueAttribute().getHandle(), controlData, nbyte);
p3miya 0:d9d7edb1ddfc 190 }
p3miya 0:d9d7edb1ddfc 191
p3miya 0:d9d7edb1ddfc 192 void indicateResponse(uint8_t opCode, uint8_t responseValue, uint16_t responseParameter) {
p3miya 0:d9d7edb1ddfc 193 controlData[0] = 0x20; // Response Code
p3miya 0:d9d7edb1ddfc 194 controlData[1] = opCode;
p3miya 0:d9d7edb1ddfc 195 controlData[2] = responseValue;
p3miya 0:d9d7edb1ddfc 196 controlData[3] = (uint8_t)(responseParameter & 0xFF);
p3miya 0:d9d7edb1ddfc 197 controlData[4] = (uint8_t)(responseParameter >> 8);
p3miya 0:d9d7edb1ddfc 198 unsigned nbyte = 5;
p3miya 0:d9d7edb1ddfc 199 ble.updateCharacteristicValue(cyclingPowerControlPoint.getValueAttribute().getHandle(), controlData, nbyte);
p3miya 0:d9d7edb1ddfc 200 }
p3miya 0:d9d7edb1ddfc 201
p3miya 0:d9d7edb1ddfc 202 virtual void onDataWritten(const GattWriteCallbackParams *params) {
p3miya 0:d9d7edb1ddfc 203 if (params->handle == cyclingPowerControlPoint.getValueAttribute().getHandle()) {
p3miya 0:d9d7edb1ddfc 204 uint32_t uu;
p3miya 0:d9d7edb1ddfc 205 uint8_t opCode = params->data[0];
p3miya 0:d9d7edb1ddfc 206 switch(opCode) {
p3miya 0:d9d7edb1ddfc 207 case OPCODE_SET_CUMULATIVE_VALUE:
p3miya 0:d9d7edb1ddfc 208 uu = params->data[4];
p3miya 0:d9d7edb1ddfc 209 uu *= 256;
p3miya 0:d9d7edb1ddfc 210 uu += params->data[3];
p3miya 0:d9d7edb1ddfc 211 uu *= 256;
p3miya 0:d9d7edb1ddfc 212 uu += params->data[2];
p3miya 0:d9d7edb1ddfc 213 uu *= 256;
p3miya 0:d9d7edb1ddfc 214 uu += params->data[1];
p3miya 0:d9d7edb1ddfc 215 cumulativeWheelRev = uu;
p3miya 0:d9d7edb1ddfc 216 indicateResponse(opCode, CyclingPowerService::RESPONSE_SUCCESS);
p3miya 0:d9d7edb1ddfc 217 break;
p3miya 0:d9d7edb1ddfc 218 default:
p3miya 0:d9d7edb1ddfc 219 indicateResponse(opCode, CyclingPowerService::RESPONSE_OP_CODE_NOT_SUPPORTED);
p3miya 0:d9d7edb1ddfc 220 }
p3miya 0:d9d7edb1ddfc 221 }
p3miya 0:d9d7edb1ddfc 222 }
p3miya 0:d9d7edb1ddfc 223
p3miya 0:d9d7edb1ddfc 224 protected:
p3miya 0:d9d7edb1ddfc 225 void setupService(void) {
p3miya 0:d9d7edb1ddfc 226 instantaneousPower = 0;
p3miya 0:d9d7edb1ddfc 227 pedalPowerBalance = 50 * 2; // 50%
p3miya 0:d9d7edb1ddfc 228 maximumTorqueMagnitude = 0;
p3miya 0:d9d7edb1ddfc 229 minimumTorqueMagnitude = 0;
p3miya 0:d9d7edb1ddfc 230
p3miya 0:d9d7edb1ddfc 231 cumulativeWheelRev = 0;
p3miya 0:d9d7edb1ddfc 232 lastWheelEventTime = 0;
p3miya 0:d9d7edb1ddfc 233 cumulativeCrankRev = 0;
p3miya 0:d9d7edb1ddfc 234 lastCrankEventTime = 0;
p3miya 0:d9d7edb1ddfc 235
p3miya 0:d9d7edb1ddfc 236 GattCharacteristic *charTable[] = {&cyclingPowerMeasurement, &cyclingPowerFeature, &cyclingPowerLocation, &cyclingPowerControlPoint};
p3miya 0:d9d7edb1ddfc 237 GattService cyclingPowerService(UUID_CYCLING_POWER_SERVICE, charTable, sizeof(charTable) / sizeof(GattCharacteristic *));
p3miya 0:d9d7edb1ddfc 238
p3miya 0:d9d7edb1ddfc 239 ble.addService(cyclingPowerService);
p3miya 0:d9d7edb1ddfc 240 ble.onDataWritten(this, &CyclingPowerService::onDataWritten);
p3miya 0:d9d7edb1ddfc 241 }
p3miya 0:d9d7edb1ddfc 242
p3miya 0:d9d7edb1ddfc 243 protected:
p3miya 0:d9d7edb1ddfc 244 BLE &ble;
p3miya 0:d9d7edb1ddfc 245
p3miya 0:d9d7edb1ddfc 246 GattCharacteristic cyclingPowerMeasurement;
p3miya 0:d9d7edb1ddfc 247 GattCharacteristic cyclingPowerControlPoint;
p3miya 0:d9d7edb1ddfc 248 ReadOnlyGattCharacteristic<uint32_t> cyclingPowerFeature;
p3miya 0:d9d7edb1ddfc 249 ReadOnlyGattCharacteristic<uint8_t> cyclingPowerLocation;
p3miya 0:d9d7edb1ddfc 250
p3miya 0:d9d7edb1ddfc 251 static const unsigned MAX_MEASURE_BYTES = 19;
p3miya 0:d9d7edb1ddfc 252 static const unsigned MAX_CONTROL_BYTES = 5;
p3miya 0:d9d7edb1ddfc 253
p3miya 0:d9d7edb1ddfc 254 uint8_t measureData[MAX_MEASURE_BYTES];
p3miya 0:d9d7edb1ddfc 255 uint8_t controlData[MAX_CONTROL_BYTES];
p3miya 0:d9d7edb1ddfc 256
p3miya 0:d9d7edb1ddfc 257 int16_t instantaneousPower;
p3miya 0:d9d7edb1ddfc 258 uint8_t pedalPowerBalance;
p3miya 0:d9d7edb1ddfc 259 int16_t maximumTorqueMagnitude;
p3miya 0:d9d7edb1ddfc 260 int16_t minimumTorqueMagnitude;
p3miya 0:d9d7edb1ddfc 261
p3miya 0:d9d7edb1ddfc 262 uint32_t cumulativeWheelRev;
p3miya 0:d9d7edb1ddfc 263 uint16_t lastWheelEventTime;
p3miya 0:d9d7edb1ddfc 264 uint16_t cumulativeCrankRev;
p3miya 0:d9d7edb1ddfc 265 uint16_t lastCrankEventTime;
p3miya 0:d9d7edb1ddfc 266 };
p3miya 0:d9d7edb1ddfc 267
p3miya 0:d9d7edb1ddfc 268 #endif /* #ifndef __BLE_CYCLING_POWER_SERVICE_H__*/