Preview build — page text is a draft awaiting human review. Code badges come from real compiles. The flasher is real but not yet hardware-tested; the Playground is still a preview.

VL53L0X with ESP32 DevKit V1 — laser distance over I2C

Wire a VL53L0X time-of-flight sensor to an ESP32 DevKit V1 at 3.3 V on GPIO21/22 and read millimetre distances with the Pololu library in continuous mode.

Arduino C++Verified — core esp32 3.3.12, VL53L0X 1.3.1, 3 Nov 2026Compile-only

Community draft — report a mistake

The VL53L0X measures distance by timing a pulse of invisible laser light — millimetre steps up to about 1.2 m, in a beam far narrower than an ultrasonic sensor’s.

On the ESP32 DevKit V1 it is an I2C part on D21/D22 at 3.3 V, so there is nothing to level-shift (unlike the 5 V HC-SR04). The sketch uses Pololu’s VL53L0X library in continuous mode and prints the distance ten times a second.

Wiring

ESP32 DevKit V1Only the pins used are shown · 3.3 V logicVL53L0X ToF distance sensorGNDD22D213V3VINGNDSCLSDAGPIO1 (not connected)XSHUT (not connected)
Every connection
ESP32 DevKit V1VL53L0X ToF distance sensorWireNotes
3V3VINredBoards with a regulator accept 3.3–5 V; 3V3 also suits the rarer bare 2.8 V boards without one.
GNDGNDblack
D22SCLyellow
D21SDAblue

2.6–5 V (on-board regulator) part, 3.3 V board. Breakouts with a regulator and level shifting accept 3.3 V or 5 V. Bare boards without them are 2.8 V-only — check the listing.

Board quirks

  • XSHUT and GPIO1 can stay unconnected for one sensor. For several sensors (all start at 0x29), wire each XSHUT to its own GPIO such as D25, D26, D27, wake them one by one and give each a new address with setAddress().
  • Peel the yellow/orange protective film off the sensor window. With it on, readings stick around 20–60 mm or time out.
  • Range is about 1.2 m in normal mode indoors, less in sunlight. Black or shiny targets return less light. For up to 4 m use the VL53L1X.
  • The sketch runs I2C at 400 kHz and a 50 ms timing budget, a good balance for robots and parking sensors. A shorter budget is faster but noisier.

Code

vl53l0x-esp32.inoArduino C++Open in PlaygroundOpen in PlaygroundFlash
// VL53L0X time-of-flight distance (up to ~1.2 m indoors) on an ESP32 DevKit V1.
// VIN → 3V3, GND → GND, SCL → D22, SDA → D21. GPIO1 and XSHUT not needed for one sensor.
#include <Wire.h>
#include <VL53L0X.h>

VL53L0X tof;

void setup() {
  Serial.begin(115200);
  Wire.begin(21, 22);
  Wire.setClock(400000);  // the VL53L0X supports fast-mode I2C
  tof.setBus(&Wire);
  tof.setTimeout(500);
  if (!tof.init()) {
    Serial.println("No VL53L0X at 0x29 — check wiring, and peel off the protective film");
    while (true) delay(1000);
  }
  tof.setMeasurementTimingBudget(50000);  // 50 ms: steadier than the 33 ms default
  tof.startContinuous();
  Serial.println("VL53L0X ready");
}

void loop() {
  uint16_t mm = tof.readRangeContinuousMillimeters();
  if (tof.timeoutOccurred()) {
    Serial.println("Timeout — sensor stopped answering");
  } else if (mm >= 8190) {
    Serial.println("Out of range");  // 8190/8191 = no target seen
  } else {
    Serial.printf("Distance: %u mm\n", mm);
  }
  delay(100);
}

Library: VL53L0X (Pololu) — compiled with VL53L0X 1.3.1.

Expected serial output

Serial Monitor · 115200Output
VL53L0X ready
Distance: 312 mm
Distance: 309 mm
Out of range

Common errors

“No VL53L0X at 0x29”

SDA/SCL swapped or XSHUT pulled low. If you wired XSHUT, drive it HIGH. Run the I2C scanner.

Readings stuck at 8190 or 8191 mm

No target within range, or the film is still on. Point it at a white wall 30 cm away to test.

“Timeout” after running for a while

Loose breadboard contact or a brown-out on the sensor. Solder the header and add 10 µF across VIN–GND.

↑↓ to move · Enter to open