motamman - I posted this on the Arduino group b...
I posted this I2C MPU9250/imu Q on the Arduino group, but maybe some folks here might be able to help:
I have a device that has the following components:
1. Beetle esp32-c6 (programmatically set SDA to GPIO 20, SCL to 19. RX to 21 and TX to 22.)
2. Beitain BE880 GPS connected to RX and TX pins. I am NOT using the internal compass. (TinyGPSPlus library: https://github.com/mikalhart/TinyGPSPlus)
3. An I2C MPU9250/imu mag and accelerometer module on 0x68. (MPU9250 library: https://github.com/hideakitai/)
4. An I2C BME28/temp, pressure and humidity module on 0x76. (Adafruit BME280 library: https://github.com/adafruit/Adafruit_BME280_Library)
I am also running wifi, OTA, and Webserver.
I use data from each sensor to send deltas to a signal k server via UDP.
The BME and GPS always work fine.
Inside the void loop block, mpu.update() only returns usable data if it isn't encapsulated in a loop or a conditional statement. If it is, I get zeros.
But after about 30 minutes, the data freezes. No errors are triggered, but the data remains the same. Give it a little more time, and I get i2cWriteReadNonStop -1 errors and, occasionally, a 263 error. I tried resetting the bus, but I did not expect that to work. It didn't.
void loop() {
// Let the Watchdog know it ain't frozen
esp_task_wdt_reset();
<snip>
mpu.update();
unsigned long currentTime = millis();
if (currentTime - lastProcessTime >= processInterval) {
lastProcessTime = currentTime;
// Stagger sensor data processing
static int sensorCycle = 0;
switch(sensorCycle) {
case 0:
Serial.println("Processing I2C data...");
processCompassData(); // Process compass dat
delay(100);
sendBMP280Data(); // Process BMP280 data
break;
<snip>
}
sensorCycle = (sensorCycle + 1) % 3; // Move to the next sensor in the next loop
}
}
}
4 Replies
Since you have two I2C devices, did you remove the pull-up resistor from one of them? (Can provide more detail if this is new to you).
The MPU9250 has been discontinued for while. You might want to try a newer module like the ICM20948. I have used
[this](https://github.com/jremington/ICM_20948-AHRS)
library successfully and the author still maintains it.
I didn't look into the details of your library, but it's possible that it's implementing a Mahony or Madgwick algorithm that relies on precise timing to calculate how long the gyro has sensed rotation. With several devices, you might need to use a dedicated ESP task.
The delay() in your loop might also be messing up timing (although unlikely to cause a hang). I would consider using [ReactESP](https://github.com/mairas/ReactESP)
instead.Thank you muchly for all of that. I am pretty new to this space so I appreciate the offerings.
And I didn't remove any pull-up resistors. I didn't think that was necessary given they have different addresses. (And I have never done that.)
Would that cause one sensor to behave erratically and the other flawlessly?
It could. There's some documentation on using multiple I2C devices here: https://learn.sparkfun.com/tutorials/i2c/all
If you have multiple devices and your total pull-up resistance is too high, at the very least you will have issues (like timeouts) on the bus. I doubt this would affect a BME280...it's a very simple device and doesn't need the bus very frequently. But an IMU is a completely different story.
However, I'm not a hardware engineer so I'm just repeating what I've read about.
Thank you. I had an extra ICM20948 that I bought as a spare for my MacArthur Hat. I hooked that up to the system, reworked the code, and, bobs your uncle, it is working flawlessly. I didn't have to play when the resistors either.
Still, that link and the process have been illuminating. Thank you.