Skip to Content

VL6180X Distance Sensor with Arduino

VL6180X Distance Sensor with Arduino

In this tutorial you will learn how to use the VL6180X Laser Range Distance Sensor with an Arduino or any other common microcontroller (ESP32/ESP8266) to measure distances up to 100 mm.

The VL6180X is a is a very small, Time-of-Flight Distance Sensor (ToF) sensor that uses infrared laser light to measure the proximity of an object. By measuring the time it takes for the light to be reflected from an objects, it can compute distances with high accuracy. Due to the comparatively short range it is especially suited as a proximity sensor or simple gesture recognition sensor.

Required Parts

Obviously, you will need an VL6180X Distance Sensor. As for the microcontroller, I used an Arduino Uno for this project, but any other Arduino or any ESP32/ESP8266 will be fine as well, since the sensor works with 5V or 3.3V. We also will use an OLED to display the distances measured by the VL6180X on a screen.

VL6180X Distance Sensor

Arduino

Arduino Uno

USB Data Sync cable Arduino

USB Cable for Arduino UNO

Dupont wire set

Dupont Wire Set

Half_breadboard56a

Breadboard

OLED display

OLED Display

Makerguides is a participant in affiliate advertising programs designed to provide a means for sites to earn advertising fees by linking to Amazon, AliExpress, Elecrow, and other sites. As an Affiliate we may earn from qualifying purchases.

Features of the VL6180X

The VL6180X is a tiny chip (4.8 x 2.8 x 1.0 mm) with several holes on the top. One is for the laser light emitter, one for the laser light detector and there is also an ambient light detector. See the picture below:

VL6180X Chip
VL6180X Chip (source)

The VL6180X operates by sending out a laser light plus from the emitter, receiving the reflected light from an object in the detector, and based of the time it took (time-of-flight) then computes the distance to the object. The picture below shows the emitter (illumination) and detector (view) cones.

Working Principle of VL6180X
Working Principle of VL6180X (source)

Here are the main features and technical specification of the VL6180X according to the datasheet:

Features of VL6180X
Features of VL6180X (source)

Note, while the datasheet states a range of 100 mm, I could actually measure ranges up to 170 mm. On the other hand, if the object gets closer than 10 mm, the readings become inaccurate.

Application Schematic of VL6180X

The following application schematic shows you the external wiring needed to use the VL6180X chip. You can see the pull-up resistors for the I2C interface that connects the VL6180X to a microcontroller, and two capacitors that stabilize the 2.8V power supply line.

Application schematic for VL6180X
Application schematic for VL6180X (source)

SDA and SCL are the pins for the I2C interface. GPIO0 is the chip enable pin. On similar laser range sensors such as VL53L1X or VL53L0X this pin is labelled XSHUT (shutdown), which allows you to shutdown the sensor, when pulled down. This is useful if you want to connect multiple sensors to the same I2C line. GPIO1 is an interrupt pin that can signal to the microcontroller that data is ready.

Instead of using the tiny VL6180X chip directly, it is better to get a breakout board that has the above electronics already integrated and is also much easier to connect.

Breakout board for VL6180X

The following picture shows the breakout board for the VL6180X. The rectangular chip in the center is the VL6180X chip. The board also has a voltage regulator and level shifters, so that you can connect the board to 5V or 3.3V microcontrollers.

Breakout board for VL53L1X
Breakout board for VL6180X (source)

The pinout largely corresponds with the pins show in the application schematic. SDA, SCL for I2C, VIN and GND for power supply and GPIO1 as interrupt signal. SHDN (= GPIO0, XSHUT) is the chip enable/shutdown pin. Finally, 2v8 is the 2.8V output from the on-board voltage regulator, which can deliver up 100mA.

Connecting the VL6180X to Arduino

Thanks to the I2C interface of the VL6180X, connecting it to an Arduino is simple. First, connect the SCL and SDA pins of the VL6180X breakout board to the corresponding pins on the Arduino board as shown below. Next, connect ground to GND and 3.3V to VIN of the VL6180X and you are done.

Connecting VL6180X with Arduino
Connecting VL6180X with Arduino

