X-NUCLEO-IKS01A1 Environmental/Motion sensors data transmitted via X-NUCLEO-IDB04A1 BLE board. Compatible with iOS/Android ST BlueMS V2.1 application.
Dependencies: BLE_API X_NUCLEO_IDB0XA1 X_NUCLEO_IKS01A1 mbed
Fork of Bluemicrosystem1 by
CustomSensorsService.h
00001 /** 00002 ****************************************************************************** 00003 * @file CustomSensorService.h 00004 * @author Central Labs / AST 00005 * @version V0.9.0 00006 * @date 23-Dec-2015 00007 * @brief BLE MEMS and environmental sensors service 00008 ****************************************************************************** 00009 * @attention 00010 * 00011 * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> 00012 * 00013 * Redistribution and use in source and binary forms, with or without modification, 00014 * are permitted provided that the following conditions are met: 00015 * 1. Redistributions of source code must retain the above copyright notice, 00016 * this list of conditions and the following disclaimer. 00017 * 2. Redistributions in binary form must reproduce the above copyright notice, 00018 * this list of conditions and the following disclaimer in the documentation 00019 * and/or other materials provided with the distribution. 00020 * 3. Neither the name of STMicroelectronics nor the names of its contributors 00021 * may be used to endorse or promote products derived from this software 00022 * without specific prior written permission. 00023 * 00024 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00025 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00026 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00027 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 00028 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00029 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00030 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00031 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00032 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00033 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00034 * 00035 ****************************************************************************** 00036 */ 00037 00038 #ifndef __CUSTOM_BLE_SENSORS_SERVICE_H__ 00039 #define __CUSTOM_BLE_SENSORS_SERVICE_H__ 00040 00041 #include "BLE.h" 00042 00043 const LongUUIDBytes_t SENS_SERVICE_UUID_128 = { 0x00,0x00,0x00,0x00,0x00,0x01,0x11,0xe1,0x9a,0xb4,0x00,0x02,0xa5,0xd5,0xc5,0x1b }; // temp, pressure, humidity, 00044 const LongUUIDBytes_t SENS_TEMP_CHAR_UUID_128 = { 0x00,0x04,0x00,0x00,0x00,0x01,0x11,0xe1,0xac,0x36,0x00,0x02,0xa5,0xd5,0xc5,0x1b }; 00045 const LongUUIDBytes_t SENS_HUMI_CHAR_UUID_128 = { 0x00,0x08,0x00,0x00,0x00,0x01,0x11,0xe1,0xac,0x36,0x00,0x02,0xa5,0xd5,0xc5,0x1b }; 00046 const LongUUIDBytes_t SENS_PRES_CHAR_UUID_128 = { 0x00,0x10,0x00,0x00,0x00,0x01,0x11,0xe1,0xac,0x36,0x00,0x02,0xa5,0xd5,0xc5,0x1b }; 00047 const LongUUIDBytes_t SENS_MAGN_CHAR_UUID_128 = { 0x00,0x20,0x00,0x00,0x00,0x01,0x11,0xe1,0xac,0x36,0x00,0x02,0xa5,0xd5,0xc5,0x1b }; 00048 const LongUUIDBytes_t SENS_GYRO_CHAR_UUID_128 = { 0x00,0x40,0x00,0x00,0x00,0x01,0x11,0xe1,0xac,0x36,0x00,0x02,0xa5,0xd5,0xc5,0x1b }; 00049 const LongUUIDBytes_t SENS_ACCE_CHAR_UUID_128 = { 0x00,0x80,0x00,0x00,0x00,0x01,0x11,0xe1,0xac,0x36,0x00,0x02,0xa5,0xd5,0xc5,0x1b }; 00050 const LongUUIDBytes_t SENS_ACC_GYRO_MAG_CHAR_UUID_128 = { 0x00,0xE0,0x00,0x00,0x00,0x01,0x11,0xe1,0xac,0x36,0x00,0x02,0xa5,0xd5,0xc5,0x1b }; 00051 00052 00053 #define TEMP_DATA_LEN 2+2 00054 #define HUM_DATA_LEN 2+2 00055 #define PRES_DATA_LEN 2+4 00056 #define ACC_DATA_LEN 6+2 00057 #define MAG_DATA_LEN 6+2 00058 #define GYRO_DATA_LEN 6+2 00059 #define ACCGYROMAG_DATA_LEN 2+3*3*2 00060 00061 00062 /* Custom Sensors Service */ 00063 class CustomSensorService 00064 { 00065 public: 00066 CustomSensorService(BLE &_ble) : 00067 ble(_ble), 00068 envTemperatureCharacteristic(SENS_TEMP_CHAR_UUID_128,envTemperature, TEMP_DATA_LEN, TEMP_DATA_LEN, 00069 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY), 00070 envHumidityCharacteristic(SENS_HUMI_CHAR_UUID_128, envHumidity, HUM_DATA_LEN, HUM_DATA_LEN, 00071 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY), 00072 envPressureCharacteristic(SENS_PRES_CHAR_UUID_128, envPressure, PRES_DATA_LEN, PRES_DATA_LEN, 00073 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY), 00074 envMagnetometerCharacteristic(SENS_MAGN_CHAR_UUID_128,envMagn, MAG_DATA_LEN, MAG_DATA_LEN, 00075 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY), 00076 envAccelerometerCharacteristic(SENS_ACCE_CHAR_UUID_128,envAcce, ACC_DATA_LEN, ACC_DATA_LEN, 00077 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY), 00078 envGyroCharacteristic(SENS_GYRO_CHAR_UUID_128,envGyro, GYRO_DATA_LEN, GYRO_DATA_LEN, 00079 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY), 00080 envAccGyroMagCharacteristic(SENS_ACC_GYRO_MAG_CHAR_UUID_128,envAccGyroMag, ACCGYROMAG_DATA_LEN, ACCGYROMAG_DATA_LEN, 00081 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY) { 00082 00083 static bool serviceAdded = false; /* We should only ever need to add the env service once. */ 00084 if (serviceAdded) { 00085 return; 00086 } 00087 00088 GattCharacteristic *charTable[] = {&envTemperatureCharacteristic, &envHumidityCharacteristic, &envPressureCharacteristic, &envMagnetometerCharacteristic, 00089 &envAccelerometerCharacteristic, &envGyroCharacteristic, &envAccGyroMagCharacteristic 00090 }; 00091 00092 GattService envService(SENS_SERVICE_UUID_128, charTable, sizeof(charTable) / sizeof(GattCharacteristic *)); 00093 00094 ble.gattServer().addService(envService); 00095 00096 isEnabledTempNotify = false; 00097 isEnabledHumNotify = false; 00098 isEnabledPresNotify = false; 00099 isEnabledGyroNotify = false; 00100 isEnabledAccNotify = false; 00101 isEnabledMagNotify = false; 00102 isEnabledAccGyroMagNotify = false; 00103 00104 isTempCalibrated = false; 00105 isHumCalibrated = false; 00106 isPresCalibrated = false; 00107 isMagCalibrated = false; 00108 isAccCalibrated = false; 00109 isAGyroCalibrated = false; 00110 00111 memset (pastenvTemperature, 0, TEMP_DATA_LEN); 00112 memset (pastenvHumidity, 0, HUM_DATA_LEN); 00113 memset (pastenvPressure, 0, PRES_DATA_LEN); 00114 00115 isBTLEConnected = DISCONNECTED; 00116 serviceAdded = true; 00117 } 00118 00119 uint32_t sendEnvTemperature (int16_t Temp, uint16_t TimeStamp) { 00120 STORE_LE_16(envTemperature,TimeStamp); 00121 STORE_LE_16(envTemperature+2,Temp); 00122 PRINTF("sendEnvTemperature!! handle: %d\n\r", envTemperatureCharacteristic.getValueAttribute().getHandle()); 00123 memcpy (pastenvTemperature, envTemperature, TEMP_DATA_LEN); 00124 return ble.gattServer().write(envTemperatureCharacteristic.getValueAttribute().getHandle(), envTemperature, TEMP_DATA_LEN, 0); 00125 } 00126 00127 /** 00128 * Update the temperature with a new value. Valid values range from 00129 * 0..100. Anything outside this range will be ignored. 00130 * @param newLevel New level. */ 00131 uint32_t updateEnvTemperature (int16_t Temp, uint16_t TimeStamp) { 00132 if (memcmp (&pastenvTemperature[2], &Temp, 2) != 0) { 00133 return sendEnvTemperature (Temp, TimeStamp); 00134 } 00135 return 0; 00136 } 00137 00138 uint32_t sendEnvHumidity(uint16_t Hum, uint16_t TimeStamp) { 00139 STORE_LE_16(envHumidity,TimeStamp); 00140 STORE_LE_16(envHumidity+2,Hum); 00141 memcpy (pastenvHumidity, envHumidity, HUM_DATA_LEN); 00142 return ble.gattServer().write(envHumidityCharacteristic.getValueAttribute().getHandle(), envHumidity, HUM_DATA_LEN, 0); 00143 } 00144 00145 uint32_t updateEnvHumidity(uint16_t Hum, uint16_t TimeStamp) { 00146 if (memcmp (&pastenvHumidity[2], &Hum, 2) != 0) { 00147 return sendEnvHumidity(Hum, TimeStamp); 00148 } 00149 return 0; 00150 } 00151 00152 uint32_t sendEnvPressure(uint32_t Press, uint16_t TimeStamp) { 00153 STORE_LE_16(envPressure,TimeStamp); 00154 STORE_LE_32(envPressure+2,Press); 00155 memcpy (pastenvPressure, envPressure, PRES_DATA_LEN); 00156 return ble.gattServer().write(envPressureCharacteristic.getValueAttribute().getHandle(), envPressure, PRES_DATA_LEN, 0); 00157 } 00158 00159 uint32_t updateEnvPressure(uint32_t Press, uint16_t TimeStamp) { 00160 if (memcmp (&pastenvPressure[2], &Press, 2) != 0) { 00161 return sendEnvPressure(Press, TimeStamp); 00162 } 00163 return 0; 00164 } 00165 00166 uint32_t sendEnvMagnetometer(AxesRaw_TypeDef *Magn, uint16_t TimeStamp, osxMFX_calibFactor magOffset) { 00167 STORE_LE_16(envMagn,TimeStamp); 00168 STORE_LE_16(envMagn+2,(Magn->AXIS_X - magOffset.magOffX)); 00169 STORE_LE_16(envMagn+4,(Magn->AXIS_Y - magOffset.magOffY)); 00170 STORE_LE_16(envMagn+6,(Magn->AXIS_Z - magOffset.magOffZ)); 00171 return ble.gattServer().write(envMagnetometerCharacteristic.getValueAttribute().getHandle(), envMagn, MAG_DATA_LEN, 0); 00172 } 00173 00174 uint32_t updateEnvMagnetometer(AxesRaw_TypeDef *Magn, uint16_t TimeStamp, osxMFX_calibFactor magOffset) { 00175 if (isMagNotificationEn()) return sendEnvMagnetometer(Magn, TimeStamp, magOffset); 00176 return 0; 00177 } 00178 00179 uint32_t sendEnvAccelerometer (AxesRaw_TypeDef *Acc, uint16_t TimeStamp) { 00180 STORE_LE_16(envAcce,TimeStamp); 00181 STORE_LE_16(envAcce+2,Acc->AXIS_X); 00182 STORE_LE_16(envAcce+4,Acc->AXIS_Y); 00183 STORE_LE_16(envAcce+6,Acc->AXIS_Z); 00184 return ble.gattServer().write(envAccelerometerCharacteristic.getValueAttribute().getHandle(), envAcce, ACC_DATA_LEN, 0); 00185 } 00186 00187 uint32_t updateEnvAccelerometer (AxesRaw_TypeDef *Acc, uint16_t TimeStamp) { 00188 if (isAccNotificationEn()) return sendEnvAccelerometer (Acc, TimeStamp); 00189 return 0; 00190 } 00191 00192 uint32_t sendEnvGyroscope (AxesRaw_TypeDef *Gyro, uint16_t TimeStamp) { 00193 STORE_LE_16(envGyro,TimeStamp); 00194 STORE_LE_16(envGyro+2,Gyro->AXIS_X); 00195 STORE_LE_16(envGyro+4,Gyro->AXIS_Y); 00196 STORE_LE_16(envGyro+6,Gyro->AXIS_Z); 00197 return ble.gattServer().write(envGyroCharacteristic.getValueAttribute().getHandle(), envGyro, GYRO_DATA_LEN, 0); 00198 } 00199 00200 uint32_t updateEnvGyroscope (AxesRaw_TypeDef *Gyro, uint16_t TimeStamp) { 00201 if (isGyroNotificationEn()) return sendEnvGyroscope (Gyro, TimeStamp); 00202 return 0; 00203 } 00204 00205 uint32_t sendEnvAccGyroMag (AxesRaw_TypeDef *Acc, AxesRaw_TypeDef *Gyro, AxesRaw_TypeDef *Magn, uint16_t TimeStamp, osxMFX_calibFactor magOffset) { 00206 STORE_LE_16(envAccGyroMag,TimeStamp); 00207 STORE_LE_16(envAccGyroMag+2,Acc->AXIS_X); 00208 STORE_LE_16(envAccGyroMag+4,Acc->AXIS_Y); 00209 STORE_LE_16(envAccGyroMag+6,Acc->AXIS_Z); 00210 00211 STORE_LE_16(envAccGyroMag+8,Gyro->AXIS_X); 00212 STORE_LE_16(envAccGyroMag+10,Gyro->AXIS_Y); 00213 STORE_LE_16(envAccGyroMag+12,Gyro->AXIS_Z); 00214 00215 STORE_LE_16(envAccGyroMag+14,(Magn->AXIS_X - magOffset.magOffX)); 00216 STORE_LE_16(envAccGyroMag+16,(Magn->AXIS_Y - magOffset.magOffY)); 00217 STORE_LE_16(envAccGyroMag+18,(Magn->AXIS_Z - magOffset.magOffZ)); 00218 return ble.gattServer().write(envAccGyroMagCharacteristic.getValueAttribute().getHandle(), envAccGyroMag, ACCGYROMAG_DATA_LEN, 0); 00219 } 00220 00221 uint32_t updateEnvAccGyroMag (AxesRaw_TypeDef *Acc, AxesRaw_TypeDef *Gyro, AxesRaw_TypeDef *Magn, uint16_t TimeStamp, osxMFX_calibFactor magOffset) { 00222 if (isAccGyroMagNotificationEn()) return sendEnvAccGyroMag (Acc, Gyro, Magn, TimeStamp, magOffset); 00223 return 0; 00224 } 00225 void enNotify (Gap::Handle_t a_handle) { 00226 Gap::Handle_t handle = a_handle - BLE_HANDLE_EN_DIS_OFFSET; 00227 if (isTempHandle(handle)) { 00228 isEnabledTempNotify = true; 00229 memset(pastenvTemperature,0,TEMP_DATA_LEN); 00230 return; 00231 } 00232 if (isHumHandle(handle)) { 00233 isEnabledHumNotify = true; 00234 memset(pastenvHumidity,0,HUM_DATA_LEN); 00235 return; 00236 } 00237 if (isPresHandle(handle)) { 00238 isEnabledPresNotify = true; 00239 memset(pastenvPressure,0,PRES_DATA_LEN); 00240 return; 00241 } 00242 if (isGyroHandle(handle)) { 00243 isEnabledGyroNotify = true; 00244 return; 00245 } 00246 if (isAccHandle(handle)) { 00247 isEnabledAccNotify = true; 00248 return; 00249 } 00250 if (isMagHandle(handle)) { 00251 isEnabledMagNotify = true; 00252 return; 00253 } 00254 if (isAccGyroMagHandle(handle)) { 00255 isEnabledAccGyroMagNotify = true; 00256 return; 00257 } 00258 } 00259 00260 void disNotify (Gap::Handle_t a_handle) { 00261 Gap::Handle_t handle = a_handle - BLE_HANDLE_EN_DIS_OFFSET; 00262 if (isTempHandle(handle)) { 00263 isEnabledTempNotify = false; 00264 memset(pastenvTemperature,0,TEMP_DATA_LEN); 00265 return; 00266 } 00267 if (isHumHandle(handle)) { 00268 isEnabledHumNotify = false; 00269 memset(pastenvHumidity,0,HUM_DATA_LEN); 00270 return; 00271 } 00272 if (isPresHandle(handle)) { 00273 isEnabledPresNotify = false; 00274 memset(pastenvPressure,0,PRES_DATA_LEN); 00275 return; 00276 } 00277 if (isGyroHandle(handle)) { 00278 isEnabledGyroNotify = false; 00279 return; 00280 } 00281 if (isAccHandle(handle)) { 00282 isEnabledAccNotify = false; 00283 return; 00284 } 00285 if (isMagHandle(handle)) { 00286 isEnabledMagNotify = false; 00287 return; 00288 } 00289 if (isAccGyroMagHandle(handle)) { 00290 isEnabledAccGyroMagNotify = false; 00291 return; 00292 } 00293 } 00294 00295 bool isTempNotificationEn (void) { 00296 return isEnabledTempNotify; 00297 } 00298 00299 bool isHumNotificationEn (void) { 00300 return isEnabledHumNotify; 00301 } 00302 00303 bool isPresNotificationEn (void) { 00304 return isEnabledPresNotify; 00305 } 00306 00307 bool isGyroNotificationEn (void) { 00308 return isEnabledGyroNotify; 00309 } 00310 00311 bool isAccNotificationEn (void) { 00312 return isEnabledAccNotify; 00313 } 00314 00315 bool isMagNotificationEn (void) { 00316 return isEnabledMagNotify; 00317 } 00318 00319 bool isAccGyroMagNotificationEn (void) { 00320 return isEnabledAccGyroMagNotify; 00321 } 00322 00323 bool isTempHandle (Gap::Handle_t handle) { 00324 if (handle == envTemperatureCharacteristic.getValueAttribute().getHandle() - BLE_HANDLE_VALUE_OFFSET) return true; 00325 return false; 00326 } 00327 00328 bool isHumHandle (Gap::Handle_t handle) { 00329 if (handle == envHumidityCharacteristic.getValueAttribute().getHandle() - BLE_HANDLE_VALUE_OFFSET) return true; 00330 return false; 00331 } 00332 00333 bool isPresHandle (Gap::Handle_t handle) { 00334 if (handle == envPressureCharacteristic.getValueAttribute().getHandle() - BLE_HANDLE_VALUE_OFFSET) return true; 00335 return false; 00336 } 00337 00338 bool isMagHandle (Gap::Handle_t handle) { 00339 if (handle == envMagnetometerCharacteristic.getValueAttribute().getHandle() - BLE_HANDLE_VALUE_OFFSET) return true; 00340 return false; 00341 } 00342 bool isAccHandle (Gap::Handle_t handle) { 00343 if (handle == envAccelerometerCharacteristic.getValueAttribute().getHandle() - BLE_HANDLE_VALUE_OFFSET) return true; 00344 return false; 00345 } 00346 bool isGyroHandle (Gap::Handle_t handle) { 00347 if (handle == envGyroCharacteristic.getValueAttribute().getHandle() - BLE_HANDLE_VALUE_OFFSET) return true; 00348 return false; 00349 } 00350 bool isAccGyroMagHandle (Gap::Handle_t handle) { 00351 if (handle == envAccGyroMagCharacteristic.getValueAttribute().getHandle() - BLE_HANDLE_VALUE_OFFSET) return true; 00352 return false; 00353 } 00354 00355 void updateConnectionStatus(ConnectionStatus_t status) { 00356 isEnabledTempNotify = false; 00357 isEnabledHumNotify = false; 00358 isEnabledPresNotify = false; 00359 isEnabledGyroNotify = false; 00360 isEnabledAccNotify = false; 00361 isEnabledMagNotify = false; 00362 isEnabledAccGyroMagNotify = false; 00363 00364 isTempCalibrated = false; 00365 isHumCalibrated = false; 00366 isPresCalibrated = false; 00367 isMagCalibrated = false; 00368 isAccCalibrated = false; 00369 isAGyroCalibrated = false; 00370 00371 memset (pastenvTemperature, 0, TEMP_DATA_LEN); 00372 memset (pastenvHumidity, 0, HUM_DATA_LEN); 00373 memset (pastenvPressure, 0, PRES_DATA_LEN); 00374 isBTLEConnected = status; 00375 } 00376 00377 00378 private: 00379 BLE &ble; 00380 uint8_t envTemperature [TEMP_DATA_LEN]; /* in C */ 00381 uint8_t pastenvTemperature [TEMP_DATA_LEN]; 00382 uint8_t envHumidity [HUM_DATA_LEN]; /* in % */ 00383 uint8_t pastenvHumidity [HUM_DATA_LEN]; 00384 uint8_t envPressure [PRES_DATA_LEN]; /* in mBar */ 00385 uint8_t pastenvPressure [PRES_DATA_LEN]; 00386 uint8_t envMagn [MAG_DATA_LEN]; 00387 uint8_t envGyro [GYRO_DATA_LEN]; 00388 uint8_t envAcce [ACC_DATA_LEN]; 00389 uint8_t envAccGyroMag [ACCGYROMAG_DATA_LEN]; 00390 00391 GattCharacteristic envTemperatureCharacteristic; 00392 GattCharacteristic envHumidityCharacteristic; 00393 GattCharacteristic envPressureCharacteristic; 00394 00395 GattCharacteristic envMagnetometerCharacteristic; 00396 GattCharacteristic envAccelerometerCharacteristic; 00397 GattCharacteristic envGyroCharacteristic; 00398 GattCharacteristic envAccGyroMagCharacteristic; 00399 00400 ConnectionStatus_t isBTLEConnected; 00401 00402 bool isEnabledTempNotify; 00403 bool isEnabledHumNotify; 00404 bool isEnabledPresNotify; 00405 bool isEnabledGyroNotify; 00406 bool isEnabledAccNotify; 00407 bool isEnabledMagNotify; 00408 bool isEnabledAccGyroMagNotify; 00409 00410 bool isTempCalibrated; 00411 bool isHumCalibrated; 00412 bool isPresCalibrated; 00413 bool isMagCalibrated; 00414 bool isAccCalibrated; 00415 bool isAGyroCalibrated; 00416 00417 }; 00418 00419 #endif /* #ifndef __CUSTOM_BLE_SENSORS_SERVICE_H__*/
Generated on Sun Jul 17 2022 23:51:22 by 1.7.2