Usando Múltiplos Sensores de Distância Laser VL53L0X

O VL53L0X é um sensor de distância infravermelho de alta precisão divulgado pela STMicroelectronics (sua fabricante) como o menor no mercado. Ele faz uso de um VCSEL (Laser Emissor de Superfície de Cavidade Vertical) com filtros que evitam a interferência de luzes externas e proporcionam um maior alcance ao sensor.

Ele funciona como um sensor reflexivo do tipo Time of Flight (ToF), emitindo uma luz invisível ao olho humano que retorna ao sensor após ser refletida por um obstáculo. A duração desse processo é então usada para calcular a distância até o obstáculo detectado, podendo alcançar até 2 metros.

O módulo VL53L0X (também encontrado como GY-VL53L0XV2, CJVL53L0XV2 ou VL53L0XV2) é uma escolha perfeita para projetos com os mais diversos  tipos de placas Arduino pois além de ser compacto e preciso, ele também possui um regulador de tensão integrado que o permite ser alimentado tanto por 3V quanto por 5V. Ele pode ser encontrado em uma variedade de cores incluindo azul, preto, verde e roxo; todas com as mesmas funcionalidades.

A comunicação do módulo VL53L0X é realizada através da interface I2C. Porém, o Arduino possui um número bastante limitado de portas contendo esta interface.

Imagine que temos um robô ou um carrinho de controle remoto e precisamos usar mais de um sensor para criar um sistema de detecção de colisão. O que fazer nesse caso? É isso que vamos ensinar nessa postagem.

Componentes necessários

Para seguir este tutorial, você precisará dos seguintes itens:

O datasheet do VL53L0X pode ser encontrado aqui.

Módulo VL53L0X

Pinagem

Além de pinos de alimentação (VIN e GND), o módulo VL53L0X possui dois pinos dedicados a comunicação I2C (SCL e SDA), um pino de reset (XSHUT) e um pino de saída de dados (GPIO1) que pode ser utilizado para programar interrupções no microcontrolador ao qual o sensor está ligado.

Imagem 1 — Módulo VL53L0X

Na tabela abaixo estão descritas as funcionalidades de cada pino.

Imagem 2 — Descrição dos pinos do VL53L0X

Endereçamento

O módulo possui um endereçamento de 7-bits que por padrão possui o valor binário 0101001 (41 na base decimal) quando ligado. Porém, ele permite sobrescrever os registradores de configuração do sensor para que um novo endereço seja atribuído. Este novo endereço será válido apenas enquanto o sensor permanecer ligado, voltando à configuração padrão ao ser reiniciado ou desligado.

Pino XSHUT

O pino XSHUT possui um resistor de pull-up que o leva a estado lógico alto (HIGH) quando o VL53L0X é alimentado. O reset é ativado quando levado a nível lógico baixo (LOW), fazendo o sensor entrar em modo standby.

Para que possamos configurar diferentes endereços para diferentes módulos VL53L0X conectados às mesmas portas I2C, precisamos desligar sequencialmente cada placa usando o pino XSHUT (cada um conectado a um pino digital diferente do Arduino) e em seguida ligar os módulos para atribuir seus novos endereços.

É importante ressaltar que o XSHUT não é tolerante a tensões de 5V, não sendo possível realizar operações de escrita nesse pino a partir do Arduino Uno ou outras placas de 5V. Mas então como vamos manipular este pino?

Inicializando o XSHUT como OUTPUT, ele entrará em um estado de baixa impedância e será ativado. Mudando o pinMode para INPUT, o pino entra em um estado de alta impedância, sendo “puxado” para uma tensão de 2.8V por seu resistor de pull-up.

Montando o Circuito

Em nosso circuito de exemplo, vamos supor que estamos construindo um carrinho com um sistema de detecção de colisão nas partes dianteira e traseira. Além do sensor de distância, usaremos também o módulo de buzzer passivo YL-44 que será acionado quando o sensor detectar algum objeto. A distância de detecção será configurada mais à frente através do código.

O módulo YL-44 possui três pinos. Um para alimentação de 5V (VCC), outro para o terra (GND) e o pino do meio (I/O) é ligado a um transistor que controla o sinal que chega ao pino e faz com que o som emitido pelo buzzer saia de maneira mais limpa. O pino I/O será ligado ao pino digital 13 do Arduino.

Os pinos SDA e SCL de ambos os VL53L0X devem ser ligados respectivamente aos pinos analógicos A4 e A5 de nosso Arduino Uno, que são os pinos utilizados pela placa para a interface I2C. Também temos acesso aos pinos SDA e SCL de nosso Arduino Uno acima do pino AREF como ilustrado na imagem.

O XSHUT de cada sensor deve ser ligado a um pino digital diferente. Usaremos os pinos 6 e 7 do Arduino.

Para alimentar os sensores, devemos ligar o VIN ao 5V do Arduino e o GND ao GND do Arduino.

Imagem 3 — Montagem do circuito

Caso o seu VL53L0X seja novo, não esqueça de remover a película de plástico protetora para que o sensor funcione corretamente.

Programando

VL53L0X

Antes de começarmos a escrever nosso código, devemos baixar a biblioteca que nos permitirá controlar nosso sensor de distância.

