I am using 11 ICM 20948 IMUs to monitor the orientation of bones of a simplified skeleton. I’m using the Qwiic Mux Breakout – 8 Channel (TCA9548A). I’m also using 3 pairs of differential I2C Breakouts (PCA9615) (Qwiic) (because of the distances to different IMUs from the Arduino). My software is based on “Example1_Basics.ino” that is included in SparkFun_ICM-20948_ArduinoLibrary-master and uses the library:
http://librarymanager/All#SparkFun_ICM_20948_IMU
I am having some difficulties when I try to use the differential breakout boards downstream of the Mux. I understand that I need to get a grip on how many of the pull up resistors to remove and I also need to decide which power method to use for the differential breakouts. I am using the following as my guide.
https://learn.sparkfun.com/tutorials/qw … 1564845932
So, with that context laid I have the following observation leading to my question. The system is currently flaky. Sometimes it will read all 11 IMUs and then the next try it will not. I blame this on not having optimized the pull up resistors and power method. The thing is, once it ceases to initialize properly, it never initializes properly until I pull the power on the IMUs. I assume that pulling the power on the IMUs is causing a more complete restart of the IMUs’ Digital Motion Processor, than just restarting the Arduino program, i.e., once I have confused the IMU processor, it will stay confused until I pull its power. So, here (finally) is my question. Is there a software method to reset the IMUs without pulling the power? And a very closely related, and likely more important question is, how can I see the methods available to me in the SparkFun_ICM_20948_IMU library?
Good questions!
First - you might try slowing down the clock frequency of the I2C communications if possible. That should help identify if it is a SW or HW problem.
- reset Function:
myICM.[swReset(); performs a software reset of the device
- A good way to see all available functions…
This is tricky. We don’t have a really good way right now. The best way I can suggest for how is to look at the [header file for the library.
We are trying to standardize on a good way to document our software, like Read the Docs, for instance. Until then the header files will be your best bet!](SparkFun_ICM-20948_ArduinoLibrary/src/ICM_20948.h at main · sparkfun/SparkFun_ICM-20948_ArduinoLibrary · GitHub)](SparkFun_ICM-20948_ArduinoLibrary/src/ICM_20948.h at main · sparkfun/SparkFun_ICM-20948_ArduinoLibrary · GitHub)
Liquid.Soulder, thank for your quick and useful response. I did not realize that the source code for the library was located on my machine. From your response, I did a little more digging and found it at:
libraries\SparkFun_9DoF_IMU_Breakout_-ICM_20948-_Arduino_Library\src and utils.
I previously thought the downloaded library would be executable only. This revelation should be very useful going forward.
As far as swReset goes, I can now see that it is already called as part of startupDefault. So, it would seem that whatever is getting reset when I pull the power on the IMUs is not being handled in swReset. There could be other things getting fouled up. But I think the Digital Motion Processor remains the primary suspect.
Are you utilizing the DMP in your code? I have not pursued it personally. AFAIK the library that we wrote should only report single-sample readings and does not involve the DMP.
To me this is all sounding more like a bus problem than a sensor problem - if you have flaky I2C communication and suspect pull-up values then (IMO) a good place to start is to slow down the clock rate. Try [Wire.setClock(val); with some values like 100000 or 10000.
If your pull-ups are too weak (which is possible if the capacitance of the lines is large - from long lines or other electrical wackiness) then a slower clock has more time for the voltage to rise (and fall, since the uC has to sink some current to ground as well)
If they are too strong… clock speed should not ake much of a difference. If the pullups are too strong the uC may not be able to create a low enough voltage when it tries to drain charge off the lines. But I’d be more concerned about the I2C pins sinking too much current and ‘blowing up’ before that happens.
Do you have access to a logic analyzer or oscilloscope?](Wire - Arduino Reference)
Liquid.Soulder, thank you for your continued assistance. First, I just want to make clear that I do not expect a more complete reset to fix my flaky problem. The fact that once something gets flaky, the only way I get it working again is to cut the power to the IMUs, indicates that something about the flaky state is lingering into the next run. It just seems bad practice to pull the USB plug (and in my case, the power to the whole system since the Arduino gets its power from either the USB to my PC or system power supply). So, I thought that in the process of going after my flaky problem it would be nice to include a more robust initialization, i.e., duplicate whatever is happening when I cut the power to the IMUs, if such a method exists.
Your comment about the library not using the DMP is very helpful. My project is a fairly long-term effort and I think it will be worth my time to offload the filtering to the chip. I suppose the use of the Madgwick filter should have told me that the DMP was not being used by the library.
I very much appreciate your comments on slowing down the clock and using a logic analyzer/scope. I have seen that the voltage at the furthest downstream sensors is down to 3.0 V (from the original 3.3) and am currently trying to get the differential breakout boards to be independently powered. My assumption is that this will free up power for the signal. I have no previous experience with this so am just slowly working my way through the issues. If after trying your suggestions, messing with the pull-up resistors, and powering the differential break out boards, I still have problems, I’ll open a more related question. In the meantime, if you think of a software equivalent to pulling the power, I still think that would be a good thing to do.
Okay - sounds good. In the meantime is it possible for you to post your example code? (A .zip of the project is best)
Okay, so, I’ve attached a zipped copy of the project. Currently, it runs 8 IMUs fairly reliably. But, when I take it up to 11, I have to unplug the power between each run and sometimes that doesn’t get it working again. I think everything points to the hardware. So, I would not spend too much time on the code. Although, I did make a few assumptions and could easily have messed something up. Again, thank-you for your help.
IMUTest.zip (4.35 KB)
I took some time to inspect your code and didn’t find anything terribly out of place. You’re probably right that this is a HW problem. Have you found out anything more?
Thank you for looking at the code, as well as the rest of the suggestions. I think at this point that my original question has run its course. If anybody comes across information about what is happening when I unplug the power to the IMUs that is different than what I am getting through a the software reset, I’d still like to know that. Otherwise, as I trouble shoot the apparent differential breakout board issue, If I run into problems, I’ll open another question (I think in the Qwiic topics).