VL53L0X Arduino Measure Distance | Time-of-Flight Sensor Guide

This tutorial will help you to use the VL53L0X Time-of-Flight (ToF) sensor with Arduino. A Time-of-flight sensor measures the distance of an object by calculating the time it takes for light to reflect from the object. Such sensors use a LASER or an LED as a light source, and a receiver to detect the reflected light.

Time-of-flight sensors differ from ultrasonic sensors such as the HC-SR04 which rely on reflected ultrasonic waves. The ‘cone’ of sense in the ToF sensor is narrower than ultrasonic sensors.

Since a Time-of-flight sensor uses a narrow light source, it can reliably measure surfaces directly in front of it.

The VL53L0X Sensor

VL53L0X is manufactured by STMicroelectronics. It is available as breakout board modules for easy interfacing with microcontrollers. The image below shows the module used in this guide called GY-53 VL53L0X or VL53L0XV2.

VL53L0X ToF Module

The VL53L0X consists of a tiny laser source and a receiver that can sense the laser. It calculates distance by measuring the time it takes for a laser pulse to travel to an object and back (Using the simple formula: Distance = Time x Speed).

VL53L0X Features

  • The sensor measures distances ranging from 50 mm to 1.2 meters (3.937 feet) in its default mode.
  • In the ‘long range’ mode, VL53L0X can measure distances up to 2 meters (6.56 feet).
  • The supply voltage can range from 2.8V to 5V, aided by an onboard voltage regulator.
  • The module comes with an onboard logic level shifter which makes it easier to interface with both 3.3V and 5V compatible microcontrollers.
  • I2C is used to interface the sensor.
  • VL53L0X uses a 940nm VCSEL emitter (Vertical-Cavity Surface-Emitting Laser) which is invisible to the human eye.

VL53L0X Pinout

The pinout of the VL53L0X Time-of-flight module (GY-53 VL53L0X) is shown below.

VL53L0X Pinout

Pin description:

PinDescription
VCCPositive of power supply (2.8V – 5V)
GNDGround of power supply
SCLI2C Serial Clock
SDAI2C Serial Data
GPIO1Used for interrupts
XSHUTShutdown pin

Other modules are also available from different manufacturers that can be interfaced in a similar way once you understand how to use the sensor. Some of these modules come with only 4 pins – VCC, GND, SCL, and SDA.

For easily wiring the module on a breadboard, you can solder some pin headers to the module.

Wiring VL53L0X with Arduino

The schematic below shows how we can connect the VL53L0X Time-of-flight sensor with an Arduino board.

Schematic: VL53L0X with Arduino

Connections:

  • Connect the ‘5V’ pin of Arduino UNO to the ‘VCC’ pin of the VL53L0X module.
  • Connect one of the ‘GND’ pins of Arduino UNO to the ‘GND’ pin of the VL53L0X module.
  • Connect the ‘A4’ pin of Arduino UNO to the ‘SDA’ pin of the VL53L0X module.
  • Connect the ‘A5’ pin of Arduino UNO to the ‘SCL’ pin of the VL53L0X module.

VL53L0X Arduino Library

We shall discuss two Arduino libraries to interface with the VL53L0X sensor.

  • One of the most popular libraries is the Pololu VL53L0X library. This library allows us to measure distances up to 2 meters but it does not support interrupts.
  • The Adafruit library for VL53L0X can measure distances up to 1.2 meters and also supports interrupts.

In Arduino IDE, navigate to Sketch>Include library>Manage libraries to access the Library Manager.

To install the Pololu library search for “VL53L0X” in Library Manager and find and install the library by Pololu.

Similarly, you can install Adafruit’s version of the VL53L0X library by searching for “VL53L0X”. Scroll to find the library by Adafruit and install the latest version. The Adafruit library may also ask you to install additional dependencies which you must do for the code to work reliably.

VL53L0X Arduino Code (Example 1)

This section will show you how to read the VL53L0X ToF sensor using the library from Pololu. You can find an example sketch in Arduino IDE by navigating to File>Examples>Single.

Alternatively, you can copy-paste the code given below. This code has some changes to enable ‘long range mode’ and high accuracy.

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

VL53L0X sensor;


// Uncomment this line to use long range mode. This
// increases the sensitivity of the sensor and extends its
// potential range, but increases the likelihood of getting
// an inaccurate reading because of reflections from objects
// other than the intended target. It works best in dark
// conditions.

#define LONG_RANGE


// Uncomment ONE of these two lines to get
// - higher speed at the cost of lower accuracy OR
// - higher accuracy at the cost of lower speed

//#define HIGH_SPEED
#define HIGH_ACCURACY


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

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

#if defined LONG_RANGE
  // lower the return signal rate limit (default is 0.25 MCPS)
  sensor.setSignalRateLimit(0.1);
  // increase laser pulse periods (defaults are 14 and 10 PCLKs)
  sensor.setVcselPulsePeriod(VL53L0X::VcselPeriodPreRange, 18);
  sensor.setVcselPulsePeriod(VL53L0X::VcselPeriodFinalRange, 14);
