Skip to content

Commit 5c398a8

Browse files
authored
Merge pull request #3 from wrdaigle/main
Added set_address function to allow use of multiple devices on one bus
2 parents 0378767 + eff8538 commit 5c398a8

File tree

2 files changed

+86
-0
lines changed

2 files changed

+86
-0
lines changed

adafruit_vl53l1x.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
# imports__version__ = "0.0.0-auto.0"
3535
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_VL53L1X.git"
3636

37+
_VL53L1X_I2C_SLAVE_DEVICE_ADDRESS = const(0x0001)
3738
_VL53L1X_VHV_CONFIG__TIMEOUT_MACROP_LOOP_BOUND = const(0x0008)
3839
_GPIO_HV_MUX__CTRL = const(0x0030)
3940
_GPIO__TIO_HV_STATUS = const(0x0031)
@@ -77,6 +78,7 @@ class VL53L1X:
7778

7879
def __init__(self, i2c, address=41):
7980
self.i2c_device = i2c_device.I2CDevice(i2c, address)
81+
self._i2c = i2c
8082
model_id, module_type, mask_rev = self.model_info
8183
if model_id != 0xEA or module_type != 0xCC or mask_rev != 0x10:
8284
raise RuntimeError("Wrong sensor ID or type!")
@@ -301,3 +303,14 @@ def _read_register(self, address, length=1):
301303
i2c.write(struct.pack(">H", address))
302304
i2c.readinto(data)
303305
return data
306+
307+
def set_address(self, new_address):
308+
"""
309+
Set a new I2C address to the instantaited object. This is only called when using
310+
multiple VL53L0X sensors on the same I2C bus (SDA & SCL pins). See also the
311+
`example <examples.html#multiple-vl53l1x-on-same-i2c-bus>`_ for proper usage.
312+
"""
313+
self._write_register(
314+
_VL53L1X_I2C_SLAVE_DEVICE_ADDRESS, struct.pack(">B", new_address)
315+
)
316+
self.i2c_device = i2c_device.I2CDevice(self._i2c, new_address)
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# SPDX-FileCopyrightText: 2022 wrdaigle for Adafruit Industries
2+
#
3+
# SPDX-License-Identifier: MIT
4+
5+
"""
6+
Example of how to use the adafruit_vl53l1x library to change the assigned address of
7+
multiple VL53L1X sensors on the same I2C bus. This example only focuses on 2 VL53L1X
8+
sensors, but can be modified for more. BE AWARE: a multitude of sensors may require
9+
more current than the on-board 3V regulator can output (typical current consumption during
10+
active range readings is about 19 mA per sensor).
11+
"""
12+
import time
13+
import board
14+
from digitalio import DigitalInOut
15+
from adafruit_vl53l1x import VL53L1X
16+
17+
# declare the singleton variable for the default I2C bus
18+
i2c = board.I2C()
19+
20+
# declare the digital output pins connected to the "SHDN" pin on each VL53L1X sensor
21+
xshut = [
22+
DigitalInOut(board.D16),
23+
DigitalInOut(board.D17),
24+
# add more VL53L1X sensors by defining their SHDN pins here
25+
]
26+
27+
for power_pin in xshut:
28+
# make sure these pins are a digital output, not a digital input
29+
power_pin.switch_to_output(value=False)
30+
# These pins are active when Low, meaning:
31+
# if the output signal is LOW, then the VL53L1X sensor is off.
32+
# if the output signal is HIGH, then the VL53L1X sensor is on.
33+
# all VL53L1X sensors are now off
34+
35+
# initialize a list to be used for the array of VL53L1X sensors
36+
vl53 = []
37+
38+
# now change the addresses of the VL53L1X sensors
39+
for i, power_pin in enumerate(xshut):
40+
# turn on the VL53L1X to allow hardware check
41+
power_pin.value = True
42+
# instantiate the VL53L1X sensor on the I2C bus & insert it into the "vl53" list
43+
vl53.insert(i, VL53L1X(i2c)) # also performs VL53L1X hardware check
44+
# no need to change the address of the last VL53L1X sensor
45+
if i < len(xshut) - 1:
46+
# default address is 0x29. Change that to something else
47+
vl53[i].set_address(i + 0x30) # address assigned should NOT be already in use
48+
# there is a helpful list of pre-designated I2C addresses for various I2C devices at
49+
# https://learn.adafruit.com/i2c-addresses/the-list
50+
# According to this list 0x30-0x34 are available, although the list may be incomplete.
51+
# In the python REPR, you can scan for all I2C devices that are attached and detirmine
52+
# their addresses using:
53+
# >>> import board
54+
# >>> i2c = board.I2C()
55+
# >>> if i2c.try_lock():
56+
# >>> [hex(x) for x in i2c.scan()]
57+
# >>> i2c.unlock()
58+
59+
60+
def detect_range(count=5):
61+
""" take count=5 samples """
62+
while count:
63+
for index, sensor in enumerate(vl53):
64+
print("Sensor {} Range: {}mm".format(index + 1, sensor.distance))
65+
time.sleep(1.0)
66+
count -= 1
67+
68+
69+
detect_range()
70+
print(
71+
"Multiple VL53L1X sensors' addresses are assigned properly\n"
72+
"execute detect_range() to read each sensors range readings"
73+
)

0 commit comments

Comments
 (0)