TOF sensors using Adafruit_VL53L0X - sensor no longer work

I March 2025 I last time worked on a little project that operated 5 TOF-sensors. Today I dealt again with it after updating the IDE and libraries. And after recompiling the project doesn’t provide the expected results. I suspect the Adafruit_VL53L0X library.
What has changed mainly is the Adafruit_VL53L0X library. I just updated the library not testing the program before and freezing the state of libraries used for the project last time it worked.

I first tried the latest Adafruit_VL53L0X (1.2.4) and after that was failing, I installed 1.2.2, the previous version, not being sure that this is the one the app was compiled with when it was last time working. I could well be, that it contains a programming bug that just reveils now. I’m posting the code FWIW below.

#include "Adafruit_VL53L0X.h"
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SH110X.h>

#define XSHUT_5 19
#define XSHUT_4 18
#define XSHUT_3 17
#define XSHUT_2 16
#define XSHUT_1 15

#define LX_ADDR_1 0x30
#define LX_ADDR_2 0x31
#define LX_ADDR_3 0x32
#define LX_ADDR_4 0x33
#define LX_ADDR_5 0x34

#define N_SENSORS 5
/* meine 5 Sensoren */
Adafruit_VL53L0X lox1 ;
Adafruit_VL53L0X lox2 ;
Adafruit_VL53L0X lox3 ;
Adafruit_VL53L0X lox4 ;
Adafruit_VL53L0X lox5 ;

struct {

Adafruit_VL53L0X *lox; // Sensor handle
uint8_t address;  // gewünschte Sensoradresse
uint8_t xshut_pin;// pin am ESP32 zum XSHUT
} lox[N_SENSORS]= {
{&lox1,LX_ADDR_1,XSHUT_1},
{&lox2,LX_ADDR_2,XSHUT_2},
{&lox3,LX_ADDR_3,XSHUT_3},
{&lox4,LX_ADDR_4,XSHUT_4},
{&lox5,LX_ADDR_5,XSHUT_5}
};

#define i2c_Address 0x3c //initialize with the I2C addr 0x3C Typically eBay OLED's
//#define i2c_Address 0x3d //initialize with the I2C addr 0x3D Typically Adafruit OLED's

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET -1   //   QT-PY / XIAO

