Skip to content

Commit 82a66fc

Browse files
committed
added data rate property for mag
1 parent 2aca353 commit 82a66fc

File tree

2 files changed

+81
-11
lines changed

2 files changed

+81
-11
lines changed

adafruit_icm20x.py

Lines changed: 59 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,7 @@ def __init__(self, i2c_bus, address):
245245

246246
def initialize(self):
247247
"""Configure the sensors with the default settings. For use after calling `reset()`"""
248+
248249
self._bank = 0
249250
sleep(0.005)
250251
self._sleep = False
@@ -253,6 +254,7 @@ def initialize(self):
253254
self.accelerometer_range = AccelRange.RANGE_8G # pylint: disable=no-member
254255
self.gyro_range = GyroRange.RANGE_500_DPS # pylint: disable=no-member
255256

257+
# TODO: Test these
256258
self.accelerometer_data_rate_divisor = 20 # ~53.57Hz
257259
self.gyro_data_rate_divisor = 10 # ~100Hz
258260

@@ -416,7 +418,6 @@ def gyro_data_rate(self):
416418
417419
Note: The data rates are set indirectly by setting a rate divisor according to the
418420
following formula: ``gyro_data_rate = 1100/(1+divisor)``
419-
420421
This function does the math to find the divisor from a given rate but it will not
421422
be exactly as specified.
422423
"""
@@ -518,6 +519,27 @@ def __init__(self, i2c_bus, address=_ICM20649_DEFAULT_ADDRESS):
518519
super().__init__(i2c_bus, address)
519520

520521

522+
# https://www.y-ic.es/datasheet/78/SMDSW.020-2OZ.pdf page 19
523+
_AK09916_WIA1 = 0x00
524+
_AK09916_WIA2 = 0x01
525+
_AK09916_ST1 = 0x10
526+
_AK09916_HXL = 0x11
527+
_AK09916_HXH = 0x12
528+
_AK09916_HYL = 0x13
529+
_AK09916_HYH = 0x14
530+
_AK09916_HZL = 0x15
531+
_AK09916_HZH = 0x16
532+
_AK09916_ST2 = 0x18
533+
_AK09916_CNTL2 = 0x31
534+
_AK09916_CNTL3 = 0x32
535+
536+
537+
class MagDataRate(CV):
538+
"""Options for ``magnetometer_data_rate``"""
539+
540+
pass # pylint: disable=unnecessary-pass
541+
542+
521543
class ICM20948(ICM20X): # pylint:disable=too-many-instance-attributes
522544
"""Library for the ST ICM-20948 Wide-Range 6-DoF Accelerometer and Gyro.
523545
@@ -563,6 +585,18 @@ def __init__(self, i2c_bus, address=_ICM20948_DEFAULT_ADDRESS):
563585
("RANGE_2000_DPS", 3, 2000, 16.4),
564586
)
565587
)
588+
589+
# https://www.y-ic.es/datasheet/78/SMDSW.020-2OZ.pdf page 9
590+
MagDataRate.add_values(
591+
(
592+
("SHUTDOWN", 0x0, "Shutdown", None),
593+
("SINGLE", 0x1, "Single", None),
594+
("RATE_10HZ", 0x2, 10, None),
595+
("RATE_20HZ", 0x4, 20, None),
596+
("RATE_50HZ", 0x6, 50, None),
597+
("RATE_100HZ", 0x8, 100, None),
598+
)
599+
)
566600
super().__init__(i2c_bus, address)
567601
self._magnetometer_init()
568602

@@ -600,18 +634,11 @@ def _magnetometer_enable(self):
600634
self._i2c_master_enable = True
601635
sleep(0.020)
602636

603-
def _set_mag_data_rate(self, data_rate=0x08):
604-
# https://www.y-ic.es/datasheet/78/SMDSW.020-2OZ.pdf page 9
605-
# set the magnetometer data rate
606-
# 0x1 = 10hz Continuous measurement mode 1
607-
# 0x2 = 20hz Continuous measurement mode 2
608-
# 0x4 = 50hz Continuous measurement mode 3
609-
# 0x8 = 100hz Continuous measurement mode 4
610-
self._write_mag_register(0x31, data_rate)
611-
612637
def _magnetometer_init(self):
613638
self._magnetometer_enable()
614-
self._set_mag_data_rate()
639+
self.magnetometer_data_rate = (
640+
MagDataRate.RATE_100HZ # pylint: disable=no-member
641+
)
615642

616643
if not self._mag_configured:
617644
return False
@@ -647,6 +674,27 @@ def magnetic(self):
647674

648675
return (x, y, z)
649676

677+
@property
678+
def magnetometer_data_rate(self):
679+
"""The rate at which the magenetometer takes measurements to update its output registers"""
680+
# read mag DR register
681+
self._read_mag_register(_AK09916_CNTL2)
682+
683+
@magnetometer_data_rate.setter
684+
def magnetometer_data_rate(self, mag_rate):
685+
# From https://www.y-ic.es/datasheet/78/SMDSW.020-2OZ.pdf page 9
686+
687+
# "When user wants to change operation mode, transit to Power-down mode first and then
688+
# transit to other modes. After Power-down mode is set, at least 100 microsectons (Twait)
689+
# is needed before setting another mode"
690+
if not MagDataRate.is_valid(mag_rate):
691+
raise AttributeError("range must be an `MagDataRate`")
692+
self._write_mag_register(
693+
_AK09916_CNTL2, MagDataRate.SHUTDOWN # pylint: disable=no-member
694+
)
695+
sleep(0.001)
696+
self._write_mag_register(_AK09916_CNTL2, mag_rate)
697+
650698
def _read_mag_register(self, register_addr, slave_addr=0x0C):
651699
self._bank = 3
652700

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import time
2+
import board
3+
import busio
4+
from adafruit_icm20x import MagDataRate, ICM20948
5+
6+
cycles = 200
7+
i2c = busio.I2C(board.SCL, board.SDA)
8+
icm = ICM20948(i2c)
9+
10+
icm.accelerometer_data_rate_divisor = 0
11+
# Cycle between two data rates
12+
# Best viewed in the Mu serial plotter where you can see how
13+
# the data rate affects the resolution of the data
14+
while True:
15+
icm.magnetometer_data_rate = MagDataRate.RATE_100HZ
16+
for i in range(cycles):
17+
print(icm.magnetic)
18+
time.sleep(0.3)
19+
icm.magnetometer_data_rate = MagDataRate.RATE_10HZ
20+
for i in range(cycles):
21+
print(icm.magnetic)
22+
time.sleep(0.3)

0 commit comments

Comments
 (0)