The VL6180X breakout board runs on 5V or 3.3V and you can use either for VIN. Next, let us write some code to test the function of the VL6180X sensor.

Code for measuring distance with VL6180X

Before you can measure distances with the VL6180X sensor, you will have to install a library. The most common ones are the Adafruit VL6180X Library and the VL6180X library by Pololu. I had, however, issues with the Adafruit libraries when writing the tutorial for the VL53L0X Distance Sensor, and will therefore use the VL6180X library by Pololu.

Installing the VL6180X Library by Pololu

To install the VL6180X library by Pololu, just search for VL6180X, find the one by Pololu and install it using the Library Manager. The picture below shows how that looks like once the library is installed:

Installing VL6180X Library by Pololu via Library Manager
Installing VL6180X Library by Pololu via Library Manager

With the library installed, let’s try the sensor out. The following code reads distances measured by the VL6180X and prints them to the Serial monitor.

#include "Wire.h"
#include "VL6180X.h"

VL6180X sensor;

void setup() {
  Serial.begin(9600);
  Wire.begin();  
  sensor.init();
  sensor.configureDefault();
  sensor.setTimeout(500);
}

void loop() { 
  Serial.println(sensor.readRangeSingleMillimeters()); 
  delay(1000);
}

Let’s have a closer look at the example code above.

Including Libraries

The first part of the code includes the necessary libraries for communication with the sensor.

#include "Wire.h"
#include "VL6180X.h"

The Wire.h library is used for I2C communication, which is how the Arduino communicates with the VL6180X sensor. The VL6180X.h library contains the functions and definitions specific to the VL6180X sensor, making it easier to interact with it.

Creating a Sensor Object

Next, we create an instance of the VL6180X class.

VL6180X sensor;

This line declares a variable named sensor that we will use to access the methods provided by the VL6180X library.

Setup Function

In the setup() function, we initialize the serial communication and the sensor.

void setup() {
  Serial.begin(9600);
  Wire.begin();  
  sensor.init();
  sensor.configureDefault();
  sensor.setTimeout(500);
}
  • Serial.begin(9600) initializes the serial communication at a baud rate of 9600 bits per second, allowing us to send data to the Serial Monitor.
  • Wire.begin() initializes the I2C bus, enabling communication with the sensor.
  • sensor.init() initializes the VL6180X sensor, preparing it for operation.
  • sensor.configureDefault() configures the sensor with default settings, ensuring it is set up correctly for distance measurement.
  • sensor.setTimeout(500) sets a timeout for sensor readings to 500 milliseconds. If the sensor does not respond within this time, it will return an error.

Loop Function

The loop() function continuously reads the distance from the sensor and prints it to the Serial Monitor.

void loop() { 
  Serial.println(sensor.readRangeSingleMillimeters()); 
  delay(1000);
}

The readRangeSingleMillimeters() function reads the distance measured by the sensor and returns it in millimeters. This value is then printed to the Serial Monitor. If the sensor does not detect any objects (out of range), a value of 255 will be printed. The following screen shot shows some example measurements on the Serial Monitor:

Distance Measurements of VL6180X on Serial Monitor
Distance Measurements of VL6180X on Serial Monitor

The delay(1000) pauses the program for 1000 milliseconds (1 second) before the next reading, slowing down the sensor readings.

In the next section we are going to add an OLED to our circuit and display the distances on that, instead of printing to the Serial Monitor.

Adding an OLED to display VL6180X data

Since the OLED is also an I2C device, connecting it is straightforward. We simply connect SDA and SCL to the same pins the VL6180X sensor is connected to. And since the OLED runs on 3.3V, we can also share the power supply lines.

Connecting OLED and VL6180X with Arduino
Connecting OLED and VL6180X with Arduino

Code to display distances measured by VL6180X on OLED

The following code reads distance measurements from the VL6180X sensor and displays them on the OLED. Have a quick look at the complete code first, and then we will discuss its details.

#include "Wire.h"
#include "VL6180X.h"
#include "Adafruit_SSD1306.h"

Adafruit_SSD1306 oled(128, 64, &Wire, -1);
VL6180X sensor;

