Neste tutorial, vais aprender a usar o Sensor de Distância VL53L0X (também chamado TOF0200C) com um Arduino ou qualquer outro microcontrolador comum (ESP32/ESP8266) para medir distâncias.
O VL53L0X é um sensor de distância Time-of-Flight (ToF) muito pequeno que usa luz laser infravermelha para medir a distância a um objeto. Ao medir o tempo que a luz demora a ser refletida por um objeto, consegue calcular distâncias com alta precisão. O tamanho compacto e o baixo consumo de energia do sensor tornam-no adequado para uma ampla variedade de projetos DIY, incluindo robótica, reconhecimento de gestos e deteção de proximidade.
Peças Necessárias
Obviamente, vais precisar de um Sensor de Distância VL53L0X. Quanto ao microcontrolador, usei um Arduino Uno para este projeto, mas qualquer outro Arduino ou ESP32/ESP8266 também funciona bem. Para mostrar as distâncias medidas, escolhi um OLED, mas também poderias usar um LCD display.

Sensor de Distância VL53L0X

Arduino Uno

Cabo USB para Arduino UNO

Conjunto de Fios Dupont

Breadboard

Ecrã OLED
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.
Características do VL53L0X
O VL53L0X é um chip minúsculo (4,4 x 2,4 x 1,0 mm) com dois orifícios no topo. Um para o emissor de luz laser e outro para o detector de luz. A imagem abaixo mostra o chip:

O VL53L0X funciona emitindo um pulso de luz laser pelo emissor, recebendo a luz refletida de um objeto no detector e, com base no tempo que demorou (time-of-flight), calcula a distância ao objeto. A imagem abaixo mostra os cones do emissor e do detector.

Aqui estão as principais especificações do VL53L0X:
- Emissor VCSEL de 940 nm (luz IR, invisível ao olho)
- Tempo de medição de 30 ms
- Distância até 2 m
- Funciona em ambientes com pouca luz e baixo contraste
- Tensão: 2,6V – 5,5V
- Interface de comunicação I2C
Podes encontrar mais detalhes na folha de dados
Esquema de Aplicação do VL53L0X
O esquema de aplicação seguinte mostra a ligação externa necessária para usar o VL53L0X. Podes ver os resistores pull-up para a interface I2C que liga o VL53L0X a um microcontrolador (host), e dois condensadores para estabilizar a alimentação.

SDA e SCL são os pinos para a interface I2C. XSHUT é o pino de desligar, que permite desligar o sensor quando puxado para baixo. Isto é útil se quiseres ligar vários sensores VL53L0X à mesma linha I2C. GPIO1 é um pino de interrupção que pode sinalizar ao microcontrolador que os dados estão prontos.
Em vez de usar o pequeno VL53L0X diretamente, é melhor obter uma placa breakout que já tenha a eletrónica acima integrada e seja muito mais fácil de ligar.
Placa breakout para VL53L0X
A imagem seguinte mostra uma típica placa breakout para o VL53L0X. O retângulo branco marca o local onde o chip VL53L0X está situado.

O pinout tem os pinos que discutimos antes. SDA, SCL para I2C, GPIO1 como sinal de interrupção, XSHUT para seleção do chip, e VIN e GND para alimentação. Nota que tens de puxar para baixo o XSHUT se quiseres desligar o chip.
Ligando o VL53L0X
Graças à interface I2C do VL53L0X, ligá-lo a um Arduino é fácil. Primeiro, liga os pinos SCL e SDA da placa breakout do VL53L0X aos pinos correspondentes na placa Arduino como mostrado abaixo. Depois, liga o terra ao GND e 3,3V ao VIN do VL53L0X.

A placa breakout do VL53L0X funciona com 5V ou 3,3V e podes usar qualquer um para o VIN. Na ligação acima, estou a usar 3,3V para o VIN.
De seguida, vamos escrever algum código para testar a função do sensor VL53L0X.
Código para medir distância com VL53L0X
Antes de poderes medir distâncias com o sensor VL53L0X, terás de instalar uma biblioteca. Estou a usar a Adafruit VL53L0X Library aqui. Podes install it via the Library Manager como de costume:

O instalador pode perguntar se queres instalar só a biblioteca ou a biblioteca com as suas dependências. Basta carregar em “INSTALL ALL” neste caso:

Com a biblioteca instalada, vamos executar um código simples para testar o sensor.
// Measure distance with VL53L0X sensor
// by Makerguides
#include "Adafruit_VL53L0X.h"
Adafruit_VL53L0X sensor = Adafruit_VL53L0X();
void setup() {
Serial.begin(9600);
sensor.begin();
}
void loop() {
VL53L0X_RangingMeasurementData_t measure;
sensor.rangingTest(&measure, false);
if(measure.RangeStatus == 4) {
Serial.println("---");
} else {
Serial.println(measure.RangeMilliMeter);
}
delay(100);
}
Como podes ver, o código inclui a biblioteca Adafruit_VL53L0X.h e cria o objeto sensor. Na função setup() inicializamos o sensor via sensor.begin(). Na função loop(), precisamos criar um objeto measure que recebe os dados da medição ao chamar sensor.rangingTest(). Se o valor de RangeStatus for 4, significa que nenhum objeto foi detetado e imprimimos “—“. Caso contrário, obtemos a distância de RangeMilliMeter e imprimimos.
Se carregares o código acima no teu Arduino, deverás ver valores de distância impressos no Monitor Serial. Se não houver nenhum objeto à frente do sensor ou estiver demasiado longe, verás “—” impresso.

Se tiveres problemas e o sensor não parecer funcionar, certifica-te de que a ligação está correta e que os pinos SDA e SCL corretos estão a ser usados no teu microcontrolador. Também podes verificar o diodo laser do sensor tirando uma foto com uma câmara digital (telemóvel). Embora a luz IR seja invisível ao olho humano, a câmara pode vê-la e no ecrã da câmara deverás ver o LED laser a piscar (a cada 100 ms).

Usando a Biblioteca VL53L0X da Pololu
Tive consideráveis dificuldades em fazer a Adafruit VL53L0X Library funcionar com código que usa a Adafruit_SSD1306 Library para mostrar as distâncias num OLED. Mais sobre isso na próxima secção.
Aqui só quero dar-te uma implementação alternativa que usa a VL53L0X Library by Pololu. Além de funcionar melhor com o ecrã OLED, também oferece mais opções de configuração para o VL53L0X. Por exemplo, podes alternar entre modo de longo ou curto alcance, e entre modo lento ou rápido.
Instalando a Biblioteca VL53L0X da Pololu
Para instalar a VL53L0X Library by pololu, basta procurar por VL53L0X, encontrar a da Pololu como mostrado abaixo e instalá-la usando o Library Manager. A imagem abaixo mostra como fica depois de instalada a biblioteca:

Exemplo de código para a Biblioteca VL53L0X da Pololu
E abaixo está o exemplo de código que usa a biblioteca da Pololu para o VL53L0X para medir distâncias:
#include "Wire.h"
#include "VL53L0X.h"
VL53L0X sensor;
void sensor_init(bool long_range, bool high_speed) {
Wire.begin();
sensor.setTimeout(500);
sensor.init();
if (long_range) {
sensor.setSignalRateLimit(0.1);
sensor.setVcselPulsePeriod(VL53L0X::VcselPeriodPreRange, 18);
sensor.setVcselPulsePeriod(VL53L0X::VcselPeriodFinalRange, 14);
}
int budget = high_speed ? 20000 : 200000;
sensor.setMeasurementTimingBudget(budget);
}
int get_distance() {
return sensor.readRangeSingleMillimeters();
}
void setup() {
Serial.begin(9600);
sensor_init(true, false);
}
void loop() {
Serial.println(get_distance());
}
Começamos por incluir a Wire.h e a VL53L0X.h biblioteca e depois criamos o objeto sensor.
A função sensor_init() configura o sensor. Permite alternar entre modo de curto ou longo alcance e entre alta e baixa velocidade de medição. Nota que os modos de longo alcance e rápido são menos precisos. As duas tabelas seguintes da datasheet mostram as compensações entre velocidade, alcance e precisão:


A função get_distance() retorna a distância medida em milímetros. Se o objeto estiver fora do alcance, o sensor retorna o valor 8190. Verifiquei que no modo de longo alcance podes medir até 2400 mm e no modo de curto alcance até 1300 mm. Isso foi feito dentro de casa contra uma parede branca.
Na função setup() inicializamos o sensor e na função loop() obtemos a distância e imprimimos no Monitor Serial.
Se carregares e executares o código, deverás ver as distâncias medidas impressas no Monitor Serial.

Nota que a saída começa com uma distância de 8190, indicando que nenhum objeto estava perto o suficiente do sensor para ser detetado. Depois apontei o sensor para o teto e obtive uma distância de cerca de 1700 mm e finalmente coloquei a minha mão à frente do sensor a cerca de 100 mm.
Na próxima secção vamos adicionar um OLED ao nosso circuito e depois usar ambas as bibliotecas (Adafruit, Pololu) para medir distâncias e mostrá-las.
Adicionar um OLED para mostrar dados do VL53L0X
Como o OLED também é um dispositivo I2C, ligá-lo é simples. Basta ligar SDA e SCL aos mesmos pinos onde o sensor VL53L0X está ligado. E como o OLED funciona a 3,3V, podemos também partilhar as linhas de alimentação.

A foto abaixo mostra a ligação completa numa breadboard real:

Se tiveres dificuldades com o OLED, dá uma vista de olhos ao tutorial How to Interface the SSD1306 I2C OLED Graphic Display With Arduino.
Instalar a Biblioteca Adafruit_SSD1306 para OLED
Nas duas secções seguintes vamos escrever código para mostrar a distância medida pelo sensor VL53L0X num ecrã OLED. Na primeira secção usaremos a biblioteca da Adafruit para o VL53L0X e na segunda usaremos a biblioteca da Pololu.
No entanto, antes de podermos mostrar qualquer coisa no OLED, precisamos instalar outra biblioteca. Neste tutorial, vamos usar a biblioteca Adafruit_SSD1306, que podes instalar via Library Manager como de costume. A imagem abaixo mostra a biblioteca após a instalação:

Nota que o endereço I2C para o ecrã OLED está definido para 0x3C em oled.begin(). A maioria destes pequenos OLEDs usa este endereço (or 0x27), mas o teu pode ser diferente. Se não vês nada no OLED, provavelmente tem um endereço I2C diferente e tens de alterar o endereço.
Se não souberes o endereço I2C, dá uma vista de olhos ao tutorial How to Interface the SSD1306 I2C OLED Graphic Display With Arduino para o encontrar. Também o tutorial Use SSD1306 I2C OLED Display With Arduino te vai explicar mais sobre como usar um OLED.
Mostrar distâncias medidas com a Biblioteca VL53L0X da Adafruit no OLED
O código abaixo usa a biblioteca da Adafruit para o VL53L0X para ler as medições de distância do sensor VL53L0X e depois mostrá-las no OLED. Dá uma vista de olhos ao código completo primeiro e depois explicamos os detalhes.
// Measure distance with VL53L0X sensor and show on OLED
// by Makerguides
#include "Adafruit_VL53L0X.h"
#include "Adafruit_SSD1306.h"
Adafruit_SSD1306 oled = Adafruit_SSD1306();
Adafruit_VL53L0X sensor = Adafruit_VL53L0X();
void oled_init() {
oled.begin(SSD1306_SWITCHCAPVCC, 0x3C);
oled.setTextSize(2);
oled.setTextColor(WHITE);
}
void display() {
VL53L0X_RangingMeasurementData_t measure;
sensor.rangingTest(&measure, false);
oled.clearDisplay();
oled.setCursor(25, 10);
if (measure.RangeStatus == 4) {
oled.print(" -----");
} else {
oled.print(measure.RangeMilliMeter);
oled.print(" mm");
}
oled.display();
}
void setup() {
oled_init();
sensor.begin();
}
void loop() {
display();
delay(100);
}
Bibliotecas
Começamos por incluir a Biblioteca Adafruit_VL53L0X para o sensor VL53L0X e a Adafruit_SSD1306 Library para o ecrã OLED.
#include "Adafruit_VL53L0X.h" #include "Adafruit_SSD1306.h"
Objetos
De seguida criamos os objetos sensor e oled:
Adafruit_SSD1306 oled = Adafruit_SSD1306(); Adafruit_VL53L0X sensor = Adafruit_VL53L0X();
Função oled_init
A função oled_init() inicializa o OLED e define o tamanho e a cor do texto:
void oled_init() {
oled.begin(SSD1306_SWITCHCAPVCC, 0x3C);
oled.setTextSize(2);
oled.setTextColor(WHITE);
}
Nota que o endereço I2C para o ecrã OLED está definido para 0x3C em oled.begin(). A maioria destes pequenos OLEDs usa este endereço, mas o teu pode ser diferente. Se não vês nada no OLED, provavelmente tem um endereço I2C diferente e tens de alterar o endereço. Se não souberes o endereço I2C, dá uma vista de olhos ao tutorial How to Interface the SSD1306 I2C OLED Graphic Display With Arduino.
Função display
A função display() chama primeiro rangingTest() para medir a distância. Depois limpamos o ecrã, definimos a posição do cursor e imprimimos a distância. Se não for possível medir a distância (RangeStatus == 4), mostramos “—-” para indicar que nenhum objeto estava ao alcance:
void display() {
VL53L0X_RangingMeasurementData_t measure;
sensor.rangingTest(&measure, false);
oled.clearDisplay();
oled.setCursor(25, 10);
if (measure.RangeStatus == 4) {
oled.print(" -----");
} else {
oled.print(measure.RangeMilliMeter);
oled.print(" mm");
}
oled.display();
}
Funções setup e loop
Na função setup() chamamos os inicializadores para o OLED e para o sensor VL53L0X, e na função loop() mostramos a distância medida a cada 100 ms:
void setup() {
oled_init();
sensor.begin();
}
void loop() {
display();
delay(100);
}
Problemas com a biblioteca Adafruit_VL53L0X
Ao escrever o código acima, encontrei vários problemas. Primeiro, não consegui usar o meu código habitual para criar o objeto OLED:
Adafruit_SSD1306 oled(128, 64, &Wire, -1);
Em segundo lugar, não consegui usar a função sprintf() para imprimir texto formatado num buffer para ser mostrado no OLED.
Em ambos os casos, o código compilava, podia ser carregado, mas o programa não corria, sem mostrar mensagens de erro. Suspeito que haja algum conflito de acesso à memória entre as bibliotecas Adafruit_SSD1306 e Adafruit_VL53L0X.
Devido a estes problemas com a biblioteca Adafruit_VL53L0X, decidi experimentar outra biblioteca. Na secção seguinte, mostro-te o código que usa a Biblioteca VL53L0X da Pololu.
Mostrar distâncias medidas com a Biblioteca VL53L0X da Pololu no OLED
O código abaixo usa a biblioteca da Pololu para o VL53L0X para ler as medições de distância do sensor VL53L0X e mostrá-las no OLED.
#include "Wire.h"
#include "VL53L0X.h"
#include "Adafruit_SSD1306.h"
Adafruit_SSD1306 oled(128, 64, &Wire, -1);
VL53L0X sensor;
const int maxdist = 2400;
void sensor_init(bool long_range, bool high_speed) {
Wire.begin();
sensor.setTimeout(500);
sensor.init();
if (long_range) {
sensor.setSignalRateLimit(0.1);
sensor.setVcselPulsePeriod(VL53L0X::VcselPeriodPreRange, 18);
sensor.setVcselPulsePeriod(VL53L0X::VcselPeriodFinalRange, 14);
}
int budget = high_speed ? 20000 : 200000;
sensor.setMeasurementTimingBudget(budget);
}
int get_distance() {
return sensor.readRangeSingleMillimeters();
}
void oled_init() {
oled.begin(SSD1306_SWITCHCAPVCC, 0x3C);
oled.setTextSize(2);
oled.setTextColor(WHITE);
}
void display() {
static char text[30];
int dist = get_distance();
if (dist > maxdist)
sprintf(text, " -----");
else
sprintf(text, "%4d mm", dist);
oled.clearDisplay();
oled.setCursor(20, 25);
oled.print(text);
int w = map(dist, 0, maxdist, 0, 120);
oled.drawFastHLine(4, 45, w, WHITE);
oled.display();
}
void setup() {
oled_init();
sensor_init(true, false);
}
void loop() {
display();
}
Se carregares e executares o código, deverás ver distâncias em milímetros a ser mostradas no OLED com uma barra por baixo proporcional em comprimento à distância.

Se não houver nada à frente do sensor (ou estiver a mais de 2 m), o ecrã mostrará “a distância máxima “—–” e uma linha de comprimento total.

