Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improvements on datarate, added dataReady function, fixed accelerometer and gyroscope divisor #20

Merged
merged 6 commits into from
Aug 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 34 additions & 5 deletions adafruit_icm20x.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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 (
Expand Down Expand Up @@ -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):
Expand All @@ -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
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand Down
9 changes: 9 additions & 0 deletions docs/examples.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
--------------------

Expand Down
36 changes: 36 additions & 0 deletions examples/icm20x_icm20649_data_rate_test.py
Original file line number Diff line number Diff line change
@@ -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
6 changes: 3 additions & 3 deletions examples/icm20x_icm20649_full_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -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])
Expand All @@ -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(
Expand Down
2 changes: 1 addition & 1 deletion examples/icm20x_icm20649_simpletest.py
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down