VL53L5CX address changes not working.
I am trying to run multiple VL53L5CX-TOF-sensors with a single Pi Pico to be able to stitch together multiple of the sensor images.However for this to work I have to change the i2c addresses of the sensors.
I am trying to use the set_i2c_address function for this.
I have read the steps from the usage guide about enabling/disabling additional sensors on the same i2c bus via the LPn pin but whenever I try to call the set_i2c_address even with just a single sensor connected I get RuntimeError: VL53L5CX: set_i2c_address error.
Currently I am using the Pimoroni Firmware that provides a driver accessible via micropython that just calls the ULD firmware / driver for the VL53L5CX.
I am not sure if something about my approach/order is wrong or if there might be an issue with the ULD driver itself.
I would greatly appreciate any help/advise. This is the code I am currently using:
import pimoroni_i2c
import breakout_vl53l5cx
import time
from time import sleep
import machine
PIN_CONFIG_1 = {"sda": 6, "scl": 7}
#The following 2 lines are necessary if LPN is connected to the sensor.
#When there is no connection between a GPIO and LPN of the sensor this and the following line are not required.
#LPN would be needed to activate/decactivate when there are multiple devices on one i2c bus.
lpn_pin = machine.Pin(10, machine.Pin.OUT)
lpn_pin.value(1) # Enable sensor_1
time.sleep(3) #wait a long duration in case the sensor takes a long time to start.
i2c_1 = pimoroni_i2c.PimoroniI2C(**PIN_CONFIG_1, baudrate=400_000) #same error with baud rate at 100k, 400k and 2_000k
print("I2C_1 devices found:", i2c_1.scan())
# Initialize sensor_1 with default address
sensor_1 = breakout_vl53l5cx.VL53L5CX(i2c_1)
# Change to a new 7-bit address (e.g., 0x2A)
new_i2c_address_7bit = 0x09 # Valid 7-bit address (0x00 to 0x7F)
sensor_1.set_i2c_address(new_i2c_address_7bit) #this always throws the error.
# Verify address change
print("Scanning I2C after address change:", i2c_1.scan())
# Continue with configuration...
sensor_1.set_resolution(breakout_vl53l5cx.RESOLUTION_8X8)
sensor_1.set_ranging_frequency_hz(30)
sensor_1.start_ranging()
while True:
if sensor_1.data_ready():
avg_distance_1 = sensor_1.get_data().distance_avg
avg_reflectance_1 = sensor_1.get_data().reflectance_avg
print(f"Sensor 1 Avg Distance: {avg_distance_1:.2f} mm, Avg Reflectance: {avg_reflectance_1:.2f}")
sleep(1)
Edit: As I thought my issue might lie with the fact that I initialize the sensor before attempting to change the address I implemented the set_i2c_address function myself now using the ULD driver as inspiration. However even with this the address doesn't seem to get changed and stays at 0x52 (0x29 as a 7 bit due to the bitshift or 41 in decimal):
MPY: soft reboot
Available i2c before attempting address change [41]
Tried to change I2C address from 41 to 32
Available i2c after address change [41]
Available i2c devices after attempting address change [41]
Traceback (most recent call last):
File "<stdin>", line 44, in <module>
RuntimeError: VL53L5CX: init error
This is the code I used for the approach to change the address before initializing the sensor:
import pimoroni_i2c
import time
import machine
import breakout_vl53l5cx
# Function to change the I2C address
def vl53l5cx_set_i2c_address(i2c, old_address, new_address):
i2c.writeto_mem(old_address, 0x7fff, bytes([0x00]))
time.sleep(1)
i2c.writeto_mem(old_address, 0x04, bytes([(new_address << 1)]))
time.sleep(1)
i2c.writeto_mem(old_address, 0x7fff, bytes([0x02])) #I believe this might need to be new_address but that results in [Errno 5] EIO as the address isn't actually changed before.
time.sleep(1)
print(f"Tried to change I2C address from {old_address} to {new_address}")
print("Available i2c after address change", i2c_1.scan())
# Configuration
PIN_CONFIG_1 = {"sda": 6, "scl": 7}
#The following 2 lines are necessary if LPN is connected to the sensor.
#When there is no connection between a GPIO and LPN of the sensor this and the following line are not required.
#LPN would be needed to activate/decactivate when there are multiple devices on one i2c bus.
lpn_pin = machine.Pin(10, machine.Pin.OUT)
lpn_pin.value(1) # Enable sensor_1
time.sleep(3) #wait a long duration in case the sensor takes a long time to start.
i2c_1 = pimoroni_i2c.PimoroniI2C(**PIN_CONFIG_1, baudrate=2_000_000)
default_address = 0x29 # default 7 bit address, shifted from 0x52, is 41 in decimal.
new_i2c_address_7bit = 0x20 # Example: new address
print("Available i2c before attempting address change", i2c_1.scan())
# Change the I2C address BEFORE initializing the sensor
vl53l5cx_set_i2c_address(i2c_1, default_address, new_i2c_address_7bit)
print("Available i2c devices after attempting address change", i2c_1.scan())
# Initialize the sensor with the new address
sensor_1 = breakout_vl53l5cx.VL53L5CX(i2c_1, new_i2c_address_7bit )
# this fails to initialize. Makes sense as the address wasn't changed. When using default_address here it still connects to the sensor just fine.
# Verify address change
print("Scanning I2C after address change:", i2c_1.scan())
# Continue with sensor configuration
sensor_1.set_resolution(breakout_vl53l5cx.RESOLUTION_8X8)
sensor_1.set_ranging_frequency_hz(30)
sensor_1.start_ranging()
while True:
if sensor_1.data_ready():
data = sensor_1.get_data()
avg_distance_1 = data.distance_avg
avg_reflectance_1 = data.reflectance_avg
print(f"Sensor 1 Avg Distance: {avg_distance_1:.2f} mm, Avg Reflectance: {avg_reflectance_1:.2f}")
time.sleep(1)
I would really appreciate any hints to what I am doing wrong.
