Publié le 28 novembre 2016 - par

Deux capteurs pour un robot

2capteur_250pxImaginer, construire un robot c’est bien. Vous imaginez par exemple un véhicule qui se déplace (en autonomie ou par télécommande). Pour qu’il puisse réagir à son environnement, il doit comme nous avec nos 5 sens intégrer des informations sur le monde qui l’entoure.
L’exemple que je connais bien, c’est un (vieil) aspirateur équipé d’un détecteur d’obstacles. Lorsqu’il rencontre un pied de chaise, un mur… Il s’arrête, recule un peu et repart dans une autre direction.

Capteur de distance et suiveur de ligne pour robot

Un aspirateur suicidaire

aspirateurSuper ! Mmmouais mais quand l’aspirateur s’enquille sous un radiateur les capteurs situés plutôt en bas du châssis restent muets et l’autre essaye vainement d’avancer puisqu’il n’y a pas d’obstacle.  Les programmeurs étaient sans doute dans un local chauffé par le sol, sans radiateur 😀

Et s’il n’y avait que ça… un escalier intérieur  sans porte a été témoin de plusieurs tentatives de suicide. L’aspirateur n’étant pas équipé non plus de détecteur de vide, ne s’aperçoit pas qu’il arrive au début des marches et… dégringole dans l’escalier.

Ça vous fait sourire, mais si vous concevez un rover, une araignée ou un drone ce sont des choses auxquelles il vaut mieux penser…

Et comment un robot peut-il être informé du monde qui l’entoure ? A l’aide de divers capteurs qui lui renvoient des valeurs mesurées ou des informations sur sa position etc.

Capteur laser : mesure de distance LIDAR

robot-capteur-de-distance-laser-2Sur le papier (enfin, sur l’écran) c’est très simple. Il suffit d’envoyer une impulsion LASER vers l’avant. SI elle rencontre un obstacle, cette impulsion revient vers le robot. Il suffit de détecter le moment exact du retour, de mesurer le temps aller/retour (temps de vol) . On connait la vitesse de la lumière. Il suffit de diviser le temps de vol par 2 (bin oui il y a un aller retour 🙂 ) et de le multiplier par c (vitesse de la lumière) pour obtenir la distance : D = c x T/2.

C’est le principe du LIDAR (Light Detection And Ranging). Cette technique est utilisée par exemple pour mesurer la distance Terre-Lune grâce à des réflecteurs déposés par les missions Apollo ou embarqués sur des véhicules lunaires soviétiques.

Les problèmes pour la réalisation de ces capteurs c’est la durée de l’impulsion (qui doit être la plus courte possible) et la taille du capteur. Les avancées dans les techniques de production des faisceaux LASER, des capteurs et de la miniaturisation de tout ça a abouti à la création d’un capteur miniature.

Le capteur LIDAR Adafruit

tps_volee_01vl53l0xLe capteur d’Adafruit est basé sur le circuit VL53L0X qui ne mesure que 4x2x1 mm

Le capteur VL53L0X permet d’ajouter un capteur de distance/proximité à votre projet. Il avertit qu’une main, un chat ou un mur se trouve à proximité. En fonction de la luminosité ambiante et de la réflectivité de l’objet, vous obtiendrez une portée d’environ 30 mm à 1,2 m avec une précision de ~ 5%.

Le capteur contient une minuscule source laser (invisible) et le récepteur correspondant. Le VL53L0X peut détecter le «temps de vol», c’est à dire le temps que la lumière a pris pour rebondir sur l’obstacle. Comme il utilise une source de lumière très étroite, il est parfait pour déterminer la distance uniquement sur la surface située directement devant lui. Contrairement aux sonars qui utilisent des ondes ultrasonores, le «cône» de détection est très étroit, contrairement aux capteurs de distance infrarouge qui essayent de mesurer la quantité de lumière rebondie, le VL53L0x est beaucoup plus précis et n’a pas de problèmes de linéarité ou de «double image» qui font que vous ne pouvez pas savoir si un objet est très loin ou très proche.

tps_volee_02

Le capteur est petit et facile à utiliser dans tout projet robotique ou embarqué. Il fonctionne en 2.8V et Adafruit a regroupé sur cette petite carte un régulateur et un décaleur de niveau. Vous pouvez l’utiliser avec n’importe quel microcontrôleur fonctionnant entre 3 et 5 volts. Chaque carte est livrée avec un petit connecteur à souder.

tps_volee_03

La communication se fait en I2C avec une API écrite par ST, donc ce n’est pas trop difficile de le connecter à votre microcontrôleur préféré. Adafruit fournit un tutoriel pour ce produit.

