ESP32 + 2x VL53L8CX with 50 cm cables — I²C/initialization issues, with and without TCA9548A multiplexer
Edit: I just effectively measured the cables, and they’re are 1.2m, not 50cm, I dont know where I got that number.
I have been sitting on this issue for a long while, trying to fix it, so it is a long post. Please bear with me.
Hardware setup
The system is based on an ESP32 WT32-ETH01 connected to two ST VL53L8CX ToF sensors (aliexpress pcb).
The main hardware configuration is:
* ESP32 WT32-ETH01
* 2x VL53L8CX
* Sensors have both NCS and SPI_I2C_N connected to GND
* TCA9548A I²C multiplexer
* 3.3 V supply for esp, sensors and multiplexer (Variable regulated DC power supply 1.2A max and 3.3v)
* I²C SDA: GPIO 32
* I²C SCL: GPIO 33
* Separate LPN control for each sensor
* Approximately 1.2m of multi conductor shielded cable between the controller and the sensors (also tried with ethernet cable)
* No Cable shield connected
The sensors work correctly when tested individually (with both long or short cables) and also worked together when using short cables. Also using one long cable connected to one sensor and a short one connected to the second. The problems start appearing when the cable length is increased and when both sensors are connected.
Firmware
The firmware is developed using PlatformIO with the Arduino framework on ESP32. The VL53L8CX is controlled using ST's VL53L8CX library. The firmware initializes the sensors individually using their LPN pins and assigns different I²C addresses.
The basic initialization sequence is:
Select TCA9548A channel, when the multiplexer is used.
Initialize the sensor.
Set the I²C address.(when no multiplexer is used)
Configure ranging.
Start ranging.
Retrieve measurements continuously.
The I²C bus was initially configured at 400 kHz. I also tested 100 kHz and 50khz to determine whether reducing the bus speed would improve communication reliability. Did not see any difference.
Initial tests — sensors individually
With the short jumpers, both sensors initialize correctly and are able to perform ranging.
I also tested each physical sensor separately, so I was able to confirm that the problem is not simply a defective sensor (apparently).
The same sensors that fail in the complete setup work correctly when tested individually.
Effect of cable length
The first major issue appeared after replacing the short connections with approximately 1.2m cables.
The failures include I²C communication errors, unsuccessful sensor initialization, failed ranging startup.
I think I may be dealing with an I²C signal integrity but that is just a guess, and I would like to confirm whether there are other VL53L8CX-specific considerations.
Two sensors without the TCA9548A
Most of my tests was on a setup without the TCA9548A.
The two sensors are controlled using their LPN pins so that they can be initialized separately and assigned different I²C addresses.
On my setup I use 5 wires for each sensor (VCC, GND, SDA, SCL and LPN). Even only one any wire of from the second long cable made the system start to pop errors while initializing the first sensor (both are first disabled then each one is turned on and changed the address).
Two sensors with the TCA9548A
I then added a TCA9548A I²C multiplexer, with each VL53L8CX connected to a separate multiplexer channel.
I tried the multiplexer, with expectation that I would be avoiding having both sensors directly on the same I²C bus.
I tested the sensors individually through the multiplexer as well as with both sensors connected.
I am still seeing communication/initialization problems when using the longer cables.
Observed I²C errors
Some of the errors observed during testing include:
requestFrom(): i2cWriteReadNonStop returned Error -1
and:
requestFrom(): i2cWriteReadNonStop returned Error 263
The behavior is not completely deterministic, which is another reason I suspect an electrical/signal-integrity issue.
Electrical measurements
I checked the power supply and wiring with a multimeter.
ESP, the sensors and mux receive approximately 3.3 V from DC power supply. On the current setup I'm not using the 3.3v from esp to supply the sensors, but I have tried supplying 5v from the DC power supply to the esp and esp supplying the 3.3v to the sensors. No noticeable difference.
I also checked continuity of the longer cables and confirmed that the individual wires are connected correctly.
Some resistance measurements on the I²C lines were also performed, including measurements between SDA/SCL, SDA/3.3 V, and SDA/GND.
Questions
I would appreciate some guidance on the following points:
Is approximately 1.2m of cable considered too long for the VL53L8CX I²C interface?
Any idea on what could be causing issues when both sensors are connected with longer cables?
Are there recommended SDA/SCL pull-up resistor values for longer cables?
Does reducing the I²C frequency could have any impact on helping communication for this cable length?
Are there specific recommendations for cable type or shielding when connecting the VL53L8CX remotely?
Are there recommended decoupling capacitors to place directly near each VL53L8CX?
Is using a TCA9548A a recommended approach for two VL53L8CX sensors with longer cables?
Could the observed initialization errors be caused by signal integrity issues on the I²C bus?
Are there any specific hardware or firmware recommendations for using multiple VL53L8CX sensors with approximately 1.2m cables? My goal is to use 3 VL53L8CX but right now I only have 2. I assumed that even with 3 sensors, I would not need a mux, but right now I'm accepting any strategies or suggestions.
This is the log that I get from using 2 sensors, same firmware (not even uploading anything), but changing the second sensor cable from 15cm jumpers to a 1.2m Ethernet cable with jumpers on the ends.
I’m doing I2C scans before and after initializing, then data being received from both sensors. Don’t mind the data itself, as it is being modified by the code.
Sensor 1 with 1.2cm cable and Sensor 2 with 15cm jumpers:
Channel 0
I2C Scan
Found device at 0x29
Found device at 0x70
Scan complete
Channel 1
I2C Scan
Found device at 0x29
Found device at 0x70
Scan complete
Initializing sensor VL8-0
Status begin 0
Status init 0
OK set_resolution = 64
OK set_ranging_frequency_hz = 1
OK set_ranging_mode = 1
OK set_sharpener_percent = 99
OK set_target_order = 1
OK VL8-0 After start_ranging status=0
Initializing sensor VL8-1
Status begin 0
Status init 0
OK set_resolution = 64
OK set_ranging_frequency_hz = 1
OK set_ranging_mode = 1
OK set_sharpener_percent = 99
OK set_target_order = 1
OK VL8-1 After start_ranging status=0
Channel 0
I2C Scan
Found device at 0x29
Found device at 0x70
Scan complete
Channel 1
I2C Scan
Found device at 0x29
Found device at 0x70
Scan complete
DATA0:65535,0,0,65535,65535,0,0,0,65535,65535,65535,65535,65535,0,0,0,65535,65535,65535,65535,65535,65535,0,0,65535,65535,65535,65535,65535,0,0,0,0,65535,65535,65535,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65535,65535,0,0,0,0
MEAN0:24575
DATA1:65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535
MEAN1:65535
DATA0:65535,0,0,65535,65535,0,0,0,65535,65535,65535,65535,65535,0,0,0,65535,65535,65535,65535,65535,65535,0,0,65535,65535,65535,65535,65535,0,0,0,0,65535,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
MEAN0:20479
DATA1:65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535
MEAN1:65535
...
Sensor 1 with 1.2m cable and Sensor 2 with 1.2m cable:
Channel 0
I2C Scan
Found device at 0x29
Found device at 0x70
Scan complete
Channel 1
I2C Scan
Found device at 0x29
Found device at 0x70
Scan complete
Initializing sensor VL8-0
Status begin 0
Status init 0
OK set_resolution = 64
OK set_ranging_frequency_hz = 1
OK set_ranging_mode = 1
OK set_sharpener_percent = 99
OK set_target_order = 1
OK VL8-0 After start_ranging status=0
Initializing sensor VL8-1
Status begin 0
[ 12109][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error -1
[ 12216][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error -1
[ 12253][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error -1
[ 12270][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error -1
[ 12317][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error -1
[ 12434][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error -1
[ 12471][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error -1
[ 12538][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error -1
[ 13775][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error 263
...Variation 1:
...
Status begin 0
Status init 2
[ 12276][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error -1
[ 13612][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error 263
[ 13662][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error -1
[ 15229][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error 263
[ 16532][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error 263
[ 16867][E][Wire.cpp:499] requestFrom(): i2cWriteReadNonStop returned Error -1
...Variation 2:
Status begin 0
Status init 5
FAIL set_resolution = 64
FAIL set_ranging_frequency_hz = 1Variation 3 (there were errors on initialization - init 5, start_ranging 255, but it got to receiving data, but only from the first sensor Data0 and Mean0):
...
Initializing sensor VL8-1
Status begin 0
Status init 5
OK set_resolution = 64
OK set_ranging_frequency_hz = 1
OK set_ranging_mode = 1
OK set_sharpener_percent = 99
OK set_target_order = 1
FAIL VL8-1 After start_ranging status=255
Channel 0
I2C Scan
Found device at 0x29
Found device at 0x70
Scan complete
Channel 1
I2C Scan
Found device at 0x29
Found device at 0x70
Scan complete
DATA0:65535,65535,0,65535,0,0,0,0,65535,65535,65535,0,0,0,0,0,0,65535,65535,0,0,0,0,65535,65535,65535,0,65535,65535,0,0,0,0,65535,65535,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65535,0,0,0,0,0,0,0,0,0
MEAN0:16383
DATA0:65535,65535,0,65535,0,0,0,0,65535,65535,65535,0,0,0,0,0,0,65535,65535,0,0,0,0,65535,65535,65535,0,65535,65535,0,0,0,0,0,65535,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65535,0,0,0,0,0,0,0,0,0
MEAN0:15359
...