Bibliotecas
Começamos por incluir as bibliotecas necessárias para o OLED e para o VL53L0X. Neste exemplo de código, usamos a Biblioteca VL53L0X da Pololu para ler dados de distância do sensor VL53L0X.
#include "Wire.h" #include "VL53L0X.h" #include "Adafruit_SSD1306.h"
Objetos e Constantes
De seguida criamos os objetos oled e sensor. Com a Biblioteca VL53L0X da Pololu não tive dificuldade em criar o objeto oled da forma habitual (oled(128, 64, &Wire, -1)), enquanto este código não funcionava ao usar a Biblioteca VL53L0X da Adafruit.
Adafruit_SSD1306 oled(128, 64, &Wire, -1); VL53L0X sensor; const int maxdist = 2400;
A constante maxdist especifica a distância máxima que o código reportará nas medições. Para além disso, o código indicará que nenhum objeto foi detetado.
Funções sensor_init e get_distance
As funções sensor_init() e get_distance() são iguais às anteriores. sensor_init() inicializa o sensor VL53L0X e define os diferentes modos de operação, enquanto get_distance() lê a distância medida do VL53L0X.
void sensor_init(bool long_range, bool high_speed) {
Wire.begin();
sensor.setTimeout(500);
sensor.init();
if (long_range) {
sensor.setSignalRateLimit(0.1);
sensor.setVcselPulsePeriod(VL53L0X::VcselPeriodPreRange, 18);
sensor.setVcselPulsePeriod(VL53L0X::VcselPeriodFinalRange, 14);
}
int budget = high_speed ? 20000 : 200000;
sensor.setMeasurementTimingBudget(budget);
}
int get_distance() {
return sensor.readRangeSingleMillimeters();
}
Função oled_init
A função oled_init() também permanece inalterada. Inicializa o OLED e define o tamanho e a cor do texto.
void oled_init() {
oled.begin(SSD1306_SWITCHCAPVCC, 0x3C);
oled.setTextSize(2);
oled.setTextColor(WHITE);
}
Função display
A função display() obtém a distância medida do sensor VL53L0X. Se a distância for maior que maxdist, assume que nenhum objeto estava ao alcance e imprime “—–” no OLED. Caso contrário, imprime o valor da distância.
void display() {
static char text[30];
int dist = get_distance();
if (dist > maxdist)
sprintf(text, " -----");
else
sprintf(text, "%4d mm", dist);
oled.clearDisplay();
oled.setCursor(20, 25);
oled.print(text);
int w = map(dist, 0, maxdist, 0, 120);
oled.drawFastHLine(4, 45, w, WHITE);
oled.display();
}
Além da saída de texto, a função display() também desenha uma linha horizontal por baixo do texto com um comprimento proporcional à distância medida.
Funções setup e loop
A função setup inicializa o OLED e o sensor VL53L0X. O modo do sensor é definido para longo alcance e velocidade padrão (sensor_init(true, false)).
Na função loop() chamamos simplesmente a função display(). O loop corre à velocidade máxima que o sensor pode fornecer dados (cerca de 30 ms na velocidade padrão)
void setup() {
oled_init();
sensor_init(true, false);
}
void loop() {
display();
}
E é isso. Agora tens a tua própria ferramenta de medição de distância
Conclusões
Neste tutorial aprendeste a usar o Sensor de Distância VL53L0X com um Arduino para medir distâncias e mostrá-las num OLED.
O Sensor VL53L0X é um sensor muito pequeno, rápido e de alta precisão que usa luz laser infravermelha para medir distâncias. O VL53L0X é muito semelhante ao sensor TOF10120 em dimensão, função e características. Ambos os sensores usam o método Time-of-Flight para calcular a distância a um objeto. O VL53L0X tem mais opções de configuração (longo alcance, velocidade rápida) e pode, no modo de longo alcance, detetar objetos a uma distância ligeiramente maior (2400 mm vs 1800 mm), embora com precisão reduzida.
Outros sensores de distância infravermelhos, como o GP2Y0A710K0F ou o GP2Y0A21YK0F usam triangulação para determinar a distância com base no ângulo da luz IR refletida e têm alcance mais curto e menor precisão.
Se tiveres alguma dúvida, sente-te à vontade para deixar nos comentários.
Boas experiências ; )

