Fix IMU magnetometer diagnostics

This commit is contained in:
Josh
2026-04-24 00:31:47 +02:00
parent 53ba59e4cd
commit 92a2ccc689
10 changed files with 828 additions and 221 deletions
+88
View File
@@ -96,6 +96,74 @@ The firmware also calls `LittleFS.begin(true)`, so an empty filesystem can be fo
## IMU And Yaw Guide
### AK09918C Compass Investigation
This firmware contains a best-effort fix and diagnostic pass for the onboard
compass path. It is intentionally documented here so anyone finding this repo can
see what was tested instead of repeating the same blind firmware changes.
Waveshare documents the board as using `QMI8658C + AK09918/AK09918C` for the
onboard 9-axis IMU. The big marked QST chip on the PCB is the `QMI8658C`
accelerometer/gyro. The AK09918C compass is a much smaller AKM WLCSP part; AKM
lists the package as a 4-pin `0.76 mm x 0.76 mm x 0.5 mm` device, so it will not
look like a normal large labelled IC.
Relevant upstream references:
- Waveshare product page: <https://www.waveshare.com/General-Driver-for-Robots.htm>
- Waveshare wiki: <https://www.waveshare.com/wiki/General_Driver_for_Robots>
- Waveshare GitHub commit that disables/ignores the mag path: <https://github.com/waveshareteam/ugv_base_general/commit/b113287ffff7fee03998f998a4e24ae221dd96aa>
- AKM AK09918C product page: <https://www.akm.com/us/en/products/electronic-compass/lineup-electronic-compass/ak09918c/>
- AK09918C datasheet package/marking page: <https://www.alldatasheet.com/html-pdf/929214/AKM/AK09918C/1641/27/AK09918C.html>
- Linux AKM magnetometer driver listing `AK09918_DEVICE_ID 0x0C`: <https://codebrowser.dev/linux/linux/drivers/iio/magnetometer/ak8975.c.html>
Observed I2C bus on the tested board:
- `0x0C`: AKM-compatible compass address
- `0x3C`: SSD1306 OLED
- `0x42`: INA219 voltage/current monitor
- `0x6B`: QMI8658C accelerometer/gyro
The firmware now probes the compass more defensively:
- checks AKM-compatible identity on `0x0C`
- also probes `0x06` to catch confusion between 7-bit and 8-bit I2C address notation
- transitions through power-down before measurement modes
- tries continuous `100 Hz`, `50 Hz`, `20 Hz`, `10 Hz`, then single-measurement mode
- reads `ST1`, `CNTL2`, raw data, and `ST2` for every mode probe
- runs a bounded AK09918 self-test diagnostic instead of hanging forever
- scans the I2C bus at boot when the compass does not produce data
- keeps yaw from using fake `0/0/0` magnetometer samples
- exposes `magSrc`, `magStatus`, `magLive`, `magAddr`, `magWIA2`, and `magSamples`
Important diagnostic pattern from the tested board:
```text
I2C scan: 0x0C 0x3C 0x42 0x6B
AK09918 addr=0x0C ... WIA2=0x0C or 0x0D
CNTL2 writes/readbacks work, e.g. 0x08 for continuous-100Hz
ST1 remains 0x00
raw remains 0/0/0
self-test sets CNTL2=0x10 but times out with no DRDY
QMI8658 mag fallback also reports raw=0/0/0
```
Interpretation:
- I2C wiring and the digital register interface are alive because the chip ACKs,
identity registers can be read, reset works, and `CNTL2` mode writes stick.
- The magnetic measurement core is not producing `DRDY` or non-zero raw samples.
- This is not the same as bad calibration; calibration needs live changing mag
samples first.
- If the same pattern appears on another board, likely causes include a board
revision issue, AK09918C supply/decoupling/soldering problem, damaged compass
die, or an AKM-compatible variant/clone that does not behave like the public
AK09918C register model.
This does not prove every General Driver board has a hardware fault. It means
this firmware has exhausted the obvious software-side address, mode, transaction,
and calibration fixes for this observed failure mode.
### What Was Fixed
The original IMU path had multiple issues that could produce unstable or misleading `yaw`:
@@ -158,6 +226,12 @@ Important feedback fields:
`1` while calibration is still collecting data
- `magCalProgress`
progress from `0` to `100`
- `magSrc`
active compass source: `ak09918`, `qmi8658`, or `none`
- `magStatus`
compass health: `ok`, `no_drdy`, `lost`, or `not_found`
- `magLive`
`1` only after at least one real magnetometer sample was received
### Successful Result
@@ -176,6 +250,11 @@ If `magCal` stays `0`:
- cover more angles
- move away from magnetic or metal interference
If `magStatus` is `no_drdy` and `magLive` is `0`, firmware can talk to the
AKM-compatible chip but the magnetic measurement core is not producing data.
That is different from a calibration problem: check the board revision, IMU
chip marking, AK09918C supply rails, and soldering around the IMU.
If `magSaved` is `0` after a good calibration:
- check that `LittleFS` mounted successfully
@@ -190,6 +269,8 @@ If `magSaved` is `0` after a good calibration:
```
Returns roll, pitch, yaw, accel, gyro, mag, temperature, and calibration state flags.
It also returns `magSrc`, `magStatus`, `magLive`, `magAddr`, `magWIA2`, and
`magSamples` for compass diagnosis.
### Recalibrate Gyro/Accel Bias
@@ -238,6 +319,9 @@ Useful fields:
- `magSaved`
- `magCalRunning`
- `magCalProgress`
- `magSrc`
- `magStatus`
- `magLive`
- `temp`
## Yaw Troubleshooting
@@ -250,8 +334,12 @@ If `yaw` still looks wrong:
- `magCal = 1`
- `magSaved = 1`
- `magCalRunning = 0`
- `magStatus = ok`
4. Reboot and verify the values are still loaded.
If `yaw` drifts while `magStatus` is not `ok`, the rover is running gyro/accel
AHRS without a live compass. Fix the magnetometer hardware path first.
If `yaw` is stable but mirrored or rotated by a fixed amount, the next thing to tune is axis convention or declination, not the calibration storage itself.
## Notes