Arduino library 路 Sensors

VL53L0X (Pololu): laser distance in millimeters

The VL53L0X is a time-of-flight sensor from ST: it fires an invisible 940 nm laser pulse and counts how long the light takes to come back, which gives distance in millimeters up to about 2 m in good conditions. Pololu鈥檚 VL53L0X library is the compact way to drive it, a few hundred lines in place of ST鈥檚 full API.

Built in on Mokxi: #include <VL53L0X.h> and it builds, with nothing to install. Free, and no account needed.

What VL53L0X does

After init(), you either ask for one measurement at a time with readRangeSingleMillimeters() or put the sensor in continuous mode with startContinuous() and read the latest result as often as you like. Set a timeout first, or a sensor that stops answering will hang the sketch inside a read.

Every VL53L0X powers up at I2C address 0x29. Two of them on one bus need their XSHUT pins: hold all but one in reset, give the live one a new address with setAddress(), and wake the next.

Library Manager nameVL53L0X
AuthorPololu
Include#include <VL53L0X.h>
Boardsevery board Mokxi compiles for but ATtiny85
In the simulatorSimulated: it runs against the part the way it does on the bench.
Parts it drivesVL53L0X time-of-flight sensor

Install it

It builds on every board Mokxi compiles for but ATtiny85.

In Mokxi it is built in: #include <VL53L0X.h> and the sketch compiles, with no download, no zip and no Library Manager.

On a real board, install "VL53L0X" by Pololu from the Arduino IDE鈥檚 Library Manager (Sketch, Include Library, Manage Libraries), or add VL53L0X to lib_deps in PlatformIO. Mokxi follows the calls of release 1.3.1, so a sketch written here builds there too.

What to know in the simulator: ST鈥檚 reference SPAD and calibration steps are left out of init(); the part does not need them.

ESP32-C3 路 Arduino Uno 路 Arduino Nano 路 Arduino Mega 2560 路 Arduino Leonardo 路 SparkFun Pro Micro 路 Arduino Micro 路 ESP32-C6 路 Raspberry Pi Pico 路 Raspberry Pi Pico W 路 Seeed XIAO SAMD21 路 STM32 路 STM32 Nucleo-F411RE 路 STM32 Blue Pill 路 micro:bit V2 路 Arduino Uno R4 路 ESP32 DevKit 路 ESP32-S3-DevKitC-1 路 ESP8266 NodeMCU 路 Arduino Pro Mini 3.3 V 路 Seeed XIAO ESP32-C3 路 ESP32-C3 SuperMini 路 Seeed XIAO ESP32-C6 路 ESP32-DevKitC V4 路 LOLIN32 Lite 路 Wemos D1 R32 路 Cheap Yellow Display 路 TTGO T-Display 路 Seeed XIAO ESP32-S3 路 Arduino Nano ESP32 路 Arduino Nano RP2040 Connect 路 Seeed XIAO RP2040 路 Waveshare RP2040-Zero 路 Arduino Uno R4 WiFi

The calls you will use

In the order a sketch meets them.

VL53L0X sensor

Creates the sensor object on the Wire bus at 0x29.

sensor.setTimeout(500)

How many milliseconds a read may wait before giving up. 0 means wait for ever, which is the default and rarely what you want.

sensor.init()

Checks the model ID and sets the sensor up. Returns false when no VL53L0X answers.

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

sensor.readRangeSingleMillimeters()

Starts one measurement, waits for it and returns the distance in millimeters.

sensor.startContinuous()

Keeps the sensor ranging back to back. Read the newest result with readRangeContinuousMillimeters().

sensor.timeoutOccurred()

True when the last read ran out of time. Check it after each read and print TIMEOUT rather than a bogus number.

sensor.setMeasurementTimingBudget(200000)

Spends more time on each measurement (here 200 ms, given in microseconds) for steadier readings.

sensor.setAddress(0x30)

Moves this sensor to a new I2C address until it is powered off, so a second one can sit on the same bus.

Example: Laser ruler

On the Arduino Uno R3. It runs in the browser exactly as printed.

sketch.ino 路 Arduino Uno R3
// Laser ruler: a VL53L0X measures how far away the target is by timing a
// pulse of infrared laser light there and back, read with Pololu's library.
//
//   VL53L0X   VIN -> 5 V   GND -> GND   SDA -> A4   SCL -> A5
//
// Light covers a meter in about 3.3 nanoseconds, so the chip times the trip
// with a grid of single-photon detectors rather than a clock, and reports the
// result in millimeters. In its default mode it reaches about 1.2 m; past
// that it reports 8190, which means nothing came back.
//
// Drag the slider on the sensor to move the target.

#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 and initialize sensor!");
    while (1) {
    }
  }
  sensor.startContinuous();
  Serial.println("Laser ruler ready");
}

void loop() {
  uint16_t mm = sensor.readRangeContinuousMillimeters();
  if (sensor.timeoutOccurred()) {
    Serial.println("timeout");
  } else if (mm >= 8190) {
    Serial.println("out of range");
  } else {
    Serial.print("distance ");
    Serial.print(mm);
    Serial.println(" mm");
  }
  delay(200);
}

Open it in the editor, wired and ready to run 路 Laser ruler: the project page

Common errors and how to fix them

Failed to detect and initialize sensor!

init() returned false. Check the wiring to SDA and SCL, that Wire.begin() ran first, and that XSHUT is not held low. Run an I2C scanner: the sensor should show at 0x29.

The reading is 8190 or 8191 all the time

That is the sensor saying nothing was in range. Point it at a surface within about 1.2 m, avoid shiny or very dark targets, and remove the protective film from the window if it is still on.

The sketch freezes on the first read

No timeout is set, so the read waits for ever for a sensor that is not answering. Call setTimeout(500) before init() and test timeoutOccurred() after every read.

Projects that use VL53L0X

Built-in projects that include it. Each page has the full sketch and opens in the editor, already wired.

Try VL53L0X without installing anything

Open the example, change the sketch, and keep your version in a free account.