Documentation

VL53L0X Pre-Soldered Laser Ranging ToF Sensor Module | ShillehTek Product Manual
Documentation / VL53L0X Pre-Soldered Laser Ranging ToF Sensor Module | ShillehTek Product Manual

VL53L0X Pre-Soldered Laser Ranging ToF Sensor Module | ShillehTek Product Manual

manualshillehtek

Overview

The ShillehTek VL53L0X is a Time-of-Flight (ToF) laser ranging sensor module built around ST Microelectronics' VL53L0X chip. Unlike ultrasonic or IR distance sensors, the VL53L0X measures distance by timing how long a Class-1 940 nm laser pulse takes to bounce off a target and return — which makes it immune to ambient light, color, and target reflectivity in ways that optical sensors can't match.

With a range of 30 mm to 2000 mm and ±3% typical accuracy, it's a perfect fit for robotics obstacle avoidance, drone altimetry, gesture sensing, presence detection, 3D scanning, liquid-level measurement, and any precision ranging project where a 10 mm-resolution reading matters. Because the sensor is only a few millimeters wide, it also fits in tight enclosures where an HC-SR04 would never go.

The module talks over I2C at the default address 0x29, runs on 2.6V to 5.5V (an onboard 2.8V LDO handles the chip's native voltage), and exposes an XSHUT pin so you can run multiple VL53L0X sensors on the same I2C bus by sequencing their addresses. It works great with Arduino, ESP32, Raspberry Pi, and Pico using the well-supported Adafruit and Pololu libraries.

At a Glance

Technology
Time-of-Flight Laser
Operating Voltage
2.6V - 5.5V
Interface
I2C (0x29 default)
Range
30 mm - 2000 mm
Accuracy
±3% (typ)
Pins
6 (VCC, GND, SCL, SDA, GPIO1, XSHUT)

Specifications

Parameter Value
Sensor Chip ST VL53L0X
Ranging Technology 940 nm Class 1 Laser (eye-safe)
Operating Voltage 2.6V - 5.5V (onboard 2.8V LDO)
Operating Current ~19 mA active, ~3 µA standby
Communication Protocol I2C up to 400 kHz (Fast Mode)
Default I2C Address 0x29 (7-bit, software configurable)
Range 30 mm to 2000 mm
Ranging Accuracy ±3% typical (good conditions)
Resolution 1 mm
Ranging Modes Default, High Accuracy, Long Range, High Speed
Timing Budget 20 ms (default) - 200 ms (high accuracy)
Field of View 25° typical
Operating Temperature -20 °C to +70 °C
Dimensions ~25 mm x 11 mm

Pinout Diagram

VL53L0X Time-of-Flight laser ranging sensor module pinout diagram showing VCC, GND, SCL, SDA, GPIO1, and XSHUT pins

Wiring Guide

Arduino Wiring

The VL53L0X runs cleanly on 5V thanks to its onboard LDO regulator. Connect SDA and SCL to the Arduino's hardware I2C pins (A4 and A5 on an UNO/Nano). XSHUT and GPIO1 are optional — you only need XSHUT for multi-sensor setups and GPIO1 for interrupt-driven reads.

VL53L0X Pin Arduino Pin
VCC 5V
GND GND
SCL A5 (SCL)
SDA A4 (SDA)
XSHUT D2 (optional — multi-sensor)
GPIO1 D3 (optional — interrupt)
Tip: The module has onboard I2C pull-up resistors, so you don't need to add any. If you chain multiple I2C devices, the pull-ups still work fine.

ESP32 Wiring

ESP32's default I2C pins are GPIO21 (SDA) and GPIO22 (SCL). Power the module from 3.3V or 5V — both work. Logic lines on the VL53L0X module are already 3.3V thanks to the onboard regulator and level-tolerant I/O, so no level shifter is required.

VL53L0X Pin ESP32 Pin
VCC 3.3V (or 5V)
GND GND
SCL GPIO22
SDA GPIO21
XSHUT GPIO4 (optional)
GPIO1 GPIO5 (optional)
Note: The ESP32 I2C peripheral can drive any GPIO. If GPIO21/22 are busy, reassign with Wire.begin(sda, scl).

Raspberry Pi Wiring

Enable I2C first in raspi-config → Interface Options → I2C. The Pi's hardware I2C bus lives on physical pins 3 (GPIO2/SDA) and 5 (GPIO3/SCL).

VL53L0X Pin Raspberry Pi Pin (BOARD)
VCC Pin 1 (3.3V) or Pin 2/4 (5V)
GND Pin 6 (GND)
SCL Pin 5 (GPIO3 / SCL)
SDA Pin 3 (GPIO2 / SDA)
XSHUT Pin 11 (GPIO17, optional)
GPIO1 Pin 13 (GPIO27, optional)
Tip: After wiring, run sudo i2cdetect -y 1. You should see 29 in the address grid — that confirms the sensor is talking.

Raspberry Pi Pico Wiring

The Pico has two I2C peripherals. We use I2C0 on GP0 (SDA) and GP1 (SCL) for the simplest pin arrangement, but any I2C-capable pair works.

VL53L0X Pin Pico Pin
VCC 3V3(OUT) or VSYS (5V)
GND GND
SCL GP1 (I2C0 SCL)
SDA GP0 (I2C0 SDA)
XSHUT GP2 (optional)
GPIO1 GP3 (optional)
Note: XSHUT is active-low — drive it HIGH to enable the sensor, LOW to reset it. Useful for changing the I2C address at boot when you want multiple VL53L0X modules on the same bus.

Code Examples

Arduino (Adafruit VL53L0X library)

vl53l0x_basic.ino
// VL53L0X Time-of-Flight ranging
// Install: Arduino Library Manager → "Adafruit VL53L0X"
// Wiring: VCC->5V, GND->GND, SCL->A5, SDA->A4

#include <Wire.h>
#include "Adafruit_VL53L0X.h"

Adafruit_VL53L0X lox = Adafruit_VL53L0X();

void setup() {
  Serial.begin(9600);
  while (!Serial);

  Serial.println("VL53L0X: initializing...");
  if (!lox.begin()) {
    Serial.println("Failed to boot VL53L0X. Check wiring.");
    while (1);
  }
  Serial.println("VL53L0X ready.");
}

void loop() {
  VL53L0X_RangingMeasurementData_t measure;
  lox.rangingTest(&measure, false);

  if (measure.RangeStatus != 4) {  // 4 = out of range
    Serial.print("Distance (mm): ");
    Serial.println(measure.RangeMilliMeter);
  } else {
    Serial.println("Out of range");
  }
  delay(100);
}

Arduino (Long Range Mode)

vl53l0x_long_range.ino
// VL53L0X in Long Range mode (up to ~2m outdoors, ~1.5m in ambient light)
// Uses Pololu VL53L0X library for finer control
// Install: Arduino Library Manager → "VL53L0X by Pololu"

#include <Wire.h>
#include <VL53L0X.h>

VL53L0X sensor;

void setup() {
  Serial.begin(9600);
  Wire.begin();

  sensor.setTimeout(500);
  if (!sensor.init()) {
    Serial.println("Failed to detect VL53L0X");
    while (1);
  }

  // Long range: lower signal rate limit, wider pulse period
  sensor.setSignalRateLimit(0.1);
  sensor.setVcselPulsePeriod(VL53L0X::VcselPeriodPreRange, 18);
  sensor.setVcselPulsePeriod(VL53L0X::VcselPeriodFinalRange, 14);
  sensor.setMeasurementTimingBudget(33000); // ~33 ms

  sensor.startContinuous();
}

void loop() {
  uint16_t distance = sensor.readRangeContinuousMillimeters();
  Serial.print("Distance (mm): ");
  Serial.println(distance);
  if (sensor.timeoutOccurred()) Serial.println("Timeout!");
  delay(50);
}

Raspberry Pi (Python)

vl53l0x_pi.py
# VL53L0X on Raspberry Pi using Adafruit CircuitPython
# Install: pip install adafruit-circuitpython-vl53l0x --break-system-packages

import time
import board
import busio
import adafruit_vl53l0x

i2c = busio.I2C(board.SCL, board.SDA)
sensor = adafruit_vl53l0x.VL53L0X(i2c)

# Optional: extend timing budget for more accuracy (default 33000 us)
sensor.measurement_timing_budget = 200000  # 200 ms

print("VL53L0X ready. Reading distance...")
while True:
    try:
        distance = sensor.range
        print(f"Distance: {distance} mm")
        time.sleep(0.1)
    except KeyboardInterrupt:
        break

Raspberry Pi Pico (MicroPython)

vl53l0x_pico.py
# VL53L0X on Raspberry Pi Pico (MicroPython)
# Wiring: VCC->3V3, GND->GND, SCL->GP1, SDA->GP0
# Needs the VL53L0X MicroPython driver by Kevin McAleer:
# Copy vl53l0x.py from https://github.com/kevinmcaleer/vl53l0x_micropython
# onto the Pico filesystem.

from machine import I2C, Pin
from vl53l0x import VL53L0X
import time

i2c = I2C(0, sda=Pin(0), scl=Pin(1), freq=400000)
print("I2C scan:", [hex(a) for a in i2c.scan()])

tof = VL53L0X(i2c)
tof.start()

while True:
    distance = tof.read()
    print("Distance:", distance, "mm")
    time.sleep_ms(100)

ESP32 (MicroPython)

vl53l0x_esp32.py
# VL53L0X on ESP32 (MicroPython)
# Wiring: VCC->3V3, GND->GND, SCL->GPIO22, SDA->GPIO21
# Upload vl53l0x.py driver to the board first (same driver as Pico).

from machine import I2C, Pin
from vl53l0x import VL53L0X
import time

i2c = I2C(0, scl=Pin(22), sda=Pin(21), freq=400000)
print("I2C scan:", [hex(a) for a in i2c.scan()])

tof = VL53L0X(i2c)
tof.start()

while True:
    print("Distance:", tof.read(), "mm")
    time.sleep_ms(100)

Frequently Asked Questions

What's the maximum range I can expect?
About 1.2 meters in default mode, and up to 2 meters using Long Range mode on a white, matte target in low ambient light. Dark or absorbent targets, bright sun, and small objects all reduce effective range. Indoors at night you can hit the full 2 m; outdoors in direct sunlight, expect closer to 1 m.
Is this sensor eye-safe?
Yes — the VL53L0X uses a 940 nm infrared laser certified as Class 1, meaning it's eye-safe under all normal conditions of use. You cannot see the laser (it's IR) and it cannot damage your eyes. That said, avoid staring directly into the emitter at close range through magnification.
Can I use multiple VL53L0X sensors on the same bus?
Yes, but they all boot with the same default I2C address (0x29), so you need to change addresses at startup. Wire each sensor's XSHUT pin to a different microcontroller GPIO. Bring all XSHUTs LOW, then bring one HIGH, reassign its address with setAddress(), then bring up the next one, and so on. This is a common robotics technique for 360-degree sensor rings.
What does GPIO1 do?
GPIO1 is an interrupt output. You can configure the VL53L0X to assert this pin when a new measurement is ready, or when a reading crosses a user-set threshold. It lets you drive the sensor in a non-blocking, event-driven way instead of polling — very useful for low-power or real-time projects.
Why is my reading fluctuating?
Three common causes. First, reflective or angled targets scatter the laser — aim at matte, flat surfaces. Second, bright sunlight or IR lamps can overwhelm the sensor — reduce ambient IR if possible. Third, a timing budget that's too short gives noisy readings — increase it from the default 33 ms to 100-200 ms for stable, high-accuracy measurements.
Which library is best for Arduino?
Adafruit's Adafruit_VL53L0X is the easiest to get started with and has great examples. Pololu's VL53L0X library exposes lower-level controls (signal rate limits, VCSEL pulse periods, custom modes) and is better if you need fine-grained tuning. Both are in the Arduino Library Manager.
Can I power it from 3.3V?
Yes. The module accepts 2.6V to 5.5V. The onboard LDO drops whatever you give it down to the 2.8V the VL53L0X chip runs on, and the I2C lines are already 2.8V logic on the chip side. That's 3.3V-compatible and works directly with Raspberry Pi, Pico, ESP32, STM32, and any other 3.3V microcontroller without level shifting.

Related Tutorials

We don't have VL53L0X-specific tutorials on the ShillehTek blog yet — but we're working on projects like robot obstacle avoidance, multi-sensor arrays, and ToF-based gesture triggers. Subscribe to the newsletter to be the first to know.