Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
3895d95
Added ICM20984
atinm Jun 29, 2025
e896acf
Added Sparkfun ICM20948 breakout board (SPI only, I2C TBD)
atinm Jun 29, 2025
527d8b1
Merge branch 'main-upstream' into atinm/icm20948-imu
atinm Jul 2, 2025
8bd66ff
Copied files to top level from Sparkfun's subdirectory and updated RE…
atinm Jul 2, 2025
1ded436
Added back the config for imu_int_mode for ICM20948
atinm Jul 2, 2025
c258480
Use uint8_t for interrupt_mode
atinm Jul 2, 2025
42736b0
Handle when we aren't using MBED or RP2040
atinm Jul 2, 2025
176314e
Moved interrupt_mode from config to gizmo
atinm Jul 2, 2025
9fa51c6
Use bool to pass interrupt mode to _imu_ll_interrupt_setup
atinm Jul 2, 2025
af6d8bf
Added some comments about the quaternion math and fixed yaw radian ca…
atinm Jul 3, 2025
b04db65
Make the IMU interrupt check a loop rather than a die for IMUs that t…
atinm Jul 3, 2025
860abb5
Added mf_IMU for AHR and fixed sign
atinm Jul 4, 2025
86d07e9
Removed extra comment
atinm Jul 4, 2025
21d4588
Moved ImuGizmoICM20948.cpp to src/imu
atinm Jul 4, 2025
726d540
Add src/imu/ImuGizmoICM20948.cpp since move
atinm Jul 4, 2025
c6ed36a
Allow imu_has_mag config option
atinm Jul 4, 2025
0088470
Fix config->has_mag - it is a bool
atinm Jul 4, 2025
7b99f7e
Move AHR setup after IMU setup, and separate interrupt setup
atinm Jul 4, 2025
af09253
Die if using mf_IMU on AHR with an IMU that does not have sensor fusion
atinm Jul 4, 2025
fa4f032
Moved imu_use_mag to bottom and pass it along to the IMUs
atinm Jul 4, 2025
73232a7
Set sample rate to 225 Hz which is the best ICM20948 can do
atinm Jul 5, 2025
bec9795
Do bias correction on the quaternions as well
atinm Jul 5, 2025
f77ef9a
Fix more Quaternion calculations and calibration
atinm Jul 5, 2025
1a3495d
Fix quaternion align and remove hack for flipYaw()
atinm Jul 6, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion src/ahr/ahr.cpp
Comment thread
atinm marked this conversation as resolved.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's put this in a new PR - I think this will need some additional considerations...

Some (random) thoughts:

Rather add a new imu_gizmo mf_ICM20948_6DOF than a new parameter. (I try to keep number of parameters as low as possible)

If adding a parameter:

New config params should be added at the end of the array - this allows users to upgrade without eeprom corruption.

I would use value 0 or 1 (not <=0 or 1)

Default value 1 makes more sense to me - use mag if we have it.

Rather name the param and related vars imu_use_mag, and reserve the "has" properties for driver capabilities.

Not consistent with current 9dof drivers...

@atinm atinm Jul 4, 2025

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, not consistent with existing drivers - made it use_mag and moved to bottom. Only really used by ICM20948 for now, could be used by MPU9250 if it supports 6DOF. But left others alone to have minimal code changes.

@atinm atinm Jul 4, 2025

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the meantime, my quadcopter crashed and burned badly - need to debug it, it stopped listening to IBUS and didn't automatically disarm itself when it lost contact!

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

my quadcopter crashed and burned badly

ouch!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I seemed to have lost some code when I split Icm20948 and ibus code so putting it back - related to calibration and quaternions

Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ SOFTWARE.
#define MF_MOD "AHR"

