feat: auto-detect IMU at I2C address 0x68 or 0x69 - #2
Open
Michaelvvt wants to merge 2 commits into
Open
Conversation
The ICM-20948 and MPU-9250 chips have a hardware-strapped I2C address controlled by the AD0 pin: low = 0x68 (default), high = 0x69. Many breakout boards (Adafruit, Sparkfun, etc.) ship with AD0 tied high, making the chip respond at 0x69. The previous code hardcoded 0x68 everywhere, so chips at 0x69 were undetectable. This change makes each driver probe both addresses at construction time: - Add MPU_ADDRESS_ALT = 0x69 constant in both drivers - Add ICMREG_WHO_AM_I / ICMREG_WHO_AM_I_VAL constants to icm20948 - Add `address byte` field to ICM20948 and MPU9250 structs - In NewICM20948 / NewMPU9250, probe both addresses for a valid WHO_AM_I response and store the detected address - Replace all I2C read/write calls to use mpu.address instead of the MPU_ADDRESS constant - Return a clear error if the chip is found at neither address The public function signatures are unchanged, so this is fully backward compatible for existing callers.
Go does not auto-dereference pointer-to-interface like pointer-to-struct. Calling ReadByteFromReg on the *embd.I2CBus parameter failed to compile; use the dereferenced copy stored at mpu.i2cbus instead.
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.
Problem
The ICM-20948 and MPU-9250 drivers hardcode
MPU_ADDRESS = 0x68for every I2C read/write. Both chips have a hardware-strapped I2C address controlled by the AD0 pin:0x68(datasheet default)0x69(used by many breakout boards: Adafruit, Sparkfun, generic AliExpress GY-91 etc.)Stratux users with AD0-high boards see the IMU show up at
0x69oni2cdetect, but the driver only ever talks to0x68, so the chip is undetectable.Reproduction (Pi 5, Stratux EU image, AHRS hat with AD0 pulled high):
0x69= ICM-20948,0x77= BMP-388. With the unpatched driver, Stratux logs:This is the same symptom as stratux/stratux#115.
Fix
Each driver constructor now probes both
0x68and0x69for a validWHO_AM_Iresponse at startup and remembers the address that answered:MPU_ADDRESS_ALT = 0x69constant alongside the existingMPU_ADDRESS = 0x68.address bytefield toICM20948andMPU9250structs.NewICM20948/NewMPU9250: probe both addresses, store the one that responds with a validWHO_AM_Ivalue, return a clear error if neither answers.MPU_ADDRESSuses withmpu.addressin I2C read/write helpers.Backward compatible: public function signatures unchanged. Existing callers get the new behavior for free.
For the ICM-20948, a strict
WHO_AM_I == 0xEAcheck is used. For the MPU-9250, any value in the0x68-0x75range is accepted (matches the existing acceptance list in Stratux'sinitIMU: MPU6000/6050/6500/9150/9250/9255/unknown-gy91-variant).Verification on hardware (Pi 5 / Bookworm / ICM-20948 at 0x69)
Before:
After:
IMU samples flowing continuously; AHRS calibrated and producing attitude output.
Companion PR
Stratux's
initIMUcurrently does its own hardcoded-0x68WHO_AM_Iprobe before invoking these constructors, which gates them from running for AD0-high chips. A companion PR simplifiesinitIMUto delegate detection entirely to the driver: stratux/stratux#TBDEither PR alone helps — together they remove the bug and the duplicated probe logic.
Notes
MPU_ADDRESSconstant retained at0x68for backward compatibility (kept as the documented default).