64
64
_MPU6050_CONFIG = 0x1A # General configuration register
65
65
_MPU6050_GYRO_CONFIG = 0x1B # Gyro specfic configuration register
66
66
_MPU6050_ACCEL_CONFIG = 0x1C # Accelerometer specific configration register
67
+ _MPU6050_FIFO_EN = 0x23 # FIFO Enable
67
68
_MPU6050_INT_PIN_CONFIG = 0x37 # Interrupt pin configuration register
68
69
_MPU6050_ACCEL_OUT = 0x3B # base address for sensor data reads
69
70
_MPU6050_TEMP_OUT = 0x41 # Temperature data high byte register
72
73
_MPU6050_USER_CTRL = 0x6A # FIFO and I2C Master control register
73
74
_MPU6050_PWR_MGMT_1 = 0x6B # Primary power/sleep control register
74
75
_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
75
78
_MPU6050_WHO_AM_I = 0x75 # Divice ID register
76
79
77
80
STANDARD_GRAVITY = 9.80665
@@ -170,7 +173,7 @@ class Rate: # pylint: disable=too-few-public-methods
170
173
CYCLE_40_HZ = 3 # 40 Hz
171
174
172
175
173
- class MPU6050 :
176
+ class MPU6050 : # pylint: disable=too-many-instance-attributes
174
177
"""Driver for the MPU6050 6-DoF accelerometer and gyroscope.
175
178
176
179
: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
215
218
self ._filter_bandwidth = Bandwidth .BAND_260_HZ
216
219
self ._gyro_range = GyroRange .RANGE_500_DPS
217
220
self ._accel_range = Range .RANGE_2_G
221
+ self ._accel_scale = 1.0 / [16384 , 8192 , 4096 , 2048 ][self ._accel_range ]
218
222
sleep (0.100 )
219
223
self .clock_source = (
220
224
ClockSource .CLKSEL_INTERNAL_X
@@ -257,6 +261,11 @@ def reset(self) -> None:
257
261
sample_rate_divisor = UnaryStruct (_MPU6050_SMPLRT_DIV , ">B" )
258
262
"""The sample rate divisor. See the datasheet for additional detail"""
259
263
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
+
260
269
@property
261
270
def temperature (self ) -> float :
262
271
"""The current temperature in º Celsius"""
@@ -268,35 +277,26 @@ def temperature(self) -> float:
268
277
def acceleration (self ) -> Tuple [float , float , float ]:
269
278
"""Acceleration X, Y, and Z axis data in :math:`m/s^2`"""
270
279
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 ]])
290
281
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
291
287
return (accel_x , accel_y , accel_z )
292
288
293
289
@property
294
290
def gyro (self ) -> Tuple [float , float , float ]:
295
291
"""Gyroscope X, Y, and Z axis data in :math:`º/s`"""
296
292
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 ]
300
300
301
301
gyro_scale = 1
302
302
gyro_range = self ._gyro_range
@@ -309,7 +309,7 @@ def gyro(self) -> Tuple[float, float, float]:
309
309
if gyro_range == GyroRange .RANGE_2000_DPS :
310
310
gyro_scale = 16.4
311
311
312
- # setup range dependant scaling
312
+ # setup range dependent scaling
313
313
gyro_x = radians (raw_x / gyro_scale )
314
314
gyro_y = radians (raw_y / gyro_scale )
315
315
gyro_z = radians (raw_z / gyro_scale )
@@ -349,6 +349,7 @@ def accelerometer_range(self, value: int) -> None:
349
349
if (value < 0 ) or (value > 3 ):
350
350
raise ValueError ("accelerometer_range must be a Range" )
351
351
self ._accel_range = value
352
+ self ._accel_scale = 1.0 / [16384 , 8192 , 4096 , 2048 ][value ]
352
353
sleep (0.01 )
353
354
354
355
@property
@@ -388,3 +389,13 @@ def clock_source(self, value: int) -> None:
388
389
"clock_source must be ClockSource value, integer from 0 - 7."
389
390
)
390
391
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