Using multiple VL53L1X sensors at the same time (Python)
This tutorial will show you how you can use multiple VL53L1X sensors at the same time. This makes sense because the I2C bus is used for communication. You will learn how to change the I2C address so that several sensors do not use the same address.
It is assumed that you have already read Distance measurement with ToF sensor VL53L1X (Python), Speed measurement with ToF sensor VL53L1X (Python) and Writing your VL53L1X driver (Python).
There are two variants of how we implement this. The Raspberry Pi can also implement a second I2C bus, this could look like this:
In my approach, both VL53L1X sensors are connected to an I2C hub. I connect the XSHUT of one sensor to GPIO 25 (pin 22) and the XSHUT of the other sensor to GPIO 12 (pin 32).
If I want to use more sensors accordingly, then I also have to connect multiple XSHUTs to the Raspberry Pi. This principle can be scaled accordingly.
For each sensor I first switch the XSHUT to LOW, this means that the sensor goes off. Then I switch on a sensor and change its I2C address. After that I switch on the next sensor and change its I2C address as well. I can proceed until I have changed the I2C address of all sensors. Theoretically I can leave the I2C standard address at my last sensor. What does not work is to switch on a second sensor before changing the I2C address of the first sensor. Again, the I2C conflict would remain and you don't know which sensor to communicate with.
If you switch off a sensor after changing its address and switch it on again, the sensor will get its default address again. That means we only switch off all sensors at the beginning and then we switch them all on one after the other and change their address.
An example code for two sensors looks like this:
import VL53L1X import RPi.GPIO as GPIO import time XSHUT1 = 25 XSHUT2 = 12 GPIO.setwarnings(False) GPIO.setmode(GPIO.BCM) GPIO.setup(XSHUT1, GPIO.OUT) GPIO.setup(XSHUT2, GPIO.OUT) GPIO.output(XSHUT1, False) GPIO.output(XSHUT2, False) GPIO.output(XSHUT1, True) tof1 = VL53L1X.VL53L1X(i2c_bus=1, i2c_address=0x29) tof1.open() tof1.change_address(new_address = 0x28) tof1.open() GPIO.output(XSHUT2, True) tof2 = VL53L1X.VL53L1X(i2c_bus=1, i2c_address=0x29) tof2.open() tof2.change_address(new_address = 0x2a) tof2.open()
We can now subsequently write a service that performs this assignment of the new addresses when our Raspberry Pi starts up. This is recommended so that we do not have another I2C address conflict after a reboot. Furthermore it is recommended so that we also assign the same addresses each time. When using our drive we don't want to change the parameters for the address every time. Furthermore we can make sure that we don't mix up the address of both sensors by mistake. The service could look like this:
[Unit] Description=vl53l1x addresses service After=network.target [Service] ExecStart=sh -c "/usr/bin/python3 -u vl53l1x_i2c_fix.py" WorkingDirectory=/home/pi StandardOutput=inherit StandardError=inherit Restart=always User=pi [Install] WantedBy=multi-user.target