Tutoriel · Débutant · 20 min de lecture
Lire une barrette IR de réflectance pour le suivi de ligne
Comment un suiveur de ligne transforme une rangée de capteurs IR en erreur de braquage : analogique ou numérique, étalonnage, et moyenne pondérée.
Un robot suiveur de ligne n’est bon que comme le nombre sur lequel il braque. Ce nombre vient d’une rangée de capteurs de réflectance infrarouge pointés vers le sol : la ligne est d’une couleur, le fond d’une autre, et les capteurs rapportent combien de lumière IR se réfléchit. Ce guide transforme cette rangée brute de lectures en une position de ligne unique et lisse — l’erreur sur laquelle votre contrôleur agit.
Comment un capteur de réflectance voit la ligne
Chaque capteur marie une LED IR à un phototransistor. La LED éclaire vers le bas ; le phototransistor mesure la réflexion. Une ligne noire mate réfléchit peu d’IR (lecture basse) ; le fond plus clair réfléchit plus (lecture haute). Balayez la barrette sur une piste noire sur blanc et chaque capteur oscille entre une valeur « sur la ligne » et une valeur « hors la ligne ».
Deux choses changent ces valeurs brutes d’une course à l’autre : la hauteur des capteurs au-dessus de la surface et la lumière ambiante. C’est pourquoi on ne code jamais de seuils en dur — on étalonne. Les mêmes capteurs pointés vers une bordure d’anneau plutôt qu’une ligne deviennent un détecteur de bord, où une lecture manquée coûte le match au robot.
Capteurs analogiques contre numériques
- Analogiques donnent une valeur continue (par ex. 0–1023 sur un ADC Arduino). Vous pouvez dire à quelle distance la ligne est de chaque capteur, ce qui permet de calculer une position lisse et de braquer proportionnellement.
- Numériques ne rapportent que tout ou rien après un seuil interne. Plus simples à câbler, mais vous perdez l’information d’entre-deux, donc le braquage est plus grossier.
Pour le suivi de ligne proportionnel — le genre réglé avec un contrôleur PID — utilisez des lectures analogiques. C’est l’approche que le simulateur de suiveur de ligne modélise.
Étalonnez d’abord
Avant une course, balayez chaque capteur sur la ligne et le fond et enregistrez le minimum et le maximum de chaque capteur. Puis normalisez chaque lecture en direct en 0–1000 sur sa propre plage :
// Per-sensor calibration captured during a sweep.
int minv[N], maxv[N];
int normalized(int raw, int i) {
long span = maxv[i] - minv[i];
if (span <= 0) return 0; // sensor never saw contrast
long v = (long)(raw - minv[i]) * 1000 / span; // 0 (background) … 1000 (line)
return constrain(v, 0, 1000);
}
Étalonner par capteur annule l’éclat inégal des LED et les petites différences de hauteur sur la barre, pour qu’un capteur ne biaise pas discrètement toute l’estimée.
Des lectures à une position de ligne
Réduisez désormais la barrette en une seule position avec une moyenne pondérée par réflectance. Donnez à chaque capteur une position fixe (…−2, −1, 0, +1, +2… sur la barre) et pondérez-la par sa lecture normalisée. Le résultat est l’emplacement de la ligne par rapport au centre de la barre — positif d’un côté, négatif de l’autre, zéro quand la ligne se tient pile au centre.
// Sensor positions across the bar, e.g. { -2000,-1000,0,1000,2000 }.
long readLinePosition() {
long weighted = 0, total = 0;
for (int i = 0; i < N; i++) {
int v = normalized(analogRead(pins[i]), i);
weighted += (long)v * position[i];
total += v;
}
if (total == 0) return lastPosition; // line lost — reuse last direction
lastPosition = weighted / total;
return lastPosition; // 0 = centered, sign = which side
}
Deux détails rendent cela robuste :
- Divisez par la lecture totale, pas le nombre de capteurs, pour qu’une ligne pâle et une ligne marquée se projettent sur la même échelle de position.
- Quand chaque capteur perd la ligne (
total == 0), réutilisez la dernière position connue au lieu de renvoyer zéro. Cela fait continuer le robot en virage vers où était la ligne, plutôt que de filer tout droit hors d’un virage serré.
Combien de capteurs ?
Cinq est un bon point de départ — assez pour voir sens et amplitude tout en gardant les maths faciles à inspecter. Trois marchent à basse vitesse ; les robots de compétition en utilisent huit ou plus pour une résolution plus fine à vitesse. Plus de capteurs achètent surtout une estimée de position plus lisse dans les courbes serrées.
La routine d’étalonnage, en entier
« Étalonnez d’abord » est facile à dire et facile à mal faire. Voici toute la routine, y compris la garde qui empêche une voie morte de ruiner l’estimée :
const int N = 8;
const int PIN[N] = {A0, A1, A2, A3, A4, A5, A6, A7};
int minv[N], maxv[N];
void calibrate(unsigned long durationMs) {
for (int i = 0; i < N; i++) { minv[i] = 1023; maxv[i] = 0; }
const unsigned long start = millis();
while (millis() - start < durationMs) {
for (int i = 0; i < N; i++) {
const int v = analogRead(PIN[i]);
if (v < minv[i]) minv[i] = v;
if (v > maxv[i]) maxv[i] = v;
}
}
// A channel that never saw contrast would turn noise into huge normalised
// values and drag the whole estimate toward itself.
for (int i = 0; i < N; i++) {
if (maxv[i] - minv[i] < 50) {
Serial.print(F("channel dead or never crossed the line: "));
Serial.println(i);
}
}
}
Balayez la barrette sur la ligne pendant toute la fenêtre d’étalonnage. Un robot immobile enregistre la même lecture comme minimum et maximum, produisant une plage nulle et un capteur qui ne contribue à rien. Faire pivoter le robot sur place au-dessus de la ligne pendant trois secondes est le mouvement standard, et cela marche parce que chaque voie traverse l’adhésif.
Réétalonnez au début de chaque course, pas une fois à la construction. La lumière ambiante change, la hauteur de roulage change à mesure que le pack de batteries bouge, et l’adhésif prend la poussière. C’est la raison la plus courante pour laquelle un suiveur de ligne marche sur une table et échoue sur une autre.
Tuer la lumière ambiante
Le soleil contient beaucoup d’infrarouge à 940 nm, et le phototransistor ne peut le distinguer de la réflexion de votre propre émetteur. Un robot qui marche dedans et échoue près d’une fenêtre voit exactement cela.
Si les émetteurs de votre barrette sont commutables — la plupart ont une broche LEDON ou CTRL — le correctif est complet et coûte une lecture supplémentaire par voie :
int ambientSubtracted(int i) {
digitalWrite(LEDON, LOW);
delayMicroseconds(200); // let the phototransistor settle
const int dark = analogRead(PIN[i]); // ambient only
digitalWrite(LEDON, HIGH);
delayMicroseconds(200);
const int lit = analogRead(PIN[i]); // ambient + our emitter
return lit - dark; // just our emitter
}
Tout ce qui est constant dans l’environnement s’annule exactement. Le coût est le double du temps d’échantillonnage, ce qui sur un suiveur de ligne rapide est réel — mais cela convertit un capteur peu fiable en fiable, et c’est la technique qu’emploient les barrettes du commerce.
Cela a aussi un second bénéfice à prendre : avec les émetteurs éteints entre lectures, leur courant moyen chute fortement. Les émetteurs d’une barrette à 8 voies peuvent tirer 100–200 mA en continu, ce qui sur un petit pack est une part significative du budget.
Perdre la ligne, et la retrouver
Le cas total == 0 ci-dessus vaut plus d’attention qu’on lui en accorde d’ordinaire, parce que c’est là qu’un suiveur de ligne échoue le plus souvent visiblement.
Renvoyer zéro est l’implémentation évidente et la mauvaise : zéro signifie « parfaitement centré », donc le robot roule tout droit à pleine vitesse — loin de la ligne qu’il vient de perdre, qui était presque sûrement en courbe.
Renvoyer la dernière position fait continuer le robot en virage dans le sens où il tournait déjà, là où est allée la ligne. Ce seul changement est la différence entre un robot qui se rétablit d’un virage serré et un qui quitte la piste.
Une version plus complète ajoute un délai maximal, pour qu’un robot vraiment perdu s’arrête plutôt que de spiraler :
long lastPosition = 0;
unsigned long lostSince = 0;
long readLinePosition() {
long weighted = 0, total = 0;
for (int i = 0; i < N; i++) {
const int v = normalized(analogRead(PIN[i]), i);
if (v > 100) { // ignore channels clearly on the floor
weighted += (long)v * POSITION[i];
total += v;
}
}
if (total == 0) {
if (lostSince == 0) lostSince = millis();
if (millis() - lostSince > 1500) stopMotors(); // genuinely lost
return lastPosition; // keep turning the way we were
}
lostSince = 0;
lastPosition = weighted / total;
return lastPosition;
}
Le seuil v > 100 compte aussi. Sans lui, huit voies lisant chacune un petit plancher non nul tirent la moyenne pondérée vers le centre de la barrette quel que soit l’endroit réel de la ligne — ce qui apparaît comme un robot qui suit bien sur un adhésif marqué et mal sur un pâle.
La hauteur de roulage décide du contraste
Les capteurs de réflectance ont une étroite zone idéale, et c’est la variable mécanique qui se déguise le plus souvent en problème logiciel.
| Hauteur de roulage | Ce que vous voyez dans la plage d’étalonnage |
|---|---|
| 1–3 mm | Plage la plus grande, mais la barrette racle sur toute irrégularité du sol |
| 3–8 mm | La bande utilisable. La plupart des barrettes spécifient autour de 3 mm |
| 8–15 mm | Plage qui rétrécit nettement ; la normalisation commence à amplifier le bruit |
| > 15 mm | Effectivement aveugle sur la plupart des surfaces |
Deux conséquences suivent. Montez-la rigidement — une barrette sur un support flexible change de hauteur à mesure que le robot accélère, ce qui change les lectures, que la boucle de commande interprète comme la ligne qui bouge. Et montez-la de niveau, parce qu’une barrette inclinée donne à chaque voie une hauteur effective différente donc un étalonnage différent, ce qui apparaît comme un robot qui suit bien dans un sens et mal dans l’autre.
Combien de capteurs, quantifié
| Voies | Résolution de position sur une ligne de 19 mm | Bon pour |
|---|---|---|
| 3 | Essentiellement gauche / centre / droit | Comprendre l’idée |
| 5 | ~4 régions discrètes, lisses entre elles | Un premier suiveur de ligne sur piste douce |
| 8 | ~7 régions | Pistes rapides, courbes serrées, détection d’intersections |
| 12–16 | Fine | Robots de compétition à vitesse |
Le nombre qui compte plus que le compte est la largeur de la barrette par rapport à la ligne. Pour le simple suivi de ligne, la barrette doit être assez large pour qu’au moins un capteur soit au sol à chaque bord de la ligne — donc environ deux fois la largeur de l’adhésif.
Pour la détection d’intersections de labyrinthe de lignes, l’exigence est plus stricte : le robot reconnaît une branche en voyant les capteurs extérieurs passer au noir pendant que le centre est encore sur la ligne, donc la barrette doit faire au moins trois fois la largeur de l’adhésif. Une barrette à 8 voies au pas de 8 mm fait environ 60 mm, ce qui convient pour de l’adhésif de 19 mm.
Dépannage
| Symptôme | Cause probable | Correctif |
|---|---|---|
| Marche sur une surface, échoue sur une autre | Étalonnage périmé ou manquant | Réétalonnez au début de chaque course |
| Une voie tire l’estimée | Émetteur mort — sa plage est minuscule | Vérifiez le maxv − minv de chaque voie ; mettez une garde dessus |
| Le robot file tout droit quand il perd la ligne | Renvoi de 0 en perte de ligne | Renvoyez la dernière position à la place |
| Suit sur adhésif marqué, divague sur pâle | Bruit de sol entrant dans la moyenne | Ajoutez le seuil v > 100 |
| Échoue près d’une fenêtre | Infrarouge ambiant | Soustraction émetteur éteint, ou capotez la barrette |
| La position saute quand la ligne traverse les capteurs | Pas normalisé par voie | Étalonnez chaque voie sur ses propres min et max |
| Les lectures dérivent sur une longue course | Batterie qui s’affaisse, donc émetteurs qui pâlissent | Vérifiez le rail en charge |
| Toutes les voies lisent pareil | Barrette trop haute | 3–8 mm, puis réétalonnez |
| Suit bien dans un sens, mal dans l’autre | Barrette pas de niveau | Chaque voie a une hauteur effective différente |
Où cela va ensuite
Cette valeur de position unique est le terme d’erreur. Injectez-la dans une boucle de commande qui accélère une roue et ralentit l’autre, et vous avez un suiveur de ligne. Apprenez cette boucle dans Régler un contrôleur PID, puis essayez le tout de bout en bout dans le simulateur de suiveur de ligne.
Explorer le graphe
Fait partie de ces réalisations
Les projets et parcours d'apprentissage qui incluent ce tutoriel.
Pour aller plus loin