39
39
__version__ = "0.0.0+auto.0"
40
40
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_MPU6050.git"
41
41
42
+
42
43
from math import radians
43
44
from time import sleep
44
45
from adafruit_register .i2c_struct import UnaryStruct , ROUnaryStruct
45
46
from adafruit_register .i2c_struct_array import StructArray
46
47
from adafruit_register .i2c_bit import RWBit
47
48
from adafruit_register .i2c_bits import RWBits
48
49
from adafruit_bus_device import i2c_device
50
+ from struct import unpack_from
49
51
50
52
try :
51
53
from typing import Tuple
64
66
_MPU6050_CONFIG = 0x1A # General configuration register
65
67
_MPU6050_GYRO_CONFIG = 0x1B # Gyro specfic configuration register
66
68
_MPU6050_ACCEL_CONFIG = 0x1C # Accelerometer specific configration register
69
+ _MPU6050_FIFO_EN = 0x23 # FIFO Enable
67
70
_MPU6050_INT_PIN_CONFIG = 0x37 # Interrupt pin configuration register
68
71
_MPU6050_ACCEL_OUT = 0x3B # base address for sensor data reads
69
72
_MPU6050_TEMP_OUT = 0x41 # Temperature data high byte register
72
75
_MPU6050_USER_CTRL = 0x6A # FIFO and I2C Master control register
73
76
_MPU6050_PWR_MGMT_1 = 0x6B # Primary power/sleep control register
74
77
_MPU6050_PWR_MGMT_2 = 0x6C # Secondary power/sleep control register
78
+ _MPU6050_FIFO_COUNT = 0x72 # FIFO byte count register (high half)
79
+ _MPU6050_FIFO_R_W = 0x74 # FIFO data register
75
80
_MPU6050_WHO_AM_I = 0x75 # Divice ID register
76
81
77
82
STANDARD_GRAVITY = 9.80665
@@ -215,6 +220,7 @@ def __init__(self, i2c_bus: I2C, address: int = _MPU6050_DEFAULT_ADDRESS) -> Non
215
220
self ._filter_bandwidth = Bandwidth .BAND_260_HZ
216
221
self ._gyro_range = GyroRange .RANGE_500_DPS
217
222
self ._accel_range = Range .RANGE_2_G
223
+ self ._accel_scale = 1.0 / [16384 ,8192 ,4096 ,2048 ][self ._accel_range ]
218
224
sleep (0.100 )
219
225
self .clock_source = (
220
226
ClockSource .CLKSEL_INTERNAL_X
@@ -257,6 +263,11 @@ def reset(self) -> None:
257
263
sample_rate_divisor = UnaryStruct (_MPU6050_SMPLRT_DIV , ">B" )
258
264
"""The sample rate divisor. See the datasheet for additional detail"""
259
265
266
+ fifo_en = RWBit (_MPU6050_USER_CTRL , 6 )
267
+ fiforst = RWBit (_MPU6050_USER_CTRL , 2 )
268
+ accel_fifo_en = RWBit (_MPU6050_FIFO_EN , 3 )
269
+ fifo_count = ROUnaryStruct (_MPU6050_FIFO_COUNT , ">h" )
270
+
260
271
@property
261
272
def temperature (self ) -> float :
262
273
"""The current temperature in º Celsius"""
@@ -268,35 +279,25 @@ def temperature(self) -> float:
268
279
def acceleration (self ) -> Tuple [float , float , float ]:
269
280
"""Acceleration X, Y, and Z axis data in :math:`m/s^2`"""
270
281
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
282
+ return self .scale_accel ([raw_data [0 ][0 ],raw_data [1 ][0 ],raw_data [2 ][0 ]])
290
283
284
+ def scale_accel (self , raw_data ) -> Tuple [float , float , float ]:
285
+ # setup range dependent scaling
286
+ accel_x = (raw_data [0 ] * self ._accel_scale ) * STANDARD_GRAVITY
287
+ accel_y = (raw_data [1 ] * self ._accel_scale ) * STANDARD_GRAVITY
288
+ accel_z = (raw_data [2 ] * self ._accel_scale ) * STANDARD_GRAVITY
291
289
return (accel_x , accel_y , accel_z )
292
290
293
291
@property
294
292
def gyro (self ) -> Tuple [float , float , float ]:
295
293
"""Gyroscope X, Y, and Z axis data in :math:`º/s`"""
296
294
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 ]
295
+ return self .scale_gyro ((raw_data [0 ][0 ], raw_data [1 ][0 ], raw_data [2 ][0 ]))
296
+
297
+ def scale_gyro (self , raw_data ) -> Tuple [float , float , float ]:
298
+ raw_x = raw_data [0 ]
299
+ raw_y = raw_data [1 ]
300
+ raw_z = raw_data [2 ]
300
301
301
302
gyro_scale = 1
302
303
gyro_range = self ._gyro_range
@@ -309,7 +310,7 @@ def gyro(self) -> Tuple[float, float, float]:
309
310
if gyro_range == GyroRange .RANGE_2000_DPS :
310
311
gyro_scale = 16.4
311
312
312
- # setup range dependant scaling
313
+ # setup range dependent scaling
313
314
gyro_x = radians (raw_x / gyro_scale )
314
315
gyro_y = radians (raw_y / gyro_scale )
315
316
gyro_z = radians (raw_z / gyro_scale )
@@ -349,6 +350,7 @@ def accelerometer_range(self, value: int) -> None:
349
350
if (value < 0 ) or (value > 3 ):
350
351
raise ValueError ("accelerometer_range must be a Range" )
351
352
self ._accel_range = value
353
+ self ._accel_scale = 1.0 / [16384 ,8192 ,4096 ,2048 ][value ]
352
354
sleep (0.01 )
353
355
354
356
@property
@@ -388,3 +390,13 @@ def clock_source(self, value: int) -> None:
388
390
"clock_source must be ClockSource value, integer from 0 - 7."
389
391
)
390
392
self ._clksel = value
393
+
394
+ def read_whole_fifo (self ):
395
+ """Return raw FIFO bytes"""
396
+ # This code must be fast to ensure samples are contiguous
397
+ c = self .fifo_count
398
+ buf = bytearray (c )
399
+ buf [0 ] = _MPU6050_FIFO_R_W
400
+ with self .i2c_device :
401
+ self .i2c_device .write_then_readinto (buf , buf , out_end = 1 , in_start = 0 )
402
+ return buf
0 commit comments