adafruit_products_defaultrangeLe graphique ci-dessus donne la mesure renvoyée en fonction de la distance et de la couleur de l’obstacle.

Conclusion

Je n’ai pas d’actions ST 🙁 mais voilà ce qu’en dit David : « Pour s’en rendre compte faut faire le test avec l’affichage direct de la distance c’est juste hallucinant ^^
Ce VL est utilisé dans divers smartphones pour permettre l’extinction de l’écran à l’approche de l’oreille mais aussi et surtout pour les nouveaux capteurs photos, il sert pour l’Auto Focus, et rend le « calcul » de la distance pour l’AF instantané. Allez j’arrête de vendre ce produit il n’a pas besoin de moi pour cela ^^
« 

Pour 15$ voilà un capteur qui pourra doter vos robots, drones… d’une sensibilité aux objets proches. Si vous avez l’occasion de le tester n’hésitez pas à laisser vos imprssions dans les commentaires ci-dessous.

Capteur de suivi de ligne

Ce capteur m’a été signalé par Stroon2 que je remercie pour cette info.

line_tracker_03Il cherche à effectuer des relevés de compteur d’eau avec son Raspberry Pi et il est tombé sur ce module capteur infrarouge intéressant.

line_tracker_01

Le capteur est un émetteur/récepteur infrarouge TCRT5000.

tcrt5000Annoncé comme suiveur de ligne (Line Tracking Sensor Module) ce module peut bien entendu être utilisé comme un détecteur classique et signaler la présence d’un obstacle ou… autre.

Ce module est peu couteux (moins de 2 euros à l’unité et moins de 5 euros par 5) et il est adapté au 3.3v du Raspberry Pi ! Sur le site du vendeur ce module est annoncé comme fonctionnant sous 5V. En regardant le capteur de plus près (une fois reçu), Stroon2 s’est aperçu que l’unique circuit intégré qu’il comporte peut fonctionner sur une plage de 2V à 6V.
Les essais ont confirmé qu’il fonctionne parfaitement en 3.3v 🙂

line_tracker_02

Le module est utilisable directement sans ajout de composant supplémentaire. La seule difficulté reste finalement dans l’adaptation mécanique au compteur d’eau…

Après essais, Stroon2 m’a communiqué les informations ci-dessous :

Voici un petit complément car le comptage des impulsions m’a joué quelques tours… ce n’est pas lié au capteur mais aux parasites.

Un câble réseau est utilisé pour transporter le signal du capteur IR.
Des sondes de températures 1-wire (DS18B20 x5) utilisent d’autres brins de ce même câble réseau.
Ce câble n’est pas très long (<3m) mais cette longueur semble suffisante pour parasiter le signal du capteur IR et déclencher des changements d’états intempestifs sur le port GPIO.

Le comptage est effectué avec un bout de code Python qui tourne en tache de fond.
J’utilise le module RPi.GPIO et la fonction GPIO.add_event_detect qui permet la détection du changement d’état du port GPIO.

J’ai commencé par additionner simplement les changements d’états pour incrémenter mon total mais ça ne fonctionne pas car la fonction se déclenche aussi sur les parasites.
Le réglage du Bouncetime ne semble pas avoir d’effet.
Un condensateur en // a amélioré un peu les choses mais pas à 100%

Étonnamment, il peut y avoir successivement plusieurs déclenchement sur le même type de front (montant ou descendant) alors qu’entre deux fronts montants devrait forcément y avoir d’un front descendant! (et vice-versa).
Ceci est peut être justement le résultat du bouncetime qui masquerait une interruption si elle est trop proches de la précédente…

Bref, pour éliminer les faux positifs j’utilise une variable previousEdge qui conserve l’état précédent du port GPIO.
Lorsqu’un changement d’état est détecté, je compare l’état actuel du port GPIO avec l’état précédent. S’il n’a pas changé, ce n’est pas un changement d’état, j’ignore cette détection.

Voici le code ci-dessous pour info. Ce n’est pas du grand développement mais le compte est juste 🙂

En résumé:
Au démarrage j’initialise mon relevé de compteur d’eau en lisant la dernière valeur dans un fichier.
J’incrémente mon relevé de 0.5 litres à chaque « vrai » déclenchement. (1 tour /litre donc 2 fronts quand le mirroir passe devant le capteur )
J’écris mon relevé dans le fichier toutes les 300 secondes.
Je trace pour info les faux positifs dans un fichiers.

#!/usr/bin/python3
import RPi.GPIO as GPIO
from time import sleep
from os import getcwd
import time
import datetime
#_________________________PARAM_____________________________

