SunTracker_BLE

Dependencies:   BLE_API X_NUCLEO_6180XA1 X_NUCLEO_IDB0XA1 X_NUCLEO_IHM01A1 X_NUCLEO_IKS01A1 mbed

Fork of SunTracker_BLE by ST Expansion SW Team

Overview

The SunTracker is a demo application running on ST Nucleo-F401RE stacking a set of ST X-NUCLEO expansion boards.
Main features provided are:

  • A solar panel follows the light source, orienting the panel in order to achieve the best panel efficiency.
  • Orientation is controlled thanks to a couple of VL6180X FlightSense light sensors mounted on a X-NUCLEO-6180XA1 expansion board and driven by X-NUCLEO-IHM01A1 controlled stepper motor acting as actuator to orientate the panel.
  • The system features a progressive control on the stepper motor in order to modulate the panel rotation speed according to the light angle.
  • The application is also able to control the panel productivity reading the panel voltage through an ADC and proving feedback on the local display.
  • A manual orientation is possible by using the accelerometer on a X-NUCLEO-IKS01A1 expansion board that, according on board tilt, controls the speed and the rotate direction.
  • A remote control is available using a X-NUCLEO-IDB04A1 or a X-NUCLEO-IDB05A1 Bluetooth Low Energy expansion board. Remote control software is here.

/media/uploads/fabiombed/suntracker_server-client.png

Working Status

  • SunTracker has 3 working status visible on FlightSense display and switchable by pressing the User Button:

Status 0 (Idle)

  • Motor: Free Turning
  • Display: Waiting for User Button

Status 1

  • Motor: Driven by Light
  • Display: Direction and Light Intensity = Direction and Motor Speed

Status 2

  • Motor: Driven by Light
  • Display: Solar Panel Efficiency

Status 3

  • Motor: Driven by Accelerometer
  • Display: Direction and Accelerometer Intensity

Server Startup

  • When you plug the power supply, the word ‘PUSH’ is shown on display.
  • You can manually rotate the structure to assign the ‘Zero Point’. Then press the User Button to launch the application.
  • The display will show this status, which means that the structure is oriented to maximize the efficiency of the solar panel.
  • If there is a light displacement, the structure will rotate, left or right, to follow the light source and on display is shown the direction and the speed.
  • You can press the User Button to show the panel efficiency with 4 digits that represent the range from 0v (0000) to 3,3v (3300).
  • Further pressing the User Button you will manual rotate the panel by tilt the Server or Client accelerometer depending by BLE connection.

Client Startup

  • The Client application can remotely control the User Button and the Accelerometer functions.
  • Power on the Client AFTER the Server, it will automatically search for the SunTracker and will establish a BLE connection.
  • The Green Led on Nucleo Client board will be powered on.

Rotation Features

  • It has been implemented a block of rotation to avoid cables twist.
  • The blocking point can be set in the firmware by changing a constant.
  • You can manually rotate the structure to assign the ‘Zero Point’ before press the User Button to launch the application.
  • The system features a progressive control on the stepper motor in order to modulate the rotation speed according to the light or accelerometer angle.

List of Components

SERVER SunTracker_BLE

  • Stepper Motor 400’’ (Part Number 5350401) - To orientate the Mechanical Structure.
  • Solar Panel 0.446w (Part Number 0194127) - To capture sunlight and generate electrical current.
  • Power Supply 12v (Part Number 7262993) - To provide power supply at the Stepper Motor.
  • Flat Cable 6 ways (Part Number 1807010) - To plug VL6180X-SATEL with X-NUCLEO-6180XA1 (60cm length each x2).
  • Cable Connector (Part Number 6737694) - To plug the Flat Cable (x4).
  • Power Connector (Part Number 0487842) - To provide Power Supply to X-NUCLEO-IHM01A1.

CLIENT SunTracker_BLE_Remote

MECHANICAL STRUCTURE

Find here the STL files to print with a 3D printer.

/media/uploads/fabiombed/assembly.png

/media/uploads/fabiombed/mechanical_structure_and_motor_legs.png

FLAT CABLE ASSEMBLY

/media/uploads/fabiombed/flat_cable.png

HARDWARE SETUP

Nucleo ADC + Solar Panel

Connect Solar Panel cables to Nucleo Morpho PC_3 (white) and Nucleo Morpho GND (black). Connect a capacitor 10uF between PC_3 and GND to stabilize its voltage value shown on display.

EasySpin (L6474) + BLE

Hardware conflict between EasySpin DIR1 and BLE Reset, both on same Arduino Pin PA_8. Disconnect PA_8 between EasySpin and Nucleo by fold EasySpin Pin. PB_2 has been configured as EasySpin DIR1 in the firmware . Connect Nucleo Morpho PB_2 to FlightSense Arduino PA_8 by a wire.

FlightSense Satellites

In case of instability with I2C due to long flat cables, solder 4 SMD capacitors 47pF on FlightSense board in parallel between R15, R16, R17, R18 and plug 2 capacitors 15pF between FlightSense Arduino PB_8 and PB_9 to GND pin to cut-off noises over 720 KHz.

Arduino & Morpho Pinout

/media/uploads/fabiombed/arduino_pinout.png /media/uploads/fabiombed/morpho_pinout.png

Committer:
fabiombed
Date:
Tue Jan 26 13:29:53 2016 +0000
Revision:
4:1d3d071a4c2c
fixed compile error and all libraries updated at last release

