rakha asyrofi / Mbed 2 deprecated BLE_CSCADXL345

Dependencies:   ADXL345 BLE_API mbed nRF51822

Fork of BLE_CycleSpeedCadence by Robert Walker

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers CyclingSpeedAndCadenceService.h Source File

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__*/