Skip to content

Lsm6ds refactor #2

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

Merged
merged 7 commits into from
Jan 15, 2020
Merged
Show file tree
Hide file tree
Changes from 5 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
4 changes: 2 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,11 @@ Usage Example
import time
import board
import busio
import adafruit_lsm6dsox
import adafruit_lsm6ds

i2c = busio.I2C(board.SCL, board.SDA)

sox = adafruit_lsm6dsox.LSM6DSOX(i2c)
sox = adafruit_lsm6ds.LSM6DSOX(i2c)

while True:
print("Acceleration: X:%.2f, Y: %.2f, Z: %.2f m/s^2"%(sox.acceleration))
Expand Down
229 changes: 131 additions & 98 deletions adafruit_lsm6dsox.py → adafruit_lsm6ds.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
"""
`adafruit_lsm6dsox`
`adafruit_lsm6ds`
================================================================================

CircuitPython library for the ST LSM6DSOX 6-axis Accelerometer and Gyro
Expand Down Expand Up @@ -58,35 +58,36 @@
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_LSM6DSOX.git"


_LSM6DSOX_DEFAULT_ADDRESS = const(0x6a)
_LSM6DSOX_CHIP_ID = const(0x6C)
_ISM330DHCX_CHIP_ID = const(0x6B)


_LSM6DSOX_FUNC_CFG_ACCESS = const(0x1)
_LSM6DSOX_PIN_CTRL = const(0x2)
_LSM6DSOX_UI_INT_OIS = const(0x6F)
_LSM6DSOX_WHOAMI = const(0xF)
_LSM6DSOX_CTRL1_XL = const(0x10)
_LSM6DSOX_CTRL2_G = const(0x11)
_LSM6DSOX_CTRL3_C = const(0x12)
_LSM6DSOX_CTRL_5_C = const(0x14)
_LSM6DSOX_MASTER_CONFIG = const(0x14)
_LSM6DSOX_CTRL9_XL = const(0x18)
_LSM6DSOX_OUT_TEMP_L = const(0x20)
_LSM6DSOX_OUT_TEMP_H = const(0x21)
_LSM6DSOX_OUTX_L_G = const(0x22)
_LSM6DSOX_OUTX_H_G = const(0x23)
_LSM6DSOX_OUTY_L_G = const(0x24)
_LSM6DSOX_OUTY_H_G = const(0x25)
_LSM6DSOX_OUTZ_L_G = const(0x26)
_LSM6DSOX_OUTZ_H_G = const(0x27)
_LSM6DSOX_OUTX_L_A = const(0x28)
_LSM6DSOX_OUTX_H_A = const(0x29)
_LSM6DSOX_OUTY_L_A = const(0x2A)
_LSM6DSOX_OUTY_H_A = const(0x2B)
_LSM6DSOX_OUTZ_L_A = const(0x2C)
_LSM6DSOX_OUTZ_H_A = const(0x2D)
_LSM6DS_DEFAULT_ADDRESS = const(0x6a)

_LSM6DS_CHIP_ID = const(0x6C)
_ISM330DHCT_CHIP_ID = const(0x6B)
_LSM6DS33_CHIP_ID = const(0x69)

_LSM6DS_FUNC_CFG_ACCESS = const(0x1)
_LSM6DS_PIN_CTRL = const(0x2)
_LSM6DS_UI_INT_OIS = const(0x6F)
_LSM6DS_WHOAMI = const(0xF)
_LSM6DS_CTRL1_XL = const(0x10)
_LSM6DS_CTRL2_G = const(0x11)
_LSM6DS_CTRL3_C = const(0x12)
_LSM6DS_CTRL_5_C = const(0x14)
_LSM6DS_MASTER_CONFIG = const(0x14)
_LSM6DS_CTRL9_XL = const(0x18)
_LSM6DS_OUT_TEMP_L = const(0x20)
_LSM6DS_OUT_TEMP_H = const(0x21)
_LSM6DS_OUTX_L_G = const(0x22)
_LSM6DS_OUTX_H_G = const(0x23)
_LSM6DS_OUTY_L_G = const(0x24)
_LSM6DS_OUTY_H_G = const(0x25)
_LSM6DS_OUTZ_L_G = const(0x26)
_LSM6DS_OUTZ_H_G = const(0x27)
_LSM6DS_OUTX_L_A = const(0x28)
_LSM6DS_OUTX_H_A = const(0x29)
_LSM6DS_OUTY_L_A = const(0x2A)
_LSM6DS_OUTY_H_A = const(0x2B)
_LSM6DS_OUTZ_L_A = const(0x2C)
_LSM6DS_OUTZ_H_A = const(0x2D)

_MILLI_G_TO_ACCEL = 0.00980665

Expand Down Expand Up @@ -153,7 +154,8 @@ class Rate(CV):
('RATE_1_6_HZ', 11, 1.6, None)
))

class LSM6DSOX: #pylint: disable=too-many-instance-attributes

class LSM6DS: #pylint: disable=too-many-instance-attributes

"""Driver for the LSM6DSOX 6-axis accelerometer and gyroscope.

