SensorLib 0.5.0
Multi-platform sensor driver library for Arduino, PlatformIO, and ESP-IDF
Loading...
Searching...
No Matches
qmi8658_calibration.ino
Go to the documentation of this file.
1
40#include <stdarg.h>
41#include <ImuDrv.hpp>
42#include "DevicesPins.h"
43
44
45// Select one interface.
46// #define USE_I2C_INTERFACE
47// #define USE_SPI_INTERFACE
48
49#if !defined(USE_I2C_INTERFACE) && !defined(USE_SPI_INTERFACE)
50#define USE_I2C_INTERFACE
51#endif
52
53#if defined(USE_SPI_INTERFACE)
54
55#ifndef SPI_MOSI
56#define SPI_MOSI 35
57#endif
58
59#ifndef SPI_MISO
60#define SPI_MISO 37
61#endif
62
63#ifndef SPI_SCK
64#define SPI_SCK 36
65#endif
66
67#ifndef IMU_CS
68#define IMU_CS 34
69#endif
70
71#else
72
73#ifndef IMU_SDA
74#define IMU_SDA 17
75#endif
76
77#ifndef IMU_SCL
78#define IMU_SCL 18
79#endif
80
81#endif
82
83#ifndef IMU_IRQ
84#define IMU_IRQ 33
85#endif
86
87#ifdef ARDUINO_T_BEAM_S3_SUPREME
88#include <XPowersAXP2101.tpp>
89#endif
90
91static void serialPrintFmt(const char *fmt, ...)
92{
93 char buf[256];
94 va_list args;
95 va_start(args, fmt);
96 vsnprintf(buf, sizeof(buf), fmt, args);
97 va_end(args);
98 Serial.print(buf);
99}
100
102{
103#if defined(ARDUINO_T_BEAM_S3_SUPREME)
104 XPowersAXP2101 power;
105 power.begin(Wire1, AXP2101_SLAVE_ADDRESS, 42, 41);
106 power.disableALDO1();
107 power.disableALDO2();
108 delay(250);
109 power.setALDO1Voltage(3300);
110 power.enableALDO1();
111 power.setALDO2Voltage(3300);
112 power.enableALDO2();
113#endif
114}
115
118
119void setup()
120{
121 Serial.begin(115200);
122 while (!Serial);
123
124 setupPower();
125
126 Serial.println("QMI8658 Calibration Example");
127
128#ifdef USE_I2C_INTERFACE
129 if (!imu.begin(Wire, QMI8658_H_SLAVE_ADDRESS, IMU_SDA, IMU_SCL)) {
130 Serial.println("Failed to initialize QMI8658!");
131 while (1) {
132 delay(1000);
133 }
134 }
135#endif
136
137#ifdef USE_SPI_INTERFACE
138 // Using SPI interface
139 if (!imu.begin(SPI, IMU_CS, SPI_MOSI, SPI_MISO, SPI_SCK)) {
140 Serial.println("Failed to initialize QMI8658!");
141 while (1) {
142 delay(1000);
143 }
144 }
145#endif
146
147 // Accelerometer: FS_2G(000), FS_4G(001), FS_8G(010), FS_16G(011)
148 // ODR: 1000, 500, 250, 125, 62.5, 31.25, 128, 21, 11, 3 Hz (6DOF: 448/224/112/56/28 Hz)
150 1000.0f);
151
152 // Gyroscope: FS_125_DPS, FS_250_DPS, FS_500_DPS, FS_1000_DPS, FS_2000_DPS, FS_4000_DPS
153 // ODR: 7174/3587/1793/896/448/224/112/56/28 Hz
155 1000.0f);
156
157 // In 6DOF mode (ACC+GYR both enabled), ODR synchronization
158 // is derived from gyroscope natural frequency.
160 imu.enableGyro();
161
162 Serial.println("\n=== On-Demand Calibration ===");
163 Serial.println("\n--- Before Calibration ---");
164 for (int i = 0; i < 10; ++i) {
167 serialPrintFmt("Gyro: %8.3f %8.3f %8.3f\n", gyro.dps.x, gyro.dps.y, gyro.dps.z);
168 delay(100);
169 }
170
171 Serial.println("\nStarting calibration... Please keep sensor motionless!");
172 delay(1000);
173
174 uint16_t gyro_x, gyro_y, gyro_z;
175 if (imu.calibrate(&gyro_x, &gyro_y, &gyro_z)) {
176 Serial.println("Calibration successful!");
177 serialPrintFmt("Gyro gains - X: 0x%04X, Y: 0x%04X, Z: 0x%04X\n",
178 gyro_x, gyro_y, gyro_z);
179
180 delay(500);
181
182 if (imu.writeCalibration(gyro_x, gyro_y, gyro_z)) {
183 Serial.println("Calibration gains applied!");
184 }
185
186 // On-demand calibration path disables sensors; re-enable runtime streaming.
187 bool enA = imu.enableAccel();
188 bool enG = imu.enableGyro();
189 serialPrintFmt("Runtime re-enable: accel=%s gyro=%s\n", enA ? "OK" : "FAIL", enG ? "OK" : "FAIL");
190 } else {
191 Serial.println("Calibration failed!");
192 }
193
194 Serial.println("\n--- After Calibration ---");
195 for (int i = 0; i < 10; ++i) {
198 serialPrintFmt("Gyro: %8.3f %8.3f %8.3f\n", gyro.dps.x, gyro.dps.y, gyro.dps.z);
199 delay(100);
200 }
201
202 Serial.println("\n=== Static Calibration (Software) ===");
203 Serial.println("Enable software-based static calibration:");
204 Serial.println("- Collects 100 samples when sensor is stationary");
205 Serial.println("- Calculates accelerometer and gyroscope offsets");
207
208 Serial.println("\n=== Dynamic Gyro Calibration ===");
209 Serial.println("Enable dynamic gyroscope calibration:");
210 Serial.println("- Continuously updates offsets when stationary detected");
211 Serial.println("- Uses accelerometer variance to detect stillness");
213
214 Serial.println("\nWaiting for static calibration to complete (about 10s @100ms loop)...");
215
216 Serial.println("\nCalibration complete. Data is now being processed.");
217}
218
219void loop()
220{
221 static uint32_t failCount = 0;
222
224 if (imu.readGyro(gyro)) {
225 failCount = 0;
227 int16_t accelOff[3], gyroOff[3];
228 imu.getStaticCalibrationOffsets(accelOff, gyroOff);
229 serialPrintFmt("[CAL] Static calibration complete. Gyro offsets: %d %d %d\n",
230 gyroOff[0], gyroOff[1], gyroOff[2]);
232 }
233 serialPrintFmt("Gyro: %8.3f %8.3f %8.3f\n", gyro.dps.x, gyro.dps.y, gyro.dps.z);
234 } else {
235 failCount++;
236 if ((failCount % 20) == 1) {
237 bool enG = imu.enableGyro();
238 serialPrintFmt("[WARN] readGyro failed (%lu), trying enableGyro: %s\n",
239 static_cast<unsigned long>(failCount), enG ? "OK" : "FAIL");
240 }
241 }
242 delay(100);
243}
@license MIT License
@ FS_1000_DPS
±1000 °/s
bool begin(CommInterface interface, SensorCommCustom::CustomCallback callback, SensorCommCustomHal::CustomHalCallback hal_callback, uint8_t addr=0)
Initialize the sensor using custom callback interface.
QMI8658 IMU sensor driver class.
bool configGyro(GyroFullScaleRange range, float data_rate_hz, LpfMode lpf=LpfMode::MODE_0)
Configure the gyroscope with specified parameters.
bool readGyro(GyroscopeData &out) override
Read gyroscope data.
void getStaticCalibrationOffsets(int16_t accel_offset[3], int16_t gyro_offset[3])
Get static calibration offsets.
bool enableAccel() override
Enable the accelerometer.
bool isStaticCalibrationComplete() const
Get the current static calibration status.
void enableStaticCalibration(bool enable)
Start static calibration.
bool enableGyro() override
Enable the gyroscope.
void enableDynamicGyroCalibration(bool enable)
Enable dynamic gyroscope calibration.
bool calibrate(uint16_t *gyro_x_gain=nullptr, uint16_t *gyro_y_gain=nullptr, uint16_t *gyro_z_gain=nullptr)
Perform on-demand calibration.
bool configAccel(AccelFullScaleRange range, float data_rate_hz, LpfMode lpf=LpfMode::MODE_0)
Configure the accelerometer with specified parameters.
bool writeCalibration(uint16_t gyro_x_gain, uint16_t gyro_y_gain, uint16_t gyro_z_gain)
Write previously saved gyro calibration gains.
uint8_t i
char buf[64]
bool staticCalDonePrinted
void setupPower()
void setup()
#define IMU_SCL
SensorQMI8658 imu
#define IMU_SDA
void loop()
IMUdata gyro[buffer_size]
Structure representing gyroscope data.