feat: add MPU-9250 / RAK1905 9-axis sensor support#10556
Open
egorsiniaev wants to merge 6 commits into
Open
Conversation
The RAK12034 (BMX160) WisBlock module is end-of-life. RAK's official replacement is the 6-axis RAK12033, which drops the magnetometer entirely. RAK1905 (InvenSense MPU-9250) is the closest 9-axis WisBlock module still in production and is a natural drop-in for users who want to keep tilt-compensated compass functionality. This adds a minimal direct-I2C driver — no new library dependency, ~5KB flash on rak4631. The MPU-6500 accel/gyro die is driven directly; the AK8963 magnetometer die is exposed via the MPU's I2C bypass mode and talked to at 0x0C. Per-axis Fuse-ROM ASA sensitivity factors and ST2 overflow are honored. Hard-iron calibration is persisted to /prefs/compass_mpu9250.dat, matching the BMX160 / ICM-20948 pattern. Detection disambiguates MPU-6050 from MPU-9250/9255 by reading WHO_AM_I (0x75) after the existing register-0x00 fallback path that already covers ICM-20948 / BMI270 / BMX160 / SEN5X. MPU-6050 paths are unchanged.
Detection found the chip and set the device type correctly, but ScanI2C::firstAccelerometer() iterates a hard-coded list that didn't include MPU9250 — so accelerometer_found stayed unset and the AccelerometerThread was never constructed for the new sensor.
Compass-only fusion is stateless, so any dynamic acceleration during device rotation immediately showed up as overshoot on the displayed heading. Add a per-axis exponential moving average on the raw accel and mag samples before tilt compensation. Accel uses alpha=0.15 to keep the gravity reference stable; mag uses alpha=0.20 for slightly faster response. Time constant is well under half a second so the needle still tracks deliberate rotation, but small jitters and rotation-induced spikes are damped.
FusionCompassCalculateHeading assumes the sensor's Z axis is world-up. That holds when the WisBlock baseboard is mounted flat, but fails on cases where the baseboard sits vertical (LCD perpendicular to the board) — chip Z is then horizontal and tilt-comp becomes unstable. Add a build-time MPU9250_UP_AXIS selector with five options: PZ (default, baseboard flat), PX, NX, PY, NY. Implementation rotates both accel and mag via FusionAxesSwap so the rest of the heading pipeline still sees Z as up. The temporary default is PX while testing on a vertical RAK case; will be reverted to PZ before the PR is marked ready, with vertical case users opting in via variant.h or build flags.
The previous commit shipped with PX as the default while validating the remap on a vertical-mount RAK case. PZ matches the assumption baked into BMX160 / ICM20948 (chip Z = world up), so leaving the default at PZ keeps existing flat-mount users untouched. Vertical mount users opt in by setting MPU9250_UP_AXIS in their variant.h or via build_flags in platformio.ini.
Author
|
Heads up - opened a design discussion about a related limitation I found while working on this: the existing compass code (here and in the BMX160 / ICM20948 drivers) assumes the sensor chip is mounted with Z = up, which breaks tilt compensation in vertical-mount cases. This PR ships with a build-time workaround (MPU9250_UP_AXIS), but the proper runtime-configurable solution is out of scope for this PR. Discussion: #10557 Doesn't block review of this PR, just flagging so reviewers know the orientation question is being tracked separately rather than ignored. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds support for the InvenSense MPU-9250 (RAK1905 WisBlock module): a 9-axis sensor that combines a 3-axis accelerometer, 3-axis gyroscope, and 3-axis magnetometer in one package. The driver provides tilt-compensated magnetic heading via the existing Fusion library, with hard-iron calibration persisted to flash - matching the BMX160 and ICM-20948 patterns.
Implemented as a minimal direct-I2C driver with no new library dependency. Flash impact on RAK4631: roughly +1 KB.
Motivation
The RAK12034 (BMX160) is end-of-life. RAK's official replacement, RAK12033 (IIM-42652), is 6-axis only and drops the magnetometer entirely. For users who want tilt-compensated compass on a WisBlock-based device, the closest still-in- production option is the RAK1905 (MPU-9250).
Detection
MPU-9250 shares I2C addresses (0x68/0x69) with MPU-6050, ICM-20948, BMX160, BMI270, SEN5X. "ScanI2CTwoWire" now reads WHO_AM_I (0x75) after the existing register-0x00 disambiguation:
No regressions to the existing detection paths.
Testing
Verified on a RAK4631 + RAK19007 baseboard + RAK1905:
References
Related WisBlock modules
MPU-9250 chip-level documentation (TDK InvenSense)
Reference implementations
my, mx, -mzto align the AK8963 magnetometer frame with the MPU-6500 accel frame).🤝 Attestations
Video of testing: https://photos.app.goo.gl/Vkcj1HB4mcSKeKBi8