From 251fcc044277771f6fa50bb925f661c39da03398 Mon Sep 17 00:00:00 2001 From: tyeth Date: Thu, 13 Nov 2025 11:58:53 +0000 Subject: [PATCH 01/21] ESP32 BSP 3.3.3 --- platformio.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformio.ini b/platformio.ini index a8dc0dd7b..2768a8931 100644 --- a/platformio.ini +++ b/platformio.ini @@ -111,7 +111,7 @@ lib_deps = ; Common build environment for ESP32 platform [common:esp32] -platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.13/platform-espressif32.zip +platform = https://github.com/pioarduino/platform-espressif32/releases/download/55.03.33/platform-espressif32.zip lib_ignore = WiFiNINA, WiFi101 monitor_filters = esp32_exception_decoder, time ; upload_speed = 921600 From e1ae1d07adf0c4d22e2d79bd843a2d4ab4854f58 Mon Sep 17 00:00:00 2001 From: tyeth Date: Thu, 13 Nov 2025 14:28:59 +0000 Subject: [PATCH 02/21] Report halt reason indefinitely --- src/Wippersnapper_V2.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Wippersnapper_V2.cpp b/src/Wippersnapper_V2.cpp index 1bdb80aeb..8f9525299 100644 --- a/src/Wippersnapper_V2.cpp +++ b/src/Wippersnapper_V2.cpp @@ -936,6 +936,7 @@ void Wippersnapper_V2::haltErrorV2(const char *error, if (!reboot) { WsV2.feedWDTV2(); // Feed the WDT indefinitely to hold the WIPPER drive // open + delay(1000); } else { // Let the WDT fail out and reset! #ifndef ARDUINO_ARCH_ESP8266 @@ -946,6 +947,13 @@ void Wippersnapper_V2::haltErrorV2(const char *error, delayMicroseconds(1000000); #endif } + WS_DEBUG_PRINT("ERROR "); + if (reboot) { + WS_DEBUG_PRINT("[RESET]: "); + } else { + WS_DEBUG_PRINT("[HANG]: "); + } + WS_DEBUG_PRINTLN(error); } } From fd47500632b512c749798bfb9e8510fd1c392a52 Mon Sep 17 00:00:00 2001 From: tyeth Date: Fri, 14 Nov 2025 14:46:41 +0000 Subject: [PATCH 03/21] Add boolean sensor type --- src/Wippersnapper_demo.ino | 6 +++++- src/components/i2c/drivers/drvBase.h | 13 +++++++++++++ src/components/i2c/model.cpp | 28 +++++++++++++++++++++++++++ src/provisioning/sdcard/ws_sdcard.cpp | 7 +++++++ 4 files changed, 53 insertions(+), 1 deletion(-) diff --git a/src/Wippersnapper_demo.ino b/src/Wippersnapper_demo.ino index 817f5b53c..b2e9ea0a7 100644 --- a/src/Wippersnapper_demo.ino +++ b/src/Wippersnapper_demo.ino @@ -23,7 +23,11 @@ ws_adapter_offline wipper; void setup() { Serial.begin(115200); - while(!Serial); + // Wait for serial to connect when dev mode, but don't wait forever + uint8_t countdown = 200; + while(!Serial && countdown-- > 0) { + delay(10); + } wipper.provision(); wipper.connect(); } diff --git a/src/components/i2c/drivers/drvBase.h b/src/components/i2c/drivers/drvBase.h index 846ea09d3..b36222392 100644 --- a/src/components/i2c/drivers/drvBase.h +++ b/src/components/i2c/drivers/drvBase.h @@ -511,6 +511,15 @@ class drvBase { return false; } + /*! + @brief Gets a sensor's Boolean value. + @param booleanEvent + The Boolean value. + @returns True if the sensor value was obtained successfully, False + otherwise. + */ + virtual bool getEventBoolean(sensors_event_t *booleanEvent) { return false; } + /*! @brief Gets a sensor's Raw value. @param rawEvent @@ -633,6 +642,10 @@ class drvBase { // Maps SensorType to function calls std::map SensorEventHandlers = { + {wippersnapper_sensor_SensorType_SENSOR_TYPE_BOOLEAN, + [this](sensors_event_t *event) -> bool { + return this->getEventBoolean(event); + }}, {wippersnapper_sensor_SensorType_SENSOR_TYPE_UNSPECIFIED, [this](sensors_event_t *event) -> bool { return this->getEventRaw(event); diff --git a/src/components/i2c/model.cpp b/src/components/i2c/model.cpp index 3003521be..09b978d8c 100644 --- a/src/components/i2c/model.cpp +++ b/src/components/i2c/model.cpp @@ -210,6 +210,28 @@ GetValueFromSensorsEventOrientation(wippersnapper_sensor_SensorType sensor_type, return value; } +/*! + @brief Returns the boolean event value mapped to a sensor + event. + @param sensor_type + The SensorType. + @param event + The sensors_event_t event. + @returns The value of the SensorType as a boolean. +*/ +bool +GetValueFromSensorsEventBoolean(wippersnapper_sensor_SensorType sensor_type, + sensors_event_t *event) { + bool value = false; + WS_DEBUG_PRINTLN("[i2c] Getting boolean event value..."); + WS_DEBUG_PRINT("[i2c] Event data[0]: "); + WS_DEBUG_PRINTLN(event->data[0]); + value = event->data[0] > 0.0f; + WS_DEBUG_PRINT("[i2c] Boolean value (x>0): "); + WS_DEBUG_PRINTLN(value); + return value; +} + /*! @brief Decodes a I2cDeviceRemove message from an input stream. @param stream @@ -472,6 +494,12 @@ bool I2cModel::AddI2cDeviceSensorEvent( .i2c_device_events[_msg_i2c_device_event.i2c_device_events_count] .value.orientation_value.pitch = value_vect.pitch; // TODO: Add color RGB(A) vector support + } else if (sensor_type == + wippersnapper_sensor_SensorType_SENSOR_TYPE_BOOLEAN) { + bool value = GetValueFromSensorsEventBoolean(sensor_type, &event); + _msg_i2c_device_event + .i2c_device_events[_msg_i2c_device_event.i2c_device_events_count] + .value.bool_value = value; } else { float value = GetValueFromSensorsEvent(sensor_type, &event); _msg_i2c_device_event diff --git a/src/provisioning/sdcard/ws_sdcard.cpp b/src/provisioning/sdcard/ws_sdcard.cpp index 0bf7657a7..e82caf08b 100644 --- a/src/provisioning/sdcard/ws_sdcard.cpp +++ b/src/provisioning/sdcard/ws_sdcard.cpp @@ -1480,6 +1480,13 @@ bool ws_sdcard::LogEventI2c( if (!LogJSONDoc(doc)) return false; continue; + } else if (msg_device_event->i2c_device_events[i].type == + wippersnapper_sensor_SensorType_SENSOR_TYPE_BOOLEAN) { + doc["value"] = msg_device_event->i2c_device_events[i].value.bool_value; + doc["si_unit"] = + SensorTypeToSIUnit(msg_device_event->i2c_device_events[i].type); + if (!LogJSONDoc(doc)) + return false; } else { // normal scalar float value doc["value"] = msg_device_event->i2c_device_events[i].value.float_value; doc["si_unit"] = From 3db9c9d3b9d6491778eb120ff5126d9016c3a24d Mon Sep 17 00:00:00 2001 From: tyeth Date: Thu, 13 Nov 2025 15:32:05 +0000 Subject: [PATCH 04/21] [wip] Add LIS3DH --- library.properties | 2 +- platformio.ini | 1 + src/components/i2c/controller.cpp | 5 ++ src/components/i2c/controller.h | 1 + src/components/i2c/drivers/drvLis3dh.cpp | 97 ++++++++++++++++++++++++ src/components/i2c/drivers/drvLis3dh.h | 90 ++++++++++++++++++++++ 6 files changed, 195 insertions(+), 1 deletion(-) create mode 100644 src/components/i2c/drivers/drvLis3dh.cpp create mode 100644 src/components/i2c/drivers/drvLis3dh.h diff --git a/library.properties b/library.properties index c46d7db17..782d124a5 100644 --- a/library.properties +++ b/library.properties @@ -7,4 +7,4 @@ paragraph=Arduino application for Adafruit.io WipperSnapper category=Communication url=https://github.com/adafruit/Adafruit_Wippersnapper_Arduino architectures=* -depends=OmronD6T - Community Fork, SdFat - Adafruit Fork, Adafruit AS5600 Library, Adafruit NeoPixel, Adafruit SPIFlash, ArduinoJson, Adafruit DotStar, Adafruit HDC302x, Adafruit INA219, Adafruit INA237 and INA238 Library, Adafruit INA260 Library, Adafruit LTR329 and LTR303, Adafruit LTR390 Library, Adafruit MCP3421, Adafruit MLX90632 Library, Adafruit NAU7802 Library, Adafruit SleepyDog Library, Adafruit TMP117, Adafruit TinyUSB Library, Adafruit AHTX0, Adafruit BME280 Library, Adafruit BMP280 Library, Adafruit BMP3XX Library, Adafruit DPS310, Adafruit DS248x, Adafruit SCD30, Adafruit SGP30 Sensor, Adafruit SGP40 Sensor, Sensirion I2C SCD4x, Sensirion I2C SEN5X, Sensirion I2C SEN66, arduino-sht, Adafruit Si7021 Library, Adafruit MQTT Library, Adafruit MS8607, Adafruit MCP9808 Library, Adafruit MCP9600 Library, Adafruit MPL115A2, Adafruit MPRLS Library, Adafruit TSL2591 Library, Adafruit_VL53L0X, Adafruit VL53L1X, STM32duino VL53L4CD, STM32duino VL53L4CX, Adafruit_VL6180X, Adafruit PM25 AQI Sensor, Adafruit QMC5883P Library, Adafruit VCNL4020 Library, Adafruit VCNL4040, Adafruit VCNL4200 Library, Adafruit VEML7700 Library, Adafruit LC709203F, Adafruit LPS2X, Adafruit LPS28, Adafruit LPS35HW, Adafruit seesaw Library, Adafruit BME680 Library, Adafruit MAX1704X, Adafruit ADT7410 Library, Adafruit HTS221, Adafruit HTU21DF Library, Adafruit HTU31D Library, Adafruit PCT2075, hp_BH1750, ENS160 - Adafruit Fork, Adafruit BusIO, Adafruit Unified Sensor, Sensirion Core, Adafruit GFX Library, Adafruit LED Backpack Library, Adafruit LiquidCrystal, Adafruit SH110X, Adafruit SSD1306, RTClib, StreamUtils, Adafruit SHT4x Library, Adafruit GPS Library, Adafruit uBlox +depends=OmronD6T - Community Fork, SdFat - Adafruit Fork, Adafruit LIS3DH, Adafruit AS5600 Library, Adafruit NeoPixel, Adafruit SPIFlash, ArduinoJson, Adafruit DotStar, Adafruit HDC302x, Adafruit INA219, Adafruit INA237 and INA238 Library, Adafruit INA260 Library, Adafruit LTR329 and LTR303, Adafruit LTR390 Library, Adafruit MCP3421, Adafruit MLX90632 Library, Adafruit NAU7802 Library, Adafruit SleepyDog Library, Adafruit TMP117, Adafruit TinyUSB Library, Adafruit AHTX0, Adafruit BME280 Library, Adafruit BMP280 Library, Adafruit BMP3XX Library, Adafruit DPS310, Adafruit DS248x, Adafruit SCD30, Adafruit SGP30 Sensor, Adafruit SGP40 Sensor, Sensirion I2C SCD4x, Sensirion I2C SEN5X, Sensirion I2C SEN66, arduino-sht, Adafruit Si7021 Library, Adafruit MQTT Library, Adafruit MS8607, Adafruit MCP9808 Library, Adafruit MCP9600 Library, Adafruit MPL115A2, Adafruit MPRLS Library, Adafruit TSL2591 Library, Adafruit_VL53L0X, Adafruit VL53L1X, STM32duino VL53L4CD, STM32duino VL53L4CX, Adafruit_VL6180X, Adafruit PM25 AQI Sensor, Adafruit QMC5883P Library, Adafruit VCNL4020 Library, Adafruit VCNL4040, Adafruit VCNL4200 Library, Adafruit VEML7700 Library, Adafruit LC709203F, Adafruit LPS2X, Adafruit LPS28, Adafruit LPS35HW, Adafruit seesaw Library, Adafruit BME680 Library, Adafruit MAX1704X, Adafruit ADT7410 Library, Adafruit HTS221, Adafruit HTU21DF Library, Adafruit HTU31D Library, Adafruit PCT2075, hp_BH1750, ENS160 - Adafruit Fork, Adafruit BusIO, Adafruit Unified Sensor, Sensirion Core, Adafruit GFX Library, Adafruit LED Backpack Library, Adafruit LiquidCrystal, Adafruit SH110X, Adafruit SSD1306, RTClib, StreamUtils, Adafruit SHT4x Library, Adafruit GPS Library, Adafruit uBlox diff --git a/platformio.ini b/platformio.ini index 2768a8931..83a6a5799 100644 --- a/platformio.ini +++ b/platformio.ini @@ -46,6 +46,7 @@ lib_deps = adafruit/Adafruit HTS221 adafruit/Adafruit HTU21DF Library adafruit/Adafruit HTU31D Library + adafruit/Adafruit LIS3DH adafruit/Adafruit LTR390 Library adafruit/Adafruit LTR329 and LTR303 adafruit/Adafruit PCT2075 diff --git a/src/components/i2c/controller.cpp b/src/components/i2c/controller.cpp index 6637f80db..4c1401412 100644 --- a/src/components/i2c/controller.cpp +++ b/src/components/i2c/controller.cpp @@ -168,6 +168,11 @@ static const std::map I2cFactorySensor = { const char *driver_name) -> drvBase * { return new drvLc709203f(i2c, addr, mux_channel, driver_name); }}, + {"lis3dh", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvLis3dh(i2c, addr, mux_channel, driver_name); + }}, {"lps3xhw", [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, const char *driver_name) -> drvBase * { diff --git a/src/components/i2c/controller.h b/src/components/i2c/controller.h index 9ef28b5bf..7ddd61320 100644 --- a/src/components/i2c/controller.h +++ b/src/components/i2c/controller.h @@ -40,6 +40,7 @@ #include "drivers/drvIna238.h" #include "drivers/drvIna260.h" #include "drivers/drvLc709203f.h" +#include "drivers/drvLis3dh.h" #include "drivers/drvLps22hb.h" #include "drivers/drvLps25hb.h" #include "drivers/drvLps3xhw.h" diff --git a/src/components/i2c/drivers/drvLis3dh.cpp b/src/components/i2c/drivers/drvLis3dh.cpp new file mode 100644 index 000000000..8021b5a9d --- /dev/null +++ b/src/components/i2c/drivers/drvLis3dh.cpp @@ -0,0 +1,97 @@ +/*! + * @file drvLis3dh.cpp + * + * Driver wrapper for the Adafruit LIS3DH 3-axis accelerometer. + * + */ + +#include "drvLis3dh.h" + +#include +#include + +/******************************************************************************/ +/*! + @brief Destructor for a LIS3DH sensor. +*/ +/******************************************************************************/ +drvLis3dh::~drvLis3dh() { + if (_lis) { + delete _lis; + _lis = nullptr; + } +} + +/******************************************************************************/ +/*! + @brief Initializes the LIS3DH sensor and begins I2C. + @returns True if initialized successfully, False otherwise. +*/ +/******************************************************************************/ +bool drvLis3dh::begin() { + // allocate LIS3DH instance with the I2C bus + _lis = new Adafruit_LIS3DH(_i2c); + + // Attempt to initialize with provided address + if (!_lis->begin(_address)) { + WS_DEBUG_PRINTLN("LIS3DH failed to initialise!"); + return false; + } + + // Set a reasonable range and data rate (use library enums) + _lis->setRange(LIS3DH_RANGE_2_G); // 2G range + // Note: some Adafruit_LIS3DH variants offer setDataRate; if present this + // keeps defaults. Keep configuration minimal to avoid API mismatches. + + return true; +} + +/******************************************************************************/ +/*! + @brief Gets the LIS3DH's raw sensor event. + @param rawEvent + Pointer to the sensor event. + @returns True if the sensor event was obtained successfully, False + otherwise. +*/ +/******************************************************************************/ +bool drvLis3dh::getEventRaw(sensors_event_t *rawEvent) { + if (!_lis) + return false; + + // Read an Adafruit_Sensor compatible event from the device + sensors_event_t event; + _lis->getEvent(&event); + + // Calculate magnitude of the acceleration vector (m/s^2) and store in + // event->data[0] to be consistent with other drivers that expose "raw" + float mag = sqrtf(event.acceleration.x * event.acceleration.x + + event.acceleration.y * event.acceleration.y + + event.acceleration.z * event.acceleration.z); + rawEvent->data[0] = mag; + return true; +} + +/******************************************************************************/ +/*! + @brief Gets the LIS3DH's accelerometer sensor event (x,y,z in m/s^2). + @param accelEvent + Pointer to the accelerometer sensor event. + @returns True if the sensor event was obtained successfully, False + otherwise. +*/ +/******************************************************************************/ +bool drvLis3dh::getEventAccelerometer(sensors_event_t *accelEvent) { + if (!_lis) + return false; + + // Fill the provided event with sensor data + _lis->getEvent(accelEvent); + return true; +} + +void drvLis3dh::ConfigureDefaultSensorTypes() { + _default_sensor_types_count = 1; + _default_sensor_types[0] = + wippersnapper_sensor_SensorType_SENSOR_TYPE_ACCELEROMETER; +} \ No newline at end of file diff --git a/src/components/i2c/drivers/drvLis3dh.h b/src/components/i2c/drivers/drvLis3dh.h new file mode 100644 index 000000000..11dee3cf0 --- /dev/null +++ b/src/components/i2c/drivers/drvLis3dh.h @@ -0,0 +1,90 @@ +/*! + * @file drvLis3dh.h + * + * Driver wrapper for the Adafruit LIS3DH 3-axis accelerometer. + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing + * products from Adafruit! + * + * Copyright (c) Adafruit Industries. + * + * MIT license, all text here must be included in any redistribution. + * + */ +#ifndef DRV_LIS3DH_H +#define DRV_LIS3DH_H + +#include "drvBase.h" +#include + +class Adafruit_LIS3DH; // forward + +/**************************************************************************/ +/*! + @brief Class that provides a driver interface for a LIS3DH accelerometer. +*/ +/**************************************************************************/ +class drvLis3dh : public drvBase { +public: + /*******************************************************************************/ + /*! + @brief Constructor for a LIS3DH sensor. + @param i2c + The I2C interface. + @param sensorAddress + 7-bit device address. + @param mux_channel + The I2C multiplexer channel. + @param driver_name + The name of the driver. + */ + /*******************************************************************************/ + drvLis3dh(TwoWire *i2c, uint16_t sensorAddress, uint32_t mux_channel, + const char *driver_name) + : drvBase(i2c, sensorAddress, mux_channel, driver_name) {} + + /*******************************************************************************/ + /*! + @brief Destructor for a LIS3DH sensor. + */ + /*******************************************************************************/ + ~drvLis3dh(); + + /*******************************************************************************/ + /*! + @brief Initializes the LIS3DH sensor and begins I2C. + @returns True if initialized successfully, False otherwise. + */ + /*******************************************************************************/ + bool begin() override; + + /*******************************************************************************/ + /*! + @brief Gets the LIS3DH's raw sensor event (magnitude stored in + event->data[0]). + @param rawEvent + Pointer to the sensor event to fill. + @returns True if the event was obtained successfully, False otherwise. + */ + /*******************************************************************************/ + bool getEventRaw(sensors_event_t *rawEvent) override; + + /*******************************************************************************/ + /*! + @brief Gets the LIS3DH's accelerometer sensor event (x,y,z in m/s^2). + @param accelEvent + Pointer to the accelerometer sensor event. + @returns True if the sensor event was obtained successfully, False + otherwise. + */ + /*******************************************************************************/ + bool getEventAccelerometer(sensors_event_t *accelEvent) override; + + void ConfigureDefaultSensorTypes() override; + +protected: + Adafruit_LIS3DH *_lis = nullptr; ///< Pointer to LIS3DH sensor object +}; + +#endif // DRV_LIS3DH_H \ No newline at end of file From 1d58b0a4b2058f9addcf4a112764006a1750a8ed Mon Sep 17 00:00:00 2001 From: tyeth Date: Fri, 14 Nov 2025 14:49:29 +0000 Subject: [PATCH 05/21] [wip] LIS3DH Click interrupt detection --- src/components/i2c/drivers/drvLis3dh.cpp | 49 ++++++++++++++++++++++-- src/components/i2c/drivers/drvLis3dh.h | 17 ++++++++ 2 files changed, 63 insertions(+), 3 deletions(-) diff --git a/src/components/i2c/drivers/drvLis3dh.cpp b/src/components/i2c/drivers/drvLis3dh.cpp index 8021b5a9d..fa335e5a6 100644 --- a/src/components/i2c/drivers/drvLis3dh.cpp +++ b/src/components/i2c/drivers/drvLis3dh.cpp @@ -43,6 +43,11 @@ bool drvLis3dh::begin() { // Note: some Adafruit_LIS3DH variants offer setDataRate; if present this // keeps defaults. Keep configuration minimal to avoid API mismatches. + // setup interrupt for click detection (boolean event) + _lis->setClick(1, LIS3DH_CLICKTHRESHHOLD); // 0-2 clicks, threshold 50 + delay(100); // ignore any spurious interrupts right after setup + _lis->readAndClearInterrupt(); + return true; } @@ -58,7 +63,7 @@ bool drvLis3dh::begin() { bool drvLis3dh::getEventRaw(sensors_event_t *rawEvent) { if (!_lis) return false; - + WS_DEBUG_PRINTLN("[drvLis3dh] Getting raw event..."); // Read an Adafruit_Sensor compatible event from the device sensors_event_t event; _lis->getEvent(&event); @@ -69,6 +74,43 @@ bool drvLis3dh::getEventRaw(sensors_event_t *rawEvent) { event.acceleration.y * event.acceleration.y + event.acceleration.z * event.acceleration.z); rawEvent->data[0] = mag; + WS_DEBUG_PRINT("[drvLis3dh] Raw magnitude: "); + WS_DEBUG_PRINTLN(mag); + return true; +} + +/******************************************************************************/ +/*! + @brief Gets the LIS3DH's boolean sensor event. + @param booleanEvent + Pointer to the sensor event. + @returns True if the sensor event was obtained successfully, False + otherwise. +*/ +/******************************************************************************/ +bool drvLis3dh::getEventBoolean(sensors_event_t *booleanEvent) { + if (!_lis) { + return false; + } + WS_DEBUG_PRINTLN("[drvLis3dh] Checking for click event..."); + uint8_t result = _lis->getClick(); + WS_DEBUG_PRINT(" Click result: "); + WS_DEBUG_PRINTHEX(result); + WS_DEBUG_PRINTLN(""); + // does it & 0x30, then 0x20 is double click, 0x10 is single click + WS_DEBUG_PRINTLN("[drvLis3dh] Click result & 0x30: "); + WS_DEBUG_PRINTHEX(result & 0x30); + WS_DEBUG_PRINTLN(""); + uint8_t interruptReason = _lis->readAndClearInterrupt(); + WS_DEBUG_PRINTLN("[drvLis3dh] Interrupt reason: "); + WS_DEBUG_PRINTHEX(interruptReason); + WS_DEBUG_PRINTLN(""); + + // todo: switch on interrupt type - needs driver library expanding + if (interruptReason == 1 && result == 1) { + WS_DEBUG_PRINTLN("[drvLis3dh] Click event detected!"); + } + booleanEvent->data[0] = result ? 1.0f : 0.0f; return true; } @@ -82,9 +124,10 @@ bool drvLis3dh::getEventRaw(sensors_event_t *rawEvent) { */ /******************************************************************************/ bool drvLis3dh::getEventAccelerometer(sensors_event_t *accelEvent) { - if (!_lis) + if (!_lis) { return false; - + } + WS_DEBUG_PRINTLN("[drvLis3dh] Getting accelerometer event..."); // Fill the provided event with sensor data _lis->getEvent(accelEvent); return true; diff --git a/src/components/i2c/drivers/drvLis3dh.h b/src/components/i2c/drivers/drvLis3dh.h index 11dee3cf0..832a6b488 100644 --- a/src/components/i2c/drivers/drvLis3dh.h +++ b/src/components/i2c/drivers/drvLis3dh.h @@ -15,11 +15,17 @@ #ifndef DRV_LIS3DH_H #define DRV_LIS3DH_H +#include "Wippersnapper_V2.h" #include "drvBase.h" #include class Adafruit_LIS3DH; // forward +// Adjust this number for the sensitivity of the 'click' force +// this strongly depend on the range! for 16G, try 5-10 +// for 8G, try 10-20. for 4G try 20-40. for 2G try 40-80 +#define LIS3DH_CLICKTHRESHHOLD 40 + /**************************************************************************/ /*! @brief Class that provides a driver interface for a LIS3DH accelerometer. @@ -59,6 +65,17 @@ class drvLis3dh : public drvBase { /*******************************************************************************/ bool begin() override; + /******************************************************************************/ + /*! + @brief Gets the LIS3DH's boolean sensor event. + @param booleanEvent + Pointer to the sensor event. + @returns True if the sensor event was obtained successfully, False + otherwise. + */ + /******************************************************************************/ + bool getEventBoolean(sensors_event_t *booleanEvent) override; + /*******************************************************************************/ /*! @brief Gets the LIS3DH's raw sensor event (magnitude stored in From a1d66f6d0934760eb511b987f4a50e23d6f2518b Mon Sep 17 00:00:00 2001 From: tyeth Date: Fri, 14 Nov 2025 16:44:25 +0000 Subject: [PATCH 06/21] Add LSM9DS1 I2C driver --- library.properties | 2 +- platformio.ini | 1 + src/components/i2c/controller.cpp | 5 + src/components/i2c/controller.h | 1 + src/components/i2c/drivers/drvLsm9ds1.cpp | 174 ++++++++++++++++++++++ src/components/i2c/drivers/drvLsm9ds1.h | 130 ++++++++++++++++ 6 files changed, 312 insertions(+), 1 deletion(-) create mode 100644 src/components/i2c/drivers/drvLsm9ds1.cpp create mode 100644 src/components/i2c/drivers/drvLsm9ds1.h diff --git a/library.properties b/library.properties index 782d124a5..227b6ff2c 100644 --- a/library.properties +++ b/library.properties @@ -7,4 +7,4 @@ paragraph=Arduino application for Adafruit.io WipperSnapper category=Communication url=https://github.com/adafruit/Adafruit_Wippersnapper_Arduino architectures=* -depends=OmronD6T - Community Fork, SdFat - Adafruit Fork, Adafruit LIS3DH, Adafruit AS5600 Library, Adafruit NeoPixel, Adafruit SPIFlash, ArduinoJson, Adafruit DotStar, Adafruit HDC302x, Adafruit INA219, Adafruit INA237 and INA238 Library, Adafruit INA260 Library, Adafruit LTR329 and LTR303, Adafruit LTR390 Library, Adafruit MCP3421, Adafruit MLX90632 Library, Adafruit NAU7802 Library, Adafruit SleepyDog Library, Adafruit TMP117, Adafruit TinyUSB Library, Adafruit AHTX0, Adafruit BME280 Library, Adafruit BMP280 Library, Adafruit BMP3XX Library, Adafruit DPS310, Adafruit DS248x, Adafruit SCD30, Adafruit SGP30 Sensor, Adafruit SGP40 Sensor, Sensirion I2C SCD4x, Sensirion I2C SEN5X, Sensirion I2C SEN66, arduino-sht, Adafruit Si7021 Library, Adafruit MQTT Library, Adafruit MS8607, Adafruit MCP9808 Library, Adafruit MCP9600 Library, Adafruit MPL115A2, Adafruit MPRLS Library, Adafruit TSL2591 Library, Adafruit_VL53L0X, Adafruit VL53L1X, STM32duino VL53L4CD, STM32duino VL53L4CX, Adafruit_VL6180X, Adafruit PM25 AQI Sensor, Adafruit QMC5883P Library, Adafruit VCNL4020 Library, Adafruit VCNL4040, Adafruit VCNL4200 Library, Adafruit VEML7700 Library, Adafruit LC709203F, Adafruit LPS2X, Adafruit LPS28, Adafruit LPS35HW, Adafruit seesaw Library, Adafruit BME680 Library, Adafruit MAX1704X, Adafruit ADT7410 Library, Adafruit HTS221, Adafruit HTU21DF Library, Adafruit HTU31D Library, Adafruit PCT2075, hp_BH1750, ENS160 - Adafruit Fork, Adafruit BusIO, Adafruit Unified Sensor, Sensirion Core, Adafruit GFX Library, Adafruit LED Backpack Library, Adafruit LiquidCrystal, Adafruit SH110X, Adafruit SSD1306, RTClib, StreamUtils, Adafruit SHT4x Library, Adafruit GPS Library, Adafruit uBlox +depends=OmronD6T - Community Fork, SdFat - Adafruit Fork, Adafruit LIS3DH, Adafruit LSM9DS1 Library, Adafruit AS5600 Library, Adafruit NeoPixel, Adafruit SPIFlash, ArduinoJson, Adafruit DotStar, Adafruit HDC302x, Adafruit INA219, Adafruit INA237 and INA238 Library, Adafruit INA260 Library, Adafruit LTR329 and LTR303, Adafruit LTR390 Library, Adafruit MCP3421, Adafruit MLX90632 Library, Adafruit NAU7802 Library, Adafruit SleepyDog Library, Adafruit TMP117, Adafruit TinyUSB Library, Adafruit AHTX0, Adafruit BME280 Library, Adafruit BMP280 Library, Adafruit BMP3XX Library, Adafruit DPS310, Adafruit DS248x, Adafruit SCD30, Adafruit SGP30 Sensor, Adafruit SGP40 Sensor, Sensirion I2C SCD4x, Sensirion I2C SEN5X, Sensirion I2C SEN66, arduino-sht, Adafruit Si7021 Library, Adafruit MQTT Library, Adafruit MS8607, Adafruit MCP9808 Library, Adafruit MCP9600 Library, Adafruit MPL115A2, Adafruit MPRLS Library, Adafruit TSL2591 Library, Adafruit_VL53L0X, Adafruit VL53L1X, STM32duino VL53L4CD, STM32duino VL53L4CX, Adafruit_VL6180X, Adafruit PM25 AQI Sensor, Adafruit QMC5883P Library, Adafruit VCNL4020 Library, Adafruit VCNL4040, Adafruit VCNL4200 Library, Adafruit VEML7700 Library, Adafruit LC709203F, Adafruit LPS2X, Adafruit LPS28, Adafruit LPS35HW, Adafruit seesaw Library, Adafruit BME680 Library, Adafruit MAX1704X, Adafruit ADT7410 Library, Adafruit HTS221, Adafruit HTU21DF Library, Adafruit HTU31D Library, Adafruit PCT2075, hp_BH1750, ENS160 - Adafruit Fork, Adafruit BusIO, Adafruit Unified Sensor, Sensirion Core, Adafruit GFX Library, Adafruit LED Backpack Library, Adafruit LiquidCrystal, Adafruit SH110X, Adafruit SSD1306, RTClib, StreamUtils, Adafruit SHT4x Library, Adafruit GPS Library, Adafruit uBlox diff --git a/platformio.ini b/platformio.ini index 83a6a5799..28b7457d1 100644 --- a/platformio.ini +++ b/platformio.ini @@ -47,6 +47,7 @@ lib_deps = adafruit/Adafruit HTU21DF Library adafruit/Adafruit HTU31D Library adafruit/Adafruit LIS3DH + adafruit/Adafruit LSM9DS1 Library adafruit/Adafruit LTR390 Library adafruit/Adafruit LTR329 and LTR303 adafruit/Adafruit PCT2075 diff --git a/src/components/i2c/controller.cpp b/src/components/i2c/controller.cpp index 4c1401412..41053f73a 100644 --- a/src/components/i2c/controller.cpp +++ b/src/components/i2c/controller.cpp @@ -173,6 +173,11 @@ static const std::map I2cFactorySensor = { const char *driver_name) -> drvBase * { return new drvLis3dh(i2c, addr, mux_channel, driver_name); }}, + {"lsm9ds1", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvLsm9ds1(i2c, addr, mux_channel, driver_name); + }}, {"lps3xhw", [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, const char *driver_name) -> drvBase * { diff --git a/src/components/i2c/controller.h b/src/components/i2c/controller.h index 7ddd61320..8e5133fa5 100644 --- a/src/components/i2c/controller.h +++ b/src/components/i2c/controller.h @@ -41,6 +41,7 @@ #include "drivers/drvIna260.h" #include "drivers/drvLc709203f.h" #include "drivers/drvLis3dh.h" +#include "drivers/drvLsm9ds1.h" #include "drivers/drvLps22hb.h" #include "drivers/drvLps25hb.h" #include "drivers/drvLps3xhw.h" diff --git a/src/components/i2c/drivers/drvLsm9ds1.cpp b/src/components/i2c/drivers/drvLsm9ds1.cpp new file mode 100644 index 000000000..30ec4aa1f --- /dev/null +++ b/src/components/i2c/drivers/drvLsm9ds1.cpp @@ -0,0 +1,174 @@ +/*! + * @file drvLsm9ds1.cpp + * + * Driver wrapper for the Adafruit LSM9DS1 9-DOF IMU. + * + */ + +#include "drvLsm9ds1.h" + +#include +#include + +/******************************************************************************/ +/*! + @brief Destructor for a LSM9DS1 sensor. +*/ +/******************************************************************************/ +drvLsm9ds1::~drvLsm9ds1() { + if (_lsm) { + delete _lsm; + _lsm = nullptr; + } +} + +/******************************************************************************/ +/*! + @brief Initializes the LSM9DS1 sensor and begins I2C. + @returns True if initialized successfully, False otherwise. +*/ +/******************************************************************************/ +bool drvLsm9ds1::begin() { + _lsm = new Adafruit_LSM9DS1(_i2c); + // Consumes I2C Addresses 0x1E and 0x6B + if (!_lsm->begin()) { + WS_DEBUG_PRINTLN("LSM9DS1 failed to initialise!"); + return false; + } + + // Mirror the configuration used by the reference example + _lsm->setupAccel(_lsm->LSM9DS1_ACCELRANGE_2G, + _lsm->LSM9DS1_ACCELDATARATE_10HZ); + _lsm->setupMag(_lsm->LSM9DS1_MAGGAIN_4GAUSS); + _lsm->setupGyro(_lsm->LSM9DS1_GYROSCALE_245DPS); + + return true; +} + +bool drvLsm9ds1::readAllEvents(sensors_event_t *accel, + sensors_event_t *mag, + sensors_event_t *gyro, + sensors_event_t *temp) { + if (!_lsm) { + return false; + } + _lsm->read(); + _lsm->getEvent(accel, mag, gyro, temp); + return true; +} + +/******************************************************************************/ +/*! + @brief Gets the LSM9DS1's raw sensor event. + @param rawEvent + Pointer to the sensor event. + @returns True if the sensor event was obtained successfully, False + otherwise. +*/ +/******************************************************************************/ +bool drvLsm9ds1::getEventRaw(sensors_event_t *rawEvent) { + //TODO: Not yet, but eventually migrate to providing the temperatre data here + WS_DEBUG_PRINTLN("[drvLsm9ds1] Getting raw event..."); + sensors_event_t accel, mag, gyro, temp; + if (!readAllEvents(&accel, &mag, &gyro, &temp)) { + return false; + } + + float mag_accel = sqrtf(accel.acceleration.x * accel.acceleration.x + + accel.acceleration.y * accel.acceleration.y + + accel.acceleration.z * accel.acceleration.z); + rawEvent->data[0] = mag_accel; + WS_DEBUG_PRINT("[drvLsm9ds1] Raw magnitude: "); + WS_DEBUG_PRINTLN(mag_accel); + return true; +} + +/******************************************************************************/ +/*! + @brief Gets the LSM9DS1's boolean sensor event. + @param booleanEvent + Pointer to the sensor event. + @returns True if the sensor event was obtained successfully, False + otherwise. +*/ +/******************************************************************************/ +bool drvLsm9ds1::getEventBoolean(sensors_event_t *booleanEvent) { + WS_DEBUG_PRINTLN("[drvLsm9ds1] Checking for tap event..."); + sensors_event_t accel, mag, gyro, temp; + if (!readAllEvents(&accel, &mag, &gyro, &temp)) { + return false; + } + + float mag_accel = sqrtf(accel.acceleration.x * accel.acceleration.x + + accel.acceleration.y * accel.acceleration.y + + accel.acceleration.z * accel.acceleration.z); + + bool tap_detected = (mag_accel > LSM9DS1_TAP_THRESHOLD_MSS); + booleanEvent->data[0] = tap_detected ? 1.0f : 0.0f; + + if (tap_detected) { + WS_DEBUG_PRINTLN("[drvLsm9ds1] Tap event detected!"); + } + + return true; +} + +/******************************************************************************/ +/*! + @brief Gets the LSM9DS1's accelerometer sensor event (x,y,z in m/s^2). + @param accelEvent + Pointer to the accelerometer sensor event. + @returns True if the sensor event was obtained successfully, False + otherwise. +*/ +/******************************************************************************/ +bool drvLsm9ds1::getEventAccelerometer(sensors_event_t *accelEvent) { + WS_DEBUG_PRINTLN("[drvLsm9ds1] Getting accelerometer event..."); + sensors_event_t mag, gyro, temp; + if (!readAllEvents(accelEvent, &mag, &gyro, &temp)) { + return false; + } + return true; +} + +/******************************************************************************/ +/*! + @brief Gets the LSM9DS1's gyroscope sensor event (x,y,z in rad/s). + @param gyroEvent + Pointer to the gyroscope sensor event. + @returns True if the sensor event was obtained successfully, False + otherwise. +*/ +/******************************************************************************/ +bool drvLsm9ds1::getEventGyroscope(sensors_event_t *gyroEvent) { + WS_DEBUG_PRINTLN("[drvLsm9ds1] Getting gyroscope event..."); + sensors_event_t accel, mag, temp; + if (!readAllEvents(&accel, &mag, gyroEvent, &temp)) { + return false; + } + return true; +} + +/******************************************************************************/ +/*! + @brief Gets the LSM9DS1's magnetometer sensor event (x,y,z in uT). + @param magEvent + Pointer to the magnetometer sensor event. + @returns True if the sensor event was obtained successfully, False + otherwise. +*/ +/******************************************************************************/ +bool drvLsm9ds1::getEventMagneticField(sensors_event_t *magEvent) { + WS_DEBUG_PRINTLN("[drvLsm9ds1] Getting magnetometer event..."); + sensors_event_t accel, gyro, temp; + if (!readAllEvents(&accel, magEvent, &gyro, &temp)) { + return false; + } + return true; +} + +void drvLsm9ds1::ConfigureDefaultSensorTypes() { + _default_sensor_types_count = 1; + _default_sensor_types[0] = + wippersnapper_sensor_SensorType_SENSOR_TYPE_ACCELEROMETER; +} diff --git a/src/components/i2c/drivers/drvLsm9ds1.h b/src/components/i2c/drivers/drvLsm9ds1.h new file mode 100644 index 000000000..b5fb1c47b --- /dev/null +++ b/src/components/i2c/drivers/drvLsm9ds1.h @@ -0,0 +1,130 @@ +/*! + * @file drvLsm9ds1.h + * + * Driver wrapper for the Adafruit LSM9DS1 9-DOF IMU. + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing + * products from Adafruit! + * + * Copyright (c) Adafruit Industries. + * + * MIT license, all text here must be included in any redistribution. + * + */ +#ifndef DRV_LSM9DS1_H +#define DRV_LSM9DS1_H + +#include "Wippersnapper_V2.h" +#include "drvBase.h" +#include + +class Adafruit_LSM9DS1; // forward + +// Approximate acceleration magnitude (m/s^2) that triggers a tap event +#define LSM9DS1_TAP_THRESHOLD_MSS 15.0f + +/**************************************************************************/ +/*! + @brief Class that provides a driver interface for a LSM9DS1 IMU. +*/ +/**************************************************************************/ +class drvLsm9ds1 : public drvBase { +public: + /*******************************************************************************/ + /*! + @brief Constructor for a LSM9DS1 sensor. + @param i2c + The I2C interface. + @param sensorAddress + 7-bit device address. + @param mux_channel + The I2C multiplexer channel. + @param driver_name + The name of the driver. + */ + /*******************************************************************************/ + drvLsm9ds1(TwoWire *i2c, uint16_t sensorAddress, uint32_t mux_channel, + const char *driver_name) + : drvBase(i2c, sensorAddress, mux_channel, driver_name) {} + + /*******************************************************************************/ + /*! + @brief Destructor for a LSM9DS1 sensor. + */ + /*******************************************************************************/ + ~drvLsm9ds1(); + + /*******************************************************************************/ + /*! + @brief Initializes the LSM9DS1 sensor and begins I2C. + @returns True if initialized successfully, False otherwise. + */ + /*******************************************************************************/ + bool begin() override; + + /******************************************************************************/ + /*! + @brief Gets the LSM9DS1's boolean sensor event. + @param booleanEvent + Pointer to the sensor event. + @returns True if the sensor event was obtained successfully, False + otherwise. + */ + /******************************************************************************/ + bool getEventBoolean(sensors_event_t *booleanEvent) override; + + /*******************************************************************************/ + /*! + @brief Gets the LSM9DS1's raw sensor event (magnitude stored in + event->data[0]). + @param rawEvent + Pointer to the sensor event to fill. + @returns True if the event was obtained successfully, False otherwise. + */ + /*******************************************************************************/ + bool getEventRaw(sensors_event_t *rawEvent) override; + + /*******************************************************************************/ + /*! + @brief Gets the LSM9DS1's accelerometer sensor event (x,y,z in m/s^2). + @param accelEvent + Pointer to the accelerometer sensor event. + @returns True if the sensor event was obtained successfully, False + otherwise. + */ + /*******************************************************************************/ + bool getEventAccelerometer(sensors_event_t *accelEvent) override; + + /*******************************************************************************/ + /*! + @brief Gets the LSM9DS1's gyroscope sensor event (x,y,z in rad/s). + @param gyroEvent + Pointer to the gyroscope sensor event. + @returns True if the sensor event was obtained successfully, False + otherwise. + */ + /*******************************************************************************/ + bool getEventGyroscope(sensors_event_t *gyroEvent) override; + + /*******************************************************************************/ + /*! + @brief Gets the LSM9DS1's magnetometer sensor event (x,y,z in uT). + @param magEvent + Pointer to the magnetometer sensor event. + @returns True if the sensor event was obtained successfully, False + otherwise. + */ + /*******************************************************************************/ + bool getEventMagneticField(sensors_event_t *magEvent) override; + + void ConfigureDefaultSensorTypes() override; + +protected: + Adafruit_LSM9DS1 *_lsm = nullptr; ///< Pointer to LSM9DS1 sensor object + + bool readAllEvents(sensors_event_t *accel, sensors_event_t *mag, + sensors_event_t *gyro, sensors_event_t *temp); +}; + +#endif // DRV_LSM9DS1_H From c3a0dcd1ddea5aaa066db10d48182c9180532a9a Mon Sep 17 00:00:00 2001 From: tyeth Date: Fri, 14 Nov 2025 17:26:26 +0000 Subject: [PATCH 07/21] [wip] ISM330DLC + ISM330DHCX --- library.properties | 2 +- platformio.ini | 1 + src/components/i2c/controller.cpp | 10 ++ src/components/i2c/controller.h | 2 + src/components/i2c/drivers/drvIsm330dhcx.cpp | 127 +++++++++++++++++++ src/components/i2c/drivers/drvIsm330dhcx.h | 37 ++++++ src/components/i2c/drivers/drvIsm330dlc.cpp | 127 +++++++++++++++++++ src/components/i2c/drivers/drvIsm330dlc.h | 43 +++++++ 8 files changed, 348 insertions(+), 1 deletion(-) create mode 100644 src/components/i2c/drivers/drvIsm330dhcx.cpp create mode 100644 src/components/i2c/drivers/drvIsm330dhcx.h create mode 100644 src/components/i2c/drivers/drvIsm330dlc.cpp create mode 100644 src/components/i2c/drivers/drvIsm330dlc.h diff --git a/library.properties b/library.properties index 227b6ff2c..cb868828f 100644 --- a/library.properties +++ b/library.properties @@ -7,4 +7,4 @@ paragraph=Arduino application for Adafruit.io WipperSnapper category=Communication url=https://github.com/adafruit/Adafruit_Wippersnapper_Arduino architectures=* -depends=OmronD6T - Community Fork, SdFat - Adafruit Fork, Adafruit LIS3DH, Adafruit LSM9DS1 Library, Adafruit AS5600 Library, Adafruit NeoPixel, Adafruit SPIFlash, ArduinoJson, Adafruit DotStar, Adafruit HDC302x, Adafruit INA219, Adafruit INA237 and INA238 Library, Adafruit INA260 Library, Adafruit LTR329 and LTR303, Adafruit LTR390 Library, Adafruit MCP3421, Adafruit MLX90632 Library, Adafruit NAU7802 Library, Adafruit SleepyDog Library, Adafruit TMP117, Adafruit TinyUSB Library, Adafruit AHTX0, Adafruit BME280 Library, Adafruit BMP280 Library, Adafruit BMP3XX Library, Adafruit DPS310, Adafruit DS248x, Adafruit SCD30, Adafruit SGP30 Sensor, Adafruit SGP40 Sensor, Sensirion I2C SCD4x, Sensirion I2C SEN5X, Sensirion I2C SEN66, arduino-sht, Adafruit Si7021 Library, Adafruit MQTT Library, Adafruit MS8607, Adafruit MCP9808 Library, Adafruit MCP9600 Library, Adafruit MPL115A2, Adafruit MPRLS Library, Adafruit TSL2591 Library, Adafruit_VL53L0X, Adafruit VL53L1X, STM32duino VL53L4CD, STM32duino VL53L4CX, Adafruit_VL6180X, Adafruit PM25 AQI Sensor, Adafruit QMC5883P Library, Adafruit VCNL4020 Library, Adafruit VCNL4040, Adafruit VCNL4200 Library, Adafruit VEML7700 Library, Adafruit LC709203F, Adafruit LPS2X, Adafruit LPS28, Adafruit LPS35HW, Adafruit seesaw Library, Adafruit BME680 Library, Adafruit MAX1704X, Adafruit ADT7410 Library, Adafruit HTS221, Adafruit HTU21DF Library, Adafruit HTU31D Library, Adafruit PCT2075, hp_BH1750, ENS160 - Adafruit Fork, Adafruit BusIO, Adafruit Unified Sensor, Sensirion Core, Adafruit GFX Library, Adafruit LED Backpack Library, Adafruit LiquidCrystal, Adafruit SH110X, Adafruit SSD1306, RTClib, StreamUtils, Adafruit SHT4x Library, Adafruit GPS Library, Adafruit uBlox +depends=OmronD6T - Community Fork, SdFat - Adafruit Fork, Adafruit LIS3DH, Adafruit LSM6DS Library, Adafruit LSM9DS1 Library, Adafruit AS5600 Library, Adafruit NeoPixel, Adafruit SPIFlash, ArduinoJson, Adafruit DotStar, Adafruit HDC302x, Adafruit INA219, Adafruit INA237 and INA238 Library, Adafruit INA260 Library, Adafruit LTR329 and LTR303, Adafruit LTR390 Library, Adafruit MCP3421, Adafruit MLX90632 Library, Adafruit NAU7802 Library, Adafruit SleepyDog Library, Adafruit TMP117, Adafruit TinyUSB Library, Adafruit AHTX0, Adafruit BME280 Library, Adafruit BMP280 Library, Adafruit BMP3XX Library, Adafruit DPS310, Adafruit DS248x, Adafruit SCD30, Adafruit SGP30 Sensor, Adafruit SGP40 Sensor, Sensirion I2C SCD4x, Sensirion I2C SEN5X, Sensirion I2C SEN66, arduino-sht, Adafruit Si7021 Library, Adafruit MQTT Library, Adafruit MS8607, Adafruit MCP9808 Library, Adafruit MCP9600 Library, Adafruit MPL115A2, Adafruit MPRLS Library, Adafruit TSL2591 Library, Adafruit_VL53L0X, Adafruit VL53L1X, STM32duino VL53L4CD, STM32duino VL53L4CX, Adafruit_VL6180X, Adafruit PM25 AQI Sensor, Adafruit QMC5883P Library, Adafruit VCNL4020 Library, Adafruit VCNL4040, Adafruit VCNL4200 Library, Adafruit VEML7700 Library, Adafruit LC709203F, Adafruit LPS2X, Adafruit LPS28, Adafruit LPS35HW, Adafruit seesaw Library, Adafruit BME680 Library, Adafruit MAX1704X, Adafruit ADT7410 Library, Adafruit HTS221, Adafruit HTU21DF Library, Adafruit HTU31D Library, Adafruit PCT2075, hp_BH1750, ENS160 - Adafruit Fork, Adafruit BusIO, Adafruit Unified Sensor, Sensirion Core, Adafruit GFX Library, Adafruit LED Backpack Library, Adafruit LiquidCrystal, Adafruit SH110X, Adafruit SSD1306, RTClib, StreamUtils, Adafruit SHT4x Library, Adafruit GPS Library, Adafruit uBlox diff --git a/platformio.ini b/platformio.ini index 28b7457d1..3b7e04d59 100644 --- a/platformio.ini +++ b/platformio.ini @@ -47,6 +47,7 @@ lib_deps = adafruit/Adafruit HTU21DF Library adafruit/Adafruit HTU31D Library adafruit/Adafruit LIS3DH + adafruit/Adafruit LSM6DS adafruit/Adafruit LSM9DS1 Library adafruit/Adafruit LTR390 Library adafruit/Adafruit LTR329 and LTR303 diff --git a/src/components/i2c/controller.cpp b/src/components/i2c/controller.cpp index 41053f73a..7e0e9c737 100644 --- a/src/components/i2c/controller.cpp +++ b/src/components/i2c/controller.cpp @@ -173,6 +173,16 @@ static const std::map I2cFactorySensor = { const char *driver_name) -> drvBase * { return new drvLis3dh(i2c, addr, mux_channel, driver_name); }}, + {"ism330dlc", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvIsm330dlc(i2c, addr, mux_channel, driver_name); + }}, + {"ism330dhcx", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvIsm330dhcx(i2c, addr, mux_channel, driver_name); + }}, {"lsm9ds1", [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, const char *driver_name) -> drvBase * { diff --git a/src/components/i2c/controller.h b/src/components/i2c/controller.h index 8e5133fa5..8d6232d84 100644 --- a/src/components/i2c/controller.h +++ b/src/components/i2c/controller.h @@ -41,6 +41,8 @@ #include "drivers/drvIna260.h" #include "drivers/drvLc709203f.h" #include "drivers/drvLis3dh.h" +#include "drivers/drvIsm330dhcx.h" +#include "drivers/drvIsm330dlc.h" #include "drivers/drvLsm9ds1.h" #include "drivers/drvLps22hb.h" #include "drivers/drvLps25hb.h" diff --git a/src/components/i2c/drivers/drvIsm330dhcx.cpp b/src/components/i2c/drivers/drvIsm330dhcx.cpp new file mode 100644 index 000000000..7f7dab50d --- /dev/null +++ b/src/components/i2c/drivers/drvIsm330dhcx.cpp @@ -0,0 +1,127 @@ +/*! + * @file drvIsm330dhcx.cpp + * + * Driver wrapper for the Adafruit ISM330DHCX (LSM6DSOX core) 6-DoF IMU. + */ + +#include "drvIsm330dhcx.h" + +#include + +drvIsm330dhcx::drvIsm330dhcx(TwoWire *i2c, uint16_t sensorAddress, + uint32_t mux_channel, const char *driver_name) + : drvBase(i2c, sensorAddress, mux_channel, driver_name) {} + +drvIsm330dhcx::~drvIsm330dhcx() { + if (_imu) { + delete _imu; + _imu = nullptr; + } +} + +bool drvIsm330dhcx::begin() { + if (_imu) { + delete _imu; + _imu = nullptr; + } + + _imu = new Adafruit_ISM330DHCX(); + if (!_imu) { + return false; + } + + uint8_t addr = _address == 0 ? LSM6DS_I2CADDR_DEFAULT : (uint8_t)_address; + WS_DEBUG_PRINT("[drvIsm330dhcx] Initialising @ 0x"); + WS_DEBUG_PRINTHEX(addr); + WS_DEBUG_PRINTLN("..."); + + if (!_imu->begin_I2C(addr, _i2c)) { + WS_DEBUG_PRINTLN("[drvIsm330dhcx] Failed to initialise sensor"); + delete _imu; + _imu = nullptr; + return false; + } + + _imu->setAccelRange(LSM6DS_ACCEL_RANGE_4_G); + _imu->setAccelDataRate(LSM6DS_RATE_104_HZ); + _imu->setGyroRange(LSM6DS_GYRO_RANGE_500_DPS); + _imu->setGyroDataRate(LSM6DS_RATE_104_HZ); + _imu->configInt1(false, false, false, false, true); + _imu->configInt2(false, false, false); + _imu->enableWakeup(true); + + WS_DEBUG_PRINTLN("[drvIsm330dhcx] Sensor initialised successfully"); + return true; +} + +bool drvIsm330dhcx::readAllEvents(sensors_event_t *accel, + sensors_event_t *gyro, + sensors_event_t *temp) { + if (!_imu) { + return false; + } + return _imu->getEvent(accel, gyro, temp); +} + +bool drvIsm330dhcx::computeAccelMagnitude(float &magnitude) { + sensors_event_t accel, gyro, temp; + if (!readAllEvents(&accel, &gyro, &temp)) { + return false; + } + magnitude = sqrtf(accel.acceleration.x * accel.acceleration.x + + accel.acceleration.y * accel.acceleration.y + + accel.acceleration.z * accel.acceleration.z); + return true; +} + +bool drvIsm330dhcx::getEventRaw(sensors_event_t *rawEvent) { + if (!_imu) { + return false; + } + WS_DEBUG_PRINTLN("[drvIsm330dhcx] Getting raw magnitude event..."); + float magnitude = 0.0f; + if (!computeAccelMagnitude(magnitude)) { + return false; + } + rawEvent->data[0] = magnitude; + WS_DEBUG_PRINT("[drvIsm330dhcx] Raw magnitude: "); + WS_DEBUG_PRINTLN(magnitude); + return true; +} + +bool drvIsm330dhcx::getEventBoolean(sensors_event_t *booleanEvent) { + if (!_imu) { + return false; + } + WS_DEBUG_PRINTLN("[drvIsm330dhcx] Checking for tap/threshold event..."); + bool tap = _imu->shake(); + booleanEvent->data[0] = tap ? 1.0f : 0.0f; + if (tap) { + WS_DEBUG_PRINTLN("[drvIsm330dhcx] Threshold event detected"); + } + return true; +} + +bool drvIsm330dhcx::getEventAccelerometer(sensors_event_t *accelEvent) { + if (!_imu) { + return false; + } + WS_DEBUG_PRINTLN("[drvIsm330dhcx] Getting accelerometer event..."); + sensors_event_t gyro, temp; + return readAllEvents(accelEvent, &gyro, &temp); +} + +bool drvIsm330dhcx::getEventGyroscope(sensors_event_t *gyroEvent) { + if (!_imu) { + return false; + } + WS_DEBUG_PRINTLN("[drvIsm330dhcx] Getting gyroscope event..."); + sensors_event_t accel, temp; + return readAllEvents(&accel, gyroEvent, &temp); +} + +void drvIsm330dhcx::ConfigureDefaultSensorTypes() { + _default_sensor_types_count = 1; + _default_sensor_types[0] = + wippersnapper_sensor_SensorType_SENSOR_TYPE_ACCELEROMETER; +} diff --git a/src/components/i2c/drivers/drvIsm330dhcx.h b/src/components/i2c/drivers/drvIsm330dhcx.h new file mode 100644 index 000000000..c5d25ee12 --- /dev/null +++ b/src/components/i2c/drivers/drvIsm330dhcx.h @@ -0,0 +1,37 @@ +/*! + * @file drvIsm330dhcx.h + * + * Driver wrapper for the Adafruit ISM330DHCX (LSM6DSOX core) 6-DoF IMU. + */ +#ifndef DRV_ISM330DHCX_H +#define DRV_ISM330DHCX_H + +#include "Wippersnapper_V2.h" +#include "drvBase.h" +#include + +#define ISM330_TAP_THRESHOLD_MSS 15.0f + +class drvIsm330dhcx : public drvBase { +public: + drvIsm330dhcx(TwoWire *i2c, uint16_t sensorAddress, uint32_t mux_channel, + const char *driver_name); + ~drvIsm330dhcx(); + + bool begin() override; + bool getEventBoolean(sensors_event_t *booleanEvent) override; + bool getEventRaw(sensors_event_t *rawEvent) override; + bool getEventAccelerometer(sensors_event_t *accelEvent) override; + bool getEventGyroscope(sensors_event_t *gyroEvent) override; + + void ConfigureDefaultSensorTypes() override; + +private: + bool readAllEvents(sensors_event_t *accel, sensors_event_t *gyro, + sensors_event_t *temp); + bool computeAccelMagnitude(float &magnitude); + + Adafruit_ISM330DHCX *_imu = nullptr; ///< Pointer to the ISM330DHCX sensor +}; + +#endif // DRV_ISM330DHCX_H diff --git a/src/components/i2c/drivers/drvIsm330dlc.cpp b/src/components/i2c/drivers/drvIsm330dlc.cpp new file mode 100644 index 000000000..38f0c80e5 --- /dev/null +++ b/src/components/i2c/drivers/drvIsm330dlc.cpp @@ -0,0 +1,127 @@ +/*! + * @file drvIsm330dlc.cpp + * + * Driver wrapper for the Adafruit ISM330DLC (LSM6DSL core) 6-DoF IMU. + */ + +#include "drvIsm330dlc.h" + +#include + +drvIsm330dlc::drvIsm330dlc(TwoWire *i2c, uint16_t sensorAddress, + uint32_t mux_channel, const char *driver_name) + : drvBase(i2c, sensorAddress, mux_channel, driver_name) {} + +drvIsm330dlc::~drvIsm330dlc() { + if (_imu) { + delete _imu; + _imu = nullptr; + } +} + +bool drvIsm330dlc::begin() { + if (_imu) { + delete _imu; + _imu = nullptr; + } + + _imu = new Adafruit_LSM6DSL(); + if (!_imu) { + return false; + } + + uint8_t addr = _address == 0 ? LSM6DS_I2CADDR_DEFAULT : (uint8_t)_address; + WS_DEBUG_PRINT("[drvIsm330dlc] Initialising @ 0x"); + WS_DEBUG_PRINTHEX(addr); + WS_DEBUG_PRINTLN("..."); + + if (!_imu->begin_I2C(addr, _i2c)) { + WS_DEBUG_PRINTLN("[drvIsm330dlc] Failed to initialise sensor"); + delete _imu; + _imu = nullptr; + return false; + } + + _imu->setAccelRange(LSM6DS_ACCEL_RANGE_4_G); + _imu->setAccelDataRate(LSM6DS_RATE_104_HZ); + _imu->setGyroRange(LSM6DS_GYRO_RANGE_500_DPS); + _imu->setGyroDataRate(LSM6DS_RATE_104_HZ); + _imu->configInt1(false, false, false, false, true); + _imu->configInt2(false, false, false); + _imu->enableWakeup(true); + + WS_DEBUG_PRINTLN("[drvIsm330dlc] Sensor initialised successfully"); + return true; +} + +bool drvIsm330dlc::readAllEvents(sensors_event_t *accel, + sensors_event_t *gyro, + sensors_event_t *temp) { + if (!_imu) { + return false; + } + return _imu->getEvent(accel, gyro, temp); +} + +bool drvIsm330dlc::computeAccelMagnitude(float &magnitude) { + sensors_event_t accel, gyro, temp; + if (!readAllEvents(&accel, &gyro, &temp)) { + return false; + } + magnitude = sqrtf(accel.acceleration.x * accel.acceleration.x + + accel.acceleration.y * accel.acceleration.y + + accel.acceleration.z * accel.acceleration.z); + return true; +} + +bool drvIsm330dlc::getEventRaw(sensors_event_t *rawEvent) { + if (!_imu) { + return false; + } + WS_DEBUG_PRINTLN("[drvIsm330dlc] Getting raw magnitude event..."); + float magnitude = 0.0f; + if (!computeAccelMagnitude(magnitude)) { + return false; + } + rawEvent->data[0] = magnitude; + WS_DEBUG_PRINT("[drvIsm330dlc] Raw magnitude: "); + WS_DEBUG_PRINTLN(magnitude); + return true; +} + +bool drvIsm330dlc::getEventBoolean(sensors_event_t *booleanEvent) { + if (!_imu) { + return false; + } + WS_DEBUG_PRINTLN("[drvIsm330dlc] Checking for tap/threshold event..."); + bool tap = _imu->shake(); + booleanEvent->data[0] = tap ? 1.0f : 0.0f; + if (tap) { + WS_DEBUG_PRINTLN("[drvIsm330dlc] Threshold event detected"); + } + return true; +} + +bool drvIsm330dlc::getEventAccelerometer(sensors_event_t *accelEvent) { + if (!_imu) { + return false; + } + WS_DEBUG_PRINTLN("[drvIsm330dlc] Getting accelerometer event..."); + sensors_event_t gyro, temp; + return readAllEvents(accelEvent, &gyro, &temp); +} + +bool drvIsm330dlc::getEventGyroscope(sensors_event_t *gyroEvent) { + if (!_imu) { + return false; + } + WS_DEBUG_PRINTLN("[drvIsm330dlc] Getting gyroscope event..."); + sensors_event_t accel, temp; + return readAllEvents(&accel, gyroEvent, &temp); +} + +void drvIsm330dlc::ConfigureDefaultSensorTypes() { + _default_sensor_types_count = 1; + _default_sensor_types[0] = + wippersnapper_sensor_SensorType_SENSOR_TYPE_ACCELEROMETER; +} diff --git a/src/components/i2c/drivers/drvIsm330dlc.h b/src/components/i2c/drivers/drvIsm330dlc.h new file mode 100644 index 000000000..8a80743ec --- /dev/null +++ b/src/components/i2c/drivers/drvIsm330dlc.h @@ -0,0 +1,43 @@ +/*! + * @file drvIsm330dlc.h + * + * Driver wrapper for the Adafruit ISM330DLC (LSM6DSL core) 6-DoF IMU. + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing + * products from Adafruit! + * + * MIT license, all text here must be included in any redistribution. + */ +#ifndef DRV_ISM330DLC_H +#define DRV_ISM330DLC_H + +#include "Wippersnapper_V2.h" +#include "drvBase.h" +#include + +#define ISM330_TAP_THRESHOLD_MSS 15.0f + +class drvIsm330dlc : public drvBase { +public: + drvIsm330dlc(TwoWire *i2c, uint16_t sensorAddress, uint32_t mux_channel, + const char *driver_name); + ~drvIsm330dlc(); + + bool begin() override; + bool getEventBoolean(sensors_event_t *booleanEvent) override; + bool getEventRaw(sensors_event_t *rawEvent) override; + bool getEventAccelerometer(sensors_event_t *accelEvent) override; + bool getEventGyroscope(sensors_event_t *gyroEvent) override; + + void ConfigureDefaultSensorTypes() override; + +private: + bool readAllEvents(sensors_event_t *accel, sensors_event_t *gyro, + sensors_event_t *temp); + bool computeAccelMagnitude(float &magnitude); + + Adafruit_LSM6DSL *_imu = nullptr; ///< Pointer to the ISM330DLC sensor +}; + +#endif // DRV_ISM330DLC_H From 08d773e7582d8bbddeddb0b8cc239099825b12bc Mon Sep 17 00:00:00 2001 From: tyeth Date: Fri, 14 Nov 2025 18:05:24 +0000 Subject: [PATCH 08/21] Add LIS3MDL magnetometer driver --- library.properties | 2 +- platformio.ini | 4 + src/components/i2c/controller.cpp | 5 + src/components/i2c/controller.h | 1 + src/components/i2c/drivers/drvLis3mdl.cpp | 140 ++++++++++++++++++++++ src/components/i2c/drivers/drvLis3mdl.h | 51 ++++++++ 6 files changed, 202 insertions(+), 1 deletion(-) create mode 100644 src/components/i2c/drivers/drvLis3mdl.cpp create mode 100644 src/components/i2c/drivers/drvLis3mdl.h diff --git a/library.properties b/library.properties index cb868828f..7c40a3411 100644 --- a/library.properties +++ b/library.properties @@ -7,4 +7,4 @@ paragraph=Arduino application for Adafruit.io WipperSnapper category=Communication url=https://github.com/adafruit/Adafruit_Wippersnapper_Arduino architectures=* -depends=OmronD6T - Community Fork, SdFat - Adafruit Fork, Adafruit LIS3DH, Adafruit LSM6DS Library, Adafruit LSM9DS1 Library, Adafruit AS5600 Library, Adafruit NeoPixel, Adafruit SPIFlash, ArduinoJson, Adafruit DotStar, Adafruit HDC302x, Adafruit INA219, Adafruit INA237 and INA238 Library, Adafruit INA260 Library, Adafruit LTR329 and LTR303, Adafruit LTR390 Library, Adafruit MCP3421, Adafruit MLX90632 Library, Adafruit NAU7802 Library, Adafruit SleepyDog Library, Adafruit TMP117, Adafruit TinyUSB Library, Adafruit AHTX0, Adafruit BME280 Library, Adafruit BMP280 Library, Adafruit BMP3XX Library, Adafruit DPS310, Adafruit DS248x, Adafruit SCD30, Adafruit SGP30 Sensor, Adafruit SGP40 Sensor, Sensirion I2C SCD4x, Sensirion I2C SEN5X, Sensirion I2C SEN66, arduino-sht, Adafruit Si7021 Library, Adafruit MQTT Library, Adafruit MS8607, Adafruit MCP9808 Library, Adafruit MCP9600 Library, Adafruit MPL115A2, Adafruit MPRLS Library, Adafruit TSL2591 Library, Adafruit_VL53L0X, Adafruit VL53L1X, STM32duino VL53L4CD, STM32duino VL53L4CX, Adafruit_VL6180X, Adafruit PM25 AQI Sensor, Adafruit QMC5883P Library, Adafruit VCNL4020 Library, Adafruit VCNL4040, Adafruit VCNL4200 Library, Adafruit VEML7700 Library, Adafruit LC709203F, Adafruit LPS2X, Adafruit LPS28, Adafruit LPS35HW, Adafruit seesaw Library, Adafruit BME680 Library, Adafruit MAX1704X, Adafruit ADT7410 Library, Adafruit HTS221, Adafruit HTU21DF Library, Adafruit HTU31D Library, Adafruit PCT2075, hp_BH1750, ENS160 - Adafruit Fork, Adafruit BusIO, Adafruit Unified Sensor, Sensirion Core, Adafruit GFX Library, Adafruit LED Backpack Library, Adafruit LiquidCrystal, Adafruit SH110X, Adafruit SSD1306, RTClib, StreamUtils, Adafruit SHT4x Library, Adafruit GPS Library, Adafruit uBlox +depends=OmronD6T - Community Fork, SdFat - Adafruit Fork, Adafruit LIS3DH, Adafruit LIS3MDL, Adafruit LSM6DS Library, Adafruit LSM9DS1 Library, Adafruit LSM303 Accel, Adafruit LSM303DLH Mag, Adafruit LIS2MDL, Adafruit AS5600 Library, Adafruit NeoPixel, Adafruit SPIFlash, ArduinoJson, Adafruit DotStar, Adafruit HDC302x, Adafruit INA219, Adafruit INA237 and INA238 Library, Adafruit INA260 Library, Adafruit LTR329 and LTR303, Adafruit LTR390 Library, Adafruit MCP3421, Adafruit MLX90632 Library, Adafruit NAU7802 Library, Adafruit SleepyDog Library, Adafruit TMP117, Adafruit TinyUSB Library, Adafruit AHTX0, Adafruit BME280 Library, Adafruit BMP280 Library, Adafruit BMP3XX Library, Adafruit DPS310, Adafruit DS248x, Adafruit SCD30, Adafruit SGP30 Sensor, Adafruit SGP40 Sensor, Sensirion I2C SCD4x, Sensirion I2C SEN5X, Sensirion I2C SEN66, arduino-sht, Adafruit Si7021 Library, Adafruit MQTT Library, Adafruit MS8607, Adafruit MCP9808 Library, Adafruit MCP9600 Library, Adafruit MPL115A2, Adafruit MPRLS Library, Adafruit TSL2591 Library, Adafruit_VL53L0X, Adafruit VL53L1X, STM32duino VL53L4CD, STM32duino VL53L4CX, Adafruit_VL6180X, Adafruit PM25 AQI Sensor, Adafruit QMC5883P Library, Adafruit VCNL4020 Library, Adafruit VCNL4040, Adafruit VCNL4200 Library, Adafruit VEML7700 Library, Adafruit LC709203F, Adafruit LPS2X, Adafruit LPS28, Adafruit LPS35HW, Adafruit seesaw Library, Adafruit BME680 Library, Adafruit MAX1704X, Adafruit ADT7410 Library, Adafruit HTS221, Adafruit HTU21DF Library, Adafruit HTU31D Library, Adafruit PCT2075, hp_BH1750, ENS160 - Adafruit Fork, Adafruit BusIO, Adafruit Unified Sensor, Sensirion Core, Adafruit GFX Library, Adafruit LED Backpack Library, Adafruit LiquidCrystal, Adafruit SH110X, Adafruit SSD1306, RTClib, StreamUtils, Adafruit SHT4x Library, Adafruit GPS Library, Adafruit uBlox diff --git a/platformio.ini b/platformio.ini index 3b7e04d59..31a9a6643 100644 --- a/platformio.ini +++ b/platformio.ini @@ -47,8 +47,12 @@ lib_deps = adafruit/Adafruit HTU21DF Library adafruit/Adafruit HTU31D Library adafruit/Adafruit LIS3DH + adafruit/Adafruit LIS3MDL + adafruit/Adafruit LIS2MDL adafruit/Adafruit LSM6DS adafruit/Adafruit LSM9DS1 Library + adafruit/Adafruit LSM303 Accel + adafruit/Adafruit LSM303DLH Mag adafruit/Adafruit LTR390 Library adafruit/Adafruit LTR329 and LTR303 adafruit/Adafruit PCT2075 diff --git a/src/components/i2c/controller.cpp b/src/components/i2c/controller.cpp index 7e0e9c737..3ec2167ed 100644 --- a/src/components/i2c/controller.cpp +++ b/src/components/i2c/controller.cpp @@ -173,6 +173,11 @@ static const std::map I2cFactorySensor = { const char *driver_name) -> drvBase * { return new drvLis3dh(i2c, addr, mux_channel, driver_name); }}, + {"lis3mdl", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvLis3mdl(i2c, addr, mux_channel, driver_name); + }}, {"ism330dlc", [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, const char *driver_name) -> drvBase * { diff --git a/src/components/i2c/controller.h b/src/components/i2c/controller.h index 8d6232d84..9735ecc02 100644 --- a/src/components/i2c/controller.h +++ b/src/components/i2c/controller.h @@ -42,6 +42,7 @@ #include "drivers/drvLc709203f.h" #include "drivers/drvLis3dh.h" #include "drivers/drvIsm330dhcx.h" +#include "drivers/drvLis3mdl.h" #include "drivers/drvIsm330dlc.h" #include "drivers/drvLsm9ds1.h" #include "drivers/drvLps22hb.h" diff --git a/src/components/i2c/drivers/drvLis3mdl.cpp b/src/components/i2c/drivers/drvLis3mdl.cpp new file mode 100644 index 000000000..c17d12eaa --- /dev/null +++ b/src/components/i2c/drivers/drvLis3mdl.cpp @@ -0,0 +1,140 @@ +/*! + * @file drvLis3mdl.cpp + * + * Driver wrapper for the Adafruit LIS3MDL 3-axis magnetometer. + */ + +#include "drvLis3mdl.h" + +#include + +/******************************************************************************/ +/*! + @brief Destructor for a LIS3MDL sensor. +*/ +/******************************************************************************/ +drvLis3mdl::~drvLis3mdl() { + if (_mag) { + delete _mag; + _mag = nullptr; + } +} + +/******************************************************************************/ +/*! + @brief Initializes the LIS3MDL sensor and begins I2C. + @returns True if initialized successfully, False otherwise. +*/ +/******************************************************************************/ +bool drvLis3mdl::begin() { + WS_DEBUG_PRINTLN("[drvLis3mdl] Initialising sensor"); + _mag = new Adafruit_LIS3MDL(); + if (!_mag) + return false; + + if (!_mag->begin_I2C(_address, _i2c)) { + WS_DEBUG_PRINTLN("[drvLis3mdl] Failed to initialise sensor"); + delete _mag; + _mag = nullptr; + return false; + } + + _mag->setPerformanceMode(LIS3MDL_ULTRAHIGHMODE); + _mag->setOperationMode(LIS3MDL_CONTINUOUSMODE); + _mag->setDataRate(LIS3MDL_DATARATE_80_HZ); + _mag->setRange(LIS3MDL_RANGE_4_GAUSS); + _mag->setIntThreshold(500); + _mag->configInterrupt(true, true, true, true, false, true); + + WS_DEBUG_PRINTLN("[drvLis3mdl] Sensor initialised successfully"); + return true; +} + +/******************************************************************************/ +/*! + @brief Reads the LIS3MDL's magnetometer event. + @param event + Pointer to the magnetometer event to populate. + @returns True if the event was obtained successfully, False otherwise. +*/ +/******************************************************************************/ +bool drvLis3mdl::readMagEvent(sensors_event_t *event) { + if (!_mag) + return false; + return _mag->getEvent(event); +} + +/******************************************************************************/ +/*! + @brief Computes the vector magnitude of a magnetometer reading. + @param event + Magnetometer event to evaluate. + @param magnitude + Reference to store the computed magnitude (micro Tesla). + @returns True if the magnitude was computed successfully. +*/ +/******************************************************************************/ +bool drvLis3mdl::computeMagnitude(const sensors_event_t &event, + float &magnitude) { + magnitude = + sqrtf(event.magnetic.x * event.magnetic.x + + event.magnetic.y * event.magnetic.y + + event.magnetic.z * event.magnetic.z); + return true; +} + +/******************************************************************************/ +/*! + @brief Gets the LIS3MDL's raw sensor event (magnitude stored in data[0]). + @param rawEvent + Pointer to the sensor event. + @returns True if the sensor event was obtained successfully, False + otherwise. +*/ +/******************************************************************************/ +bool drvLis3mdl::getEventRaw(sensors_event_t *rawEvent) { + sensors_event_t magEvent; + if (!readMagEvent(&magEvent)) { + return false; + } + + float magnitude = 0; + computeMagnitude(magEvent, magnitude); + rawEvent->data[0] = magnitude; + return true; +} + +/******************************************************************************/ +/*! + @brief Gets the LIS3MDL's boolean sensor event. + @param booleanEvent + Pointer to the sensor event. + @returns True if the sensor event was obtained successfully, False + otherwise. +*/ +/******************************************************************************/ +bool drvLis3mdl::getEventBoolean(sensors_event_t *booleanEvent) { + // TODO(#offline-imu-compass): Reuse the raw magnitude once compass headings + // are supported. For now, magnetometers do not emit boolean events. + booleanEvent->data[0] = 0.0f; + return true; +} + +/******************************************************************************/ +/*! + @brief Gets the LIS3MDL's magnetometer sensor event (x,y,z in uTesla). + @param magEvent + Pointer to the magnetometer sensor event. + @returns True if the sensor event was obtained successfully, False + otherwise. +*/ +/******************************************************************************/ +bool drvLis3mdl::getEventMagneticField(sensors_event_t *magEvent) { + return readMagEvent(magEvent); +} + +void drvLis3mdl::ConfigureDefaultSensorTypes() { + _default_sensor_types_count = 1; + _default_sensor_types[0] = + wippersnapper_sensor_SensorType_SENSOR_TYPE_MAGNETIC_FIELD; +} diff --git a/src/components/i2c/drivers/drvLis3mdl.h b/src/components/i2c/drivers/drvLis3mdl.h new file mode 100644 index 000000000..26b480011 --- /dev/null +++ b/src/components/i2c/drivers/drvLis3mdl.h @@ -0,0 +1,51 @@ +/*! + * @file drvLis3mdl.h + * + * Driver wrapper for the Adafruit LIS3MDL 3-axis magnetometer. + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing + * products from Adafruit! + * + * MIT license, all text here must be included in any redistribution. + */ +#ifndef DRV_LIS3MDL_H +#define DRV_LIS3MDL_H + +#include "Wippersnapper_V2.h" +#include "drvBase.h" +#include + + +/**************************************************************************/ +/*! + @brief Class that provides a driver interface for a LIS3MDL magnetometer. +*/ +/**************************************************************************/ +class drvLis3mdl : public drvBase { +public: + drvLis3mdl(TwoWire *i2c, uint16_t sensorAddress, uint32_t mux_channel, + const char *driver_name) + : drvBase(i2c, sensorAddress, mux_channel, driver_name) {} + + ~drvLis3mdl(); + + bool begin() override; + + bool getEventRaw(sensors_event_t *rawEvent) override; + + bool getEventBoolean(sensors_event_t *booleanEvent) override; + + bool getEventMagneticField(sensors_event_t *magEvent) override; + +protected: + void ConfigureDefaultSensorTypes() override; + +private: + bool readMagEvent(sensors_event_t *event); + bool computeMagnitude(const sensors_event_t &event, float &magnitude); + + Adafruit_LIS3MDL *_mag = nullptr; +}; + +#endif // DRV_LIS3MDL_H From 345fee8943fe3e0caa2785424891354006fe8060 Mon Sep 17 00:00:00 2001 From: tyeth Date: Fri, 14 Nov 2025 19:40:20 +0000 Subject: [PATCH 09/21] [wip] Add LSM6DS3, LSM6DSO32 --- src/components/i2c/controller.cpp | 28 +++-- src/components/i2c/controller.h | 2 + src/components/i2c/drivers/drvLsm6ds3.cpp | 118 ++++++++++++++++++++ src/components/i2c/drivers/drvLsm6ds3.h | 43 +++++++ src/components/i2c/drivers/drvLsm6dso32.cpp | 116 +++++++++++++++++++ src/components/i2c/drivers/drvLsm6dso32.h | 43 +++++++ 6 files changed, 341 insertions(+), 9 deletions(-) create mode 100644 src/components/i2c/drivers/drvLsm6ds3.cpp create mode 100644 src/components/i2c/drivers/drvLsm6ds3.h create mode 100644 src/components/i2c/drivers/drvLsm6dso32.cpp create mode 100644 src/components/i2c/drivers/drvLsm6dso32.h diff --git a/src/components/i2c/controller.cpp b/src/components/i2c/controller.cpp index 3ec2167ed..6e710e245 100644 --- a/src/components/i2c/controller.cpp +++ b/src/components/i2c/controller.cpp @@ -173,21 +173,31 @@ static const std::map I2cFactorySensor = { const char *driver_name) -> drvBase * { return new drvLis3dh(i2c, addr, mux_channel, driver_name); }}, - {"lis3mdl", - [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + {"lis3mdl", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, const char *driver_name) -> drvBase * { return new drvLis3mdl(i2c, addr, mux_channel, driver_name); - }}, - {"ism330dlc", - [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + }}, + {"lsm6ds3", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvLsm6ds3(i2c, addr, mux_channel, driver_name); + }}, + {"lsm6dso32", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvLsm6dso32(i2c, addr, mux_channel, driver_name); + }}, + {"ism330dlc", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, const char *driver_name) -> drvBase * { return new drvIsm330dlc(i2c, addr, mux_channel, driver_name); - }}, - {"ism330dhcx", - [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + }}, + {"ism330dhcx", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, const char *driver_name) -> drvBase * { return new drvIsm330dhcx(i2c, addr, mux_channel, driver_name); - }}, + }}, {"lsm9ds1", [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, const char *driver_name) -> drvBase * { diff --git a/src/components/i2c/controller.h b/src/components/i2c/controller.h index 9735ecc02..628938d56 100644 --- a/src/components/i2c/controller.h +++ b/src/components/i2c/controller.h @@ -44,6 +44,8 @@ #include "drivers/drvIsm330dhcx.h" #include "drivers/drvLis3mdl.h" #include "drivers/drvIsm330dlc.h" +#include "drivers/drvLsm6ds3.h" +#include "drivers/drvLsm6dso32.h" #include "drivers/drvLsm9ds1.h" #include "drivers/drvLps22hb.h" #include "drivers/drvLps25hb.h" diff --git a/src/components/i2c/drivers/drvLsm6ds3.cpp b/src/components/i2c/drivers/drvLsm6ds3.cpp new file mode 100644 index 000000000..be1860d5c --- /dev/null +++ b/src/components/i2c/drivers/drvLsm6ds3.cpp @@ -0,0 +1,118 @@ +/*! + * @file drvLsm6ds3.cpp + * + * Driver wrapper for the Adafruit LSM6DS3 6-DoF IMU. + */ + +#include "drvLsm6ds3.h" + +#include + +/******************************************************************************/ +/*! @brief Destructor */ +/******************************************************************************/ +drvLsm6ds3::~drvLsm6ds3() { + if (_imu) { + delete _imu; + _imu = nullptr; + } +} + +/******************************************************************************/ +bool drvLsm6ds3::begin() { + if (_imu) { + delete _imu; + _imu = nullptr; + } + + _imu = new Adafruit_LSM6DS3(); + if (!_imu) { + return false; + } + + uint8_t addr = _address == 0 ? LSM6DS_I2CADDR_DEFAULT : (uint8_t)_address; + WS_DEBUG_PRINT("[drvLsm6ds3] Initialising @ 0x"); + WS_DEBUG_PRINTHEX(addr); + WS_DEBUG_PRINTLN("..."); + + if (!_imu->begin_I2C(addr, _i2c)) { + WS_DEBUG_PRINTLN("[drvLsm6ds3] Failed to initialise sensor"); + delete _imu; + _imu = nullptr; + return false; + } + + _imu->setAccelRange(LSM6DS_ACCEL_RANGE_4_G); + _imu->setAccelDataRate(LSM6DS_RATE_104_HZ); + _imu->setGyroRange(LSM6DS_GYRO_RANGE_500_DPS); + _imu->setGyroDataRate(LSM6DS_RATE_104_HZ); + _imu->configInt1(false, false, false, false, true); + _imu->configInt2(false, false, false); + _imu->enableWakeup(true); + + WS_DEBUG_PRINTLN("[drvLsm6ds3] Sensor initialised successfully"); + return true; +} + +bool drvLsm6ds3::readAllEvents(sensors_event_t *accel, + sensors_event_t *gyro, + sensors_event_t *temp) { + if (!_imu) { + return false; + } + return _imu->getEvent(accel, gyro, temp); +} + +bool drvLsm6ds3::computeAccelMagnitude(float &magnitude) { + sensors_event_t accel, gyro, temp; + if (!readAllEvents(&accel, &gyro, &temp)) { + return false; + } + magnitude = sqrtf(accel.acceleration.x * accel.acceleration.x + + accel.acceleration.y * accel.acceleration.y + + accel.acceleration.z * accel.acceleration.z); + return true; +} + +bool drvLsm6ds3::getEventRaw(sensors_event_t *rawEvent) { + if (!_imu) { + return false; + } + float magnitude = 0.0f; + if (!computeAccelMagnitude(magnitude)) { + return false; + } + rawEvent->data[0] = magnitude; + return true; +} + +bool drvLsm6ds3::getEventBoolean(sensors_event_t *booleanEvent) { + if (!_imu) { + return false; + } + bool shake = _imu->shake(); + booleanEvent->data[0] = shake ? 1.0f : 0.0f; + return true; +} + +bool drvLsm6ds3::getEventAccelerometer(sensors_event_t *accelEvent) { + if (!_imu) { + return false; + } + sensors_event_t gyro, temp; + return readAllEvents(accelEvent, &gyro, &temp); +} + +bool drvLsm6ds3::getEventGyroscope(sensors_event_t *gyroEvent) { + if (!_imu) { + return false; + } + sensors_event_t accel, temp; + return readAllEvents(&accel, gyroEvent, &temp); +} + +void drvLsm6ds3::ConfigureDefaultSensorTypes() { + _default_sensor_types_count = 1; + _default_sensor_types[0] = + wippersnapper_sensor_SensorType_SENSOR_TYPE_ACCELEROMETER; +} diff --git a/src/components/i2c/drivers/drvLsm6ds3.h b/src/components/i2c/drivers/drvLsm6ds3.h new file mode 100644 index 000000000..0a5cdcdaf --- /dev/null +++ b/src/components/i2c/drivers/drvLsm6ds3.h @@ -0,0 +1,43 @@ +/*! + * @file drvLsm6ds3.h + * + * Driver wrapper for the Adafruit LSM6DS3 6-DoF IMU. + */ +#ifndef DRV_LSM6DS3_H +#define DRV_LSM6DS3_H + +#include "Wippersnapper_V2.h" +#include "drvBase.h" + +#include + +class drvLsm6ds3 : public drvBase { +public: + drvLsm6ds3(TwoWire *i2c, uint16_t sensorAddress, uint32_t mux_channel, + const char *driver_name) + : drvBase(i2c, sensorAddress, mux_channel, driver_name) {} + + ~drvLsm6ds3(); + + bool begin() override; + + bool getEventRaw(sensors_event_t *rawEvent) override; + + bool getEventBoolean(sensors_event_t *booleanEvent) override; + + bool getEventAccelerometer(sensors_event_t *accelEvent) override; + + bool getEventGyroscope(sensors_event_t *gyroEvent) override; + +protected: + void ConfigureDefaultSensorTypes() override; + +private: + bool readAllEvents(sensors_event_t *accel, sensors_event_t *gyro, + sensors_event_t *temp); + bool computeAccelMagnitude(float &magnitude); + + Adafruit_LSM6DS3 *_imu = nullptr; +}; + +#endif // DRV_LSM6DS3_H diff --git a/src/components/i2c/drivers/drvLsm6dso32.cpp b/src/components/i2c/drivers/drvLsm6dso32.cpp new file mode 100644 index 000000000..c4d7885dc --- /dev/null +++ b/src/components/i2c/drivers/drvLsm6dso32.cpp @@ -0,0 +1,116 @@ +/*! + * @file drvLsm6dso32.cpp + * + * Driver wrapper for the Adafruit LSM6DSO32 6-DoF IMU. + */ + +#include "drvLsm6dso32.h" + +#include + +/******************************************************************************/ +drvLsm6dso32::~drvLsm6dso32() { + if (_imu) { + delete _imu; + _imu = nullptr; + } +} + +/******************************************************************************/ +bool drvLsm6dso32::begin() { + if (_imu) { + delete _imu; + _imu = nullptr; + } + + _imu = new Adafruit_LSM6DSO32(); + if (!_imu) { + return false; + } + + uint8_t addr = _address == 0 ? LSM6DS_I2CADDR_DEFAULT : (uint8_t)_address; + WS_DEBUG_PRINT("[drvLsm6dso32] Initialising @ 0x"); + WS_DEBUG_PRINTHEX(addr); + WS_DEBUG_PRINTLN("..."); + + if (!_imu->begin_I2C(addr, _i2c)) { + WS_DEBUG_PRINTLN("[drvLsm6dso32] Failed to initialise sensor"); + delete _imu; + _imu = nullptr; + return false; + } + + _imu->setAccelRange(LSM6DSO32_ACCEL_RANGE_8_G); + _imu->setAccelDataRate(LSM6DS_RATE_104_HZ); + _imu->setGyroRange(LSM6DS_GYRO_RANGE_500_DPS); + _imu->setGyroDataRate(LSM6DS_RATE_104_HZ); + _imu->configInt1(false, false, false, false, true); + _imu->configInt2(false, false, false); + _imu->enableWakeup(true); + + WS_DEBUG_PRINTLN("[drvLsm6dso32] Sensor initialised successfully"); + return true; +} + +bool drvLsm6dso32::readAllEvents(sensors_event_t *accel, + sensors_event_t *gyro, + sensors_event_t *temp) { + if (!_imu) { + return false; + } + return _imu->getEvent(accel, gyro, temp); +} + +bool drvLsm6dso32::computeAccelMagnitude(float &magnitude) { + sensors_event_t accel, gyro, temp; + if (!readAllEvents(&accel, &gyro, &temp)) { + return false; + } + magnitude = sqrtf(accel.acceleration.x * accel.acceleration.x + + accel.acceleration.y * accel.acceleration.y + + accel.acceleration.z * accel.acceleration.z); + return true; +} + +bool drvLsm6dso32::getEventRaw(sensors_event_t *rawEvent) { + if (!_imu) { + return false; + } + float magnitude = 0.0f; + if (!computeAccelMagnitude(magnitude)) { + return false; + } + rawEvent->data[0] = magnitude; + return true; +} + +bool drvLsm6dso32::getEventBoolean(sensors_event_t *booleanEvent) { + if (!_imu) { + return false; + } + bool shake = _imu->shake(); + booleanEvent->data[0] = shake ? 1.0f : 0.0f; + return true; +} + +bool drvLsm6dso32::getEventAccelerometer(sensors_event_t *accelEvent) { + if (!_imu) { + return false; + } + sensors_event_t gyro, temp; + return readAllEvents(accelEvent, &gyro, &temp); +} + +bool drvLsm6dso32::getEventGyroscope(sensors_event_t *gyroEvent) { + if (!_imu) { + return false; + } + sensors_event_t accel, temp; + return readAllEvents(&accel, gyroEvent, &temp); +} + +void drvLsm6dso32::ConfigureDefaultSensorTypes() { + _default_sensor_types_count = 1; + _default_sensor_types[0] = + wippersnapper_sensor_SensorType_SENSOR_TYPE_ACCELEROMETER; +} diff --git a/src/components/i2c/drivers/drvLsm6dso32.h b/src/components/i2c/drivers/drvLsm6dso32.h new file mode 100644 index 000000000..2bf499383 --- /dev/null +++ b/src/components/i2c/drivers/drvLsm6dso32.h @@ -0,0 +1,43 @@ +/*! + * @file drvLsm6dso32.h + * + * Driver wrapper for the Adafruit LSM6DSO32 6-DoF IMU. + */ +#ifndef DRV_LSM6DSO32_H +#define DRV_LSM6DSO32_H + +#include "Wippersnapper_V2.h" +#include "drvBase.h" + +#include + +class drvLsm6dso32 : public drvBase { +public: + drvLsm6dso32(TwoWire *i2c, uint16_t sensorAddress, uint32_t mux_channel, + const char *driver_name) + : drvBase(i2c, sensorAddress, mux_channel, driver_name) {} + + ~drvLsm6dso32(); + + bool begin() override; + + bool getEventRaw(sensors_event_t *rawEvent) override; + + bool getEventBoolean(sensors_event_t *booleanEvent) override; + + bool getEventAccelerometer(sensors_event_t *accelEvent) override; + + bool getEventGyroscope(sensors_event_t *gyroEvent) override; + +protected: + void ConfigureDefaultSensorTypes() override; + +private: + bool readAllEvents(sensors_event_t *accel, sensors_event_t *gyro, + sensors_event_t *temp); + bool computeAccelMagnitude(float &magnitude); + + Adafruit_LSM6DSO32 *_imu = nullptr; +}; + +#endif // DRV_LSM6DSO32_H From 4e8a1c45e22e63ca6ea466f98bd5dcd901f8e9d3 Mon Sep 17 00:00:00 2001 From: tyeth Date: Fri, 14 Nov 2025 23:22:15 +0000 Subject: [PATCH 10/21] [wip] add LSM303AGR/DLH --- src/components/i2c/controller.cpp | 10 ++ src/components/i2c/controller.h | 2 + src/components/i2c/drivers/drvLsm303agr.cpp | 117 ++++++++++++++++++++ src/components/i2c/drivers/drvLsm303agr.h | 42 +++++++ src/components/i2c/drivers/drvLsm303dlh.cpp | 117 ++++++++++++++++++++ src/components/i2c/drivers/drvLsm303dlh.h | 42 +++++++ 6 files changed, 330 insertions(+) create mode 100644 src/components/i2c/drivers/drvLsm303agr.cpp create mode 100644 src/components/i2c/drivers/drvLsm303agr.h create mode 100644 src/components/i2c/drivers/drvLsm303dlh.cpp create mode 100644 src/components/i2c/drivers/drvLsm303dlh.h diff --git a/src/components/i2c/controller.cpp b/src/components/i2c/controller.cpp index 6e710e245..ce2414846 100644 --- a/src/components/i2c/controller.cpp +++ b/src/components/i2c/controller.cpp @@ -178,6 +178,16 @@ static const std::map I2cFactorySensor = { const char *driver_name) -> drvBase * { return new drvLis3mdl(i2c, addr, mux_channel, driver_name); }}, + {"lsm303agr", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvLsm303agr(i2c, addr, mux_channel, driver_name); + }}, + {"lsm303dlh", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvLsm303dlh(i2c, addr, mux_channel, driver_name); + }}, {"lsm6ds3", [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, const char *driver_name) -> drvBase * { diff --git a/src/components/i2c/controller.h b/src/components/i2c/controller.h index 628938d56..69c0c61f3 100644 --- a/src/components/i2c/controller.h +++ b/src/components/i2c/controller.h @@ -41,6 +41,8 @@ #include "drivers/drvIna260.h" #include "drivers/drvLc709203f.h" #include "drivers/drvLis3dh.h" +#include "drivers/drvLsm303agr.h" +#include "drivers/drvLsm303dlh.h" #include "drivers/drvIsm330dhcx.h" #include "drivers/drvLis3mdl.h" #include "drivers/drvIsm330dlc.h" diff --git a/src/components/i2c/drivers/drvLsm303agr.cpp b/src/components/i2c/drivers/drvLsm303agr.cpp new file mode 100644 index 000000000..8ddd24f8e --- /dev/null +++ b/src/components/i2c/drivers/drvLsm303agr.cpp @@ -0,0 +1,117 @@ +/*! + * @file drvLsm303agr.cpp + * + * Driver wrapper for the Adafruit LSM303AGR combo sensor. + */ + +#include "drvLsm303agr.h" + +#include + +namespace { +constexpr uint8_t kLsm303agrAccelDefaultAddr = LSM303_ADDRESS_ACCEL; +constexpr uint8_t kLsm303agrMagDefaultAddr = 0x1E; // LIS2MDL address +} + +/******************************************************************************/ +/*! @brief Destructor */ +/******************************************************************************/ +drvLsm303agr::~drvLsm303agr() { teardown(); } + +/******************************************************************************/ +void drvLsm303agr::teardown() { + if (_accel) { + delete _accel; + _accel = nullptr; + } + if (_mag) { + delete _mag; + _mag = nullptr; + } +} + +/******************************************************************************/ +bool drvLsm303agr::begin() { + teardown(); + + _accel = new Adafruit_LSM303_Accel_Unified(); + _mag = new Adafruit_LIS2MDL(); + if (!_accel || !_mag) { + teardown(); + return false; + } + + const uint8_t accel_addr = + _address == 0 ? kLsm303agrAccelDefaultAddr : (uint8_t)_address; + + WS_DEBUG_PRINT("[drvLsm303agr] Initialising accel @ 0x"); + WS_DEBUG_PRINTHEX(accel_addr); + WS_DEBUG_PRINTLN("..."); + if (!_accel->begin(accel_addr, _i2c)) { + WS_DEBUG_PRINTLN("[drvLsm303agr] Failed to initialise accelerometer"); + teardown(); + return false; + } + _accel->setRange(LSM303_RANGE_2G); + _accel->setMode(LSM303_MODE_HIGH_RESOLUTION); + + WS_DEBUG_PRINT("[drvLsm303agr] Initialising magnetometer @ 0x"); + WS_DEBUG_PRINTHEX(kLsm303agrMagDefaultAddr); + WS_DEBUG_PRINTLN("..."); + if (!_mag->begin(kLsm303agrMagDefaultAddr, _i2c)) { + WS_DEBUG_PRINTLN("[drvLsm303agr] Failed to initialise LIS2MDL"); + teardown(); + return false; + } + _mag->setDataRate(LIS2MDL_RATE_50_HZ); + _mag->enableInterrupts(false); + _mag->interruptsActiveHigh(false); + + WS_DEBUG_PRINTLN("[drvLsm303agr] Sensor initialised successfully"); + return true; +} + +bool drvLsm303agr::computeAccelMagnitude(float &magnitude) { + if (!_accel) { + return false; + } + sensors_event_t accel_event; + if (!_accel->getEvent(&accel_event)) { + return false; + } + magnitude = sqrtf(accel_event.acceleration.x * accel_event.acceleration.x + + accel_event.acceleration.y * accel_event.acceleration.y + + accel_event.acceleration.z * accel_event.acceleration.z); + return true; +} + +bool drvLsm303agr::getEventRaw(sensors_event_t *rawEvent) { + float magnitude = 0.0f; + if (!computeAccelMagnitude(magnitude)) { + return false; + } + rawEvent->data[0] = magnitude; + return true; +} + +bool drvLsm303agr::getEventAccelerometer(sensors_event_t *accelEvent) { + if (!_accel) { + return false; + } + return _accel->getEvent(accelEvent); +} + +bool drvLsm303agr::getEventMagneticField(sensors_event_t *magEvent) { + if (!_mag) { + return false; + } + return _mag->getEvent(magEvent); +} + +void drvLsm303agr::ConfigureDefaultSensorTypes() { + _default_sensor_types_count = 2; + _default_sensor_types[0] = + wippersnapper_sensor_SensorType_SENSOR_TYPE_ACCELEROMETER; + _default_sensor_types[1] = + wippersnapper_sensor_SensorType_SENSOR_TYPE_MAGNETIC_FIELD; +} diff --git a/src/components/i2c/drivers/drvLsm303agr.h b/src/components/i2c/drivers/drvLsm303agr.h new file mode 100644 index 000000000..1e39118b0 --- /dev/null +++ b/src/components/i2c/drivers/drvLsm303agr.h @@ -0,0 +1,42 @@ +/*! + * @file drvLsm303agr.h + * + * Driver wrapper for the Adafruit LSM303AGR combo sensor (accel + mag). + */ +#ifndef DRV_LSM303AGR_H +#define DRV_LSM303AGR_H + +#include "Wippersnapper_V2.h" +#include "drvBase.h" + +#include +#include + +class drvLsm303agr : public drvBase { +public: + drvLsm303agr(TwoWire *i2c, uint16_t sensorAddress, uint32_t mux_channel, + const char *driver_name) + : drvBase(i2c, sensorAddress, mux_channel, driver_name) {} + + ~drvLsm303agr(); + + bool begin() override; + + bool getEventRaw(sensors_event_t *rawEvent) override; + + bool getEventAccelerometer(sensors_event_t *accelEvent) override; + + bool getEventMagneticField(sensors_event_t *magEvent) override; + +protected: + void ConfigureDefaultSensorTypes() override; + +private: + void teardown(); + bool computeAccelMagnitude(float &magnitude); + + Adafruit_LSM303_Accel_Unified *_accel = nullptr; + Adafruit_LIS2MDL *_mag = nullptr; +}; + +#endif // DRV_LSM303AGR_H diff --git a/src/components/i2c/drivers/drvLsm303dlh.cpp b/src/components/i2c/drivers/drvLsm303dlh.cpp new file mode 100644 index 000000000..c3b7b771f --- /dev/null +++ b/src/components/i2c/drivers/drvLsm303dlh.cpp @@ -0,0 +1,117 @@ +/*! + * @file drvLsm303dlh.cpp + * + * Driver wrapper for the legacy Adafruit LSM303DLH combo sensor. + */ + +#include "drvLsm303dlh.h" + +#include + +namespace { +constexpr uint8_t kLsm303dlhAccelDefaultAddr = LSM303_ADDRESS_ACCEL; +constexpr uint8_t kLsm303dlhMagDefaultAddr = 0x1E; +} + +/******************************************************************************/ +/*! @brief Destructor */ +/******************************************************************************/ +drvLsm303dlh::~drvLsm303dlh() { teardown(); } + +/******************************************************************************/ +void drvLsm303dlh::teardown() { + if (_accel) { + delete _accel; + _accel = nullptr; + } + if (_mag) { + delete _mag; + _mag = nullptr; + } +} + +/******************************************************************************/ +bool drvLsm303dlh::begin() { + teardown(); + + _accel = new Adafruit_LSM303_Accel_Unified(); + _mag = new Adafruit_LSM303DLH_Mag_Unified(); + if (!_accel || !_mag) { + teardown(); + return false; + } + + const uint8_t accel_addr = + _address == 0 ? kLsm303dlhAccelDefaultAddr : (uint8_t)_address; + + WS_DEBUG_PRINT("[drvLsm303dlh] Initialising accel @ 0x"); + WS_DEBUG_PRINTHEX(accel_addr); + WS_DEBUG_PRINTLN("..."); + if (!_accel->begin(accel_addr, _i2c)) { + WS_DEBUG_PRINTLN("[drvLsm303dlh] Failed to initialise accelerometer"); + teardown(); + return false; + } + _accel->setRange(LSM303_RANGE_2G); + _accel->setMode(LSM303_MODE_HIGH_RESOLUTION); + + WS_DEBUG_PRINT("[drvLsm303dlh] Initialising magnetometer @ 0x"); + WS_DEBUG_PRINTHEX(kLsm303dlhMagDefaultAddr); + WS_DEBUG_PRINTLN("..."); + if (!_mag->begin(kLsm303dlhMagDefaultAddr, _i2c)) { + WS_DEBUG_PRINTLN("[drvLsm303dlh] Failed to initialise LSM303DLH mag"); + teardown(); + return false; + } + _mag->enableAutoRange(true); + _mag->setMagGain(LSM303_MAGGAIN_1_9); + _mag->setMagRate(LSM303_MAGRATE_15); + + WS_DEBUG_PRINTLN("[drvLsm303dlh] Sensor initialised successfully"); + return true; +} + +bool drvLsm303dlh::computeAccelMagnitude(float &magnitude) { + if (!_accel) { + return false; + } + sensors_event_t accel_event; + if (!_accel->getEvent(&accel_event)) { + return false; + } + magnitude = sqrtf(accel_event.acceleration.x * accel_event.acceleration.x + + accel_event.acceleration.y * accel_event.acceleration.y + + accel_event.acceleration.z * accel_event.acceleration.z); + return true; +} + +bool drvLsm303dlh::getEventRaw(sensors_event_t *rawEvent) { + float magnitude = 0.0f; + if (!computeAccelMagnitude(magnitude)) { + return false; + } + rawEvent->data[0] = magnitude; + return true; +} + +bool drvLsm303dlh::getEventAccelerometer(sensors_event_t *accelEvent) { + if (!_accel) { + return false; + } + return _accel->getEvent(accelEvent); +} + +bool drvLsm303dlh::getEventMagneticField(sensors_event_t *magEvent) { + if (!_mag) { + return false; + } + return _mag->getEvent(magEvent); +} + +void drvLsm303dlh::ConfigureDefaultSensorTypes() { + _default_sensor_types_count = 2; + _default_sensor_types[0] = + wippersnapper_sensor_SensorType_SENSOR_TYPE_ACCELEROMETER; + _default_sensor_types[1] = + wippersnapper_sensor_SensorType_SENSOR_TYPE_MAGNETIC_FIELD; +} diff --git a/src/components/i2c/drivers/drvLsm303dlh.h b/src/components/i2c/drivers/drvLsm303dlh.h new file mode 100644 index 000000000..bd4b1d204 --- /dev/null +++ b/src/components/i2c/drivers/drvLsm303dlh.h @@ -0,0 +1,42 @@ +/*! + * @file drvLsm303dlh.h + * + * Driver wrapper for the classic Adafruit LSM303DLH combo sensor. + */ +#ifndef DRV_LSM303DLH_H +#define DRV_LSM303DLH_H + +#include "Wippersnapper_V2.h" +#include "drvBase.h" + +#include +#include + +class drvLsm303dlh : public drvBase { +public: + drvLsm303dlh(TwoWire *i2c, uint16_t sensorAddress, uint32_t mux_channel, + const char *driver_name) + : drvBase(i2c, sensorAddress, mux_channel, driver_name) {} + + ~drvLsm303dlh(); + + bool begin() override; + + bool getEventRaw(sensors_event_t *rawEvent) override; + + bool getEventAccelerometer(sensors_event_t *accelEvent) override; + + bool getEventMagneticField(sensors_event_t *magEvent) override; + +protected: + void ConfigureDefaultSensorTypes() override; + +private: + void teardown(); + bool computeAccelMagnitude(float &magnitude); + + Adafruit_LSM303_Accel_Unified *_accel = nullptr; + Adafruit_LSM303DLH_Mag_Unified *_mag = nullptr; +}; + +#endif // DRV_LSM303DLH_H From 73749fd57aa29ec7a6d9c83e429da889cfe1e367 Mon Sep 17 00:00:00 2001 From: tyeth Date: Sat, 15 Nov 2025 00:39:00 +0000 Subject: [PATCH 11/21] [wip] Add LIS2MDL + doxygen --- src/components/i2c/controller.cpp | 5 + src/components/i2c/controller.h | 1 + src/components/i2c/drivers/drvLis2mdl.cpp | 146 ++++++++++++++++++++ src/components/i2c/drivers/drvLis2mdl.h | 104 ++++++++++++++ src/components/i2c/drivers/drvLsm303agr.cpp | 46 +++++- src/components/i2c/drivers/drvLsm303agr.h | 62 ++++++++- src/components/i2c/drivers/drvLsm303dlh.cpp | 46 +++++- src/components/i2c/drivers/drvLsm303dlh.h | 62 ++++++++- 8 files changed, 468 insertions(+), 4 deletions(-) create mode 100644 src/components/i2c/drivers/drvLis2mdl.cpp create mode 100644 src/components/i2c/drivers/drvLis2mdl.h diff --git a/src/components/i2c/controller.cpp b/src/components/i2c/controller.cpp index ce2414846..5e1001c4e 100644 --- a/src/components/i2c/controller.cpp +++ b/src/components/i2c/controller.cpp @@ -173,6 +173,11 @@ static const std::map I2cFactorySensor = { const char *driver_name) -> drvBase * { return new drvLis3dh(i2c, addr, mux_channel, driver_name); }}, + {"lis2mdl", + [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, + const char *driver_name) -> drvBase * { + return new drvLis2mdl(i2c, addr, mux_channel, driver_name); + }}, {"lis3mdl", [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, const char *driver_name) -> drvBase * { diff --git a/src/components/i2c/controller.h b/src/components/i2c/controller.h index 69c0c61f3..fd2da38ae 100644 --- a/src/components/i2c/controller.h +++ b/src/components/i2c/controller.h @@ -40,6 +40,7 @@ #include "drivers/drvIna238.h" #include "drivers/drvIna260.h" #include "drivers/drvLc709203f.h" +#include "drivers/drvLis2mdl.h" #include "drivers/drvLis3dh.h" #include "drivers/drvLsm303agr.h" #include "drivers/drvLsm303dlh.h" diff --git a/src/components/i2c/drivers/drvLis2mdl.cpp b/src/components/i2c/drivers/drvLis2mdl.cpp new file mode 100644 index 000000000..42e63268b --- /dev/null +++ b/src/components/i2c/drivers/drvLis2mdl.cpp @@ -0,0 +1,146 @@ +/*! + * @file drvLis2mdl.cpp + * + * Driver wrapper for the Adafruit LIS2MDL 3-axis magnetometer. + */ + +#include "drvLis2mdl.h" + +#include + +namespace { +constexpr uint8_t kLis2mdlDefaultAddr = 0x1E; +} + +/******************************************************************************/ +/*! + @brief Destructor for the LIS2MDL driver wrapper. +*/ +/******************************************************************************/ +drvLis2mdl::~drvLis2mdl() { + if (_mag) { + delete _mag; + _mag = nullptr; + } +} + +/******************************************************************************/ +/*! + @brief Initializes the LIS2MDL sensor and begins I2C. + @returns True if initialized successfully, False otherwise. +*/ +/******************************************************************************/ +bool drvLis2mdl::begin() { + WS_DEBUG_PRINTLN("[drvLis2mdl] Initialising sensor"); + + if (_mag) { + delete _mag; + _mag = nullptr; + } + + _mag = new Adafruit_LIS2MDL(); + if (!_mag) { + return false; + } + + const uint8_t addr = + _address == 0 ? kLis2mdlDefaultAddr : static_cast(_address); + if (!_mag->begin(addr, _i2c)) { + WS_DEBUG_PRINTLN("[drvLis2mdl] Failed to initialise sensor"); + delete _mag; + _mag = nullptr; + return false; + } + + _mag->setDataRate(LIS2MDL_RATE_50_HZ); + _mag->enableInterrupts(false); + _mag->interruptsActiveHigh(false); + + WS_DEBUG_PRINTLN("[drvLis2mdl] Sensor initialised successfully"); + return true; +} + +/******************************************************************************/ +/*! + @brief Reads the LIS2MDL's magnetometer event. + @param event Pointer to the magnetometer event to populate. + @returns True if the event was obtained successfully. +*/ +/******************************************************************************/ +bool drvLis2mdl::readMagEvent(sensors_event_t *event) { + if (!_mag) { + return false; + } + return _mag->getEvent(event); +} + +/******************************************************************************/ +/*! + @brief Computes the vector magnitude of a magnetometer reading. + @param event Magnetometer event to evaluate. + @param magnitude Reference to store the computed magnitude (micro Tesla). + @returns True if the magnitude was computed successfully. +*/ +/******************************************************************************/ +bool drvLis2mdl::computeMagnitude(const sensors_event_t &event, + float &magnitude) { + magnitude = + sqrtf(event.magnetic.x * event.magnetic.x + + event.magnetic.y * event.magnetic.y + + event.magnetic.z * event.magnetic.z); + return true; +} + +/******************************************************************************/ +/*! + @brief Gets the LIS2MDL's raw sensor event (magnitude stored in data[0]). + @param rawEvent Pointer to the sensor event. + @returns True if the sensor event was obtained successfully. +*/ +/******************************************************************************/ +bool drvLis2mdl::getEventRaw(sensors_event_t *rawEvent) { + sensors_event_t magEvent; + if (!readMagEvent(&magEvent)) { + return false; + } + + float magnitude = 0.0f; + computeMagnitude(magEvent, magnitude); + rawEvent->data[0] = magnitude; + return true; +} + +/******************************************************************************/ +/*! + @brief Gets the LIS2MDL's boolean sensor event. + @param booleanEvent Pointer to the sensor event. + @returns True once the placeholder value has been populated. +*/ +/******************************************************************************/ +bool drvLis2mdl::getEventBoolean(sensors_event_t *booleanEvent) { + // Magnetometers do not emit boolean events; reserve the field for future use. + booleanEvent->data[0] = 0.0f; + return true; +} + +/******************************************************************************/ +/*! + @brief Gets the LIS2MDL's magnetometer sensor event (x,y,z in microTesla). + @param magEvent Pointer to the magnetometer sensor event. + @returns True if the sensor event was obtained successfully. +*/ +/******************************************************************************/ +bool drvLis2mdl::getEventMagneticField(sensors_event_t *magEvent) { + return readMagEvent(magEvent); +} + +/******************************************************************************/ +/*! + @brief Registers the driver's default magnetometer sensor type. +*/ +/******************************************************************************/ +void drvLis2mdl::ConfigureDefaultSensorTypes() { + _default_sensor_types_count = 1; + _default_sensor_types[0] = + wippersnapper_sensor_SensorType_SENSOR_TYPE_MAGNETIC_FIELD; +} diff --git a/src/components/i2c/drivers/drvLis2mdl.h b/src/components/i2c/drivers/drvLis2mdl.h new file mode 100644 index 000000000..34be7f1fe --- /dev/null +++ b/src/components/i2c/drivers/drvLis2mdl.h @@ -0,0 +1,104 @@ +/*! + * @file drvLis2mdl.h + * + * Driver wrapper for the Adafruit LIS2MDL 3-axis magnetometer. + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing + * products from Adafruit! + * + * MIT license, all text here must be included in any redistribution. + */ +#ifndef DRV_LIS2MDL_H +#define DRV_LIS2MDL_H + +#include "Wippersnapper_V2.h" +#include "drvBase.h" + +#include + +/**************************************************************************/ +/*! + @brief Class that provides a driver interface for a LIS2MDL magnetometer. +*/ +/**************************************************************************/ +class drvLis2mdl : public drvBase { +public: + drvLis2mdl(TwoWire *i2c, uint16_t sensorAddress, uint32_t mux_channel, + const char *driver_name) + : drvBase(i2c, sensorAddress, mux_channel, driver_name) {} + + /**************************************************************************/ + /*! + @brief Destructor for the LIS2MDL driver wrapper. + */ + /**************************************************************************/ + ~drvLis2mdl(); + + /**************************************************************************/ + /*! + @brief Initializes the LIS2MDL sensor and begins I2C. + @returns True if initialized successfully, False otherwise. + */ + /**************************************************************************/ + bool begin() override; + + /**************************************************************************/ + /*! + @brief Gets a raw magnetometer magnitude event (micro Tesla). + @param rawEvent Pointer to the destination sensor event. + @returns True if the event was obtained successfully. + */ + /**************************************************************************/ + bool getEventRaw(sensors_event_t *rawEvent) override; + + /**************************************************************************/ + /*! + @brief Placeholder boolean event implementation for compatibility. + @param booleanEvent Pointer to the destination sensor event. + @returns True once the placeholder event has been populated. + */ + /**************************************************************************/ + bool getEventBoolean(sensors_event_t *booleanEvent) override; + + /**************************************************************************/ + /*! + @brief Retrieves the LIS2MDL's magnetometer vector event. + @param magEvent Pointer to the destination sensor event. + @returns True if the event was obtained successfully. + */ + /**************************************************************************/ + bool getEventMagneticField(sensors_event_t *magEvent) override; + +protected: + /**************************************************************************/ + /*! + @brief Registers the default virtual sensors exposed by the driver. + */ + /**************************************************************************/ + void ConfigureDefaultSensorTypes() override; + +private: + /**************************************************************************/ + /*! + @brief Reads a magnetometer event from the LIS2MDL helper. + @param event Pointer to the destination sensor event. + @returns True if the event was obtained successfully. + */ + /**************************************************************************/ + bool readMagEvent(sensors_event_t *event); + + /**************************************************************************/ + /*! + @brief Computes the vector magnitude of a magnetometer reading. + @param event Magnetometer event to evaluate. + @param magnitude Reference to store the computed magnitude (micro Tesla). + @returns True if the magnitude was computed successfully. + */ + /**************************************************************************/ + bool computeMagnitude(const sensors_event_t &event, float &magnitude); + + Adafruit_LIS2MDL *_mag = nullptr; +}; + +#endif // DRV_LIS2MDL_H diff --git a/src/components/i2c/drivers/drvLsm303agr.cpp b/src/components/i2c/drivers/drvLsm303agr.cpp index 8ddd24f8e..15f424b34 100644 --- a/src/components/i2c/drivers/drvLsm303agr.cpp +++ b/src/components/i2c/drivers/drvLsm303agr.cpp @@ -14,10 +14,16 @@ constexpr uint8_t kLsm303agrMagDefaultAddr = 0x1E; // LIS2MDL address } /******************************************************************************/ -/*! @brief Destructor */ +/*! + @brief Destructor for the LSM303AGR driver wrapper. +*/ /******************************************************************************/ drvLsm303agr::~drvLsm303agr() { teardown(); } +/******************************************************************************/ +/*! + @brief Releases any allocated accelerometer or magnetometer instances. +*/ /******************************************************************************/ void drvLsm303agr::teardown() { if (_accel) { @@ -30,6 +36,11 @@ void drvLsm303agr::teardown() { } } +/******************************************************************************/ +/*! + @brief Initializes the LSM303AGR accelerometer and LIS2MDL magnetometer. + @returns True if initialization succeeded, False otherwise. +*/ /******************************************************************************/ bool drvLsm303agr::begin() { teardown(); @@ -71,6 +82,13 @@ bool drvLsm303agr::begin() { return true; } +/******************************************************************************/ +/*! + @brief Computes the magnitude of the accelerometer vector. + @param magnitude Reference to store the computed m/s^2 value. + @returns True if the accelerometer event was retrieved successfully. +*/ +/******************************************************************************/ bool drvLsm303agr::computeAccelMagnitude(float &magnitude) { if (!_accel) { return false; @@ -85,6 +103,13 @@ bool drvLsm303agr::computeAccelMagnitude(float &magnitude) { return true; } +/******************************************************************************/ +/*! + @brief Fills the raw event with the accelerometer magnitude in data[0]. + @param rawEvent Pointer to the destination sensor event. + @returns True if the magnitude was computed successfully. +*/ +/******************************************************************************/ bool drvLsm303agr::getEventRaw(sensors_event_t *rawEvent) { float magnitude = 0.0f; if (!computeAccelMagnitude(magnitude)) { @@ -94,6 +119,13 @@ bool drvLsm303agr::getEventRaw(sensors_event_t *rawEvent) { return true; } +/******************************************************************************/ +/*! + @brief Retrieves the 3-axis accelerometer event. + @param accelEvent Pointer to the destination sensor event. + @returns True if the event was populated successfully. +*/ +/******************************************************************************/ bool drvLsm303agr::getEventAccelerometer(sensors_event_t *accelEvent) { if (!_accel) { return false; @@ -101,6 +133,13 @@ bool drvLsm303agr::getEventAccelerometer(sensors_event_t *accelEvent) { return _accel->getEvent(accelEvent); } +/******************************************************************************/ +/*! + @brief Retrieves the 3-axis magnetic field event. + @param magEvent Pointer to the destination sensor event. + @returns True if the event was populated successfully. +*/ +/******************************************************************************/ bool drvLsm303agr::getEventMagneticField(sensors_event_t *magEvent) { if (!_mag) { return false; @@ -108,6 +147,11 @@ bool drvLsm303agr::getEventMagneticField(sensors_event_t *magEvent) { return _mag->getEvent(magEvent); } +/******************************************************************************/ +/*! + @brief Registers the driver's default accelerometer and magnetometer types. +*/ +/******************************************************************************/ void drvLsm303agr::ConfigureDefaultSensorTypes() { _default_sensor_types_count = 2; _default_sensor_types[0] = diff --git a/src/components/i2c/drivers/drvLsm303agr.h b/src/components/i2c/drivers/drvLsm303agr.h index 1e39118b0..abcd8265f 100644 --- a/src/components/i2c/drivers/drvLsm303agr.h +++ b/src/components/i2c/drivers/drvLsm303agr.h @@ -1,7 +1,13 @@ -/*! +/*! * @file drvLsm303agr.h * * Driver wrapper for the Adafruit LSM303AGR combo sensor (accel + mag). + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing + * products from Adafruit! + * + * MIT license, all text here must be included in any redistribution. */ #ifndef DRV_LSM303AGR_H #define DRV_LSM303AGR_H @@ -12,27 +18,81 @@ #include #include +/**************************************************************************/ +/*! + @brief Driver interface for the Adafruit LSM303AGR combo sensor. +*/ +/**************************************************************************/ class drvLsm303agr : public drvBase { public: drvLsm303agr(TwoWire *i2c, uint16_t sensorAddress, uint32_t mux_channel, const char *driver_name) : drvBase(i2c, sensorAddress, mux_channel, driver_name) {} + /**************************************************************************/ + /*! + @brief Destructor for the LSM303AGR driver. + */ + /**************************************************************************/ ~drvLsm303agr(); + /**************************************************************************/ + /*! + @brief Initializes the accelerometer and magnetometer peripherals. + @returns True if initialization succeeded, False otherwise. + */ + /**************************************************************************/ bool begin() override; + /**************************************************************************/ + /*! + @brief Populates a raw magnitude reading into a sensor event. + @param rawEvent Pointer to the destination sensor event. + @returns True if the event was populated successfully. + */ + /**************************************************************************/ bool getEventRaw(sensors_event_t *rawEvent) override; + /**************************************************************************/ + /*! + @brief Retrieves the accelerometer vector event. + @param accelEvent Pointer to the destination sensor event. + @returns True if the event was populated successfully. + */ + /**************************************************************************/ bool getEventAccelerometer(sensors_event_t *accelEvent) override; + /**************************************************************************/ + /*! + @brief Retrieves the magnetic field vector event. + @param magEvent Pointer to the destination sensor event. + @returns True if the event was populated successfully. + */ + /**************************************************************************/ bool getEventMagneticField(sensors_event_t *magEvent) override; protected: + /**************************************************************************/ + /*! + @brief Registers the default set of virtual sensor types. + */ + /**************************************************************************/ void ConfigureDefaultSensorTypes() override; private: + /**************************************************************************/ + /*! + @brief Releases any allocated sensor instances. + */ + /**************************************************************************/ void teardown(); + /**************************************************************************/ + /*! + @brief Computes the linear acceleration magnitude in m/s^2. + @param magnitude Reference to store the computed value. + @returns True if the magnitude was computed successfully. + */ + /**************************************************************************/ bool computeAccelMagnitude(float &magnitude); Adafruit_LSM303_Accel_Unified *_accel = nullptr; diff --git a/src/components/i2c/drivers/drvLsm303dlh.cpp b/src/components/i2c/drivers/drvLsm303dlh.cpp index c3b7b771f..61a55a53d 100644 --- a/src/components/i2c/drivers/drvLsm303dlh.cpp +++ b/src/components/i2c/drivers/drvLsm303dlh.cpp @@ -14,10 +14,16 @@ constexpr uint8_t kLsm303dlhMagDefaultAddr = 0x1E; } /******************************************************************************/ -/*! @brief Destructor */ +/*! + @brief Destructor for the legacy LSM303DLH driver wrapper. +*/ /******************************************************************************/ drvLsm303dlh::~drvLsm303dlh() { teardown(); } +/******************************************************************************/ +/*! + @brief Releases any allocated accelerometer or magnetometer instances. +*/ /******************************************************************************/ void drvLsm303dlh::teardown() { if (_accel) { @@ -30,6 +36,11 @@ void drvLsm303dlh::teardown() { } } +/******************************************************************************/ +/*! + @brief Initializes the LSM303DLH accelerometer and magnetometer helpers. + @returns True if initialization succeeded, False otherwise. +*/ /******************************************************************************/ bool drvLsm303dlh::begin() { teardown(); @@ -71,6 +82,13 @@ bool drvLsm303dlh::begin() { return true; } +/******************************************************************************/ +/*! + @brief Computes the magnitude of the accelerometer vector. + @param magnitude Reference to store the computed m/s^2 value. + @returns True if the accelerometer event was retrieved successfully. +*/ +/******************************************************************************/ bool drvLsm303dlh::computeAccelMagnitude(float &magnitude) { if (!_accel) { return false; @@ -85,6 +103,13 @@ bool drvLsm303dlh::computeAccelMagnitude(float &magnitude) { return true; } +/******************************************************************************/ +/*! + @brief Fills the raw event with the accelerometer magnitude in data[0]. + @param rawEvent Pointer to the destination sensor event. + @returns True if the magnitude was computed successfully. +*/ +/******************************************************************************/ bool drvLsm303dlh::getEventRaw(sensors_event_t *rawEvent) { float magnitude = 0.0f; if (!computeAccelMagnitude(magnitude)) { @@ -94,6 +119,13 @@ bool drvLsm303dlh::getEventRaw(sensors_event_t *rawEvent) { return true; } +/******************************************************************************/ +/*! + @brief Retrieves the 3-axis accelerometer event. + @param accelEvent Pointer to the destination sensor event. + @returns True if the event was populated successfully. +*/ +/******************************************************************************/ bool drvLsm303dlh::getEventAccelerometer(sensors_event_t *accelEvent) { if (!_accel) { return false; @@ -101,6 +133,13 @@ bool drvLsm303dlh::getEventAccelerometer(sensors_event_t *accelEvent) { return _accel->getEvent(accelEvent); } +/******************************************************************************/ +/*! + @brief Retrieves the 3-axis magnetic field event. + @param magEvent Pointer to the destination sensor event. + @returns True if the event was populated successfully. +*/ +/******************************************************************************/ bool drvLsm303dlh::getEventMagneticField(sensors_event_t *magEvent) { if (!_mag) { return false; @@ -108,6 +147,11 @@ bool drvLsm303dlh::getEventMagneticField(sensors_event_t *magEvent) { return _mag->getEvent(magEvent); } +/******************************************************************************/ +/*! + @brief Registers the driver's default accelerometer and magnetometer types. +*/ +/******************************************************************************/ void drvLsm303dlh::ConfigureDefaultSensorTypes() { _default_sensor_types_count = 2; _default_sensor_types[0] = diff --git a/src/components/i2c/drivers/drvLsm303dlh.h b/src/components/i2c/drivers/drvLsm303dlh.h index bd4b1d204..8925cd6b3 100644 --- a/src/components/i2c/drivers/drvLsm303dlh.h +++ b/src/components/i2c/drivers/drvLsm303dlh.h @@ -1,7 +1,13 @@ -/*! +/*! * @file drvLsm303dlh.h * * Driver wrapper for the classic Adafruit LSM303DLH combo sensor. + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing + * products from Adafruit! + * + * MIT license, all text here must be included in any redistribution. */ #ifndef DRV_LSM303DLH_H #define DRV_LSM303DLH_H @@ -12,27 +18,81 @@ #include #include +/**************************************************************************/ +/*! + @brief Driver interface for the legacy Adafruit LSM303DLH combo sensor. +*/ +/**************************************************************************/ class drvLsm303dlh : public drvBase { public: drvLsm303dlh(TwoWire *i2c, uint16_t sensorAddress, uint32_t mux_channel, const char *driver_name) : drvBase(i2c, sensorAddress, mux_channel, driver_name) {} + /**************************************************************************/ + /*! + @brief Destructor for the LSM303DLH driver. + */ + /**************************************************************************/ ~drvLsm303dlh(); + /**************************************************************************/ + /*! + @brief Initializes the accelerometer and magnetometer peripherals. + @returns True if initialization succeeded, False otherwise. + */ + /**************************************************************************/ bool begin() override; + /**************************************************************************/ + /*! + @brief Populates a raw magnitude reading into a sensor event. + @param rawEvent Pointer to the destination sensor event. + @returns True if the event was populated successfully. + */ + /**************************************************************************/ bool getEventRaw(sensors_event_t *rawEvent) override; + /**************************************************************************/ + /*! + @brief Retrieves the accelerometer vector event. + @param accelEvent Pointer to the destination sensor event. + @returns True if the event was populated successfully. + */ + /**************************************************************************/ bool getEventAccelerometer(sensors_event_t *accelEvent) override; + /**************************************************************************/ + /*! + @brief Retrieves the magnetic field vector event. + @param magEvent Pointer to the destination sensor event. + @returns True if the event was populated successfully. + */ + /**************************************************************************/ bool getEventMagneticField(sensors_event_t *magEvent) override; protected: + /**************************************************************************/ + /*! + @brief Registers the default set of virtual sensor types. + */ + /**************************************************************************/ void ConfigureDefaultSensorTypes() override; private: + /**************************************************************************/ + /*! + @brief Releases any allocated sensor instances. + */ + /**************************************************************************/ void teardown(); + /**************************************************************************/ + /*! + @brief Computes the linear acceleration magnitude in m/s^2. + @param magnitude Reference to store the computed value. + @returns True if the magnitude was computed successfully. + */ + /**************************************************************************/ bool computeAccelMagnitude(float &magnitude); Adafruit_LSM303_Accel_Unified *_accel = nullptr; From 2e79f5ee6df579ad469932e4225efe8a4c003b3d Mon Sep 17 00:00:00 2001 From: tyeth Date: Sat, 15 Nov 2025 16:39:03 +0000 Subject: [PATCH 12/21] [chore] formatting --- src/components/i2c/drivers/drvIsm330dhcx.cpp | 3 +- src/components/i2c/drivers/drvIsm330dlc.cpp | 5 ++-- src/components/i2c/drivers/drvLis2mdl.cpp | 29 +++++++++---------- src/components/i2c/drivers/drvLis2mdl.h | 18 ++++++------ src/components/i2c/drivers/drvLis3dh.cpp | 4 +-- src/components/i2c/drivers/drvLis3mdl.cpp | 21 +++++++------- src/components/i2c/drivers/drvLis3mdl.h | 3 +- src/components/i2c/drivers/drvLsm303agr.cpp | 30 ++++++++++---------- src/components/i2c/drivers/drvLsm303agr.h | 20 ++++++------- src/components/i2c/drivers/drvLsm303dlh.cpp | 30 ++++++++++---------- src/components/i2c/drivers/drvLsm303dlh.h | 20 ++++++------- src/components/i2c/drivers/drvLsm6ds3.cpp | 3 +- src/components/i2c/drivers/drvLsm6dso32.cpp | 3 +- src/components/i2c/drivers/drvLsm9ds1.cpp | 12 ++++---- src/components/i2c/drivers/drvLsm9ds1.h | 4 +-- 15 files changed, 97 insertions(+), 108 deletions(-) diff --git a/src/components/i2c/drivers/drvIsm330dhcx.cpp b/src/components/i2c/drivers/drvIsm330dhcx.cpp index 7f7dab50d..3a79a7979 100644 --- a/src/components/i2c/drivers/drvIsm330dhcx.cpp +++ b/src/components/i2c/drivers/drvIsm330dhcx.cpp @@ -54,8 +54,7 @@ bool drvIsm330dhcx::begin() { return true; } -bool drvIsm330dhcx::readAllEvents(sensors_event_t *accel, - sensors_event_t *gyro, +bool drvIsm330dhcx::readAllEvents(sensors_event_t *accel, sensors_event_t *gyro, sensors_event_t *temp) { if (!_imu) { return false; diff --git a/src/components/i2c/drivers/drvIsm330dlc.cpp b/src/components/i2c/drivers/drvIsm330dlc.cpp index 38f0c80e5..a3c1804ba 100644 --- a/src/components/i2c/drivers/drvIsm330dlc.cpp +++ b/src/components/i2c/drivers/drvIsm330dlc.cpp @@ -54,9 +54,8 @@ bool drvIsm330dlc::begin() { return true; } -bool drvIsm330dlc::readAllEvents(sensors_event_t *accel, - sensors_event_t *gyro, - sensors_event_t *temp) { +bool drvIsm330dlc::readAllEvents(sensors_event_t *accel, sensors_event_t *gyro, + sensors_event_t *temp) { if (!_imu) { return false; } diff --git a/src/components/i2c/drivers/drvLis2mdl.cpp b/src/components/i2c/drivers/drvLis2mdl.cpp index 42e63268b..5a2b27ea2 100644 --- a/src/components/i2c/drivers/drvLis2mdl.cpp +++ b/src/components/i2c/drivers/drvLis2mdl.cpp @@ -8,12 +8,10 @@ #include -namespace { -constexpr uint8_t kLis2mdlDefaultAddr = 0x1E; -} +#define LIS2MDL_DEFAULT_ADDR 0x1E /******************************************************************************/ -/*! +/*! @brief Destructor for the LIS2MDL driver wrapper. */ /******************************************************************************/ @@ -25,7 +23,7 @@ drvLis2mdl::~drvLis2mdl() { } /******************************************************************************/ -/*! +/*! @brief Initializes the LIS2MDL sensor and begins I2C. @returns True if initialized successfully, False otherwise. */ @@ -44,7 +42,7 @@ bool drvLis2mdl::begin() { } const uint8_t addr = - _address == 0 ? kLis2mdlDefaultAddr : static_cast(_address); + _address == 0 ? LIS2MDL_DEFAULT_ADDR : static_cast(_address); if (!_mag->begin(addr, _i2c)) { WS_DEBUG_PRINTLN("[drvLis2mdl] Failed to initialise sensor"); delete _mag; @@ -61,7 +59,7 @@ bool drvLis2mdl::begin() { } /******************************************************************************/ -/*! +/*! @brief Reads the LIS2MDL's magnetometer event. @param event Pointer to the magnetometer event to populate. @returns True if the event was obtained successfully. @@ -75,7 +73,7 @@ bool drvLis2mdl::readMagEvent(sensors_event_t *event) { } /******************************************************************************/ -/*! +/*! @brief Computes the vector magnitude of a magnetometer reading. @param event Magnetometer event to evaluate. @param magnitude Reference to store the computed magnitude (micro Tesla). @@ -84,15 +82,14 @@ bool drvLis2mdl::readMagEvent(sensors_event_t *event) { /******************************************************************************/ bool drvLis2mdl::computeMagnitude(const sensors_event_t &event, float &magnitude) { - magnitude = - sqrtf(event.magnetic.x * event.magnetic.x + - event.magnetic.y * event.magnetic.y + - event.magnetic.z * event.magnetic.z); + magnitude = sqrtf(event.magnetic.x * event.magnetic.x + + event.magnetic.y * event.magnetic.y + + event.magnetic.z * event.magnetic.z); return true; } /******************************************************************************/ -/*! +/*! @brief Gets the LIS2MDL's raw sensor event (magnitude stored in data[0]). @param rawEvent Pointer to the sensor event. @returns True if the sensor event was obtained successfully. @@ -111,7 +108,7 @@ bool drvLis2mdl::getEventRaw(sensors_event_t *rawEvent) { } /******************************************************************************/ -/*! +/*! @brief Gets the LIS2MDL's boolean sensor event. @param booleanEvent Pointer to the sensor event. @returns True once the placeholder value has been populated. @@ -124,7 +121,7 @@ bool drvLis2mdl::getEventBoolean(sensors_event_t *booleanEvent) { } /******************************************************************************/ -/*! +/*! @brief Gets the LIS2MDL's magnetometer sensor event (x,y,z in microTesla). @param magEvent Pointer to the magnetometer sensor event. @returns True if the sensor event was obtained successfully. @@ -135,7 +132,7 @@ bool drvLis2mdl::getEventMagneticField(sensors_event_t *magEvent) { } /******************************************************************************/ -/*! +/*! @brief Registers the driver's default magnetometer sensor type. */ /******************************************************************************/ diff --git a/src/components/i2c/drivers/drvLis2mdl.h b/src/components/i2c/drivers/drvLis2mdl.h index 34be7f1fe..e8c00f0a4 100644 --- a/src/components/i2c/drivers/drvLis2mdl.h +++ b/src/components/i2c/drivers/drvLis2mdl.h @@ -18,7 +18,7 @@ #include /**************************************************************************/ -/*! +/*! @brief Class that provides a driver interface for a LIS2MDL magnetometer. */ /**************************************************************************/ @@ -29,14 +29,14 @@ class drvLis2mdl : public drvBase { : drvBase(i2c, sensorAddress, mux_channel, driver_name) {} /**************************************************************************/ - /*! + /*! @brief Destructor for the LIS2MDL driver wrapper. */ /**************************************************************************/ ~drvLis2mdl(); /**************************************************************************/ - /*! + /*! @brief Initializes the LIS2MDL sensor and begins I2C. @returns True if initialized successfully, False otherwise. */ @@ -44,7 +44,7 @@ class drvLis2mdl : public drvBase { bool begin() override; /**************************************************************************/ - /*! + /*! @brief Gets a raw magnetometer magnitude event (micro Tesla). @param rawEvent Pointer to the destination sensor event. @returns True if the event was obtained successfully. @@ -53,7 +53,7 @@ class drvLis2mdl : public drvBase { bool getEventRaw(sensors_event_t *rawEvent) override; /**************************************************************************/ - /*! + /*! @brief Placeholder boolean event implementation for compatibility. @param booleanEvent Pointer to the destination sensor event. @returns True once the placeholder event has been populated. @@ -62,7 +62,7 @@ class drvLis2mdl : public drvBase { bool getEventBoolean(sensors_event_t *booleanEvent) override; /**************************************************************************/ - /*! + /*! @brief Retrieves the LIS2MDL's magnetometer vector event. @param magEvent Pointer to the destination sensor event. @returns True if the event was obtained successfully. @@ -72,7 +72,7 @@ class drvLis2mdl : public drvBase { protected: /**************************************************************************/ - /*! + /*! @brief Registers the default virtual sensors exposed by the driver. */ /**************************************************************************/ @@ -80,7 +80,7 @@ class drvLis2mdl : public drvBase { private: /**************************************************************************/ - /*! + /*! @brief Reads a magnetometer event from the LIS2MDL helper. @param event Pointer to the destination sensor event. @returns True if the event was obtained successfully. @@ -89,7 +89,7 @@ class drvLis2mdl : public drvBase { bool readMagEvent(sensors_event_t *event); /**************************************************************************/ - /*! + /*! @brief Computes the vector magnitude of a magnetometer reading. @param event Magnetometer event to evaluate. @param magnitude Reference to store the computed magnitude (micro Tesla). diff --git a/src/components/i2c/drivers/drvLis3dh.cpp b/src/components/i2c/drivers/drvLis3dh.cpp index fa335e5a6..13c8cdd67 100644 --- a/src/components/i2c/drivers/drvLis3dh.cpp +++ b/src/components/i2c/drivers/drvLis3dh.cpp @@ -71,8 +71,8 @@ bool drvLis3dh::getEventRaw(sensors_event_t *rawEvent) { // Calculate magnitude of the acceleration vector (m/s^2) and store in // event->data[0] to be consistent with other drivers that expose "raw" float mag = sqrtf(event.acceleration.x * event.acceleration.x + - event.acceleration.y * event.acceleration.y + - event.acceleration.z * event.acceleration.z); + event.acceleration.y * event.acceleration.y + + event.acceleration.z * event.acceleration.z); rawEvent->data[0] = mag; WS_DEBUG_PRINT("[drvLis3dh] Raw magnitude: "); WS_DEBUG_PRINTLN(mag); diff --git a/src/components/i2c/drivers/drvLis3mdl.cpp b/src/components/i2c/drivers/drvLis3mdl.cpp index c17d12eaa..68b911b1b 100644 --- a/src/components/i2c/drivers/drvLis3mdl.cpp +++ b/src/components/i2c/drivers/drvLis3mdl.cpp @@ -9,7 +9,7 @@ #include /******************************************************************************/ -/*! +/*! @brief Destructor for a LIS3MDL sensor. */ /******************************************************************************/ @@ -21,7 +21,7 @@ drvLis3mdl::~drvLis3mdl() { } /******************************************************************************/ -/*! +/*! @brief Initializes the LIS3MDL sensor and begins I2C. @returns True if initialized successfully, False otherwise. */ @@ -51,7 +51,7 @@ bool drvLis3mdl::begin() { } /******************************************************************************/ -/*! +/*! @brief Reads the LIS3MDL's magnetometer event. @param event Pointer to the magnetometer event to populate. @@ -65,7 +65,7 @@ bool drvLis3mdl::readMagEvent(sensors_event_t *event) { } /******************************************************************************/ -/*! +/*! @brief Computes the vector magnitude of a magnetometer reading. @param event Magnetometer event to evaluate. @@ -76,15 +76,14 @@ bool drvLis3mdl::readMagEvent(sensors_event_t *event) { /******************************************************************************/ bool drvLis3mdl::computeMagnitude(const sensors_event_t &event, float &magnitude) { - magnitude = - sqrtf(event.magnetic.x * event.magnetic.x + - event.magnetic.y * event.magnetic.y + - event.magnetic.z * event.magnetic.z); + magnitude = sqrtf(event.magnetic.x * event.magnetic.x + + event.magnetic.y * event.magnetic.y + + event.magnetic.z * event.magnetic.z); return true; } /******************************************************************************/ -/*! +/*! @brief Gets the LIS3MDL's raw sensor event (magnitude stored in data[0]). @param rawEvent Pointer to the sensor event. @@ -105,7 +104,7 @@ bool drvLis3mdl::getEventRaw(sensors_event_t *rawEvent) { } /******************************************************************************/ -/*! +/*! @brief Gets the LIS3MDL's boolean sensor event. @param booleanEvent Pointer to the sensor event. @@ -121,7 +120,7 @@ bool drvLis3mdl::getEventBoolean(sensors_event_t *booleanEvent) { } /******************************************************************************/ -/*! +/*! @brief Gets the LIS3MDL's magnetometer sensor event (x,y,z in uTesla). @param magEvent Pointer to the magnetometer sensor event. diff --git a/src/components/i2c/drivers/drvLis3mdl.h b/src/components/i2c/drivers/drvLis3mdl.h index 26b480011..53399aa37 100644 --- a/src/components/i2c/drivers/drvLis3mdl.h +++ b/src/components/i2c/drivers/drvLis3mdl.h @@ -16,9 +16,8 @@ #include "drvBase.h" #include - /**************************************************************************/ -/*! +/*! @brief Class that provides a driver interface for a LIS3MDL magnetometer. */ /**************************************************************************/ diff --git a/src/components/i2c/drivers/drvLsm303agr.cpp b/src/components/i2c/drivers/drvLsm303agr.cpp index 15f424b34..6f0ac862c 100644 --- a/src/components/i2c/drivers/drvLsm303agr.cpp +++ b/src/components/i2c/drivers/drvLsm303agr.cpp @@ -8,20 +8,18 @@ #include -namespace { -constexpr uint8_t kLsm303agrAccelDefaultAddr = LSM303_ADDRESS_ACCEL; -constexpr uint8_t kLsm303agrMagDefaultAddr = 0x1E; // LIS2MDL address -} +#define LSM303AGR_ACCEL_DEFAULT_ADDR LSM303_ADDRESS_ACCEL +#define LSM303AGR_MAG_DEFAULT_ADDR 0x1E ///< LIS2MDL default address /******************************************************************************/ -/*! +/*! @brief Destructor for the LSM303AGR driver wrapper. */ /******************************************************************************/ drvLsm303agr::~drvLsm303agr() { teardown(); } /******************************************************************************/ -/*! +/*! @brief Releases any allocated accelerometer or magnetometer instances. */ /******************************************************************************/ @@ -37,7 +35,7 @@ void drvLsm303agr::teardown() { } /******************************************************************************/ -/*! +/*! @brief Initializes the LSM303AGR accelerometer and LIS2MDL magnetometer. @returns True if initialization succeeded, False otherwise. */ @@ -52,8 +50,10 @@ bool drvLsm303agr::begin() { return false; } + // TODO: if _address isn't default (or alt), shift mag by same offset. + // to support adress translators. Alternatively compound components. const uint8_t accel_addr = - _address == 0 ? kLsm303agrAccelDefaultAddr : (uint8_t)_address; + _address == 0 ? LSM303AGR_ACCEL_DEFAULT_ADDR : (uint8_t)_address; WS_DEBUG_PRINT("[drvLsm303agr] Initialising accel @ 0x"); WS_DEBUG_PRINTHEX(accel_addr); @@ -67,9 +67,9 @@ bool drvLsm303agr::begin() { _accel->setMode(LSM303_MODE_HIGH_RESOLUTION); WS_DEBUG_PRINT("[drvLsm303agr] Initialising magnetometer @ 0x"); - WS_DEBUG_PRINTHEX(kLsm303agrMagDefaultAddr); + WS_DEBUG_PRINTHEX(LSM303AGR_MAG_DEFAULT_ADDR); WS_DEBUG_PRINTLN("..."); - if (!_mag->begin(kLsm303agrMagDefaultAddr, _i2c)) { + if (!_mag->begin(LSM303AGR_MAG_DEFAULT_ADDR, _i2c)) { WS_DEBUG_PRINTLN("[drvLsm303agr] Failed to initialise LIS2MDL"); teardown(); return false; @@ -83,7 +83,7 @@ bool drvLsm303agr::begin() { } /******************************************************************************/ -/*! +/*! @brief Computes the magnitude of the accelerometer vector. @param magnitude Reference to store the computed m/s^2 value. @returns True if the accelerometer event was retrieved successfully. @@ -104,7 +104,7 @@ bool drvLsm303agr::computeAccelMagnitude(float &magnitude) { } /******************************************************************************/ -/*! +/*! @brief Fills the raw event with the accelerometer magnitude in data[0]. @param rawEvent Pointer to the destination sensor event. @returns True if the magnitude was computed successfully. @@ -120,7 +120,7 @@ bool drvLsm303agr::getEventRaw(sensors_event_t *rawEvent) { } /******************************************************************************/ -/*! +/*! @brief Retrieves the 3-axis accelerometer event. @param accelEvent Pointer to the destination sensor event. @returns True if the event was populated successfully. @@ -134,7 +134,7 @@ bool drvLsm303agr::getEventAccelerometer(sensors_event_t *accelEvent) { } /******************************************************************************/ -/*! +/*! @brief Retrieves the 3-axis magnetic field event. @param magEvent Pointer to the destination sensor event. @returns True if the event was populated successfully. @@ -148,7 +148,7 @@ bool drvLsm303agr::getEventMagneticField(sensors_event_t *magEvent) { } /******************************************************************************/ -/*! +/*! @brief Registers the driver's default accelerometer and magnetometer types. */ /******************************************************************************/ diff --git a/src/components/i2c/drivers/drvLsm303agr.h b/src/components/i2c/drivers/drvLsm303agr.h index abcd8265f..7a704700c 100644 --- a/src/components/i2c/drivers/drvLsm303agr.h +++ b/src/components/i2c/drivers/drvLsm303agr.h @@ -1,4 +1,4 @@ -/*! +/*! * @file drvLsm303agr.h * * Driver wrapper for the Adafruit LSM303AGR combo sensor (accel + mag). @@ -19,7 +19,7 @@ #include /**************************************************************************/ -/*! +/*! @brief Driver interface for the Adafruit LSM303AGR combo sensor. */ /**************************************************************************/ @@ -30,14 +30,14 @@ class drvLsm303agr : public drvBase { : drvBase(i2c, sensorAddress, mux_channel, driver_name) {} /**************************************************************************/ - /*! + /*! @brief Destructor for the LSM303AGR driver. */ /**************************************************************************/ ~drvLsm303agr(); /**************************************************************************/ - /*! + /*! @brief Initializes the accelerometer and magnetometer peripherals. @returns True if initialization succeeded, False otherwise. */ @@ -45,7 +45,7 @@ class drvLsm303agr : public drvBase { bool begin() override; /**************************************************************************/ - /*! + /*! @brief Populates a raw magnitude reading into a sensor event. @param rawEvent Pointer to the destination sensor event. @returns True if the event was populated successfully. @@ -54,7 +54,7 @@ class drvLsm303agr : public drvBase { bool getEventRaw(sensors_event_t *rawEvent) override; /**************************************************************************/ - /*! + /*! @brief Retrieves the accelerometer vector event. @param accelEvent Pointer to the destination sensor event. @returns True if the event was populated successfully. @@ -63,7 +63,7 @@ class drvLsm303agr : public drvBase { bool getEventAccelerometer(sensors_event_t *accelEvent) override; /**************************************************************************/ - /*! + /*! @brief Retrieves the magnetic field vector event. @param magEvent Pointer to the destination sensor event. @returns True if the event was populated successfully. @@ -73,7 +73,7 @@ class drvLsm303agr : public drvBase { protected: /**************************************************************************/ - /*! + /*! @brief Registers the default set of virtual sensor types. */ /**************************************************************************/ @@ -81,13 +81,13 @@ class drvLsm303agr : public drvBase { private: /**************************************************************************/ - /*! + /*! @brief Releases any allocated sensor instances. */ /**************************************************************************/ void teardown(); /**************************************************************************/ - /*! + /*! @brief Computes the linear acceleration magnitude in m/s^2. @param magnitude Reference to store the computed value. @returns True if the magnitude was computed successfully. diff --git a/src/components/i2c/drivers/drvLsm303dlh.cpp b/src/components/i2c/drivers/drvLsm303dlh.cpp index 61a55a53d..8d1b26ee1 100644 --- a/src/components/i2c/drivers/drvLsm303dlh.cpp +++ b/src/components/i2c/drivers/drvLsm303dlh.cpp @@ -8,20 +8,18 @@ #include -namespace { -constexpr uint8_t kLsm303dlhAccelDefaultAddr = LSM303_ADDRESS_ACCEL; -constexpr uint8_t kLsm303dlhMagDefaultAddr = 0x1E; -} +#define LSM303DLH_ACCEL_DEFAULT_ADDR LSM303_ADDRESS_ACCEL +#define LSM303DLH_MAG_DEFAULT_ADDR 0x1E /******************************************************************************/ -/*! +/*! @brief Destructor for the legacy LSM303DLH driver wrapper. */ /******************************************************************************/ drvLsm303dlh::~drvLsm303dlh() { teardown(); } /******************************************************************************/ -/*! +/*! @brief Releases any allocated accelerometer or magnetometer instances. */ /******************************************************************************/ @@ -37,7 +35,7 @@ void drvLsm303dlh::teardown() { } /******************************************************************************/ -/*! +/*! @brief Initializes the LSM303DLH accelerometer and magnetometer helpers. @returns True if initialization succeeded, False otherwise. */ @@ -52,8 +50,10 @@ bool drvLsm303dlh::begin() { return false; } + // TODO: if _address isn't default (or alt), shift mag by same offset. + // to support adress translators. Alternatively compound components. const uint8_t accel_addr = - _address == 0 ? kLsm303dlhAccelDefaultAddr : (uint8_t)_address; + _address == 0 ? LSM303DLH_ACCEL_DEFAULT_ADDR : (uint8_t)_address; WS_DEBUG_PRINT("[drvLsm303dlh] Initialising accel @ 0x"); WS_DEBUG_PRINTHEX(accel_addr); @@ -67,9 +67,9 @@ bool drvLsm303dlh::begin() { _accel->setMode(LSM303_MODE_HIGH_RESOLUTION); WS_DEBUG_PRINT("[drvLsm303dlh] Initialising magnetometer @ 0x"); - WS_DEBUG_PRINTHEX(kLsm303dlhMagDefaultAddr); + WS_DEBUG_PRINTHEX(LSM303DLH_MAG_DEFAULT_ADDR); WS_DEBUG_PRINTLN("..."); - if (!_mag->begin(kLsm303dlhMagDefaultAddr, _i2c)) { + if (!_mag->begin(LSM303DLH_MAG_DEFAULT_ADDR, _i2c)) { WS_DEBUG_PRINTLN("[drvLsm303dlh] Failed to initialise LSM303DLH mag"); teardown(); return false; @@ -83,7 +83,7 @@ bool drvLsm303dlh::begin() { } /******************************************************************************/ -/*! +/*! @brief Computes the magnitude of the accelerometer vector. @param magnitude Reference to store the computed m/s^2 value. @returns True if the accelerometer event was retrieved successfully. @@ -104,7 +104,7 @@ bool drvLsm303dlh::computeAccelMagnitude(float &magnitude) { } /******************************************************************************/ -/*! +/*! @brief Fills the raw event with the accelerometer magnitude in data[0]. @param rawEvent Pointer to the destination sensor event. @returns True if the magnitude was computed successfully. @@ -120,7 +120,7 @@ bool drvLsm303dlh::getEventRaw(sensors_event_t *rawEvent) { } /******************************************************************************/ -/*! +/*! @brief Retrieves the 3-axis accelerometer event. @param accelEvent Pointer to the destination sensor event. @returns True if the event was populated successfully. @@ -134,7 +134,7 @@ bool drvLsm303dlh::getEventAccelerometer(sensors_event_t *accelEvent) { } /******************************************************************************/ -/*! +/*! @brief Retrieves the 3-axis magnetic field event. @param magEvent Pointer to the destination sensor event. @returns True if the event was populated successfully. @@ -148,7 +148,7 @@ bool drvLsm303dlh::getEventMagneticField(sensors_event_t *magEvent) { } /******************************************************************************/ -/*! +/*! @brief Registers the driver's default accelerometer and magnetometer types. */ /******************************************************************************/ diff --git a/src/components/i2c/drivers/drvLsm303dlh.h b/src/components/i2c/drivers/drvLsm303dlh.h index 8925cd6b3..17f3b65ac 100644 --- a/src/components/i2c/drivers/drvLsm303dlh.h +++ b/src/components/i2c/drivers/drvLsm303dlh.h @@ -1,4 +1,4 @@ -/*! +/*! * @file drvLsm303dlh.h * * Driver wrapper for the classic Adafruit LSM303DLH combo sensor. @@ -19,7 +19,7 @@ #include /**************************************************************************/ -/*! +/*! @brief Driver interface for the legacy Adafruit LSM303DLH combo sensor. */ /**************************************************************************/ @@ -30,14 +30,14 @@ class drvLsm303dlh : public drvBase { : drvBase(i2c, sensorAddress, mux_channel, driver_name) {} /**************************************************************************/ - /*! + /*! @brief Destructor for the LSM303DLH driver. */ /**************************************************************************/ ~drvLsm303dlh(); /**************************************************************************/ - /*! + /*! @brief Initializes the accelerometer and magnetometer peripherals. @returns True if initialization succeeded, False otherwise. */ @@ -45,7 +45,7 @@ class drvLsm303dlh : public drvBase { bool begin() override; /**************************************************************************/ - /*! + /*! @brief Populates a raw magnitude reading into a sensor event. @param rawEvent Pointer to the destination sensor event. @returns True if the event was populated successfully. @@ -54,7 +54,7 @@ class drvLsm303dlh : public drvBase { bool getEventRaw(sensors_event_t *rawEvent) override; /**************************************************************************/ - /*! + /*! @brief Retrieves the accelerometer vector event. @param accelEvent Pointer to the destination sensor event. @returns True if the event was populated successfully. @@ -63,7 +63,7 @@ class drvLsm303dlh : public drvBase { bool getEventAccelerometer(sensors_event_t *accelEvent) override; /**************************************************************************/ - /*! + /*! @brief Retrieves the magnetic field vector event. @param magEvent Pointer to the destination sensor event. @returns True if the event was populated successfully. @@ -73,7 +73,7 @@ class drvLsm303dlh : public drvBase { protected: /**************************************************************************/ - /*! + /*! @brief Registers the default set of virtual sensor types. */ /**************************************************************************/ @@ -81,13 +81,13 @@ class drvLsm303dlh : public drvBase { private: /**************************************************************************/ - /*! + /*! @brief Releases any allocated sensor instances. */ /**************************************************************************/ void teardown(); /**************************************************************************/ - /*! + /*! @brief Computes the linear acceleration magnitude in m/s^2. @param magnitude Reference to store the computed value. @returns True if the magnitude was computed successfully. diff --git a/src/components/i2c/drivers/drvLsm6ds3.cpp b/src/components/i2c/drivers/drvLsm6ds3.cpp index be1860d5c..2de080449 100644 --- a/src/components/i2c/drivers/drvLsm6ds3.cpp +++ b/src/components/i2c/drivers/drvLsm6ds3.cpp @@ -54,8 +54,7 @@ bool drvLsm6ds3::begin() { return true; } -bool drvLsm6ds3::readAllEvents(sensors_event_t *accel, - sensors_event_t *gyro, +bool drvLsm6ds3::readAllEvents(sensors_event_t *accel, sensors_event_t *gyro, sensors_event_t *temp) { if (!_imu) { return false; diff --git a/src/components/i2c/drivers/drvLsm6dso32.cpp b/src/components/i2c/drivers/drvLsm6dso32.cpp index c4d7885dc..b6477daf6 100644 --- a/src/components/i2c/drivers/drvLsm6dso32.cpp +++ b/src/components/i2c/drivers/drvLsm6dso32.cpp @@ -52,8 +52,7 @@ bool drvLsm6dso32::begin() { return true; } -bool drvLsm6dso32::readAllEvents(sensors_event_t *accel, - sensors_event_t *gyro, +bool drvLsm6dso32::readAllEvents(sensors_event_t *accel, sensors_event_t *gyro, sensors_event_t *temp) { if (!_imu) { return false; diff --git a/src/components/i2c/drivers/drvLsm9ds1.cpp b/src/components/i2c/drivers/drvLsm9ds1.cpp index 30ec4aa1f..7a07829f0 100644 --- a/src/components/i2c/drivers/drvLsm9ds1.cpp +++ b/src/components/i2c/drivers/drvLsm9ds1.cpp @@ -45,10 +45,8 @@ bool drvLsm9ds1::begin() { return true; } -bool drvLsm9ds1::readAllEvents(sensors_event_t *accel, - sensors_event_t *mag, - sensors_event_t *gyro, - sensors_event_t *temp) { +bool drvLsm9ds1::readAllEvents(sensors_event_t *accel, sensors_event_t *mag, + sensors_event_t *gyro, sensors_event_t *temp) { if (!_lsm) { return false; } @@ -67,7 +65,7 @@ bool drvLsm9ds1::readAllEvents(sensors_event_t *accel, */ /******************************************************************************/ bool drvLsm9ds1::getEventRaw(sensors_event_t *rawEvent) { - //TODO: Not yet, but eventually migrate to providing the temperatre data here + // TODO: Not yet, but eventually migrate to providing the temperatre data here WS_DEBUG_PRINTLN("[drvLsm9ds1] Getting raw event..."); sensors_event_t accel, mag, gyro, temp; if (!readAllEvents(&accel, &mag, &gyro, &temp)) { @@ -105,11 +103,11 @@ bool drvLsm9ds1::getEventBoolean(sensors_event_t *booleanEvent) { bool tap_detected = (mag_accel > LSM9DS1_TAP_THRESHOLD_MSS); booleanEvent->data[0] = tap_detected ? 1.0f : 0.0f; - + if (tap_detected) { WS_DEBUG_PRINTLN("[drvLsm9ds1] Tap event detected!"); } - + return true; } diff --git a/src/components/i2c/drivers/drvLsm9ds1.h b/src/components/i2c/drivers/drvLsm9ds1.h index b5fb1c47b..a91d6ce06 100644 --- a/src/components/i2c/drivers/drvLsm9ds1.h +++ b/src/components/i2c/drivers/drvLsm9ds1.h @@ -123,8 +123,8 @@ class drvLsm9ds1 : public drvBase { protected: Adafruit_LSM9DS1 *_lsm = nullptr; ///< Pointer to LSM9DS1 sensor object - bool readAllEvents(sensors_event_t *accel, sensors_event_t *mag, - sensors_event_t *gyro, sensors_event_t *temp); + bool readAllEvents(sensors_event_t *accel, sensors_event_t *mag, + sensors_event_t *gyro, sensors_event_t *temp); }; #endif // DRV_LSM9DS1_H From 24be577148528c0abf78d97e283c930dff7839cd Mon Sep 17 00:00:00 2001 From: tyeth Date: Sat, 15 Nov 2025 17:11:09 +0000 Subject: [PATCH 13/21] [chore] more formatting --- src/components/i2c/controller.h | 12 ++++++------ src/components/i2c/model.cpp | 5 ++--- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/components/i2c/controller.h b/src/components/i2c/controller.h index fd2da38ae..304b8bfa9 100644 --- a/src/components/i2c/controller.h +++ b/src/components/i2c/controller.h @@ -39,20 +39,20 @@ #include "drivers/drvIna237.h" #include "drivers/drvIna238.h" #include "drivers/drvIna260.h" +#include "drivers/drvIsm330dhcx.h" +#include "drivers/drvIsm330dlc.h" #include "drivers/drvLc709203f.h" #include "drivers/drvLis2mdl.h" #include "drivers/drvLis3dh.h" +#include "drivers/drvLis3mdl.h" +#include "drivers/drvLps22hb.h" +#include "drivers/drvLps25hb.h" +#include "drivers/drvLps3xhw.h" #include "drivers/drvLsm303agr.h" #include "drivers/drvLsm303dlh.h" -#include "drivers/drvIsm330dhcx.h" -#include "drivers/drvLis3mdl.h" -#include "drivers/drvIsm330dlc.h" #include "drivers/drvLsm6ds3.h" #include "drivers/drvLsm6dso32.h" #include "drivers/drvLsm9ds1.h" -#include "drivers/drvLps22hb.h" -#include "drivers/drvLps25hb.h" -#include "drivers/drvLps3xhw.h" #include "drivers/drvLtr329_Ltr303.h" #include "drivers/drvLtr390.h" #include "drivers/drvMCP9808.h" diff --git a/src/components/i2c/model.cpp b/src/components/i2c/model.cpp index 09b978d8c..0ecb3b9f2 100644 --- a/src/components/i2c/model.cpp +++ b/src/components/i2c/model.cpp @@ -219,9 +219,8 @@ GetValueFromSensorsEventOrientation(wippersnapper_sensor_SensorType sensor_type, The sensors_event_t event. @returns The value of the SensorType as a boolean. */ -bool -GetValueFromSensorsEventBoolean(wippersnapper_sensor_SensorType sensor_type, - sensors_event_t *event) { +bool GetValueFromSensorsEventBoolean( + wippersnapper_sensor_SensorType sensor_type, sensors_event_t *event) { bool value = false; WS_DEBUG_PRINTLN("[i2c] Getting boolean event value..."); WS_DEBUG_PRINT("[i2c] Event data[0]: "); From 0757f70951239d52dfd4e70cbfe2c2271abe2b99 Mon Sep 17 00:00:00 2001 From: tyeth Date: Sat, 15 Nov 2025 17:28:37 +0000 Subject: [PATCH 14/21] [fix] library.properties LSM6DS --- library.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library.properties b/library.properties index 7c40a3411..ec5018627 100644 --- a/library.properties +++ b/library.properties @@ -7,4 +7,4 @@ paragraph=Arduino application for Adafruit.io WipperSnapper category=Communication url=https://github.com/adafruit/Adafruit_Wippersnapper_Arduino architectures=* -depends=OmronD6T - Community Fork, SdFat - Adafruit Fork, Adafruit LIS3DH, Adafruit LIS3MDL, Adafruit LSM6DS Library, Adafruit LSM9DS1 Library, Adafruit LSM303 Accel, Adafruit LSM303DLH Mag, Adafruit LIS2MDL, Adafruit AS5600 Library, Adafruit NeoPixel, Adafruit SPIFlash, ArduinoJson, Adafruit DotStar, Adafruit HDC302x, Adafruit INA219, Adafruit INA237 and INA238 Library, Adafruit INA260 Library, Adafruit LTR329 and LTR303, Adafruit LTR390 Library, Adafruit MCP3421, Adafruit MLX90632 Library, Adafruit NAU7802 Library, Adafruit SleepyDog Library, Adafruit TMP117, Adafruit TinyUSB Library, Adafruit AHTX0, Adafruit BME280 Library, Adafruit BMP280 Library, Adafruit BMP3XX Library, Adafruit DPS310, Adafruit DS248x, Adafruit SCD30, Adafruit SGP30 Sensor, Adafruit SGP40 Sensor, Sensirion I2C SCD4x, Sensirion I2C SEN5X, Sensirion I2C SEN66, arduino-sht, Adafruit Si7021 Library, Adafruit MQTT Library, Adafruit MS8607, Adafruit MCP9808 Library, Adafruit MCP9600 Library, Adafruit MPL115A2, Adafruit MPRLS Library, Adafruit TSL2591 Library, Adafruit_VL53L0X, Adafruit VL53L1X, STM32duino VL53L4CD, STM32duino VL53L4CX, Adafruit_VL6180X, Adafruit PM25 AQI Sensor, Adafruit QMC5883P Library, Adafruit VCNL4020 Library, Adafruit VCNL4040, Adafruit VCNL4200 Library, Adafruit VEML7700 Library, Adafruit LC709203F, Adafruit LPS2X, Adafruit LPS28, Adafruit LPS35HW, Adafruit seesaw Library, Adafruit BME680 Library, Adafruit MAX1704X, Adafruit ADT7410 Library, Adafruit HTS221, Adafruit HTU21DF Library, Adafruit HTU31D Library, Adafruit PCT2075, hp_BH1750, ENS160 - Adafruit Fork, Adafruit BusIO, Adafruit Unified Sensor, Sensirion Core, Adafruit GFX Library, Adafruit LED Backpack Library, Adafruit LiquidCrystal, Adafruit SH110X, Adafruit SSD1306, RTClib, StreamUtils, Adafruit SHT4x Library, Adafruit GPS Library, Adafruit uBlox +depends=OmronD6T - Community Fork, SdFat - Adafruit Fork, Adafruit LIS3DH, Adafruit LIS3MDL, Adafruit LSM6DS, Adafruit LSM9DS1 Library, Adafruit LSM303 Accel, Adafruit LSM303DLH Mag, Adafruit LIS2MDL, Adafruit AS5600 Library, Adafruit NeoPixel, Adafruit SPIFlash, ArduinoJson, Adafruit DotStar, Adafruit HDC302x, Adafruit INA219, Adafruit INA237 and INA238 Library, Adafruit INA260 Library, Adafruit LTR329 and LTR303, Adafruit LTR390 Library, Adafruit MCP3421, Adafruit MLX90632 Library, Adafruit NAU7802 Library, Adafruit SleepyDog Library, Adafruit TMP117, Adafruit TinyUSB Library, Adafruit AHTX0, Adafruit BME280 Library, Adafruit BMP280 Library, Adafruit BMP3XX Library, Adafruit DPS310, Adafruit DS248x, Adafruit SCD30, Adafruit SGP30 Sensor, Adafruit SGP40 Sensor, Sensirion I2C SCD4x, Sensirion I2C SEN5X, Sensirion I2C SEN66, arduino-sht, Adafruit Si7021 Library, Adafruit MQTT Library, Adafruit MS8607, Adafruit MCP9808 Library, Adafruit MCP9600 Library, Adafruit MPL115A2, Adafruit MPRLS Library, Adafruit TSL2591 Library, Adafruit_VL53L0X, Adafruit VL53L1X, STM32duino VL53L4CD, STM32duino VL53L4CX, Adafruit_VL6180X, Adafruit PM25 AQI Sensor, Adafruit QMC5883P Library, Adafruit VCNL4020 Library, Adafruit VCNL4040, Adafruit VCNL4200 Library, Adafruit VEML7700 Library, Adafruit LC709203F, Adafruit LPS2X, Adafruit LPS28, Adafruit LPS35HW, Adafruit seesaw Library, Adafruit BME680 Library, Adafruit MAX1704X, Adafruit ADT7410 Library, Adafruit HTS221, Adafruit HTU21DF Library, Adafruit HTU31D Library, Adafruit PCT2075, hp_BH1750, ENS160 - Adafruit Fork, Adafruit BusIO, Adafruit Unified Sensor, Sensirion Core, Adafruit GFX Library, Adafruit LED Backpack Library, Adafruit LiquidCrystal, Adafruit SH110X, Adafruit SSD1306, RTClib, StreamUtils, Adafruit SHT4x Library, Adafruit GPS Library, Adafruit uBlox From 3936e2eb79e35fb0f1905a2074f830647ec47462 Mon Sep 17 00:00:00 2001 From: tyeth Date: Mon, 17 Nov 2025 15:29:24 +0000 Subject: [PATCH 15/21] [wip]: Step counter --- platformio.ini | 44 ++++++++-- src/components/i2c/drivers/drvIsm330dhcx.cpp | 85 +++++++++++++++----- src/components/i2c/drivers/drvIsm330dhcx.h | 17 +++- src/components/i2c/drivers/drvLsm6dso32.cpp | 4 +- 4 files changed, 118 insertions(+), 32 deletions(-) diff --git a/platformio.ini b/platformio.ini index 31a9a6643..5460ac6e6 100644 --- a/platformio.ini +++ b/platformio.ini @@ -119,7 +119,7 @@ lib_deps = ; Common build environment for ESP32 platform [common:esp32] platform = https://github.com/pioarduino/platform-espressif32/releases/download/55.03.33/platform-espressif32.zip -lib_ignore = WiFiNINA, WiFi101 +lib_ignore = WiFiNINA, WiFi101, WiFiNINA_-_Adafruit_Fork monitor_filters = esp32_exception_decoder, time ; upload_speed = 921600 @@ -148,7 +148,7 @@ board_build.core = earlephilhower board_build.filesystem_size = 0.5m build_flags = -DUSE_TINYUSB ; Once https://github.com/platformio/platformio-core > 6.1.11 these can be removed -lib_ignore = WiFiNINA, WiFi101, Adafruit Zero DMA Library +lib_ignore = WiFiNINA, WiFi101, Adafruit Zero DMA Library, WiFiNINA_-_Adafruit_Fork lib_compat_mode = soft ; can be strict once pio detects SleepyDog on RP2040 @@ -197,13 +197,32 @@ board_build.filesystem = littlefs [env:featheresp32s2] extends = common:esp32 board = featheresp32-s2 -build_flags = -DARDUINO_ADAFRUIT_FEATHER_ESP32S2 -DBOARD_HAS_PSRAM -DBUILD_OFFLINE_ONLY +build_flags = + -DARDUINO_ADAFRUIT_FEATHER_ESP32S2 + -DBOARD_HAS_PSRAM + -DBUILD_OFFLINE_ONLY + ; -DSDFAT_FILE_TYPE=3 board_build.partitions = tinyuf2-partitions-4MB-noota.csv ;board_build.partitions = tinyuf2-partitions-4MB.csv ;build_type = debug monitor_filters = esp32_exception_decoder extra_scripts = pre:rename_usb_config.py +[env:featheresp32s2_debug] +extends = env:featheresp32s2 +build_type = debug +build_flags = + -DARDUINO_ADAFRUIT_FEATHER_ESP32S2 + -DBOARD_HAS_PSRAM + -DBUILD_OFFLINE_ONLY + ; -DSDFAT_FILE_TYPE=3 + -DDEBUG=1 + -DCFG_TUSB_DEBUG=1 + -DESP_LOG_LEVEL=ESP_LOG_VERBOSE + -DARDUINO_CORE_DEBUG_LEVEL=5 + -DCORE_DEBUG_LEVEL=5 + -DARDUHAL_LOG_LEVEL=5 + ; Adafruit Feather ESP32-S2 TFT [env:adafruit_feather_esp32s2_tft] extends = common:esp32 @@ -467,43 +486,53 @@ build_flags = -DUSE_TINYUSB=1 upload_port = /dev/cu.usbmodem1201 [env:raspberrypi_pico] +extends = common:rp2040 platform = https://github.com/maxgerhardt/platform-raspberrypi.git#develop board = rpipico platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git board_build.filesystem_size = 0.5m build_flags = -DUSE_TINYUSB ; Once https://github.com/platformio/platformio-core > 6.1.11 these can be removed -lib_ignore = WiFiNINA, WiFi101, Adafruit Zero DMA Library [env:raspberrypi_pico_2] +extends = common:rp2040 platform = https://github.com/maxgerhardt/platform-raspberrypi.git#develop board = rpipico2 platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git board_build.filesystem_size = 0.5m build_flags = -DUSE_TINYUSB -DBUILD_OFFLINE_ONLY ; Once https://github.com/platformio/platformio-core > 6.1.11 these can be removed -lib_ignore = WiFiNINA, WiFi101, Adafruit Zero DMA Library + +[env:raspberrypi_pico_2w] +extends: common:rp2040 +platform = https://github.com/maxgerhardt/platform-raspberrypi.git#develop +board = rpipico2w +platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git +board_build.filesystem_size = 0.5m +build_flags = -DUSE_TINYUSB -DBUILD_OFFLINE_ONLY +; Once https://github.com/platformio/platformio-core > 6.1.11 these can be removed [env:adafruit_feather_adalogger] +extends = common:rp2040 platform = https://github.com/maxgerhardt/platform-raspberrypi.git#develop board = adafruit_feather_adalogger platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git board_build.filesystem_size = 0.5m build_flags = -DUSE_TINYUSB ; Once https://github.com/platformio/platformio-core > 6.1.11 these can be removed -lib_ignore = WiFiNINA, WiFi101, Adafruit Zero DMA Library [env:adafruit_metro_rp2350] +extends = common:rp2040 platform = https://github.com/brentru/platform-raspberrypi.git#develop board = adafruit_metro_rp2350 platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git board_build.filesystem_size = 0.5m build_flags = -DUSE_TINYUSB -DBUILD_OFFLINE_ONLY ; Once https://github.com/platformio/platformio-core > 6.1.11 these can be removed -lib_ignore = WiFiNINA, WiFi101, Adafruit Zero DMA Library [env:adafruit_metro_rp2350_debug] +extends = common:rp2040 platform = https://github.com/brentru/platform-raspberrypi.git#develop platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git board = adafruit_metro_rp2350 @@ -542,7 +571,6 @@ build_flags = ; build_flags = -DPIO_FRAMEWORK_ARDUINO_NO_USB ; -DPIO_FRAMEWORK_ARDUINO_ENABLE_IPV6 ; Once https://github.com/platformio/platformio-core > 6.1.11 these can be removed -lib_ignore = WiFiNINA, WiFi101, Adafruit Zero DMA Library [env:raspberypi_picow] diff --git a/src/components/i2c/drivers/drvIsm330dhcx.cpp b/src/components/i2c/drivers/drvIsm330dhcx.cpp index 3a79a7979..5a8884fc1 100644 --- a/src/components/i2c/drivers/drvIsm330dhcx.cpp +++ b/src/components/i2c/drivers/drvIsm330dhcx.cpp @@ -46,8 +46,10 @@ bool drvIsm330dhcx::begin() { _imu->setAccelDataRate(LSM6DS_RATE_104_HZ); _imu->setGyroRange(LSM6DS_GYRO_RANGE_500_DPS); _imu->setGyroDataRate(LSM6DS_RATE_104_HZ); + _imu->highPassFilter(true, LSM6DS_HPF_ODR_DIV_100); _imu->configInt1(false, false, false, false, true); _imu->configInt2(false, false, false); + _imu->enablePedometer(true); _imu->enableWakeup(true); WS_DEBUG_PRINTLN("[drvIsm330dhcx] Sensor initialised successfully"); @@ -55,21 +57,41 @@ bool drvIsm330dhcx::begin() { } bool drvIsm330dhcx::readAllEvents(sensors_event_t *accel, sensors_event_t *gyro, - sensors_event_t *temp) { + sensors_event_t *temp, boolean *shake, uint16_t *steps) { if (!_imu) { return false; } + if (_lastPoll > 0 && _internalPollPeriod > 0 && millis() - _lastPoll < _internalPollPeriod) { + // Limit polling to every 200ms, return cache, but not first time + return true; + } + _lastPoll = millis(); // TODO: set in fastTicks, if used, instead + if (_imu->shake()) { + WS_DEBUG_PRINTLN("[drvIsm330dhcx] Shake detected!"); + *shake = true; + } + uint16_t step_change = _imu->readPedometer(); + if (step_change > 0) { + WS_DEBUG_PRINT("[drvIsm330dhcx] Steps detected: ") + WS_DEBUG_PRINTLN(step_change); + steps = steps + step_change; + _imu->resetPedometer(); + } return _imu->getEvent(accel, gyro, temp); } +bool drvIsm330dhcx::readAllEvents() { + return readAllEvents(&_lastAccelEvent, &_lastGyroEvent, &_lastTempEvent, + &_last_shake, &_last_steps); +} + bool drvIsm330dhcx::computeAccelMagnitude(float &magnitude) { - sensors_event_t accel, gyro, temp; - if (!readAllEvents(&accel, &gyro, &temp)) { + if (!readAllEvents()) { return false; } - magnitude = sqrtf(accel.acceleration.x * accel.acceleration.x + - accel.acceleration.y * accel.acceleration.y + - accel.acceleration.z * accel.acceleration.z); + magnitude = sqrtf(_lastAccelEvent.acceleration.x * _lastAccelEvent.acceleration.x + + _lastAccelEvent.acceleration.y * _lastAccelEvent.acceleration.y + + _lastAccelEvent.acceleration.z * _lastAccelEvent.acceleration.z); return true; } @@ -77,27 +99,42 @@ bool drvIsm330dhcx::getEventRaw(sensors_event_t *rawEvent) { if (!_imu) { return false; } - WS_DEBUG_PRINTLN("[drvIsm330dhcx] Getting raw magnitude event..."); - float magnitude = 0.0f; - if (!computeAccelMagnitude(magnitude)) { + + if (!readAllEvents()) { return false; } - rawEvent->data[0] = magnitude; - WS_DEBUG_PRINT("[drvIsm330dhcx] Raw magnitude: "); - WS_DEBUG_PRINTLN(magnitude); + // Return step count as raw event, counter cleared at read + rawEvent->data[0] = (float)_last_steps; + _last_steps = 0; return true; + + + ////MAGNITUDE ONLY - DISABLED FOR NOW + // WS_DEBUG_PRINTLN("[drvIsm330dhcx] Getting raw magnitude event..."); + // float magnitude = 0.0f; + // if (!computeAccelMagnitude(magnitude)) { + // return false; + // } + // rawEvent->data[0] = magnitude; + // WS_DEBUG_PRINT("[drvIsm330dhcx] Raw magnitude: "); + // WS_DEBUG_PRINTLN(magnitude); + // return true; } bool drvIsm330dhcx::getEventBoolean(sensors_event_t *booleanEvent) { if (!_imu) { return false; } - WS_DEBUG_PRINTLN("[drvIsm330dhcx] Checking for tap/threshold event..."); - bool tap = _imu->shake(); - booleanEvent->data[0] = tap ? 1.0f : 0.0f; - if (tap) { - WS_DEBUG_PRINTLN("[drvIsm330dhcx] Threshold event detected"); + if (!readAllEvents()) { + return false; + } + WS_DEBUG_PRINT("[drvIsm330dhcx] Checking for shake/tap/threshold event..."); + WS_DEBUG_PRINTLN(_last_shake ? " DETECTED!" : " none."); + booleanEvent->data[0] = _last_shake ? 1.0f : 0.0f; + if (_last_shake) { + WS_DEBUG_PRINTLN("[drvIsm330dhcx] *** Threshold event detected ***"); } + _last_shake = false; return true; } @@ -106,8 +143,11 @@ bool drvIsm330dhcx::getEventAccelerometer(sensors_event_t *accelEvent) { return false; } WS_DEBUG_PRINTLN("[drvIsm330dhcx] Getting accelerometer event..."); - sensors_event_t gyro, temp; - return readAllEvents(accelEvent, &gyro, &temp); + bool result = readAllEvents() + ? memcpy(accelEvent, &_lastAccelEvent, sizeof(sensors_event_t)), + true + : false; + return result; } bool drvIsm330dhcx::getEventGyroscope(sensors_event_t *gyroEvent) { @@ -115,8 +155,11 @@ bool drvIsm330dhcx::getEventGyroscope(sensors_event_t *gyroEvent) { return false; } WS_DEBUG_PRINTLN("[drvIsm330dhcx] Getting gyroscope event..."); - sensors_event_t accel, temp; - return readAllEvents(&accel, gyroEvent, &temp); + bool result = readAllEvents() + ? memcpy(gyroEvent, &_lastGyroEvent, sizeof(sensors_event_t)), + true + : false; + return result; } void drvIsm330dhcx::ConfigureDefaultSensorTypes() { diff --git a/src/components/i2c/drivers/drvIsm330dhcx.h b/src/components/i2c/drivers/drvIsm330dhcx.h index c5d25ee12..9c0e6b9dc 100644 --- a/src/components/i2c/drivers/drvIsm330dhcx.h +++ b/src/components/i2c/drivers/drvIsm330dhcx.h @@ -25,12 +25,27 @@ class drvIsm330dhcx : public drvBase { bool getEventGyroscope(sensors_event_t *gyroEvent) override; void ConfigureDefaultSensorTypes() override; + void setInternalPollingInterval(uint32_t interval_ms) { // override { + // Polling interval is managed internally. + _internalPollPeriod = interval_ms < 0 ? 0 : interval_ms; + } private: bool readAllEvents(sensors_event_t *accel, sensors_event_t *gyro, - sensors_event_t *temp); + sensors_event_t *temp, boolean *shake, + uint16_t *steps); + bool readAllEvents(); bool computeAccelMagnitude(float &magnitude); + bool _has_last_events = false; ///< Flag to track if last events are stored + bool _last_shake = false; ///< Last state of shake / tap detection + sensors_event_t _lastAccelEvent; ///< Last accelerometer event + sensors_event_t _lastGyroEvent; ///< Last gyroscope event + sensors_event_t _lastTempEvent; ///< Last temperature event (raw) + uint16_t _last_steps = 0; ///< Last step count + uint32_t _lastPoll = 0; ///< Last poll time + uint32_t _internalPollPeriod = 200; ///< Internal Polling interval in ms + Adafruit_ISM330DHCX *_imu = nullptr; ///< Pointer to the ISM330DHCX sensor }; diff --git a/src/components/i2c/drivers/drvLsm6dso32.cpp b/src/components/i2c/drivers/drvLsm6dso32.cpp index b6477daf6..2e325be07 100644 --- a/src/components/i2c/drivers/drvLsm6dso32.cpp +++ b/src/components/i2c/drivers/drvLsm6dso32.cpp @@ -33,7 +33,7 @@ bool drvLsm6dso32::begin() { WS_DEBUG_PRINTHEX(addr); WS_DEBUG_PRINTLN("..."); - if (!_imu->begin_I2C(addr, _i2c)) { + if (!_imu->begin_I2C(addr, _i2c)) { // consider 3rd argument of sensor id, ensure we can run two of these. Could pass mux(+255+muxADDR) add 1000 for bus 1 vs 0 and add sensor addr WS_DEBUG_PRINTLN("[drvLsm6dso32] Failed to initialise sensor"); delete _imu; _imu = nullptr; @@ -44,7 +44,7 @@ bool drvLsm6dso32::begin() { _imu->setAccelDataRate(LSM6DS_RATE_104_HZ); _imu->setGyroRange(LSM6DS_GYRO_RANGE_500_DPS); _imu->setGyroDataRate(LSM6DS_RATE_104_HZ); - _imu->configInt1(false, false, false, false, true); + _imu->configInt1(false, false, false, true, true); _imu->configInt2(false, false, false); _imu->enableWakeup(true); From a653faee51a93d4d38d260d8afa5dcf3958a5ebf Mon Sep 17 00:00:00 2001 From: tyeth Date: Mon, 17 Nov 2025 15:30:01 +0000 Subject: [PATCH 16/21] [wip] Base class for LSM6DS --- .../i2c/drivers/drvBaseAccelLsm6.cpp | 118 ++++++++++++++++++ src/components/i2c/drivers/drvBaseAccelLsm6.h | 45 +++++++ src/components/i2c/drivers/drvIsm330dhcx.cpp | 115 +---------------- src/components/i2c/drivers/drvIsm330dhcx.h | 30 +---- src/components/i2c/drivers/drvIsm330dlc.cpp | 75 +---------- src/components/i2c/drivers/drvIsm330dlc.h | 15 +-- src/components/i2c/drivers/drvLsm6ds3.cpp | 64 +--------- src/components/i2c/drivers/drvLsm6ds3.h | 24 +--- src/components/i2c/drivers/drvLsm6dso32.cpp | 64 +--------- src/components/i2c/drivers/drvLsm6dso32.h | 20 +-- 10 files changed, 186 insertions(+), 384 deletions(-) create mode 100644 src/components/i2c/drivers/drvBaseAccelLsm6.cpp create mode 100644 src/components/i2c/drivers/drvBaseAccelLsm6.h diff --git a/src/components/i2c/drivers/drvBaseAccelLsm6.cpp b/src/components/i2c/drivers/drvBaseAccelLsm6.cpp new file mode 100644 index 000000000..893d17015 --- /dev/null +++ b/src/components/i2c/drivers/drvBaseAccelLsm6.cpp @@ -0,0 +1,118 @@ +/*! + * @file drvBaseAccelLsm6.cpp + */ + +#include "drvBaseAccelLsm6.h" + +#include + +drvBaseAccelLsm6::drvBaseAccelLsm6(TwoWire *i2c, uint16_t sensorAddress, + uint32_t mux_channel, + const char *driver_name) + : drvBase(i2c, sensorAddress, mux_channel, driver_name) {} + +drvBaseAccelLsm6::~drvBaseAccelLsm6() {} + +void drvBaseAccelLsm6::setInternalPollingInterval(uint32_t interval_ms) { + _internalPollPeriod = interval_ms; +} + +bool drvBaseAccelLsm6::readAllEvents() { + Adafruit_LSM6DS *imu = getLSM6Sensor(); + if (!imu) { + return false; + } + + uint32_t now = millis(); + if (_has_last_events && _internalPollPeriod > 0 && + (now - _lastPoll) < _internalPollPeriod) { + // too soon reuse cached data, except first run or interval=0 + return true; + } + + _lastPoll = now; + + if (imu->shake()) { + WS_DEBUG_PRINT("["); + WS_DEBUG_PRINT(_name); + WS_DEBUG_PRINTLN("] Shake detected!"); + _last_shake = true; + } + + uint16_t step_change = imu->readPedometer(); + if (step_change > 0) { + WS_DEBUG_PRINT("["); + WS_DEBUG_PRINT(_name); + WS_DEBUG_PRINT("] Steps detected: "); + WS_DEBUG_PRINTLN(step_change); + _last_steps += step_change; + imu->resetPedometer(); + } + + bool success = imu->getEvent(&_lastAccelEvent, &_lastGyroEvent, &_lastTempEvent); + _has_last_events = success; + return success; +} + +bool drvBaseAccelLsm6::computeAccelMagnitude(float &magnitude) { + if (!readAllEvents()) { + return false; + } + + magnitude = sqrtf(_lastAccelEvent.acceleration.x * + _lastAccelEvent.acceleration.x + + _lastAccelEvent.acceleration.y * + _lastAccelEvent.acceleration.y + + _lastAccelEvent.acceleration.z * + _lastAccelEvent.acceleration.z); + return true; +} + +bool drvBaseAccelLsm6::getEventRaw(sensors_event_t *rawEvent) { + if (!readAllEvents()) { + return false; + } + + rawEvent->data[0] = static_cast(_last_steps); + _last_steps = 0; + return true; +} + +bool drvBaseAccelLsm6::getEventBoolean(sensors_event_t *booleanEvent) { + if (!readAllEvents()) { + return false; + } + + booleanEvent->data[0] = _last_shake ? 1.0f : 0.0f; + if (_last_shake) { + WS_DEBUG_PRINT("["); + WS_DEBUG_PRINT(_name); + WS_DEBUG_PRINTLN("] *** Threshold event detected ***"); + _last_shake = false; + } + return true; +} + +bool drvBaseAccelLsm6::getEventAccelerometer(sensors_event_t *accelEvent) { + if (!readAllEvents()) { + return false; + } + + *accelEvent = _lastAccelEvent; + return true; +} + +bool drvBaseAccelLsm6::getEventGyroscope(sensors_event_t *gyroEvent) { + if (!readAllEvents()) { + return false; + } + + *gyroEvent = _lastGyroEvent; + return true; +} + +void drvBaseAccelLsm6::ConfigureDefaultSensorTypes() { + _default_sensor_types_count = 1; + _default_sensor_types[0] = + wippersnapper_sensor_SensorType_SENSOR_TYPE_ACCELEROMETER; +} diff --git a/src/components/i2c/drivers/drvBaseAccelLsm6.h b/src/components/i2c/drivers/drvBaseAccelLsm6.h new file mode 100644 index 000000000..ac77ebae0 --- /dev/null +++ b/src/components/i2c/drivers/drvBaseAccelLsm6.h @@ -0,0 +1,45 @@ +/*! + * @file drvBaseAccelLsm6.h + * + * Shared helper for Adafruit LSM6-series accelerometer/gyroscope drivers + * that expose shake and pedometer functionality. + */ +#ifndef DRV_BASE_ACCEL_LSM6_H +#define DRV_BASE_ACCEL_LSM6_H + +#include "drvBase.h" + +#include + +class drvBaseAccelLsm6 : public drvBase { +public: + drvBaseAccelLsm6(TwoWire *i2c, uint16_t sensorAddress, + uint32_t mux_channel, const char *driver_name); + virtual ~drvBaseAccelLsm6(); + + bool getEventBoolean(sensors_event_t *booleanEvent) override; + bool getEventRaw(sensors_event_t *rawEvent) override; + bool getEventAccelerometer(sensors_event_t *accelEvent) override; + bool getEventGyroscope(sensors_event_t *gyroEvent) override; + + void ConfigureDefaultSensorTypes() override; + + void setInternalPollingInterval(uint32_t interval_ms); + +protected: + virtual Adafruit_LSM6DS *getLSM6Sensor() const = 0; + + bool readAllEvents(); + bool computeAccelMagnitude(float &magnitude); + + bool _has_last_events = false; ///< Flag to track if last events are stored + bool _last_shake = false; ///< Last state of shake / tap detection + sensors_event_t _lastAccelEvent; ///< Last accelerometer event + sensors_event_t _lastGyroEvent; ///< Last gyroscope event + sensors_event_t _lastTempEvent; ///< Last temperature event (raw) + uint16_t _last_steps = 0; ///< Last step count + uint32_t _lastPoll = 0; ///< Last poll time + uint32_t _internalPollPeriod = 200; ///< Internal Polling interval in ms +}; + +#endif // DRV_BASE_ACCEL_LSM6_H diff --git a/src/components/i2c/drivers/drvIsm330dhcx.cpp b/src/components/i2c/drivers/drvIsm330dhcx.cpp index 5a8884fc1..a2137a404 100644 --- a/src/components/i2c/drivers/drvIsm330dhcx.cpp +++ b/src/components/i2c/drivers/drvIsm330dhcx.cpp @@ -6,11 +6,9 @@ #include "drvIsm330dhcx.h" -#include - drvIsm330dhcx::drvIsm330dhcx(TwoWire *i2c, uint16_t sensorAddress, uint32_t mux_channel, const char *driver_name) - : drvBase(i2c, sensorAddress, mux_channel, driver_name) {} + : drvBaseAccelLsm6(i2c, sensorAddress, mux_channel, driver_name) {} drvIsm330dhcx::~drvIsm330dhcx() { if (_imu) { @@ -56,114 +54,3 @@ bool drvIsm330dhcx::begin() { return true; } -bool drvIsm330dhcx::readAllEvents(sensors_event_t *accel, sensors_event_t *gyro, - sensors_event_t *temp, boolean *shake, uint16_t *steps) { - if (!_imu) { - return false; - } - if (_lastPoll > 0 && _internalPollPeriod > 0 && millis() - _lastPoll < _internalPollPeriod) { - // Limit polling to every 200ms, return cache, but not first time - return true; - } - _lastPoll = millis(); // TODO: set in fastTicks, if used, instead - if (_imu->shake()) { - WS_DEBUG_PRINTLN("[drvIsm330dhcx] Shake detected!"); - *shake = true; - } - uint16_t step_change = _imu->readPedometer(); - if (step_change > 0) { - WS_DEBUG_PRINT("[drvIsm330dhcx] Steps detected: ") - WS_DEBUG_PRINTLN(step_change); - steps = steps + step_change; - _imu->resetPedometer(); - } - return _imu->getEvent(accel, gyro, temp); -} - -bool drvIsm330dhcx::readAllEvents() { - return readAllEvents(&_lastAccelEvent, &_lastGyroEvent, &_lastTempEvent, - &_last_shake, &_last_steps); -} - -bool drvIsm330dhcx::computeAccelMagnitude(float &magnitude) { - if (!readAllEvents()) { - return false; - } - magnitude = sqrtf(_lastAccelEvent.acceleration.x * _lastAccelEvent.acceleration.x + - _lastAccelEvent.acceleration.y * _lastAccelEvent.acceleration.y + - _lastAccelEvent.acceleration.z * _lastAccelEvent.acceleration.z); - return true; -} - -bool drvIsm330dhcx::getEventRaw(sensors_event_t *rawEvent) { - if (!_imu) { - return false; - } - - if (!readAllEvents()) { - return false; - } - // Return step count as raw event, counter cleared at read - rawEvent->data[0] = (float)_last_steps; - _last_steps = 0; - return true; - - - ////MAGNITUDE ONLY - DISABLED FOR NOW - // WS_DEBUG_PRINTLN("[drvIsm330dhcx] Getting raw magnitude event..."); - // float magnitude = 0.0f; - // if (!computeAccelMagnitude(magnitude)) { - // return false; - // } - // rawEvent->data[0] = magnitude; - // WS_DEBUG_PRINT("[drvIsm330dhcx] Raw magnitude: "); - // WS_DEBUG_PRINTLN(magnitude); - // return true; -} - -bool drvIsm330dhcx::getEventBoolean(sensors_event_t *booleanEvent) { - if (!_imu) { - return false; - } - if (!readAllEvents()) { - return false; - } - WS_DEBUG_PRINT("[drvIsm330dhcx] Checking for shake/tap/threshold event..."); - WS_DEBUG_PRINTLN(_last_shake ? " DETECTED!" : " none."); - booleanEvent->data[0] = _last_shake ? 1.0f : 0.0f; - if (_last_shake) { - WS_DEBUG_PRINTLN("[drvIsm330dhcx] *** Threshold event detected ***"); - } - _last_shake = false; - return true; -} - -bool drvIsm330dhcx::getEventAccelerometer(sensors_event_t *accelEvent) { - if (!_imu) { - return false; - } - WS_DEBUG_PRINTLN("[drvIsm330dhcx] Getting accelerometer event..."); - bool result = readAllEvents() - ? memcpy(accelEvent, &_lastAccelEvent, sizeof(sensors_event_t)), - true - : false; - return result; -} - -bool drvIsm330dhcx::getEventGyroscope(sensors_event_t *gyroEvent) { - if (!_imu) { - return false; - } - WS_DEBUG_PRINTLN("[drvIsm330dhcx] Getting gyroscope event..."); - bool result = readAllEvents() - ? memcpy(gyroEvent, &_lastGyroEvent, sizeof(sensors_event_t)), - true - : false; - return result; -} - -void drvIsm330dhcx::ConfigureDefaultSensorTypes() { - _default_sensor_types_count = 1; - _default_sensor_types[0] = - wippersnapper_sensor_SensorType_SENSOR_TYPE_ACCELEROMETER; -} diff --git a/src/components/i2c/drivers/drvIsm330dhcx.h b/src/components/i2c/drivers/drvIsm330dhcx.h index 9c0e6b9dc..67960748f 100644 --- a/src/components/i2c/drivers/drvIsm330dhcx.h +++ b/src/components/i2c/drivers/drvIsm330dhcx.h @@ -7,45 +7,23 @@ #define DRV_ISM330DHCX_H #include "Wippersnapper_V2.h" -#include "drvBase.h" +#include "drvBaseAccelLsm6.h" #include #define ISM330_TAP_THRESHOLD_MSS 15.0f -class drvIsm330dhcx : public drvBase { +class drvIsm330dhcx : public drvBaseAccelLsm6 { public: drvIsm330dhcx(TwoWire *i2c, uint16_t sensorAddress, uint32_t mux_channel, const char *driver_name); ~drvIsm330dhcx(); bool begin() override; - bool getEventBoolean(sensors_event_t *booleanEvent) override; - bool getEventRaw(sensors_event_t *rawEvent) override; - bool getEventAccelerometer(sensors_event_t *accelEvent) override; - bool getEventGyroscope(sensors_event_t *gyroEvent) override; - void ConfigureDefaultSensorTypes() override; - void setInternalPollingInterval(uint32_t interval_ms) { // override { - // Polling interval is managed internally. - _internalPollPeriod = interval_ms < 0 ? 0 : interval_ms; - } +protected: + Adafruit_LSM6DS *getLSM6Sensor() const override { return _imu; } private: - bool readAllEvents(sensors_event_t *accel, sensors_event_t *gyro, - sensors_event_t *temp, boolean *shake, - uint16_t *steps); - bool readAllEvents(); - bool computeAccelMagnitude(float &magnitude); - - bool _has_last_events = false; ///< Flag to track if last events are stored - bool _last_shake = false; ///< Last state of shake / tap detection - sensors_event_t _lastAccelEvent; ///< Last accelerometer event - sensors_event_t _lastGyroEvent; ///< Last gyroscope event - sensors_event_t _lastTempEvent; ///< Last temperature event (raw) - uint16_t _last_steps = 0; ///< Last step count - uint32_t _lastPoll = 0; ///< Last poll time - uint32_t _internalPollPeriod = 200; ///< Internal Polling interval in ms - Adafruit_ISM330DHCX *_imu = nullptr; ///< Pointer to the ISM330DHCX sensor }; diff --git a/src/components/i2c/drivers/drvIsm330dlc.cpp b/src/components/i2c/drivers/drvIsm330dlc.cpp index a3c1804ba..9bc63c752 100644 --- a/src/components/i2c/drivers/drvIsm330dlc.cpp +++ b/src/components/i2c/drivers/drvIsm330dlc.cpp @@ -6,11 +6,9 @@ #include "drvIsm330dlc.h" -#include - drvIsm330dlc::drvIsm330dlc(TwoWire *i2c, uint16_t sensorAddress, uint32_t mux_channel, const char *driver_name) - : drvBase(i2c, sensorAddress, mux_channel, driver_name) {} + : drvBaseAccelLsm6(i2c, sensorAddress, mux_channel, driver_name) {} drvIsm330dlc::~drvIsm330dlc() { if (_imu) { @@ -48,79 +46,10 @@ bool drvIsm330dlc::begin() { _imu->setGyroDataRate(LSM6DS_RATE_104_HZ); _imu->configInt1(false, false, false, false, true); _imu->configInt2(false, false, false); + _imu->enablePedometer(true); _imu->enableWakeup(true); WS_DEBUG_PRINTLN("[drvIsm330dlc] Sensor initialised successfully"); return true; } -bool drvIsm330dlc::readAllEvents(sensors_event_t *accel, sensors_event_t *gyro, - sensors_event_t *temp) { - if (!_imu) { - return false; - } - return _imu->getEvent(accel, gyro, temp); -} - -bool drvIsm330dlc::computeAccelMagnitude(float &magnitude) { - sensors_event_t accel, gyro, temp; - if (!readAllEvents(&accel, &gyro, &temp)) { - return false; - } - magnitude = sqrtf(accel.acceleration.x * accel.acceleration.x + - accel.acceleration.y * accel.acceleration.y + - accel.acceleration.z * accel.acceleration.z); - return true; -} - -bool drvIsm330dlc::getEventRaw(sensors_event_t *rawEvent) { - if (!_imu) { - return false; - } - WS_DEBUG_PRINTLN("[drvIsm330dlc] Getting raw magnitude event..."); - float magnitude = 0.0f; - if (!computeAccelMagnitude(magnitude)) { - return false; - } - rawEvent->data[0] = magnitude; - WS_DEBUG_PRINT("[drvIsm330dlc] Raw magnitude: "); - WS_DEBUG_PRINTLN(magnitude); - return true; -} - -bool drvIsm330dlc::getEventBoolean(sensors_event_t *booleanEvent) { - if (!_imu) { - return false; - } - WS_DEBUG_PRINTLN("[drvIsm330dlc] Checking for tap/threshold event..."); - bool tap = _imu->shake(); - booleanEvent->data[0] = tap ? 1.0f : 0.0f; - if (tap) { - WS_DEBUG_PRINTLN("[drvIsm330dlc] Threshold event detected"); - } - return true; -} - -bool drvIsm330dlc::getEventAccelerometer(sensors_event_t *accelEvent) { - if (!_imu) { - return false; - } - WS_DEBUG_PRINTLN("[drvIsm330dlc] Getting accelerometer event..."); - sensors_event_t gyro, temp; - return readAllEvents(accelEvent, &gyro, &temp); -} - -bool drvIsm330dlc::getEventGyroscope(sensors_event_t *gyroEvent) { - if (!_imu) { - return false; - } - WS_DEBUG_PRINTLN("[drvIsm330dlc] Getting gyroscope event..."); - sensors_event_t accel, temp; - return readAllEvents(&accel, gyroEvent, &temp); -} - -void drvIsm330dlc::ConfigureDefaultSensorTypes() { - _default_sensor_types_count = 1; - _default_sensor_types[0] = - wippersnapper_sensor_SensorType_SENSOR_TYPE_ACCELEROMETER; -} diff --git a/src/components/i2c/drivers/drvIsm330dlc.h b/src/components/i2c/drivers/drvIsm330dlc.h index 8a80743ec..ba09649d7 100644 --- a/src/components/i2c/drivers/drvIsm330dlc.h +++ b/src/components/i2c/drivers/drvIsm330dlc.h @@ -13,30 +13,23 @@ #define DRV_ISM330DLC_H #include "Wippersnapper_V2.h" -#include "drvBase.h" +#include "drvBaseAccelLsm6.h" #include #define ISM330_TAP_THRESHOLD_MSS 15.0f -class drvIsm330dlc : public drvBase { +class drvIsm330dlc : public drvBaseAccelLsm6 { public: drvIsm330dlc(TwoWire *i2c, uint16_t sensorAddress, uint32_t mux_channel, const char *driver_name); ~drvIsm330dlc(); bool begin() override; - bool getEventBoolean(sensors_event_t *booleanEvent) override; - bool getEventRaw(sensors_event_t *rawEvent) override; - bool getEventAccelerometer(sensors_event_t *accelEvent) override; - bool getEventGyroscope(sensors_event_t *gyroEvent) override; - void ConfigureDefaultSensorTypes() override; +protected: + Adafruit_LSM6DS *getLSM6Sensor() const override { return _imu; } private: - bool readAllEvents(sensors_event_t *accel, sensors_event_t *gyro, - sensors_event_t *temp); - bool computeAccelMagnitude(float &magnitude); - Adafruit_LSM6DSL *_imu = nullptr; ///< Pointer to the ISM330DLC sensor }; diff --git a/src/components/i2c/drivers/drvLsm6ds3.cpp b/src/components/i2c/drivers/drvLsm6ds3.cpp index 2de080449..9b8bd2399 100644 --- a/src/components/i2c/drivers/drvLsm6ds3.cpp +++ b/src/components/i2c/drivers/drvLsm6ds3.cpp @@ -6,8 +6,6 @@ #include "drvLsm6ds3.h" -#include - /******************************************************************************/ /*! @brief Destructor */ /******************************************************************************/ @@ -48,70 +46,10 @@ bool drvLsm6ds3::begin() { _imu->setGyroDataRate(LSM6DS_RATE_104_HZ); _imu->configInt1(false, false, false, false, true); _imu->configInt2(false, false, false); + _imu->enablePedometer(true); _imu->enableWakeup(true); WS_DEBUG_PRINTLN("[drvLsm6ds3] Sensor initialised successfully"); return true; } -bool drvLsm6ds3::readAllEvents(sensors_event_t *accel, sensors_event_t *gyro, - sensors_event_t *temp) { - if (!_imu) { - return false; - } - return _imu->getEvent(accel, gyro, temp); -} - -bool drvLsm6ds3::computeAccelMagnitude(float &magnitude) { - sensors_event_t accel, gyro, temp; - if (!readAllEvents(&accel, &gyro, &temp)) { - return false; - } - magnitude = sqrtf(accel.acceleration.x * accel.acceleration.x + - accel.acceleration.y * accel.acceleration.y + - accel.acceleration.z * accel.acceleration.z); - return true; -} - -bool drvLsm6ds3::getEventRaw(sensors_event_t *rawEvent) { - if (!_imu) { - return false; - } - float magnitude = 0.0f; - if (!computeAccelMagnitude(magnitude)) { - return false; - } - rawEvent->data[0] = magnitude; - return true; -} - -bool drvLsm6ds3::getEventBoolean(sensors_event_t *booleanEvent) { - if (!_imu) { - return false; - } - bool shake = _imu->shake(); - booleanEvent->data[0] = shake ? 1.0f : 0.0f; - return true; -} - -bool drvLsm6ds3::getEventAccelerometer(sensors_event_t *accelEvent) { - if (!_imu) { - return false; - } - sensors_event_t gyro, temp; - return readAllEvents(accelEvent, &gyro, &temp); -} - -bool drvLsm6ds3::getEventGyroscope(sensors_event_t *gyroEvent) { - if (!_imu) { - return false; - } - sensors_event_t accel, temp; - return readAllEvents(&accel, gyroEvent, &temp); -} - -void drvLsm6ds3::ConfigureDefaultSensorTypes() { - _default_sensor_types_count = 1; - _default_sensor_types[0] = - wippersnapper_sensor_SensorType_SENSOR_TYPE_ACCELEROMETER; -} diff --git a/src/components/i2c/drivers/drvLsm6ds3.h b/src/components/i2c/drivers/drvLsm6ds3.h index 0a5cdcdaf..4f7a5d1ef 100644 --- a/src/components/i2c/drivers/drvLsm6ds3.h +++ b/src/components/i2c/drivers/drvLsm6ds3.h @@ -7,36 +7,24 @@ #define DRV_LSM6DS3_H #include "Wippersnapper_V2.h" -#include "drvBase.h" +#include "drvBaseAccelLsm6.h" #include -class drvLsm6ds3 : public drvBase { +class drvLsm6ds3 : public drvBaseAccelLsm6 { public: - drvLsm6ds3(TwoWire *i2c, uint16_t sensorAddress, uint32_t mux_channel, - const char *driver_name) - : drvBase(i2c, sensorAddress, mux_channel, driver_name) {} + drvLsm6ds3(TwoWire *i2c, uint16_t sensorAddress, uint32_t mux_channel, + const char *driver_name) + : drvBaseAccelLsm6(i2c, sensorAddress, mux_channel, driver_name) {} ~drvLsm6ds3(); bool begin() override; - bool getEventRaw(sensors_event_t *rawEvent) override; - - bool getEventBoolean(sensors_event_t *booleanEvent) override; - - bool getEventAccelerometer(sensors_event_t *accelEvent) override; - - bool getEventGyroscope(sensors_event_t *gyroEvent) override; - protected: - void ConfigureDefaultSensorTypes() override; + Adafruit_LSM6DS *getLSM6Sensor() const override { return _imu; } private: - bool readAllEvents(sensors_event_t *accel, sensors_event_t *gyro, - sensors_event_t *temp); - bool computeAccelMagnitude(float &magnitude); - Adafruit_LSM6DS3 *_imu = nullptr; }; diff --git a/src/components/i2c/drivers/drvLsm6dso32.cpp b/src/components/i2c/drivers/drvLsm6dso32.cpp index 2e325be07..8f77d4a2b 100644 --- a/src/components/i2c/drivers/drvLsm6dso32.cpp +++ b/src/components/i2c/drivers/drvLsm6dso32.cpp @@ -6,8 +6,6 @@ #include "drvLsm6dso32.h" -#include - /******************************************************************************/ drvLsm6dso32::~drvLsm6dso32() { if (_imu) { @@ -46,70 +44,10 @@ bool drvLsm6dso32::begin() { _imu->setGyroDataRate(LSM6DS_RATE_104_HZ); _imu->configInt1(false, false, false, true, true); _imu->configInt2(false, false, false); + _imu->enablePedometer(true); _imu->enableWakeup(true); WS_DEBUG_PRINTLN("[drvLsm6dso32] Sensor initialised successfully"); return true; } -bool drvLsm6dso32::readAllEvents(sensors_event_t *accel, sensors_event_t *gyro, - sensors_event_t *temp) { - if (!_imu) { - return false; - } - return _imu->getEvent(accel, gyro, temp); -} - -bool drvLsm6dso32::computeAccelMagnitude(float &magnitude) { - sensors_event_t accel, gyro, temp; - if (!readAllEvents(&accel, &gyro, &temp)) { - return false; - } - magnitude = sqrtf(accel.acceleration.x * accel.acceleration.x + - accel.acceleration.y * accel.acceleration.y + - accel.acceleration.z * accel.acceleration.z); - return true; -} - -bool drvLsm6dso32::getEventRaw(sensors_event_t *rawEvent) { - if (!_imu) { - return false; - } - float magnitude = 0.0f; - if (!computeAccelMagnitude(magnitude)) { - return false; - } - rawEvent->data[0] = magnitude; - return true; -} - -bool drvLsm6dso32::getEventBoolean(sensors_event_t *booleanEvent) { - if (!_imu) { - return false; - } - bool shake = _imu->shake(); - booleanEvent->data[0] = shake ? 1.0f : 0.0f; - return true; -} - -bool drvLsm6dso32::getEventAccelerometer(sensors_event_t *accelEvent) { - if (!_imu) { - return false; - } - sensors_event_t gyro, temp; - return readAllEvents(accelEvent, &gyro, &temp); -} - -bool drvLsm6dso32::getEventGyroscope(sensors_event_t *gyroEvent) { - if (!_imu) { - return false; - } - sensors_event_t accel, temp; - return readAllEvents(&accel, gyroEvent, &temp); -} - -void drvLsm6dso32::ConfigureDefaultSensorTypes() { - _default_sensor_types_count = 1; - _default_sensor_types[0] = - wippersnapper_sensor_SensorType_SENSOR_TYPE_ACCELEROMETER; -} diff --git a/src/components/i2c/drivers/drvLsm6dso32.h b/src/components/i2c/drivers/drvLsm6dso32.h index 2bf499383..be5f257e3 100644 --- a/src/components/i2c/drivers/drvLsm6dso32.h +++ b/src/components/i2c/drivers/drvLsm6dso32.h @@ -7,36 +7,24 @@ #define DRV_LSM6DSO32_H #include "Wippersnapper_V2.h" -#include "drvBase.h" +#include "drvBaseAccelLsm6.h" #include -class drvLsm6dso32 : public drvBase { +class drvLsm6dso32 : public drvBaseAccelLsm6 { public: drvLsm6dso32(TwoWire *i2c, uint16_t sensorAddress, uint32_t mux_channel, const char *driver_name) - : drvBase(i2c, sensorAddress, mux_channel, driver_name) {} + : drvBaseAccelLsm6(i2c, sensorAddress, mux_channel, driver_name) {} ~drvLsm6dso32(); bool begin() override; - bool getEventRaw(sensors_event_t *rawEvent) override; - - bool getEventBoolean(sensors_event_t *booleanEvent) override; - - bool getEventAccelerometer(sensors_event_t *accelEvent) override; - - bool getEventGyroscope(sensors_event_t *gyroEvent) override; - protected: - void ConfigureDefaultSensorTypes() override; + Adafruit_LSM6DS *getLSM6Sensor() const override { return _imu; } private: - bool readAllEvents(sensors_event_t *accel, sensors_event_t *gyro, - sensors_event_t *temp); - bool computeAccelMagnitude(float &magnitude); - Adafruit_LSM6DSO32 *_imu = nullptr; }; From 95d7a243d40fa88b8207070705bd037401d13131 Mon Sep 17 00:00:00 2001 From: tyeth Date: Mon, 17 Nov 2025 16:35:33 +0000 Subject: [PATCH 17/21] [fix]: I2C not setting which_value type per event --- src/components/i2c/model.cpp | 21 +++++++++++++-------- src/provisioning/sdcard/ws_sdcard.cpp | 9 +++++---- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/components/i2c/model.cpp b/src/components/i2c/model.cpp index 0ecb3b9f2..e8cbdd303 100644 --- a/src/components/i2c/model.cpp +++ b/src/components/i2c/model.cpp @@ -221,14 +221,7 @@ GetValueFromSensorsEventOrientation(wippersnapper_sensor_SensorType sensor_type, */ bool GetValueFromSensorsEventBoolean( wippersnapper_sensor_SensorType sensor_type, sensors_event_t *event) { - bool value = false; - WS_DEBUG_PRINTLN("[i2c] Getting boolean event value..."); - WS_DEBUG_PRINT("[i2c] Event data[0]: "); - WS_DEBUG_PRINTLN(event->data[0]); - value = event->data[0] > 0.0f; - WS_DEBUG_PRINT("[i2c] Boolean value (x>0): "); - WS_DEBUG_PRINTLN(value); - return value; + return event->data[0] > 0.0f; } /*! @@ -477,6 +470,9 @@ bool I2cModel::AddI2cDeviceSensorEvent( _msg_i2c_device_event .i2c_device_events[_msg_i2c_device_event.i2c_device_events_count] .value.vector_value.z = value_vect.z; + _msg_i2c_device_event + .i2c_device_events[_msg_i2c_device_event.i2c_device_events_count] + .which_value = wippersnapper_sensor_SensorEvent_vector_value_tag; } else if (sensor_type == wippersnapper_sensor_SensorType_SENSOR_TYPE_ORIENTATION || sensor_type == @@ -492,6 +488,9 @@ bool I2cModel::AddI2cDeviceSensorEvent( _msg_i2c_device_event .i2c_device_events[_msg_i2c_device_event.i2c_device_events_count] .value.orientation_value.pitch = value_vect.pitch; + _msg_i2c_device_event + .i2c_device_events[_msg_i2c_device_event.i2c_device_events_count] + .which_value = wippersnapper_sensor_SensorEvent_orientation_value_tag; // TODO: Add color RGB(A) vector support } else if (sensor_type == wippersnapper_sensor_SensorType_SENSOR_TYPE_BOOLEAN) { @@ -499,11 +498,17 @@ bool I2cModel::AddI2cDeviceSensorEvent( _msg_i2c_device_event .i2c_device_events[_msg_i2c_device_event.i2c_device_events_count] .value.bool_value = value; + _msg_i2c_device_event + .i2c_device_events[_msg_i2c_device_event.i2c_device_events_count] + .which_value = wippersnapper_sensor_SensorEvent_bool_value_tag; } else { float value = GetValueFromSensorsEvent(sensor_type, &event); _msg_i2c_device_event .i2c_device_events[_msg_i2c_device_event.i2c_device_events_count] .value.float_value = value; + _msg_i2c_device_event + .i2c_device_events[_msg_i2c_device_event.i2c_device_events_count] + .which_value = wippersnapper_sensor_SensorEvent_float_value_tag; } _msg_i2c_device_event.i2c_device_events_count++; diff --git a/src/provisioning/sdcard/ws_sdcard.cpp b/src/provisioning/sdcard/ws_sdcard.cpp index e82caf08b..fdbcacc83 100644 --- a/src/provisioning/sdcard/ws_sdcard.cpp +++ b/src/provisioning/sdcard/ws_sdcard.cpp @@ -1382,23 +1382,24 @@ bool ws_sdcard::LogEventDs18x(wippersnapper_ds18x20_Ds18x20Event *event_msg) { */ bool ws_sdcard::LogEventI2c( wippersnapper_i2c_I2cDeviceEvent *msg_device_event) { - JsonDocument doc; + JsonDocument baseDoc; // Pull the DeviceDescriptor out wippersnapper_i2c_I2cDeviceDescriptor descriptor = msg_device_event->i2c_device_description; char hex_addr[5]; snprintf(hex_addr, sizeof(hex_addr), "0x%02X", descriptor.i2c_device_address); - doc["i2c_address"] = hex_addr; + baseDoc["i2c_address"] = hex_addr; // Using I2C MUX? if (descriptor.i2c_mux_address != 0x00) { snprintf(hex_addr, sizeof(hex_addr), "0x%02X", descriptor.i2c_mux_address); - doc["i2c_mux_addr"] = hex_addr; - doc["i2c_mux_ch"] = descriptor.i2c_mux_channel; + baseDoc["i2c_mux_addr"] = hex_addr; + baseDoc["i2c_mux_ch"] = descriptor.i2c_mux_channel; } // Log each event for (pb_size_t i = 0; i < msg_device_event->i2c_device_events_count; i++) { + JsonDocument doc = baseDoc; // no stale vectors/values doc["timestamp"] = GetTimestamp(); // if mag/vector/colour etc log all value elements if (msg_device_event->i2c_device_events[i].type == From 878b3c6c2ece34529cad83a6296bd55267851d73 Mon Sep 17 00:00:00 2001 From: tyeth Date: Tue, 18 Nov 2025 00:32:01 +0000 Subject: [PATCH 18/21] add(board): Feather RP2350 HSTX --- platformio.ini | 11 ++++++++++- src/Wippersnapper_Boards.h | 7 +++++++ src/adapters/offline/ws_offline_pico.h | 1 + src/provisioning/tinyusb/Wippersnapper_FS.cpp | 1 + src/ws_adapters.h | 1 + 5 files changed, 20 insertions(+), 1 deletion(-) diff --git a/platformio.ini b/platformio.ini index 5460ac6e6..fc86fd4c7 100644 --- a/platformio.ini +++ b/platformio.ini @@ -146,7 +146,7 @@ board = rpipicow framework = arduino board_build.core = earlephilhower board_build.filesystem_size = 0.5m -build_flags = -DUSE_TINYUSB +build_flags = -DUSE_TINYUSB -DBUILD_OFFLINE_ONLY ; Once https://github.com/platformio/platformio-core > 6.1.11 these can be removed lib_ignore = WiFiNINA, WiFi101, Adafruit Zero DMA Library, WiFiNINA_-_Adafruit_Fork lib_compat_mode = soft ; can be strict once pio detects SleepyDog on RP2040 @@ -521,6 +521,15 @@ board_build.filesystem_size = 0.5m build_flags = -DUSE_TINYUSB ; Once https://github.com/platformio/platformio-core > 6.1.11 these can be removed +[env:adafruit_feather_rp2350_hstx] +extends = common:rp2040 +platform = https://github.com/maxgerhardt/platform-raspberrypi.git#develop +board = adafruit_feather_rp2350_hstx +platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git +board_build.filesystem_size = 0.5m +build_flags = -DUSE_TINYUSB +; Once https://github.com/platformio/platformio-core > 6.1.11 these can be removed + [env:adafruit_metro_rp2350] extends = common:rp2040 platform = https://github.com/brentru/platform-raspberrypi.git#develop diff --git a/src/Wippersnapper_Boards.h b/src/Wippersnapper_Boards.h index 21e5a675e..fef336086 100644 --- a/src/Wippersnapper_Boards.h +++ b/src/Wippersnapper_Boards.h @@ -245,6 +245,13 @@ #define STATUS_NEOPIXEL_NUM 1 #define SD_USE_SPI_1 #define SD_CS_PIN 23 +#elif defined(ARDUINO_ADAFRUIT_FEATHER_RP2350_HSTX) +#define BOARD_ID "feather-rp2350-hstx" +#define USE_TINYUSB +#define USE_STATUS_NEOPIXEL +#define STATUS_NEOPIXEL_PIN PIN_NEOPIXEL +#define STATUS_NEOPIXEL_NUM 1 +#define SD_CS_PIN 1 #elif defined(ARDUINO_ADAFRUIT_METRO_RP2350) #define BOARD_ID "metro-rp2350" #define USE_TINYUSB diff --git a/src/adapters/offline/ws_offline_pico.h b/src/adapters/offline/ws_offline_pico.h index 247ea5f68..7fad9bd01 100644 --- a/src/adapters/offline/ws_offline_pico.h +++ b/src/adapters/offline/ws_offline_pico.h @@ -19,6 +19,7 @@ #if defined(ARDUINO_RASPBERRY_PI_PICO) || \ defined(ARDUINO_RASPBERRY_PI_PICO_2) || \ defined(ARDUINO_ADAFRUIT_FEATHER_RP2040_ADALOGGER) || \ + defined(ARDUINO_ADAFRUIT_FEATHER_RP2350_HSTX) || \ defined(ARDUINO_ADAFRUIT_METRO_RP2350) #define PICO_CONNECT_TIMEOUT_MS 20000 /*!< Connection timeout (in ms) */ diff --git a/src/provisioning/tinyusb/Wippersnapper_FS.cpp b/src/provisioning/tinyusb/Wippersnapper_FS.cpp index d62e3f302..f5f2d3101 100644 --- a/src/provisioning/tinyusb/Wippersnapper_FS.cpp +++ b/src/provisioning/tinyusb/Wippersnapper_FS.cpp @@ -30,6 +30,7 @@ defined(ARDUINO_RASPBERRY_PI_PICO) || \ defined(ARDUINO_RASPBERRY_PI_PICO_2) || \ defined(ARDUINO_ADAFRUIT_FEATHER_RP2040_ADALOGGER) || \ + defined(ARDUINO_ADAFRUIT_FEATHER_RP2350_HSTX) || \ defined(ARDUINO_ADAFRUIT_METRO_RP2350) || \ defined(ARDUINO_RASPBERRY_PI_PICO_2W) #include "Wippersnapper_FS.h" diff --git a/src/ws_adapters.h b/src/ws_adapters.h index 7e240232b..221cb4672 100644 --- a/src/ws_adapters.h +++ b/src/ws_adapters.h @@ -50,6 +50,7 @@ typedef ws_wifi_ninafw ws_adapter_wifi; #elif defined(ARDUINO_RASPBERRY_PI_PICO_2) || \ defined(ARDUINO_RASPBERRY_PI_PICO) || \ defined(ARDUINO_ADAFRUIT_FEATHER_RP2040_ADALOGGER) || \ + defined(ARDUINO_ADAFRUIT_FEATHER_RP2350_HSTX) || \ defined(ARDUINO_ADAFRUIT_METRO_RP2350) #define WS_OFFLINE_ADAPTER #include "adapters/offline/ws_offline_pico.h" From 440ebe7817539b1f7029064466e5eee2ebda84b9 Mon Sep 17 00:00:00 2001 From: tyeth Date: Tue, 18 Nov 2025 00:35:43 +0000 Subject: [PATCH 19/21] fix(drivers): add auto-config addresses, unique sensorID generator, swap ism330dlc to dhcx --- src/components/i2c/controller.cpp | 16 ++++-- src/components/i2c/controller.h | 1 - .../i2c/drivers/drvBaseAccelLsm6.cpp | 33 ++++++----- src/components/i2c/drivers/drvBaseAccelLsm6.h | 15 ++++- src/components/i2c/drivers/drvIsm330dlc.cpp | 55 ------------------- src/components/i2c/drivers/drvIsm330dlc.h | 36 ------------ src/components/i2c/drivers/drvLsm6dso32.cpp | 13 +++-- 7 files changed, 50 insertions(+), 119 deletions(-) delete mode 100644 src/components/i2c/drivers/drvIsm330dlc.cpp delete mode 100644 src/components/i2c/drivers/drvIsm330dlc.h diff --git a/src/components/i2c/controller.cpp b/src/components/i2c/controller.cpp index 5e1001c4e..b32fd64ad 100644 --- a/src/components/i2c/controller.cpp +++ b/src/components/i2c/controller.cpp @@ -206,7 +206,7 @@ static const std::map I2cFactorySensor = { {"ism330dlc", [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, const char *driver_name) -> drvBase * { - return new drvIsm330dlc(i2c, addr, mux_channel, driver_name); + return new drvIsm330dhcx(i2c, addr, mux_channel, driver_name); }}, {"ism330dhcx", [](TwoWire *i2c, uint16_t addr, uint32_t mux_channel, @@ -457,13 +457,13 @@ static const std::unordered_map> {0x0B, {"lc709203f"}}, {0x12, {"pmsa003i"}}, {0x13, {"vncl4020"}}, - {0x18, {"ds2484", "mcp9808", "mprls"}}, - {0x19, {"mcp9808"}}, + {0x18, {"ds2484", "mcp9808", "mprls", "lis3dh"}}, + {0x19, {"mcp9808", "lis3dh", "lsm303dlh", "lsm303agr"}}, {0x1A, {"mcp9808"}}, {0x1B, {"mcp9808"}}, - {0x1C, {"mcp9808"}}, + {0x1C, {"mcp9808", "lis3mdl"}}, {0x1D, {"mcp9808"}}, - {0x1E, {"mcp9808"}}, + {0x1E, {"mcp9808", "lis2mdl", "lis3mdl"}}, {0x1F, {"mcp9808"}}, {0x23, {"bh1750"}}, {0x28, {"pct2075"}}, @@ -508,7 +508,11 @@ static const std::unordered_map> {0x62, {"scd40"}}, {0x68, {"mcp3421"}}, {0x69, {"sen55"}}, - {0x6B, {"sen66"}}, + {0x6A, {"lsm6dso32", "ism330dhcx", "lsm6ds3"}}, + {0x6B, {"sen66", "lsm6ds3", "lsm6dso32", "ism330dhcx"}}, + {0x6C, {"lsm303dlh"}}, + {0x6D, {"lsm303agr"}}, + {0x6E, {"lsm9ds1"}}, {0x70, {"pct2075", "shtc3"}}, {0x71, {"pct2075"}}, {0x72, {"pct2075"}}, diff --git a/src/components/i2c/controller.h b/src/components/i2c/controller.h index 304b8bfa9..57d582420 100644 --- a/src/components/i2c/controller.h +++ b/src/components/i2c/controller.h @@ -40,7 +40,6 @@ #include "drivers/drvIna238.h" #include "drivers/drvIna260.h" #include "drivers/drvIsm330dhcx.h" -#include "drivers/drvIsm330dlc.h" #include "drivers/drvLc709203f.h" #include "drivers/drvLis2mdl.h" #include "drivers/drvLis3dh.h" diff --git a/src/components/i2c/drivers/drvBaseAccelLsm6.cpp b/src/components/i2c/drivers/drvBaseAccelLsm6.cpp index 893d17015..9d87f0ab6 100644 --- a/src/components/i2c/drivers/drvBaseAccelLsm6.cpp +++ b/src/components/i2c/drivers/drvBaseAccelLsm6.cpp @@ -39,27 +39,27 @@ bool drvBaseAccelLsm6::readAllEvents() { _last_shake = true; } - uint16_t step_change = imu->readPedometer(); - if (step_change > 0) { - WS_DEBUG_PRINT("["); - WS_DEBUG_PRINT(_name); - WS_DEBUG_PRINT("] Steps detected: "); - WS_DEBUG_PRINTLN(step_change); - _last_steps += step_change; - imu->resetPedometer(); - } +// uint16_t step_change = imu->readPedometer(); +// if (step_change > 0) { +// WS_DEBUG_PRINT("["); +// WS_DEBUG_PRINT(_name); +// WS_DEBUG_PRINT("] Steps detected !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n!: "); +// WS_DEBUG_PRINTLN(step_change); +// _last_steps += step_change; +// imu->resetPedometer(); +// } bool success = imu->getEvent(&_lastAccelEvent, &_lastGyroEvent, &_lastTempEvent); _has_last_events = success; return success; } -bool drvBaseAccelLsm6::computeAccelMagnitude(float &magnitude) { +bool drvBaseAccelLsm6::computeAccelMagnitude(float *magnitude) { if (!readAllEvents()) { return false; } - magnitude = sqrtf(_lastAccelEvent.acceleration.x * + *magnitude = sqrtf(_lastAccelEvent.acceleration.x * _lastAccelEvent.acceleration.x + _lastAccelEvent.acceleration.y * _lastAccelEvent.acceleration.y + @@ -72,12 +72,19 @@ bool drvBaseAccelLsm6::getEventRaw(sensors_event_t *rawEvent) { if (!readAllEvents()) { return false; } + return computeAccelMagnitude(&(rawEvent->data[0])); +} + +bool drvBaseAccelLsm6::getEventAmbientTemp(sensors_event_t *temperatureEvent) { + if (!readAllEvents()) { + return false; + } - rawEvent->data[0] = static_cast(_last_steps); - _last_steps = 0; + *temperatureEvent = _lastTempEvent; return true; } +// NO Shake/tap/wakeup for now, using pedometer steps instead on INT1 bool drvBaseAccelLsm6::getEventBoolean(sensors_event_t *booleanEvent) { if (!readAllEvents()) { return false; diff --git a/src/components/i2c/drivers/drvBaseAccelLsm6.h b/src/components/i2c/drivers/drvBaseAccelLsm6.h index ac77ebae0..2ed730f53 100644 --- a/src/components/i2c/drivers/drvBaseAccelLsm6.h +++ b/src/components/i2c/drivers/drvBaseAccelLsm6.h @@ -21,6 +21,7 @@ class drvBaseAccelLsm6 : public drvBase { bool getEventRaw(sensors_event_t *rawEvent) override; bool getEventAccelerometer(sensors_event_t *accelEvent) override; bool getEventGyroscope(sensors_event_t *gyroEvent) override; + bool getEventAmbientTemp(sensors_event_t *temperatureEvent) override; void ConfigureDefaultSensorTypes() override; @@ -28,16 +29,26 @@ class drvBaseAccelLsm6 : public drvBase { protected: virtual Adafruit_LSM6DS *getLSM6Sensor() const = 0; + + uint32_t getLsmSensorID() { + // allow 4 ids per sensor (acc/mag/gyro/temp) + uint32_t sensor_id = 10 * GetAddress(); + if (GetMuxAddress() != 0x0) { + sensor_id += 10000 + GetMuxAddress(); + sensor_id += 1000 + (1000 * GetMuxChannel()); + } + return sensor_id; + } bool readAllEvents(); - bool computeAccelMagnitude(float &magnitude); + bool computeAccelMagnitude(float *magnitude); bool _has_last_events = false; ///< Flag to track if last events are stored bool _last_shake = false; ///< Last state of shake / tap detection sensors_event_t _lastAccelEvent; ///< Last accelerometer event sensors_event_t _lastGyroEvent; ///< Last gyroscope event sensors_event_t _lastTempEvent; ///< Last temperature event (raw) - uint16_t _last_steps = 0; ///< Last step count +// uint16_t _last_steps = 0; ///< Last step count uint32_t _lastPoll = 0; ///< Last poll time uint32_t _internalPollPeriod = 200; ///< Internal Polling interval in ms }; diff --git a/src/components/i2c/drivers/drvIsm330dlc.cpp b/src/components/i2c/drivers/drvIsm330dlc.cpp deleted file mode 100644 index 9bc63c752..000000000 --- a/src/components/i2c/drivers/drvIsm330dlc.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/*! - * @file drvIsm330dlc.cpp - * - * Driver wrapper for the Adafruit ISM330DLC (LSM6DSL core) 6-DoF IMU. - */ - -#include "drvIsm330dlc.h" - -drvIsm330dlc::drvIsm330dlc(TwoWire *i2c, uint16_t sensorAddress, - uint32_t mux_channel, const char *driver_name) - : drvBaseAccelLsm6(i2c, sensorAddress, mux_channel, driver_name) {} - -drvIsm330dlc::~drvIsm330dlc() { - if (_imu) { - delete _imu; - _imu = nullptr; - } -} - -bool drvIsm330dlc::begin() { - if (_imu) { - delete _imu; - _imu = nullptr; - } - - _imu = new Adafruit_LSM6DSL(); - if (!_imu) { - return false; - } - - uint8_t addr = _address == 0 ? LSM6DS_I2CADDR_DEFAULT : (uint8_t)_address; - WS_DEBUG_PRINT("[drvIsm330dlc] Initialising @ 0x"); - WS_DEBUG_PRINTHEX(addr); - WS_DEBUG_PRINTLN("..."); - - if (!_imu->begin_I2C(addr, _i2c)) { - WS_DEBUG_PRINTLN("[drvIsm330dlc] Failed to initialise sensor"); - delete _imu; - _imu = nullptr; - return false; - } - - _imu->setAccelRange(LSM6DS_ACCEL_RANGE_4_G); - _imu->setAccelDataRate(LSM6DS_RATE_104_HZ); - _imu->setGyroRange(LSM6DS_GYRO_RANGE_500_DPS); - _imu->setGyroDataRate(LSM6DS_RATE_104_HZ); - _imu->configInt1(false, false, false, false, true); - _imu->configInt2(false, false, false); - _imu->enablePedometer(true); - _imu->enableWakeup(true); - - WS_DEBUG_PRINTLN("[drvIsm330dlc] Sensor initialised successfully"); - return true; -} - diff --git a/src/components/i2c/drivers/drvIsm330dlc.h b/src/components/i2c/drivers/drvIsm330dlc.h deleted file mode 100644 index ba09649d7..000000000 --- a/src/components/i2c/drivers/drvIsm330dlc.h +++ /dev/null @@ -1,36 +0,0 @@ -/*! - * @file drvIsm330dlc.h - * - * Driver wrapper for the Adafruit ISM330DLC (LSM6DSL core) 6-DoF IMU. - * - * Adafruit invests time and resources providing this open source code, - * please support Adafruit and open-source hardware by purchasing - * products from Adafruit! - * - * MIT license, all text here must be included in any redistribution. - */ -#ifndef DRV_ISM330DLC_H -#define DRV_ISM330DLC_H - -#include "Wippersnapper_V2.h" -#include "drvBaseAccelLsm6.h" -#include - -#define ISM330_TAP_THRESHOLD_MSS 15.0f - -class drvIsm330dlc : public drvBaseAccelLsm6 { -public: - drvIsm330dlc(TwoWire *i2c, uint16_t sensorAddress, uint32_t mux_channel, - const char *driver_name); - ~drvIsm330dlc(); - - bool begin() override; - -protected: - Adafruit_LSM6DS *getLSM6Sensor() const override { return _imu; } - -private: - Adafruit_LSM6DSL *_imu = nullptr; ///< Pointer to the ISM330DLC sensor -}; - -#endif // DRV_ISM330DLC_H diff --git a/src/components/i2c/drivers/drvLsm6dso32.cpp b/src/components/i2c/drivers/drvLsm6dso32.cpp index 8f77d4a2b..a6bc7a110 100644 --- a/src/components/i2c/drivers/drvLsm6dso32.cpp +++ b/src/components/i2c/drivers/drvLsm6dso32.cpp @@ -39,13 +39,14 @@ bool drvLsm6dso32::begin() { } _imu->setAccelRange(LSM6DSO32_ACCEL_RANGE_8_G); - _imu->setAccelDataRate(LSM6DS_RATE_104_HZ); - _imu->setGyroRange(LSM6DS_GYRO_RANGE_500_DPS); - _imu->setGyroDataRate(LSM6DS_RATE_104_HZ); - _imu->configInt1(false, false, false, true, true); - _imu->configInt2(false, false, false); - _imu->enablePedometer(true); + _imu->setGyroRange(LSM6DS_GYRO_RANGE_250_DPS); + _imu->setAccelDataRate(LSM6DS_RATE_416_HZ); + _imu->setGyroDataRate(LSM6DS_RATE_416_HZ); + // _imu->highPassFilter(true, LSM6DS_HPF_ODR_DIV_100); + _imu->configInt1(false, false, false, false, true); + // _imu->configInt2(false, false, false); _imu->enableWakeup(true); + // _imu->enablePedometer(true); WS_DEBUG_PRINTLN("[drvLsm6dso32] Sensor initialised successfully"); return true; From 2b217fce845bcc5db329968cbc5fc347b1aa5c11 Mon Sep 17 00:00:00 2001 From: tyeth Date: Tue, 18 Nov 2025 00:41:38 +0000 Subject: [PATCH 20/21] fix(drivers): stop extra read for LSM9DS1, and LS6DS pedometer enable --- src/components/i2c/drivers/drvIsm330dhcx.cpp | 4 ++-- src/components/i2c/drivers/drvLsm6ds3.cpp | 2 +- src/components/i2c/drivers/drvLsm9ds1.cpp | 4 +--- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/components/i2c/drivers/drvIsm330dhcx.cpp b/src/components/i2c/drivers/drvIsm330dhcx.cpp index a2137a404..eacfc10e2 100644 --- a/src/components/i2c/drivers/drvIsm330dhcx.cpp +++ b/src/components/i2c/drivers/drvIsm330dhcx.cpp @@ -44,10 +44,10 @@ bool drvIsm330dhcx::begin() { _imu->setAccelDataRate(LSM6DS_RATE_104_HZ); _imu->setGyroRange(LSM6DS_GYRO_RANGE_500_DPS); _imu->setGyroDataRate(LSM6DS_RATE_104_HZ); - _imu->highPassFilter(true, LSM6DS_HPF_ODR_DIV_100); + // _imu->highPassFilter(true, LSM6DS_HPF_ODR_DIV_100); _imu->configInt1(false, false, false, false, true); _imu->configInt2(false, false, false); - _imu->enablePedometer(true); + // _imu->enablePedometer(true); _imu->enableWakeup(true); WS_DEBUG_PRINTLN("[drvIsm330dhcx] Sensor initialised successfully"); diff --git a/src/components/i2c/drivers/drvLsm6ds3.cpp b/src/components/i2c/drivers/drvLsm6ds3.cpp index 9b8bd2399..647ca337e 100644 --- a/src/components/i2c/drivers/drvLsm6ds3.cpp +++ b/src/components/i2c/drivers/drvLsm6ds3.cpp @@ -46,7 +46,7 @@ bool drvLsm6ds3::begin() { _imu->setGyroDataRate(LSM6DS_RATE_104_HZ); _imu->configInt1(false, false, false, false, true); _imu->configInt2(false, false, false); - _imu->enablePedometer(true); + // _imu->enablePedometer(true); _imu->enableWakeup(true); WS_DEBUG_PRINTLN("[drvLsm6ds3] Sensor initialised successfully"); diff --git a/src/components/i2c/drivers/drvLsm9ds1.cpp b/src/components/i2c/drivers/drvLsm9ds1.cpp index 7a07829f0..51f658169 100644 --- a/src/components/i2c/drivers/drvLsm9ds1.cpp +++ b/src/components/i2c/drivers/drvLsm9ds1.cpp @@ -50,9 +50,7 @@ bool drvLsm9ds1::readAllEvents(sensors_event_t *accel, sensors_event_t *mag, if (!_lsm) { return false; } - _lsm->read(); - _lsm->getEvent(accel, mag, gyro, temp); - return true; + return _lsm->getEvent(accel, mag, gyro, temp); } /******************************************************************************/ From edcf7d9479f52d0bac1c6dafe9926cafe487d449 Mon Sep 17 00:00:00 2001 From: tyeth Date: Thu, 20 Nov 2025 12:19:25 +0000 Subject: [PATCH 21/21] WIP: Acc+debug tweaks --- platformio.ini | 9 ++-- src/components/i2c/controller.cpp | 4 +- src/components/i2c/drivers/drvLsm303agr.cpp | 10 ++-- src/components/i2c/drivers/drvLsm303dlh.cpp | 23 +++++---- src/components/i2c/drivers/drvLsm9ds1.cpp | 53 ++++++++++----------- src/components/i2c/drivers/drvLsm9ds1.h | 26 +++++----- src/helpers/ws_helper_macros.h | 6 +-- 7 files changed, 64 insertions(+), 67 deletions(-) diff --git a/platformio.ini b/platformio.ini index fc86fd4c7..cb32d494e 100644 --- a/platformio.ini +++ b/platformio.ini @@ -608,14 +608,14 @@ build_flags = -DDEBUG_RP2040_CORE -DDEBUG_RP2040_WIFI -DLWIP_DEBUG - -DDEBUG_RP2040_PORT=Serial1 - -DDEBUG_RP2040_UART_1 - -DDEBUG_RP2040_UART=1 + ; -DDEBUG_RP2040_PORT=Serial1 + ; -DDEBUG_RP2040_UART_1 + ; -DDEBUG_RP2040_UART=1 -Og ; Enable debug stack protection -fstack-protector ; Enable Exceptions - -DPIO_FRAMEWORK_ARDUINO_ENABLE_EXCEPTIONS + ; -DPIO_FRAMEWORK_ARDUINO_ENABLE_EXCEPTIONS ; Enable RTTI -DPIO_FRAMEWORK_ARDUINO_ENABLE_RTTI ; ; Enable default USB Stack of Pico SDK USB Stack with none of below usb options @@ -624,3 +624,4 @@ build_flags = ; ; No USB stack ; build_flags = -DPIO_FRAMEWORK_ARDUINO_NO_USB ; -DPIO_FRAMEWORK_ARDUINO_ENABLE_IPV6 + -DBUILD_OFFLINE_ONLY diff --git a/src/components/i2c/controller.cpp b/src/components/i2c/controller.cpp index b32fd64ad..7a5b67bfd 100644 --- a/src/components/i2c/controller.cpp +++ b/src/components/i2c/controller.cpp @@ -458,12 +458,12 @@ static const std::unordered_map> {0x12, {"pmsa003i"}}, {0x13, {"vncl4020"}}, {0x18, {"ds2484", "mcp9808", "mprls", "lis3dh"}}, - {0x19, {"mcp9808", "lis3dh", "lsm303dlh", "lsm303agr"}}, + {0x19, {"mcp9808", "lsm303agr", "lsm303dlh", "lis3dh"}}, // LIS3DH last - seems to match LSM303AGR {0x1A, {"mcp9808"}}, {0x1B, {"mcp9808"}}, {0x1C, {"mcp9808", "lis3mdl"}}, {0x1D, {"mcp9808"}}, - {0x1E, {"mcp9808", "lis2mdl", "lis3mdl"}}, + {0x1E, {"mcp9808", "lis3mdl", "lis2mdl"}}, // "lsm303dlh", "lsm303agr", but rely on first addr {0x1F, {"mcp9808"}}, {0x23, {"bh1750"}}, {0x28, {"pct2075"}}, diff --git a/src/components/i2c/drivers/drvLsm303agr.cpp b/src/components/i2c/drivers/drvLsm303agr.cpp index 6f0ac862c..414252f6f 100644 --- a/src/components/i2c/drivers/drvLsm303agr.cpp +++ b/src/components/i2c/drivers/drvLsm303agr.cpp @@ -8,7 +8,7 @@ #include -#define LSM303AGR_ACCEL_DEFAULT_ADDR LSM303_ADDRESS_ACCEL +#define LSM303AGR_ACCEL_DEFAULT_ADDR 0x19 ///< LSM303AGR default address #define LSM303AGR_MAG_DEFAULT_ADDR 0x1E ///< LIS2MDL default address /******************************************************************************/ @@ -52,13 +52,11 @@ bool drvLsm303agr::begin() { // TODO: if _address isn't default (or alt), shift mag by same offset. // to support adress translators. Alternatively compound components. - const uint8_t accel_addr = - _address == 0 ? LSM303AGR_ACCEL_DEFAULT_ADDR : (uint8_t)_address; - + WS_DEBUG_PRINT("[drvLsm303agr] Initialising accel @ 0x"); - WS_DEBUG_PRINTHEX(accel_addr); + WS_DEBUG_PRINTHEX(LSM303AGR_ACCEL_DEFAULT_ADDR); WS_DEBUG_PRINTLN("..."); - if (!_accel->begin(accel_addr, _i2c)) { + if (!_accel->begin(LSM303AGR_ACCEL_DEFAULT_ADDR, _i2c)) { WS_DEBUG_PRINTLN("[drvLsm303agr] Failed to initialise accelerometer"); teardown(); return false; diff --git a/src/components/i2c/drivers/drvLsm303dlh.cpp b/src/components/i2c/drivers/drvLsm303dlh.cpp index 8d1b26ee1..2e208d0df 100644 --- a/src/components/i2c/drivers/drvLsm303dlh.cpp +++ b/src/components/i2c/drivers/drvLsm303dlh.cpp @@ -41,24 +41,29 @@ void drvLsm303dlh::teardown() { */ /******************************************************************************/ bool drvLsm303dlh::begin() { + WS_DEBUG_PRINTLN("[drvLsm303dlh] Initializing LSM303DLH driver..."); + WS_PRINTER.flush(); + + WS_DEBUG_PRINTLN("[drvLsm303dlh] Tearing down any existing sensor instances..."); + WS_PRINTER.flush(); teardown(); + WS_DEBUG_PRINTLN("[drvLsm303dlh] Creating new sensor instances..."); + WS_PRINTER.flush(); _accel = new Adafruit_LSM303_Accel_Unified(); + WS_DEBUG_PRINTLN("[drvLsm303dlh] Created accelerometer instance, DLH mag next"); + WS_PRINTER.flush(); _mag = new Adafruit_LSM303DLH_Mag_Unified(); + WS_DEBUG_PRINTLN("[drvLsm303dlh] Created magnetometer instance"); + WS_PRINTER.flush(); if (!_accel || !_mag) { teardown(); return false; } - - // TODO: if _address isn't default (or alt), shift mag by same offset. - // to support adress translators. Alternatively compound components. - const uint8_t accel_addr = - _address == 0 ? LSM303DLH_ACCEL_DEFAULT_ADDR : (uint8_t)_address; - - WS_DEBUG_PRINT("[drvLsm303dlh] Initialising accel @ 0x"); - WS_DEBUG_PRINTHEX(accel_addr); + WS_DEBUG_PRINT("[drvLsm303dlh] Initialising accelerometer @ 0x"); + WS_DEBUG_PRINTHEX(LSM303DLH_ACCEL_DEFAULT_ADDR); WS_DEBUG_PRINTLN("..."); - if (!_accel->begin(accel_addr, _i2c)) { + if (!_accel->begin(LSM303DLH_ACCEL_DEFAULT_ADDR, _i2c)) { WS_DEBUG_PRINTLN("[drvLsm303dlh] Failed to initialise accelerometer"); teardown(); return false; diff --git a/src/components/i2c/drivers/drvLsm9ds1.cpp b/src/components/i2c/drivers/drvLsm9ds1.cpp index 51f658169..7dbde1430 100644 --- a/src/components/i2c/drivers/drvLsm9ds1.cpp +++ b/src/components/i2c/drivers/drvLsm9ds1.cpp @@ -37,8 +37,8 @@ bool drvLsm9ds1::begin() { } // Mirror the configuration used by the reference example - _lsm->setupAccel(_lsm->LSM9DS1_ACCELRANGE_2G, - _lsm->LSM9DS1_ACCELDATARATE_10HZ); + _lsm->setupAccel(_lsm->LSM9DS1_ACCELRANGE_4G, + _lsm->LSM9DS1_ACCELDATARATE_119HZ); _lsm->setupMag(_lsm->LSM9DS1_MAGGAIN_4GAUSS); _lsm->setupGyro(_lsm->LSM9DS1_GYROSCALE_245DPS); @@ -50,6 +50,7 @@ bool drvLsm9ds1::readAllEvents(sensors_event_t *accel, sensors_event_t *mag, if (!_lsm) { return false; } + return _lsm->getEvent(accel, mag, gyro, temp); } @@ -81,47 +82,35 @@ bool drvLsm9ds1::getEventRaw(sensors_event_t *rawEvent) { /******************************************************************************/ /*! - @brief Gets the LSM9DS1's boolean sensor event. - @param booleanEvent - Pointer to the sensor event. + @brief Gets the LSM9DS1's accelerometer sensor event (x,y,z in m/s^2). + @param accelEvent + Pointer to the accelerometer sensor event. @returns True if the sensor event was obtained successfully, False otherwise. */ /******************************************************************************/ -bool drvLsm9ds1::getEventBoolean(sensors_event_t *booleanEvent) { - WS_DEBUG_PRINTLN("[drvLsm9ds1] Checking for tap event..."); - sensors_event_t accel, mag, gyro, temp; - if (!readAllEvents(&accel, &mag, &gyro, &temp)) { +bool drvLsm9ds1::getEventAccelerometer(sensors_event_t *accelEvent) { + WS_DEBUG_PRINTLN("[drvLsm9ds1] Getting accelerometer event..."); + sensors_event_t mag, gyro, temp; + if (!readAllEvents(accelEvent, &mag, &gyro, &temp)) { return false; } - - float mag_accel = sqrtf(accel.acceleration.x * accel.acceleration.x + - accel.acceleration.y * accel.acceleration.y + - accel.acceleration.z * accel.acceleration.z); - - bool tap_detected = (mag_accel > LSM9DS1_TAP_THRESHOLD_MSS); - booleanEvent->data[0] = tap_detected ? 1.0f : 0.0f; - - if (tap_detected) { - WS_DEBUG_PRINTLN("[drvLsm9ds1] Tap event detected!"); - } - return true; } /******************************************************************************/ /*! - @brief Gets the LSM9DS1's accelerometer sensor event (x,y,z in m/s^2). - @param accelEvent - Pointer to the accelerometer sensor event. + @brief Gets the LSM9DS1's temperature sensor event (not necessarily *C). + @param tempEvent + Pointer to the temperature sensor event. @returns True if the sensor event was obtained successfully, False otherwise. */ /******************************************************************************/ -bool drvLsm9ds1::getEventAccelerometer(sensors_event_t *accelEvent) { - WS_DEBUG_PRINTLN("[drvLsm9ds1] Getting accelerometer event..."); - sensors_event_t mag, gyro, temp; - if (!readAllEvents(accelEvent, &mag, &gyro, &temp)) { +bool drvLsm9ds1::getEventAmbientTemp(sensors_event_t *tempEvent) { + WS_DEBUG_PRINTLN("[drvLsm9ds1] Getting temperature event..."); + sensors_event_t accel, mag, gyro; + if (!readAllEvents(&accel, &mag, &gyro, tempEvent)) { return false; } return true; @@ -164,7 +153,13 @@ bool drvLsm9ds1::getEventMagneticField(sensors_event_t *magEvent) { } void drvLsm9ds1::ConfigureDefaultSensorTypes() { - _default_sensor_types_count = 1; + _default_sensor_types_count = 4; _default_sensor_types[0] = wippersnapper_sensor_SensorType_SENSOR_TYPE_ACCELEROMETER; + _default_sensor_types[1] = + wippersnapper_sensor_SensorType_SENSOR_TYPE_MAGNETIC_FIELD; + _default_sensor_types[2] = + wippersnapper_sensor_SensorType_SENSOR_TYPE_GYROSCOPE; + _default_sensor_types[3] = + wippersnapper_sensor_SensorType_SENSOR_TYPE_AMBIENT_TEMPERATURE; } diff --git a/src/components/i2c/drivers/drvLsm9ds1.h b/src/components/i2c/drivers/drvLsm9ds1.h index a91d6ce06..eb73bafe2 100644 --- a/src/components/i2c/drivers/drvLsm9ds1.h +++ b/src/components/i2c/drivers/drvLsm9ds1.h @@ -21,9 +21,6 @@ class Adafruit_LSM9DS1; // forward -// Approximate acceleration magnitude (m/s^2) that triggers a tap event -#define LSM9DS1_TAP_THRESHOLD_MSS 15.0f - /**************************************************************************/ /*! @brief Class that provides a driver interface for a LSM9DS1 IMU. @@ -63,17 +60,6 @@ class drvLsm9ds1 : public drvBase { /*******************************************************************************/ bool begin() override; - /******************************************************************************/ - /*! - @brief Gets the LSM9DS1's boolean sensor event. - @param booleanEvent - Pointer to the sensor event. - @returns True if the sensor event was obtained successfully, False - otherwise. - */ - /******************************************************************************/ - bool getEventBoolean(sensors_event_t *booleanEvent) override; - /*******************************************************************************/ /*! @brief Gets the LSM9DS1's raw sensor event (magnitude stored in @@ -96,6 +82,17 @@ class drvLsm9ds1 : public drvBase { /*******************************************************************************/ bool getEventAccelerometer(sensors_event_t *accelEvent) override; + /*******************************************************************************/ + /*! + @brief Gets the LSM9DS1's temperature sensor event (not necessarily *C). + @param tempEvent + Pointer to the temperature sensor event. + @returns True if the sensor event was obtained successfully, False + otherwise. + */ + /*******************************************************************************/ + bool getEventAmbientTemp(sensors_event_t *tempEvent) override; + /*******************************************************************************/ /*! @brief Gets the LSM9DS1's gyroscope sensor event (x,y,z in rad/s). @@ -125,6 +122,7 @@ class drvLsm9ds1 : public drvBase { bool readAllEvents(sensors_event_t *accel, sensors_event_t *mag, sensors_event_t *gyro, sensors_event_t *temp); + }; #endif // DRV_LSM9DS1_H diff --git a/src/helpers/ws_helper_macros.h b/src/helpers/ws_helper_macros.h index cfd6d9722..5d1eb79c8 100644 --- a/src/helpers/ws_helper_macros.h +++ b/src/helpers/ws_helper_macros.h @@ -7,11 +7,11 @@ // Define actual debug output functions when necessary. #ifdef WS_DEBUG #define WS_DEBUG_PRINT(...) \ - { WS_PRINTER.print(__VA_ARGS__); } ///< Prints debug output. + { WS_PRINTER.print(__VA_ARGS__);WS_PRINTER.flush();delay(5); } ///< Prints debug output. #define WS_DEBUG_PRINTLN(...) \ - { WS_PRINTER.println(__VA_ARGS__); } ///< Prints line from debug output. + { WS_PRINTER.println(__VA_ARGS__);WS_PRINTER.flush();delay(5); } ///< Prints line from debug output. #define WS_DEBUG_PRINTHEX(...) \ - { WS_PRINTER.print(__VA_ARGS__, HEX); } ///< Prints debug output. + { WS_PRINTER.print(__VA_ARGS__, HEX);WS_PRINTER.flush();delay(5); } ///< Prints debug output. #else #define WS_DEBUG_PRINT(...) \ {} ///< Prints debug output