loopTime=300            #attente entre les enregistrements periodiques
Pin=27                  #GPIO to monitor
Bouncetime=100
outputLog="trace.log"
dataFile="datafile.dat"

#___________________________________________________________
NBRising=0
NBFalling=0
NBFalsepositive=0
previousEdge=0

print ("Port= ",Pin)
print ("Bouncetime= ",Bouncetime)
print ("NBRising= ",NBRising)
print ("LoopTime= ",loopTime)

obFichier = open(dataFile ,'r')
releve=float(obFichier.readline())
obFichier.close()
print ("RELEVE= ",releve)

GPIO.setmode(GPIO.BCM)                                     # set up BCM GPIO numbering
GPIO.setup(Pin, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)       # set GP as input




def my_callback(channel):
    global NBRising
    global NBFalling
    global releve
    global previousEdge, NBFalsepositive
    pinStatus= GPIO.input(Pin)
    if ( pinStatus == 1 ):
        NBRising = NBRising + 1
    else:
        NBFalling = NBFalling + 1
    if ( pinStatus == previousEdge ):
        print ("False positive")
        NBFalsepositive = NBFalsepositive + 1
    else:
        previousEdge=pinStatus
        print ("True edge detected ")
        releve = releve + 0.5


GPIO.add_event_detect(Pin, GPIO.BOTH, callback=my_callback, bouncetime=Bouncetime)



while (True):
    print ("Waiting events...."  )
    sleep(loopTime)
    ts = time.time()
    now=datetime.datetime.fromtimestamp(ts).strftime('%Y-%m-%d %H:%M:%S')
    obFichier = open(outputLog,'a')
    line=now + " Rise= " + str(NBRising)  + " Fall= " + str(NBFalling) + " False= " + str(NBFalsepositive) + " Releve=  " + str(releve) + "\n "
    obFichier.write(line)
    print(line)
    obFichier.close()
    obFichier = open(dataFile ,'w')
    obFichier.write(str(releve))
    obFichier.close()

GPIO.cleanup()                                       # clean up after yourself

Conclusion

Voilà un capteur infrarouge de taille et de prix réduits qui pourra sans doute s’intégrer à un de vos projets. Là encore n’hésitez pas à laisser un retour sur votre utilisation dans les commentaires ci-dessous.

 Sources

Share Button

À propos François MOCQ

Électronicien d'origine, devenu informaticien, et passionné de nouvelles technologies, formateur en maintenance informatique puis en Réseau et Télécommunications. Dès son arrivée sur le marché, le potentiel offert par Raspberry Pi m’a enthousiasmé j'ai rapidement créé un blog dédié à ce nano-ordinateur (www.framboise314.fr) pour partager cette passion. .