void sensor_init() {
  Wire.begin();
  sensor.init();
  sensor.configureDefault();
  sensor.setTimeout(500);
}

void oled_init() {
  oled.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  oled.setTextSize(2);
  oled.setTextColor(WHITE);
}

void display() {
  static char text[30];
  int dist = sensor.readRangeSingleMillimeters();
  sprintf(text, "%4d mm", dist);

  oled.clearDisplay();
  oled.setCursor(20, 25);
  oled.print(text);
  oled.display();
}

void setup() {
  oled_init();
  sensor_init(); 
}

void loop() {
  display();
}

Let’s break down the code into its parts for a better understanding.

Libraries Included

At the beginning of the code, we include the necessary libraries for I2C communication (Wire), the VL6180X sensor, and the Adafruit SSD1306 OLED display.

#include "Wire.h"
#include "VL6180X.h"
#include "Adafruit_SSD1306.h"

If you haven’t already installed the Adafruit_SSD1306 Library, you will have to. Just install it via the Library Manager as usual:

Adafruit_SSD1306 library installed in Library Manager
Adafruit_SSD1306 library installed in Library Manager

Object Initialization

We create instances of the OLED display and the VL6180X sensor. The OLED display is initialized with a width of 128 pixels and a height of 64 pixels.

Adafruit_SSD1306 oled(128, 64, &Wire, -1);
VL6180X sensor;

Sensor Initialization Function

The sensor_init() function initializes the I2C communication and configures the VL6180X sensor with default settings. It also sets a timeout of 500 milliseconds for sensor readings.

void sensor_init() {
  Wire.begin();
  sensor.init();
  sensor.configureDefault();
  sensor.setTimeout(500);
}

OLED Initialization Function

The oled_init() function initializes the OLED display. It sets the display to use the internal charge pump and specifies the I2C address (0x3C). The text size is set to 2, and the text color is set to white.

void oled_init() {
  oled.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  oled.setTextSize(2);
  oled.setTextColor(WHITE);
}

Note that the I2C address for the OLED display is set to 0x3C in oled.begin(). Most of these small OLEDs use this address but yours might be different. If you don’t see anything on the OLED, it most likely has a different I2C address and you have change the address. If you don’t know the I2C address have a look at the How to Interface the SSD1306 I2C OLED Graphic Display With Arduino tutorial.

Display Function

The display() function reads the distance from the sensor in millimeters and formats it into a string. It then clears the OLED display, sets the cursor position, prints the distance, and updates the display.

void display() {
  static char text[30];
  int dist = sensor.readRangeSingleMillimeters();
  sprintf(text, "%4d mm", dist);

  oled.clearDisplay();
  oled.setCursor(20, 25);
  oled.print(text);
  oled.display();
}

If the sensor could not detect an object, since it is out of range, a value of 255 mm will be shown on the OLED:

Output of VL6180X on OLED
Output of VL6180X on OLED

Setup Function

In the setup() function, we call the initialization functions for both the OLED display and the sensor to prepare them for use.

void setup() {
  oled_init();
  sensor_init(); 
}

Loop Function

Finally, the loop() function continuously calls the display() function, allowing the distance readings to be updated on the OLED display in real-time.

void loop() {
  display();
}

The following short video clip shows the VL6180X sensor and display in action:

Distance measurements with VL6180X sensor
Distance measurements with VL6180X sensor

Conclusions

In this tutorial you learned how to use the VL6180X Distance Sensor with an Arduino to measure distances and to display them on an OLED.

The VL6180X Sensor is a is a very small sensor that uses infrared laser light to measure distances. The VL6180X is similar to the VL53L1X, VL53L0X and TOF10120 sensors but has a shorter range. If you need a sensor for a much larger range, have a look at the TF Luna that can measure distances of up to 8 meters.

It is more suitable as a proximity or simple gesture sensor than a long-range distance meter. It also comes with an integrated ambient light sensor, though I could not get any reading from the light sensor using the VL6180X Library by Pololu.

If you have any questions feel free to leave them in the comment section.

Happy Tinkering ; )