|
| 1 | +/* |
| 2 | + @file ISM330DHCX_FIFO.ino |
| 3 | + @author STMicroelectronics |
| 4 | + @brief Example to use the ISM330DHCX 3D accelerometer and 3D gyroscope FIFO |
| 5 | + ******************************************************************************* |
| 6 | + Copyright (c) 2022, STMicroelectronics |
| 7 | + All rights reserved. |
| 8 | +
|
| 9 | + This software component is licensed by ST under BSD 3-Clause license, |
| 10 | + the "License"; You may not use this file except in compliance with the |
| 11 | + License. You may obtain a copy of the License at: |
| 12 | + opensource.org/licenses/BSD-3-Clause |
| 13 | +
|
| 14 | + ******************************************************************************* |
| 15 | +*/ |
| 16 | + |
| 17 | +// Includes |
| 18 | +#include <ISM330DHCXSensor.h> |
| 19 | + |
| 20 | +#if defined(ARDUINO_STM32WB5MM_DK) || defined(ARDUINO_B_U585I_IOT02A) |
| 21 | +#define USE_I2C_INTERFACE |
| 22 | +#else |
| 23 | +// Uncomment one communication interface to use: |
| 24 | +// X-NUCLEO-IKS02A1 uses I2C interface (set by default) |
| 25 | +// #define USE_SPI_INTERFACE |
| 26 | +#define USE_I2C_INTERFACE |
| 27 | +#endif |
| 28 | + |
| 29 | +#if !defined(USE_SPI_INTERFACE) && !defined(USE_I2C_INTERFACE) || \ |
| 30 | + defined(USE_SPI_INTERFACE) && defined(USE_I2C_INTERFACE) |
| 31 | +#error "Uncomment one communication interface to use!" |
| 32 | +#endif |
| 33 | + |
| 34 | +#ifdef USE_SPI_INTERFACE |
| 35 | +// Uncomment to set SPI pins to use else default instance will be used |
| 36 | +// #define ISM330DHCX_SPI_MOSI PB10 |
| 37 | +// #define ISM330DHCX_SPI_MISO PB11 |
| 38 | +// #define ISM330DHCX_SPI_SCLK PB11 |
| 39 | +// Define Software Chip Select pin to use (default: SS) |
| 40 | +#define ISM330DHCX_SPI_SSEL SS |
| 41 | + |
| 42 | +#if defined(ISM330DHCX_SPI_MOSI) && defined(ISM330DHCX_SPI_MISO) && \ |
| 43 | + defined(ISM330DHCX_SPI_SCLK) && defined(ISM330DHCX_SPI_SSEL) |
| 44 | +SPIClass dev_interface(ISM330DHCX_SPI_MOSI, ISM330DHCX_SPI_MISO, ISM330DHCX_SPI_SCLK); |
| 45 | +#else |
| 46 | +#define dev_interface SPI |
| 47 | +#endif |
| 48 | + |
| 49 | +ISM330DHCXSensor AccGyr(&dev_interface, ISM330DHCX_SPI_SSEL); |
| 50 | +#else // USE_I2C_INTERFACE |
| 51 | +#if defined(ARDUINO_STM32WB5MM_DK) |
| 52 | +#define ISM330DHCX_I2C_SCL PB13 |
| 53 | +#define ISM330DHCX_I2C_SDA PB11 |
| 54 | +#elif defined(ARDUINO_B_U585I_IOT02A) |
| 55 | +#define ISM330DHCX_I2C_SCL PH4 |
| 56 | +#define ISM330DHCX_I2C_SDA PH5 |
| 57 | +#else |
| 58 | +// Uncomment to set I2C pins to use else default instance will be used |
| 59 | +// #define ISM330DHCX_I2C_SCL PYn |
| 60 | +// #define ISM330DHCX_I2C_SDA PYn |
| 61 | +#endif |
| 62 | +#if defined(ISM330DHCX_I2C_SCL) && defined(ISM330DHCX_I2C_SDA) |
| 63 | +TwoWire dev_interface(ISM330DHCX_I2C_SDA, ISM330DHCX_I2C_SCL); |
| 64 | +#else |
| 65 | +// X-NUCLEO-IKS02A1 uses default instance |
| 66 | +#define dev_interface Wire |
| 67 | +#endif |
| 68 | + |
| 69 | +ISM330DHCXSensor AccGyr(&dev_interface); |
| 70 | +#endif |
| 71 | + |
| 72 | +#define SENSOR_ODR 104.0f // In Hertz |
| 73 | +#define ACC_FS 2 // In g |
| 74 | +#define GYR_FS 2000 // In dps |
| 75 | +#define MEASUREMENT_TIME_INTERVAL (1000.0f/SENSOR_ODR) // In ms |
| 76 | +#define FIFO_SAMPLE_THRESHOLD 199 |
| 77 | +#define FLASH_BUFF_LEN 8192 |
| 78 | + |
| 79 | +unsigned long timestamp_count = 0; |
| 80 | +bool acc_available = false; |
| 81 | +bool gyr_available = false; |
| 82 | +int32_t acc_value[3]; |
| 83 | +int32_t gyr_value[3]; |
| 84 | +char buff[FLASH_BUFF_LEN]; |
| 85 | +uint32_t pos = 0; |
| 86 | + |
| 87 | +void Read_FIFO_Data(uint16_t samples_to_read); |
| 88 | + |
| 89 | +void setup() { |
| 90 | + Serial.begin(115200); |
| 91 | + |
| 92 | + dev_interface.begin(); |
| 93 | + |
| 94 | + // Initialize IMU. |
| 95 | + AccGyr.begin(); |
| 96 | + AccGyr.ACC_Enable(); |
| 97 | + AccGyr.GYRO_Enable(); |
| 98 | + // Configure ODR and FS of the acc and gyro |
| 99 | + AccGyr.ACC_SetOutputDataRate(SENSOR_ODR); |
| 100 | + AccGyr.ACC_SetFullScale(ACC_FS); |
| 101 | + AccGyr.GYRO_SetOutputDataRate(SENSOR_ODR); |
| 102 | + AccGyr.GYRO_SetFullScale(GYR_FS); |
| 103 | + // Configure FIFO BDR for acc and gyro |
| 104 | + AccGyr.FIFO_ACC_Set_BDR(SENSOR_ODR); |
| 105 | + AccGyr.FIFO_GYRO_Set_BDR(SENSOR_ODR); |
| 106 | + // Set FIFO in Continuous mode |
| 107 | + AccGyr.FIFO_Set_Mode(ISM330DHCX_STREAM_MODE); |
| 108 | + Serial.println("ISM330DHCX FIFO Demo"); |
| 109 | +} |
| 110 | + |
| 111 | +void loop() { |
| 112 | + uint16_t fifo_samples; |
| 113 | + |
| 114 | + // Check the number of samples inside FIFO |
| 115 | + AccGyr.FIFO_Get_Num_Samples(&fifo_samples); |
| 116 | + |
| 117 | + // If we reach the threshold we can empty the FIFO |
| 118 | + if (fifo_samples > FIFO_SAMPLE_THRESHOLD) { |
| 119 | + // Empty the FIFO |
| 120 | + Read_FIFO_Data(fifo_samples); |
| 121 | + // Print FIFO data |
| 122 | + Serial.print(buff); |
| 123 | + } |
| 124 | +} |
| 125 | + |
| 126 | +void Read_FIFO_Data(uint16_t samples_to_read) |
| 127 | +{ |
| 128 | + uint16_t i; |
| 129 | + |
| 130 | + for (i = 0; i < samples_to_read; i++) { |
| 131 | + uint8_t tag; |
| 132 | + // Check the FIFO tag |
| 133 | + AccGyr.FIFO_Get_Tag(&tag); |
| 134 | + switch (tag) { |
| 135 | + // If we have a gyro tag, read the gyro data |
| 136 | + case ISM330DHCX_GYRO_NC_TAG: { |
| 137 | + AccGyr.FIFO_GYRO_Get_Axes(gyr_value); |
| 138 | + gyr_available = true; |
| 139 | + break; |
| 140 | + } |
| 141 | + // If we have an acc tag, read the acc data |
| 142 | + case ISM330DHCX_XL_NC_TAG: { |
| 143 | + AccGyr.FIFO_ACC_Get_Axes(acc_value); |
| 144 | + acc_available = true; |
| 145 | + break; |
| 146 | + } |
| 147 | + // We can discard other tags |
| 148 | + default: { |
| 149 | + break; |
| 150 | + } |
| 151 | + } |
| 152 | + // If we have the measurements of both acc and gyro, we can store them with timestamp |
| 153 | + if (acc_available && gyr_available) { |
| 154 | + int num_bytes; |
| 155 | + num_bytes = snprintf(&buff[pos], (FLASH_BUFF_LEN - pos), "%lu %d %d %d %d %d %d\r\n", (unsigned long)((float)timestamp_count * MEASUREMENT_TIME_INTERVAL), (int)acc_value[0], (int)acc_value[1], (int)acc_value[2], (int)gyr_value[0], (int)gyr_value[1], (int)gyr_value[2]); |
| 156 | + pos += num_bytes; |
| 157 | + timestamp_count++; |
| 158 | + acc_available = false; |
| 159 | + gyr_available = false; |
| 160 | + } |
| 161 | + } |
| 162 | + // We can add the termination character to the string, so we are ready to print it on hyper-terminal |
| 163 | + buff[pos] = '\0'; |
| 164 | + pos = 0; |
| 165 | +} |
0 commit comments