You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Currently the magnetometer can only be used in bypass mode. This means you can't use two MPUs on the same bus - even though you can change the address of one of them using AD0, their magnetometers still have the same address. Learned this the hard and long way.
The InvenSense driver (which I finally found inside a SparkFun library, lol) does this by setting the magnetometer to single read mode (not continuous 8 Hz or 100Hz), and using SLV0 to read, and SLV1 to trigger the next measurement. I guess it should be possible to do it using only SLV0 and continuous read mode, but I couldn't make it work and didn't need to, because the InvenSense solution already runs at slightly over 100 Hz.
Now that requires some work:
Slave configuration (why are SLV1-3 registers missing..?)
// lib.rs// omitted all the I2C-related type parameters for readabilityimpl<Mode:Marg>Mpu9250<Mode>{// most of the current functions except for magnetometer reading}implMpu9250<MargBypass>{pubfndisable_bypass(self) -> Mpu9250<MargMaster>;// the current magnetometer reading function}implMpu9250<MargMaster>{pubfnenable_bypass(self) -> Mpu9250<Marg>;// a special function for reading magnetometer from the configured SLV register// and/or a generic function for reading any SLV register}
A different implementation of NineDOFDevice - it can't be implemented for I2cDevice, because it depends on bypass state, which I2cDevice doesn't know about
What do you think?
The text was updated successfully, but these errors were encountered:
It's even more complicated lol
With two MPUs on one bus, you must set one of them into master mode before configuring magnetometers. With how it currently works + what I came up with above, funny things happen:
letmut mpu1 = Mpu9250::new_marg(...);letmut mpu2 = Mpu9250::new_marg(...);// And now you realize that inside Mpu9250::new_marg, AK8963::init enables bypass,// which means we've tried initializing two magnetometers at the same time twice,// leaving them in unknown state.// That's not good.// Let's try againletmut mpu1 = Mpu9250::new_marg(...);// First we should make mpu1 magnetometer unreachableletmut mpu1 = mpu1.disable_bypass();// And now we can properly initalize mpu2letmut mpu2 = Mpu9250::new_marg(...);// Disconnect mpu2 magnetometerletmut mpu2 = mpu2.disable_bypass();// Note that we don't know if mpu2 was set to bypass when we initialized mpu1// so we don't know if it initialized properlyletmut mpu1 = mpu1.enable_bypass();// Initialize mpu1 again, maybe there is a better way than re-defining itletmut mpu1 = Mpu9250::new_marg(...);// And finally disable bypassletmut mpu1 = mpu1.disable_bypass();// And now we have two properly configured MPUs
To prevent that, MPU and magnetometer initialization probably would have to be separate functions, which requires significant changes to the API 🤔
And then it's up to the user to sequence everything properly for a single MPU, because it can't be controlled from inside one MPU when you have two. Not good.
Also, maybe I should first make magnetometer mode configurable in a separate PR, that's a much easier change
Currently the magnetometer can only be used in bypass mode. This means you can't use two MPUs on the same bus - even though you can change the address of one of them using AD0, their magnetometers still have the same address. Learned this the hard and long way.
The InvenSense driver (which I finally found inside a SparkFun library, lol) does this by setting the magnetometer to single read mode (not continuous 8 Hz or 100Hz), and using
SLV0
to read, andSLV1
to trigger the next measurement. I guess it should be possible to do it using onlySLV0
and continuous read mode, but I couldn't make it work and didn't need to, because the InvenSense solution already runs at slightly over 100 Hz.Now that requires some work:
Marg
)Maybe like this?
NineDOFDevice
- it can't be implemented forI2cDevice
, because it depends on bypass state, whichI2cDevice
doesn't know aboutWhat do you think?
The text was updated successfully, but these errors were encountered: