Motion and Environmental sensor reader application connected via BLE to ST BlueMS iOS/Android application.

Dependencies:   HTS221 LIS3MDL LPS22HB LSM303AGR LSM6DSL

Fork of MOTENV_Mbed by ST Expansion SW Team

This application supports three different sets of ST hardware boards:

  • STEVAL-STLKT01V1 (aka SensorTile)
  • X-NUCLEO-IDB05A1 and X-NUCLEO-IKS01A2 expansion boards
  • B-L475E-IOT01A IoT Discovery board

    and runs over four different target configurations:

  • Nucleo F401RE + X-NUCLEO-IDB05A1 + X-NUCLEO-IKS01A2 (set target NUCLEO_F401RE)
  • DISCO_L475VG_IOT01A (set target DISCO_L475VG_IOT01A)
  • Nucleo L476RG + CRADLE + SENSORTILE (set compile target NUCLEO_L476RG)
  • Nucleo L476RG + CRADLE_EXPANSION_BOARD + SENSORTILE (set compile target NUCLEO_L476RG, remove macro MINI_CRADLE from mbed_app.json)

The first 2 configurations do not require any HW modifications (just use the above indicated targets).

Third configuration (CRADLE ) only requires to remove the two ST-LINK jumpers and JP6 from the Nucleo L476RG board in order to allow flashing the SensorTile through the Nucleo Jtag controller. Once flashed, if the battery is properly plugged and charged, the SensorTile could be mounted in the plastic enclosure being able to run as a small stand alone wearable device. Please note that this configuration do not provide a serial console for printf.

To enable last configuration (CRADLE_EXPANSION_BOARD), follow the steps below:

  • On Nucleo L476RG
    • open the two "ST-LINK" jumpers
    • open the MCU power supply jumper JP6
    • close the solder bridges SB63 and SB62 (to enable the serial console)
  • On SensorTile Arduino Cradle close the solder bridges SB21 and SB10 (to enable the serial console) and move the jumper J2 to the 5V position
  • Plug the Sensor Tile on the Arduino Cradle
  • Plug the Cradle on the Nucleo Arduino connector and connect the debug flat cable between Cradle and Nucleo Jtag connector (the cradle pin1 -identified by a dot- must be connected to the Nucleo pin1 (dot) of SWD CN4 jtag connector)
  • Plug the Nucleo USB cable on PC (a new COM port should appear); no need to plug the micro USB cable on the cradle.
  • Open a PC terminal to see the messages
  • Compile from mbed CLI or on-line compiler removing macro MINI_CRADLE from mbed_app.json file and selecting NUCLEO_ L476RG target
  • Flash the board with the binary

For all configurations on an Android or iOS device download and open the ST BlueMS application and connect to "MotEnvMbedOS" BLE device to see the sensor data.

For all configurations is also possible to add a 9 axis MotionFX sensor fusion library, which is part of the X-CUBE-MEMS package at this link.
The library comes in three flavours, choose your preferred according to the toolchain used (IAR, Keil or GC, Keil version should be used for the online compiler) and copy it in the Middlewares\ST\STM32_MotionFX_Library\Lib directory changing the file extension according to the toolchain used (.a for GCC, .ar for Keil).
In the file mbed_app.json add the macro definition "USE_SENSOR_FUSION_LIB" to the chosen target.
If compiling from CLI and using GCC_ARM toolchain option, in the file \mbed-os\tools\toolchains\gcc.py change the compiling option from

        if target.core == "Cortex-M4F":
            self.cpu.append("-mfpu=fpv4-sp-d16")
            self.cpu.append("-mfloat-abi=softfp")

to

        if target.core == "Cortex-M4F":
            self.cpu.append("-mfpu=fpv4-sp-d16")
            self.cpu.append("-mfloat-abi=hard")

and compile.