Adafruit_SH1106G display = Adafruit_SH1106G(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
char str[128];

void setup() {
Serial.begin(115200);
int i,j;
// wait until serial port opens for native USB devices
while (! Serial) {
delay(1);
}

/* shut them all down */

Serial.println("Adafruit VL53L0X test - shutting down sensors");
for(i=0 ; i< N_SENSORS ;  i++) {
digitalWrite(lox[i].xshut_pin,0);
delay(10);
}

Serial.println(F("VL53L0X schalte Sensoren ein und setze Adresse\n\n"));

digitalWrite(XSHUT_1,1); // schalte Sensor ein
delay(10);

if (!lox1.begin(LX_ADDR_1)) { // setze Adresse und starte Sensor
Serial.println(F("Failed to boot VL53L0X 1"));
//while(1); /* hang here forever /
}
digitalWrite(XSHUT_2,1); // schalte Sensor ein
if (!lox2.begin(LX_ADDR_2)) { // setze Adresse und starte Sensor
Serial.println(F("Failed to boot VL53L0X 2"));
//while(1); / hang here forever /
}
digitalWrite(XSHUT_3,1); // schalte Sensor ein
if(!lox3.begin(LX_ADDR_3)) { // setze Adresse und starte Sensor
Serial.println(F("Failed to boot VL53L0X 3"));
//while(1); / hang here forever /
}
digitalWrite(XSHUT_4,1); // schalte Sensor ein
if(!lox4.begin(LX_ADDR_4)) { // setze Adresse und starte Sensor
Serial.println(F("Failed to boot VL53L0X 4"));
//while(1); / hang here forever /
}
digitalWrite(XSHUT_5,1); // schalte Sensor ein
if(!lox5.begin(LX_ADDR_5)) { // setze Adresse und starte Sensor
Serial.println(F("Failed to boot VL53L0X 5"));
//while(1); / hang here forever */
}
Serial.println("all sensors done...");
// power
Serial.println(F("VL53L0X Adressen initialisiert\n"));
delay(250); // wait for the OLED to power up
display.begin(i2c_Address, true); // Address 0x3C default
display.display();
delay(1000);
display.clearDisplay();
display.display();
}

void loop() {
VL53L0X_RangingMeasurementData_t measure1;
VL53L0X_RangingMeasurementData_t measure2;
VL53L0X_RangingMeasurementData_t measure3;
VL53L0X_RangingMeasurementData_t measure4;
VL53L0X_RangingMeasurementData_t measure5;
int i;
Serial.print("Reading a measurement...\n");
lox1.rangingTest(&measure1, false); // pass in 'true' to get debug data printout!
lox2.rangingTest(&measure2, false); // pass in 'true' to get debug data printout!
lox3.rangingTest(&measure3, false); // pass in 'true' to get debug data printout!
lox4.rangingTest(&measure4, false); // pass in 'true' to get debug data printout!
lox5.rangingTest(&measure5, false); // pass in 'true' to get debug data printout!

if (measure1.RangeStatus != 4) {  // phase failures have incorrect data



  display.setTextSize(1);
  display.setTextColor(SH110X_WHITE);
  display.setCursor(0, 0);
  display.fillRect(0,0,120,20,SH110X_BLACK);
  sprintf(str,"Abstand:  %04d mm",measure1.RangeMilliMeter);
  display.println(str);
  display.display();
  delay(100);
  } else {
  display.setTextSize(1);
  display.setTextColor(SH110X_WHITE);
  display.setCursor(0, 0);
  display.fillRect(0,0,120,20,SH110X_BLACK);
  sprintf(str,"Abstand:  ---- mm",measure1.RangeMilliMeter);
  display.println(str);
  display.display();
  delay(100);
  }

}

Program output:

Rebooting...

ets Jul 29 2019 12:21:46

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)

configsip: 0, SPIWP:0xee

clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00

mode:DIO, clock div:1

load:0x3fff0030,len:4980

load:0x40078000,len:16612

load:0x40080400,len:3500

entry 0x400805b4

Adafruit VL53L0X test - shut down

VL53L0X schalte Sensoren ein und setze Adresse

Guru Meditation Error: Core  1 panic'ed (LoadProhibited). Exception was unhandled.

Core  1 register dump:

PC      : 0x400f4eeb  PS      : 0x00060530  A0      : 0x800d48a4  A1      : 0x3ffc8310

A2      : 0x00000000  A3      : 0x0000008a  A4      : 0x3ffc833c  A5      : 0x00000001

A6      : 0x00000000  A7      : 0x00060023  A8      : 0x00060023  A9      : 0x3f40ce38

A10     : 0x3ffbe0b0  A11     : 0xffffffff  A12     : 0x80000020  A13     : 0x80000000

A14     : 0x00000001  A15     : 0x00000000  SAR     : 0x0000000f  EXCCAUSE: 0x0000001c

EXCVADDR: 0x00000000  LBEG    : 0x40085255  LEND    : 0x40085265  LCOUNT  : 0xffffffff

Backtrace: 0x400f4ee8:0x3ffc8310 0x400d48a1:0x3ffc8330 0x400d49a2:0x3ffc8360 0x400d2174:0x3ffc8380 0x400d1cd4:0x3ffc83a0 0x400d1b84:0x3ffc83c0 0x400da115:0x3ffc83f0 0x40088589:0x3ffc8410

ELF file SHA256: 66f74cff0

Please post code and text here according to forum standards. Helpers avoid downloading unknown material and the result is no replies to Your post.

could be a problem with ESP32 Migration from core 2.x to 3.xESP32 Migration from core 2.x to 3.x

try resetting the ESP32 core to 2.0.17?

try testing with just one sensor?

EDIT: ran a quick test using a ESP32 using Adafruit_VL53L0X library V1.2.4 ESP32 core
3.3.5

#include "Adafruit_VL53L0X.h"

Adafruit_VL53L0X lox = Adafruit_VL53L0X();

