SensorLib 0.5.0
Multi-platform sensor driver library for Arduino, PlatformIO, and ESP-IDF
Loading...
Searching...
No Matches
sensor/accelerometer/bma/SensorBMA422.hpp
Go to the documentation of this file.
1
31#pragma once
32
33#include "../../../SensorBuildOpt.h"
34#if !SENSORLIB_EXCLUDE_BMA422
35
36#include "SensorBMA4XX.hpp"
37#include "../../../bosch/bma4xx/bma422_an.h"
38
40{
41public:
42
50 std::function<void(void)> onAnyMotion = nullptr;
51 std::function<void(void)> onNoMotion = nullptr;
52 std::function<void(AccelerometerData &)> onDataReady = nullptr;
53 };
54
61 {
62 _remap_reg_offset = BMA422_AN_AXES_REMAP_START_ADDR;
63 }
64
66
71 ~SensorBMA422() = default;
72
80
86 void setOnAnyMotionCallback(std::function<void(void)> cb)
87 {
88 callbacks.onAnyMotion = std::move(cb);
89 }
90
96 void setOnNoMotionCallback(std::function<void(void)> cb)
97 {
98 callbacks.onNoMotion = std::move(cb);
99 }
100
106 void setOnDataReadyCallback(std::function<void(AccelerometerData)> cb)
107 {
108 callbacks.onDataReady = std::move(cb);
109 }
110
117 {
118 callbacks = cbs;
119 }
120
127 {
128 return callbacks;
129 }
130
136 {
137 return callbacks;
138 }
139
147 bool enableDataReady(bool enable = true, InterruptPinMap pin_map = InterruptPinMap::PIN1) override
148 {
149 return enableInterrupt(pin_map, BMA4_DATA_RDY_INT, enable);
150 }
151
161 bool enableAnyMotionDetection(const MotionAxesConfig &cfg, bool enable,
162 bool interrupt_enable = false,
163 InterruptPinMap pin_map = InterruptPinMap::PIN1) override
164 {
165 int8_t rslt = 0;
166 struct bma422_an_any_no_mot_config any_mot_config = { 0, 0, 0};
167
168 rslt = bma422_an_get_any_mot_config(&any_mot_config, dev.get());
169 if (rslt != 0) {
170 SENSORLIB_LOG_E("bma422_an_get_any_mot_config failed");
171 return false;
172 }
173
174 any_mot_config.axes_en = 0x00;
175 if (enable) {
176 if (cfg.x_axis) any_mot_config.axes_en |= BMA422_AN_X_AXIS_EN;
177 if (cfg.y_axis) any_mot_config.axes_en |= BMA422_AN_Y_AXIS_EN;
178 if (cfg.z_axis) any_mot_config.axes_en |= BMA422_AN_Z_AXIS_EN;
179 }
180
181 if (!enableInterrupt(pin_map, BMA422_AN_ANY_MOT_INT, interrupt_enable)) {
182 return false;
183 }
184
185 rslt = bma422_an_set_any_mot_config(&any_mot_config, dev.get());
186 return rslt == 0;
187 }
188
198 bool enableNoMotionDetection(const MotionAxesConfig &cfg, bool enable,
199 bool interrupt_enable = false,
200 InterruptPinMap pin_map = InterruptPinMap::PIN1) override
201 {
202 int8_t rslt = 0;
203 struct bma422_an_any_no_mot_config no_mot_config = { 0, 0, 0};
204 rslt = bma422_an_get_no_mot_config(&no_mot_config, dev.get());
205 if (rslt != 0) {
206 SENSORLIB_LOG_E("bma422_an_get_no_mot_config failed");
207 return false;
208 }
209 no_mot_config.axes_en = 0x00;
210 if (enable) {
211 if (cfg.x_axis) no_mot_config.axes_en |= BMA422_AN_X_AXIS_EN;
212 if (cfg.y_axis) no_mot_config.axes_en |= BMA422_AN_Y_AXIS_EN;
213 if (cfg.z_axis) no_mot_config.axes_en |= BMA422_AN_Z_AXIS_EN;
214 }
215
216 if (!enableInterrupt(pin_map, BMA422_AN_NO_MOT_INT, interrupt_enable)) {
217 return false;
218 }
219
220 rslt = bma422_an_set_no_mot_config(&no_mot_config, dev.get());
221 return rslt == 0;
222 }
223
265 bool configNoMotion(uint16_t threshold, uint16_t duration) override
266 {
267 return configMotion(false, threshold, duration);
268 }
269
311 bool configAnyMotion(uint16_t threshold, uint16_t duration) override
312 {
313 return configMotion(true, threshold, duration);
314 }
315
359 bool configMotion(bool any_motion, uint16_t threshold, uint16_t duration) override
360 {
361 int8_t rslt = 0;
362
363 if (threshold > 16380) { // Max threshold based on 0.48mg resolution for 16g range
364 SENSORLIB_LOG_E("Threshold %u exceeds recommended maximum (16380)", threshold);
365 }
366
367 if (duration > 16383) { // Maximum 14-bit value
368 SENSORLIB_LOG_E("Duration %u exceeds recommended maximum (16383)", duration);
369 }
370
371 struct bma422_an_any_no_mot_config any_mot_config = {0, 0, 0};
372
373 if (any_motion) {
374 rslt = bma422_an_get_any_mot_config(&any_mot_config, dev.get());
375 if (rslt != 0) {
376 SENSORLIB_LOG_E("bma422_an_get_any_mot_config failed");
377 return false;
378 }
379 } else {
380 rslt = bma422_an_get_no_mot_config(&any_mot_config, dev.get());
381 if (rslt != 0) {
382 SENSORLIB_LOG_E("bma422_an_get_no_mot_config failed");
383 return false;
384 }
385 }
386
387 any_mot_config.threshold = threshold;
388 any_mot_config.duration = duration;
389
390 SENSORLIB_LOG_D("Configuring motion detection: threshold=%u LSB (%.2f mG), duration=%u LSB (%.2f ms at 50Hz)",
391 threshold, threshold * 0.48f,
392 duration, duration * 20.0f);
393
394 if (any_motion) {
395 if (bma422_an_set_any_mot_config(&any_mot_config, dev.get()) != 0) {
396 SENSORLIB_LOG_E("Failed to configure any-motion detection");
397 return false;
398 }
399 } else {
400 if (bma422_an_set_no_mot_config(&any_mot_config, dev.get()) != 0) {
401 SENSORLIB_LOG_E("Failed to configure no-motion detection");
402 return false;
403 }
404 }
405 return true;
406 }
407
408
419 bool configAnyMotionInPhysicalUnits(float threshold_mg, float duration_ms) override
420 {
421 uint16_t threshold_lsb = static_cast<uint16_t>(threshold_mg / 0.48f + 0.5f);
422 uint16_t duration_lsb = static_cast<uint16_t>(duration_ms / 20.0f + 0.5f);
423
424 SENSORLIB_LOG_D("Converting: %.2f mg -> %u LSB, %.2f ms -> %u LSB",
425 threshold_mg, threshold_lsb, duration_ms, duration_lsb);
426
427 return configAnyMotion(threshold_lsb, duration_lsb);
428 }
429
430
441 bool configNoMotionInPhysicalUnits(float threshold_mg, float duration_ms) override
442 {
443 uint16_t threshold_lsb = static_cast<uint16_t>(threshold_mg / 0.48f + 0.5f);
444 uint16_t duration_lsb = static_cast<uint16_t>(duration_ms / 20.0f + 0.5f);
445
446 SENSORLIB_LOG_D("Converting: %.2f mg -> %u LSB, %.2f ms -> %u LSB",
447 threshold_mg, threshold_lsb, duration_ms, duration_lsb);
448
449 return configNoMotion(threshold_lsb, duration_lsb);
450 }
451
460 bool getAnyMotionConfig(float &threshold_mg, float &duration_ms)
461 {
462 struct bma422_an_any_no_mot_config any_mot_config;
463 if (bma422_an_get_any_mot_config(&any_mot_config, dev.get()) != 0) {
464 SENSORLIB_LOG_E("Failed to read motion configuration");
465 return false;
466 }
467
468 threshold_mg = any_mot_config.threshold * 0.48f;
469 duration_ms = any_mot_config.duration * 20.0f;
470
471 SENSORLIB_LOG_D("Current config: threshold=%u LSB (%.2f mg), duration=%u LSB (%.2f ms)",
472 any_mot_config.threshold, threshold_mg,
473 any_mot_config.duration, duration_ms);
474
475 return true;
476 }
477
486 bool getNoMotionConfig(float &threshold_mg, float &duration_ms)
487 {
488 struct bma422_an_any_no_mot_config no_mot_config;
489 if (bma422_an_get_no_mot_config(&no_mot_config, dev.get()) != 0) {
490 SENSORLIB_LOG_E("Failed to read no-motion configuration");
491 return false;
492 }
493
494 threshold_mg = no_mot_config.threshold * 0.48f;
495 duration_ms = no_mot_config.duration * 20.0f;
496
497 SENSORLIB_LOG_D("Current no-motion config: threshold=%u LSB (%.2f mg), duration=%u LSB (%.2f ms)",
498 no_mot_config.threshold, threshold_mg,
499 no_mot_config.duration, duration_ms);
500
501 return true;
502 }
503
511 void update() override
512 {
513 if (bma4_read_int_status(&_status, dev.get()) != 0) {
514 return;
515 }
516
517 if (_status == 0) {
518 return;
519 }
520
521 if ((_status & BMA422_AN_ANY_MOT_INT) && callbacks.onAnyMotion) {
523 }
524
525 if ((_status & BMA422_AN_NO_MOT_INT) && callbacks.onNoMotion) {
527 }
528
529 if ((_status & BMA4_ACCEL_DATA_RDY_INT) && callbacks.onDataReady) {
531 if (readData(data)) {
533 }
534 }
535
536 _status = 0;
537 }
538
539private:
545 bool boschInitImpl() override
546 {
547 int8_t rslt = bma422_an_init(dev.get());
548 if ( rslt != 0 ) {
549 SENSORLIB_LOG_E("bma422_an_init failed with code %d", rslt);
550 return false;
551 }
552 rslt = bma422_an_write_config_file(dev.get());
553 if (rslt != 0) {
554 SENSORLIB_LOG_E("bma422_an_write_config_file failed with code %d", rslt);
555 return false;
556 }
557 return true;
558 }
559protected:
561 uint16_t _status;
562};
563
564#endif
InterruptPinMap
Enumeration of interrupt pin mapping options.
@ PIN1
Interrupt pin 1.
#define SENSORLIB_LOG_E(...)
#define SENSORLIB_LOG_D(...)
~SensorBMA422()=default
Destructor for the SensorBMA422 class.
void setOnNoMotionCallback(std::function< void(void)> cb)
Set the callback for no-motion events.
void setCallbacks(const EventCallbacks &cbs)
Set all callbacks at once.
bool enableAnyMotionDetection(const MotionAxesConfig &cfg, bool enable, bool interrupt_enable=false, InterruptPinMap pin_map=InterruptPinMap::PIN1) override
Enable or disable any-motion detection.
const EventCallbacks & getCallbacks() const
Get the current callbacks (const version)
void update() override
Update sensor state and process interrupts.
bool getNoMotionConfig(float &threshold_mg, float &duration_ms)
Get current no-motion detection configuration.
void setOnDataReadyCallback(std::function< void(AccelerometerData)> cb)
Set the callback for data ready events.
SensorBMA422()
Constructor for the SensorBMA422 class.
void setOnAnyMotionCallback(std::function< void(void)> cb)
Set the any-motion callback for motion events.
bool configNoMotion(uint16_t threshold, uint16_t duration) override
Configure no-motion detection parameters with detailed unit conversion.
bool configNoMotionInPhysicalUnits(float threshold_mg, float duration_ms) override
Configure no-motion detection using physical units.
bool getAnyMotionConfig(float &threshold_mg, float &duration_ms)
Get current motion detection configuration.
bool configAnyMotionInPhysicalUnits(float threshold_mg, float duration_ms) override
Configure any-motion detection using physical units.
BMA4XXCapability::Capability getCapabilities() const override
Get supported capabilities.
bool enableDataReady(bool enable=true, InterruptPinMap pin_map=InterruptPinMap::PIN1) override
Enable data ready interrupt.
bool configAnyMotion(uint16_t threshold, uint16_t duration) override
Configure any-motion detection parameters with detailed unit conversion.
EventCallbacks & getCallbacks()
Get the current callbacks.
bool enableNoMotionDetection(const MotionAxesConfig &cfg, bool enable, bool interrupt_enable=false, InterruptPinMap pin_map=InterruptPinMap::PIN1) override
Enable or disable no-motion detection.
bool configMotion(bool any_motion, uint16_t threshold, uint16_t duration) override
Configure any-motion or no-motion detection parameters with detailed unit conversion.
bool enableInterrupt(InterruptPinMap pin_map, uint16_t interrupt_sources, bool enable)
Enable or disable specific interrupt sources on a pin.
bool readData(AccelerometerData &data) override
Get the accelerometer data.
std::unique_ptr< struct bma4_dev > dev
Structure representing accelerometer data.
std::function< void(void)> onAnyMotion
Callback for any motion detection.
std::function< void(void)> onNoMotion
Callback for no-motion detection.
std::function< void(AccelerometerData &)> onDataReady
Callback for new accelerometer data.
uint8_t z_axis
Enable motion detection on Z-axis (1=enabled, 0=disabled)
uint8_t y_axis
Enable motion detection on Y-axis (1=enabled, 0=disabled)
uint8_t x_axis
Enable motion detection on X-axis (1=enabled, 0=disabled)