Skip to content

Commit 180fe9c

Browse files
committed
Fix slow mag
I let claude figure this one out and it works tho I probably would've done the same
1 parent d0844a0 commit 180fe9c

2 files changed

Lines changed: 27 additions & 18 deletions

File tree

src/sensors/F_ICM20948.cpp

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -125,28 +125,36 @@ void ICM20948::update()
125125
float gy = (float)rawGyro[1] * gRes - calibration.gyroBias[1];
126126
float gz = (float)rawGyro[2] * gRes - calibration.gyroBias[2];
127127

128-
// rawData[14] = ST1: bit 0 is DRDY from AK09916
129-
if (magInitialized && (rawData[14] & 0x01)) {
130-
mag.timestamp = now;
128+
// Detect new AK09916 data by comparing raw bytes rather than ST1.DRDY.
129+
// The ICM20948 I2C master runs independently at ~1.1 kHz and clears ST1.DRDY
130+
// via ST2 on its first read; subsequent reads within the same accel cycle see
131+
// DRDY=0, so the latched EXT_SLV_SENS_DATA rarely shows DRDY=1 even when the
132+
// mag is producing data normally. The measurement bytes are stable between
133+
// AK09916 conversions, so a value change reliably marks a new sample.
134+
if (magInitialized) {
131135
int16_t mc[3];
132136
mc[0] = (int16_t)((rawData[16] << 8) | rawData[15]);
133137
mc[1] = (int16_t)((rawData[18] << 8) | rawData[17]);
134138
mc[2] = (int16_t)((rawData[20] << 8) | rawData[19]);
135-
136-
// Remap AK09916 axis to align with ICM20948
137-
float mx = ((float)mc[1] * mRes - calibration.magBias[1]) * calibration.magScale[1];
138-
float my = ((float)mc[0] * mRes - calibration.magBias[0]) * calibration.magScale[0];
139-
float mz = -((float)mc[2] * mRes - calibration.magBias[2]) * calibration.magScale[2];
140-
141-
switch (geometryIndex) {
142-
case 0: mag.magX = mx; mag.magY = my; mag.magZ = mz; break;
143-
case 1: mag.magX = -my; mag.magY = mx; mag.magZ = mz; break;
144-
case 2: mag.magX = -mx; mag.magY = -my; mag.magZ = mz; break;
145-
case 3: mag.magX = my; mag.magY = -mx; mag.magZ = mz; break;
146-
case 4: mag.magX = -mz; mag.magY = -my; mag.magZ = -mx; break;
147-
case 5: mag.magX = -mz; mag.magY = mx; mag.magZ = -my; break;
148-
case 6: mag.magX = -mz; mag.magY = my; mag.magZ = mx; break;
149-
case 7: mag.magX = -mz; mag.magY = -mx; mag.magZ = my; break;
139+
if (mc[0] != prevRawMag[0] || mc[1] != prevRawMag[1] || mc[2] != prevRawMag[2]) {
140+
prevRawMag[0] = mc[0]; prevRawMag[1] = mc[1]; prevRawMag[2] = mc[2];
141+
mag.timestamp = now;
142+
143+
// Remap AK09916 axis to align with ICM20948
144+
float mx = ((float)mc[1] * mRes - calibration.magBias[1]) * calibration.magScale[1];
145+
float my = ((float)mc[0] * mRes - calibration.magBias[0]) * calibration.magScale[0];
146+
float mz = -((float)mc[2] * mRes - calibration.magBias[2]) * calibration.magScale[2];
147+
148+
switch (geometryIndex) {
149+
case 0: mag.magX = mx; mag.magY = my; mag.magZ = mz; break;
150+
case 1: mag.magX = -my; mag.magY = mx; mag.magZ = mz; break;
151+
case 2: mag.magX = -mx; mag.magY = -my; mag.magZ = mz; break;
152+
case 3: mag.magX = my; mag.magY = -mx; mag.magZ = mz; break;
153+
case 4: mag.magX = -mz; mag.magY = -my; mag.magZ = -mx; break;
154+
case 5: mag.magX = -mz; mag.magY = mx; mag.magZ = -my; break;
155+
case 6: mag.magX = -mz; mag.magY = my; mag.magZ = mx; break;
156+
case 7: mag.magX = -mz; mag.magY = -mx; mag.magZ = my; break;
157+
}
150158
}
151159
}
152160

src/sensors/F_ICM20948.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ class ICM20948 : public IMUBase {
165165
MagData mag = { 0 };
166166
bool magInitialized = false;
167167
int16_t prevRawAccel[3] = {0, 0, 0};
168+
int16_t prevRawMag[3] = {0, 0, 0};
168169

169170
calData calibration;
170171
uint8_t IMUAddress;

0 commit comments

Comments
 (0)