void setup() {
  Serial.begin(115200);

  // wait until serial port opens for native USB devices
  while (! Serial) {
    delay(1);
  }

  Serial.println("Adafruit VL53L0X test.");
  if (!lox.begin()) {
    Serial.println(F("Failed to boot VL53L0X"));
    while(1);
  }
  // power
  Serial.println(F("VL53L0X API Continuous Ranging example\n\n"));

  // start continuous ranging
  lox.startRangeContinuous();
}

void loop() {
  if (lox.isRangeComplete()) {
    Serial.print("Distance in mm: ");
    Serial.println(lox.readRange());
  }
  delay(1000);
}

serial monitor output

Adafruit VL53L0X test.
VL53L0X API Continuous Ranging example


Distance in mm: 9
Distance in mm: 10
Distance in mm: 2
Distance in mm: 189
Distance in mm: 167
Distance in mm: 187
Distance in mm: 214
Distance in mm: 236
Distance in mm: 263
Distance in mm: 287
Distance in mm: 281
Distance in mm: 231
Distance in mm: 251
Distance in mm: 317
Distance in mm: 328
Distance in mm: 322
Distance in mm: 312
Distance in mm: 292

Sorry for that. I hope, my corrections meet the posting standards now.

1 Like

How does one revert to a previous core? It doesn`t seem to be in libraries, is it?

Have you tried different code examples?
I used this about 2 weeks ago with a few VL53L0X modules on the same I2C bus for a ESP32-S3 and it worked fine. Considering that version 1.2.4 came our November 2023, I likely used the same version as you.

select Tools>Board then Board Manager then enter ESP32 and you should see

what core do you have installed?

however, the program of post 3 runs OK using a ESP32 using Adafruit_VL53L0X library V1.2.4 ESP32 core
3.3.5

1 Like

what has happened ? does not work at all? some sensors OK some wrong? all wrong?

1 Like

@Oblivionz Thanks for the code examples but they seem to be intended for an Arduino, not ESP32, at least when I look at the first example. They are talking about Interrupt pins etc.

I reverted to Esp 2.0.17 and the picture is different but still not functioning:

ets Jul 29 2019 12:21:46

rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)

configsip: 0, SPIWP:0xee

clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00

mode:DIO, clock div:1

load:0x3fff0030,len:1344

load:0x40078000,len:13964

load:0x40080400,len:3600

entry 0x400805f0

Adafruit VL53L0X test - shutting down sensors

VL53L0X schalte Sensoren ein und setze Adresse

Failed to boot VL53L0X 1

Failed to boot VL53L0X 2

Failed to boot VL53L0X 3

Failed to boot VL53L0X 4

Failed to boot VL53L0X 5

all sensors done...

VL53L0X Adressen initialisiert

Reading a measurement...

I’ll give up trying with all sorts of reverting to older versions and wil start piecewise from beginning. One single module first and then get on.

good idea!
if you have 5 VL53L0X are you using the XSHUT input to disable devices while you change I2C addresses?
I never used more than two VL53L0X and used XSHUT to disable one while I changed the I2C address of the other
also tested VL6180X and VL53L1X

Yes, I’ using - as can be seen in the posted project - the XSHUT input is used to shut down the respective devices.

I narrowed down the example to one device (on the breadboard) the devices are still daisy chained.

This is what the program outputs:

ets Jul 29 2019 12:21:46

rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)

configsip: 0, SPIWP:0xee

clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00

mode:DIO, clock div:1

load:0x3fff0030,len:4980

load:0x40078000,len:16612

load:0x40080400,len:3500

entry 0x400805b4

Adafruit VL53L0X test

VL53L0X Info:

Device Name: VL53L0X ES1 or later, Type: VL53L0X, ID: VL53L0CAV0DH/1$5

Rev Major: 1, Minor: 1

VL53L0X: StaticInit

VL53L0X: PerformRefSpadManagement

refSpadCount = 3, isApertureSpads = 0

VL53L0X Error: -6

Failed to boot VL53L0X

And this is the program itself:

#include "Adafruit_VL53L0X.h"
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SH110X.h>
#Adafruit_VL53L0X lox = Adafruit_VL53L0X();
#define i2c_Address 0x3c //initialize with the I2C addr 0x3C Typically eBay OLED's
//#define i2c_Address 0x3d //initialize with the I2C addr 0x3D Typically Adafruit OLED's

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

#define OLED_RESET -1 // QT-PY / XIAO

#define XSHUT_5 19
#define XSHUT_4 18
#define XSHUT_3 17
#define XSHUT_2 16
#define XSHUT_1 15

Adafruit_SH1106G display = Adafruit_SH1106G(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
char str[128];

void setup() {
Serial.begin(115200);
// wait until serial port opens for native USB devices

while (! Serial) {
delay(1);

}

digitalWrite(15,0);
delay(10);
digitalWrite(15,1);
Serial.println("Adafruit VL53L0X test");
if (!lox.begin(0x30,true)) {
Serial.println(F("Failed to boot VL53L0X"));

while(1);
}

// power
Serial.println(F("VL53L0X API Simple Ranging example\n\n"));
delay(250); // wait for the OLED to power up
display.begin(i2c_Address, true); // Address 0x3C default
display.display();
delay(1000);
display.clearDisplay();
sprintf(str,"VL53L0X API Simple Ranging example");
display.setTextSize(1);
display.setTextColor(SH110X_WHITE);
display.setCursor(0, 30);
display.println(str);
display.display();
}

void loop() {
VL53L0X_RangingMeasurementData_t measure;
Serial.print("Reading a measurement... ");
lox.rangingTest(&measure, true); // pass in 'true' to get debug data printout!

if (measure.RangeStatus != 4) { // phase failures have incorrect data
display.setTextSize(1);
display.setTextColor(SH110X_WHITE);
display.setCursor(0, 0);
display.fillRect(0,0,120,20,SH110X_BLACK);
sprintf(str,"Abstand: %04d mm",measure.RangeMilliMeter);
display.println(str);
display.display();
delay(100);
} else {
display.setTextSize(1);
display.setTextColor(SH110X_WHITE);
display.setCursor(0, 0);
display.fillRect(0,0,120,20,SH110X_BLACK);
sprintf(str,"Abstand: ---- mm",measure.RangeMilliMeter);
display.println(str);
display.display();
delay(100);
}
}

I tried the example (2 device initialization second example) from the site you gave the link to. It gives a compiling error.

/Users/me/Library/Arduino15/packages/esp32/tools/esp-x32/2511/bin/../lib/gcc/xtensa-esp-elf/14.2.0/../../../../xtensa-esp-elf/bin/ld: /Users/me/Library/Caches/arduino/cores/9888ff8ce85003010d2c07dcb96d0e00/core.a(main.cpp.o):(.literal._Z8loopTaskPv+0x8): undefined reference to _Z4loopv' /Users/me/Library/Arduino15/packages/esp32/tools/esp-x32/2511/bin/../lib/gcc/xtensa-esp-elf/14.2.0/../../../../xtensa-esp-elf/bin/ld: /Users/me/Library/Caches/arduino/cores/9888ff8ce85003010d2c07dcb96d0e00/core.a(main.cpp.o): in function _Z8loopTaskPv':
/Users/me/Library/Arduino15/packages/esp32/hardware/esp32/3.3.6/cores/esp32/main.cpp:71:(.text._Z8loopTaskPv+0x37): undefined reference to `_Z4loopv'
collect2: error: ld returned 1 exit status
exit status 1

