Skip to content

added ability to use multiple VL53L0X on the same I2C bus #12

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 3 commits into from
Jan 30, 2020
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
17 changes: 17 additions & 0 deletions adafruit_vl53l0x.py
Original file line number Diff line number Diff line change
Expand Up @@ -453,3 +453,20 @@ def range(self):
range_mm = self._read_u16(_RESULT_RANGE_STATUS + 10)
self._write_u8(_SYSTEM_INTERRUPT_CLEAR, 0x01)
return range_mm

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-vl53l0x-on-same-i2c-bus>`_ for proper usage.

:param int new_address: The 7-bit `int` that is to be assigned to the VL53L0X sensor.
The address that is assigned should NOT be already in use by another device on the
I2C bus.

.. important:: To properly set the address to an individual VL53L0X sensor, you must
first ensure that all other VL53L0X sensors (using the default address of ``0x29``)
on the same I2C bus are in their off state by pulling the "SHDN" pins LOW. When the
"SHDN" pin is pulled HIGH again the default I2C address is ``0x29``.
"""
self._write_u8(_I2C_SLAVE_DEVICE_ADDRESS, new_address & 0x7f)
self._device.device_address = new_address
9 changes: 9 additions & 0 deletions docs/examples.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,12 @@ Ensure your device works with this simple test.
.. literalinclude:: ../examples/vl53l0x_simpletest.py
:caption: examples/vl53l0x_simpletest.py
:linenos:

Multiple VL53L0X on Same I2C Bus
--------------------------------

Copy "../examples/vl53l0x_multiple_sensors.py" to your "CIRCUITPY" drive, then run the script with ``from vl53l0x_multiple_sensors import *``

.. literalinclude:: ../examples/vl53l0x_multiple_sensors.py
:caption: examples/vl53l0x_multiple_sensors.py
:linenos:
64 changes: 64 additions & 0 deletions examples/vl53l0x_multiple_sensors.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
"""
Example of how to use the adafruit_vl53l0x library to change the assigned address of
multiple VL53L0X sensors on the same I2C bus. This example only focuses on 2 VL53L0X
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_vl53l0x import VL53L0X

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

# declare the digital output pins connected to the "SHDN" pin on each VL53L0X sensor
xshut = [
DigitalInOut(board.D7),
DigitalInOut(board.D9),
# add more VL53L0X 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 VL53L0X sensor is off.
# if the output signal is HIGH, then the VL53L0X sensor is on.
# all VL53L0X sensors are now off

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

# now change the addresses of the VL53L0X sensors
for i, power_pin in enumerate(xshut):
# turn on the VL53L0X to allow hardware check
power_pin.value = True
# instantiate the VL53L0X sensor on the I2C bus & insert it into the "vl53" list
vl53.insert(i, VL53L0X(i2c)) # also performs VL53L0X hardware check
# no need to change the address of the last VL53L0X 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.range))
time.sleep(1.0)
count -= 1

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