Not sure what is happening here (I2C and/or MPU6050 issue)

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Post Reply
User avatar
mathieu
Posts: 88
Joined: Fri Nov 10, 2017 9:57 pm

Not sure what is happening here (I2C and/or MPU6050 issue)

Post by mathieu » Sun Oct 17, 2021 8:23 am

  • I am using a TinyPICO Nano (ESP32) to read values from a MPU6050 gyro/accelerometer using I2C.
  • The MPU is on a GY-521 breakout board (schematics here).
  • The MPU specs state that I2C clock should be 400 kHz.
  • As demonstrated by the code below, a single reading at that clock speed requires almost 40 ms, which seems huge.
  • Increasing the clock speed to 600 kHz reduces the time required for a single reading to 3 ms.
  • In both cases the readings seem accurate.
  • Experimenting yields good results up to 1.2 MHz, with negligible time gains (down to 2.6 ms)
I am really puzzled by this behaviour. Anybody know what is happening?

Code:

Code: Select all

from machine import Pin, I2C
from imu import MPU6050
from time import sleep_ms, ticks_ms, ticks_us, ticks_diff

for f in [6e5, 4e5]:

	i2c = I2C(0, scl = Pin(22), sda = Pin(21), freq = int(f))
	imu = MPU6050(i2c)

	for _ in range(8):
		sleep_ms(50)
		now = ticks_us()
		imu.gyro.xyz
		diff = ticks_diff(ticks_us(),now)
		print('freq = %d kHz, uses %d us, accel = %s, gyro = %s' % (int(f)/1000, diff, imu.accel.xyz, imu.gyro.xyz))

	print()
Output:

Code: Select all

freq = 600 kHz, uses 2862 us, accel = (0.40625, 0.5942383, 0.6477051), gyro = (-4.320611, 0.5954198, -0.1526718)
freq = 600 kHz, uses 3080 us, accel = (0.4006348, 0.5837402, 0.6489258), gyro = (-3.847328, 0.4961832, -0.1374046)
freq = 600 kHz, uses 3089 us, accel = (0.3962402, 0.5895996, 0.6398926), gyro = (-4.045802, 0.6641222, -0.06870229)
freq = 600 kHz, uses 3120 us, accel = (0.4047852, 0.5883789, 0.6535645), gyro = (-3.961832, 0.7099237, -0.3282443)
freq = 600 kHz, uses 3083 us, accel = (0.4025879, 0.5871582, 0.6469727), gyro = (-4.21374, 0.4656488, -0.389313)
freq = 600 kHz, uses 3068 us, accel = (0.40625, 0.5917969, 0.6411133), gyro = (-3.969466, 0.5725191, 0.04580153)
freq = 600 kHz, uses 3048 us, accel = (0.4086914, 0.5869141, 0.6508789), gyro = (-4.160306, 0.5801527, -0.129771)
freq = 600 kHz, uses 3094 us, accel = (0.4040527, 0.583252, 0.6513672), gyro = (-3.984733, 0.351145, -0.2519084)

freq = 400 kHz, uses 38464 us, accel = (0.402832, 0.5881348, 0.6462402), gyro = (-3.862595, 0.4198473, -0.2519084)
freq = 400 kHz, uses 38508 us, accel = (0.4025879, 0.5895996, 0.654541), gyro = (-3.80916, -0.03816794, -0.2137404)
freq = 400 kHz, uses 38642 us, accel = (0.4160156, 0.5878906, 0.6477051), gyro = (-4.465649, 0.4122138, 0.007633588)
freq = 400 kHz, uses 38657 us, accel = (0.4033203, 0.5915527, 0.6464844), gyro = (-3.687023, 0.6030535, 0.03053435)
freq = 400 kHz, uses 38650 us, accel = (0.4008789, 0.5864258, 0.6381836), gyro = (-3.343511, 1.900763, 1.137405)
freq = 400 kHz, uses 38640 us, accel = (0.4084473, 0.590332, 0.6606445), gyro = (-4.122138, -0.7480916, -0.3435115)
freq = 400 kHz, uses 38723 us, accel = (0.3981934, 0.5842285, 0.6586914), gyro = (-1.954198, -0.3664122, -0.3587786)
freq = 400 kHz, uses 38678 us, accel = (0.40625, 0.5871582, 0.6447754), gyro = (-2.946565, -1.21374, -0.6641222)

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Not sure what is happening here (I2C and/or MPU6050 issue)

Post by pythoncoder » Mon Oct 18, 2021 10:57 am