Compilation error: exit status 1
/*
 * Ethan Zaitchik
 * VL53L0X Distance Sensor Basic Example
 * Full guide: https://zaitronics.com.au/blogs/guides/vl53l0x-time-of-flight-distance-sensor-advanced-guide
*/
#include "Adafruit_VL53L0X.h"
Adafruit_VL53L0X lox1;
Adafruit_VL53L0X lox2;

// Pin definitions
const byte XSHUT_1 = 15;  // XSHUT for first sensor
const byte XSHUT_2 = 16;  // XSHUT for second sensor

void setup() {
Serial.begin(115200);

  // Set both XSHUT pins as outputs and hold sensors in shutdown
pinMode(XSHUT_1, OUTPUT);
pinMode(XSHUT_2, OUTPUT);
digitalWrite(XSHUT_1, LOW);
digitalWrite(XSHUT_2, LOW);

  // Enable and configure first sensor with new address 0x30
digitalWrite(XSHUT_1, HIGH);
delay(10); // Small delay for sensor to wake up
if (!lox1.begin(0x30)) {
Serial.println("Failed to boot sensor 1");

while (1);
 }

// Enable and configure second sensor with new address 0x31
digitalWrite(XSHUT_2, HIGH);
delay(10);
if (!lox2.begin(0x31)) {
Serial.println("Failed to boot sensor 2");
while (1);
  }

Serial.println("Both sensors initialized with unique addresses!");
}