Committer:
mapellil
Date:
Thu Dec 17 15:58:35 2015 +0000
Revision:
7:34014895dda8
Parent:
6:c1b8fb74072e
Child:
8:b042fe719f51
Updated BLE stack/API (now BigEndian UUID), set max tx power

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mapellil 6:c1b8fb74072e 1 /**
mapellil 6:c1b8fb74072e 2 ******************************************************************************
mapellil 6:c1b8fb74072e 3 * @file CustomSensorService.h
mapellil 6:c1b8fb74072e 4 * @author AST / EST
mapellil 6:c1b8fb74072e 5 * @version V0.0.1
mapellil 6:c1b8fb74072e 6 * @date 16-Dec-2015
mapellil 6:c1b8fb74072e 7 * @brief Ble sensor service of Bluemicrosystem1 application
mapellil 6:c1b8fb74072e 8 ******************************************************************************
mapellil 6:c1b8fb74072e 9 * @attention
mapellil 0:e93a11b4e044 10 *
mapellil 6:c1b8fb74072e 11 * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
mapellil 0:e93a11b4e044 12 *
mapellil 6:c1b8fb74072e 13 * Redistribution and use in source and binary forms, with or without modification,
mapellil 6:c1b8fb74072e 14 * are permitted provided that the following conditions are met:
mapellil 6:c1b8fb74072e 15 * 1. Redistributions of source code must retain the above copyright notice,
mapellil 6:c1b8fb74072e 16 * this list of conditions and the following disclaimer.
mapellil 6:c1b8fb74072e 17 * 2. Redistributions in binary form must reproduce the above copyright notice,
mapellil 6:c1b8fb74072e 18 * this list of conditions and the following disclaimer in the documentation
mapellil 6:c1b8fb74072e 19 * and/or other materials provided with the distribution.
mapellil 6:c1b8fb74072e 20 * 3. Neither the name of STMicroelectronics nor the names of its contributors
mapellil 6:c1b8fb74072e 21 * may be used to endorse or promote products derived from this software
mapellil 6:c1b8fb74072e 22 * without specific prior written permission.
mapellil 0:e93a11b4e044 23 *
mapellil 6:c1b8fb74072e 24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
mapellil 6:c1b8fb74072e 25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
mapellil 6:c1b8fb74072e 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
mapellil 6:c1b8fb74072e 27 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
mapellil 6:c1b8fb74072e 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
mapellil 6:c1b8fb74072e 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
mapellil 6:c1b8fb74072e 30 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
mapellil 6:c1b8fb74072e 31 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
mapellil 6:c1b8fb74072e 32 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
mapellil 6:c1b8fb74072e 33 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
mapellil 6:c1b8fb74072e 34 *
mapellil 6:c1b8fb74072e 35 ******************************************************************************
mapellil 0:e93a11b4e044 36 */
mapellil 0:e93a11b4e044 37
mapellil 0:e93a11b4e044 38 #ifndef __CUSTOM_BLE_SENSORS_SERVICE_H__
mapellil 0:e93a11b4e044 39 #define __CUSTOM_BLE_SENSORS_SERVICE_H__
mapellil 0:e93a11b4e044 40
mapellil 0:e93a11b4e044 41 #include "BLE.h"
mapellil 0:e93a11b4e044 42
mapellil 7:34014895dda8 43 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,
mapellil 7:34014895dda8 44 const LongUUIDBytes_t SENS_TEMP_CHAR_UUID_128 = { 0x00,0x04,0x00,0x00,0x00,0x01,0x11,0xe1,0xac,0x36,0x00,0x02,0xa5,0xd5,0xc5,0x1b };
mapellil 7:34014895dda8 45 const LongUUIDBytes_t SENS_HUMI_CHAR_UUID_128 = { 0x00,0x08,0x00,0x00,0x00,0x01,0x11,0xe1,0xac,0x36,0x00,0x02,0xa5,0xd5,0xc5,0x1b };
mapellil 7:34014895dda8 46 const LongUUIDBytes_t SENS_PRES_CHAR_UUID_128 = { 0x00,0x10,0x00,0x00,0x00,0x01,0x11,0xe1,0xac,0x36,0x00,0x02,0xa5,0xd5,0xc5,0x1b };
mapellil 7:34014895dda8 47 const LongUUIDBytes_t SENS_MAGN_CHAR_UUID_128 = { 0x00,0x20,0x00,0x00,0x00,0x01,0x11,0xe1,0xac,0x36,0x00,0x02,0xa5,0xd5,0xc5,0x1b };
mapellil 7:34014895dda8 48 const LongUUIDBytes_t SENS_GYRO_CHAR_UUID_128 = { 0x00,0x40,0x00,0x00,0x00,0x01,0x11,0xe1,0xac,0x36,0x00,0x02,0xa5,0xd5,0xc5,0x1b };
mapellil 7:34014895dda8 49 const LongUUIDBytes_t SENS_ACCE_CHAR_UUID_128 = { 0x00,0x80,0x00,0x00,0x00,0x01,0x11,0xe1,0xac,0x36,0x00,0x02,0xa5,0xd5,0xc5,0x1b };
mapellil 7:34014895dda8 50 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 };
mapellil 0:e93a11b4e044 51
mapellil 0:e93a11b4e044 52 #define TEMP_DATA_LEN 2+2
mapellil 0:e93a11b4e044 53 #define HUM_DATA_LEN 2+2
mapellil 0:e93a11b4e044 54 #define PRES_DATA_LEN 2+4
mapellil 0:e93a11b4e044 55 #define ACC_DATA_LEN 6+2
mapellil 0:e93a11b4e044 56 #define MAG_DATA_LEN 6+2
mapellil 0:e93a11b4e044 57 #define GYRO_DATA_LEN 6+2
mapellil 0:e93a11b4e044 58 #define ACCGYROMAG_DATA_LEN 2+3*3*2
mapellil 0:e93a11b4e044 59
mapellil 0:e93a11b4e044 60
mapellil 0:e93a11b4e044 61 /* Custom Sensors Service */
mapellil 0:e93a11b4e044 62 class CustomSensorService {
mapellil 0:e93a11b4e044 63 public:
mapellil 6:c1b8fb74072e 64 CustomSensorService(BLE &_ble, CustomBleErrManagement * ErrMgr=NULL ) :
mapellil 0:e93a11b4e044 65 ble(_ble),
mapellil 0:e93a11b4e044 66 envTemperatureCharacteristic(SENS_TEMP_CHAR_UUID_128,envTemperature, TEMP_DATA_LEN, TEMP_DATA_LEN,
mapellil 0:e93a11b4e044 67 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY),
mapellil 0:e93a11b4e044 68 envHumidityCharacteristic(SENS_HUMI_CHAR_UUID_128, envHumidity, HUM_DATA_LEN, HUM_DATA_LEN,
mapellil 0:e93a11b4e044 69 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY),
mapellil 0:e93a11b4e044 70 envPressureCharacteristic(SENS_PRES_CHAR_UUID_128, envPressure, PRES_DATA_LEN, PRES_DATA_LEN,
mapellil 0:e93a11b4e044 71 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY),
mapellil 0:e93a11b4e044 72 envMagnetometerCharacteristic(SENS_MAGN_CHAR_UUID_128,envMagn, MAG_DATA_LEN, MAG_DATA_LEN,
mapellil 0:e93a11b4e044 73 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY),
mapellil 0:e93a11b4e044 74 envAccelerometerCharacteristic(SENS_ACCE_CHAR_UUID_128,envAcce, ACC_DATA_LEN, ACC_DATA_LEN,
mapellil 0:e93a11b4e044 75 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY),
mapellil 0:e93a11b4e044 76 envGyroCharacteristic(SENS_GYRO_CHAR_UUID_128,envGyro, GYRO_DATA_LEN, GYRO_DATA_LEN,
mapellil 0:e93a11b4e044 77 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY),
mapellil 0:e93a11b4e044 78 envAccGyroMagCharacteristic(SENS_ACC_GYRO_MAG_CHAR_UUID_128,envAccGyroMag, ACCGYROMAG_DATA_LEN, ACCGYROMAG_DATA_LEN,
mapellil 0:e93a11b4e044 79 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY)
mapellil 0:e93a11b4e044 80 {
mapellil 0:e93a11b4e044 81
mapellil 0:e93a11b4e044 82 static bool serviceAdded = false; /* We should only ever need to add the env service once. */
mapellil 0:e93a11b4e044 83 if (serviceAdded) {
mapellil 0:e93a11b4e044 84 return;
mapellil 0:e93a11b4e044 85 }
mapellil 6:c1b8fb74072e 86 bleErrMgr = ErrMgr;
mapellil 0:e93a11b4e044 87 GattCharacteristic *charTable[] = {&envTemperatureCharacteristic, &envHumidityCharacteristic, &envPressureCharacteristic, &envMagnetometerCharacteristic,
mapellil 0:e93a11b4e044 88 &envAccelerometerCharacteristic, &envGyroCharacteristic, &envAccGyroMagCharacteristic};
mapellil 0:e93a11b4e044 89
mapellil 0:e93a11b4e044 90 GattService envService(SENS_SERVICE_UUID_128, charTable, sizeof(charTable) / sizeof(GattCharacteristic *));
mapellil 0:e93a11b4e044 91
mapellil 0:e93a11b4e044 92 ble.gattServer().addService(envService);
mapellil 0:e93a11b4e044 93
mapellil 0:e93a11b4e044 94 isEnabledTempNotify = false;
mapellil 0:e93a11b4e044 95 isEnabledHumNotify = false;
mapellil 0:e93a11b4e044 96 isEnabledPresNotify = false;
mapellil 0:e93a11b4e044 97 isEnabledGyroNotify = false;
mapellil 0:e93a11b4e044 98 isEnabledAccNotify = false;
mapellil 0:e93a11b4e044 99 isEnabledMagNotify = false;
mapellil 0:e93a11b4e044 100 isEnabledAccGyroMagNotify = false;
mapellil 0:e93a11b4e044 101
mapellil 0:e93a11b4e044 102 isTempCalibrated = false;
mapellil 0:e93a11b4e044 103 isHumCalibrated = false;
mapellil 0:e93a11b4e044 104 isPresCalibrated = false;
mapellil 0:e93a11b4e044 105 isMagCalibrated = false;
mapellil 0:e93a11b4e044 106 isAccCalibrated = false;
mapellil 0:e93a11b4e044 107 isAGyroCalibrated = false;
mapellil 0:e93a11b4e044 108
mapellil 0:e93a11b4e044 109 memset (pastenvTemperature, 0, TEMP_DATA_LEN);
mapellil 0:e93a11b4e044 110 memset (pastenvHumidity, 0, HUM_DATA_LEN);
mapellil 0:e93a11b4e044 111 memset (pastenvPressure, 0, PRES_DATA_LEN);
mapellil 0:e93a11b4e044 112
mapellil 0:e93a11b4e044 113 isBTLEConnected = DISCONNECTED;
mapellil 0:e93a11b4e044 114 serviceAdded = true;
mapellil 0:e93a11b4e044 115 }
mapellil 0:e93a11b4e044 116
mapellil 0:e93a11b4e044 117 void sendEnvTemperature (int16_t Temp, uint16_t TimeStamp) {
mapellil 6:c1b8fb74072e 118 if (bleErrMgr != NULL) {
mapellil 6:c1b8fb74072e 119 if (!bleErrMgr->isBleTxChannelOk()){
mapellil 6:c1b8fb74072e 120 bleErrMgr->signalBleTxOk(); // skip tx because of previous error
mapellil 6:c1b8fb74072e 121 return;
mapellil 6:c1b8fb74072e 122 }
mapellil 6:c1b8fb74072e 123 }
mapellil 6:c1b8fb74072e 124 STORE_LE_16(envTemperature,TimeStamp);
mapellil 6:c1b8fb74072e 125 STORE_LE_16(envTemperature+2,Temp);
mapellil 6:c1b8fb74072e 126 PRINTF("sendEnvTemperature!! handle: %d\n\r", envTemperatureCharacteristic.getValueAttribute().getHandle());
mapellil 6:c1b8fb74072e 127 memcpy (pastenvTemperature, envTemperature, TEMP_DATA_LEN);
mapellil 6:c1b8fb74072e 128 uint32_t err = ble.gattServer().write(envTemperatureCharacteristic.getValueAttribute().getHandle(), envTemperature, TEMP_DATA_LEN, 0);
mapellil 6:c1b8fb74072e 129 if (!err) {
mapellil 6:c1b8fb74072e 130 bleErrMgr->signalBleTxOk();
mapellil 6:c1b8fb74072e 131 }else{
mapellil 6:c1b8fb74072e 132 bleErrMgr->signalBleTxErr(err);
mapellil 6:c1b8fb74072e 133 }
mapellil 0:e93a11b4e044 134 }
mapellil 0:e93a11b4e044 135
mapellil 0:e93a11b4e044 136 /**
mapellil 0:e93a11b4e044 137 * Update the temperature with a new value. Valid values range from
mapellil 0:e93a11b4e044 138 * 0..100. Anything outside this range will be ignored.
mapellil 0:e93a11b4e044 139 * @param newLevel New level. */
mapellil 0:e93a11b4e044 140 void updateEnvTemperature (int16_t Temp, uint16_t TimeStamp) {
mapellil 6:c1b8fb74072e 141 if (isTempNotificationEn()){
mapellil 0:e93a11b4e044 142 if (memcmp (&pastenvTemperature[2], &Temp, 2) != 0) {
mapellil 0:e93a11b4e044 143 sendEnvTemperature (Temp, TimeStamp);
mapellil 0:e93a11b4e044 144 }
mapellil 0:e93a11b4e044 145 }
mapellil 6:c1b8fb74072e 146 }
mapellil 0:e93a11b4e044 147
mapellil 6:c1b8fb74072e 148 void sendEnvHumidity(uint16_t Hum, uint16_t TimeStamp) {
mapellil 6:c1b8fb74072e 149 if (bleErrMgr != NULL) {
mapellil 6:c1b8fb74072e 150 if (!bleErrMgr->isBleTxChannelOk()){
mapellil 6:c1b8fb74072e 151 bleErrMgr->signalBleTxOk(); // skip tx because of previous error
mapellil 6:c1b8fb74072e 152 return;
mapellil 6:c1b8fb74072e 153 }
mapellil 6:c1b8fb74072e 154 }
mapellil 6:c1b8fb74072e 155 STORE_LE_16(envHumidity,TimeStamp);
mapellil 6:c1b8fb74072e 156 STORE_LE_16(envHumidity+2,Hum);
mapellil 6:c1b8fb74072e 157 memcpy (pastenvHumidity, envHumidity, HUM_DATA_LEN);
mapellil 6:c1b8fb74072e 158 uint32_t err = ble.gattServer().write(envHumidityCharacteristic.getValueAttribute().getHandle(), envHumidity, HUM_DATA_LEN, 0);
mapellil 6:c1b8fb74072e 159 if (!err) {
mapellil 6:c1b8fb74072e 160 bleErrMgr->signalBleTxOk();
mapellil 6:c1b8fb74072e 161 }else{
mapellil 6:c1b8fb74072e 162 bleErrMgr->signalBleTxErr(err);
mapellil 6:c1b8fb74072e 163 }
mapellil 6:c1b8fb74072e 164 }
mapellil 0:e93a11b4e044 165
mapellil 0:e93a11b4e044 166 void updateEnvHumidity(uint16_t Hum, uint16_t TimeStamp) {
mapellil 6:c1b8fb74072e 167 if (isHumNotificationEn()){
mapellil 0:e93a11b4e044 168 if (memcmp (&pastenvHumidity[2], &Hum, 2) != 0) {
mapellil 0:e93a11b4e044 169 sendEnvHumidity(Hum, TimeStamp);
mapellil 0:e93a11b4e044 170 }
mapellil 6:c1b8fb74072e 171 }
mapellil 0:e93a11b4e044 172 }
mapellil 0:e93a11b4e044 173
mapellil 0:e93a11b4e044 174 void sendEnvPressure(uint32_t Press, uint16_t TimeStamp) {
mapellil 6:c1b8fb74072e 175 if (bleErrMgr != NULL) {
mapellil 6:c1b8fb74072e 176 if (!bleErrMgr->isBleTxChannelOk()){
mapellil 6:c1b8fb74072e 177 bleErrMgr->signalBleTxOk(); // skip tx because of previous error
mapellil 6:c1b8fb74072e 178 return;
mapellil 6:c1b8fb74072e 179 }
mapellil 6:c1b8fb74072e 180 }
mapellil 6:c1b8fb74072e 181 STORE_LE_16(envPressure,TimeStamp);
mapellil 6:c1b8fb74072e 182 STORE_LE_32(envPressure+2,Press);
mapellil 6:c1b8fb74072e 183 memcpy (pastenvPressure, envPressure, PRES_DATA_LEN);
mapellil 6:c1b8fb74072e 184 uint32_t err=ble.gattServer().write(envPressureCharacteristic.getValueAttribute().getHandle(), envPressure, PRES_DATA_LEN, 0);
mapellil 6:c1b8fb74072e 185 if (!err) {
mapellil 6:c1b8fb74072e 186 bleErrMgr->signalBleTxOk();
mapellil 6:c1b8fb74072e 187 }else{
mapellil 6:c1b8fb74072e 188 bleErrMgr->signalBleTxErr(err);
mapellil 6:c1b8fb74072e 189 }
mapellil 6:c1b8fb74072e 190 }
mapellil 0:e93a11b4e044 191
mapellil 0:e93a11b4e044 192 void updateEnvPressure(uint32_t Press, uint16_t TimeStamp) {
mapellil 6:c1b8fb74072e 193 if (isPresNotificationEn()){
mapellil 0:e93a11b4e044 194 if (memcmp (&pastenvPressure[2], &Press, 2) != 0) {
mapellil 0:e93a11b4e044 195 sendEnvPressure(Press, TimeStamp);
mapellil 6:c1b8fb74072e 196 }
mapellil 6:c1b8fb74072e 197 }
mapellil 0:e93a11b4e044 198 }
mapellil 0:e93a11b4e044 199
mapellil 6:c1b8fb74072e 200 void sendEnvMagnetometer(AxesRaw_TypeDef *Magn, uint16_t TimeStamp, osxMFX_calibFactor magOffset) {
mapellil 6:c1b8fb74072e 201 if (bleErrMgr != NULL) {
mapellil 6:c1b8fb74072e 202 if (!bleErrMgr->isBleTxChannelOk()){
mapellil 6:c1b8fb74072e 203 bleErrMgr->signalBleTxOk(); // skip tx because of previous error
mapellil 6:c1b8fb74072e 204 return;
mapellil 6:c1b8fb74072e 205 }
mapellil 6:c1b8fb74072e 206 }
mapellil 6:c1b8fb74072e 207 STORE_LE_16(envMagn,TimeStamp);
mapellil 6:c1b8fb74072e 208 STORE_LE_16(envMagn+2,(Magn->AXIS_X - magOffset.magOffX));
mapellil 6:c1b8fb74072e 209 STORE_LE_16(envMagn+4,(Magn->AXIS_Y - magOffset.magOffY));
mapellil 6:c1b8fb74072e 210 STORE_LE_16(envMagn+6,(Magn->AXIS_Z - magOffset.magOffZ));
mapellil 6:c1b8fb74072e 211 uint32_t err = ble.gattServer().write(envMagnetometerCharacteristic.getValueAttribute().getHandle(), envMagn, MAG_DATA_LEN, 0);
mapellil 6:c1b8fb74072e 212 if (!err) {
mapellil 6:c1b8fb74072e 213 bleErrMgr->signalBleTxOk();
mapellil 6:c1b8fb74072e 214 }else{
mapellil 6:c1b8fb74072e 215 bleErrMgr->signalBleTxErr(err);
mapellil 6:c1b8fb74072e 216 }
mapellil 0:e93a11b4e044 217 }
mapellil 0:e93a11b4e044 218
mapellil 0:e93a11b4e044 219 void updateEnvMagnetometer(AxesRaw_TypeDef *Magn, uint16_t TimeStamp, osxMFX_calibFactor magOffset) {
mapellil 0:e93a11b4e044 220 if (isMagNotificationEn()) sendEnvMagnetometer(Magn, TimeStamp, magOffset);
mapellil 0:e93a11b4e044 221 }
mapellil 0:e93a11b4e044 222
mapellil 0:e93a11b4e044 223 void sendEnvAccelerometer (AxesRaw_TypeDef *Acc, uint16_t TimeStamp) {
mapellil 6:c1b8fb74072e 224 if (bleErrMgr != NULL) {
mapellil 6:c1b8fb74072e 225 if (!bleErrMgr->isBleTxChannelOk()){
mapellil 6:c1b8fb74072e 226 bleErrMgr->signalBleTxOk(); // skip tx because of previous error
mapellil 6:c1b8fb74072e 227 return;
mapellil 6:c1b8fb74072e 228 }
mapellil 6:c1b8fb74072e 229 }
mapellil 6:c1b8fb74072e 230 STORE_LE_16(envAcce,TimeStamp);
mapellil 6:c1b8fb74072e 231 STORE_LE_16(envAcce+2,Acc->AXIS_X);
mapellil 6:c1b8fb74072e 232 STORE_LE_16(envAcce+4,Acc->AXIS_Y);
mapellil 6:c1b8fb74072e 233 STORE_LE_16(envAcce+6,Acc->AXIS_Z);
mapellil 6:c1b8fb74072e 234 uint32_t err = ble.gattServer().write(envAccelerometerCharacteristic.getValueAttribute().getHandle(), envAcce, ACC_DATA_LEN, 0);
mapellil 6:c1b8fb74072e 235 if (!err) {
mapellil 6:c1b8fb74072e 236 bleErrMgr->signalBleTxOk();
mapellil 6:c1b8fb74072e 237 }else{
mapellil 6:c1b8fb74072e 238 bleErrMgr->signalBleTxErr(err);
mapellil 6:c1b8fb74072e 239 }
mapellil 6:c1b8fb74072e 240
mapellil 0:e93a11b4e044 241 }
mapellil 0:e93a11b4e044 242
mapellil 0:e93a11b4e044 243 void updateEnvAccelerometer (AxesRaw_TypeDef *Acc, uint16_t TimeStamp) {
mapellil 0:e93a11b4e044 244 if (isAccNotificationEn()) sendEnvAccelerometer (Acc, TimeStamp);
mapellil 0:e93a11b4e044 245 }
mapellil 0:e93a11b4e044 246
mapellil 0:e93a11b4e044 247 void sendEnvGyroscope (AxesRaw_TypeDef *Gyro, uint16_t TimeStamp) {
mapellil 6:c1b8fb74072e 248 if (bleErrMgr != NULL) {
mapellil 6:c1b8fb74072e 249 if (!bleErrMgr->isBleTxChannelOk()){
mapellil 6:c1b8fb74072e 250 bleErrMgr->signalBleTxOk(); // skip tx because of previous error
mapellil 6:c1b8fb74072e 251 return;
mapellil 6:c1b8fb74072e 252 }
mapellil 6:c1b8fb74072e 253 }
mapellil 6:c1b8fb74072e 254 STORE_LE_16(envGyro,TimeStamp);
mapellil 6:c1b8fb74072e 255 STORE_LE_16(envGyro+2,Gyro->AXIS_X);
mapellil 6:c1b8fb74072e 256 STORE_LE_16(envGyro+4,Gyro->AXIS_Y);
mapellil 6:c1b8fb74072e 257 STORE_LE_16(envGyro+6,Gyro->AXIS_Z);
mapellil 6:c1b8fb74072e 258 uint32_t err = ble.gattServer().write(envGyroCharacteristic.getValueAttribute().getHandle(), envGyro, GYRO_DATA_LEN, 0);
mapellil 6:c1b8fb74072e 259 if (!err) {
mapellil 6:c1b8fb74072e 260 bleErrMgr->signalBleTxOk();
mapellil 6:c1b8fb74072e 261 }else{
mapellil 6:c1b8fb74072e 262 bleErrMgr->signalBleTxErr(err);
mapellil 6:c1b8fb74072e 263 }
mapellil 0:e93a11b4e044 264 }
mapellil 0:e93a11b4e044 265
mapellil 0:e93a11b4e044 266 void updateEnvGyroscope (AxesRaw_TypeDef *Gyro, uint16_t TimeStamp) {
mapellil 0:e93a11b4e044 267 if (isGyroNotificationEn()) sendEnvGyroscope (Gyro, TimeStamp);
mapellil 0:e93a11b4e044 268 }
mapellil 0:e93a11b4e044 269
mapellil 0:e93a11b4e044 270 void sendEnvAccGyroMag (AxesRaw_TypeDef *Acc, AxesRaw_TypeDef *Gyro, AxesRaw_TypeDef *Magn, uint16_t TimeStamp, osxMFX_calibFactor magOffset) {
mapellil 6:c1b8fb74072e 271 if (bleErrMgr != NULL) {
mapellil 6:c1b8fb74072e 272 if (!bleErrMgr->isBleTxChannelOk()){
mapellil 6:c1b8fb74072e 273 bleErrMgr->signalBleTxOk(); // skip tx because of previous error
mapellil 6:c1b8fb74072e 274 return;
mapellil 6:c1b8fb74072e 275 }
mapellil 6:c1b8fb74072e 276 }
mapellil 6:c1b8fb74072e 277 STORE_LE_16(envAccGyroMag,TimeStamp);
mapellil 6:c1b8fb74072e 278 STORE_LE_16(envAccGyroMag+2,Acc->AXIS_X);
mapellil 6:c1b8fb74072e 279 STORE_LE_16(envAccGyroMag+4,Acc->AXIS_Y);
mapellil 6:c1b8fb74072e 280 STORE_LE_16(envAccGyroMag+6,Acc->AXIS_Z);
mapellil 0:e93a11b4e044 281
mapellil 6:c1b8fb74072e 282 STORE_LE_16(envAccGyroMag+8,Gyro->AXIS_X);
mapellil 6:c1b8fb74072e 283 STORE_LE_16(envAccGyroMag+10,Gyro->AXIS_Y);
mapellil 6:c1b8fb74072e 284 STORE_LE_16(envAccGyroMag+12,Gyro->AXIS_Z);
mapellil 0:e93a11b4e044 285
mapellil 6:c1b8fb74072e 286 STORE_LE_16(envAccGyroMag+14,(Magn->AXIS_X - magOffset.magOffX));
mapellil 6:c1b8fb74072e 287 STORE_LE_16(envAccGyroMag+16,(Magn->AXIS_Y - magOffset.magOffY));
mapellil 6:c1b8fb74072e 288 STORE_LE_16(envAccGyroMag+18,(Magn->AXIS_Z - magOffset.magOffZ));
mapellil 6:c1b8fb74072e 289 uint32_t err = ble.gattServer().write(envAccGyroMagCharacteristic.getValueAttribute().getHandle(), envAccGyroMag, ACCGYROMAG_DATA_LEN, 0);
mapellil 6:c1b8fb74072e 290 if (!err) {
mapellil 6:c1b8fb74072e 291 bleErrMgr->signalBleTxOk();
mapellil 6:c1b8fb74072e 292 }else{
mapellil 6:c1b8fb74072e 293 bleErrMgr->signalBleTxErr(err);
mapellil 6:c1b8fb74072e 294 }
mapellil 0:e93a11b4e044 295 }
mapellil 0:e93a11b4e044 296
mapellil 0:e93a11b4e044 297 void updateEnvAccGyroMag (AxesRaw_TypeDef *Acc, AxesRaw_TypeDef *Gyro, AxesRaw_TypeDef *Magn, uint16_t TimeStamp, osxMFX_calibFactor magOffset) {
mapellil 0:e93a11b4e044 298 if (isAccGyroMagNotificationEn())sendEnvAccGyroMag (Acc, Gyro, Magn, TimeStamp, magOffset);
mapellil 0:e93a11b4e044 299 }
mapellil 0:e93a11b4e044 300
mapellil 0:e93a11b4e044 301 void enNotify (Gap::Handle_t handle) {
mapellil 0:e93a11b4e044 302 if (isTempHandle(handle)) { isEnabledTempNotify = true; memset(pastenvTemperature,0,TEMP_DATA_LEN); return; }
mapellil 0:e93a11b4e044 303 if (isHumHandle(handle)) { isEnabledHumNotify = true; memset(pastenvHumidity,0,HUM_DATA_LEN); return; }
mapellil 0:e93a11b4e044 304 if (isPresHandle(handle)) { isEnabledPresNotify = true; memset(pastenvPressure,0,PRES_DATA_LEN); return; }
mapellil 0:e93a11b4e044 305 if (isGyroHandle(handle)) { isEnabledGyroNotify = true; return; }
mapellil 0:e93a11b4e044 306 if (isAccHandle(handle)) { isEnabledAccNotify = true; return; }
mapellil 0:e93a11b4e044 307 if (isMagHandle(handle)) { isEnabledMagNotify = true; return; }
mapellil 0:e93a11b4e044 308 if (isAccGyroMagHandle(handle)) { isEnabledAccGyroMagNotify = true; return; }
mapellil 0:e93a11b4e044 309 }
mapellil 0:e93a11b4e044 310
mapellil 0:e93a11b4e044 311 void disNotify (Gap::Handle_t handle) {
mapellil 0:e93a11b4e044 312 if (isTempHandle(handle)) { isEnabledTempNotify = false; memset(pastenvTemperature,0,TEMP_DATA_LEN); return; }
mapellil 0:e93a11b4e044 313 if (isHumHandle(handle)) { isEnabledHumNotify = false; memset(pastenvHumidity,0,HUM_DATA_LEN); return; }
mapellil 0:e93a11b4e044 314 if (isPresHandle(handle)) { isEnabledPresNotify = false; memset(pastenvPressure,0,PRES_DATA_LEN); return; }
mapellil 0:e93a11b4e044 315 if (isGyroHandle(handle)) { isEnabledGyroNotify = false; return; }
mapellil 0:e93a11b4e044 316 if (isAccHandle(handle)) { isEnabledAccNotify = false; return; }
mapellil 0:e93a11b4e044 317 if (isMagHandle(handle)) { isEnabledMagNotify = false; return; }
mapellil 0:e93a11b4e044 318 if (isAccGyroMagHandle(handle)) { isEnabledAccGyroMagNotify = false; return; }
mapellil 0:e93a11b4e044 319 }
mapellil 0:e93a11b4e044 320
mapellil 0:e93a11b4e044 321 bool isTempNotificationEn (void) {
mapellil 0:e93a11b4e044 322 return isEnabledTempNotify;
mapellil 0:e93a11b4e044 323 }
mapellil 0:e93a11b4e044 324
mapellil 0:e93a11b4e044 325 bool isHumNotificationEn (void) {
mapellil 0:e93a11b4e044 326 return isEnabledHumNotify;
mapellil 0:e93a11b4e044 327 }
mapellil 0:e93a11b4e044 328
mapellil 0:e93a11b4e044 329 bool isPresNotificationEn (void) {
mapellil 0:e93a11b4e044 330 return isEnabledPresNotify;
mapellil 0:e93a11b4e044 331 }
mapellil 0:e93a11b4e044 332
mapellil 0:e93a11b4e044 333 bool isGyroNotificationEn (void) {
mapellil 0:e93a11b4e044 334 return isEnabledGyroNotify;
mapellil 0:e93a11b4e044 335 }
mapellil 0:e93a11b4e044 336
mapellil 0:e93a11b4e044 337 bool isAccNotificationEn (void) {
mapellil 0:e93a11b4e044 338 return isEnabledAccNotify;
mapellil 0:e93a11b4e044 339 }
mapellil 0:e93a11b4e044 340
mapellil 0:e93a11b4e044 341 bool isMagNotificationEn (void) {
mapellil 0:e93a11b4e044 342 return isEnabledMagNotify;
mapellil 0:e93a11b4e044 343 }
mapellil 0:e93a11b4e044 344
mapellil 0:e93a11b4e044 345 bool isAccGyroMagNotificationEn (void) {
mapellil 0:e93a11b4e044 346 return isEnabledAccGyroMagNotify;
mapellil 0:e93a11b4e044 347 }
mapellil 0:e93a11b4e044 348
mapellil 0:e93a11b4e044 349 bool isTempHandle (Gap::Handle_t handle) {
mapellil 0:e93a11b4e044 350 if (handle == envTemperatureCharacteristic.getValueAttribute().getHandle()) return true;
mapellil 0:e93a11b4e044 351 return false;
mapellil 0:e93a11b4e044 352 }
mapellil 0:e93a11b4e044 353
mapellil 0:e93a11b4e044 354 bool isHumHandle (Gap::Handle_t handle) {
mapellil 0:e93a11b4e044 355 if (handle == envHumidityCharacteristic.getValueAttribute().getHandle()) return true;
mapellil 0:e93a11b4e044 356 return false;
mapellil 0:e93a11b4e044 357 }
mapellil 0:e93a11b4e044 358
mapellil 0:e93a11b4e044 359 bool isPresHandle (Gap::Handle_t handle) {
mapellil 0:e93a11b4e044 360 if (handle == envPressureCharacteristic.getValueAttribute().getHandle()) return true;
mapellil 0:e93a11b4e044 361 return false;
mapellil 0:e93a11b4e044 362 }
mapellil 0:e93a11b4e044 363
mapellil 0:e93a11b4e044 364 bool isMagHandle (Gap::Handle_t handle) {
mapellil 0:e93a11b4e044 365 if (handle == envMagnetometerCharacteristic.getValueAttribute().getHandle()) return true;
mapellil 0:e93a11b4e044 366 return false;
mapellil 0:e93a11b4e044 367 }
mapellil 0:e93a11b4e044 368 bool isAccHandle (Gap::Handle_t handle) {
mapellil 0:e93a11b4e044 369 if (handle == envAccelerometerCharacteristic.getValueAttribute().getHandle()) return true;
mapellil 0:e93a11b4e044 370 return false;
mapellil 0:e93a11b4e044 371 }
mapellil 0:e93a11b4e044 372 bool isGyroHandle (Gap::Handle_t handle) {
mapellil 0:e93a11b4e044 373 if (handle == envGyroCharacteristic.getValueAttribute().getHandle()) return true;
mapellil 0:e93a11b4e044 374 return false;
mapellil 0:e93a11b4e044 375 }
mapellil 0:e93a11b4e044 376 bool isAccGyroMagHandle (Gap::Handle_t handle) {
mapellil 0:e93a11b4e044 377 if (handle == envAccGyroMagCharacteristic.getValueAttribute().getHandle()) return true;
mapellil 0:e93a11b4e044 378 return false;
mapellil 0:e93a11b4e044 379 }
mapellil 0:e93a11b4e044 380
mapellil 0:e93a11b4e044 381 void updateConnectionStatus(ConnectionStatus_t status) {
mapellil 0:e93a11b4e044 382 isEnabledTempNotify = false;
mapellil 0:e93a11b4e044 383 isEnabledHumNotify = false;
mapellil 0:e93a11b4e044 384 isEnabledPresNotify = false;
mapellil 0:e93a11b4e044 385 isEnabledGyroNotify = false;
mapellil 0:e93a11b4e044 386 isEnabledAccNotify = false;
mapellil 0:e93a11b4e044 387 isEnabledMagNotify = false;
mapellil 0:e93a11b4e044 388 isEnabledAccGyroMagNotify = false;
mapellil 0:e93a11b4e044 389
mapellil 0:e93a11b4e044 390 isTempCalibrated = false;
mapellil 0:e93a11b4e044 391 isHumCalibrated = false;
mapellil 0:e93a11b4e044 392 isPresCalibrated = false;
mapellil 0:e93a11b4e044 393 isMagCalibrated = false;
mapellil 0:e93a11b4e044 394 isAccCalibrated = false;
mapellil 0:e93a11b4e044 395 isAGyroCalibrated = false;
mapellil 0:e93a11b4e044 396
mapellil 0:e93a11b4e044 397 memset (pastenvTemperature, 0, TEMP_DATA_LEN);
mapellil 0:e93a11b4e044 398 memset (pastenvHumidity, 0, HUM_DATA_LEN);
mapellil 0:e93a11b4e044 399 memset (pastenvPressure, 0, PRES_DATA_LEN);
mapellil 0:e93a11b4e044 400 isBTLEConnected = status;
mapellil 0:e93a11b4e044 401 }
mapellil 0:e93a11b4e044 402
mapellil 0:e93a11b4e044 403
mapellil 0:e93a11b4e044 404 private:
mapellil 6:c1b8fb74072e 405 BLE &ble;
mapellil 6:c1b8fb74072e 406 CustomBleErrManagement *bleErrMgr;
mapellil 0:e93a11b4e044 407 uint8_t envTemperature [TEMP_DATA_LEN]; /* in C */
mapellil 0:e93a11b4e044 408 uint8_t pastenvTemperature [TEMP_DATA_LEN];
mapellil 0:e93a11b4e044 409 uint8_t envHumidity [HUM_DATA_LEN]; /* in % */
mapellil 0:e93a11b4e044 410 uint8_t pastenvHumidity [HUM_DATA_LEN];
mapellil 0:e93a11b4e044 411 uint8_t envPressure [PRES_DATA_LEN]; /* in mBar */
mapellil 0:e93a11b4e044 412 uint8_t pastenvPressure [PRES_DATA_LEN];
mapellil 0:e93a11b4e044 413 uint8_t envMagn [MAG_DATA_LEN];
mapellil 0:e93a11b4e044 414 uint8_t envGyro [GYRO_DATA_LEN];
mapellil 0:e93a11b4e044 415 uint8_t envAcce [ACC_DATA_LEN];
mapellil 0:e93a11b4e044 416 uint8_t envAccGyroMag [ACCGYROMAG_DATA_LEN];
mapellil 0:e93a11b4e044 417
mapellil 0:e93a11b4e044 418 GattCharacteristic envTemperatureCharacteristic;
mapellil 0:e93a11b4e044 419 GattCharacteristic envHumidityCharacteristic;
mapellil 0:e93a11b4e044 420 GattCharacteristic envPressureCharacteristic;
mapellil 0:e93a11b4e044 421
mapellil 0:e93a11b4e044 422 GattCharacteristic envMagnetometerCharacteristic;
mapellil 0:e93a11b4e044 423 GattCharacteristic envAccelerometerCharacteristic;
mapellil 0:e93a11b4e044 424 GattCharacteristic envGyroCharacteristic;
mapellil 0:e93a11b4e044 425 GattCharacteristic envAccGyroMagCharacteristic;
mapellil 0:e93a11b4e044 426
mapellil 0:e93a11b4e044 427 ConnectionStatus_t isBTLEConnected;
mapellil 0:e93a11b4e044 428
mapellil 0:e93a11b4e044 429 bool isEnabledTempNotify;
mapellil 0:e93a11b4e044 430 bool isEnabledHumNotify;
mapellil 0:e93a11b4e044 431 bool isEnabledPresNotify;
mapellil 0:e93a11b4e044 432 bool isEnabledGyroNotify;
mapellil 0:e93a11b4e044 433 bool isEnabledAccNotify;
mapellil 0:e93a11b4e044 434 bool isEnabledMagNotify;
mapellil 0:e93a11b4e044 435 bool isEnabledAccGyroMagNotify;
mapellil 0:e93a11b4e044 436
mapellil 0:e93a11b4e044 437 bool isTempCalibrated;
mapellil 0:e93a11b4e044 438 bool isHumCalibrated;
mapellil 0:e93a11b4e044 439 bool isPresCalibrated;
mapellil 0:e93a11b4e044 440 bool isMagCalibrated;
mapellil 0:e93a11b4e044 441 bool isAccCalibrated;
mapellil 0:e93a11b4e044 442 bool isAGyroCalibrated;
mapellil 0:e93a11b4e044 443
mapellil 0:e93a11b4e044 444 };
mapellil 0:e93a11b4e044 445
mapellil 0:e93a11b4e044 446 #endif /* #ifndef __CUSTOM_BLE_SENSORS_SERVICE_H__*/