Expand All @@ -163,74 +165,73 @@ class LSM6DSOX: #pylint: disable=too-many-instance-attributes
"""

#ROUnaryStructs:
_chip_id = ROUnaryStruct(_LSM6DSOX_WHOAMI, "<b")
_temperature = ROUnaryStruct(_LSM6DSOX_OUT_TEMP_L, "<h")
_chip_id = ROUnaryStruct(_LSM6DS_WHOAMI, "<b")
_temperature = ROUnaryStruct(_LSM6DS_OUT_TEMP_L, "<h")

#RWBits:
_ois_ctrl_from_ui = RWBit(_LSM6DSOX_FUNC_CFG_ACCESS, 0)
_shub_reg_access = RWBit(_LSM6DSOX_FUNC_CFG_ACCESS, 6)
_func_cfg_access = RWBit(_LSM6DSOX_FUNC_CFG_ACCESS, 7)
_sdo_pu_en = RWBit(_LSM6DSOX_PIN_CTRL, 6)
_ois_pu_dis = RWBit(_LSM6DSOX_PIN_CTRL, 7)
_spi2_read_en = RWBit(_LSM6DSOX_UI_INT_OIS, 3)
_den_lh_ois = RWBit(_LSM6DSOX_UI_INT_OIS, 5)
_lvl2_ois = RWBit(_LSM6DSOX_UI_INT_OIS, 6)
_int2_drdy_ois = RWBit(_LSM6DSOX_UI_INT_OIS, 7)
_lpf_xl = RWBit(_LSM6DSOX_CTRL1_XL, 1)

_accel_range = RWBits(2, _LSM6DSOX_CTRL1_XL, 2)
_accel_data_rate = RWBits(4, _LSM6DSOX_CTRL1_XL, 4)

_gyro_data_rate = RWBits(4, _LSM6DSOX_CTRL2_G, 4)
_gyro_range = RWBits(2, _LSM6DSOX_CTRL2_G, 2)
_gyro_range_125dps = RWBit(_LSM6DSOX_CTRL2_G, 1)

_sw_reset = RWBit(_LSM6DSOX_CTRL3_C, 0)
_if_inc = RWBit(_LSM6DSOX_CTRL3_C, 2)
_sim = RWBit(_LSM6DSOX_CTRL3_C, 3)
_pp_od = RWBit(_LSM6DSOX_CTRL3_C, 4)
_h_lactive = RWBit(_LSM6DSOX_CTRL3_C, 5)
_bdu = RWBit(_LSM6DSOX_CTRL3_C, 6)
_boot = RWBit(_LSM6DSOX_CTRL3_C, 7)
_st_xl = RWBits(2, _LSM6DSOX_CTRL_5_C, 0)
_st_g = RWBits(2, _LSM6DSOX_CTRL_5_C, 2)
_rounding_status = RWBit(_LSM6DSOX_CTRL_5_C, 4)
_rounding = RWBits(2, _LSM6DSOX_CTRL_5_C, 5)
_xl_ulp_en = RWBit(_LSM6DSOX_CTRL_5_C, 7)
_aux_sens_on = RWBits(2, _LSM6DSOX_MASTER_CONFIG, 0)
_master_on = RWBit(_LSM6DSOX_MASTER_CONFIG, 2)
_shub_pu_en = RWBit(_LSM6DSOX_MASTER_CONFIG, 3)
_pass_through_mode = RWBit(_LSM6DSOX_MASTER_CONFIG, 4)
_start_config = RWBit(_LSM6DSOX_MASTER_CONFIG, 5)
_write_once = RWBit(_LSM6DSOX_MASTER_CONFIG, 6)
_rst_master_regs = RWBit(_LSM6DSOX_MASTER_CONFIG, 7)
_i3c_disable = RWBit(_LSM6DSOX_CTRL9_XL, 1)

_raw_temp = ROUnaryStruct(_LSM6DSOX_OUT_TEMP_L, "<h")

_raw_accel_data = Struct(_LSM6DSOX_OUTX_L_A, "<hhh")
_raw_gyro_data = Struct(_LSM6DSOX_OUTX_L_G, "<hhh")

def __init__(self, i2c_bus, address=_LSM6DSOX_DEFAULT_ADDRESS):
_ois_ctrl_from_ui = RWBit(_LSM6DS_FUNC_CFG_ACCESS, 0)
_shub_reg_access = RWBit(_LSM6DS_FUNC_CFG_ACCESS, 6)
_func_cfg_access = RWBit(_LSM6DS_FUNC_CFG_ACCESS, 7)
_sdo_pu_en = RWBit(_LSM6DS_PIN_CTRL, 6)
_ois_pu_dis = RWBit(_LSM6DS_PIN_CTRL, 7)
_spi2_read_en = RWBit(_LSM6DS_UI_INT_OIS, 3)
_den_lh_ois = RWBit(_LSM6DS_UI_INT_OIS, 5)
_lvl2_ois = RWBit(_LSM6DS_UI_INT_OIS, 6)
_int2_drdy_ois = RWBit(_LSM6DS_UI_INT_OIS, 7)
_lpf_xl = RWBit(_LSM6DS_CTRL1_XL, 1)

_accel_range = RWBits(2, _LSM6DS_CTRL1_XL, 2)
_accel_data_rate = RWBits(4, _LSM6DS_CTRL1_XL, 4)

_gyro_data_rate = RWBits(4, _LSM6DS_CTRL2_G, 4)
_gyro_range = RWBits(2, _LSM6DS_CTRL2_G, 2)
_gyro_range_125dps = RWBit(_LSM6DS_CTRL2_G, 1)
_gyro_range_4000dps = RWBit(_LSM6DS_CTRL2_G, 0)

_sw_reset = RWBit(_LSM6DS_CTRL3_C, 0)
_sim = RWBit(_LSM6DS_CTRL3_C, 3)
_pp_od = RWBit(_LSM6DS_CTRL3_C, 4)
_h_lactive = RWBit(_LSM6DS_CTRL3_C, 5)
_bdu = RWBit(_LSM6DS_CTRL3_C, 6)
_boot = RWBit(_LSM6DS_CTRL3_C, 7)
_st_xl = RWBits(2, _LSM6DS_CTRL_5_C, 0)
_st_g = RWBits(2, _LSM6DS_CTRL_5_C, 2)
_rounding_status = RWBit(_LSM6DS_CTRL_5_C, 4)
_rounding = RWBits(2, _LSM6DS_CTRL_5_C, 5)
_xl_ulp_en = RWBit(_LSM6DS_CTRL_5_C, 7)
_aux_sens_on = RWBits(2, _LSM6DS_MASTER_CONFIG, 0)
_master_on = RWBit(_LSM6DS_MASTER_CONFIG, 2)
_shub_pu_en = RWBit(_LSM6DS_MASTER_CONFIG, 3)
_pass_through_mode = RWBit(_LSM6DS_MASTER_CONFIG, 4)
_start_config = RWBit(_LSM6DS_MASTER_CONFIG, 5)
_write_once = RWBit(_LSM6DS_MASTER_CONFIG, 6)
_rst_master_regs = RWBit(_LSM6DS_MASTER_CONFIG, 7)
_i3c_disable = RWBit(_LSM6DS_CTRL9_XL, 1)

_raw_temp = ROUnaryStruct(_LSM6DS_OUT_TEMP_L, "<h")

_raw_accel_data = Struct(_LSM6DS_OUTX_L_A, "<hhh")
_raw_gyro_data = Struct(_LSM6DS_OUTX_L_G, "<hhh")
CHIP_ID = None
def __init__(self, i2c_bus, address=_LSM6DS_DEFAULT_ADDRESS):
self.i2c_device = i2c_device.I2CDevice(i2c_bus, address)

if self._chip_id not in [_LSM6DSOX_CHIP_ID, _ISM330DHCX_CHIP_ID]:
raise RuntimeError("Failed to find LSM6DSOX or ISM330DHCX - check your wiring!")
if self.CHIP_ID is None:
raise AttributeError("LSM6DS Parent Class cannot be directly instantiated")
if self._chip_id != self.CHIP_ID:
raise RuntimeError("Failed to find %s - check your wiring!"%self.__class__.__name__)
self.reset()

self._bdu = True
self._i3c_disable = True
self._if_inc = True

self._accel_data_rate = Rate.RATE_104_HZ #pylint: disable=no-member
self._gyro_data_rate = Rate.RATE_104_HZ #pylint: disable=no-member
self.accelerometer_data_rate = Rate.RATE_104_HZ #pylint: disable=no-member
self.gyro_data_rate = Rate.RATE_104_HZ #pylint: disable=no-member

self.accelerometer_range = AccelRange.RANGE_4G #pylint: disable=no-member
self.gyro_range = GyroRange.RANGE_250_DPS #pylint: disable=no-member

self._accel_range = AccelRange.RANGE_4G #pylint: disable=no-member
self._cached_accel_range = self._accel_range
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this line here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I usually have lines like these to set the default values to something more useful, though 250dps should change then as it's already the default.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

self._cached_accel_range = self._accel_range
should be handled within the property/setter right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, you're right. I misunderstood

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pylint just reminded me that it doesn't like when you do that because it ends up getting defined outside of __init__
image

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

set it to None at the top of init

self._gyro_range = GyroRange.RANGE_250_DPS #pylint: disable=no-member
self._cached_gyro_range = self._gyro_range
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto



def reset(self):
"Resets the sensor's configuration into an initial state"
self._sw_reset = True
Expand All @@ -240,12 +241,6 @@ def reset(self):
while self._boot:
sleep(0.001)

@property
def is_lsm6dsox(self):
"""Returns `True` if the connected sensor is an LSM6DSOX,
`False` if not, it's an ICM330DHCX"""
return self._chip_id is _LSM6DSOX_CHIP_ID

