ST Microelectronics commercialise plusieurs types de capteurs de distance reposants sur la mesure du temps que met un faisceau laser à faire l’aller-retour entre le capteur et la cible. Cette technologie est présentée comme précise et robuste à la couleur de la cible et à l’éclairage ambiant. Voyons voir ce qu’il en est.
Le capteur VL6180X
.
Par :
DIFFICULTÉ :★★☆
Détecter la présence de matériel roulant est un problème récurrent en modélisme ferroviaire. Les applications sont multiples : sécurité des circulations ou automatisme comme les passages à niveau. Plusieurs technologies peuvent être mises en œuvre : détection de consommation, ILS + aimants sur le matériel, masquage de la lumière ambiante ou dispositifs optiques. Le capteur que nous allons examiner appartient à cette dernière catégorie. Plusieurs expérimentations menées par des Locoduinistes ont déjà eu lieu et un fil du forum y est consacré.
Les capteurs optiques fonctionnent selon différents principes. Le plus souvent, la détection est de type tout ou rien, soit par coupure d’un faisceau, soit par réflection. Dans le premier cas on va disposer de part d’autre de la voie une diode infrarouge (IR) et un récepteur, phototransistor ou photodiode. Si aucun matériel roulant n’interrompt le faisceau le photo-élément est excité par la diode IR et sinon il ne l’est pas. Dans le second cas, émetteur et récepteur sont positionnés du même côté de la voie et le matériel roulant, si il est présent, va réfléchir le faisceau IR. Si ils ont le mérite de la simplicité ces dispositifs sont souvent sensibles aux conditions d’éclairage du réseau car le photo-élément peut se retrouver excité par votre éclairage et ne plus être capable de détecter le matériel roulant. La technologie de détection par réflexion peut aussi être sensible à la couleur du matériel. En effet, une locomotive noire, réfléchit peu de lumière et peut passer inaperçue.
Des méthodes plus sophistiquées existent et utilisent des faisceaux laser. Le capteur qui nous intéresse est Time-of-Flight (TOF). La distance est mesurée en mesurant le temps que met un train d’impulsions laser à faire le trajet aller-retour entre le capteur et la cible.
Caractéristiques du VL6180X
Le VL6180X est un composant CMS de petite taille (4,8 x 2,8 x 1,0 mm) [1] à 12 broches et dont les broches sont situées sous le boîtier. Pour un amateur, le soudage est impossible à réaliser à moins d’avoir un four à refusion pour CMS. Mais il existe de nombreuses petites cartes comprenant le VL6180X et les composants annexes : résistances, condensateurs, mosfet d’adaptation de niveau et régulateur de tension. En effet, le VL6180X s’alimente en 2,8V. L’une de ces cartes (figure 2) a de très petites dimensions, environ 11 x 13mm, permettant de la dissimuler plus facilement dans le décor. On la trouve pour une somme variant de 2 à 3€ sur eBay ou AliExpress.
Ce capteur est donné pour permettre des mesures de distance au millimètre entre 0 et 100mm. Éventuellement plus si les conditions de luminosité ambiante et de couleur de la cible sont bonnes. L’idéal étant une cible de couleur blanche dans le noir complet. La figure 1 ci-dessous, tirée de la documentation, donne les mesures effectuées par le fabricant.
On peut voir une anomalie en dessous de 10mm. La mesure donne une valeur plus grande que la distance réelle.
Le capteur contient un émetteur permettant d’illuminer la cible, un récepteur et un capteur de luminosité ambiante. Le cône d’émission est de 25°, le cône de réception n’est pas donné mais comme le trou du récepteur a un diamètre plus faible que le trou de l’émetteur (0,3mm contre 0,5mm) ce cône doit être plus petit.
La connexion avec le micro-contrôleur se fait via le bus I2C.
La carte
La carte comporte 6 broches :
- VIN : tension d’alimentation, soit 5V, soit 3,3V selon la carte Arduino dont vous disposez ;
- GND : la masse de la carte Arduino ;
- SDA et SCL : les broches I2C ;
- 0 : GPIO 0 du VL6180X. Utilisable pour mettre le capteur hors circuit ;
- 1 : GPIO 1 du VL6180X. Utilisable pour que le capteur envoie une interruption.
La figure 2 montre la carte avec l’identification des composants.
Le schéma de cette carte est introuvable sur le Web, un examen des composants a permis de déduire le schéma présenté à la figure 3.
On voit que cette carte inclut les résistances de pull-up nécessaires au bus I2C et il n’est donc pas indispensable d’en ajouter des externes. On voit également que les GPIO ne sont pas munis de « level shifters ». Si ils doivent être pilotés par l’Arduino, il faudra passer par un transistor à collecteur ouvert car appliquer la tension haute d’une broche de l’Arduino à un de ces deux signaux endommagera le VL6180X.
La bibliothèque
Il existe plusieurs bibliothèques pour piloter ce composant. Pour ma part, j’ai utilisé celle d’Adafruit qui est disponible dans le gestionnaire de bibliothèques. Elle suit un canevas habituel dans le monde Arduino. Tout d’abord on instancie un objet qui représente le composant.
Adafruit_VL6180X capteur = Adafruit_VL6180X();
Optionnellement, on peut spécifier l’adresse I2C du capteur, qui par défaut est à l’adresse 0x29
. Par exemple comme ceci pour l’adresse 0x30
:
Adafruit_VL6180X capteur = Adafruit_VL6180X(0x30);
Nous reviendrons sur cette adresse I2C car elle n’est pas modifiable via des jumper contrairement à ce qui est souvent le cas pour des composants I2C.
Ensuite on démarre le capteur dans setup
. La fonction begin
retourne true
si le capteur répond, false
sinon. Typiquement on aura :
if ( ! capteur.begin() ) {
Serial.println("VL6180X non trouvé");
while(1);
}
Par défaut, la communication s’engage sur le bus I2C primaire, c’est à dire le bus incarné par l’objet Wire
. begin
peut prendre en argument le bus I2C sur lequel le capteur est connecté lorsque votre carte Arduino comprend plusieurs bus I2C. Dans ce cas, ça sera par exemple Wire1
.
La fonction readRange
permet de lire la distance qui est retournée directement en millimètres sur un seul octet. On écrira par exemple :
uint8_t distance = capteur.readRange();
Une seconde fonction, readRangeStatus
retourne un code renseignant sur l’état du capteur. En effet, si un problème de mesure est survenu, la valeur retournée par readRange
est erronée. Il faut donc systématiquement appeler readRangeStatus
après readRange
. Les codes possibles sont :
Numéro | Symbole de la bibliothèque | Commentaire |
---|---|---|
0 | VL6180X_ERROR_NONE | Tout s’est bien passé |
1 à 5 | VL6180X_ERROR_SYSERR_n | Où n vaut 1 ou 5. Erreur système, n’arrive qu’au démarrage. À noter que Adafruit n’a pas mis en place de symbole pour les erreurs 2 à 4 |
6 | VL6180X_ERROR_ECEFAIL | L’estimation initiale de présence d’un objet a échoué |
7 | VL6180X_ERROR_NOCONVERGE | L’algorithme du VL6180X n’a pas convergé avant la date limite |
8 | VL6180X_ERROR_RANGEIGNORE | Sert à s’assurer que la capteur n’a pas mesuré la distance à une vitre de protection. À priori désactivé par défaut. |
11 | VL6180X_ERROR_SNR | Lumière ambiante trop forte |
12 et 14 | VL6180X_ERROR_RAWUFLOW et VL6180X_ERROR_RANGEUFLOW | La cible étant très proche du capteur, L’algorithme du VL6180X a convergé vers une valeur négative |
13 et 15 | VL6180X_ERROR_RAWOFLOW et VL6180X_ERROR_RANGEOFLOW | La cible est trop loin du capteur (> 200 mm) |
La vitesse d’acquisition peut varier selon la facilité avec laquelle le capteur converge. Quelques mesures permettent de constater qu’une lecture de distance (readRange()
) et d’état (readRangeStatus()
prend un peut moins de 3ms quand elle est isolée et un peu plus de 10ms quand plusieurs sont effectuées successivement, transaction I2C comprise. On peut donc lire une distance à un rythme d’une centaine de Hertz.
L’adresse I2C
L’adresse I2C ne peut pas être changée matériellement mais peut l’être via la fonction setAddress
de la bibliothèque. Toutefois, le capteur conservant l’adresse programmée en RAM, elle est perdue à chaque mise hors tension. Il faut donc la programmer au démarrage. Oui, mais si vous avez plusieurs VL6180X sur votre bus I2C, changer l’adresse changera l’adresse de tous les VL6180X. Pour en sélectionner 1, il faut mettre les autres hors service. C’est ici que la broche GPIO 0 entre en scène. En mettant cette broche à LOW, le capteur est désactivé. Par conséquent, pour pouvoir programmer les adresses d’une série de capteurs sur le même bus I2C, il faut piloter les GPIO 0 des capteurs avec une broche de l’Arduino et ne sélectionner que celui dont on reprogrammé l’adresse. Ça n’est pas très pratique car cela monopolise une broche de l’Arduino pour chaque capteur mais surtout cela nécessite de souder un fil supplémentaire à l’autre bout de la carte du capteur alors même que l’on veut minimiser l’encombrement de cette dernière.
L’alternative est d’employer un multiplexeur I2C. Il en existe à 8 canaux. Ce composant agit comme un aiguillage, concept qui nous est familier, à 8 voies. Il a lui même une adresse I2C et le réglage de la position de l’aiguillage se fait en lui envoyant un message I2C.
L’application
Sur mon réseau à l’écartement N, j’ai le projet d’utiliser ce capteur pour mesurer, à l’intérieur des différentes remises à locomotive, la distance entre le heurtoir et la locomotive. En mode manuel, ceci permet d’avoir un retour de position dans un endroit où la locomotive est masquée. On peut également imaginer un mode automatique où le capteur est couplé au système de conduite des trains et où la locomotive est arrêtée automatiquement quand la distance requise est atteinte.
Dans les deux cas, la fiabilité de la mesure est cruciale et il convient donc d’évaluer ce capteur le plus sérieusement possible.
L’intégration du capteur
Afin de dissimuler au mieux le capteur, il est possible de l’intégrer dans un heurtoir. Toutefois, comme on va le voir, cette intégration n’est pas si simple.
Première tentative
Le capteur n’est pas en bord de carte à cause des deux broches du GPIO. Il faut donc le mettre en dessous de la barre transversale du heurtoir. Si le capteur est placé dans une boîte parallélépipédique réalisé en carton de 0,5mm d’épaisseur et que le haut de cette boîte correspond à celle d’un heurtoir, environ 10mm pour l’échelle N, comme montré à la figure 4, il mesure une distance de 60mm en moyenne en l’absence de tout engin sur la voie.
En effet, placé à cette distance du plan de roulement, le capteur voit le sol, les traverses, etc.
Deux solutions s’offrent à nous :
- Placer le capteur plus haut. L’expérience montre qu’il est nécessaire de monter la boîte 20mm au dessus du plan de roulement pour avoir une mesure de distance de 115mm en l’absence de tout engin sur la voie ;
- Placer le capteur avec un angle de manière à ce qu’il vise vers le haut. Un calcul basé sur les mesures de distance en l’absence de tout engin sur la voie et avec un angle nul montre qu’un angle de 7,5° conviendrait.
La première solution nuit à la dissimulation du capteur car il n’est pas très esthétique d’avoir le monolithe de 2001 l’odyssée de l’espace au bout des voies de garage.
Expérimentations avec divers matériels
Pour évaluer la seconde solution, le mieux est de construire un banc d’essai reproduisant les distances et les obstacles pour simuler ce que verrait le capteur de l’intérieur d’une remise.
- Le haut du boîtier contenant le capteur incliné en arrière de 7,5° est placé à 10mm au dessus du plan de roulement. À cette position, une traverse alignée avec le haut serait à la hauteur des tampons. On a donc le gabarit d’un heurtoir. L’axe optique du capteur est à 6mm au dessus du plan de roulement et passe sous cette traverse hypothétique.
- Le mur où se situeraient les portes est placé à 180mm du capteur, la profondeur totale de la remise est de 195mm. Étant donné le cône de détection du capteur, ce mur pourrait être détecté.
- Les locomotives sont des vapeurs. Une BR38 (noire) et une BR71 (noire). Plusieurs surfaces sont à des distances différentes et de couleurs différentes : attelage (noir), tampons (noirs cerclés de blanc), traverse (rouge), chaudière (noir), cheminée (noir). Calculer une distance pour une locomotive n’est pas un problème simple.
- Une règle placée au sol permet de positionner la locomotive relativement au capteur. Le repère est le marchepied.
- Pour compliquer les choses, une ampoule LED éclaire la scène et est dirigée vers le capteur. Toutefois des essais ont été effectués avec et sans la lampe et montrent que cette dernière ne perturbe pas le capteur.
On se place donc dans des conditions plutôt difficiles mais réalistes.
La locomotive étant retirée de la voie, le capteur donne une distance moyenne de 167,45mm. Sans doute mesure-il encore la distance au sol ou aux traverses de la voie ou encore le mur. Toutefois, cette distance est supérieure à celle donnée dans la datasheet et largement suffisante pour l’application visée.
Le test consiste ensuite à effectuer des mesures de distance en déplaçant la locomotive d’un centimètre entre deux séries de mesures puis de 5mm lorsque la distance est inférieure à 40mm. Pour chacune des distances, 1000 mesures sont effectuées, à un rythme d’une mesure toutes les 50ms, puis la moyenne, l’écart type et les valeurs extrêmes sont calculés. Comme le capteur donne une distance moyenne de 167,45mm en l’absence de locomotive, les mesures sont commencées à une distance de 160mm.
Sur toutes les courbes, l’écart type est représenté sous forme d’une barre d’erreur autour de la moyenne.
Étalonnage
Avant tout, il est nécessaire de faire une campagne de mesures avec une cible facile. À cet effet une carte de plastique blanc format carte de crédit est posée sur les tampons d’un wagon de marchandise. Le résultat est présenté à la figure 5.
Hormis les erreurs de mesure à très courte distance, qui ne sont pas contradictoires avec les données de la datasheet, la mesure est plutôt précise. En dessous de 70mm, il est probable que l’attelage du wagon commence à contribuer à la distance et comme il est plus près que la carte de 6mm, la mesure donne une distance inférieure à celle de la carte.
La BR38 en marche avant
Le résultat de l’expérience est donné figure 6 ci-dessous.
On voit que dans ces conditions le capteur mesure les longues distances de manière erronée avec une surévaluation pouvant atteindre 30% à 100mm. En deçà de 70mm, le capteur sous-évalue la distance de quelques millimètres. Toutefois il faut noter les points suivants :
- Plus la locomotive est loin et plus le capteur, du fait de son inclinaison de 7,5°, vise le haut de la locomotive. Or, le haut est en arrière par rapport au marchepied. Mais même en prenant la cheminée comme repère, la distance est surévaluée.
- Symétriquement, plus la locomotive est près et plus le capteur vise le bas qui est soit au niveau du marchepied soit en avant par rapport au marchepied. Ici par contre, si on prend les tampons comme référence, la mesure est plutôt juste.
- Les valeurs minimum et maximum peuvent être assez éloignées de la moyenne. Il faudra donc les filtrer.
- Sur les 20000 mesures effectuées, aucune n’a donné de valeur aberrante ou d’erreur de fonctionnement du capteur.
La BR 38 en marche arrière
Les mêmes mesures sont effectuées en présentant la locomotive en marche arrière, tender vers le capteur. Deux différences :
- Le tender est moins haut
- L’attelage NEM, qui est absent à l’avant, est décalé de 8mm par rapport au repère. La mesure à 5mm n’est pas possible et on s’attend à ce que pour les courtes distances, le décalage soit plus prononcé que dans les mesures avec l’avant de la locomotive. Le résultat est présenté figure 7 ci-dessous.
L’erreur à longue distance est plus prononcée et atteint 40%. Ceci est probablement dû au fait que le tender est moins haut et offre une cible plus petite à longue distance. Comme prévu, la présence de l’attelage NEM produit un décalage qui est à peu près égal à la longueur de l’attelage. On a donc une mesure exacte en dessous de 60mm de distance sauf pour la dernière où l’attelage n’est qu’à 2mm du capteur et où on retrouve le problème montré dans le graphe issu de la documentation.
Ici aussi, sur les 20000 mesures, aucune erreur du capteur.
La BR71 en marche avant
Le choix de cette locomotive est dû à sa petite taille. La figure 8 permet de comparer le gabarit les deux machines. Contrairement à la BR38, la BR71 est équipée d’un attelage à l’avant mais il n’y a que 7mm d’écart par rapport au marchepied. Le résultat est présenté à la figure 9 ci-dessous.
La petitesse de la locomotive semble avoir une influence sur la précision à grande distance avec ici une erreur qui peut atteindre 50%. la distance où la précision devient bonne est aussi plus faible, 50mm au lieu de 65mm. Sur les 1000 mesures effectuées à 10mm, le capteur a renvoyé deux fois l’erreur VL6180X_ERROR_RAWUFLOW
, c’est à dire que le capteur a convergé vers une distance négative. J’ai arbitrairement remplacé ces deux occurrences d’erreur par la valeur -1, ce qui explique que la courbe du minimum passe en dessous de 0.
Filtrons
Comme l’écart type n’est pas négligeable, les données issues du capteur peuvent être filtrées. Par exemple, 6 mesures consécutives sont faites puis la plus grande et la plus petite des mesures sont éliminés et, enfin, la moyenne des 4 mesures restantes est calculée. Le résultat de 1000 résultats filtrés, c’est à dire 6000 mesures à 20 distances différentes est donné à la figure 10.
Comme on peut le voir, l’écart type est resserré. Minimum et maximum restent toutefois importants pour les faibles distances mais c’est un effet dû à la discrétisation au millimètre opérée par le capteur.
Filtrer de cette manière va aussi diminuer le rythme d’acquisition de données (15Hz ici) mais il est également possible de filtrer en effectuant une moyenne glissante et en gardant le rythme maximum permis par le capteur.
Conclusion
Le format compact de cette carte permet de la dissimuler facilement dans le décor. Les performances sont plutôt bonnes sauf en ce qui concerne la mesure à longue distance. ST garantit les performances pour une distance inférieure ou égale à 100mm mais l’erreur de mesure peut atteindre malgré tout 50%.
À sa décharge, l’éclairage et la couleur du matériel roulant rendent le problème difficile. Le positionnement incliné à 7,5° permet d’éviter de détecter le sol mais il a également l’effet de faire sortir partiellement du champ du capteur un matériel qui finalement n’est pas très haut et d’engendrer des erreurs de mesure à longue distance. Cet effet est amplifié par la petitesse de la cible comme le montre l’expérience avec la BR71.
Les expériences montrent que ce capteur peut être employé pour mesurer efficacement la distance entre un heurtoir et une locomotive quand on est à courte distance mais il ne faudra pas espérer une précision au millimètre. Il est insensible à la luminosité ambiante et très peu sensible à la couleur de la cible.
Peut-on l’utiliser pour mettre en place un système automatique pour arrêter précisément une locomotive quand la distance devient inférieure à un seuil ? La réponse est oui. Peut-on l’utiliser pour asservir la vitesse sur la distance qui reste entre le point d’arrêt et la locomotive, la réponse est également oui à condition d’éviter de se retrouver dans le cas où la distance mesurée grandit alors même que la distance réelle diminue comme c’est la cas à la figure 7. Il faut donc s’arrêter à une distance suffisante.
[1] 2,8mm est exactement l’espace entre deux traverses de la voie PECO code 55.