Skip to content

Added set_address function to allow use of multiple devices on one bus #3

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 9 commits into from
Mar 28, 2022
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
13 changes: 13 additions & 0 deletions adafruit_vl53l1x.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
# imports__version__ = "0.0.0-auto.0"
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_VL53L1X.git"

_VL53L1X_I2C_SLAVE_DEVICE_ADDRESS = const(0x0001)
_VL53L1X_VHV_CONFIG__TIMEOUT_MACROP_LOOP_BOUND = const(0x0008)
_GPIO_HV_MUX__CTRL = const(0x0030)
_GPIO__TIO_HV_STATUS = const(0x0031)
Expand Down Expand Up @@ -77,6 +78,7 @@ class VL53L1X:

def __init__(self, i2c, address=41):
self.i2c_device = i2c_device.I2CDevice(i2c, address)
self._i2c = i2c
model_id, module_type, mask_rev = self.model_info
if model_id != 0xEA or module_type != 0xCC or mask_rev != 0x10:
raise RuntimeError("Wrong sensor ID or type!")
Expand Down Expand Up @@ -301,3 +303,14 @@ def _read_register(self, address, length=1):
i2c.write(struct.pack(">H", address))
i2c.readinto(data)
return data

def set_address(self, new_address):
"""
Set a new I2C address to the instantaited object. This is only called when using
multiple VL53L0X sensors on the same I2C bus (SDA & SCL pins). See also the
`example <examples.html#multiple-vl53l1x-on-same-i2c-bus>`_ for proper usage.
"""
self._write_register(
_VL53L1X_I2C_SLAVE_DEVICE_ADDRESS, struct.pack(">B", new_address)
)
self.i2c_device = i2c_device.I2CDevice(self._i2c, new_address)
73 changes: 73 additions & 0 deletions examples/vl53l1x_multiple_on_same_i2c_bus.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# SPDX-FileCopyrightText: 2022 wrdaigle for Adafruit Industries
#
# SPDX-License-Identifier: MIT

"""
Example of how to use the adafruit_vl53l1x library to change the assigned address of
multiple VL53L1X sensors on the same I2C bus. This example only focuses on 2 VL53L1X
sensors, but can be modified for more. BE AWARE: a multitude of sensors may require
more current than the on-board 3V regulator can output (typical current consumption during
active range readings is about 19 mA per sensor).
"""
import time
import board
from digitalio import DigitalInOut
from adafruit_vl53l1x import VL53L1X

# declare the singleton variable for the default I2C bus
i2c = board.I2C()

# declare the digital output pins connected to the "SHDN" pin on each VL53L1X sensor
xshut = [
DigitalInOut(board.D16),
DigitalInOut(board.D17),
# add more VL53L1X sensors by defining their SHDN pins here
]

for power_pin in xshut:
# make sure these pins are a digital output, not a digital input
power_pin.switch_to_output(value=False)
# These pins are active when Low, meaning:
# if the output signal is LOW, then the VL53L1X sensor is off.
# if the output signal is HIGH, then the VL53L1X sensor is on.
# all VL53L1X sensors are now off

# initialize a list to be used for the array of VL53L1X sensors
vl53 = []

# now change the addresses of the VL53L1X sensors
for i, power_pin in enumerate(xshut):
# turn on the VL53L1X to allow hardware check
power_pin.value = True
# instantiate the VL53L1X sensor on the I2C bus & insert it into the "vl53" list
vl53.insert(i, VL53L1X(i2c)) # also performs VL53L1X hardware check
# no need to change the address of the last VL53L1X sensor
if i < len(xshut) - 1:
# default address is 0x29. Change that to something else
vl53[i].set_address(i + 0x30) # address assigned should NOT be already in use
# there is a helpful list of pre-designated I2C addresses for various I2C devices at
# https://learn.adafruit.com/i2c-addresses/the-list
# According to this list 0x30-0x34 are available, although the list may be incomplete.
# In the python REPR, you can scan for all I2C devices that are attached and detirmine
# their addresses using:
# >>> import board
# >>> i2c = board.I2C()
# >>> if i2c.try_lock():
# >>> [hex(x) for x in i2c.scan()]
# >>> i2c.unlock()


def detect_range(count=5):
""" take count=5 samples """
while count:
for index, sensor in enumerate(vl53):
print("Sensor {} Range: {}mm".format(index + 1, sensor.distance))
time.sleep(1.0)
count -= 1


detect_range()
print(
"Multiple VL53L1X sensors' addresses are assigned properly\n"
"execute detect_range() to read each sensors range readings"
)