15 réflexions au sujet de « Deux capteurs pour un robot »

  1. Matthieu

    Petit commentaire vite fait, on a pas 5 sens mais 9. Sinon merci pour tous les articles, je suis le site depuis longtemps, et l’effort de vulgarisation et l’accessibilité ici sont très appréciables!

    Répondre
    1. François MOCQ Auteur de l’article

      Bonjour Matthieu
      merci pour ce retour
      🙂 je suis formé à la vieille école aristotélicienne
      j’en suis resté aux 5 sens de nos anciens : la thermoception, l’équilibrioception, la nociception et la proprioception ont de toute façon des noms trop compliqués pour que je puisse les retenir vu mon grand âge 😉
      cordialement
      François

      Répondre
  2. msg

    Y a plus simple pour détecter les Fronts sur un pin d’entrée , il suffit de raisonner en binaire .

    En Python :
    # On utilise une variable globale qu’on appelle Pin_Etat .
    Pin_Etat = 0
    # Puis on boucle sur ce qui suit :
    # On commence par pousser les bits déjà enregistrés d’un rang vers la gauche .
    Pin_Etat <<= 1
    # On ajoute la valeur du Pin d'entrée .
    Pin_Etat += GPIO.input(Pin)
    # On garde uniquement les deux bits à droite du mot , les autres sont effacés .
    # le Bit 1 mémorise l'état précedent du pin
    # le Bit 0 mémorise l'état actuel du pin
    Pin_Etat %= 4
    # On obtient ainsi les 4 valeurs d'état possible :
    IF Pin_Etat == 0b00 :
    print "LOW"
    IF Pin_Etat == 0b01 :
    print "UP"
    Compteur += 1 # sur front montant au choix
    IF Pin_Etat == 0b10 :
    print "DOWN"
    Compteur += 1 # sur front descendant au choix
    IF Pin_Etat == 0b11 :
    print "HIGH"
    # c'est pas plus compliqué .

    Répondre
  3. Etienne

    Bonjour et merci pour cet articles (et les autres).
    J’avais bien repéré ce capteur VL53L0X qui semble intéressant pour remplacer (ou seconder) un HCSR04 (ou US2100). Par contre, après une première recherche rapide, l’utilisation en ‘tapant’ directement dans les registres I2C avec un petit script python ne semble pas triviale…
    J’ai trouvé uniquement
    – la lib pour arduino chez Adafruit
    – une doc du fabricant ST (UM2039 User Manual) au sujet d’une lib en C à compiler pour une couche d’abstraction (API).
    – un portage / compilation de cette API a été fait sur la framboise (https://github.com/cassou/VL53L0X_rasp)
    Si quelqu’un a des infos complémentaires ça devrait intéresser quelques bidouilleurs !
    Salutations!

    Répondre
  4. nico

    Effectivement le VL53L0X semble intéressant mais en rupture de stock chez adafruit. Dans ce cas que penser de la version disponible chez robotshop (lien ci dessous – la version roboshop mentionne une distance max de mesure de 2m) ? Serait elle compatible avec les codes pré-cités? D’autres références existent chez d’autres commerçants?
    http://www.robotshop.com/eu/fr/platine-deploiement-capteur-distance-tof-regulateur-tension-vl53l0x.html?gclid=Cj0KEQiA6_TBBRDInaPjhcelt5oBEiQApPeTF4Hy7TRm-mtluEarwsPWe2nF06CbhJfyyShHizVrHNIaAt268P8HAQ

    Je me posais une dernière question: par rapport à des capteurs à ultrason son plutôt inoffensifs, que penser de ce type de capteur laser si par exemple il venait à être dirigé accidentellement vers un oeil ?

    Répondre
    1. François MOCQ Auteur de l’article

      Bonjour
      la doc http://www.st.com/content/ccc/resource/technical/document/datasheet/group3/b2/1e/33/77/c6/92/47/6b/DM00279086/files/DM00279086.pdf/jcr:content/translations/en.DM00279086.pdf précise en page 26 que la portée peut atteindre 2,4m mais avec une précision moindre et des surfaces réfléchissantes blanches… donc la doc de robotshop est dans les clous
      Le laser est un classe 1 si l’API de ST est utilisée donc aucun danger pour les yeux (doc page 32) et
      https://www.apinex.com/det/classification_des_lasers.html

      dispo aussi chez Polulu https://www.pololu.com/product/2490
      Tindie https://www.tindie.com/products/onehorse/vl53l0x-time-of-flight-ranging-sensor/
      Banggood http://www.banggood.com/CJMCU-VL53L0X-Laser-ToF-Time-of-Flight-Ranging-Sensor-Module-For-Arduino-p-1103114.html
      cordialement
      François

      Répondre
  5. klesigo

    J’adore aussi ce VL53L0X, je l’utilise pour tous mes nouveaux projets, il peut être réglé à 22ms de temps de mesure avec des résultats qui restent correctes. Le HC-R04 permet peut être des mesures de distance plus grande, mais il reste lent si on veut éviter le problème d’écho parasite.
    Pour ce qui est de tous les capteurs de distance IR de sharp, ils ont souvent des courses de mesure bâtardes, et ils ont aussi un temps de rafraîchissement, de 16 ms pour le plus rapide de la gamme mais malheureusement, ce temps n’est pas toujours respecté par l’utilisateur, enfin, comme il faut une entrée analogique, il n’est pas plug and play avec le Raspberry.
    Perso, je les ai commandés chez pololu mais il y en a aussi en stock chez gotronic.

    Répondre
  6. gUI

    Sympa l’article, ça donne des idées !

    Par contre je ne comprends pas le capteur infrarouge pour le compteur d’eau. Qu’est-ce qu’il détecte ? Un mouvement sur le compteur (chiffres à rouleaux) ?

    Répondre
    1. François MOCQ Auteur de l’article

      Bonjour
      Stroon2 serait mieux placé que moi pour répondre (il le fera peut-être)
      certains compteurs d’eau ont une molette alternativement noire et blanche ou une roue avec des bâtons qui tourne
      je pense que c’est plutôt ça qui est détecté.
      Pour la lecture des chiffres (entre autre) voir https://youtu.be/sPl1WnNsCkU 🙂
      cordialement
      François

      Répondre

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Complétez ce captcha SVP * Time limit is exhausted. Please reload CAPTCHA.