6464_MPU6050_CONFIG = 0x1A # General configuration register
6565_MPU6050_GYRO_CONFIG = 0x1B # Gyro specfic configuration register
6666_MPU6050_ACCEL_CONFIG = 0x1C # Accelerometer specific configration register
67+ _MPU6050_FIFO_EN = 0x23 # FIFO Enable
6768_MPU6050_INT_PIN_CONFIG = 0x37 # Interrupt pin configuration register
6869_MPU6050_ACCEL_OUT = 0x3B # base address for sensor data reads
6970_MPU6050_TEMP_OUT = 0x41 # Temperature data high byte register
7273_MPU6050_USER_CTRL = 0x6A # FIFO and I2C Master control register
7374_MPU6050_PWR_MGMT_1 = 0x6B # Primary power/sleep control register
7475_MPU6050_PWR_MGMT_2 = 0x6C # Secondary power/sleep control register
76+ _MPU6050_FIFO_COUNT = 0x72 # FIFO byte count register (high half)
77+ _MPU6050_FIFO_R_W = 0x74 # FIFO data register
7578_MPU6050_WHO_AM_I = 0x75 # Divice ID register
7679
7780STANDARD_GRAVITY = 9.80665
@@ -170,7 +173,7 @@ class Rate: # pylint: disable=too-few-public-methods
170173 CYCLE_40_HZ = 3 # 40 Hz
171174
172175
173- class MPU6050 :
176+ class MPU6050 : # pylint: disable=too-many-instance-attributes
174177 """Driver for the MPU6050 6-DoF accelerometer and gyroscope.
175178
176179 :param ~busio.I2C i2c_bus: The I2C bus the device is connected to
@@ -215,6 +218,7 @@ def __init__(self, i2c_bus: I2C, address: int = _MPU6050_DEFAULT_ADDRESS) -> Non
215218 self ._filter_bandwidth = Bandwidth .BAND_260_HZ
216219 self ._gyro_range = GyroRange .RANGE_500_DPS
217220 self ._accel_range = Range .RANGE_2_G
221+ self ._accel_scale = 1.0 / [16384 , 8192 , 4096 , 2048 ][self ._accel_range ]
218222 sleep (0.100 )
219223 self .clock_source = (
220224 ClockSource .CLKSEL_INTERNAL_X
@@ -257,6 +261,11 @@ def reset(self) -> None:
257261 sample_rate_divisor = UnaryStruct (_MPU6050_SMPLRT_DIV , ">B" )
258262 """The sample rate divisor. See the datasheet for additional detail"""
259263
264+ fifo_en = RWBit (_MPU6050_USER_CTRL , 6 )
265+ fiforst = RWBit (_MPU6050_USER_CTRL , 2 )
266+ accel_fifo_en = RWBit (_MPU6050_FIFO_EN , 3 )
267+ fifo_count = ROUnaryStruct (_MPU6050_FIFO_COUNT , ">h" )
268+
260269 @property
261270 def temperature (self ) -> float :
262271 """The current temperature in º Celsius"""
@@ -268,35 +277,26 @@ def temperature(self) -> float:
268277 def acceleration (self ) -> Tuple [float , float , float ]:
269278 """Acceleration X, Y, and Z axis data in :math:`m/s^2`"""
270279 raw_data = self ._raw_accel_data
271- raw_x = raw_data [0 ][0 ]
272- raw_y = raw_data [1 ][0 ]
273- raw_z = raw_data [2 ][0 ]
274-
275- accel_range = self ._accel_range
276- accel_scale = 1
277- if accel_range == Range .RANGE_16_G :
278- accel_scale = 2048
279- if accel_range == Range .RANGE_8_G :
280- accel_scale = 4096
281- if accel_range == Range .RANGE_4_G :
282- accel_scale = 8192
283- if accel_range == Range .RANGE_2_G :
284- accel_scale = 16384
285-
286- # setup range dependant scaling
287- accel_x = (raw_x / accel_scale ) * STANDARD_GRAVITY
288- accel_y = (raw_y / accel_scale ) * STANDARD_GRAVITY
289- accel_z = (raw_z / accel_scale ) * STANDARD_GRAVITY
280+ return self .scale_accel ([raw_data [0 ][0 ], raw_data [1 ][0 ], raw_data [2 ][0 ]])
290281
282+ def scale_accel (self , raw_data ) -> Tuple [float , float , float ]:
283+ """Scale raw X, Y, and Z axis data to :math:`m/s^2`"""
284+ accel_x = (raw_data [0 ] * self ._accel_scale ) * STANDARD_GRAVITY
285+ accel_y = (raw_data [1 ] * self ._accel_scale ) * STANDARD_GRAVITY
286+ accel_z = (raw_data [2 ] * self ._accel_scale ) * STANDARD_GRAVITY
291287 return (accel_x , accel_y , accel_z )
292288
293289 @property
294290 def gyro (self ) -> Tuple [float , float , float ]:
295291 """Gyroscope X, Y, and Z axis data in :math:`º/s`"""
296292 raw_data = self ._raw_gyro_data
297- raw_x = raw_data [0 ][0 ]
298- raw_y = raw_data [1 ][0 ]
299- raw_z = raw_data [2 ][0 ]
293+ return self .scale_gyro ((raw_data [0 ][0 ], raw_data [1 ][0 ], raw_data [2 ][0 ]))
294+
295+ def scale_gyro (self , raw_data ) -> Tuple [float , float , float ]:
296+ """Scale raw gyro data to :math:`º/s`"""
297+ raw_x = raw_data [0 ]
298+ raw_y = raw_data [1 ]
299+ raw_z = raw_data [2 ]
300300
301301 gyro_scale = 1
302302 gyro_range = self ._gyro_range
@@ -309,7 +309,7 @@ def gyro(self) -> Tuple[float, float, float]:
309309 if gyro_range == GyroRange .RANGE_2000_DPS :
310310 gyro_scale = 16.4
311311
312- # setup range dependant scaling
312+ # setup range dependent scaling
313313 gyro_x = radians (raw_x / gyro_scale )
314314 gyro_y = radians (raw_y / gyro_scale )
315315 gyro_z = radians (raw_z / gyro_scale )
@@ -349,6 +349,7 @@ def accelerometer_range(self, value: int) -> None:
349349 if (value < 0 ) or (value > 3 ):
350350 raise ValueError ("accelerometer_range must be a Range" )
351351 self ._accel_range = value
352+ self ._accel_scale = 1.0 / [16384 , 8192 , 4096 , 2048 ][value ]
352353 sleep (0.01 )
353354
354355 @property
@@ -388,3 +389,13 @@ def clock_source(self, value: int) -> None:
388389 "clock_source must be ClockSource value, integer from 0 - 7."
389390 )
390391 self ._clksel = value
392+
393+ def read_whole_fifo (self ):
394+ """Return raw FIFO bytes"""
395+ # This code must be fast to ensure samples are contiguous
396+ count = self .fifo_count
397+ buf = bytearray (count )
398+ buf [0 ] = _MPU6050_FIFO_R_W
399+ with self .i2c_device :
400+ self .i2c_device .write_then_readinto (buf , buf , out_end = 1 , in_start = 0 )
401+ return buf
0 commit comments