@property
def acceleration(self):
"""The x, y, z acceleration values returned in a 3-tuple and are in m / s ^ 2."""
Expand Down Expand Up @@ -291,15 +286,15 @@ def accelerometer_range(self, value):
def gyro_range(self):
"""Adjusts the range of values that the sensor can measure, from 125 Degrees/second to 4000
degrees/s. Note that larger ranges will be less accurate. Must be a `GyroRange`. 4000 DPS
is only available for the ISM330DHCX"""
is only available for the ISM330DHCT"""
return self._cached_gyro_range

@gyro_range.setter
def gyro_range(self, value):
if not GyroRange.is_valid(value):
raise AttributeError("range must be a `GyroRange`")
if value is GyroRange.RANGE_4000_DPS and self.is_lsm6dsox:
raise AttributeError("4000 DPS is only available for ISM330DHCX")
if value is GyroRange.RANGE_4000_DPS and not isinstance(self, ISM330DHCT):
raise AttributeError("4000 DPS is only available for ISM330DHCT")

if value is GyroRange.RANGE_125_DPS:
self._gyro_range_125dps = True
Expand All @@ -309,7 +304,7 @@ def gyro_range(self, value):
self._gyro_range_4000dps = True
else:
self._gyro_range_125dps = False
self._gyro_range_4000dps = True
self._gyro_range_4000dps = False
self._gyro_range = value

self._cached_gyro_range = value
Expand Down Expand Up @@ -344,3 +339,41 @@ def gyro_data_rate(self, value):

self._gyro_data_rate = value
# sleep(.2) # needed to let new range settle

class LSM6DSOX(LSM6DS): #pylint: disable=too-many-instance-attributes

"""Driver for the LSM6DSOX 6-axis accelerometer and gyroscope.

