SensorLib 0.5.0
Multi-platform sensor driver library for Arduino, PlatformIO, and ESP-IDF
Loading...
Searching...
No Matches
qmi8658_tap_detection.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
125float peakThreshold = 0.3f;
126float quietThreshold = 0.18f;
127uint16_t tapWindow = 55;
128uint16_t doubleTapWindow = 140;
129uint8_t peakWindow = 20;
130
131
132
134{
135 switch (event) {
136 case SensorQMI8658::TapEvent::SINGLE:
137 Serial.println("[TAP] Single tap detected!");
138 break;
139 case SensorQMI8658::TapEvent::DOUBLE:
140 Serial.println("[TAP] Double tap detected!");
141 break;
142 default:
143 Serial.println("[TAP] Invalid tap");
144 break;
145 }
146}
147
149{
150 imu.disableTap();
151 delay(20);
152
155 tapWindow,
159
160 imu.enableTap(SensorQMI8658::IntPin::PIN1);
161
162 serialPrintFmt("[TAP CFG] peak=%.3f quiet=%.3f peakWin=%u tapWin=%u dblWin=%u\n",
164}
165
167{
168 Serial.println("\nTap debug commands:");
169 Serial.println(" p+ / p- : peak threshold +/- 0.05 g^2");
170 Serial.println(" q+ / q- : quiet threshold +/- 0.02 g^2");
171 Serial.println(" w+ / w- : tap window +/- 5 samples");
172 Serial.println(" d+ / d- : double tap window +/- 10 samples");
173 Serial.println(" s : show current tap config");
174 Serial.println(" h : show this help");
175 Serial.println("Single-key shortcuts (no Enter needed):");
176 Serial.println(" 1:p- 2:p+ 3:q- 4:q+ 5:w- 6:w+ 7:d- 8:d+");
177}
178
179bool applyCommand(const String &cmd)
180{
181 bool changed = false;
182
183 if (cmd == "p+") {
184 peakThreshold += 0.05f;
185 changed = true;
186 } else if (cmd == "p-") {
187 peakThreshold -= 0.05f;
188 if (peakThreshold < 0.1f) peakThreshold = 0.1f;
189 changed = true;
190 } else if (cmd == "q+") {
191 quietThreshold += 0.02f;
192 changed = true;
193 } else if (cmd == "q-") {
194 quietThreshold -= 0.02f;
195 if (quietThreshold < 0.05f) quietThreshold = 0.05f;
196 changed = true;
197 } else if (cmd == "w+") {
198 tapWindow += 5;
199 changed = true;
200 } else if (cmd == "w-") {
201 tapWindow = (tapWindow > 10) ? (tapWindow - 5) : 5;
202 changed = true;
203 } else if (cmd == "d+") {
204 doubleTapWindow += 10;
205 changed = true;
206 } else if (cmd == "d-") {
207 doubleTapWindow = (doubleTapWindow > 20) ? (doubleTapWindow - 10) : 10;
208 changed = true;
209 } else if (cmd == "s") {
211 } else if (cmd == "h") {
213 } else {
214 return false;
215 }
216
217 if (changed) {
219 }
220
221 return true;
222}
223
225{
226 static String lineBuf;
227 while (Serial.available()) {
228 char c = (char)Serial.read();
229
230 if (c == '\r' || c == '\n') {
231 lineBuf.trim();
232 if (lineBuf.length() > 0) {
233 if (!applyCommand(lineBuf)) {
234 Serial.println("Unknown command, input 'h' for help.");
235 }
236 }
237 lineBuf = "";
238 continue;
239 }
240
241 // Single-key quick adjust (works without line ending)
242 if (c == 'h' || c == 's') {
243 String cmd = String(c);
245 continue;
246 }
247 if (c >= '1' && c <= '8') {
248 switch (c) {
249 case '1': applyCommand("p-"); break;
250 case '2': applyCommand("p+"); break;
251 case '3': applyCommand("q-"); break;
252 case '4': applyCommand("q+"); break;
253 case '5': applyCommand("w-"); break;
254 case '6': applyCommand("w+"); break;
255 case '7': applyCommand("d-"); break;
256 case '8': applyCommand("d+"); break;
257 }
258 continue;
259 }
260
261 if (isPrintable(c)) {
262 lineBuf += c;
263 }
264 }
265}
266
267void setup()
268{
269 Serial.begin(115200);
270 while (!Serial);
271
272 setupPower();
273
274 Serial.println("QMI8658 Tap Detection Example");
275
276#ifdef USE_I2C_INTERFACE
277 if (!imu.begin(Wire, QMI8658_H_SLAVE_ADDRESS, IMU_SDA, IMU_SCL)) {
278 Serial.println("Failed to initialize QMI8658!");
279 while (1) {
280 delay(1000);
281 }
282 }
283#endif
284
285#ifdef USE_SPI_INTERFACE
286 // Using SPI interface
287 if (!imu.begin(SPI, IMU_CS, SPI_MOSI, SPI_MISO, SPI_SCK)) {
288 Serial.println("Failed to initialize QMI8658!");
289 while (1) {
290 delay(1000);
291 }
292 }
293#endif
294
296
297 // Accelerometer: FS_2G(000), FS_4G(001), FS_8G(010), FS_16G(011)
298 // ODR: 1000, 500, 250, 125, 62.5, 31.25, 128, 21, 11, 3 Hz (6DOF: 448/224/112/56/28 Hz)
300 500.0f,
302
304
305 Serial.println("\n=== Simple Usage ===");
306 Serial.println("Using configTapDefault() with sensible defaults:");
307 Serial.println("- peak_window: 30 samples");
308 Serial.println("- tap_window: 100 samples");
309 Serial.println("- double_tap_window: 500 samples");
310 Serial.println("- peak_mag_threshold: 1.5 g^2");
311 Serial.println("- quiet_threshold: 0.5 g^2");
313
314 Serial.println("\n=== Advanced Usage ===");
315 Serial.println("Using configTap() with runtime tuning support");
316 Serial.println("(Tuned to reduce single-tap reported as double)");
318
320
321 Serial.println("\nTap detection configured. Tap the sensor!");
322 Serial.println("Expected: Single tap = 1 event, Double tap = 2 events");
324}
325
326void loop()
327{
329 imu.update();
330 delay(10);
331}
@license MIT License
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 disableTap()
Disable tap detection.
bool enableAccel() override
Enable the accelerometer.
void setTapCallback(TapCallback callback)
Set callback for tap event.
bool configTap(TapPriority priority, uint8_t peak_window, uint16_t tap_window, uint16_t double_tap_window, float peak_mag_threshold, float quiet_threshold)
Configure tap detection parameters.
bool enableTap(IntPin pin=IntPin::PIN1)
Enable tap detection.
@ OFF
Disable low-pass filter.
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.
bool configTapDefault(TapPriority priority=TapPriority::X_GT_Y_GT_Z)
Configure tap detection with default parameters.
void setPins(int pin)
Set interrupt pin.
char buf[64]
void printCommandHelp()
float quietThreshold
bool applyCommand(const String &cmd)
uint16_t doubleTapWindow
void setupPower()
void setup()
void tapCallback(SensorQMI8658::TapEvent event)
#define IMU_IRQ
#define IMU_SCL
float peakThreshold
SensorQMI8658 imu
void handleSerialCommands()
void applyTapConfig()
uint16_t tapWindow
#define IMU_SDA
uint8_t peakWindow
void loop()