Who changed what in which revision?

UserRevisionLine numberNew contents of line
fabiombed 4:1d3d071a4c2c 1 /******************************************************************************
fabiombed 4:1d3d071a4c2c 2 * @file CustomSunTrackerService.h
fabiombed 4:1d3d071a4c2c 3 * @author Fabio Brembilla
fabiombed 4:1d3d071a4c2c 4 * @version V1.0.0
fabiombed 4:1d3d071a4c2c 5 * @date January 22th, 2016
fabiombed 4:1d3d071a4c2c 6 * @brief SunTracker Custom Service for BlueTooth (IDB0XA1 expansion board)
fabiombed 4:1d3d071a4c2c 7 ******************************************************************************
fabiombed 4:1d3d071a4c2c 8
fabiombed 4:1d3d071a4c2c 9 * mbed Microcontroller Library
fabiombed 4:1d3d071a4c2c 10 * Copyright (c) 2006-2013 ARM Limited
fabiombed 4:1d3d071a4c2c 11 *
fabiombed 4:1d3d071a4c2c 12 * Licensed under the Apache License, Version 2.0 (the "License");
fabiombed 4:1d3d071a4c2c 13 * you may not use this file except in compliance with the License.
fabiombed 4:1d3d071a4c2c 14 * You may obtain a copy of the License at
fabiombed 4:1d3d071a4c2c 15 *
fabiombed 4:1d3d071a4c2c 16 * http://www.apache.org/licenses/LICENSE-2.0
fabiombed 4:1d3d071a4c2c 17 *
fabiombed 4:1d3d071a4c2c 18 * Unless required by applicable law or agreed to in writing, software
fabiombed 4:1d3d071a4c2c 19 * distributed under the License is distributed on an "AS IS" BASIS,
fabiombed 4:1d3d071a4c2c 20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
fabiombed 4:1d3d071a4c2c 21 * See the License for the specific language governing permissions and
fabiombed 4:1d3d071a4c2c 22 * limitations under the License.
fabiombed 4:1d3d071a4c2c 23 */
fabiombed 4:1d3d071a4c2c 24
fabiombed 4:1d3d071a4c2c 25 #ifndef __CUSTOM_BLE_SENSORS_SERVICE_H__
fabiombed 4:1d3d071a4c2c 26 #define __CUSTOM_BLE_SENSORS_SERVICE_H__
fabiombed 4:1d3d071a4c2c 27
fabiombed 4:1d3d071a4c2c 28 #include "BLE.h"
fabiombed 4:1d3d071a4c2c 29 #include "debug.h" // Need for PRINTF
fabiombed 4:1d3d071a4c2c 30 #include "Utils.h" // Need for STORE_LE_16 and _32
fabiombed 4:1d3d071a4c2c 31
fabiombed 4:1d3d071a4c2c 32 typedef struct {
fabiombed 4:1d3d071a4c2c 33 int32_t AXIS_X;
fabiombed 4:1d3d071a4c2c 34 int32_t AXIS_Y;
fabiombed 4:1d3d071a4c2c 35 int32_t AXIS_Z;
fabiombed 4:1d3d071a4c2c 36 } AxesRaw_TypeDef;
fabiombed 4:1d3d071a4c2c 37
fabiombed 4:1d3d071a4c2c 38 typedef enum ConnectionStatus_t {
fabiombed 4:1d3d071a4c2c 39 DISCONNECTED =0,
fabiombed 4:1d3d071a4c2c 40 CONNECTED =1
fabiombed 4:1d3d071a4c2c 41 }cns_t;
fabiombed 4:1d3d071a4c2c 42
fabiombed 4:1d3d071a4c2c 43 const unsigned LENGTH_OF_LONG_UUID = 16;
fabiombed 4:1d3d071a4c2c 44 typedef uint16_t ShortUUIDBytes_t;
fabiombed 4:1d3d071a4c2c 45 typedef uint8_t LongUUIDBytes_t[LENGTH_OF_LONG_UUID];
fabiombed 4:1d3d071a4c2c 46
fabiombed 4:1d3d071a4c2c 47
fabiombed 4:1d3d071a4c2c 48 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,
fabiombed 4:1d3d071a4c2c 49
fabiombed 4:1d3d071a4c2c 50 const LongUUIDBytes_t SENS_TEMP_CHAR_UUID_128 = { 0x1b,0xc5,0xa5,0xd5,0x02,0x00,0x36,0xac,0xe1,0x11,0x01,0x00,0x00,0x00,0x04,0x00};
fabiombed 4:1d3d071a4c2c 51 const LongUUIDBytes_t SENS_HUMI_CHAR_UUID_128 = { 0x1b,0xc5,0xa5,0xd5,0x02,0x00,0x36,0xac,0xe1,0x11,0x01,0x00,0x00,0x00,0x08,0x00};
fabiombed 4:1d3d071a4c2c 52 const LongUUIDBytes_t SENS_PRES_CHAR_UUID_128 = { 0x1b,0xc5,0xa5,0xd5,0x02,0x00,0x36,0xac,0xe1,0x11,0x01,0x00,0x00,0x00,0x10,0x00};
fabiombed 4:1d3d071a4c2c 53 const LongUUIDBytes_t SENS_MAGN_CHAR_UUID_128 = { 0x1b,0xc5,0xa5,0xd5,0x02,0x00,0x36,0xac,0xe1,0x11,0x01,0x00,0x00,0x00,0x20,0x00};
fabiombed 4:1d3d071a4c2c 54 const LongUUIDBytes_t SENS_GYRO_CHAR_UUID_128 = { 0x1b,0xc5,0xa5,0xd5,0x02,0x00,0x36,0xac,0xe1,0x11,0x01,0x00,0x00,0x00,0x40,0x00};
fabiombed 4:1d3d071a4c2c 55 const LongUUIDBytes_t SENS_ACCE_CHAR_UUID_128 = { 0x1b,0xc5,0xa5,0xd5,0x02,0x00,0x36,0xac,0xe1,0x11,0x01,0x00,0x00,0x00,0x80,0x00};
fabiombed 4:1d3d071a4c2c 56 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};
fabiombed 4:1d3d071a4c2c 57
fabiombed 4:1d3d071a4c2c 58
fabiombed 4:1d3d071a4c2c 59 #define TEMP_DATA_LEN 2+2
fabiombed 4:1d3d071a4c2c 60 #define HUM_DATA_LEN 2+2
fabiombed 4:1d3d071a4c2c 61 #define PRES_DATA_LEN 2+4
fabiombed 4:1d3d071a4c2c 62 #define ACC_DATA_LEN 6+2
fabiombed 4:1d3d071a4c2c 63 #define MAG_DATA_LEN 6+2
fabiombed 4:1d3d071a4c2c 64 #define GYRO_DATA_LEN 6+2
fabiombed 4:1d3d071a4c2c 65 #define ACCGYROMAG_DATA_LEN 2+3*3*2
fabiombed 4:1d3d071a4c2c 66
fabiombed 4:1d3d071a4c2c 67
fabiombed 4:1d3d071a4c2c 68 /* Custom Sensors Service */
fabiombed 4:1d3d071a4c2c 69 class CustomSensorService {
fabiombed 4:1d3d071a4c2c 70 public:
fabiombed 4:1d3d071a4c2c 71 CustomSensorService(BLEDevice &_ble) :
fabiombed 4:1d3d071a4c2c 72 ble(_ble),
fabiombed 4:1d3d071a4c2c 73 envTemperatureCharacteristic(SENS_TEMP_CHAR_UUID_128,envTemperature, TEMP_DATA_LEN, TEMP_DATA_LEN,
fabiombed 4:1d3d071a4c2c 74 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY),
fabiombed 4:1d3d071a4c2c 75 envHumidityCharacteristic(SENS_HUMI_CHAR_UUID_128, envHumidity, HUM_DATA_LEN, HUM_DATA_LEN,
fabiombed 4:1d3d071a4c2c 76 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY),
fabiombed 4:1d3d071a4c2c 77 envPressureCharacteristic(SENS_PRES_CHAR_UUID_128, envPressure, PRES_DATA_LEN, PRES_DATA_LEN,
fabiombed 4:1d3d071a4c2c 78 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY),
fabiombed 4:1d3d071a4c2c 79 envMagnetometerCharacteristic(SENS_MAGN_CHAR_UUID_128,envMagn, MAG_DATA_LEN, MAG_DATA_LEN,
fabiombed 4:1d3d071a4c2c 80 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY),
fabiombed 4:1d3d071a4c2c 81 envAccelerometerCharacteristic(SENS_ACCE_CHAR_UUID_128,envAcce, ACC_DATA_LEN, ACC_DATA_LEN,
fabiombed 4:1d3d071a4c2c 82 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY),
fabiombed 4:1d3d071a4c2c 83 envGyroCharacteristic(SENS_GYRO_CHAR_UUID_128,envGyro, GYRO_DATA_LEN, GYRO_DATA_LEN,
fabiombed 4:1d3d071a4c2c 84 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY),
fabiombed 4:1d3d071a4c2c 85 envAccGyroMagCharacteristic(SENS_ACC_GYRO_MAG_CHAR_UUID_128,envAccGyroMag, ACCGYROMAG_DATA_LEN, ACCGYROMAG_DATA_LEN,
fabiombed 4:1d3d071a4c2c 86 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY)
fabiombed 4:1d3d071a4c2c 87 {
fabiombed 4:1d3d071a4c2c 88
fabiombed 4:1d3d071a4c2c 89
fabiombed 4:1d3d071a4c2c 90
fabiombed 4:1d3d071a4c2c 91 static bool serviceAdded = false; /* We should only ever need to add the env service once. */
fabiombed 4:1d3d071a4c2c 92 if (serviceAdded) {
fabiombed 4:1d3d071a4c2c 93 return;
fabiombed 4:1d3d071a4c2c 94 }
fabiombed 4:1d3d071a4c2c 95
fabiombed 4:1d3d071a4c2c 96 GattCharacteristic *charTable[] = {&envTemperatureCharacteristic, &envHumidityCharacteristic, &envPressureCharacteristic, &envMagnetometerCharacteristic,
fabiombed 4:1d3d071a4c2c 97 &envAccelerometerCharacteristic, &envGyroCharacteristic, &envAccGyroMagCharacteristic};
fabiombed 4:1d3d071a4c2c 98
fabiombed 4:1d3d071a4c2c 99 GattService envService(SENS_SERVICE_UUID_128, charTable, sizeof(charTable) / sizeof(GattCharacteristic *));
fabiombed 4:1d3d071a4c2c 100
fabiombed 4:1d3d071a4c2c 101 ble.gattServer().addService(envService);
fabiombed 4:1d3d071a4c2c 102
fabiombed 4:1d3d071a4c2c 103 isEnabledTempNotify = false;
fabiombed 4:1d3d071a4c2c 104 isEnabledHumNotify = false;
fabiombed 4:1d3d071a4c2c 105 isEnabledPresNotify = false;
fabiombed 4:1d3d071a4c2c 106 isEnabledGyroNotify = false;
fabiombed 4:1d3d071a4c2c 107 isEnabledAccNotify = false;
fabiombed 4:1d3d071a4c2c 108 isEnabledMagNotify = false;
fabiombed 4:1d3d071a4c2c 109 isEnabledAccGyroMagNotify = false;
fabiombed 4:1d3d071a4c2c 110
fabiombed 4:1d3d071a4c2c 111 isTempCalibrated = false;
fabiombed 4:1d3d071a4c2c 112 isHumCalibrated = false;
fabiombed 4:1d3d071a4c2c 113 isPresCalibrated = false;
fabiombed 4:1d3d071a4c2c 114 isMagCalibrated = false;
fabiombed 4:1d3d071a4c2c 115 isAccCalibrated = false;
fabiombed 4:1d3d071a4c2c 116 isAGyroCalibrated = false;
fabiombed 4:1d3d071a4c2c 117
fabiombed 4:1d3d071a4c2c 118 memset (pastenvTemperature, 0, TEMP_DATA_LEN);
fabiombed 4:1d3d071a4c2c 119 memset (pastenvHumidity, 0, HUM_DATA_LEN);
fabiombed 4:1d3d071a4c2c 120 memset (pastenvPressure, 0, PRES_DATA_LEN);
fabiombed 4:1d3d071a4c2c 121
fabiombed 4:1d3d071a4c2c 122 isBTLEConnected = DISCONNECTED;
fabiombed 4:1d3d071a4c2c 123 serviceAdded = true;
fabiombed 4:1d3d071a4c2c 124 }
fabiombed 4:1d3d071a4c2c 125
fabiombed 4:1d3d071a4c2c 126 void sendEnvTemperature (int16_t Temp, uint16_t TimeStamp) {
fabiombed 4:1d3d071a4c2c 127 STORE_LE_16(envTemperature,TimeStamp);
fabiombed 4:1d3d071a4c2c 128 STORE_LE_16(envTemperature+2,Temp);
fabiombed 4:1d3d071a4c2c 129 PRINTF("sendEnvTemperature!! handle: %d\n\r", envTemperatureCharacteristic.getValueAttribute().getHandle());
fabiombed 4:1d3d071a4c2c 130 memcpy (pastenvTemperature, envTemperature, TEMP_DATA_LEN);
fabiombed 4:1d3d071a4c2c 131 ble.gattServer().write(envTemperatureCharacteristic.getValueAttribute().getHandle(), envTemperature, TEMP_DATA_LEN, 0);
fabiombed 4:1d3d071a4c2c 132 }
fabiombed 4:1d3d071a4c2c 133
fabiombed 4:1d3d071a4c2c 134 /**
fabiombed 4:1d3d071a4c2c 135 * Update the temperature with a new value. Valid values range from
fabiombed 4:1d3d071a4c2c 136 * 0..100. Anything outside this range will be ignored.
fabiombed 4:1d3d071a4c2c 137 * @param newLevel New level. */
fabiombed 4:1d3d071a4c2c 138 void updateEnvTemperature (int16_t Temp, uint16_t TimeStamp) {
fabiombed 4:1d3d071a4c2c 139 if (memcmp (&pastenvTemperature[2], &Temp, 2) != 0) {
fabiombed 4:1d3d071a4c2c 140 sendEnvTemperature (Temp, TimeStamp);
fabiombed 4:1d3d071a4c2c 141 }
fabiombed 4:1d3d071a4c2c 142 }
fabiombed 4:1d3d071a4c2c 143
fabiombed 4:1d3d071a4c2c 144 void sendEnvHumidity(uint16_t Hum, uint16_t TimeStamp) {
fabiombed 4:1d3d071a4c2c 145 STORE_LE_16(envHumidity,TimeStamp);
fabiombed 4:1d3d071a4c2c 146 STORE_LE_16(envHumidity+2,Hum);
fabiombed 4:1d3d071a4c2c 147 memcpy (pastenvHumidity, envHumidity, HUM_DATA_LEN);
fabiombed 4:1d3d071a4c2c 148 ble.gattServer().write(envHumidityCharacteristic.getValueAttribute().getHandle(), envHumidity, HUM_DATA_LEN, 0);
fabiombed 4:1d3d071a4c2c 149
fabiombed 4:1d3d071a4c2c 150 }
fabiombed 4:1d3d071a4c2c 151
fabiombed 4:1d3d071a4c2c 152 void updateEnvHumidity(uint16_t Hum, uint16_t TimeStamp) {
fabiombed 4:1d3d071a4c2c 153 if (memcmp (&pastenvHumidity[2], &Hum, 2) != 0) {
fabiombed 4:1d3d071a4c2c 154 sendEnvHumidity(Hum, TimeStamp);
fabiombed 4:1d3d071a4c2c 155 }
fabiombed 4:1d3d071a4c2c 156 }
fabiombed 4:1d3d071a4c2c 157
fabiombed 4:1d3d071a4c2c 158 void sendEnvPressure(uint32_t Press, uint16_t TimeStamp) {
fabiombed 4:1d3d071a4c2c 159 STORE_LE_16(envPressure,TimeStamp);
fabiombed 4:1d3d071a4c2c 160 STORE_LE_32(envPressure+2,Press);
fabiombed 4:1d3d071a4c2c 161 memcpy (pastenvPressure, envPressure, PRES_DATA_LEN);
fabiombed 4:1d3d071a4c2c 162 ble.gattServer().write(envPressureCharacteristic.getValueAttribute().getHandle(), envPressure, PRES_DATA_LEN, 0);
fabiombed 4:1d3d071a4c2c 163 }
fabiombed 4:1d3d071a4c2c 164
fabiombed 4:1d3d071a4c2c 165 void updateEnvPressure(uint32_t Press, uint16_t TimeStamp) {
fabiombed 4:1d3d071a4c2c 166 if (memcmp (&pastenvPressure[2], &Press, 2) != 0) {
fabiombed 4:1d3d071a4c2c 167 sendEnvPressure(Press, TimeStamp);
fabiombed 4:1d3d071a4c2c 168 }
fabiombed 4:1d3d071a4c2c 169 }
fabiombed 4:1d3d071a4c2c 170
fabiombed 4:1d3d071a4c2c 171 void sendEnvMagnetometer(AxesRaw_TypeDef *Magn, uint16_t TimeStamp, osxMFX_calibFactor magOffset) {
fabiombed 4:1d3d071a4c2c 172 STORE_LE_16(envMagn,TimeStamp);
fabiombed 4:1d3d071a4c2c 173 STORE_LE_16(envMagn+2,(Magn->AXIS_X - magOffset.magOffX));
fabiombed 4:1d3d071a4c2c 174 STORE_LE_16(envMagn+4,(Magn->AXIS_Y - magOffset.magOffY));
fabiombed 4:1d3d071a4c2c 175 STORE_LE_16(envMagn+6,(Magn->AXIS_Z - magOffset.magOffZ));
fabiombed 4:1d3d071a4c2c 176 ble.gattServer().write(envMagnetometerCharacteristic.getValueAttribute().getHandle(), envMagn, MAG_DATA_LEN, 0);
fabiombed 4:1d3d071a4c2c 177 }
fabiombed 4:1d3d071a4c2c 178
fabiombed 4:1d3d071a4c2c 179 void updateEnvMagnetometer(AxesRaw_TypeDef *Magn, uint16_t TimeStamp, osxMFX_calibFactor magOffset) {
fabiombed 4:1d3d071a4c2c 180 if (isMagNotificationEn()) sendEnvMagnetometer(Magn, TimeStamp, magOffset);
fabiombed 4:1d3d071a4c2c 181 }
fabiombed 4:1d3d071a4c2c 182
fabiombed 4:1d3d071a4c2c 183 void sendEnvAccelerometer (AxesRaw_TypeDef *Acc, uint16_t TimeStamp) {
fabiombed 4:1d3d071a4c2c 184 STORE_LE_16(envAcce,TimeStamp);
fabiombed 4:1d3d071a4c2c 185 STORE_LE_16(envAcce+2,Acc->AXIS_X);
fabiombed 4:1d3d071a4c2c 186 STORE_LE_16(envAcce+4,Acc->AXIS_Y);
fabiombed 4:1d3d071a4c2c 187 STORE_LE_16(envAcce+6,Acc->AXIS_Z);
fabiombed 4:1d3d071a4c2c 188 ble.gattServer().write(envAccelerometerCharacteristic.getValueAttribute().getHandle(), envAcce, ACC_DATA_LEN, 0);
fabiombed 4:1d3d071a4c2c 189 }
fabiombed 4:1d3d071a4c2c 190
fabiombed 4:1d3d071a4c2c 191 void updateEnvAccelerometer (AxesRaw_TypeDef *Acc, uint16_t TimeStamp) {
fabiombed 4:1d3d071a4c2c 192 if (isAccNotificationEn()) sendEnvAccelerometer (Acc, TimeStamp);
fabiombed 4:1d3d071a4c2c 193 }
fabiombed 4:1d3d071a4c2c 194
fabiombed 4:1d3d071a4c2c 195 void sendEnvGyroscope (AxesRaw_TypeDef *Gyro, uint16_t TimeStamp) {
fabiombed 4:1d3d071a4c2c 196 STORE_LE_16(envGyro,TimeStamp);
fabiombed 4:1d3d071a4c2c 197 STORE_LE_16(envGyro+2,Gyro->AXIS_X);
fabiombed 4:1d3d071a4c2c 198 STORE_LE_16(envGyro+4,Gyro->AXIS_Y);
fabiombed 4:1d3d071a4c2c 199 STORE_LE_16(envGyro+6,Gyro->AXIS_Z);
fabiombed 4:1d3d071a4c2c 200 ble.gattServer().write(envGyroCharacteristic.getValueAttribute().getHandle(), envGyro, GYRO_DATA_LEN, 0);
fabiombed 4:1d3d071a4c2c 201 }
fabiombed 4:1d3d071a4c2c 202
fabiombed 4:1d3d071a4c2c 203 void updateEnvGyroscope (AxesRaw_TypeDef *Gyro, uint16_t TimeStamp) {
fabiombed 4:1d3d071a4c2c 204 if (isGyroNotificationEn()) sendEnvGyroscope (Gyro, TimeStamp);
fabiombed 4:1d3d071a4c2c 205 }
fabiombed 4:1d3d071a4c2c 206
fabiombed 4:1d3d071a4c2c 207 void sendEnvAccGyroMag (AxesRaw_TypeDef *Acc, AxesRaw_TypeDef *Gyro, AxesRaw_TypeDef *Magn, uint16_t TimeStamp, osxMFX_calibFactor magOffset) {
fabiombed 4:1d3d071a4c2c 208 STORE_LE_16(envAccGyroMag,TimeStamp);
fabiombed 4:1d3d071a4c2c 209 STORE_LE_16(envAccGyroMag+2,Acc->AXIS_X);
fabiombed 4:1d3d071a4c2c 210 STORE_LE_16(envAccGyroMag+4,Acc->AXIS_Y);
fabiombed 4:1d3d071a4c2c 211 STORE_LE_16(envAccGyroMag+6,Acc->AXIS_Z);
fabiombed 4:1d3d071a4c2c 212
fabiombed 4:1d3d071a4c2c 213 STORE_LE_16(envAccGyroMag+8,Gyro->AXIS_X);
fabiombed 4:1d3d071a4c2c 214 STORE_LE_16(envAccGyroMag+10,Gyro->AXIS_Y);
fabiombed 4:1d3d071a4c2c 215 STORE_LE_16(envAccGyroMag+12,Gyro->AXIS_Z);
fabiombed 4:1d3d071a4c2c 216
fabiombed 4:1d3d071a4c2c 217 STORE_LE_16(envAccGyroMag+14,(Magn->AXIS_X - magOffset.magOffX));
fabiombed 4:1d3d071a4c2c 218 STORE_LE_16(envAccGyroMag+16,(Magn->AXIS_Y - magOffset.magOffY));
fabiombed 4:1d3d071a4c2c 219 STORE_LE_16(envAccGyroMag+18,(Magn->AXIS_Z - magOffset.magOffZ));
fabiombed 4:1d3d071a4c2c 220 ble.gattServer().write(envAccGyroMagCharacteristic.getValueAttribute().getHandle(), envAccGyroMag, ACCGYROMAG_DATA_LEN, 0);
fabiombed 4:1d3d071a4c2c 221 }
fabiombed 4:1d3d071a4c2c 222
fabiombed 4:1d3d071a4c2c 223 void updateEnvAccGyroMag (AxesRaw_TypeDef *Acc, AxesRaw_TypeDef *Gyro, AxesRaw_TypeDef *Magn, uint16_t TimeStamp, osxMFX_calibFactor magOffset) {
fabiombed 4:1d3d071a4c2c 224 if (isAccGyroMagNotificationEn())sendEnvAccGyroMag (Acc, Gyro, Magn, TimeStamp, magOffset);
fabiombed 4:1d3d071a4c2c 225 }
fabiombed 4:1d3d071a4c2c 226
fabiombed 4:1d3d071a4c2c 227 void enNotify (Gap::Handle_t handle) {
fabiombed 4:1d3d071a4c2c 228 if (isTempHandle(handle)) { isEnabledTempNotify = true; memset(pastenvTemperature,0,TEMP_DATA_LEN); return; }
fabiombed 4:1d3d071a4c2c 229 if (isHumHandle(handle)) { isEnabledHumNotify = true; memset(pastenvHumidity,0,HUM_DATA_LEN); return; }
fabiombed 4:1d3d071a4c2c 230 if (isPresHandle(handle)) { isEnabledPresNotify = true; memset(pastenvPressure,0,PRES_DATA_LEN); return; }
fabiombed 4:1d3d071a4c2c 231 if (isGyroHandle(handle)) { isEnabledGyroNotify = true; return; }
fabiombed 4:1d3d071a4c2c 232 if (isAccHandle(handle)) { isEnabledAccNotify = true; return; }
fabiombed 4:1d3d071a4c2c 233 if (isMagHandle(handle)) { isEnabledMagNotify = true; return; }
fabiombed 4:1d3d071a4c2c 234 if (isAccGyroMagHandle(handle)) { isEnabledAccGyroMagNotify = true; return; }
fabiombed 4:1d3d071a4c2c 235 }
fabiombed 4:1d3d071a4c2c 236
fabiombed 4:1d3d071a4c2c 237 void disNotify (Gap::Handle_t handle) {
fabiombed 4:1d3d071a4c2c 238 if (isTempHandle(handle)) { isEnabledTempNotify = false; memset(pastenvTemperature,0,TEMP_DATA_LEN); return; }
fabiombed 4:1d3d071a4c2c 239 if (isHumHandle(handle)) { isEnabledHumNotify = false; memset(pastenvHumidity,0,HUM_DATA_LEN); return; }
fabiombed 4:1d3d071a4c2c 240 if (isPresHandle(handle)) { isEnabledPresNotify = false; memset(pastenvPressure,0,PRES_DATA_LEN); return; }
fabiombed 4:1d3d071a4c2c 241 if (isGyroHandle(handle)) { isEnabledGyroNotify = false; return; }
fabiombed 4:1d3d071a4c2c 242 if (isAccHandle(handle)) { isEnabledAccNotify = false; return; }
fabiombed 4:1d3d071a4c2c 243 if (isMagHandle(handle)) { isEnabledMagNotify = false; return; }
fabiombed 4:1d3d071a4c2c 244 if (isAccGyroMagHandle(handle)) { isEnabledAccGyroMagNotify = false; return; }
fabiombed 4:1d3d071a4c2c 245 }
fabiombed 4:1d3d071a4c2c 246
fabiombed 4:1d3d071a4c2c 247 bool isTempNotificationEn (void) {
fabiombed 4:1d3d071a4c2c 248 return isEnabledTempNotify;
fabiombed 4:1d3d071a4c2c 249 }
fabiombed 4:1d3d071a4c2c 250
fabiombed 4:1d3d071a4c2c 251 bool isHumNotificationEn (void) {
fabiombed 4:1d3d071a4c2c 252 return isEnabledHumNotify;
fabiombed 4:1d3d071a4c2c 253 }
fabiombed 4:1d3d071a4c2c 254
fabiombed 4:1d3d071a4c2c 255 bool isPresNotificationEn (void) {
fabiombed 4:1d3d071a4c2c 256 return isEnabledPresNotify;
fabiombed 4:1d3d071a4c2c 257 }
fabiombed 4:1d3d071a4c2c 258
fabiombed 4:1d3d071a4c2c 259 bool isGyroNotificationEn (void) {
fabiombed 4:1d3d071a4c2c 260 return isEnabledGyroNotify;
fabiombed 4:1d3d071a4c2c 261 }
fabiombed 4:1d3d071a4c2c 262
fabiombed 4:1d3d071a4c2c 263 bool isAccNotificationEn (void) {
fabiombed 4:1d3d071a4c2c 264 return isEnabledAccNotify;
fabiombed 4:1d3d071a4c2c 265 }
fabiombed 4:1d3d071a4c2c 266
fabiombed 4:1d3d071a4c2c 267 bool isMagNotificationEn (void) {
fabiombed 4:1d3d071a4c2c 268 return isEnabledMagNotify;
fabiombed 4:1d3d071a4c2c 269 }
fabiombed 4:1d3d071a4c2c 270
fabiombed 4:1d3d071a4c2c 271 bool isAccGyroMagNotificationEn (void) {
fabiombed 4:1d3d071a4c2c 272 return isEnabledAccGyroMagNotify;
fabiombed 4:1d3d071a4c2c 273 }
fabiombed 4:1d3d071a4c2c 274
fabiombed 4:1d3d071a4c2c 275 bool isTempHandle (Gap::Handle_t handle) {
fabiombed 4:1d3d071a4c2c 276 if (handle == envTemperatureCharacteristic.getValueAttribute().getHandle()) return true;
fabiombed 4:1d3d071a4c2c 277 return false;
fabiombed 4:1d3d071a4c2c 278 }
fabiombed 4:1d3d071a4c2c 279
fabiombed 4:1d3d071a4c2c 280 bool isHumHandle (Gap::Handle_t handle) {
fabiombed 4:1d3d071a4c2c 281 if (handle == envHumidityCharacteristic.getValueAttribute().getHandle()) return true;
fabiombed 4:1d3d071a4c2c 282 return false;
fabiombed 4:1d3d071a4c2c 283 }
fabiombed 4:1d3d071a4c2c 284
fabiombed 4:1d3d071a4c2c 285 bool isPresHandle (Gap::Handle_t handle) {
fabiombed 4:1d3d071a4c2c 286 if (handle == envPressureCharacteristic.getValueAttribute().getHandle()) return true;
fabiombed 4:1d3d071a4c2c 287 return false;
fabiombed 4:1d3d071a4c2c 288 }
fabiombed 4:1d3d071a4c2c 289
fabiombed 4:1d3d071a4c2c 290 bool isMagHandle (Gap::Handle_t handle) {
fabiombed 4:1d3d071a4c2c 291 if (handle == envMagnetometerCharacteristic.getValueAttribute().getHandle()) return true;
fabiombed 4:1d3d071a4c2c 292 return false;
fabiombed 4:1d3d071a4c2c 293 }
fabiombed 4:1d3d071a4c2c 294 bool isAccHandle (Gap::Handle_t handle) {
fabiombed 4:1d3d071a4c2c 295 if (handle == envAccelerometerCharacteristic.getValueAttribute().getHandle()) return true;
fabiombed 4:1d3d071a4c2c 296 return false;
fabiombed 4:1d3d071a4c2c 297 }
fabiombed 4:1d3d071a4c2c 298 bool isGyroHandle (Gap::Handle_t handle) {
fabiombed 4:1d3d071a4c2c 299 if (handle == envGyroCharacteristic.getValueAttribute().getHandle()) return true;
fabiombed 4:1d3d071a4c2c 300 return false;
fabiombed 4:1d3d071a4c2c 301 }
fabiombed 4:1d3d071a4c2c 302 bool isAccGyroMagHandle (Gap::Handle_t handle) {
fabiombed 4:1d3d071a4c2c 303 if (handle == envAccGyroMagCharacteristic.getValueAttribute().getHandle()) return true;
fabiombed 4:1d3d071a4c2c 304 return false;
fabiombed 4:1d3d071a4c2c 305 }
fabiombed 4:1d3d071a4c2c 306
fabiombed 4:1d3d071a4c2c 307 void updateConnectionStatus(ConnectionStatus_t status) {
fabiombed 4:1d3d071a4c2c 308 isEnabledTempNotify = false;
fabiombed 4:1d3d071a4c2c 309 isEnabledHumNotify = false;
fabiombed 4:1d3d071a4c2c 310 isEnabledPresNotify = false;
fabiombed 4:1d3d071a4c2c 311 isEnabledGyroNotify = false;
fabiombed 4:1d3d071a4c2c 312 isEnabledAccNotify = false;
fabiombed 4:1d3d071a4c2c 313 isEnabledMagNotify = false;
fabiombed 4:1d3d071a4c2c 314 isEnabledAccGyroMagNotify = false;
fabiombed 4:1d3d071a4c2c 315
fabiombed 4:1d3d071a4c2c 316 isTempCalibrated = false;
fabiombed 4:1d3d071a4c2c 317 isHumCalibrated = false;
fabiombed 4:1d3d071a4c2c 318 isPresCalibrated = false;
fabiombed 4:1d3d071a4c2c 319 isMagCalibrated = false;
fabiombed 4:1d3d071a4c2c 320 isAccCalibrated = false;
fabiombed 4:1d3d071a4c2c 321 isAGyroCalibrated = false;
fabiombed 4:1d3d071a4c2c 322
fabiombed 4:1d3d071a4c2c 323 memset (pastenvTemperature, 0, TEMP_DATA_LEN);
fabiombed 4:1d3d071a4c2c 324 memset (pastenvHumidity, 0, HUM_DATA_LEN);
fabiombed 4:1d3d071a4c2c 325 memset (pastenvPressure, 0, PRES_DATA_LEN);
fabiombed 4:1d3d071a4c2c 326 isBTLEConnected = status;
fabiombed 4:1d3d071a4c2c 327 }
fabiombed 4:1d3d071a4c2c 328
fabiombed 4:1d3d071a4c2c 329
fabiombed 4:1d3d071a4c2c 330 private:
fabiombed 4:1d3d071a4c2c 331
fabiombed 4:1d3d071a4c2c 332 BLEDevice &ble;
fabiombed 4:1d3d071a4c2c 333 uint8_t envTemperature [TEMP_DATA_LEN]; /* in C */
fabiombed 4:1d3d071a4c2c 334 uint8_t pastenvTemperature [TEMP_DATA_LEN];
fabiombed 4:1d3d071a4c2c 335 uint8_t envHumidity [HUM_DATA_LEN]; /* in % */
fabiombed 4:1d3d071a4c2c 336 uint8_t pastenvHumidity [HUM_DATA_LEN];
fabiombed 4:1d3d071a4c2c 337 uint8_t envPressure [PRES_DATA_LEN]; /* in mBar */
fabiombed 4:1d3d071a4c2c 338 uint8_t pastenvPressure [PRES_DATA_LEN];
fabiombed 4:1d3d071a4c2c 339 uint8_t envMagn [MAG_DATA_LEN];
fabiombed 4:1d3d071a4c2c 340 uint8_t envGyro [GYRO_DATA_LEN];
fabiombed 4:1d3d071a4c2c 341 uint8_t envAcce [ACC_DATA_LEN];
fabiombed 4:1d3d071a4c2c 342 uint8_t envAccGyroMag [ACCGYROMAG_DATA_LEN];
fabiombed 4:1d3d071a4c2c 343
fabiombed 4:1d3d071a4c2c 344 GattCharacteristic envTemperatureCharacteristic;
fabiombed 4:1d3d071a4c2c 345 GattCharacteristic envHumidityCharacteristic;
fabiombed 4:1d3d071a4c2c 346 GattCharacteristic envPressureCharacteristic;
fabiombed 4:1d3d071a4c2c 347
fabiombed 4:1d3d071a4c2c 348 GattCharacteristic envMagnetometerCharacteristic;
fabiombed 4:1d3d071a4c2c 349 GattCharacteristic envAccelerometerCharacteristic;
fabiombed 4:1d3d071a4c2c 350 GattCharacteristic envGyroCharacteristic;
fabiombed 4:1d3d071a4c2c 351 GattCharacteristic envAccGyroMagCharacteristic;
fabiombed 4:1d3d071a4c2c 352
fabiombed 4:1d3d071a4c2c 353 ConnectionStatus_t isBTLEConnected;
fabiombed 4:1d3d071a4c2c 354
fabiombed 4:1d3d071a4c2c 355 bool isEnabledTempNotify;
fabiombed 4:1d3d071a4c2c 356 bool isEnabledHumNotify;
fabiombed 4:1d3d071a4c2c 357 bool isEnabledPresNotify;
fabiombed 4:1d3d071a4c2c 358 bool isEnabledGyroNotify;
fabiombed 4:1d3d071a4c2c 359 bool isEnabledAccNotify;
fabiombed 4:1d3d071a4c2c 360 bool isEnabledMagNotify;
fabiombed 4:1d3d071a4c2c 361 bool isEnabledAccGyroMagNotify;
fabiombed 4:1d3d071a4c2c 362
fabiombed 4:1d3d071a4c2c 363 bool isTempCalibrated;
fabiombed 4:1d3d071a4c2c 364 bool isHumCalibrated;
fabiombed 4:1d3d071a4c2c 365 bool isPresCalibrated;
fabiombed 4:1d3d071a4c2c 366 bool isMagCalibrated;
fabiombed 4:1d3d071a4c2c 367 bool isAccCalibrated;
fabiombed 4:1d3d071a4c2c 368 bool isAGyroCalibrated;
fabiombed 4:1d3d071a4c2c 369
fabiombed 4:1d3d071a4c2c 370 };
fabiombed 4:1d3d071a4c2c 371
fabiombed 4:1d3d071a4c2c 372 #endif /* #ifndef __CUSTOM_BLE_SENSORS_SERVICE_H__*/