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.
Fork of BLE_API by
HeartRateService.h
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2006-2013 ARM Limited 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_HEART_RATE_SERVICE_H__ 00018 #define __BLE_HEART_RATE_SERVICE_H__ 00019 00020 #include "ble/BLE.h" 00021 00022 /** 00023 * @class HeartRateService 00024 * @brief BLE Service for HeartRate. This BLE Service contains the location of the sensor, the heartrate in beats per minute. <br> 00025 * Service: https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.heart_rate.xml <br> 00026 * HRM Char: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.heart_rate_measurement.xml <br> 00027 * Location: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.body_sensor_location.xml 00028 */ 00029 class HeartRateService { 00030 public: 00031 /** 00032 * @enum SensorLocation 00033 * @brief Location of HeartRate sensor on body. 00034 */ 00035 enum { 00036 LOCATION_OTHER = 0, /*!< Other Location */ 00037 LOCATION_CHEST , /*!< Chest */ 00038 LOCATION_WRIST , /*!< Wrist */ 00039 LOCATION_FINGER , /*!< Finger */ 00040 LOCATION_HAND , /*!< Hand */ 00041 LOCATION_EAR_LOBE , /*!< Earlobe */ 00042 LOCATION_FOOT , /*!< Foot */ 00043 }; 00044 00045 public: 00046 /** 00047 * @brief Constructor with 8bit HRM Counter value. 00048 * 00049 * @param[ref] _ble 00050 * Reference to the underlying BLE. 00051 * @param[in] hrmCounter (8-bit) 00052 * initial value for the hrm counter. 00053 * @param[in] location 00054 * Sensor's location. 00055 */ 00056 HeartRateService(BLE &_ble, uint8_t hrmCounter, uint8_t location) : 00057 ble(_ble), 00058 valueBytes(hrmCounter), 00059 hrmRate(GattCharacteristic::UUID_HEART_RATE_MEASUREMENT_CHAR, valueBytes.getPointer(), 00060 valueBytes.getNumValueBytes(), HeartRateValueBytes::MAX_VALUE_BYTES, 00061 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY), 00062 hrmLocation(GattCharacteristic::UUID_BODY_SENSOR_LOCATION_CHAR, &location), 00063 controlPoint(GattCharacteristic::UUID_HEART_RATE_CONTROL_POINT_CHAR, &controlPointValue) { 00064 setupService(); 00065 } 00066 00067 /** 00068 * @brief Constructor with a 16-bit HRM Counter value. 00069 * 00070 * @param[in] _ble 00071 * Reference to the underlying BLE. 00072 * @param[in] hrmCounter (8-bit) 00073 * initial value for the hrm counter. 00074 * @param[in] location 00075 * Sensor's location. 00076 */ 00077 HeartRateService(BLE &_ble, uint16_t v1, uint16_t v2, uint8_t location) : 00078 ble(_ble), 00079 valueBytes(v1,v2), 00080 hrmRate(GattCharacteristic::UUID_HEART_RATE_MEASUREMENT_CHAR, valueBytes.getPointer(), 00081 valueBytes.getNumValueBytes(), HeartRateValueBytes::MAX_VALUE_BYTES, 00082 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY), 00083 hrmLocation(GattCharacteristic::UUID_BODY_SENSOR_LOCATION_CHAR, &location), 00084 controlPoint(GattCharacteristic::UUID_HEART_RATE_CONTROL_POINT_CHAR, &controlPointValue) { 00085 setupService(); 00086 } 00087 00088 /** 00089 * @brief Set a new 8-bit value for heart rate. 00090 * 00091 * @param[in] hrmCounter 00092 * HeartRate in bpm. 00093 */ 00094 void updateHeartRate(uint8_t hrmCounter) { 00095 valueBytes.updateHeartRate(hrmCounter); 00096 ble.gattServer().write(hrmRate.getValueHandle(), valueBytes.getPointer(), valueBytes.getNumValueBytes()); 00097 } 00098 00099 /** 00100 * Set a new 16-bit value for heart rate. 00101 * 00102 * @param[in] hrmCounter 00103 * HeartRate in bpm. 00104 */ 00105 void updateHeartRate(uint16_t hrmCounter) { 00106 valueBytes.updateHeartRate(hrmCounter); 00107 ble.gattServer().write(hrmRate.getValueHandle(), valueBytes.getPointer(), valueBytes.getNumValueBytes()); 00108 } 00109 00110 void updateHeartRate(uint16_t v1, uint16_t v2) { 00111 valueBytes.updateHeartRate(v1,v2); 00112 ble.gattServer().write(hrmRate.getValueHandle(), valueBytes.getPointer(), valueBytes.getNumValueBytes()); 00113 } 00114 00115 void updateHeartRate(int32_t v1, int32_t v2) { 00116 valueBytes.updateHeartRate(v1,v2); 00117 ble.gattServer().write(hrmRate.getValueHandle(), valueBytes.getPointer(), valueBytes.getNumValueBytes()); 00118 } 00119 00120 /** 00121 * This callback allows the HeartRateService to receive updates to the 00122 * controlPoint Characteristic. 00123 * 00124 * @param[in] params 00125 * Information about the characterisitc being updated. 00126 */ 00127 virtual void onDataWritten(const GattWriteCallbackParams *params) { 00128 if (params->handle == controlPoint.getValueAttribute().getHandle()) { 00129 /* Do something here if the new value is 1; else you can override this method by 00130 * extending this class. 00131 * @NOTE: if you are extending this class, be sure to also call 00132 * ble.onDataWritten(this, &ExtendedHRService::onDataWritten); in 00133 * your constructor. 00134 */ 00135 } 00136 } 00137 00138 protected: 00139 void setupService(void) { 00140 GattCharacteristic *charTable[] = {&hrmRate, &hrmLocation, &controlPoint}; 00141 GattService hrmService(GattService::UUID_HEART_RATE_SERVICE, charTable, sizeof(charTable) / sizeof(GattCharacteristic *)); 00142 00143 ble.addService(hrmService); 00144 ble.onDataWritten(this, &HeartRateService::onDataWritten); 00145 } 00146 00147 protected: 00148 /* Private internal representation for the bytes used to work with the vaulue of the heart-rate characteristic. */ 00149 struct HeartRateValueBytes { 00150 static const unsigned MAX_VALUE_BYTES = 10; /* FLAGS + up to two bytes for heart-rate */ 00151 static const unsigned FLAGS_BYTE_INDEX = 0; 00152 00153 static const unsigned VALUE_FORMAT_BITNUM = 0; 00154 static const uint8_t VALUE_FORMAT_FLAG = (1 << VALUE_FORMAT_BITNUM); 00155 00156 HeartRateValueBytes(uint8_t hrmCounter) : valueBytes() { 00157 updateHeartRate(hrmCounter); 00158 } 00159 00160 HeartRateValueBytes(uint16_t hrmCounter) : valueBytes() { 00161 updateHeartRate(hrmCounter); 00162 } 00163 00164 HeartRateValueBytes(uint16_t v1, uint16_t v2) : valueBytes() { 00165 updateHeartRate(v1,v2); 00166 } 00167 00168 void updateHeartRate(uint8_t hrmCounter) { 00169 valueBytes[FLAGS_BYTE_INDEX] &= ~VALUE_FORMAT_FLAG; 00170 valueBytes[FLAGS_BYTE_INDEX + 1] = hrmCounter; 00171 } 00172 00173 void updateHeartRate(uint16_t hrmCounter) { 00174 valueBytes[FLAGS_BYTE_INDEX] |= VALUE_FORMAT_FLAG; 00175 valueBytes[FLAGS_BYTE_INDEX + 1] = (uint8_t)(hrmCounter & 0xFF); 00176 valueBytes[FLAGS_BYTE_INDEX + 2] = (uint8_t)(hrmCounter >> 8); 00177 } 00178 00179 void updateHeartRate(uint16_t v1, uint16_t v2) 00180 { 00181 valueBytes[FLAGS_BYTE_INDEX] |= VALUE_FORMAT_FLAG; 00182 valueBytes[FLAGS_BYTE_INDEX + 1] = (uint8_t)(v1 & 0xFF); 00183 valueBytes[FLAGS_BYTE_INDEX + 2] = (uint8_t)(v1 >> 8); 00184 valueBytes[FLAGS_BYTE_INDEX + 3] = (uint8_t)(v2 & 0xFF); 00185 valueBytes[FLAGS_BYTE_INDEX + 4] = (uint8_t)(v2 >> 8); 00186 } 00187 00188 void updateHeartRate(int32_t v1, int32_t v2) 00189 { 00190 unsigned char *u1; 00191 u1 = ((unsigned char*)&v1); 00192 valueBytes[FLAGS_BYTE_INDEX] |= VALUE_FORMAT_FLAG; 00193 valueBytes[FLAGS_BYTE_INDEX + 1] = (uint8_t)(u1[0]&0xFF); 00194 valueBytes[FLAGS_BYTE_INDEX + 2] = (uint8_t)(u1[1]&0xFF); 00195 valueBytes[FLAGS_BYTE_INDEX + 3] = (uint8_t)(u1[2]&0xFF); 00196 valueBytes[FLAGS_BYTE_INDEX + 4] = (uint8_t)(u1[3]&0xFF); 00197 00198 u1 = ((unsigned char*)&v2); 00199 valueBytes[FLAGS_BYTE_INDEX + 5] = (uint8_t)(u1[0]&0xFF); 00200 valueBytes[FLAGS_BYTE_INDEX + 6] = (uint8_t)(u1[1]&0xFF); 00201 valueBytes[FLAGS_BYTE_INDEX + 7] = (uint8_t)(u1[2]&0xFF); 00202 valueBytes[FLAGS_BYTE_INDEX + 8] = (uint8_t)(u1[3]&0xFF); 00203 } 00204 00205 00206 uint8_t *getPointer(void) { 00207 return valueBytes; 00208 } 00209 00210 const uint8_t *getPointer(void) const { 00211 return valueBytes; 00212 } 00213 00214 unsigned getNumValueBytes(void) const { 00215 //return 1 + ((valueBytes[FLAGS_BYTE_INDEX] & VALUE_FORMAT_FLAG) ? sizeof(uint16_t) : sizeof(uint8_t)); 00216 return 1 + sizeof(uint32_t)*2; 00217 } 00218 00219 private: 00220 /* First byte = 8-bit values, no extra info, Second byte = uint8_t HRM value */ 00221 /* See --> https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.heart_rate_measurement.xml */ 00222 uint8_t valueBytes[MAX_VALUE_BYTES]; 00223 }; 00224 00225 protected: 00226 BLE &ble; 00227 00228 HeartRateValueBytes valueBytes; 00229 uint8_t controlPointValue; 00230 00231 GattCharacteristic hrmRate; 00232 ReadOnlyGattCharacteristic<uint8_t> hrmLocation; 00233 WriteOnlyGattCharacteristic<uint8_t> controlPoint; 00234 }; 00235 00236 #endif /* #ifndef __BLE_HEART_RATE_SERVICE_H__*/
Generated on Tue Jul 12 2022 21:38:40 by
1.7.2
