Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: ADXL345 BLE_API mbed nRF51822
Fork of BLE_CycleSpeedCadence by
CyclingSpeedAndCadenceService.h
00001 /* 00002 * Copyright (c) 2015 Robert Walker 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #ifndef __BLE_CYCLING_SPEED_AND_CADENCE_SERVICE_H__ 00018 #define __BLE_CYCLING_SPEED_AND_CADENCE_SERVICE_H__ 00019 00020 #include "ble/BLE.h" 00021 00022 /** 00023 * @class CyclingSpeedAndCadenceService 00024 * @brief BLE Service for Cycling Speed and Cadence. This BLE Service contains the location of the sensor, the total wheel revolutions, total crank revolutiosn. <br> 00025 * Service: https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.cycling_speed_and_cadence.xml <br> 00026 * CSC Char: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.csc_measurement.xml <br> 00027 * Location: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.sensor_location.xml 00028 */ 00029 class CyclingSpeedAndCadenceService { 00030 public: 00031 static const uint8_t FLAG_WHEEL_PRESENT = (1 << 0); 00032 static const uint8_t FLAG_CRANK_PRESENT = (1 << 1); 00033 00034 enum Mode { 00035 MODE_SPEED = FLAG_WHEEL_PRESENT, 00036 MODE_CADENCE = FLAG_CRANK_PRESENT, 00037 MODE_SPEED_CADENCE = FLAG_WHEEL_PRESENT | FLAG_CRANK_PRESENT 00038 }; 00039 00040 /** 00041 * @enum SensorLocation 00042 * @brief Location of sensor on bike. 00043 */ 00044 enum { 00045 LOCATION_OTHER , /*!< Other */ 00046 LOCATION_TOP_OF_SHOE , /*!< Top of shoe */ 00047 LOCATION_IN_SHOE , /*!< In shoe */ 00048 LOCATION_HIP , /*!< Hip */ 00049 LOCATION_FRONT_WHEEL , /*!< Front Wheel */ 00050 LOCATION_LEFT_CRANK , /*!< Left Crank */ 00051 LOCATION_RIGHT_CRANK , /*!< Right Crank */ 00052 LOCATION_LEFT_PEDAL , /*!< Left Pedal */ 00053 LOCATION_RIGHT_PEDAL , /*!< Right Pedal */ 00054 LOCATION_FRONT_HUB , /*!< Front Hub */ 00055 LOCATION_REAR_DROPOUT , /*!< Rear Dropout */ 00056 LOCATION_CHAINSTAY , /*!< Chainstay */ 00057 LOCATION_REAR_WHEEL , /*!< Rear Wheel */ 00058 LOCATION_REAR_HUB , /*!< Rear Hub */ 00059 LOCATION_CHEST , /*!< Chest */ 00060 }; 00061 00062 enum { 00063 UUID_SENSOR_LOCATION_CHAR = 0x2A5D, 00064 UUID_SC_CONTROL_POINT_CHAR = 0x2A55 00065 }; 00066 00067 public: 00068 /** 00069 * @brief Constructor with initial counter values. 00070 * 00071 * @param[ref] _ble 00072 * Reference to the underlying BLE. 00073 * @param[in] wheelCounter (32-bit) 00074 * initial value for the wheel counter. 00075 * @param[in] crankCounter (32-bit) 00076 * initial value for the crank counter. 00077 * @param[in] location 00078 * Sensor's location. 00079 */ 00080 CyclingSpeedAndCadenceService(BLE &_ble, Mode _mode, uint8_t location) : 00081 ble(_ble), 00082 value(_mode), 00083 mode(_mode), 00084 csc(GattCharacteristic::UUID_CSC_MEASUREMENT_CHAR, 00085 value.bytes, 00086 value.getSize(), value.getSize(), 00087 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY), 00088 cscFeat(GattCharacteristic::UUID_CSC_FEATURE_CHAR, (uint8_t*)&mode, 00089 2, 2, 00090 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ), 00091 scLocation(UUID_SENSOR_LOCATION_CHAR, &location), 00092 controlPoint(UUID_SC_CONTROL_POINT_CHAR, &controlPointValue) { 00093 setupService(); 00094 } 00095 00096 /** 00097 * @brief Set a new value for wheel revolutions. 00098 * 00099 * @param[in] wheelCounter 00100 * Total wheel revolutions. 00101 * @param[in] eventTime 00102 * Time of event. 00103 */ 00104 void updateWheelCounter(uint32_t wheelCounter, uint16_t eventTime) 00105 { 00106 value.updateWheelCounter(wheelCounter, eventTime); 00107 sendUpdate(); 00108 } 00109 00110 /** 00111 * @brief Set a new value for crank revolutions. 00112 * 00113 * @param[in] crankCounter 00114 * Total crank revolutions. 00115 * @param[in] eventTime 00116 * Time of event. 00117 */ 00118 void updateCrankCounter(uint16_t crankCounter, uint16_t eventTime) 00119 { 00120 value.updateCrankCounter(crankCounter, eventTime); 00121 sendUpdate(); 00122 } 00123 00124 void updateCounters(uint32_t wheelCounter, uint16_t crankCounter, uint16_t eventTime) 00125 { 00126 value.updateCounters(wheelCounter, crankCounter, eventTime); 00127 sendUpdate(); 00128 } 00129 00130 /** 00131 * This callback allows the CyclingSpeedAndCadenceService to receive updates to the 00132 * controlPoint Characteristic. 00133 * 00134 * @param[in] params 00135 * Information about the characterisitc being updated. 00136 */ 00137 virtual void onDataWritten(const GattWriteCallbackParams *params) { 00138 if (params->handle == controlPoint.getValueAttribute().getHandle()) { 00139 /* Do something here if the new value is 1; else you can override this method by 00140 * extending this class. 00141 * @NOTE: if you are extending this class, be sure to also call 00142 * ble.onDataWritten(this, &ExtendedHRService::onDataWritten); in 00143 * your constructor. 00144 */ 00145 } 00146 } 00147 00148 protected: 00149 void setupService(void) { 00150 GattCharacteristic *charTable[] = {&csc, &cscFeat, &scLocation, &controlPoint}; 00151 GattService cscService(GattService::UUID_CYCLING_SPEED_AND_CADENCE, charTable, sizeof(charTable) / sizeof(GattCharacteristic *)); 00152 00153 ble.addService(cscService); 00154 ble.onDataWritten(this, &CyclingSpeedAndCadenceService::onDataWritten); 00155 } 00156 00157 00158 void sendUpdate() 00159 { 00160 ble.gattServer().write(csc.getValueHandle(), value.bytes, value.getSize()); 00161 } 00162 00163 protected: 00164 static const uint16_t MAX_BYTES = (1 + 4 + 2 + 2 + 2); 00165 union SpeedCadenceValue 00166 { 00167 SpeedCadenceValue(uint16_t mode) 00168 { 00169 switch (mode) 00170 { 00171 case MODE_SPEED: 00172 v.flags = FLAG_WHEEL_PRESENT; 00173 break; 00174 case MODE_CADENCE: 00175 v.flags = FLAG_CRANK_PRESENT; 00176 break; 00177 case MODE_SPEED_CADENCE: 00178 v.flags = FLAG_WHEEL_PRESENT | FLAG_CRANK_PRESENT; 00179 break; 00180 default: 00181 v.flags = 0; 00182 break; 00183 } 00184 } 00185 00186 void updateWheelCounter(uint32_t wheelCounter, uint16_t eventTime) 00187 { 00188 switch(v.flags) 00189 { 00190 case FLAG_WHEEL_PRESENT: 00191 v.v.speed.wheelCounter = wheelCounter; 00192 v.v.speed.lastWheelEvent = eventTime; 00193 break; 00194 case FLAG_WHEEL_PRESENT | FLAG_CRANK_PRESENT: 00195 v.v.speedCadence.wheelCounter = wheelCounter; 00196 v.v.speedCadence.lastWheelEvent = eventTime; 00197 break; 00198 default: 00199 break; 00200 } 00201 } 00202 00203 void updateCrankCounter(uint16_t crankCounter, uint16_t eventTime) 00204 { 00205 switch(v.flags) 00206 { 00207 case FLAG_CRANK_PRESENT: 00208 v.v.cadence.crankCounter = crankCounter; 00209 v.v.cadence.lastCrankEvent = eventTime; 00210 break; 00211 case FLAG_WHEEL_PRESENT | FLAG_CRANK_PRESENT: 00212 v.v.speedCadence.crankCounter = crankCounter; 00213 v.v.speedCadence.lastCrankEvent = eventTime; 00214 break; 00215 default: 00216 break; 00217 } 00218 } 00219 00220 void updateCounters(uint32_t wheelCounter, uint16_t crankCounter, uint16_t eventTime) 00221 { 00222 switch(v.flags) 00223 { 00224 case FLAG_WHEEL_PRESENT: 00225 v.v.speed.wheelCounter = wheelCounter; 00226 v.v.speed.lastWheelEvent = eventTime; 00227 break; 00228 case FLAG_CRANK_PRESENT: 00229 v.v.cadence.crankCounter = crankCounter; 00230 v.v.cadence.lastCrankEvent = eventTime; 00231 break; 00232 case FLAG_WHEEL_PRESENT | FLAG_CRANK_PRESENT: 00233 v.v.speedCadence.wheelCounter = wheelCounter; 00234 v.v.speedCadence.lastWheelEvent = eventTime; 00235 v.v.speedCadence.crankCounter = crankCounter; 00236 v.v.speedCadence.lastCrankEvent = eventTime; 00237 break; 00238 default: 00239 break; 00240 } 00241 } 00242 00243 uint16_t getSize() 00244 { 00245 return 1 + 00246 ((v.flags & FLAG_WHEEL_PRESENT) ? (4+2) : 0) + 00247 ((v.flags & FLAG_CRANK_PRESENT) ? (2+2) : 0); 00248 } 00249 00250 __packed struct Value 00251 { 00252 uint8_t flags; 00253 __packed union 00254 { 00255 __packed struct Speed 00256 { 00257 uint32_t wheelCounter; 00258 uint16_t lastWheelEvent; 00259 } speed; 00260 __packed struct Cadence 00261 { 00262 uint16_t crankCounter; 00263 uint16_t lastCrankEvent; 00264 } cadence; 00265 __packed struct SpeedCadence 00266 { 00267 uint32_t wheelCounter; 00268 uint16_t lastWheelEvent; 00269 uint16_t crankCounter; 00270 uint16_t lastCrankEvent; 00271 } speedCadence; 00272 } v; 00273 } v; 00274 uint8_t bytes[1+4+2+2+2]; 00275 }; 00276 00277 protected: 00278 BLE &ble; 00279 00280 SpeedCadenceValue value; 00281 uint16_t mode; 00282 uint8_t controlPointValue; 00283 00284 GattCharacteristic csc; 00285 GattCharacteristic cscFeat; 00286 ReadOnlyGattCharacteristic<uint8_t> scLocation; 00287 WriteOnlyGattCharacteristic<uint8_t> controlPoint; 00288 }; 00289 00290 #endif /* #ifndef __BLE_CYCLING_SPEED_AND_CADENCE_SERVICE_H__*/
Generated on Thu Jul 21 2022 09:23:01 by
1.7.2
