From 1f1fb421e9823bd213e25e04e4f07c1055417512 Mon Sep 17 00:00:00 2001 From: Niklas Jensen Date: Thu, 27 Nov 2025 16:34:24 +0100 Subject: [PATCH] Added ICM20948 support --- app/src/routes/peripherals/i2c/i2c.svelte | 5 +++ esp32/features.ini | 2 + esp32/include/features.h | 10 ++++- esp32/include/peripherals/imu.h | 53 +++++++++++++++++++++++ esp32/include/peripherals/peripherals.h | 4 +- esp32/src/features.cpp | 5 ++- platformio.ini | 1 + 7 files changed, 75 insertions(+), 5 deletions(-) diff --git a/app/src/routes/peripherals/i2c/i2c.svelte b/app/src/routes/peripherals/i2c/i2c.svelte index df7c2b9..dd462f2 100644 --- a/app/src/routes/peripherals/i2c/i2c.svelte +++ b/app/src/routes/peripherals/i2c/i2c.svelte @@ -16,6 +16,11 @@ part_number: 'MPU6050', name: 'Six-Axis (Gyro + Accelerometer) MEMS MotionTracking™ Devices' }, + { + address: 105, + part_number: 'ICM20948', + name: 'Nine-Axis (Gyro + Accelerometer + Magnetometer) MEMS MotionTracking™ Device' + }, { address: 115, part_number: 'PAJ7620U2', name: 'Gesture sensor' }, { address: 119, part_number: 'BMP085', name: 'Temp/Barometric' } ] diff --git a/esp32/features.ini b/esp32/features.ini index 5ecd496..2f8189a 100644 --- a/esp32/features.ini +++ b/esp32/features.ini @@ -13,6 +13,8 @@ build_flags = -D USE_HMC5883=0 -D USE_BMP180=0 -D USE_MPU6050=0 + -D USE_ICM20948=1 + -D USE_ICM20948_SPIMODE=0 -D USE_WS2812=1 -D USE_BNO055=0 -D USE_USS=0 diff --git a/esp32/include/features.h b/esp32/include/features.h index 7972a33..6c29920 100644 --- a/esp32/include/features.h +++ b/esp32/include/features.h @@ -12,7 +12,7 @@ #define USE_CAMERA 0 #endif -// ESP32 IMU on by default +// ESP32 IMU off by default #ifndef USE_MPU6050 #define USE_MPU6050 0 #endif @@ -22,6 +22,14 @@ #define USE_BNO055 1 #endif +// ESP32 IMU off by default +#ifndef USE_ICM20948 +#define USE_ICM20948 0 +#endif +#ifndef USE_ICM20948_SPIMODE // I2C on by default +#define USE_ICM20948_SPIMODE 0 +#endif + // ESP32 magnetometer on by default #ifndef USE_HMC5883 #define USE_HMC5883 0 diff --git a/esp32/include/peripherals/imu.h b/esp32/include/peripherals/imu.h index 7ea4c1d..af7d93d 100644 --- a/esp32/include/peripherals/imu.h +++ b/esp32/include/peripherals/imu.h @@ -6,6 +6,10 @@ #include #include +#if FT_ENABLED(USE_ICM20948) +#include "ICM_20948.h" +#endif + #if FT_ENABLED(USE_MPU6050) #include #endif @@ -67,6 +71,26 @@ class IMU : public SensorBase { return false; } _imu.setExtCrystalUse(true); +#endif +#if FT_ENABLED(USE_ICM20948) + #if USE_ICM20948_SPIMODE > 0 + _imu.begin(CS_PIN, SPI_PORT); + #else + _imu.begin(Wire, 1); + #endif + if (_imu.status != ICM_20948_Stat_Ok){ return false; } + + _imu.setSampleMode((ICM_20948_Internal_Acc | ICM_20948_Internal_Gyr), ICM_20948_Sample_Mode_Continuous); + if (_imu.status != ICM_20948_Stat_Ok){ return false; } + + ICM_20948_fss_t myFSS; + myFSS.a = gpm2; + myFSS.g = dps250; + _imu.setFullScale((ICM_20948_Internal_Acc | ICM_20948_Internal_Gyr), myFSS); + if (_imu.status != ICM_20948_Stat_Ok){ return false; } + // TODO: Setup low pass filter config + _imu.startupMagnetometer(); + if (_imu.status != ICM_20948_Stat_Ok){ return false; } #endif return true; } @@ -84,12 +108,31 @@ class IMU : public SensorBase { } return false; #endif +#if FT_ENABLED(USE_ICM20948) + if (_imu.dataReady()) + { + _imu.getAGMT(); + _msg.rpy[0] = _imu.magX(); + _msg.rpy[1] = _imu.magY(); + _msg.rpy[2] = _imu.magZ(); + } +#endif #if FT_ENABLED(USE_BNO055) sensors_event_t event; _imu.getEvent(&event); _msg.rpy[0] = event.orientation.x; _msg.rpy[1] = event.orientation.y; _msg.rpy[2] = event.orientation.z; +#endif +#if FT_ENABLED(USE_ICM20948) + #if FT_ENABLED(USE_ICM20948_SPIMODE) > 0 + #define SPI_PORT SPI // TODO in periphearals_seetings.h + #define CS_PIN 2 + ICM_20948_SPI _imu; + #else + //#define WIRE_PORT Wire + ICM_20948_I2C _imu; + #endif #endif return true; } @@ -113,4 +156,14 @@ class IMU : public SensorBase { #if FT_ENABLED(USE_BNO055) Adafruit_BNO055 _imu {55, 0x29}; #endif +#if FT_ENABLED(USE_ICM20948) + #if FT_ENABLED(USE_ICM20948_SPIMODE) > 0 + #define SPI_PORT SPI // TODO in periphearals_seetings.h + #define CS_PIN 2 + ICM_20948_SPI _imu; + #else + //#define WIRE_PORT Wire + ICM_20948_I2C _imu; + #endif +#endif }; \ No newline at end of file diff --git a/esp32/include/peripherals/peripherals.h b/esp32/include/peripherals/peripherals.h index f90e5c1..18248e5 100644 --- a/esp32/include/peripherals/peripherals.h +++ b/esp32/include/peripherals/peripherals.h @@ -87,10 +87,10 @@ class Peripherals : public StatefulService { JsonDocument doc; char message[MAX_ESP_IMU_SIZE]; -#if FT_ENABLED(USE_MPU6050 || USE_BNO055) +#if FT_ENABLED(USE_MPU6050 || USE_BNO055 || USE_ICM20948) IMU _imu; #endif -#if FT_ENABLED(USE_HMC5883) +#if FT_ENABLED(USE_HMC5883 || USE_ICM20948) Magnetometer _mag; #endif #if FT_ENABLED(USE_BMP180) diff --git a/esp32/src/features.cpp b/esp32/src/features.cpp index 4b76031..2e23663 100644 --- a/esp32/src/features.cpp +++ b/esp32/src/features.cpp @@ -12,6 +12,7 @@ void printFeatureConfiguration() { ESP_LOGI("Features", "USE_MOTION: %s", USE_MOTION ? "enabled" : "disabled"); // Sensors + ESP_LOGI("Features", "USE_ICM20948: %s", USE_ICM20948 ? "enabled" : "disabled"); ESP_LOGI("Features", "USE_BNO055: %s", USE_BNO055 ? "enabled" : "disabled"); ESP_LOGI("Features", "USE_MPU6050: %s", USE_MPU6050 ? "enabled" : "disabled"); ESP_LOGI("Features", "USE_HMC5883: %s", USE_HMC5883 ? "enabled" : "disabled"); @@ -31,8 +32,8 @@ void printFeatureConfiguration() { void features(JsonObject &root) { root["camera"] = USE_CAMERA ? true : false; - root["imu"] = (USE_MPU6050 || USE_BNO055) ? true : false; - root["mag"] = (USE_HMC5883 || USE_BNO055) ? true : false; + root["imu"] = (USE_MPU6050 || USE_BNO055 || USE_ICM20948) ? true : false; + root["mag"] = (USE_HMC5883 || USE_BNO055 || USE_ICM20948) ? true : false; root["bmp"] = USE_BMP180 ? true : false; root["sonar"] = USE_USS ? true : false; root["servo"] = USE_PCA9685 ? true : false; diff --git a/platformio.ini b/platformio.ini index c1ec31d..fbb8c7b 100644 --- a/platformio.ini +++ b/platformio.ini @@ -116,6 +116,7 @@ lib_deps = adafruit/Adafruit Unified Sensor@^1.1.14 adafruit/Adafruit BNO055@^1.6.4 FastLED@3.5.0 + sparkfun/SparkFun 9DoF IMU Breakout - ICM 20948 - Arduino Library@^1.3.2 extra_scripts = pre:esp32/scripts/pre_build.py pre:esp32/scripts/build_app.py