BLE demo for the Cycling Power service.
Dependencies: BLE_API mbed nRF51822
CyclingPowerService.h@0:d9d7edb1ddfc, 2016-02-27 (annotated)
- 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?
User | Revision | Line number | New 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__*/ |