#endif

#if defined HIGH_SPEED
  // reduce timing budget to 20 ms (default is about 33 ms)
  sensor.setMeasurementTimingBudget(20000);
#elif defined HIGH_ACCURACY
  // increase timing budget to 200 ms
  sensor.setMeasurementTimingBudget(200000);
#endif
}

void loop()
{
  if(sensor.readRangeSingleMillimeters()>2000)
  {
    Serial.println("Out of range");
  }
  else
  {
    Serial.print(sensor.readRangeSingleMillimeters());
    Serial.println(" mm");
  }
  
  if (sensor.timeoutOccurred()) 
  { 
    Serial.println(" TIMEOUT"); 
  }
}
Code language: PHP (php)

The code above will let you measure objects at a distance of up to 2 meters from the VL53L0X ToF sensor.

This code begins by including the necessary libraries, Wire.h for I2C communication and VL53L0X.h for interacting with the VL53L0X sensor. It then creates an instance of the sensor object with VL53L0X sensor.

In the setup() function, serial communication is initialized using Serial.begin(9600), and the I2C bus is started with Wire.begin(). The sensor is configured to have a response timeout of 500 ms with sensor.setTimeout(500). If the sensor fails to initialize, an error message is printed, and the program halts in an infinite while loop.

The code then checks for defined modes: if #define LONG_RANGE is active, it configures the VL53L0X sensor for long-range operation by lowering the return signal rate limit and laser pulse periods. Additionally, depending on whether #define HIGH_SPEED or #define HIGH_ACCURACY is set, the code adjusts the measurement timing budget to prioritize either speed (sensor.setMeasurementTimingBudget(20000)) or accuracy (sensor.setMeasurementTimingBudget(200000)).

In the loop() function, the code repeatedly checks the sensor’s distance reading. If the measured distance is greater than 2000 mm (if(sensor.readRangeSingleMillimeters()>2000)), it prints “Out of range” to the serial monitor; otherwise, it prints the measured distance in millimeters. If a timeout occurs during measurement, it prints “TIMEOUT” using if (sensor.timeoutOccurred()).

Output

The output of the sketch will be available on the Serial Monitor of Arduino IDE which can be accessed by navigating to Tools>Serial Monitor. Set the baud rate in the serial monitor the same as your code (9600 in this example). The screenshot below shows the output data obtained from the sensor. The readings are in ‘mm’ by default.

VL53L0X Arduino Example 2

Next, we shall use Adafruit’s library to interface the time-of-flight sensor with Arduino code. The example code can be found in Arduino IDE by navigating to File>Examples>Adafruit_VL53L0X>vl53l0x.

You can copy the code below to get output from the distance sensor:

#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 Simple Ranging example\n\n")); 
}

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

  if (measure.RangeStatus != 4) {  // phase failures have incorrect data
    Serial.print("Distance (mm): "); Serial.println(measure.RangeMilliMeter);
  } else {
    Serial.println(" out of range ");
  }
    
  delay(100);
}Code language: PHP (php)

The code above can measure distances up to 1200mm (1.2 meters/3.94 feet) from the sensor.

This code begins by including the Adafruit VL53L0X library and initiates Serial communication with a baud rate of 115200. The sensor is initialized with lox.begin(), and if the initialization fails, an error message “Failed to boot VL53L0X” is printed, followed by an infinite loop to halt further execution.

After successful initialization, the program prints “VL53L0X API Simple Ranging example” to the serial monitor.

The loop() function handles the continuous reading of distance measurements. A VL53L0X_RangingMeasurementData_t structure named measure is declared to store the sensor’s measurement data. The sensor’s ranging test is initiated with lox.rangingTest(&measure, false), where the false parameter disables debug data printout.

The code then checks if the measurement status (measure.RangeStatus) is not equal to 4, indicating valid data.

If the data is valid, the code prints the distance in millimeters. If the measurement is out of range, it prints “out of range”. The loop pauses for 100 milliseconds before taking the next measurement.

Output

The output can be viewed in the Serial Monitor of Arduino IDE by setting the baud rate to 115200.

The Adafruit library for VL53L0X also supports additional features such as reading two VL53L0X sensors using I2C, or using interrupt routine to read the sensor only when the measurement is within a specified range. You can explore such examples through the ‘examples’ section in Arduino IDE or by visiting the Github link for the Adafruit VL53L0X library.

Conclusion

This article explored how we can use the VL53L0X sensor with Arduino to measure distances up to 2 meters. This guide can be used to make projects such as a car parking assistant, digital ruler, drone altitude sensor, etc.

Also check out our article: Measure Distance Using Raspberry Pi Pico & HC-SR04 (MicroPython code)


Posted

in

by

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *