Skip to Content

Capteur de distance VL53L1X/TOF400C avec Arduino

Capteur de distance VL53L1X/TOF400C avec Arduino

Dans ce tutoriel, vous apprendrez à utiliser le capteur de distance laser VL53L1X (également appelé TOF400C) avec un Arduino ou tout autre microcontrôleur courant (ESP32/ESP8266) pour mesurer des distances.

Le VL53L1X est un capteur de distance Time-of-Flight (ToF) très compact qui utilise un laser infrarouge pour mesurer la proximité d’un objet. En mesurant le temps que met la lumière à être réfléchie par un objet, il peut calculer des distances avec une grande précision.

Pièces requises

Vous aurez besoin d’un capteur de distance VL53L1X. Pour le microcontrôleur, j’ai utilisé un Arduino Uno pour ce projet, mais tout autre Arduino ou ESP32/ESP8266 fonctionnera également. Nous utiliserons aussi un écran OLED pour afficher les distances mesurées par le VL53L1X.

Capteur de distance VL53L1X

Arduino

Arduino Uno

USB Data Sync cable Arduino

Câble USB pour Arduino UNO

Dupont wire set

Jeu de fils Dupont

Half_breadboard56a

Plaque d’essai (breadboard)

OLED display

Écran 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.

Caractéristiques du VL53L1X

Le VL53L1X est une puce minuscule (4,4 x 2,5 x 1,56 mm) avec deux ouvertures sur le dessus. Une pour l’émetteur laser et une pour le détecteur de lumière. Le VL53L1X fonctionne en envoyant une impulsion laser depuis l’émetteur, en recevant la lumière réfléchie par un objet via le détecteur, puis en calculant la distance à partir du temps de vol de la lumière. L’image ci-dessous montre les cônes de l’émetteur et du détecteur.

Principe de fonctionnement du VL53L1X (source)

Voici les principales spécifications du VL53L1X :

  • Émetteur VCSEL 940 nm (lumière IR, invisible à l’œil)
  • Temps de mesure de 20 ms à 1000 ms
  • Taille programmable de la région d’intérêt (ROI)
  • Position programmable de la ROI sur la matrice de réception
  • Trois modes de distance : court, moyen et long
  • Distance entre 4 cm et 400 cm
  • Résolution : 1 mm
  • Tension : 2,6 à 3,5 V
  • Interface de communication I2C (jusqu’à 400 kHz)

Les régions d’intérêt programmables (ROI) du VL53L1X permettent de réduire ou de diviser le champ de vision en plusieurs zones. Vous pouvez utiliser cela pour implémenter la reconnaissance de gestes, comme un balayage par exemple. Pour plus de détails, consultez la fiche technique du capteur VL53L1X :

VL53L1X dans un système LiDAR

Les capteurs de distance laser ont de nombreuses applications, comme l’alerte de proximité de stationnement, la détection d’intrus, l’évitement d’obstacles en robotique, et plus encore. Surtout, les capteurs laser sont couramment utilisés dans les LiDAR systèmes, qui signifie Light Detection et Ranging et servent à créer des cartes et modèles 3D très précis.

En plus du capteur laser, un système LiDAR comprend généralement une unité GPS et une unité de mesure inertielle (IMU). Le scanner est un mécanisme qui déplace le faisceau laser sur une large zone, permettant au système de capturer des données sous différents angles et positions. L’unité GPS fournit des données de localisation précises. Enfin, l’IMU suit l’orientation et le mouvement du système LiDAR, ce qui est crucial pour maintenir la précision lors du balayage.

Au fur et à mesure que les impulsions laser sont émises et réfléchies, le système enregistre continuellement les mesures de distance ainsi que leurs angles et positions correspondants. Ces données sont ensuite utilisées pour créer un nuage de points, représentant la distribution spatiale des objets dans la zone scannée.

Vous pouvez construire un LiDAR simple vous-même en fixant le capteur laser sur un servo et en utilisant ce servo pour scanner l’environnement, tandis que le capteur mesure les distances. Cependant, dans ce tutoriel, nous utiliserons uniquement le capteur laser, sans dispositif de balayage.

Schéma d’application du VL53L1X

Le schéma d’application suivant montre le câblage externe nécessaire pour utiliser la puce VL53L1X. Vous pouvez voir les résistances de tirage pour l’interface I2C qui connecte le VL53L1X à un microcontrôleur (hôte), ainsi que deux condensateurs qui stabilisent l’alimentation.

Application Schematic of VL53L1X
Schéma d’application du VL53L1X (source)

SDA et SCL sont les broches pour l’interface I2C. XSHUT est la broche d’arrêt, qui permet d’éteindre le capteur lorsqu’elle est tirée à la masse. Cela est utile si vous souhaitez connecter plusieurs capteurs VL53L1X sur la même ligne I2C. GPIO1 est une broche d’interruption qui peut signaler au microcontrôleur que des données sont prêtes.

Cependant, au lieu d’utiliser directement la petite puce VL53L1X, il est préférable d’acheter une carte breakout qui intègre déjà l’électronique ci-dessus et est beaucoup plus facile à connecter.

Carte breakout pour VL53L1X

L’image suivante montre le verso et le recto d’une carte breakout typique pour le VL53L1X. La puce capteur se trouve derrière la protection ovale. Cette protection réduit l’impact de la lumière ambiante sur la précision du capteur.

Carte breakout pour VL53L1X (source)

Le brochage est le même que celui discuté précédemment : SDA, SCL pour I2C, GPIO1 comme signal d’interruption, XSHUT pour la sélection de la puce, et VIN et GND pour l’alimentation.

Connexion du VL53L1X

Grâce à l’interface I2C du VL53L1X, le connecter à un Arduino est simple. Commencez par relier les broches SCL et SDA de la carte breakout VL53L1X aux broches correspondantes de l’Arduino comme montré ci-dessous. Ensuite, connectez la masse à GND et le 3,3 V à VIN du VL53L1X.

Connecting VL53L1X with Arduino
Connexion du VL53L1X avec Arduino

La carte breakout VL53L1X fonctionne en 5 V ou 3,3 V et vous pouvez utiliser l’un ou l’autre pour VIN. Ici, j’utilise 3,3 V pour VIN. Passons maintenant à l’écriture du code pour tester le fonctionnement du capteur VL53L1X.

Code pour mesurer la distance avec VL53L1X

Avant de pouvoir mesurer des distances avec le capteur VL53L1X, vous devrez installer une bibliothèque. Les plus courantes sont la Adafruit VL53L1X Library et la VL53L1X Library by Pololu. Cependant, j’ai rencontré des problèmes avec les bibliothèques Adafruit lors de la rédaction du tutoriel pour le VL53L0X Distance Sensor, et j’utiliserai donc la VL53L1X Library by Pololu. Elle offre aussi plus d’options de configuration pour le VL53L1X.

Installation de la bibliothèque VL53L1X par Pololu

Pour installer la VL53L1X Library by Pololu, ouvrez le Library Manager, cherchez VL53L1X, trouvez celle de Pololu et installez-la. L’image ci-dessous montre à quoi cela ressemble une fois la bibliothèque installée :

Installing VL53L1X Library by Pololu via Library Manager
Installation de la bibliothèque VL53L1X par Pololu via le Library Manager

Avec la bibliothèque installée, testons le capteur. Le code suivant lit les distances mesurées par le VL53L1X et les affiche dans le moniteur série.

#include "VL53L1X.h"

VL53L1X sensor;

void sensor_init(VL53L1X::DistanceMode range_mode, bool high_speed) {
  Wire.begin();
  sensor.setTimeout(500);
  sensor.init();
  sensor.setDistanceMode(range_mode);  
  int budget = high_speed ? 33000 : 140000;
  sensor.setMeasurementTimingBudget(budget);
}

void setup() {
  Serial.begin(9600);
  // range_mode: VL53L1X::Short, VL53L1X::Medium, or VL53L1X::Long
  sensor_init(VL53L1X::Medium, false);   
}

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

Décomposons le code en ses composants pour mieux le comprendre.

Inclusion de la bibliothèque

Le code commence par inclure la bibliothèque nécessaire pour le capteur VL53L1X. Cette bibliothèque fournit les fonctions nécessaires pour communiquer avec le capteur.

#include "VL53L1X.h"

Création d’un objet capteur

Ensuite, nous créons une instance de la classe VL53L1X, qui nous permet d’interagir avec le capteur.

VL53L1X sensor;

Fonction d’initialisation du capteur

La fonction sensor_init() est responsable de l’initialisation du capteur. Elle prend deux paramètres : range_mode qui spécifie le mode de mesure de distance, et high_speed qui détermine le budget de temps de mesure.

void sensor_init(VL53L1X::DistanceMode range_mode, bool high_speed) {
  Wire.begin();
  sensor.setTimeout(500);
  sensor.init();
  sensor.setDistanceMode(range_mode);  
  int budget = high_speed ? 33000 : 140000;
  sensor.setMeasurementTimingBudget(budget);
}

Dans cette fonction :

  • Wire.begin(); initialise la communication I2C.
  • sensor.setTimeout(500); définit un délai d’attente pour les opérations du capteur.
  • sensor.init(); initialise le capteur.
  • sensor.setDistanceMode(range_mode); définit le mode de distance selon le paramètre d’entrée.
  • Le budget de temps de mesure est défini selon que la haute vitesse est demandée ou non.

Selon la datasheet, le budget de temps du VL53L1X doit être réglé comme suit.

  • 20 ms est le budget de temps minimum et ne peut être utilisé qu’en mode courte distance.
  • 33 ms est le budget de temps minimum qui fonctionne pour tous les modes de distance.
  • 140 ms est le budget de temps qui permet d’atteindre la distance maximale de 4 m (dans l’obscurité sur un tableau blanc) en mode longue distance.

Dans le code, j’utilise 33 ms pour le mode rapide, car il fonctionne avec toutes les portées, sinon 140 ms, car il permet la distance maximale.

Pour la portée, vous pouvez utiliser les constantes prédéfinies VL53L1X::Short, VL53L1X::Medium, ou VL53L1X::Long. La portée mesurable dépend du mode choisi et de la lumière ambiante. Le tableau suivant extrait de la datasheet du VL53L1X montre ces dépendances :

Maximum distance vs. distance mode under ambient light for VL53L1X
Distance maximale vs mode de distance sous lumière ambiante pour VL53L1X

Le mode longue distance permet d’atteindre la plus grande portée possible, jusqu’à 4 m, dans des conditions idéales (obscurité). En général, la portée est affectée par la lumière ambiante. Le mode courte distance est plus résistant à la lumière ambiante, mais sa portée maximale est généralement limitée à 1,3 m.

Fonction Setup

Dans la fonction setup(), nous démarrons la communication série et initialisons le capteur avec un mode de distance spécifique.

void setup() {
  Serial.begin(9600);
  // range_mode: VL53L1X::Short, VL53L1X::Medium, or VL53L1X::Long
  sensor_init(VL53L1X::Medium, false);   
}

Ici, Serial.begin(9600); configure le moniteur série à un débit de 9600 bauds. La fonction sensor_init() est appelée avec VL53L1X::Medium comme mode de portée et false pour la haute vitesse, ce qui signifie que le capteur fonctionnera en portée moyenne avec un budget de temps plus long.

Fonction Loop

Enfin, dans la fonction loop(), nous lisons continuellement la distance du capteur et l’affichons dans le moniteur série.

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

Si vous téléversez et exécutez le code, vous devriez voir les distances mesurées s’afficher dans le moniteur série.

Distances measured with VL53L1X printed on Serial Monitor
Distances mesurées avec VL53L1X affichées dans le moniteur série

Dans la section suivante, nous allons ajouter un écran OLED à notre circuit pour afficher les distances dessus, au lieu de les imprimer dans le moniteur série.

Ajout d’un OLED pour afficher les données du VL53L1X

Comme l’OLED est aussi un dispositif I2C, sa connexion est simple. Il suffit de connecter SDA et SCL aux mêmes broches que le capteur VL53L1X. Et comme l’OLED fonctionne en 3,3 V, nous pouvons aussi partager les lignes d’alimentation.

Connecting OLED and VL53L1X with Arduino
Connexion de l’OLED et du VL53L1X avec Arduino

Code pour afficher les distances mesurées par le VL53L1X sur OLED

Le code suivant lit les mesures de distance du capteur VL53L1X et les affiche sur l’OLED. Jetez un coup d’œil rapide au code complet, puis nous en discuterons les détails.

#include "Wire.h"
#include "VL53L1X.h"
#include "Adafruit_SSD1306.h"

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

void sensor_init(VL53L1X::DistanceMode range_mode, bool high_speed) {
  Wire.begin();
  sensor.setTimeout(500);
  sensor.init();
  sensor.setDistanceMode(range_mode); 
  int budget = high_speed ? 33000 : 140000;
  sensor.setMeasurementTimingBudget(budget);
}

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(VL53L1X::Medium, false); 
}

void loop() {
  display();
}

Décomposons le code en ses parties pour mieux le comprendre.

Inclusions de bibliothèques

Au début du code, nous incluons les bibliothèques nécessaires pour notre projet. La bibliothèque Wire.h est utilisée pour la communication I2C, VL53L1X.h pour l’interface avec le capteur de distance VL53L1X, et Adafruit_SSD1306.h pour contrôler l’écran OLED.

#include "Wire.h"
#include "VL53L1X.h"
#include "Adafruit_SSD1306.h"

Si vous n’avez pas encore installé la Adafruit_SSD1306 Library, vous devrez le faire. Installez-la simplement via le Library Manager comme d’habitude :

Adafruit_SSD1306 library installed in Library Manager
Bibliothèque Adafruit_SSD1306 installée dans le Library Manager

Notez que l’adresse I2C de l’écran OLED est réglée sur 0x3C dans oled.begin(). La plupart de ces petits OLED utilisent cette adresse (or 0x27) mais la vôtre peut être différente. Si vous ne voyez rien sur l’OLED, il est probable qu’il ait une adresse I2C différente et vous devrez la modifier.

Si vous ne connaissez pas l’adresse I2C, consultez le tutoriel How to Interface the SSD1306 I2C OLED Graphic Display With Arduino pour la trouver. Le tutoriel Use SSD1306 I2C OLED Display With Arduino vous expliquera aussi comment utiliser un OLED.

Initialisation des objets

Ensuite, nous créons des instances de l’écran OLED et du capteur de distance. L’écran OLED est initialisé avec une largeur de 128 pixels et une hauteur de 64 pixels. Le paramètre &Wire indique que nous utilisons la bibliothèque Wire pour la communication I2C, et -1 indique que nous n’utilisons pas de broche de reset.

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

Fonction d’initialisation du capteur

La fonction sensor_init() initialise le capteur VL53L1X. Elle prend deux paramètres : range_mode pour définir le mode de mesure de distance et high_speed pour déterminer le budget de temps de mesure. Dans la fonction, nous démarrons la communication I2C, définissons un délai d’attente pour le capteur, l’initialisons et configurons le mode de distance. Le budget de temps est réglé selon que la haute vitesse est activée ou non.

void sensor_init(VL53L1X::DistanceMode range_mode, bool high_speed) {
  Wire.begin();
  sensor.setTimeout(500);
  sensor.init();
  sensor.setDistanceMode(range_mode); 
  int budget = high_speed ? 33000 : 140000;
  sensor.setMeasurementTimingBudget(budget);
}

Fonction d’initialisation de l’OLED

La fonction oled_init() initialise l’écran OLED. Elle commence par alimenter l’écran en utilisant le paramètre SSD1306_SWITCHCAPVCC et en réglant l’adresse I2C à 0x3C. Nous réglons aussi la taille du texte à 2 et la couleur du texte en blanc.

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

Fonction d’affichage

La fonction display() est responsable de la lecture de la distance du capteur et de son affichage sur l’écran OLED. Elle déclare d’abord un tableau de caractères statique text pour contenir la chaîne de distance. La distance est lue en millimètres avec sensor.readRangeSingleMillimeters(), et le résultat est formaté dans le tableau text avec sprintf(). L’écran OLED est ensuite effacé, le curseur positionné, et la distance affichée. Enfin, l’écran est mis à jour pour montrer le nouveau contenu.

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();
}

Fonction Setup

Dans la fonction setup(), nous appelons les fonctions d’initialisation pour l’écran OLED et le capteur de distance. Le capteur est initialisé en mode portée moyenne avec la haute vitesse désactivée.

void setup() {
  oled_init();
  sensor_init(VL53L1X::Medium, false); 
}

Fonction Loop

Enfin, la fonction loop() appelle en boucle la fonction display(), qui met à jour l’écran OLED avec la dernière mesure de distance du capteur. Cette boucle tourne indéfiniment, fournissant des mesures de distance en temps réel.

void loop() {
  display();
}

Conclusions

Dans ce tutoriel, vous avez appris à utiliser le capteur de distance VL53L1X avec un Arduino pour mesurer des distances et les afficher sur un écran OLED.

Le capteur VL53L1X est un capteur très petit, rapide et précis qui utilise un laser infrarouge pour mesurer les distances. Le VL53L1X est presque identique au VL53L0X mais offre une portée plus grande. Le premier peut mesurer jusqu’à 400 cm, tandis que le second est limité à 200 cm. Si vous avez besoin d’un capteur pour une portée beaucoup plus grande, regardez le TF Luna qui peut mesurer jusqu’à 8 mètres.

Un autre capteur de distance laser similaire utilisant la méthode Time-of-Flight est le capteur TOF10120. Cependant, le VL53L1X offre plus d’options de configuration (longue portée, haute vitesse) et une portée plus grande (jusqu’à 400 cm contre 180 cm).

D’autres capteurs infrarouges courants comme le GP2Y0A710K0F ou le GP2Y0A21YK0F utilisent la triangulation pour déterminer la distance en fonction de l’angle de la lumière IR réfléchie, avec une portée plus courte et une précision moindre.

Si vous avez des questions, n’hésitez pas à les poser dans la section commentaires.

Bon bricolage ; )