#include <Arduino.h> //Serial
#include <math.h>
#include "ahr.h"
#include "AhrGizmoMahony.h"
#include "AhrGizmoMadgwick.h"
Expand All @@ -43,9 +44,20 @@ int Ahr::setup() {
cfg.printModule(MF_MOD);

B_gyr = lowpass_to_beta(config.gyrLpFreq, config.pimu->getSampleRate());
if (isnan(B_gyr)) {
Comment thread
atinm marked this conversation as resolved.
Outdated
// imu might not be set up yet
B_gyr = 1.0;
}
B_acc = lowpass_to_beta(config.accLpFreq, config.pimu->getSampleRate());
if (isnan(B_acc)) {
// imu might not be set up yet
B_acc = 1.0;
}
B_mag = lowpass_to_beta(config.magLpFreq, config.pimu->getSampleRate());

if (isnan(B_mag)) {
// imu might not be set up yet
B_mag = 1.0;
}
//create gizmo
delete gizmo;
switch(config.gizmo) {
Expand Down
1 change: 1 addition & 0 deletions src/cfg/cfg.h
Comment thread
atinm marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ SOFTWARE.
MF_PARAM( imu_rate, 1000, float, 'f') /*IMU sample rate in Hz (default 1000) NOTE: not all IMU drivers support a different rate*/ \
MF_PARAM( imu_acc_lp, 70, float, 'f') /*Accelerometer Low Pass Filter cutoff frequency in Hz */ \
MF_PARAM( imu_gyr_lp, 60, float, 'f') /*Gyro Low Pass Filter cutoff frequency in Hz */ \
MF_PARAM( imu_has_mag, -1, int32_t, 'i') /*whether the IMU has/should use its magnetometer, <= 0: no, 1: yes*/ \
\
/*LED*/ \
MF_PARAM( led_on, 0, int32_t, 'e', mf_LOW_IS_ON,mf_HIGH_IS_ON) \
Expand Down
4 changes: 2 additions & 2 deletions src/imu/ImuGizmoICM20948.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ uint16_t ImuGizmoICM20948::_convertGyroScale(uint16_t range) {
return ret;
}

ImuGizmoICM20948::ImuGizmoICM20948(SPIClass *spi, const uint8_t csPin, const uint8_t intPin)
ImuGizmoICM20948::ImuGizmoICM20948(SPIClass *spi, const uint8_t csPin, const uint8_t intPin, const bool has_mag)
: _spi(spi), _csPin(csPin), _interrupt_pin(intPin) {
_wrapped_imu = new ICM_20948_SPI();
has_mag = true;
this->has_mag = has_mag;
uses_i2c = false;
has_sensor_fusion = true;
interrupt_has_rising_edge = false;
Expand Down
2 changes: 1 addition & 1 deletion src/imu/ImuGizmoICM20948.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class ImuGizmoICM20948 : public ImuGizmo {
}

public:
ImuGizmoICM20948(SPIClass *spi, const uint8_t csPin, const uint8_t intPin);
ImuGizmoICM20948(SPIClass *spi, const uint8_t csPin, const uint8_t intPin, const bool has_mag);
~ImuGizmoICM20948();

int begin(int gyro_scale_dps, int acc_scale_g, int rate_hz);
Expand Down
1 change: 1 addition & 0 deletions src/imu/imu.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ struct ImuConfig {
MF_I2C *i2c_bus = nullptr; //i2c bus (only used if spi_bus == nullptr)
uint8_t i2c_adr = 0; //i2c address. 0=default address
bool uses_i2c = false; //use I2C bus?
bool has_mag = false; // has magnetometer
};

//imu sample data (raw, uncorrected and unfiltered)
Expand Down
13 changes: 7 additions & 6 deletions src/imu/imu_cpp.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,42 +118,43 @@ int Imu::setup() {
auto mpu_iface = new MPU_InterfaceSPI(config.spi_bus, config.spi_cs);
gizmo = new MPUXXXX(MPUXXXX::MPU9250, mpu_iface);
gizmo->uses_i2c = false;
gizmo->has_mag = true;
gizmo->has_mag = true || config.has_mag > 0;
break;
}
case Cfg::imu_gizmo_enum::mf_MPU6500 : {
auto mpu_iface = new MPU_InterfaceSPI(config.spi_bus, config.spi_cs);
gizmo = new MPUXXXX(MPUXXXX::MPU6500, mpu_iface);
gizmo->uses_i2c = false;
gizmo->has_mag = false;
gizmo->has_mag = false || config.has_mag > 0;
break;
}
case Cfg::imu_gizmo_enum::mf_MPU6000 : {
auto mpu_iface = new MPU_InterfaceSPI(config.spi_bus, config.spi_cs);
gizmo = new MPUXXXX(MPUXXXX::MPU6000, mpu_iface);
gizmo->uses_i2c = false;
gizmo->has_mag = false;
gizmo->has_mag = false || config.has_mag > 0;
break;
}
case Cfg::imu_gizmo_enum::mf_BMI270 : {
gizmo = new ImuGizmoBMI270(config.spi_bus, config.spi_cs);
gizmo->uses_i2c = false;
gizmo->has_mag = false;
gizmo->has_mag = false || config.has_mag > 0;
break;
}
case Cfg::imu_gizmo_enum::mf_ICM45686 : {
auto icm_iface = new Invensensev3_InterfaceSPI(config.spi_bus, config.spi_cs);
gizmo = new ImuGizmoICM45686( (uint8_t)config.pin_int, icm_iface );
gizmo->uses_i2c = false;
gizmo->has_mag = false;
gizmo->has_mag = false || config.has_mag > 0;
break;
}
case Cfg::imu_gizmo_enum::mf_ICM42688 : {
gizmo = ImuGizmoICM426XX::create(&config, (ImuState*)this);
gizmo->has_mag = gizmo->has_mag || config.has_mag > 0;
break;
}
case Cfg::imu_gizmo_enum::mf_ICM20948 : {
gizmo = new ImuGizmoICM20948(config.spi_bus, config.spi_cs, config.pin_int);
gizmo = new ImuGizmoICM20948(config.spi_bus, config.spi_cs, config.pin_int, config.has_mag);
break;
}
default: {
Expand Down
2 changes: 1 addition & 1 deletion src/madflight.h
Comment thread
atinm marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ void madflight_setup() {
imu.config.i2c_bus = hal_get_i2c_bus(cfg.imu_i2c_bus); //I2C bus (only used if spi_bus==nullptr)
imu.config.i2c_adr = cfg.imu_i2c_adr; //i2c address. 0=default address
imu.config.uses_i2c = ((Cfg::imu_bus_type_enum)cfg.imu_bus_type == Cfg::imu_bus_type_enum::mf_I2C);

imu.config.has_mag = cfg.imu_has_mag > 0;
// Some sensors need a couple of tries...
int tries = 10;
while(true) {
Expand Down