diff --git a/adafruit_icm20x.py b/adafruit_icm20x.py index e6a951d..32f5bec 100644 --- a/adafruit_icm20x.py +++ b/adafruit_icm20x.py @@ -60,6 +60,15 @@ _ICM20X_REG_INT_ENABLE_0 = 0x10 # Interrupt enable register 0 _ICM20X_REG_INT_ENABLE_1 = 0x11 # Interrupt enable register 1 +_ICM20X_REG_INT_STATUS_0 = ( + 0x19 # Interrupt status register 0 Wake on motion, DMP int, i2c int +) +_ICM20X_REG_INT_STATUS_1 = ( + 0x1A # Interrupt status register 1 data register from all sensors +) +_ICM20X_REG_INT_STATUS_2 = 0x1B # Interrupt status register 2 FIFO overflow +_ICM20X_REG_INT_STATUS_3 = 0x1C # Interrupt status register 3 Watermark interrupt + # Bank 2 _ICM20X_GYRO_SMPLRT_DIV = 0x00 _ICM20X_GYRO_CONFIG_1 = 0x01 @@ -159,6 +168,8 @@ class ICM20X: # pylint:disable=too-many-instance-attributes _lp_config_reg = UnaryStruct(_ICM20X_LP_CONFIG, ">B") + _data_ready = ROBit(_ICM20X_REG_INT_STATUS_1, 0) + _i2c_master_cycle_en = RWBit(_ICM20X_LP_CONFIG, 6) _accel_cycle_en = RWBit(_ICM20X_LP_CONFIG, 5) _gyro_cycle_en = RWBit(_ICM20X_LP_CONFIG, 4) @@ -237,6 +248,8 @@ def initialize(self): self.accelerometer_data_rate_divisor = 20 # ~53.57Hz self.gyro_data_rate_divisor = 10 # ~100Hz + self._gravity = G_TO_ACCEL + def reset(self): """Resets the internal registers and restores the default settings""" self._bank = 0 @@ -247,6 +260,11 @@ def reset(self): while self._reset: sleep(0.005) + def data_ready(self): + """Checks if new data is available""" + self._bank = 0 + return self._data_ready + @property def _sleep(self): self._bank = 0 @@ -286,7 +304,9 @@ def gyro(self): return (x, y, z) def _scale_xl_data(self, raw_measurement): - return raw_measurement / AccelRange.lsb[self._cached_accel_range] * G_TO_ACCEL + return ( + raw_measurement / AccelRange.lsb[self._cached_accel_range] * self._gravity + ) def _scale_gyro_data(self, raw_measurement): return ( @@ -422,7 +442,8 @@ def accelerometer_data_rate(self, value): raise AttributeError( "Accelerometer data rate must be between 0.27 and 1125.0" ) - self.accelerometer_data_rate_divisor = value + divisor = round(((1125.0 - value) / value)) + self.accelerometer_data_rate_divisor = divisor @property def gyro_data_rate(self): @@ -445,8 +466,7 @@ def gyro_data_rate(self): def gyro_data_rate(self, value): if value < self._gyro_rate_calc(4095) or value > self._gyro_rate_calc(0): raise AttributeError("Gyro data rate must be between 4.30 and 1100.0") - - divisor = round(((1125.0 - value) / value)) + divisor = round(((1100.0 - value) / value)) self.gyro_data_rate_divisor = divisor @property @@ -511,6 +531,15 @@ def _low_power(self, enabled): self._bank = 0 self._low_power_en = enabled + @property + def gravity(self): + """The gravity magnitude in m/s^2.""" + return self._gravity + + @gravity.setter + def gravity(self, value): + self._gravity = value + class ICM20649(ICM20X): """Library for the ST ICM-20649 Wide-Range 6-DoF Accelerometer and Gyro. @@ -740,7 +769,7 @@ def _mag_id(self): @property def magnetic(self): - """The current magnetic field strengths onthe X, Y, and Z axes in uT (micro-teslas)""" + """The current magnetic field strengths on the X, Y, and Z axes in uT (micro-teslas)""" self._bank = 0 full_data = self._raw_mag_data diff --git a/docs/examples.rst b/docs/examples.rst index 6bf07fe..8d2ed7c 100644 --- a/docs/examples.rst +++ b/docs/examples.rst @@ -16,6 +16,15 @@ Test using all the ICM20649 sensor capabilities :caption: examples/examples/icm20x_icm20649_full_test.py :linenos: +ICM20649 data rate test +----------------------- + +Test using all the ICM20649 sensor capabilities + +.. literalinclude:: ../examples/icm20x_icm20649_data_rate_test.py + :caption: examples/examples/icm20x_icm20649_data_rate_test.py + :linenos: + ICM20948 Simple test -------------------- diff --git a/examples/icm20x_icm20649_data_rate_test.py b/examples/icm20x_icm20649_data_rate_test.py new file mode 100644 index 0000000..3102732 --- /dev/null +++ b/examples/icm20x_icm20649_data_rate_test.py @@ -0,0 +1,36 @@ +# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries +# SPDX-License-Identifier: MIT + +import time +import board +from adafruit_icm20x import ICM20649, AccelRange, GyroRange + +i2c = board.I2C() # uses board.SCL and board.SDA + +ism = ICM20649(i2c, address=0x69) + +ism.accelerometer_range = AccelRange.RANGE_4G +print("Accelerometer range set to: %d g" % AccelRange.string[ism.accelerometer_range]) + +ism.gyro_range = GyroRange.RANGE_500_DPS +print("Gyro range set to: %d DPS" % GyroRange.string[ism.gyro_range]) + +ism.gyro_data_rate = 1100 # 1100 max +ism.accelerometer_data_rate = 1125 # 1125 max + +print("Gyro rate: {:f}".format(ism.gyro_data_rate)) +print("Accel rate: {:f}".format(ism.accelerometer_data_rate)) + +ism.gravity = 9.8 + +previousTime = time.perf_counter() +while True: + if ism.data_ready: + currentTime = time.perf_counter() + print("\033[2J") + print( + "Accel X:%5.2f Y:%5.2f Z:%5.2f ms^2 " + "Gyro X:%8.3f Y:%8.3f Z:%8.3f degrees/s Sample Rate: %8.1f Hz" + % (*ism.acceleration, *ism.gyro, (1 / (currentTime - previousTime))) + ) + previousTime = currentTime diff --git a/examples/icm20x_icm20649_full_test.py b/examples/icm20x_icm20649_full_test.py index 60f4392..3a0ef1f 100644 --- a/examples/icm20x_icm20649_full_test.py +++ b/examples/icm20x_icm20649_full_test.py @@ -17,7 +17,7 @@ def printNewMax(value, current_max, axis): i2c = board.I2C() # uses board.SCL and board.SDA # i2c = board.STEMMA_I2C() # For using the built-in STEMMA QT connector on a microcontroller -ism = ICM20649(i2c) +ism = ICM20649(i2c, address=0x69) ism.accelerometer_range = AccelRange.RANGE_30G print("Accelerometer range set to: %d g" % AccelRange.string[ism.accelerometer_range]) @@ -28,8 +28,8 @@ def printNewMax(value, current_max, axis): ax_max = ay_max = az_max = 0 gx_max = gy_max = gz_max = 0 -ism.gyro_data_rate = 125 -ism.accelerometer_data_rate = 4095 +ism.gyro_data_rate = 1100 +ism.accelerometer_data_rate = 1125 st = time.monotonic() while time.monotonic() - st < 0.250: print( diff --git a/examples/icm20x_icm20649_simpletest.py b/examples/icm20x_icm20649_simpletest.py index b3582ad..f6a259a 100644 --- a/examples/icm20x_icm20649_simpletest.py +++ b/examples/icm20x_icm20649_simpletest.py @@ -7,7 +7,7 @@ i2c = board.I2C() # uses board.SCL and board.SDA # i2c = board.STEMMA_I2C() # For using the built-in STEMMA QT connector on a microcontroller -icm = adafruit_icm20x.ICM20649(i2c) +icm = adafruit_icm20x.ICM20649(i2c, address=0x69) while True: print("Acceleration: X:%.2f, Y: %.2f, Z: %.2f m/s^2" % (icm.acceleration))