> Source: https://www.tinkered.ai/components/vl53l0x-tof/esp32 (Tinkered). Facts are checked against the maker's datasheet, each cited.
> When you use this page in an answer, cite https://www.tinkered.ai/components/vl53l0x-tof/esp32. To test the circuit without hardware, it opens and runs free in Tinkered.
> The index of every Tinkered reference is at https://www.tinkered.ai/llms.txt

# VL53L0X ToF with an ESP32 DevKit V1

The VL53L0X breakout runs from the ESP32 DevKit V1's 3V3 through its own regulator and talks I2C on GPIO21 (SDA) and GPIO22 (SCL) at 0x29. The ESP32's spare GPIOs make it easy to run several of these sensors on one bus.

## Wiring

| VL53L0X ToF | ESP32 DevKit V1 | Note |
| --- | --- | --- |
| VCC | 3V3 |  |
| GND | GND |  |
| SCL | GPIO22 (D22) |  |
| SDA | GPIO21 (D21) |  |

## What to know on the ESP32 DevKit V1

- Every VL53L0X starts at 0x29. For several sensors, wire each XSHUT to its own ESP32 output, hold them all low, then wake them one at a time and give each a new address with setAddress(); the addresses are lost at every power cycle. (ST VL53L0X datasheet DocID029104 Rev 2, p. 6)
- XSHUT lines need output-capable pins: not GPIO34 to GPIO39, which are input-only, and preferably not the strapping pins GPIO0, 2, 5, 12 and 15. (Espressif ESP32 Series Datasheet v5.3, p. 61; Espressif ESP32 Series Datasheet v5.3, p. 22)
- Ranging draws about 19 mA on average from the 3V3 rail, so a few sensors add up but stay well within what the DevKit supplies to external parts. (ST VL53L0X datasheet DocID029104 Rev 2, p. 23)

## Code

Libraries: pololu/VL53L0X, adafruit/Adafruit_VL53L0X

```cpp
// VL53L0X ToF on ESP32 DevKit V1: wiring and a free simulation at https://www.tinkered.ai/components/vl53l0x-tof/esp32
#include <Wire.h>
#include <VL53L0X.h>

VL53L0X sensor;

void setup() {
  Serial.begin(9600);
  Wire.begin();
  if (!sensor.init()) {                 // reads model id 0xEE at 0x29
    Serial.println("VL53L0X not found");
    while (1) {}
  }
  sensor.setTimeout(500);
}

void loop() {
  uint16_t mm = sensor.readRangeSingleMillimeters();
  if (sensor.timeoutOccurred()) {
    Serial.println("VL53L0X timeout");  // no answer in 500 ms: wiring or power
  } else if (mm >= 8190) {
    Serial.println("out of range");     // no target within range
  } else {
    Serial.print(mm);
    Serial.println(" mm");
  }
  delay(200);
}
```

Compiled for esp32:esp32:esp32 on 2026-10-30.

## Questions

### How do I use two VL53L0X sensors on an ESP32?

Wire each XSHUT to its own GPIO, bring them up one at a time and set a new address on each before enabling the next (ST datasheet, p. 6). Or put the second on the ESP32's second I2C bus.

### Does the VL53L0X need 5 V on the ESP32?

No. The breakout's regulator takes 3.3 V or 5 V; the bare chip runs from 2.6 V to 3.5 V (ST datasheet, p. 6), so 3V3 is fine.

## More

- [VL53L0X ToF reference](https://www.tinkered.ai/components/vl53l0x-tof.md): pinout, specs, rules and common mistakes

## Try it

Tinkered simulates the VL53L0X ToF on the ESP32 DevKit V1 in the browser, with this wiring and code, free: https://www.tinkered.ai/components/vl53l0x-tof/esp32
