diff --git a/adafruit_vl53l1x.py b/adafruit_vl53l1x.py index dba0c9f..e48f08a 100644 --- a/adafruit_vl53l1x.py +++ b/adafruit_vl53l1x.py @@ -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) @@ -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!") @@ -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 `_ 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) diff --git a/examples/vl53l1x_multiple_on_same_i2c_bus.py b/examples/vl53l1x_multiple_on_same_i2c_bus.py new file mode 100644 index 0000000..fd42fd4 --- /dev/null +++ b/examples/vl53l1x_multiple_on_same_i2c_bus.py @@ -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" +)