Na barra de menu no topo da IDE do Arduino, navegue até Sketch -> Incluir Biblioteca -> Gerenciador de Bibliotecas… e pesquise por “VL53L0X.” Em seguida, instale a biblioteca VL53L0X criada pela Pololu Robotics and Electronics.

Imagem 4 — Biblioteca VL53L0X

Após a instalação, a primeira coisa que devemos fazer é importar a biblioteca do sensor e também a biblioteca Wire, pois o sensor faz uso de ambas:

Em seguida vamos definir os pinos do Arduino aos quais os pinos XSHUT dos sensores VL53L0X estão conectados:

E o endereço de cada sensor. Lembrando que o endereço padrão do sensor é 41.

Como estamos usando dois sensores, bastaria configurar o endereço apenas do segundo sensor, mas vamos mostrar o processo completo para que você saiba como expandir seu projeto a partir deste tutorial.

Vamos agora criar os objetos responsáveis pelo controle de cada sensor:

E definir um limiar de detecção para os sensores. Como estes valores não serão alterados durante a execução do código, eles serão declarados como constantes.

Vamos fazer a medição em centímetros, detectando obstáculos entre 0 e 25cm dos sensores. Objetos mais distantes que isso não serão detectados.

Caso queira uma distância diferente, basta alterar os valores destas variáveis.

Teremos também uma variável de controle para indicar a detecção de objetos dentro do limite demarcado:

setup()

Entrando na função setup(), vamos desligar todos os sensores configurando os pinos XSHUT como OUTPUT:

Agora devemos ligar os sensores um a um configurando-os como INPUT e em seguida atribuir o novo endereço através do método setAddress().

Depois inicializamos os sensores:

E definimos um timeout em milissegundos:

Se o sensor não estiver conectado, preparado ou funcionando corretamente, a operação de leitura será abortada após o período de timeout que definimos.

Por último, precisamos definir um tipo de leitura para os sensores. Vamos usar uma leitura contínua para que os obstáculos sejam detectados o mais rápido possível. Isso é configurado através do método startContinuous():

Também podemos configurar as leituras para serem acionadas em intervalos fixos de tempo passando um valor em milissegundos para esse método.

loop()

No loop() vamos chamar uma função que criaremos com o nome lerSensores():

Dentro de lerSensores(), vamos fazer a leitura dos sensores utilizando o método readRangeContinuousMillimeters() e convertê-la para centímetros ao multiplicar o resultado por 0,1.

E será verificado se o objeto que o sensor detectou está dentro dos limites que definimos no início do código. Se estiver, o valor da variável detectado se torna true.

Lembrando que para imprimir valores no monitor serial devemos antes inicializá-lo dentro do setup() usando o método Serial.begin().

Buzzer

Para controlar o buzzer, vamos nos basear no exemplo BlinkWithoutDelay disponível na IDE do Arduino que usa a função millis() para detectar a passagem de tempo e determinar quando está na hora de acionar ou desligar um LED (no nosso caso, substituiremos o LED por um buzzer). Esta função retorna a quantidade de tempo (em milissegundos) que se passou desde que o programa foi iniciado.

Faremos isso para evitar o uso da função delay(), que pode interferir nas leituras do VL53L0X.

Como variáveis globais teremos três constantes: o pino ao qual o buzzer está ligado (pino 13), a frequência do som que vai emitir e o intervalo de tempo (em milissegundos) entre o estado lógico alto e estado lógico baixo (equivalente a um delay).

Teremos também duas variáveis, uma para armazenar o momento em que o estado do buzzer foi trocado pela última vez e outra para armazenar o estado atual do buzzer.

Como estamos trabalhando com tempo, é importante que previousMillis seja capaz de armazenar valores grandes e por isso ela deve ser declarada como unsigned long.

Dentro do setup(), o buzzer deve ser configurado como OUTPUT:

No loop(), além da função lerSensores(), chamaremos uma segunda função que vamos criar com o nome processaBuzzer():

Esta função será responsável por nosso “blink sem delay” e será ativada apenas quando um obstáculo for detectado pelo VL53L0X (verificado pelo primeiro if). Será então verificado se a diferença entre o tempo de execução do programa e a última vez em que o buzzer foi tocado é maior ou igual ao intervalo que definimos no início do código (nosso “delay”). Se esse for o caso, o estado do buzzer é alterado e o tempo atual é armazenado para uma verificação futura.

Código completo

Segue o código completo de nosso projeto. Ele pode ser incrementado para adicionar outros sensores VL53L0X, possibilitando assim a detecção de colisão em outros ângulos.

Gostou? Deixe seu comentário logo abaixo, não deixe de conferir outras postagens do nosso blog. Confira também a nossa loja virtual e encontre todos os componentes utilizados no projeto no post.

Gabriel Martins de Freitas

Graduando em Sistemas e Mídias Digitais. Tenho experiência com Arduino e ESP8266. Atualmente compartilhando meu conhecimento no blog da Smart Kits.

Post navigation

Deixe um Comentário

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Robô Otto e a Robótica Educativa

Conhecendo o Arduino Mega 2560

Módulo Bluetooth AT-09 com Arduino