I must say I'm puzzled too. You could time this line which is where the I2C read takes place, but I think you'll see the same results: the rest of the code is just maths which should be consistent in its timing. I suspect that what's going on is on-chip. The datasheet says
The data within the gyroscope sensors’ internal register set is always updated at the Sample Rate.
Meanwhile, the user-facing read register set duplicates the internal register set’s data values
whenever the serial interface is idle. This guarantees that a burst read of sensor registers will read
measurements from the same sampling instant.
It says nothing about timing. My guess is that an I2C read is delayed if the update happens to coincide with an attempt to perform a burst read. Changing the bit rate slightly alters the loop timing. This could be proved one way or the other by looking at the effect of changing the loop delay. If you have a scope, putting it on the I2C interface would clarify this.

I must admit I never measured this when developing this driver. My testing was done at the default 400,000 baud.
Peter Hinch
Index to my micropython libraries.

User avatar
mathieu
Posts: 88
Joined: Fri Nov 10, 2017 9:57 pm

Re: Not sure what is happening here (I2C and/or MPU6050 issue)

Post by mathieu » Tue Oct 19, 2021 6:14 pm

I have been experimenting some more and I suspect I may have a faulty GY-521 or I2C connection issues. I ordered a few more GY-521 boards and I will test further when they arrive.

User avatar
mathieu
Posts: 88
Joined: Fri Nov 10, 2017 9:57 pm

Re: Not sure what is happening here (I2C and/or MPU6050 issue)

Post by mathieu » Wed Oct 20, 2021 11:18 am

It seems likely my initial observation was due to some problematic circuitry. I tested with another GY-521 and got the following results:

Code: Select all

freq = 100 kHz, uses 3764 us, accel = (-0.204834, 0.0, 0.9907227), gyro = (35.52672, 2.343511, 0.6335878)
freq = 100 kHz, uses 3985 us, accel = (-0.1931152, -0.0009765625, 0.9943848), gyro = (35.65649, 3.068702, 0.7328244)
freq = 200 kHz, uses 2763 us, accel = (-0.208252, -0.006347656, 0.9882813), gyro = (35.68702, 2.175573, 0.6946565)
freq = 200 kHz, uses 3018 us, accel = (-0.1967773, -0.002685547, 0.9897461), gyro = (35.54199, 2.603053, 0.7862596)
freq = 300 kHz, uses 2452 us, accel = (-0.2036133, -0.006591797, 1.004883), gyro = (35.67176, 2.366412, 0.7022901)
freq = 300 kHz, uses 2675 us, accel = (-0.1992188, -0.001464844, 0.9956055), gyro = (35.67939, 2.290076, 0.610687)
freq = 400 kHz, uses 2254 us, accel = (-0.203125, -0.003662109, 0.9882813), gyro = (35.58016, 2.549618, 0.778626)
freq = 400 kHz, uses 2495 us, accel = (-0.2036133, -0.0078125, 1.000488), gyro = (35.61069, 2.412214, 0.6564885)
freq = 600 kHz, uses 2022 us, accel = (-0.2041016, -0.005371094, 0.9941406), gyro = (35.57252, 2.358779, 0.7557252)
freq = 600 kHz, uses 2306 us, accel = (-0.2092285, -0.002441406, 0.996582), gyro = (35.58016, 2.458015, 0.8091603)
freq = 800 kHz, uses 2015 us, accel = (-0.2053223, 0.0002441406, 1.006104), gyro = (35.44275, 2.427481, 0.8854962)
freq = 800 kHz, uses 2252 us, accel = (-0.2050781, -0.006103516, 1.000977), gyro = (35.80916, 2.496183, 0.5648855)
freq = 1000 kHz, uses 1864 us, accel = (-0.1999512, -0.004150391, 0.9934082), gyro = (35.74809, 2.625954, 0.778626)
freq = 1000 kHz, uses 2085 us, accel = (-0.2053223, -0.003173828, 0.9934082), gyro = (35.78626, 2.48855, 0.7633588)
freq = 1200 kHz, uses 1938 us, accel = (-0.1987305, -0.003662109, 1.004639), gyro = (35.64885, 2.541985, 0.6335878)
freq = 1200 kHz, uses 2128 us, accel = (-0.201416, -0.004150391, 0.9926758), gyro = (35.8397, 2.519084, 0.5954198)

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Not sure what is happening here (I2C and/or MPU6050 issue)

Post by pythoncoder » Thu Oct 21, 2021 9:08 am

That looks much better ;)
Peter Hinch
Index to my micropython libraries.

Post Reply