I assume you only have one VL53L0X connected to the I2C SCL and SDA GPIOs?

using IDE v2.3.4 ESP32 core 3.3.6 if I run the program of post 12 on an ESP32 with a VL53L0X I get (note I don't have a SH110X)

Adafruit VL53L0X test
VL53L0X Info:
Device Name: VL53L0X ES1 or later, Type: VL53L0X, ID: VL53L0CBV0DH/1$1
Rev Major: 1, Minor: 1
VL53L0X: StaticInit
VL53L0X: PerformRefSpadManagement
refSpadCount = 5, isApertureSpads = 1
VL53L0X: PerformRefCalibration
VL53L0X: SetDeviceMode
VL53L0X API Simple Ranging example


Reading a measurement... sVL53L0X: PerformSingleRangingMeasurement
Range Status: 0 : Range Valid
RANGE IGNORE THRESHOLD: 14.09
Measured distance: 246
Reading a measurement... sVL53L0X: PerformSingleRangingMeasurement
Range Status: 0 : Range Valid
RANGE IGNORE THRESHOLD: 14.02
Measured distance: 249
Reading a measurement... sVL53L0X: PerformSingleRangingMeasurement
Range Status: 0 : Range Valid
RANGE IGNORE THRESHOLD: 13.99
Measured distance: 249
Reading a measurement... sVL53L0X: PerformSingleRangingMeasurement
Range Status: 0 : Range Valid
RANGE IGNORE THRESHOLD: 13.60
Measured distance: 248
Reading a measurement... sVL53L0X: PerformSingleRangingMeasurement
Range Status: 0 : Range Valid
RANGE IGNORE THRESHOLD: 13.38
Measured distance: 251
Reading a measurement... sVL53L0X: PerformSingleRangingMeasurement
Range Status: 0 : Range Valid
RANGE IGNORE THRESHOLD: 10.73
Measured distance: 275
Reading a measurement... sVL53L0X: PerformSingleRangingMeasurement
Range Status: 0 : Range Valid
RANGE IGNORE THRESHOLD: 10.06
Measured distance: 283
Reading a measurement... sVL53L0X: PerformSingleRangingMeasurement
Range Status: 0 : Range Valid
RANGE IGNORE THRESHOLD: 9.59
Measured distance: 284

checking with a ruler the Measured distance: appears to be correct

you have a lot of devices attached to the ESP32 - could you be overloading the ESP32 3.3v supply?

Can you post back your program so I can try it out? I’m getting (yes, one device connected):

ets Jul 29 2019 12:21:46
rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:4980
load:0x40078000,len:16612
load:0x40080400,len:3500
entry 0x400805b4

Adafruit VL53L0X test

VL53L0X Info:
Device Name: VL53L0X ES1 or later, Type: VL53L0X, ID: VL53L0CAV0DH/1$5
Rev Major: 1, Minor: 1
VL53L0X: StaticInit
VL53L0X: PerformRefSpadManagement
refSpadCount = 3, isApertureSpads = 0
VL53L0X Error: -6

Failed to boot VL53L0X

The ESP32 is powered via the USB-C cable (5V) from a USB HUB which in turn get his supply from a wall outlet supply.

EDIT: I got one of my own examples working (with a single device). The behaviour is still a bit flakey. I found an article and a YT video saying that a delay(50) in the setup() section before the device is initialized could help. It seems that it worked.

void setup() {
   delay(50); // to avoid Error -6 (really?)
   Serial.begin(115200);