SensorLib 0.5.0
Multi-platform sensor driver library for Arduino, PlatformIO, and ESP-IDF
Loading...
Searching...
No Matches
qmi8658_wake_on_motion.ino
Go to the documentation of this file.
1
47#include <stdarg.h>
48#include <ImuDrv.hpp>
49#include "DevicesPins.h"
50
51
52// Select one interface.
53// #define USE_I2C_INTERFACE
54// #define USE_SPI_INTERFACE
55
56#if !defined(USE_I2C_INTERFACE) && !defined(USE_SPI_INTERFACE)
57#define USE_I2C_INTERFACE
58#endif
59
60#if defined(USE_SPI_INTERFACE)
61
62#ifndef SPI_MOSI
63#define SPI_MOSI 35
64#endif
65
66#ifndef SPI_MISO
67#define SPI_MISO 37
68#endif
69
70#ifndef SPI_SCK
71#define SPI_SCK 36
72#endif
73
74#ifndef IMU_CS
75#define IMU_CS 34
76#endif
77
78#else
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#endif
89
90#ifndef IMU_IRQ
91#define IMU_IRQ 33
92#endif
93
94#ifdef ARDUINO_T_BEAM_S3_SUPREME
95#include <XPowersAXP2101.tpp>
96#endif
97
98static void serialPrintFmt(const char *fmt, ...)
99{
100 char buf[256];
101 va_list args;
102 va_start(args, fmt);
103 vsnprintf(buf, sizeof(buf), fmt, args);
104 va_end(args);
105 Serial.print(buf);
106}
107
109{
110#if defined(ARDUINO_T_BEAM_S3_SUPREME)
111 XPowersAXP2101 power;
112 power.begin(Wire1, AXP2101_SLAVE_ADDRESS, 42, 41);
113 power.disableALDO1();
114 power.disableALDO2();
115 delay(250);
116 power.setALDO1Voltage(3300);
117 power.enableALDO1();
118 power.setALDO2Voltage(3300);
119 power.enableALDO2();
120#endif
121}
122
124
125
126uint32_t lastPollMs = 0;
127volatile bool isInterruptTriggered = false;
128constexpr uint32_t kPollIntervalMs = 50;
129uint8_t womThreshold = 150;
130float womOdrHz = 11.0f;
132uint8_t womBlankingTime = 0x20;
134SensorQMI8658::IntPin womIntPin = SensorQMI8658::IntPin::PIN2;
135
137{
138 Serial.print("["); Serial.print(millis() / 1000);
139 Serial.println("][WOM] Wake-on-motion detected!");
140}
141
143{
144 // womRange: FS_2G, FS_4G, FS_8G, FS_16G
145 // womOdrHz: 3, 11, 21, 128 Hz
147 womOdrHz,
148 womIntPin,
151 womRange);
152 serialPrintFmt("[WOM CFG] thr=%u odr=%.1f pinDefault=%u blank=0x%02X range=%s -> %s\n",
154 womOdrHz,
159 (womRange == AccelFullScaleRange::FS_8G) ? "8G" : "16G",
160 ok ? "OK" : "FAIL");
161}
162
164{
165 Serial.println("\nWoM debug commands:");
166 Serial.println(" t+ / t- : threshold +/- 10");
167 Serial.println(" b+ / b- : blanking +/- 1");
168 Serial.println(" p0 / p1 : default pin level 0/1");
169 Serial.println(" o3/o11/o21/o128 : ODR 3/11/21/128Hz");
170 Serial.println(" r2/r4/r8/r16 : accel range 2/4/8/16G");
171 Serial.println(" s : show/apply current config");
172 Serial.println(" h : show this help");
173}
174
176{
177 if (!Serial.available()) {
178 return;
179 }
180
181 String cmd = Serial.readStringUntil('\n');
182 cmd.trim();
183 if (cmd.length() == 0) {
184 return;
185 }
186
187 bool changed = false;
188
189 if (cmd == "t+") {
190 womThreshold = (womThreshold <= 245) ? womThreshold + 10 : 255;
191 changed = true;
192 } else if (cmd == "t-") {
193 womThreshold = (womThreshold >= 10) ? womThreshold - 10 : 0;
194 changed = true;
195 } else if (cmd == "b+") {
196 womBlankingTime = (womBlankingTime < 0x3F) ? (womBlankingTime + 1) : 0x3F;
197 changed = true;
198 } else if (cmd == "b-") {
200 changed = true;
201 } else if (cmd == "p0") {
203 changed = true;
204 } else if (cmd == "p1") {
206 changed = true;
207 } else if (cmd == "o3") {
208 womOdrHz = 3.0f;
209 changed = true;
210 } else if (cmd == "o11") {
211 womOdrHz = 11.0f;
212 changed = true;
213 } else if (cmd == "o21") {
214 womOdrHz = 21.0f;
215 changed = true;
216 } else if (cmd == "o128") {
217 womOdrHz = 128.0f;
218 changed = true;
219 } else if (cmd == "r2") {
221 changed = true;
222 } else if (cmd == "r4") {
224 changed = true;
225 } else if (cmd == "r8") {
227 changed = true;
228 } else if (cmd == "r16") {
230 changed = true;
231 } else if (cmd == "s") {
233 } else if (cmd == "h") {
234 printWomHelp();
235 } else {
236 Serial.println("Unknown command, input 'h' for help.");
237 }
238
239 if (changed) {
241 }
242}
243
244void setup()
245{
246 Serial.begin(115200);
247 while (!Serial);
248
249 setupPower();
250
251 Serial.println("QMI8658 Wake-on-Motion Example");
252
253#ifdef USE_I2C_INTERFACE
254 if (!imu.begin(Wire, QMI8658_H_SLAVE_ADDRESS, IMU_SDA, IMU_SCL)) {
255 Serial.println("Failed to initialize QMI8658!");
256 while (1) {
257 delay(1000);
258 }
259 }
260#endif
261
262#ifdef USE_SPI_INTERFACE
263 // Using SPI interface
264 if (!imu.begin(SPI, IMU_CS, SPI_MOSI, SPI_MISO, SPI_SCK)) {
265 Serial.println("Failed to initialize QMI8658!");
266 while (1) {
267 delay(1000);
268 }
269 }
270#endif
271
273
275
276 Serial.println("\n=== Advanced Usage ===");
277 Serial.println("Custom: threshold=150, ODR=11Hz, PIN2, pinDefault=1, blanking=0x20, range=8G");
279
280 Serial.println("\nWake-on-motion configured. Move the sensor to trigger!");
281 printWomHelp();
282
283 int irq = digitalPinToInterrupt(IMU_IRQ);
284 if (irq >= 0) {
285 attachInterrupt(irq, +[]() {
287 }, CHANGE);
288 serialPrintFmt("IRQ attached on pin %d (CHANGE trigger)\n", IMU_IRQ);
289 } else {
290 serialPrintFmt("IRQ pin %d has no interrupt mapping, polling only\n", IMU_IRQ);
291 }
292}
293
294void loop()
295{
297
298 bool doUpdate = false;
300 isInterruptTriggered = false;
301 doUpdate = true;
302 }
303
304 uint32_t now = millis();
305 if (!doUpdate && (now - lastPollMs >= kPollIntervalMs)) {
306 doUpdate = true;
307 }
308
309 if (doUpdate) {
310 lastPollMs = now;
311 imu.update();
312 }
313 delay(10);
314}
@license MIT License
AccelFullScaleRange
Enumeration of accelerometer full-scale range settings.
@ FS_16G
±16g range
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.
uint16_t update()
Update sensor status and process events.
void setPins(int pin)
Set interrupt pin.
bool configWakeOnMotionAdvanced(uint8_t threshold, float odr_hz, IntPin pin, uint8_t default_pin_value, uint8_t blanking_time, AccelFullScaleRange acc_range)
Configure wake-on-motion (WoM) with full vendor parameters.
void setWakeOnMotionCallback(MotionCallback callback)
Set callback for wake-on-motion event.
char buf[64]
uint8_t womBlankingTime
void applyWomConfig()
void printWomHelp()
void setupPower()
volatile bool isInterruptTriggered
SensorQMI8658::IntPin womIntPin
void handleWomCommands()
#define IMU_IRQ
#define IMU_SCL
uint8_t womThreshold
SensorQMI8658 imu
void womCallback()
AccelFullScaleRange womRange
constexpr uint32_t kPollIntervalMs
uint32_t lastPollMs
#define IMU_SDA
uint8_t womDefaultPinValue