|
| 1 | +/* |
| 2 | + @file STEVAL_MKBOXPRO_MEMS_FIFO_Interrupt.ino |
| 3 | + @author STMicroelectronics |
| 4 | + @brief Example to use the LSM6DSV16X library with FIFO status interrupts. |
| 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 | +#include <LSM6DSV16XSensor.h> |
| 17 | + |
| 18 | +#define SENSOR_ODR 104.0f // In Hertz |
| 19 | +#define ACC_FS 2 // In g |
| 20 | +#define GYR_FS 2000 // In dps |
| 21 | +#define MEASUREMENT_TIME_INTERVAL (1000.0f/SENSOR_ODR) // In ms |
| 22 | +#define FIFO_SAMPLE_THRESHOLD 199 |
| 23 | +#define FLASH_BUFF_LEN 8192 |
| 24 | +#define INT1_pin PA4 |
| 25 | +LSM6DSV16XSensor AccGyr(&Wire); |
| 26 | + |
| 27 | +volatile uint8_t fullFlag = 0; // FIFO full flag |
| 28 | + |
| 29 | +// ISR callback for INT1 |
| 30 | +void INT1_fullEvent_cb() { |
| 31 | + fullFlag = 1; |
| 32 | +} |
| 33 | + |
| 34 | +unsigned long timestamp_count = 0; |
| 35 | +bool acc_available = false; |
| 36 | +bool gyr_available = false; |
| 37 | +int32_t acc_value[3]; |
| 38 | +int32_t gyr_value[3]; |
| 39 | +char buff[FLASH_BUFF_LEN]; |
| 40 | +uint32_t pos = 0; |
| 41 | + |
| 42 | +void Read_FIFO_Data(); |
| 43 | + |
| 44 | +void setup() { |
| 45 | + |
| 46 | + Serial.begin(115200); |
| 47 | + Wire.begin(); |
| 48 | + |
| 49 | + // Enable INT1 pin. |
| 50 | + attachInterrupt(INT1_pin, INT1_fullEvent_cb, RISING); |
| 51 | + |
| 52 | + // Initialize LSM6DSV16X. |
| 53 | + AccGyr.begin(); |
| 54 | + AccGyr.Enable_X(); |
| 55 | + AccGyr.Enable_G(); |
| 56 | + |
| 57 | + // Configure ODR and FS of the acc and gyro |
| 58 | + AccGyr.Set_X_ODR(SENSOR_ODR); |
| 59 | + AccGyr.Set_X_FS(ACC_FS); |
| 60 | + AccGyr.Set_G_ODR(SENSOR_ODR); |
| 61 | + AccGyr.Set_G_FS(GYR_FS); |
| 62 | + |
| 63 | + // Configure FIFO BDR for acc and gyro |
| 64 | + AccGyr.FIFO_Set_X_BDR(SENSOR_ODR); |
| 65 | + AccGyr.FIFO_Set_G_BDR(SENSOR_ODR); |
| 66 | + |
| 67 | + // Set Set FIFO watermark level |
| 68 | + AccGyr.FIFO_Set_Watermark_Level(FIFO_SAMPLE_THRESHOLD); |
| 69 | + // Set FIFO stop on watermark level |
| 70 | + AccGyr.FIFO_Set_Stop_On_Fth(1); |
| 71 | + // Enable FIFO full interrupt on sensor INT1 pin |
| 72 | + AccGyr.FIFO_Set_INT1_FIFO_Full(1); |
| 73 | + // Set FIFO in Continuous mode |
| 74 | + AccGyr.FIFO_Set_Mode(LSM6DSV16X_STREAM_MODE); |
| 75 | + |
| 76 | + Serial.println("LSM6DSV16X FIFO Demo"); |
| 77 | +} |
| 78 | + |
| 79 | +void loop() { |
| 80 | + uint8_t fullStatus = 0; |
| 81 | + |
| 82 | + // If we reach the threshold we can empty the FIFO |
| 83 | + if (fullFlag != 0) { |
| 84 | + fullFlag = 0; |
| 85 | + |
| 86 | + AccGyr.FIFO_Get_Full_Status(&fullStatus); |
| 87 | + |
| 88 | + if(fullStatus) { |
| 89 | + fullStatus = 0; |
| 90 | + |
| 91 | + // Empty the FIFO |
| 92 | + Read_FIFO_Data(); |
| 93 | + |
| 94 | + // Print FIFO data |
| 95 | + Serial.print(buff); |
| 96 | + } |
| 97 | + } |
| 98 | +} |
| 99 | + |
| 100 | +void Read_FIFO_Data() |
| 101 | +{ |
| 102 | + uint16_t i; |
| 103 | + uint16_t samples_to_read; |
| 104 | + |
| 105 | + // Check the number of samples inside FIFO |
| 106 | + AccGyr.FIFO_Get_Num_Samples(&samples_to_read); |
| 107 | + |
| 108 | + for (i = 0; i < samples_to_read; i++) { |
| 109 | + uint8_t tag; |
| 110 | + |
| 111 | + // Check the FIFO tag |
| 112 | + AccGyr.FIFO_Get_Tag(&tag); |
| 113 | + switch (tag) { |
| 114 | + // If we have a gyro tag, read the gyro data |
| 115 | + case 1: { |
| 116 | + AccGyr.FIFO_Get_G_Axes(gyr_value); |
| 117 | + gyr_available = true; |
| 118 | + break; |
| 119 | + } |
| 120 | + |
| 121 | + // If we have an acc tag, read the acc data |
| 122 | + case 2: { |
| 123 | + AccGyr.FIFO_Get_X_Axes(acc_value); |
| 124 | + acc_available = true; |
| 125 | + break; |
| 126 | + } |
| 127 | + |
| 128 | + // We can discard other tags |
| 129 | + default: { |
| 130 | + break; |
| 131 | + } |
| 132 | + } |
| 133 | + // If we have the measurements of both acc and gyro, we can store them with timestamp |
| 134 | + if (acc_available && gyr_available) { |
| 135 | + int num_bytes; |
| 136 | + 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]); |
| 137 | + pos += num_bytes; |
| 138 | + timestamp_count++; |
| 139 | + acc_available = false; |
| 140 | + gyr_available = false; |
| 141 | + } |
| 142 | + } |
| 143 | + // We can add the termination character to the string, so we are ready to print it on hyper-terminal |
| 144 | + buff[pos] = '\0'; |
| 145 | + pos = 0; |
| 146 | +} |
0 commit comments