:param ~busio.I2C i2c_bus: The I2C bus the LSM6DSOX is connected to.
:param address: The I2C slave address of the sensor

"""
CHIP_ID = _LSM6DS_CHIP_ID
def __init__(self, i2c_bus, address=_LSM6DS_DEFAULT_ADDRESS):
super().__init__(i2c_bus, address)
self._i3c_disable = True

class LSM6DS33(LSM6DS): #pylint: disable=too-many-instance-attributes

"""Driver for the LSM6DS33 6-axis accelerometer and gyroscope.

:param ~busio.I2C i2c_bus: The I2C bus the LSM6DS33 is connected to.
:param address: The I2C slave address of the sensor

"""
CHIP_ID = _LSM6DS33_CHIP_ID

class ISM330DHCT(LSM6DS): #pylint: disable=too-many-instance-attributes

"""Driver for the LSM6DS33 6-axis accelerometer and gyroscope.

:param ~busio.I2C i2c_bus: The I2C bus the LSM6DS33 is connected to.
:param address: The I2C slave address of the sensor

"""
CHIP_ID = _ISM330DHCT_CHIP_ID
def __init__(self, i2c_bus, address=_LSM6DS_DEFAULT_ADDRESS):
super().__init__(i2c_bus, address)

# Called DEVICE_CONF in the datasheet, but it recommends setting it
self._i3c_disable = True
2 changes: 1 addition & 1 deletion docs/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@
.. If your library file(s) are nested in a directory (e.g. /adafruit_foo/foo.py)
.. use this format as the module name: "adafruit_foo.foo"

.. automodule:: adafruit_lsm6dsox
.. automodule:: adafruit_lsm6ds
:members:
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
# Uncomment the below if you use native CircuitPython modules such as
# digitalio, micropython and busio. List the modules you use. Without it, the
# autodoc module docs will fail to generate with a warning.
# autodoc_mock_imports = ["digitalio", "busio"]
autodoc_mock_imports = ["micropython", "adafruit_bus_device", "adafruit_register"]


intersphinx_mapping = {'python': ('https://docs.python.org/3.4', None),'BusDevice': ('https://circuitpython.readthedocs.io/projects/busdevice/en/latest/', None),'Register': ('https://circuitpython.readthedocs.io/projects/register/en/latest/', None),'CircuitPython': ('https://circuitpython.readthedocs.io/en/latest/', None)}
Expand Down
14 changes: 14 additions & 0 deletions examples/ism330dhct_simpletest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import time
import board
import busio
from adafruit_lsm6ds import ISM330DHCT

i2c = busio.I2C(board.SCL, board.SDA)

sensor = ISM330DHCT(i2c)

while True:
print("Acceleration: X:%.2f, Y: %.2f, Z: %.2f m/s^2"%(sensor.acceleration))
print("Gyro X:%.2f, Y: %.2f, Z: %.2f degrees/s"%(sensor.gyro))
print("")
time.sleep(0.5)
14 changes: 14 additions & 0 deletions examples/lsm6ds33_simpletest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import time
import board
import busio
from adafruit_lsm6ds import LSM6DS33

i2c = busio.I2C(board.SCL, board.SDA)

sensor = LSM6DS33(i2c)

while True:
print("Acceleration: X:%.2f, Y: %.2f, Z: %.2f m/s^2"%(sensor.acceleration))
print("Gyro X:%.2f, Y: %.2f, Z: %.2f degrees/s"%(sensor.gyro))
print("")
time.sleep(0.5)
29 changes: 29 additions & 0 deletions examples/lsm6ds_full_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import time
import board
import busio
#pylint:disable=no-member,unused-import
from adafruit_lsm6ds import LSM6DS33, LSM6DSOX, ISM330DHCT, Rate, AccelRange, GyroRange

i2c = busio.I2C(board.SCL, board.SDA)

sensor = LSM6DS33(i2c)
#sensor = LSM6DSOX(i2c)
#sensor = ISM330DHCT(i2c)

sensor.accelerometer_range = AccelRange.RANGE_8G
print("Accelerometer range set to: %d G"%AccelRange.string[sensor.accelerometer_range])

sensor.gyro_range = GyroRange.RANGE_2000_DPS
print("Gyro range set to: %d DPS"%GyroRange.string[sensor.gyro_range])

sensor.accelerometer_data_rate = Rate.RATE_1_66K_HZ
#sensor.accelerometer_data_rate = Rate.RATE_12_5_HZ
print("Accelerometer rate set to: %d HZ"%Rate.string[sensor.accelerometer_data_rate])

sensor.gyro_data_rate = Rate.RATE_1_66K_HZ
print("Gyro rate set to: %d HZ"%Rate.string[sensor.gyro_data_rate])

while True:
print("Accel X:%.2f Y:%.2f Z:%.2f ms^2 Gyro X:%.2f Y:%.2f Z:%.2f degrees/s"%
(sensor.acceleration+sensor.gyro))
time.sleep(0.05)
Loading