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 13:53:13 2015 +0000
Revision:
6:c1b8fb74072e
Parent:
4:007539036889
Child:
7:34014895dda8
I2C@400KHz, BLE app congestion management, license disclaimer

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 0:e93a11b4e044 43 const LongUUIDBytes_t SENS_SERVICE_UUID_128 = { 0x1b,0xc5,0xa5,0xd5,0x02,0x00,0xb4,0x9a,0xe1,0x11,0x01,0x00,0x00,0x00,0x00,0x00}; // temp, pressure, humidity,
mapellil 0:e93a11b4e044 44
mapellil 0:e93a11b4e044 45 const LongUUIDBytes_t SENS_TEMP_CHAR_UUID_128 = { 0x1b,0xc5,0xa5,0xd5,0x02,0x00,0x36,0xac,0xe1,0x11,0x01,0x00,0x00,0x00,0x04,0x00 };
mapellil 0:e93a11b4e044 46 const LongUUIDBytes_t SENS_HUMI_CHAR_UUID_128 = { 0x1b,0xc5,0xa5,0xd5,0x02,0x00,0x36,0xac,0xe1,0x11,0x01,0x00,0x00,0x00,0x08,0x00};
mapellil 0:e93a11b4e044 47 const LongUUIDBytes_t SENS_PRES_CHAR_UUID_128 = { 0x1b,0xc5,0xa5,0xd5,0x02,0x00,0x36,0xac,0xe1,0x11,0x01,0x00,0x00,0x00,0x10,0x00};
mapellil 0:e93a11b4e044 48 const LongUUIDBytes_t SENS_MAGN_CHAR_UUID_128 = { 0x1b,0xc5,0xa5,0xd5,0x02,0x00,0x36,0xac,0xe1,0x11,0x01,0x00,0x00,0x00,0x20,0x00};
mapellil 0:e93a11b4e044 49 const LongUUIDBytes_t SENS_GYRO_CHAR_UUID_128 = { 0x1b,0xc5,0xa5,0xd5,0x02,0x00,0x36,0xac,0xe1,0x11,0x01,0x00,0x00,0x00,0x40,0x00};
mapellil 0:e93a11b4e044 50 const LongUUIDBytes_t SENS_ACCE_CHAR_UUID_128 = { 0x1b,0xc5,0xa5,0xd5,0x02,0x00,0x36,0xac,0xe1,0x11,0x01,0x00,0x00,0x00,0x80,0x00};
mapellil 0:e93a11b4e044 51 const LongUUIDBytes_t SENS_ACC_GYRO_MAG_CHAR_UUID_128 = { 0x1b,0xc5,0xa5,0xd5,0x02,0x00,0x36,0xac,0xe1,0x11,0x01,0x00,0x00,0x00,0xE0,0x00};
mapellil 0:e93a11b4e044 52
mapellil 0:e93a11b4e044 53
mapellil 0:e93a11b4e044 54 #define TEMP_DATA_LEN 2+2
mapellil 0:e93a11b4e044 55 #define HUM_DATA_LEN 2+2
mapellil 0:e93a11b4e044 56 #define PRES_DATA_LEN 2+4
mapellil 0:e93a11b4e044 57 #define ACC_DATA_LEN 6+2
mapellil 0:e93a11b4e044 58 #define MAG_DATA_LEN 6+2
mapellil 0:e93a11b4e044 59 #define GYRO_DATA_LEN 6+2
mapellil 0:e93a11b4e044 60 #define ACCGYROMAG_DATA_LEN 2+3*3*2
mapellil 0:e93a11b4e044 61
mapellil 0:e93a11b4e044 62
mapellil 0:e93a11b4e044 63 /* Custom Sensors Service */
mapellil 0:e93a11b4e044 64 class CustomSensorService {
mapellil 0:e93a11b4e044 65 public:
mapellil 6:c1b8fb74072e 66 CustomSensorService(BLE &_ble, CustomBleErrManagement * ErrMgr=NULL ) :
mapellil 0:e93a11b4e044 67 ble(_ble),
mapellil 0:e93a11b4e044 68 envTemperatureCharacteristic(SENS_TEMP_CHAR_UUID_128,envTemperature, TEMP_DATA_LEN, TEMP_DATA_LEN,
mapellil 0:e93a11b4e044 69 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY),
mapellil 0:e93a11b4e044 70 envHumidityCharacteristic(SENS_HUMI_CHAR_UUID_128, envHumidity, HUM_DATA_LEN, HUM_DATA_LEN,
mapellil 0:e93a11b4e044 71 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY),
mapellil 0:e93a11b4e044 72 envPressureCharacteristic(SENS_PRES_CHAR_UUID_128, envPressure, PRES_DATA_LEN, PRES_DATA_LEN,
mapellil 0:e93a11b4e044 73 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY),
mapellil 0:e93a11b4e044 74 envMagnetometerCharacteristic(SENS_MAGN_CHAR_UUID_128,envMagn, MAG_DATA_LEN, MAG_DATA_LEN,
mapellil 0:e93a11b4e044 75 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY),
mapellil 0:e93a11b4e044 76 envAccelerometerCharacteristic(SENS_ACCE_CHAR_UUID_128,envAcce, ACC_DATA_LEN, ACC_DATA_LEN,
mapellil 0:e93a11b4e044 77 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY),
mapellil 0:e93a11b4e044 78 envGyroCharacteristic(SENS_GYRO_CHAR_UUID_128,envGyro, GYRO_DATA_LEN, GYRO_DATA_LEN,
mapellil 0:e93a11b4e044 79 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY),
mapellil 0:e93a11b4e044 80 envAccGyroMagCharacteristic(SENS_ACC_GYRO_MAG_CHAR_UUID_128,envAccGyroMag, ACCGYROMAG_DATA_LEN, ACCGYROMAG_DATA_LEN,
mapellil 0:e93a11b4e044 81 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY)
mapellil 0:e93a11b4e044 82 {
mapellil 0:e93a11b4e044 83
mapellil 0:e93a11b4e044 84 static bool serviceAdded = false; /* We should only ever need to add the env service once. */
mapellil 0:e93a11b4e044 85 if (serviceAdded) {
mapellil 0:e93a11b4e044 86 return;
mapellil 0:e93a11b4e044 87 }
mapellil 6:c1b8fb74072e 88 bleErrMgr = ErrMgr;
mapellil 0:e93a11b4e044 89 GattCharacteristic *charTable[] = {&envTemperatureCharacteristic, &envHumidityCharacteristic, &envPressureCharacteristic, &envMagnetometerCharacteristic,
mapellil 0:e93a11b4e044 90 &envAccelerometerCharacteristic, &envGyroCharacteristic, &envAccGyroMagCharacteristic};
mapellil 0:e93a11b4e044 91
mapellil 0:e93a11b4e044 92 GattService envService(SENS_SERVICE_UUID_128, charTable, sizeof(charTable) / sizeof(GattCharacteristic *));
mapellil 0:e93a11b4e044 93
mapellil 0:e93a11b4e044 94 ble.gattServer().addService(envService);
mapellil 0:e93a11b4e044 95
mapellil 0:e93a11b4e044 96 isEnabledTempNotify = false;
mapellil 0:e93a11b4e044 97 isEnabledHumNotify = false;
mapellil 0:e93a11b4e044 98 isEnabledPresNotify = false;
mapellil 0:e93a11b4e044 99 isEnabledGyroNotify = false;
mapellil 0:e93a11b4e044 100 isEnabledAccNotify = false;
mapellil 0:e93a11b4e044 101 isEnabledMagNotify = false;
mapellil 0:e93a11b4e044 102 isEnabledAccGyroMagNotify = false;
mapellil 0:e93a11b4e044 103
mapellil 0:e93a11b4e044 104 isTempCalibrated = false;
mapellil 0:e93a11b4e044 105 isHumCalibrated = false;
mapellil 0:e93a11b4e044 106 isPresCalibrated = false;
mapellil 0:e93a11b4e044 107 isMagCalibrated = false;
mapellil 0:e93a11b4e044 108 isAccCalibrated = false;
mapellil 0:e93a11b4e044 109 isAGyroCalibrated = false;
mapellil 0:e93a11b4e044 110
mapellil 0:e93a11b4e044 111 memset (pastenvTemperature, 0, TEMP_DATA_LEN);
mapellil 0:e93a11b4e044 112 memset (pastenvHumidity, 0, HUM_DATA_LEN);
mapellil 0:e93a11b4e044 113 memset (pastenvPressure, 0, PRES_DATA_LEN);
mapellil 0:e93a11b4e044 114
mapellil 0:e93a11b4e044 115 isBTLEConnected = DISCONNECTED;
mapellil 0:e93a11b4e044 116 serviceAdded = true;
mapellil 0:e93a11b4e044 117 }
mapellil 0:e93a11b4e044 118
mapellil 0:e93a11b4e044 119 void sendEnvTemperature (int16_t Temp, uint16_t TimeStamp) {
mapellil 6:c1b8fb74072e 120 if (bleErrMgr != NULL) {
mapellil 6:c1b8fb74072e 121 if (!bleErrMgr->isBleTxChannelOk()){
mapellil 6:c1b8fb74072e 122 bleErrMgr->signalBleTxOk(); // skip tx because of previous error
mapellil 6:c1b8fb74072e 123 return;
mapellil 6:c1b8fb74072e 124 }
mapellil 6:c1b8fb74072e 125 }
mapellil 6:c1b8fb74072e 126 STORE_LE_16(envTemperature,TimeStamp);
mapellil 6:c1b8fb74072e 127 STORE_LE_16(envTemperature+2,Temp);
mapellil 6:c1b8fb74072e 128 PRINTF("sendEnvTemperature!! handle: %d\n\r", envTemperatureCharacteristic.getValueAttribute().getHandle());
mapellil 6:c1b8fb74072e 129 memcpy (pastenvTemperature, envTemperature, TEMP_DATA_LEN);
mapellil 6:c1b8fb74072e 130 uint32_t err = ble.gattServer().write(envTemperatureCharacteristic.getValueAttribute().getHandle(), envTemperature, TEMP_DATA_LEN, 0);
mapellil 6:c1b8fb74072e 131 if (!err) {
mapellil 6:c1b8fb74072e 132 bleErrMgr->signalBleTxOk();
mapellil 6:c1b8fb74072e 133 }else{
mapellil 6:c1b8fb74072e 134 bleErrMgr->signalBleTxErr(err);
mapellil 6:c1b8fb74072e 135 }
mapellil 0:e93a11b4e044 136 }
mapellil 0:e93a11b4e044 137
mapellil 0:e93a11b4e044 138 /**
mapellil 0:e93a11b4e044 139 * Update the temperature with a new value. Valid values range from
mapellil 0:e93a11b4e044 140 * 0..100. Anything outside this range will be ignored.
mapellil 0:e93a11b4e044 141 * @param newLevel New level. */
mapellil 0:e93a11b4e044 142 void updateEnvTemperature (int16_t Temp, uint16_t TimeStamp) {
mapellil 6:c1b8fb74072e 143 if (isTempNotificationEn()){
mapellil 0:e93a11b4e044 144 if (memcmp (&pastenvTemperature[2], &Temp, 2) != 0) {
mapellil 0:e93a11b4e044 145 sendEnvTemperature (Temp, TimeStamp);
mapellil 0:e93a11b4e044 146 }
mapellil 0:e93a11b4e044 147 }
mapellil 6:c1b8fb74072e 148 }
mapellil 0:e93a11b4e044 149
mapellil 6:c1b8fb74072e 150 void sendEnvHumidity(uint16_t Hum, uint16_t TimeStamp) {
mapellil 6:c1b8fb74072e 151 if (bleErrMgr != NULL) {
mapellil 6:c1b8fb74072e 152 if (!bleErrMgr->isBleTxChannelOk()){
mapellil 6:c1b8fb74072e 153 bleErrMgr->signalBleTxOk(); // skip tx because of previous error
mapellil 6:c1b8fb74072e 154 return;
mapellil 6:c1b8fb74072e 155 }
mapellil 6:c1b8fb74072e 156 }
mapellil 6:c1b8fb74072e 157 STORE_LE_16(envHumidity,TimeStamp);
mapellil 6:c1b8fb74072e 158 STORE_LE_16(envHumidity+2,Hum);
mapellil 6:c1b8fb74072e 159 memcpy (pastenvHumidity, envHumidity, HUM_DATA_LEN);
mapellil 6:c1b8fb74072e 160 uint32_t err = ble.gattServer().write(envHumidityCharacteristic.getValueAttribute().getHandle(), envHumidity, HUM_DATA_LEN, 0);
mapellil 6:c1b8fb74072e 161 if (!err) {
mapellil 6:c1b8fb74072e 162 bleErrMgr->signalBleTxOk();
mapellil 6:c1b8fb74072e 163 }else{
mapellil 6:c1b8fb74072e 164 bleErrMgr->signalBleTxErr(err);
mapellil 6:c1b8fb74072e 165 }
mapellil 6:c1b8fb74072e 166 }
mapellil 0:e93a11b4e044 167
mapellil 0:e93a11b4e044 168 void updateEnvHumidity(uint16_t Hum, uint16_t TimeStamp) {
mapellil 6:c1b8fb74072e 169 if (isHumNotificationEn()){
mapellil 0:e93a11b4e044 170 if (memcmp (&pastenvHumidity[2], &Hum, 2) != 0) {
mapellil 0:e93a11b4e044 171 sendEnvHumidity(Hum, TimeStamp);
mapellil 0:e93a11b4e044 172 }
mapellil 6:c1b8fb74072e 173 }
mapellil 0:e93a11b4e044 174 }
mapellil 0:e93a11b4e044 175
mapellil 0:e93a11b4e044 176 void sendEnvPressure(uint32_t Press, uint16_t TimeStamp) {
mapellil 6:c1b8fb74072e 177 if (bleErrMgr != NULL) {
mapellil 6:c1b8fb74072e 178 if (!bleErrMgr->isBleTxChannelOk()){
mapellil 6:c1b8fb74072e 179 bleErrMgr->signalBleTxOk(); // skip tx because of previous error
mapellil 6:c1b8fb74072e 180 return;
mapellil 6:c1b8fb74072e 181 }
mapellil 6:c1b8fb74072e 182 }
mapellil 6:c1b8fb74072e 183 STORE_LE_16(envPressure,TimeStamp);
mapellil 6:c1b8fb74072e 184 STORE_LE_32(envPressure+2,Press);
mapellil 6:c1b8fb74072e 185 memcpy (pastenvPressure, envPressure, PRES_DATA_LEN);
mapellil 6:c1b8fb74072e 186 uint32_t err=ble.gattServer().write(envPressureCharacteristic.getValueAttribute().getHandle(), envPressure, PRES_DATA_LEN, 0);
mapellil 6:c1b8fb74072e 187 if (!err) {
mapellil 6:c1b8fb74072e 188 bleErrMgr->signalBleTxOk();
mapellil 6:c1b8fb74072e 189 }else{
mapellil 6:c1b8fb74072e 190 bleErrMgr->signalBleTxErr(err);
mapellil 6:c1b8fb74072e 191 }
mapellil 6:c1b8fb74072e 192 }
mapellil 0:e93a11b4e044 193
mapellil 0:e93a11b4e044 194 void updateEnvPressure(uint32_t Press, uint16_t TimeStamp) {
mapellil 6:c1b8fb74072e 195 if (isPresNotificationEn()){
mapellil 0:e93a11b4e044 196 if (memcmp (&pastenvPressure[2], &Press, 2) != 0) {
mapellil 0:e93a11b4e044 197 sendEnvPressure(Press, TimeStamp);
mapellil 6:c1b8fb74072e 198 }
mapellil 6:c1b8fb74072e 199 }
mapellil 0:e93a11b4e044 200 }
mapellil 0:e93a11b4e044 201
mapellil 6:c1b8fb74072e 202 void sendEnvMagnetometer(AxesRaw_TypeDef *Magn, uint16_t TimeStamp, osxMFX_calibFactor magOffset) {
mapellil 6:c1b8fb74072e 203 if (bleErrMgr != NULL) {
mapellil 6:c1b8fb74072e 204 if (!bleErrMgr->isBleTxChannelOk()){
mapellil 6:c1b8fb74072e 205 bleErrMgr->signalBleTxOk(); // skip tx because of previous error
mapellil 6:c1b8fb74072e 206 return;
mapellil 6:c1b8fb74072e 207 }
mapellil 6:c1b8fb74072e 208 }
mapellil 6:c1b8fb74072e 209 STORE_LE_16(envMagn,TimeStamp);
mapellil 6:c1b8fb74072e 210 STORE_LE_16(envMagn+2,(Magn->AXIS_X - magOffset.magOffX));
mapellil 6:c1b8fb74072e 211 STORE_LE_16(envMagn+4,(Magn->AXIS_Y - magOffset.magOffY));
mapellil 6:c1b8fb74072e 212 STORE_LE_16(envMagn+6,(Magn->AXIS_Z - magOffset.magOffZ));
mapellil 6:c1b8fb74072e 213 uint32_t err = ble.gattServer().write(envMagnetometerCharacteristic.getValueAttribute().getHandle(), envMagn, MAG_DATA_LEN, 0);
mapellil 6:c1b8fb74072e 214 if (!err) {
mapellil 6:c1b8fb74072e 215 bleErrMgr->signalBleTxOk();
mapellil 6:c1b8fb74072e 216 }else{
mapellil 6:c1b8fb74072e 217 bleErrMgr->signalBleTxErr(err);
mapellil 6:c1b8fb74072e 218 }
mapellil 0:e93a11b4e044 219 }
mapellil 0:e93a11b4e044 220
mapellil 0:e93a11b4e044 221 void updateEnvMagnetometer(AxesRaw_TypeDef *Magn, uint16_t TimeStamp, osxMFX_calibFactor magOffset) {
mapellil 0:e93a11b4e044 222 if (isMagNotificationEn()) sendEnvMagnetometer(Magn, TimeStamp, magOffset);
mapellil 0:e93a11b4e044 223 }
mapellil 0:e93a11b4e044 224
mapellil 0:e93a11b4e044 225 void sendEnvAccelerometer (AxesRaw_TypeDef *Acc, uint16_t TimeStamp) {
mapellil 6:c1b8fb74072e 226 if (bleErrMgr != NULL) {
mapellil 6:c1b8fb74072e 227 if (!bleErrMgr->isBleTxChannelOk()){
mapellil 6:c1b8fb74072e 228 bleErrMgr->signalBleTxOk(); // skip tx because of previous error
mapellil 6:c1b8fb74072e 229 return;
mapellil 6:c1b8fb74072e 230 }
mapellil 6:c1b8fb74072e 231 }
mapellil 6:c1b8fb74072e 232 STORE_LE_16(envAcce,TimeStamp);
mapellil 6:c1b8fb74072e 233 STORE_LE_16(envAcce+2,Acc->AXIS_X);
mapellil 6:c1b8fb74072e 234 STORE_LE_16(envAcce+4,Acc->AXIS_Y);
mapellil 6:c1b8fb74072e 235 STORE_LE_16(envAcce+6,Acc->AXIS_Z);
mapellil 6:c1b8fb74072e 236 uint32_t err = ble.gattServer().write(envAccelerometerCharacteristic.getValueAttribute().getHandle(), envAcce, ACC_DATA_LEN, 0);
mapellil 6:c1b8fb74072e 237 if (!err) {
mapellil 6:c1b8fb74072e 238 bleErrMgr->signalBleTxOk();
mapellil 6:c1b8fb74072e 239 }else{
mapellil 6:c1b8fb74072e 240 bleErrMgr->signalBleTxErr(err);
mapellil 6:c1b8fb74072e 241 }
mapellil 6:c1b8fb74072e 242
mapellil 0:e93a11b4e044 243 }
mapellil 0:e93a11b4e044 244
mapellil 0:e93a11b4e044 245 void updateEnvAccelerometer (AxesRaw_TypeDef *Acc, uint16_t TimeStamp) {
mapellil 0:e93a11b4e044 246 if (isAccNotificationEn()) sendEnvAccelerometer (Acc, TimeStamp);
mapellil 0:e93a11b4e044 247 }
mapellil 0:e93a11b4e044 248
mapellil 0:e93a11b4e044 249 void sendEnvGyroscope (AxesRaw_TypeDef *Gyro, uint16_t TimeStamp) {
mapellil 6:c1b8fb74072e 250 if (bleErrMgr != NULL) {
mapellil 6:c1b8fb74072e 251 if (!bleErrMgr->isBleTxChannelOk()){
mapellil 6:c1b8fb74072e 252 bleErrMgr->signalBleTxOk(); // skip tx because of previous error
mapellil 6:c1b8fb74072e 253 return;
mapellil 6:c1b8fb74072e 254 }
mapellil 6:c1b8fb74072e 255 }
mapellil 6:c1b8fb74072e 256 STORE_LE_16(envGyro,TimeStamp);
mapellil 6:c1b8fb74072e 257 STORE_LE_16(envGyro+2,Gyro->AXIS_X);
mapellil 6:c1b8fb74072e 258 STORE_LE_16(envGyro+4,Gyro->AXIS_Y);
mapellil 6:c1b8fb74072e 259 STORE_LE_16(envGyro+6,Gyro->AXIS_Z);
mapellil 6:c1b8fb74072e 260 uint32_t err = ble.gattServer().write(envGyroCharacteristic.getValueAttribute().getHandle(), envGyro, GYRO_DATA_LEN, 0);
mapellil 6:c1b8fb74072e 261 if (!err) {
mapellil 6:c1b8fb74072e 262 bleErrMgr->signalBleTxOk();
mapellil 6:c1b8fb74072e 263 }else{
mapellil 6:c1b8fb74072e 264 bleErrMgr->signalBleTxErr(err);
mapellil 6:c1b8fb74072e 265 }
mapellil 0:e93a11b4e044 266 }
mapellil 0:e93a11b4e044 267
mapellil 0:e93a11b4e044 268 void updateEnvGyroscope (AxesRaw_TypeDef *Gyro, uint16_t TimeStamp) {
mapellil 0:e93a11b4e044 269 if (isGyroNotificationEn()) sendEnvGyroscope (Gyro, TimeStamp);
mapellil 0:e93a11b4e044 270 }
mapellil 0:e93a11b4e044 271
mapellil 0:e93a11b4e044 272 void sendEnvAccGyroMag (AxesRaw_TypeDef *Acc, AxesRaw_TypeDef *Gyro, AxesRaw_TypeDef *Magn, uint16_t TimeStamp, osxMFX_calibFactor magOffset) {
mapellil 6:c1b8fb74072e 273 if (bleErrMgr != NULL) {
mapellil 6:c1b8fb74072e 274 if (!bleErrMgr->isBleTxChannelOk()){
mapellil 6:c1b8fb74072e 275 bleErrMgr->signalBleTxOk(); // skip tx because of previous error
mapellil 6:c1b8fb74072e 276 return;
mapellil 6:c1b8fb74072e 277 }
mapellil 6:c1b8fb74072e 278 }
mapellil 6:c1b8fb74072e 279 STORE_LE_16(envAccGyroMag,TimeStamp);
mapellil 6:c1b8fb74072e 280 STORE_LE_16(envAccGyroMag+2,Acc->AXIS_X);
mapellil 6:c1b8fb74072e 281 STORE_LE_16(envAccGyroMag+4,Acc->AXIS_Y);
mapellil 6:c1b8fb74072e 282 STORE_LE_16(envAccGyroMag+6,Acc->AXIS_Z);
mapellil 0:e93a11b4e044 283
mapellil 6:c1b8fb74072e 284 STORE_LE_16(envAccGyroMag+8,Gyro->AXIS_X);
mapellil 6:c1b8fb74072e 285 STORE_LE_16(envAccGyroMag+10,Gyro->AXIS_Y);
mapellil 6:c1b8fb74072e 286 STORE_LE_16(envAccGyroMag+12,Gyro->AXIS_Z);
mapellil 0:e93a11b4e044 287
mapellil 6:c1b8fb74072e 288 STORE_LE_16(envAccGyroMag+14,(Magn->AXIS_X - magOffset.magOffX));
mapellil 6:c1b8fb74072e 289 STORE_LE_16(envAccGyroMag+16,(Magn->AXIS_Y - magOffset.magOffY));
mapellil 6:c1b8fb74072e 290 STORE_LE_16(envAccGyroMag+18,(Magn->AXIS_Z - magOffset.magOffZ));
mapellil 6:c1b8fb74072e 291 uint32_t err = ble.gattServer().write(envAccGyroMagCharacteristic.getValueAttribute().getHandle(), envAccGyroMag, ACCGYROMAG_DATA_LEN, 0);
mapellil 6:c1b8fb74072e 292 if (!err) {
mapellil 6:c1b8fb74072e 293 bleErrMgr->signalBleTxOk();
mapellil 6:c1b8fb74072e 294 }else{
mapellil 6:c1b8fb74072e 295 bleErrMgr->signalBleTxErr(err);
mapellil 6:c1b8fb74072e 296 }
mapellil 0:e93a11b4e044 297 }
mapellil 0:e93a11b4e044 298
mapellil 0:e93a11b4e044 299 void updateEnvAccGyroMag (AxesRaw_TypeDef *Acc, AxesRaw_TypeDef *Gyro, AxesRaw_TypeDef *Magn, uint16_t TimeStamp, osxMFX_calibFactor magOffset) {
mapellil 0:e93a11b4e044 300 if (isAccGyroMagNotificationEn())sendEnvAccGyroMag (Acc, Gyro, Magn, TimeStamp, magOffset);
mapellil 0:e93a11b4e044 301 }
mapellil 0:e93a11b4e044 302
mapellil 0:e93a11b4e044 303 void enNotify (Gap::Handle_t handle) {
mapellil 0:e93a11b4e044 304 if (isTempHandle(handle)) { isEnabledTempNotify = true; memset(pastenvTemperature,0,TEMP_DATA_LEN); return; }
mapellil 0:e93a11b4e044 305 if (isHumHandle(handle)) { isEnabledHumNotify = true; memset(pastenvHumidity,0,HUM_DATA_LEN); return; }
mapellil 0:e93a11b4e044 306 if (isPresHandle(handle)) { isEnabledPresNotify = true; memset(pastenvPressure,0,PRES_DATA_LEN); return; }
mapellil 0:e93a11b4e044 307 if (isGyroHandle(handle)) { isEnabledGyroNotify = true; return; }
mapellil 0:e93a11b4e044 308 if (isAccHandle(handle)) { isEnabledAccNotify = true; return; }
mapellil 0:e93a11b4e044 309 if (isMagHandle(handle)) { isEnabledMagNotify = true; return; }
mapellil 0:e93a11b4e044 310 if (isAccGyroMagHandle(handle)) { isEnabledAccGyroMagNotify = true; return; }
mapellil 0:e93a11b4e044 311 }
mapellil 0:e93a11b4e044 312
mapellil 0:e93a11b4e044 313 void disNotify (Gap::Handle_t handle) {
mapellil 0:e93a11b4e044 314 if (isTempHandle(handle)) { isEnabledTempNotify = false; memset(pastenvTemperature,0,TEMP_DATA_LEN); return; }
mapellil 0:e93a11b4e044 315 if (isHumHandle(handle)) { isEnabledHumNotify = false; memset(pastenvHumidity,0,HUM_DATA_LEN); return; }
mapellil 0:e93a11b4e044 316 if (isPresHandle(handle)) { isEnabledPresNotify = false; memset(pastenvPressure,0,PRES_DATA_LEN); return; }
mapellil 0:e93a11b4e044 317 if (isGyroHandle(handle)) { isEnabledGyroNotify = false; return; }
mapellil 0:e93a11b4e044 318 if (isAccHandle(handle)) { isEnabledAccNotify = false; return; }
mapellil 0:e93a11b4e044 319 if (isMagHandle(handle)) { isEnabledMagNotify = false; return; }
mapellil 0:e93a11b4e044 320 if (isAccGyroMagHandle(handle)) { isEnabledAccGyroMagNotify = false; return; }
mapellil 0:e93a11b4e044 321 }
mapellil 0:e93a11b4e044 322
mapellil 0:e93a11b4e044 323 bool isTempNotificationEn (void) {
mapellil 0:e93a11b4e044 324 return isEnabledTempNotify;
mapellil 0:e93a11b4e044 325 }
mapellil 0:e93a11b4e044 326
mapellil 0:e93a11b4e044 327 bool isHumNotificationEn (void) {
mapellil 0:e93a11b4e044 328 return isEnabledHumNotify;
mapellil 0:e93a11b4e044 329 }
mapellil 0:e93a11b4e044 330
mapellil 0:e93a11b4e044 331 bool isPresNotificationEn (void) {
mapellil 0:e93a11b4e044 332 return isEnabledPresNotify;
mapellil 0:e93a11b4e044 333 }
mapellil 0:e93a11b4e044 334
mapellil 0:e93a11b4e044 335 bool isGyroNotificationEn (void) {
mapellil 0:e93a11b4e044 336 return isEnabledGyroNotify;
mapellil 0:e93a11b4e044 337 }
mapellil 0:e93a11b4e044 338
mapellil 0:e93a11b4e044 339 bool isAccNotificationEn (void) {
mapellil 0:e93a11b4e044 340 return isEnabledAccNotify;
mapellil 0:e93a11b4e044 341 }
mapellil 0:e93a11b4e044 342
mapellil 0:e93a11b4e044 343 bool isMagNotificationEn (void) {
mapellil 0:e93a11b4e044 344 return isEnabledMagNotify;
mapellil 0:e93a11b4e044 345 }
mapellil 0:e93a11b4e044 346
mapellil 0:e93a11b4e044 347 bool isAccGyroMagNotificationEn (void) {
mapellil 0:e93a11b4e044 348 return isEnabledAccGyroMagNotify;
mapellil 0:e93a11b4e044 349 }
mapellil 0:e93a11b4e044 350
mapellil 0:e93a11b4e044 351 bool isTempHandle (Gap::Handle_t handle) {
mapellil 0:e93a11b4e044 352 if (handle == envTemperatureCharacteristic.getValueAttribute().getHandle()) return true;
mapellil 0:e93a11b4e044 353 return false;
mapellil 0:e93a11b4e044 354 }
mapellil 0:e93a11b4e044 355
mapellil 0:e93a11b4e044 356 bool isHumHandle (Gap::Handle_t handle) {
mapellil 0:e93a11b4e044 357 if (handle == envHumidityCharacteristic.getValueAttribute().getHandle()) return true;
mapellil 0:e93a11b4e044 358 return false;
mapellil 0:e93a11b4e044 359 }
mapellil 0:e93a11b4e044 360
mapellil 0:e93a11b4e044 361 bool isPresHandle (Gap::Handle_t handle) {
mapellil 0:e93a11b4e044 362 if (handle == envPressureCharacteristic.getValueAttribute().getHandle()) return true;
mapellil 0:e93a11b4e044 363 return false;
mapellil 0:e93a11b4e044 364 }
mapellil 0:e93a11b4e044 365
mapellil 0:e93a11b4e044 366 bool isMagHandle (Gap::Handle_t handle) {
mapellil 0:e93a11b4e044 367 if (handle == envMagnetometerCharacteristic.getValueAttribute().getHandle()) return true;
mapellil 0:e93a11b4e044 368 return false;
mapellil 0:e93a11b4e044 369 }
mapellil 0:e93a11b4e044 370 bool isAccHandle (Gap::Handle_t handle) {
mapellil 0:e93a11b4e044 371 if (handle == envAccelerometerCharacteristic.getValueAttribute().getHandle()) return true;
mapellil 0:e93a11b4e044 372 return false;
mapellil 0:e93a11b4e044 373 }
mapellil 0:e93a11b4e044 374 bool isGyroHandle (Gap::Handle_t handle) {
mapellil 0:e93a11b4e044 375 if (handle == envGyroCharacteristic.getValueAttribute().getHandle()) return true;
mapellil 0:e93a11b4e044 376 return false;
mapellil 0:e93a11b4e044 377 }
mapellil 0:e93a11b4e044 378 bool isAccGyroMagHandle (Gap::Handle_t handle) {
mapellil 0:e93a11b4e044 379 if (handle == envAccGyroMagCharacteristic.getValueAttribute().getHandle()) return true;
mapellil 0:e93a11b4e044 380 return false;
mapellil 0:e93a11b4e044 381 }
mapellil 0:e93a11b4e044 382
mapellil 0:e93a11b4e044 383 void updateConnectionStatus(ConnectionStatus_t status) {
mapellil 0:e93a11b4e044 384 isEnabledTempNotify = false;
mapellil 0:e93a11b4e044 385 isEnabledHumNotify = false;
mapellil 0:e93a11b4e044 386 isEnabledPresNotify = false;
mapellil 0:e93a11b4e044 387 isEnabledGyroNotify = false;
mapellil 0:e93a11b4e044 388 isEnabledAccNotify = false;
mapellil 0:e93a11b4e044 389 isEnabledMagNotify = false;
mapellil 0:e93a11b4e044 390 isEnabledAccGyroMagNotify = false;
mapellil 0:e93a11b4e044 391
mapellil 0:e93a11b4e044 392 isTempCalibrated = false;
mapellil 0:e93a11b4e044 393 isHumCalibrated = false;
mapellil 0:e93a11b4e044 394 isPresCalibrated = false;
mapellil 0:e93a11b4e044 395 isMagCalibrated = false;
mapellil 0:e93a11b4e044 396 isAccCalibrated = false;
mapellil 0:e93a11b4e044 397 isAGyroCalibrated = false;
mapellil 0:e93a11b4e044 398
mapellil 0:e93a11b4e044 399 memset (pastenvTemperature, 0, TEMP_DATA_LEN);
mapellil 0:e93a11b4e044 400 memset (pastenvHumidity, 0, HUM_DATA_LEN);
mapellil 0:e93a11b4e044 401 memset (pastenvPressure, 0, PRES_DATA_LEN);
mapellil 0:e93a11b4e044 402 isBTLEConnected = status;
mapellil 0:e93a11b4e044 403 }
mapellil 0:e93a11b4e044 404
mapellil 0:e93a11b4e044 405
mapellil 0:e93a11b4e044 406 private:
mapellil 6:c1b8fb74072e 407 BLE &ble;
mapellil 6:c1b8fb74072e 408 CustomBleErrManagement *bleErrMgr;
mapellil 0:e93a11b4e044 409 uint8_t envTemperature [TEMP_DATA_LEN]; /* in C */
mapellil 0:e93a11b4e044 410 uint8_t pastenvTemperature [TEMP_DATA_LEN];
mapellil 0:e93a11b4e044 411 uint8_t envHumidity [HUM_DATA_LEN]; /* in % */
mapellil 0:e93a11b4e044 412 uint8_t pastenvHumidity [HUM_DATA_LEN];
mapellil 0:e93a11b4e044 413 uint8_t envPressure [PRES_DATA_LEN]; /* in mBar */
mapellil 0:e93a11b4e044 414 uint8_t pastenvPressure [PRES_DATA_LEN];
mapellil 0:e93a11b4e044 415 uint8_t envMagn [MAG_DATA_LEN];
mapellil 0:e93a11b4e044 416 uint8_t envGyro [GYRO_DATA_LEN];
mapellil 0:e93a11b4e044 417 uint8_t envAcce [ACC_DATA_LEN];
mapellil 0:e93a11b4e044 418 uint8_t envAccGyroMag [ACCGYROMAG_DATA_LEN];
mapellil 0:e93a11b4e044 419
mapellil 0:e93a11b4e044 420 GattCharacteristic envTemperatureCharacteristic;
mapellil 0:e93a11b4e044 421 GattCharacteristic envHumidityCharacteristic;
mapellil 0:e93a11b4e044 422 GattCharacteristic envPressureCharacteristic;
mapellil 0:e93a11b4e044 423
mapellil 0:e93a11b4e044 424 GattCharacteristic envMagnetometerCharacteristic;
mapellil 0:e93a11b4e044 425 GattCharacteristic envAccelerometerCharacteristic;
mapellil 0:e93a11b4e044 426 GattCharacteristic envGyroCharacteristic;
mapellil 0:e93a11b4e044 427 GattCharacteristic envAccGyroMagCharacteristic;
mapellil 0:e93a11b4e044 428
mapellil 0:e93a11b4e044 429 ConnectionStatus_t isBTLEConnected;
mapellil 0:e93a11b4e044 430
mapellil 0:e93a11b4e044 431 bool isEnabledTempNotify;
mapellil 0:e93a11b4e044 432 bool isEnabledHumNotify;
mapellil 0:e93a11b4e044 433 bool isEnabledPresNotify;
mapellil 0:e93a11b4e044 434 bool isEnabledGyroNotify;
mapellil 0:e93a11b4e044 435 bool isEnabledAccNotify;
mapellil 0:e93a11b4e044 436 bool isEnabledMagNotify;
mapellil 0:e93a11b4e044 437 bool isEnabledAccGyroMagNotify;
mapellil 0:e93a11b4e044 438
mapellil 0:e93a11b4e044 439 bool isTempCalibrated;
mapellil 0:e93a11b4e044 440 bool isHumCalibrated;
mapellil 0:e93a11b4e044 441 bool isPresCalibrated;
mapellil 0:e93a11b4e044 442 bool isMagCalibrated;
mapellil 0:e93a11b4e044 443 bool isAccCalibrated;
mapellil 0:e93a11b4e044 444 bool isAGyroCalibrated;
mapellil 0:e93a11b4e044 445
mapellil 0:e93a11b4e044 446 };
mapellil 0:e93a11b4e044 447
mapellil 0:e93a11b4e044 448 #endif /* #ifndef __CUSTOM_BLE_SENSORS_SERVICE_H__*/