SensorLib 0.5.0
Multi-platform sensor driver library for Arduino, PlatformIO, and ESP-IDF
Loading...
Searching...
No Matches
qmi8658_pedometer.ino
Go to the documentation of this file.
1
40#include <Arduino.h>
41#include <stdarg.h>
42#include <stdio.h>
43#include <Wire.h>
44#include <ImuDrv.hpp>
45#include "DevicesPins.h"
46
47
48// #define USE_I2C_INTERFACE true
49// #define USE_SPI_INTERFACE true
50
51#if !defined(USE_I2C_INTERFACE) && !defined(USE_SPI_INTERFACE)
52#define USE_I2C_INTERFACE
53#warning "No interface type is selected, use I2C interface"
54#endif
55
56#if defined(USE_SPI_INTERFACE)
57
58#ifndef SPI_MOSI
59#define SPI_MOSI 35
60#endif
61
62#ifndef SPI_MISO
63#define SPI_MISO 37
64#endif
65
66#ifndef SPI_SCK
67#define SPI_SCK 36
68#endif
69
70#ifndef IMU_CS
71#define IMU_CS 34
72#endif
73
74#ifndef IMU_IRQ
75#define IMU_IRQ 33
76#endif
77
78#else /* USE_I2C_INTERFACE */
79
80#ifndef IMU_SDA
81#define IMU_SDA 17
82#endif
83
84#ifndef IMU_SCL
85#define IMU_SCL 18
86#endif
87
88#ifndef IMU_IRQ
89#define IMU_IRQ 33
90#endif
91
92#endif /* USE_SPI_INTERFACE */
93
94
96uint32_t lastSteps = 0;
97volatile bool isInterruptTriggered = false;
98
99#ifdef ARDUINO_T_BEAM_S3_SUPREME
100#include <XPowersAXP2101.tpp> //PMU Library https://github.com/lewisxhe/XPowersLib.git
101#endif
103{
104 // T_BEAM_S3_SUPREME The PMU voltage needs to be turned on to use the sensor
105#if defined(ARDUINO_T_BEAM_S3_SUPREME)
106 XPowersAXP2101 power;
107 power.begin(Wire1, AXP2101_SLAVE_ADDRESS, 42, 41);
108 power.disableALDO1();
109 power.disableALDO2();
110 delay(250);
111 power.setALDO1Voltage(3300); power.enableALDO1();
112 power.setALDO2Voltage(3300); power.enableALDO2();
113#endif
114
115}
116
118{
119 Serial.println("[PEDOMETER] Step detected!");
120 uint32_t steps = imu.getStepCount();
121 if (steps != lastSteps) {
122 serialPrintFmt("[PEDOMETER] Steps: %u\n", steps);
123 lastSteps = steps;
124 }
125}
126
127static void serialPrintFmt(const char *fmt, ...)
128{
129 char buf[256];
130 va_list args;
131 va_start(args, fmt);
132 vsnprintf(buf, sizeof(buf), fmt, args);
133 va_end(args);
134 Serial.print(buf);
135}
136
137void setup()
138{
139 Serial.begin(115200);
140 while (!Serial);
141
142 setupPower();
143
144 Serial.println("QMI8658 Pedometer Example");
145
146#ifdef USE_I2C_INTERFACE
147 if (!imu.begin(Wire, QMI8658_H_SLAVE_ADDRESS, IMU_SDA, IMU_SCL)) {
148 Serial.println("Failed to initialize QMI8658!");
149 while (1) {
150 delay(1000);
151 }
152 }
153#endif
154
155#ifdef USE_SPI_INTERFACE
156 // Using SPI interface
157 if (!imu.begin(SPI, IMU_CS, SPI_MOSI, SPI_MISO, SPI_SCK)) {
158 Serial.println("Failed to initialize QMI8658!");
159 while (1) {
160 delay(1000);
161 }
162 }
163#endif
164
166
167 // Keep ACC+GYR both enabled, matching vendor pedometer runtime path.
168 // In 6DOF mode, synchronized ODR base follows gyro natural frequency.
169 // Accelerometer: FS_2G(000), FS_4G(001), FS_8G(010), FS_16G(011)
170 // ODR: 1000, 500, 250, 125, 62.5, 31.25, 128, 21, 11, 3 Hz (6DOF: 448/224/112/56/28 Hz)
172 112.0f);
173 // Gyroscope: FS_125_DPS, FS_250_DPS, FS_500_DPS, FS_1000_DPS, FS_2000_DPS, FS_4000_DPS
174 // ODR: 7174/3587/1793/896/448/224/112/56/28 Hz
176 112.0f);
177
179 imu.enableGyro();
180
181 Serial.println("\nUsing pedometer debug profile (easier trigger than strict walking profile)");
182 // Datasheet profile is conservative and designed to reject non-step vibration.
183 // For handheld bring-up, use a lower entry count and lower thresholds.
184 // sample_cnt=50, peak2peak=80mg, peak=60mg, time_up=400, time_low=8,
185 // entry=1, precision=0, sig_count=1
186 bool cfg_ok = imu.configPedometer(50, 80, 60, 400, 8, 1, 0, 1);
187 serialPrintFmt("configPedometer: %s\n", cfg_ok ? "OK" : "FAIL");
188
190 bool ped_ok = imu.enablePedometer(SensorQMI8658::IntPin::PIN1);
191 serialPrintFmt("enablePedometer: %s\n", ped_ok ? "OK" : "FAIL");
192
193 Serial.println("\nRegister snapshot after pedometer setup:");
195
197
198 Serial.println("\nPedometer configured. Start walking!");
199 Serial.println("Tip: step engine is for periodic gait, not random shaking.");
200 Serial.println("For handheld debug: simulate walking cadence (1-2Hz up/down motion).\n");
201 Serial.println("Note: Pedometer callback is triggered by step-count change, not only by status bit.");
202
203 int irq = digitalPinToInterrupt(IMU_IRQ);
204 if (irq >= 0) {
205 attachInterrupt(irq, +[]() {
207 }, CHANGE);
208 serialPrintFmt("IRQ attached on pin %d (CHANGE trigger)\n", IMU_IRQ);
209 } else {
210 serialPrintFmt("IRQ pin %d has no interrupt mapping, polling only\n", IMU_IRQ);
211 }
212
213}
214
215void loop()
216{
217 // Fallback poll period when no IRQ arrives (ms).
218 constexpr uint32_t kPollIntervalMs = 50;
219 static uint32_t lastPollMs = 0;
220
221 bool doUpdate = false;
223 isInterruptTriggered = false;
224 doUpdate = true;
225 }
226
227 uint32_t now = millis();
228 if (!doUpdate && (now - lastPollMs >= kPollIntervalMs)) {
229 doUpdate = true;
230 }
231
232 if (doUpdate) {
233 lastPollMs = now;
234 imu.update();
235 }
236 delay(10);
237}
@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 configPedometer(uint16_t sample_count, uint16_t peak_to_peak, uint16_t peak_threshold, uint16_t time_up, uint8_t time_low=20, uint8_t entry_count=10, uint8_t fix_precision=0, uint8_t sig_count=4)
Configure pedometer parameters.
uint32_t getStepCount()
Get pedometer step count.
bool enableAccel() override
Enable the accelerometer.
bool enablePedometer(IntPin pin=IntPin::DISABLE)
Enable pedometer.
bool enableGyro() override
Enable the gyroscope.
void setPedometerCallback(MotionCallback callback)
Set callback for pedometer event.
void dumpRegisters()
Dump control registers for debugging.
bool resetStepCount()
Reset pedometer counter.
bool configAccel(AccelFullScaleRange range, float data_rate_hz, LpfMode lpf=LpfMode::MODE_0)
Configure the accelerometer with specified parameters.
uint16_t update()
Update sensor status and process events.
void setPins(int pin)
Set interrupt pin.
char buf[64]
constexpr uint32_t kPollIntervalMs
void pedometerCallback()
void setup()
__attribute__((weak)) void setupPower()
uint32_t lastSteps
volatile bool isInterruptTriggered
#define IMU_IRQ
#define IMU_SCL
SensorQMI8658 imu
#define IMU_SDA
void loop()
uint32_t lastPollMs