diff --git a/README.md b/README.md
index 0e52285..1d6fe11 100644
--- a/README.md
+++ b/README.md
@@ -25,6 +25,11 @@ to SensiBLE and see sensors data. The data are also printed to the serial port.
X-NUCLEO-IKS01A2 or X-NUCLEO-IKS01A3, X-NUCLEO-IDB05A1 and X-NUCLEO-53L1A1 Expansion Boards. The application gather data from the sensor mounted and then communicates
them via bluetooth to a suitable Android app (such as ST BLE Sensor). The data gathered include enviromental data (temperature, pression, humidity),
distance, gesture recognition (tap and directional swipe), acceleration (with accelerometer hardware events) and a gyroscope.
+* Flight2: This application provides an example of usage of a NUCLEO board (it was tested with NUCLEO-F401RE) with
+X-NUCLEO-IKS01A3, X-NUCLEO-IDB05A2 and X-NUCLEO-53L1A1 Expansion Boards. The application gathers data from the sensors mounted and then communicates
+them via bluetooth to a suitable Android or iOS app (such as ST BLE Sensor). The data gathered include enviromental data (temperature, pression, humidity),
+distance, gesture recognition (tap and directional swipe), acceleration (with accelerometer hardware events), a gyroscope and a magnetometer. Note that
+unlike the Flight1 application, this one makes use of the STM32duinoBLE API instead of SPBTLE-RF, and does not support X-NUCLEO-IKS01A2 boards. In addition, an up-to-date version of the STM32duinoBLE library is required, as this application uses some of the newest features.
* IKS01A3_S2LP_P2P_Demo: This application provides a simple example of usage of two NUCLEO boards (it was tested with NUCLEO-F401RE and NUCLEO-L053R8)
with a X-NUCLEO-IKS01A3 and one among X-NUCLEO-S2868A1, X-NUCLEO-S2868A2 and X-NUCLEO-S2915A1. It shows how to send and receive all the sensor data
provided by the X-NUCLEO-IKS01A3 between two NUCLEO boards connected each other through S2-LP based Expansion Boards; in order to send the sensor data
@@ -60,6 +65,7 @@ The FP_Examples library requires the following STM32duino libraries (link to the
* STM32duino S2-LP: https://github.com/stm32duino/S2-LP
* STM32duino M95640-R: https://github.com/stm32duino/M95640-R
* STM32duino X-NUCLEO-IKS02A1 Audio: https://github.com/stm32duino/X-NUCLEO-IKS02A1-Audio
+* STM32duinoBLE: https://github.com/stm32duino/STM32duinoBLE
## Documentation
diff --git a/examples/Flight2/Flight2.ino b/examples/Flight2/Flight2.ino
new file mode 100644
index 0000000..ae00baa
--- /dev/null
+++ b/examples/Flight2/Flight2.ino
@@ -0,0 +1,920 @@
+/**
+ ******************************************************************************
+ @file Flight2.ino
+ @author STMicroelectronics
+ @version V1.0.0
+ @date 15 March 2023
+ @brief Arduino demo application for the STMicrolectronics
+ X-NUCLEO-IKS01A3, X-NUCLEO-53L1A1
+ and X-NUCLEO-IDB05A1
+ ******************************************************************************
+ @attention
+
+
© COPYRIGHT(c) 2023 STMicroelectronics
+
+ Redistribution and use in source and binary forms, with or without modification,
+ are permitted provided that the following conditions are met:
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ 3. Neither the name of STMicroelectronics nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ ******************************************************************************
+*/
+
+// Note: make sure your STM32duinoBLE is updated to the latest version!
+
+// Includes ------------------------------------------------------------------
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+#define DEV_I2C Wire
+#define SerialPort Serial
+
+//#define DEBUG_MODE
+
+#define INT_1 4
+#define INT_2 5
+
+// BLE boards
+#if defined(ARDUINO_STEVAL_MKBOXPRO)
+/* STEVAL-MKBOXPRO */
+SPIClass SpiHCI(PA7, PA6, PA5);
+HCISpiTransportClass HCISpiTransport(SpiHCI, BLUENRG_LP, PA2, PB11, PD4, 1000000, SPI_MODE3);
+#if !defined(FAKE_BLELOCALDEVICE)
+BLELocalDevice BLEObj(&HCISpiTransport);
+BLELocalDevice &BLE = BLEObj;
+#endif
+#elif defined(ARDUINO_STEVAL_MKSBOX1V1)
+/* STEVAL-MKSBOX1V1 */
+SPIClass SpiHCI(PC3, PD3, PD1);
+HCISpiTransportClass HCISpiTransport(SpiHCI, SPBTLE_1S, PD0, PD4, PA8, 1000000, SPI_MODE1);
+#if !defined(FAKE_BLELOCALDEVICE)
+BLELocalDevice BLEObj(&HCISpiTransport);
+BLELocalDevice &BLE = BLEObj;
+#endif
+#elif defined(ARDUINO_B_L475E_IOT01A) || defined(ARDUINO_B_L4S5I_IOT01A)
+/* B-L475E-IOT01A1 or B_L4S5I_IOT01A */
+SPIClass SpiHCI(PC12, PC11, PC10);
+HCISpiTransportClass HCISpiTransport(SpiHCI, SPBTLE_RF, PD13, PE6, PA8, 8000000, SPI_MODE0);
+#if !defined(FAKE_BLELOCALDEVICE)
+BLELocalDevice BLEObj(&HCISpiTransport);
+BLELocalDevice &BLE = BLEObj;
+#endif
+#elif defined(ARDUINO_NUCLEO_WB15CC) || defined(ARDUINO_P_NUCLEO_WB55RG) || defined(ARDUINO_STM32WB5MM_DK)
+HCISharedMemTransportClass HCISharedMemTransport;
+#if !defined(FAKE_BLELOCALDEVICE)
+BLELocalDevice BLEObj(&HCISharedMemTransport);
+BLELocalDevice &BLE = BLEObj;
+#endif
+#else
+/* Shield IDB05A2 with SPI clock on D3 */
+SPIClass SpiHCI(D11, D12, D3);
+HCISpiTransportClass HCISpiTransport(SpiHCI, BLUENRG_M0, A1, A0, D7, 8000000, SPI_MODE0);
+#if !defined(FAKE_BLELOCALDEVICE)
+BLELocalDevice BLEObj(&HCISpiTransport);
+BLELocalDevice &BLE = BLEObj;
+#endif
+/* Shield IDB05A2 with SPI clock on D13 */
+// #define SpiHCI SPI
+// HCISpiTransportClass HCISpiTransport(SpiHCI, BLUENRG_M0, A1, A0, D7, 8000000, SPI_MODE0);
+// #if !defined(FAKE_BLELOCALDEVICE)
+// BLELocalDevice BLEObj(&HCISpiTransport);
+// BLELocalDevice& BLE = BLEObj;
+// #endif
+/* Shield IDB05A1 with SPI clock on D3 */
+// SPIClass SpiHCI(D11, D12, D3);
+// HCISpiTransportClass HCISpiTransport(SpiHCI, SPBTLE_RF, A1, A0, D7, 8000000, SPI_MODE0);
+// #if !defined(FAKE_BLELOCALDEVICE)
+// BLELocalDevice BLEObj(&HCISpiTransport);
+// BLELocalDevice& BLE = BLEObj;
+// #endif
+/* Shield IDB05A1 with SPI clock on D13 */
+// #define SpiHCI SPI
+// HCISpiTransportClass HCISpiTransport(SpiHCI, SPBTLE_RF, A1, A0, D7, 8000000, SPI_MODE0);
+// #if !defined(FAKE_BLELOCALDEVICE)
+// BLELocalDevice BLEObj(&HCISpiTransport);
+// BLELocalDevice& BLE = BLEObj;
+// #endif
+/* Shield BNRG2A1 with SPI clock on D3 */
+// SPIClass SpiHCI(D11, D12, D3);
+// HCISpiTransportClass HCISpiTransport(SpiHCI, BLUENRG_M2SP, A1, A0, D7, 1000000, SPI_MODE1);
+// #if !defined(FAKE_BLELOCALDEVICE)
+// BLELocalDevice BLEObj(&HCISpiTransport);
+// BLELocalDevice& BLE = BLEObj;
+// #endif
+/* Shield BNRG2A1 with SPI clock on D13 */
+// #define SpiHCI SPI
+// HCISpiTransportClass HCISpiTransport(SpiHCI, BLUENRG_M2SP, A1, A0, D7, 1000000, SPI_MODE1);
+// #if !defined(FAKE_BLELOCALDEVICE)
+// BLELocalDevice BLEObj(&HCISpiTransport);
+// BLELocalDevice& BLE = BLEObj;
+// #endif
+#endif
+
+// Interrupts
+volatile int mems_event = 0;
+
+// Package Version only numbers 0->9
+#define FLIGHT1_VERSION_MAJOR '5'
+#define FLIGHT1_VERSION_MINOR '0'
+#define FLIGHT1_VERSION_PATCH '0'
+
+#ifdef DEBUG_MODE
+#define FLIGHT1_PRINTF(...) \
+ do {\
+ char report[130];\
+ snprintf(report, sizeof(report), __VA_ARGS__);\
+ SerialPort.print(report);\
+ } while(0);
+#else
+#define FLIGHT1_PRINTF(...) while(0){;}
+#endif
+// Define the FLIGHT1 Name MUST be 7 char long
+#define NAME_FLIGHT1 'F','L','2','V',FLIGHT1_VERSION_MAJOR,FLIGHT1_VERSION_MINOR,FLIGHT1_VERSION_PATCH
+
+// SPI Configuration
+#define IDB0XA1_PIN_SPI_MOSI (11)
+#define IDB0XA1_PIN_SPI_MISO (12)
+#define IDB0XA1_PIN_SPI_SCK (3)
+
+#define IDB0XA1_PIN_SPI_nCS (A1)
+#define IDB0XA1_PIN_SPI_RESET (7)
+#define IDB0XA1_PIN_SPI_IRQ (A0)
+
+#define STORE_LE_16(buf, val) ( ((buf)[0] = (uint8_t) (val) ) , \
+ ((buf)[1] = (uint8_t) (val>>8) ) )
+
+#define STORE_LE_32(buf, val) ( ((buf)[0] = (uint8_t) (val) ) , \
+ ((buf)[1] = (uint8_t) (val>>8) ) , \
+ ((buf)[2] = (uint8_t) (val>>16) ) , \
+ ((buf)[3] = (uint8_t) (val>>24) ) )
+
+#define STORE_BE_32(buf, val) ( ((buf)[3] = (uint8_t) (val) ) , \
+ ((buf)[2] = (uint8_t) (val>>8) ) , \
+ ((buf)[1] = (uint8_t) (val>>16) ) , \
+ ((buf)[0] = (uint8_t) (val>>24) ) )
+
+// Macros for conversion from float to int
+#define MCR_BLUEMS_F2I_1D(in, out_int, out_dec) {out_int = (int32_t)in; out_dec= (int32_t)((in-out_int)*10);};
+#define MCR_BLUEMS_F2I_2D(in, out_int, out_dec) {out_int = (int32_t)in; out_dec= (int32_t)((in-out_int)*100);};
+
+#define FEATURE_MASK_ACC_EVENTS 0x00000400u
+
+// Distance components
+STMPE1600DigiOut *xshutdown_top;
+STMPE1600DigiOut *xshutdown_left;
+STMPE1600DigiOut *xshutdown_right;
+VL53L1X_X_NUCLEO_53L1A1 *sensor_vl53l1_top;
+VL53L1X_X_NUCLEO_53L1A1 *sensor_vl53l1_left;
+VL53L1X_X_NUCLEO_53L1A1 *sensor_vl53l1_right;
+
+
+// Gesture structure
+Gesture_DIRSWIPE_1_Data_t gestureDirSwipeData;
+Gesture_TAP_1_Data_t gestureTapData;
+// Range values
+uint16_t distance_top, distance_left, distance_right;
+
+// MEMS sensors
+HTS221Sensor *HumTemp;
+LPS22HHSensor *PressTemp;
+LSM6DSOSensor *AccGyr;
+LIS2DW12Sensor *Acc2;
+LIS2MDLSensor *Mag;
+STTS751Sensor *Temp;
+
+// STRING UUIDs
+char *uuidSensorService = "00000000-0001-11e1-9ab4-0002a5d5c51b";
+char *uuidConfigService = "00000000-000f-11e1-9ab4-0002a5d5c51b";
+char *uuidPressChar = "00100000-0001-11e1-ac36-0002a5d5c51b";
+char *uuidHumChar = "00080000-0001-11e1-ac36-0002a5d5c51b";
+char *uuidTempChar = "00040000-0001-11e1-ac36-0002a5d5c51b";
+char *uuidAccChar = "00800000-0001-11e1-ac36-0002a5d5c51b";
+char *uuidGyroChar = "00400000-0001-11e1-ac36-0002a5d5c51b";
+char *uuidMagChar = "00200000-0001-11e1-ac36-0002a5d5c51b";
+char *uuidProxChar = "02000000-0001-11e1-ac36-0002a5d5c51b";
+char *uuidGestureChar = "00000004-0001-11e1-ac36-0002a5d5c51b";
+char *uuidAccEventChar = "00000400-0001-11e1-ac36-0002a5d5c51b";
+char *uuidConfigChar = "00000002-000f-11e1-ac36-0002a5d5c51b";
+
+#define LEN_DISTANCE 4
+#define LEN_GESTURE 3
+#define LEN_MAG 8
+#define LEN_GYRO 8
+#define LEN_ACC 8
+#define LEN_ACCEVENT 5 // This might become 3 or 4, make sure to check!
+#define LEN_PRESS 6
+#define LEN_HUM 4
+#define LEN_TEMP 4
+#define LEN_CFG 20
+
+// ABLE services and characteristics
+BLEService sensorService(uuidSensorService);
+BLEService configService(uuidConfigService);
+
+BLECharacteristic distanceC(uuidProxChar, BLERead | BLENotify, LEN_DISTANCE);
+BLECharacteristic gestureC(uuidGestureChar, BLERead | BLENotify, LEN_GESTURE);
+
+BLECharacteristic pressC(uuidPressChar, BLERead | BLENotify, LEN_PRESS);
+BLECharacteristic humC(uuidHumChar, BLERead | BLENotify, LEN_HUM);
+BLECharacteristic tempC(uuidTempChar, BLERead | BLENotify, LEN_TEMP);
+
+BLECharacteristic accC(uuidAccChar, BLERead | BLENotify, LEN_ACC);
+BLECharacteristic accEventC(uuidAccEventChar, BLERead | BLENotify, LEN_ACCEVENT);
+BLECharacteristic gyroC(uuidGyroChar, BLERead | BLENotify, LEN_GYRO);
+BLECharacteristic magC(uuidMagChar, BLERead | BLENotify, LEN_MAG);
+
+BLECharacteristic configC(uuidConfigChar, BLENotify | BLEWrite, LEN_CFG);
+
+// Class for bluetooth communication and services
+class Flight1Service {
+ public:
+
+ uint16_t globalSteps = 0;
+ boolean shortMode = false;
+
+ Flight1Service(void)
+ {
+ }
+
+ // Initializes the sensor with the default params
+ int begin()
+ {
+ const char BoardName[8] = {NAME_FLIGHT1, 0};
+ int ret;
+ ret = BLE.begin();
+
+ BLE.setLocalName(BoardName);
+ BLE.setAdvertisedService(sensorService);
+
+ uint8_t addr[6] = {0xff};
+ BLE.getRandomAddress(addr);
+
+#define FEATURE_MASK 0x02,0xfc,0x04,0x15
+
+ uint8_t data [14] = {0x0d, 0xff, 0x01, 0x80, FEATURE_MASK};
+
+ data[8] = addr[5];
+ data[9] = addr[4];
+ data[10] = addr[3];
+ data[11] = addr[2];
+ data[12] = addr[1];
+ data[13] = addr[0];
+
+ BLEAdvertisingData adv;
+ adv.setRawData(data, 14);
+ BLE.setAdvertisingData(adv);
+
+ BLE.advertise();
+
+ Add_HWServW2ST_Service();
+
+ return ret;
+ }
+
+ // Update enviromental data
+ int Environmental_Update(int32_t Press, uint16_t Hum, int16_t Temp)
+ {
+ uint8_t pBuff[LEN_PRESS];
+ uint8_t hBuff[LEN_HUM];
+ uint8_t tBuff[LEN_TEMP];
+
+ STORE_LE_16(pBuff, millis());
+ STORE_LE_32(pBuff + 2, (Press));
+
+ STORE_LE_16(hBuff, millis());
+ STORE_LE_16(hBuff + 2, (Hum));
+
+ STORE_LE_16(tBuff, millis());
+ STORE_LE_16(tBuff + 2, (Temp));
+
+ int ret = 0;
+ ret += pressC.writeValue(pBuff, LEN_PRESS);
+ ret += humC.writeValue(hBuff, LEN_HUM);
+ ret += tempC.writeValue(tBuff, LEN_TEMP);
+
+ return ret; // Should be 3 (true) on return
+ }
+
+ //Update the proximity sensor distance
+ int FlightSense_Distance_Update(uint16_t Distance)
+ {
+ uint8_t buff[LEN_DISTANCE];
+
+ /* To discriminate the long proximity range from 53L1A1*/
+ //Distance= Distance | (1 << 15);
+
+ STORE_LE_16(buff, millis());
+ STORE_LE_16(buff + 2, Distance);
+
+ int err = 0;
+ err += distanceC.writeValue(buff, LEN_DISTANCE);
+
+ return err;
+ }
+
+ // Update the accelerometer and gyroscope
+ // Order of axes: X, Y, Z
+ int AccGyroMag_Update(int32_t *Accel, int32_t *Gyros, int32_t *Mag)
+ {
+ int32_t AXIS_X;
+ int32_t AXIS_Y;
+ int32_t AXIS_Z;
+
+ uint8_t buff[2 + 3 * 2 * 2];
+
+ uint8_t aBuff[LEN_ACC];
+ uint8_t gBuff[LEN_GYRO];
+ uint8_t mBuff[LEN_MAG];
+
+ STORE_LE_16(aBuff, millis());
+ STORE_LE_16(aBuff + 2, Accel[0]);
+ STORE_LE_16(aBuff + 4, Accel[1]);
+ STORE_LE_16(aBuff + 6, Accel[2]);
+
+ STORE_LE_16(mBuff, millis());
+ STORE_LE_16(mBuff + 2, Mag[0]);
+ STORE_LE_16(mBuff + 4, Mag[1]);
+ STORE_LE_16(mBuff + 6, Mag[2]);
+
+ AXIS_X = (Gyros[0]) * 10;
+ AXIS_Y = (Gyros[1]) * 10;
+ AXIS_Z = (Gyros[2]) * 10;
+
+ STORE_LE_16(gBuff, millis());
+ STORE_LE_16(gBuff + 2, AXIS_X);
+ STORE_LE_16(gBuff + 4, AXIS_Y);
+ STORE_LE_16(gBuff + 6, AXIS_Z);
+
+ int ret = 0;
+ ret += gyroC.writeValue(gBuff, LEN_GYRO);
+ ret += accC.writeValue(aBuff, LEN_ACC);
+ ret += magC.writeValue(mBuff, LEN_MAG);
+
+ return ret;
+ }
+
+ // Update the gesture recognition
+ int Gestures_Update(uint8_t gest_code)
+ {
+ uint8_t buff[LEN_GESTURE];
+
+ STORE_LE_16(buff, millis());
+ buff[2] = gest_code;
+
+ int ret = 0;
+ ret += gestureC.writeValue(buff, LEN_GESTURE);
+
+ return ret;
+ }
+
+ int AccEvent_Notify(uint16_t steps, uint8_t event)
+ {
+ uint8_t buff_2[2 + 1]; // Only event
+ uint8_t buff_3[2 + 2]; // Only pedometer
+ uint8_t buff_4[5]; // Event and pedometer
+
+ int ret = 0;
+
+ if (shortMode) {
+ STORE_LE_16(buff_4, millis());
+ buff_2[2] = event;
+ ret += accEventC.writeValue(buff_2, 2 + 1);
+ } else {
+ STORE_LE_16(buff_4, millis());
+ buff_4[2] = event;
+ STORE_LE_16(buff_4 + 3, steps);
+ ret += accEventC.writeValue(buff_4, LEN_ACCEVENT);
+ }
+ return ret;
+ }
+
+ int Config_Notify(uint8_t Feature [4], uint8_t Command, uint8_t data)
+ {
+ uint8_t buff[2 + 4 + 1 + 1];
+ int ret = 0;
+
+ STORE_LE_16(buff, millis());
+ buff[2] = Feature[0];
+ buff[3] = Feature[1];
+ buff[4] = Feature[2];
+ buff[5] = Feature[3];
+ buff[6] = Command;
+ buff[7] = data;
+
+ ret = configC.writeValue(buff, 2 + 4 + 1 + 1);
+
+ return ret;
+ }
+
+ private:
+
+ // Add the services
+ void Add_HWServW2ST_Service(void)
+ {
+ sensorService.addCharacteristic(gestureC);
+ sensorService.addCharacteristic(distanceC);
+ sensorService.addCharacteristic(pressC);
+ sensorService.addCharacteristic(humC);
+ sensorService.addCharacteristic(tempC);
+ sensorService.addCharacteristic(accC);
+ sensorService.addCharacteristic(accEventC);
+ sensorService.addCharacteristic(gyroC);
+ sensorService.addCharacteristic(magC);
+
+ configService.addCharacteristic(configC);
+
+ BLE.addService(sensorService);
+ BLE.addService(configService);
+
+ return;
+ }
+};
+
+Flight1Service Flight1;
+
+void enableAllFunc()
+{
+ AccGyr->Enable_Pedometer();
+ AccGyr->Enable_Tilt_Detection(LSM6DSO_INT1_PIN);
+ AccGyr->Enable_Free_Fall_Detection(LSM6DSO_INT1_PIN);
+ AccGyr->Enable_Single_Tap_Detection(LSM6DSO_INT1_PIN);
+ AccGyr->Enable_Double_Tap_Detection(LSM6DSO_INT1_PIN);
+ AccGyr->Enable_6D_Orientation(LSM6DSO_INT1_PIN);
+ AccGyr->Step_Counter_Reset();
+}
+
+void disableAllFunc()
+{
+ AccGyr->Disable_Pedometer();
+ AccGyr->Disable_Tilt_Detection();
+ AccGyr->Disable_Free_Fall_Detection();
+ AccGyr->Disable_Single_Tap_Detection();
+ AccGyr->Disable_Double_Tap_Detection();
+ AccGyr->Disable_6D_Orientation();
+}
+
+// Setup distance sensors for gesture detection
+void SetupSingleShot(VL53L1X_X_NUCLEO_53L1A1 *sensor)
+{
+ int status;
+
+ //Change distance mode to short range
+ status = sensor->VL53L1X_SetDistanceMode(1);
+ if (status) {
+ SerialPort.println("SetDistanceMode failed");
+ }
+
+ //Change timing budget to 20 ms
+ status = sensor->VL53L1X_SetTimingBudgetInMs(20);
+ if (status) {
+ SerialPort.println("SetMeasurementTimingBudgetMicroSeconds failed");
+ }
+ status = sensor->VL53L1X_SetInterMeasurementInMs(20);
+ if (status) {
+ SerialPort.println("SetInterMeasurementPeriodMilliSeconds failed");
+ }
+
+}
+
+void INT1Event_cb()
+{
+ mems_event = 1;
+}
+
+void INT2Event_cb()
+{
+ mems_event = 1;
+}
+
+
+
+void configCB(BLEDevice unused1, BLECharacteristic unused2)
+{
+ uint8_t buf[LEN_CFG];
+
+ configC.readValue(buf, LEN_CFG);
+ char command = buf[4];
+ uint8_t data = buf[5];
+ uint8_t signalEvents [4] = {0x00, 0x00, 0x04, 0x00};
+
+ if (!memcmp(buf, signalEvents, 4) && data) {
+ enableAllFunc();
+ switch (command) {
+ case 'o':
+ Flight1.shortMode = true;
+ break;
+ default:
+ Flight1.shortMode = false;
+ break;
+ }
+ } else {
+ disableAllFunc();
+ }
+
+ // Either way, respond by repeating the command
+ uint8_t feature [4] = {0x00};
+ memcpy(feature, buf, 4);
+ Flight1.Config_Notify(feature, buf[4], buf[5]);
+}
+
+int gestureGuard = 0;
+
+bool envEnable = false;
+bool proxEnable = false;
+bool eventEnable = false;
+bool accEnable = false;
+bool gyroEnable = false;
+bool magEnable = false;
+
+void setup()
+{
+ SerialPort.begin(115200);
+ DEV_I2C.begin();
+
+ pinMode(LED_BUILTIN, OUTPUT); //D13 LED
+
+ //Interrupts.
+ attachInterrupt(INT_1, INT1Event_cb, RISING);
+ attachInterrupt(INT_2, INT2Event_cb, RISING);
+
+ if (!Flight1.begin()) {
+ SerialPort.println("Bluetooth services configuration error!");
+ while (1);
+ }
+ SerialPort.println("Bluetooth configuration done!");
+
+ // Create VL53L1X top component.
+ xshutdown_top = new STMPE1600DigiOut(&DEV_I2C, GPIO_15, (0x42 * 2));
+ sensor_vl53l1_top = new VL53L1X_X_NUCLEO_53L1A1(&DEV_I2C, xshutdown_top);
+ sensor_vl53l1_top->begin();
+
+ // Switch off VL53L1X top component.
+ sensor_vl53l1_top->VL53L1X_Off();
+
+ // Create (if present) VL53L1X left component.
+ xshutdown_left = new STMPE1600DigiOut(&DEV_I2C, GPIO_14, (0x43 * 2));
+ sensor_vl53l1_left = new VL53L1X_X_NUCLEO_53L1A1(&DEV_I2C, xshutdown_left);
+ sensor_vl53l1_left->begin();
+
+ //Switch off (if present) VL53L1X left component.
+ sensor_vl53l1_left->VL53L1X_Off();
+
+ // Create (if present) VL53L1X right component.
+ xshutdown_right = new STMPE1600DigiOut(&DEV_I2C, GPIO_15, (0x43 * 2));
+ sensor_vl53l1_right = new VL53L1X_X_NUCLEO_53L1A1(&DEV_I2C, xshutdown_right);
+ sensor_vl53l1_right->begin();
+
+ // Switch off (if present) VL53L1X right component.
+ sensor_vl53l1_right->VL53L1X_Off();
+
+ //Initialize the sensor
+ sensor_vl53l1_top->InitSensor(0x10);
+ sensor_vl53l1_left->InitSensor(0x12);
+ sensor_vl53l1_right->InitSensor(0x14);
+
+ //Change Distance mode and timings
+ SetupSingleShot(sensor_vl53l1_top);
+ SetupSingleShot(sensor_vl53l1_left);
+ SetupSingleShot(sensor_vl53l1_right);
+
+
+ //Top sensor should be in long distance mode
+ sensor_vl53l1_top->VL53L1X_SetDistanceMode(2);
+
+ // Initialize VL53L1X gesture library.
+ tof_gestures_initDIRSWIPE_1(400, 0, 500, &gestureDirSwipeData);
+ tof_gestures_initTAP_1(&gestureTapData);
+
+ //Start measurement
+ sensor_vl53l1_top->VL53L1X_StartRanging();
+ sensor_vl53l1_left->VL53L1X_StartRanging();
+ sensor_vl53l1_right->VL53L1X_StartRanging();
+
+ //Setup MEMS sensors
+ HumTemp = new HTS221Sensor(&DEV_I2C);
+ PressTemp = new LPS22HHSensor(&DEV_I2C);
+ AccGyr = new LSM6DSOSensor(&DEV_I2C);
+ Acc2 = new LIS2DW12Sensor(&DEV_I2C);
+ Mag = new LIS2MDLSensor(&DEV_I2C);
+ Temp = new STTS751Sensor(&DEV_I2C);
+ Temp->begin();
+ Temp->Enable();
+ Acc2->begin();
+ Acc2->Enable_X();
+ HumTemp->begin();
+ HumTemp->Enable();
+ PressTemp->begin();
+ PressTemp->Enable();
+ AccGyr->begin();
+ AccGyr->Enable_X();
+ AccGyr->Set_X_ODR(4.0f);
+ AccGyr->Enable_G();
+ Mag->begin();
+ Mag->Enable();
+
+ configC.setEventHandler(BLEWritten, configCB);
+}
+
+void loop()
+{
+
+ int status;
+ uint8_t ready = 0;
+ uint16_t distance;
+ int32_t decPart, intPart;
+ int32_t PressToSend = 0;
+ uint16_t HumToSend = 0;
+ int16_t TempToSend = 0;
+ int gesture_code;
+ int left_done = 0;
+ int right_done = 0;
+ uint8_t NewDataReady = 0;
+ uint8_t RangeStatus;
+
+ BLE.poll();
+
+ envEnable = pressC.subscribed() || tempC.subscribed() || humC.subscribed();
+ accEnable = accC.subscribed();
+ gyroEnable = gyroC.subscribed();
+ magEnable = magC.subscribed();
+ eventEnable = accEventC.subscribed();
+ proxEnable = distanceC.subscribed() || gestureC.subscribed();
+
+ if (envEnable) {
+ //Get enviroment data
+ float humidity, temperature, pressure;
+ HumTemp->GetHumidity(&humidity);
+ Temp->GetTemperature(&temperature);
+ PressTemp->GetPressure(&pressure);
+ MCR_BLUEMS_F2I_2D(pressure, intPart, decPart);
+ PressToSend = intPart * 100 + decPart;
+ MCR_BLUEMS_F2I_1D(humidity, intPart, decPart);
+ HumToSend = intPart * 10 + decPart;
+ MCR_BLUEMS_F2I_1D(temperature, intPart, decPart);
+ TempToSend = intPart * 10 + decPart;
+ }
+
+ int32_t accelerometer[3];
+ int32_t gyroscope[3];
+ int32_t magnetometer[3];
+
+ if (accEnable) {
+ // Read accelerometer
+ AccGyr->Get_X_Axes(accelerometer);
+ }
+ if (gyroEnable) {
+ // Read gyroscope
+ AccGyr->Get_G_Axes(gyroscope);
+ }
+ if (magEnable) {
+ // Read magnetometer
+ Mag->GetAxes(magnetometer);
+ }
+
+ if (mems_event) {
+ mems_event = 0;
+ LSM6DSO_Event_Status_t Astatus;
+ AccGyr->Get_X_Event_Status(&Astatus);
+ uint8_t stat = 0;
+
+ if (Astatus.StepStatus) {
+ uint16_t step_count = 0;
+ AccGyr->Get_Step_Count(&step_count);
+ FLIGHT1_PRINTF("Step %d\n", step_count);
+
+ Flight1.globalSteps = step_count;
+ }
+ if (Astatus.FreeFallStatus) {
+ FLIGHT1_PRINTF("Free fall\n");
+ stat = stat | 0x10u;
+ }
+
+ if (Astatus.TapStatus) {
+ FLIGHT1_PRINTF("Single tap\n");
+ stat = stat | 0x20u;
+ }
+
+ if (Astatus.DoubleTapStatus) {
+ FLIGHT1_PRINTF("Double tap\n");
+ stat = stat | 0x40u;
+ }
+
+ if (Astatus.TiltStatus) {
+ FLIGHT1_PRINTF("Tilt\n");
+ stat = stat | 0x08u;
+ }
+
+ if (Astatus.D6DOrientationStatus) {
+ FLIGHT1_PRINTF("6D Interrupt\n");
+ uint8_t xl = 0;
+ uint8_t xh = 0;
+ uint8_t yl = 0;
+ uint8_t yh = 0;
+ uint8_t zl = 0;
+ uint8_t zh = 0;
+ uint8_t OrientationResult = 0;
+ AccGyr->Get_6D_Orientation_XL(&xl);
+ AccGyr->Get_6D_Orientation_XH(&xh);
+ AccGyr->Get_6D_Orientation_YL(&yl);
+ AccGyr->Get_6D_Orientation_YH(&yh);
+ AccGyr->Get_6D_Orientation_ZL(&zl);
+ AccGyr->Get_6D_Orientation_ZH(&zh);
+ if (xl == 0 && yl == 0 && zl == 0 && xh == 0 && yh == 1 && zh == 0) {
+ OrientationResult = 0x04u;
+ } else if (xl == 1 && yl == 0 && zl == 0 && xh == 0 && yh == 0 && zh == 0) {
+ OrientationResult = 0x01u;
+ } else if (xl == 0 && yl == 0 && zl == 0 && xh == 1 && yh == 0 && zh == 0) {
+ OrientationResult = 0x03u;
+ } else if (xl == 0 && yl == 1 && zl == 0 && xh == 0 && yh == 0 && zh == 0) {
+ OrientationResult = 0x02u;
+ } else if (xl == 0 && yl == 0 && zl == 0 && xh == 0 && yh == 0 && zh == 1) {
+ OrientationResult = 0x05u;
+ } else if (xl == 0 && yl == 0 && zl == 1 && xh == 0 && yh == 0 && zh == 0) {
+ OrientationResult = 0x06u;
+ }
+ stat = stat | OrientationResult;
+ }
+
+ if (Astatus.WakeUpStatus) {
+ FLIGHT1_PRINTF("Wake Up\n");
+ stat = stat | 0x80u;
+ }
+ Flight1.AccEvent_Notify(Flight1.globalSteps, stat);
+ }
+
+ if (proxEnable) {
+ //Get top sensor distance and transmit
+ do {
+ sensor_vl53l1_top->VL53L1X_CheckForDataReady(&ready);
+ } while (!ready);
+
+ status = sensor_vl53l1_top->VL53L1X_GetRangeStatus(&RangeStatus);
+ status = sensor_vl53l1_top->VL53L1X_GetDistance(&distance);
+
+ if (status == VL53L1X_ERROR_NONE) {
+ Flight1.FlightSense_Distance_Update(distance);
+ }
+
+ //Clear interrupt
+ status = sensor_vl53l1_top->VL53L1X_ClearInterrupt();
+
+ distance = (RangeStatus == 0 && distance < 1400) ? distance : 1400;
+
+ // Launch gesture detection algorithm.
+ gesture_code = tof_gestures_detectTAP_1(distance, &gestureTapData);
+
+ // Check the result of the gesture detection algorithm.
+ switch (gesture_code) {
+ case GESTURES_SINGLE_TAP:
+ Flight1.Gestures_Update(1);
+ gestureGuard = 0;
+ break;
+ default:
+ // Do nothing
+ break;
+ }
+
+
+ // Wait for data ready
+ do {
+ //if left not done
+ if (left_done == 0) {
+ NewDataReady = 0;
+ //check measurement data ready
+ int status = sensor_vl53l1_left->VL53L1X_CheckForDataReady(&NewDataReady);
+
+ if (status) {
+ SerialPort.println("GetMeasurementDataReady left sensor failed");
+ }
+ //if ready
+ if (NewDataReady) {
+ //get status
+ status = sensor_vl53l1_left->VL53L1X_GetRangeStatus(&RangeStatus);
+ if (status) {
+ SerialPort.println("GetRangeStatus left sensor failed");
+ }
+
+ //if distance < 1.3 m
+ if (RangeStatus == 0) {
+ // we have a valid range.
+ status = sensor_vl53l1_left->VL53L1X_GetDistance(&distance_left);
+ if (status) {
+ SerialPort.println("GetDistance left sensor failed");
+ }
+ } else {
+ distance_left = 1400; //default distance
+ }
+
+ //restart measurement
+ status = sensor_vl53l1_left->VL53L1X_ClearInterrupt();
+ if (status) {
+ SerialPort.println("Restart left sensor failed");
+ }
+
+ left_done = 1 ;
+ }
+ }
+
+ //if right not done
+ if (right_done == 0) {
+ NewDataReady = 0;
+ //check measurement data ready
+ int status = sensor_vl53l1_right->VL53L1X_CheckForDataReady(&NewDataReady);
+
+ if (status) {
+ SerialPort.println("GetMeasurementDataReady right sensor failed");
+ }
+ //if ready
+ if (NewDataReady) {
+ //get status
+ status = sensor_vl53l1_right->VL53L1X_GetRangeStatus(&RangeStatus);
+ if (status) {
+ SerialPort.println("GetRangeStatus right sensor failed");
+ }
+ //if distance < 1.3 m
+ if (RangeStatus == 0) {
+ // we have a valid range.
+ status = sensor_vl53l1_right->VL53L1X_GetDistance(&distance_right);
+ if (status) {
+ SerialPort.println("GetDistance right sensor failed");
+ }
+ } else {
+ distance_right = 1400; //default distance
+ }
+
+ //restart measurement
+ status = sensor_vl53l1_right->VL53L1X_ClearInterrupt();
+ if (status) {
+ SerialPort.println("Restart right sensor failed");
+ }
+
+ right_done = 1 ;
+ }
+ }
+ } while (left_done == 0 || right_done == 0);
+
+
+ // Launch gesture detection algorithm.
+ gesture_code = tof_gestures_detectDIRSWIPE_1(distance_left, distance_right, &gestureDirSwipeData);
+
+ // Check the result of the gesture detection algorithm.
+ switch (gesture_code) {
+ case GESTURES_SWIPE_LEFT_RIGHT:
+ Flight1.Gestures_Update(3);
+ gestureGuard = 0;
+ break;
+ case GESTURES_SWIPE_RIGHT_LEFT:
+ Flight1.Gestures_Update(2);
+ gestureGuard = 0;
+ break;
+ default:
+ if (!gestureGuard) {
+ Flight1.Gestures_Update(0);
+ gestureGuard = 1;
+ }
+ break;
+ }
+ }
+
+ //Send all mems sensors data
+ if (envEnable) {
+ Flight1.Environmental_Update(PressToSend, HumToSend, TempToSend);
+ }
+
+ if (gyroEnable || accEnable || magEnable) {
+ Flight1.AccGyroMag_Update(accelerometer, gyroscope, magnetometer);
+ }
+}
diff --git a/library.properties b/library.properties
index 751bc35..15547dc 100644
--- a/library.properties
+++ b/library.properties
@@ -7,4 +7,4 @@ paragraph=This library provides several Function Packs that combine the usage of
category=Other
url=https://github.com/stm32duino/FP_Examples
architectures=stm32
-depends=STM32duino LSM6DSL, STM32duino LSM303AGR, STM32duino LPS22HB, STM32duino VL6180X, STM32duino VL53L0X, STM32duino VL53L1X, STM32duino Proximity Gesture, STM32duino X-NUCLEO-6180XA1, STM32duino X-NUCLEO-53L0A1, STM32duino X-NUCLEO-53L1A1, STM32duino SPBTLE-RF, STM32duino X-NUCLEO-IHM02A1, STM32duino X-NUCLEO-LED61A1, STM32duino LPS25HB, STM32duino LSM6DS3, STM32duino LSM6DSO, STM32duino LIS2DW12, STM32duino LIS2MDL, STM32duino HTS221, STM32duino LPS22HH, STM32duino STTS751, STM32duino S2-LP, STM32duino M95640-R, STM32duino X-NUCLEO-IKS02A1 Audio
+depends=STM32duino LSM6DSL, STM32duino LSM303AGR, STM32duino LPS22HB, STM32duino VL6180X, STM32duino VL53L0X, STM32duino VL53L1X, STM32duino Proximity Gesture, STM32duino X-NUCLEO-6180XA1, STM32duino X-NUCLEO-53L0A1, STM32duino X-NUCLEO-53L1A1, STM32duino SPBTLE-RF, STM32duino X-NUCLEO-IHM02A1, STM32duino X-NUCLEO-LED61A1, STM32duino LPS25HB, STM32duino LSM6DS3, STM32duino LSM6DSO, STM32duino LIS2DW12, STM32duino LIS2MDL, STM32duino HTS221, STM32duino LPS22HH, STM32duino STTS751, STM32duino S2-LP, STM32duino M95640-R, STM32duino X-NUCLEO-IKS02A1 Audio, STM32duinoBLE