Tuto pas à pas Python : Le capteur ultrason HCSR04

Dans ce tuto nous verrons comment réaliser un court programme permettant d’effectuer des mesures à l’aide du capteur ultrason HCSR04 fourni dans le pack d’accessoires avec CircuitPython.

Avant tout : Installation des outils

Ce tuto est réalisé sur l’IDE Mu pour Circuit Python.
Si vous n’avez pas encore installé l’un et l’autre veuillez vous référer au guide d’installation Mu et CircuitPython disponible sur le site.

Les branchements :

HCSR04 Backpack Couleur Description
GND GND BRUN Masse
VCC VBAT ROUGE Alimentation
TRIG D4 VERT Emetteur ultrason
ECHO D3 JAUNE Récepteur ultrason

Etape 1 : La base du programme

Commencez par ouvrir Mu et créer un nouveau fichier.

Copiez-y le code suivant :

from gamebuino_meta import begin, waitForUpdate, display
import time
import board
from digitalio import DigitalInOut, Direction

_USE_PULSEIO = False
try:
    from pulseio import PulseIn

    _USE_PULSEIO = True
except ImportError:
    pass

while True:
    waitForUpdate()
    display.clear()

Cela va importer les libraires Gamebuino nécessaires au fonctionnement de notre programme, On y ajoute les librairies “time” et “board” qui permettent d’utiliser des fonctions de mesure du temps et de lire des données depuis les ports externes de la console (là on l’on branche notre capteur). On importe également des fonctions spécifiques des librairies “digitalio” et “pulseio” qui vont nous servir à récupérer les données de notre capteur ultrason.

La partie commencant par “while True:” constitue la boucle principale de notre programme, sans elle il ne se passerait rien. Nous la compléterons un peu plus tard.

Etape 2 : Configurer le capteur ultrason

Pour pouvoir utiliser notre capteur on va avoir besoin de lire manipuler les deux parties qui le composent à savoir la partie émettrice TRIG et la partie réceptrice ECHO. Ceux deux parties sont banchées sur des pins digitaux, D4 pour le pin TRIG et D3 pour le pin ECHO. Ici nous allons préciser à notre programme que ce sont ces deux pins qui vont être utilisés par la suite.

Cela se fait de ka manière suivante :

trig_pin = DigitalInOut(board.D4)
trig_pin.direction = Direction.OUTPUT

On précise ainsi que le pin digital D4 de notre console s’appelle désormais “trig_pin” et on ajoute que c’est un pin de SORTIE (OUTPUT en anglais).

On s’occupe ensuite de notre pin ECHO :

if _USE_PULSEIO:
    echo_pin = PulseIn(board.D3)
    echo_pin.pause()
    echo_pin.clear()
else:
    echo_pin = DigitalInOut(board.D3)
    echo_pin.direction = Direction.INPUT

Ici on précise que notre pin digital D3 s’appelera “echo_pin” et qu’il sera un pin d’ENTRÉE (INPUT en anglais). Notez qu’on utilise une condition pour définir le statut de notre pin, cela est du à la façon dont on a importé notre fonction PulseIn un peu plus haut.

Enfin nous allons déclarer deux variables appelées “timeout” et “error_count” telles que :

timeout = 0.1
error_count = 0

Elle nous serviront à vérifier que notre capteur fonctionne correctement.

Etape 3 : Lecture et affichage de données

On va maintenant créer une fonction nous permettant d’effectuer une mesure à l’aide de notre capteur. Ensuite nous verrons brièvement comment afficher la valeur obtenue en gérant au passage les cas d’erreur de mesure.

Pour cela on crée une fonction “US_measure()” telle que :

def US_measure(trig, echo, timing):

Notez que notre fonction prend trois paramètres : les deux pins trig et echo ainsi qu’un troisième paramètre timing. Dans l’absolu ce n’est pas indispensable, on le fait ici pour rendre le code plus clair et gagner un peu de temps.
Gardez à l’esprit que nous réalisons un programme très simple à titre d’exemple, mais dans un programme plus complexe il est important de bien “ranger” et organiser son code pour s’y retrouver facilement.

On peut à présent commencer à remplir notre fonction. En premier lieu nous allons initialiser notre mesure à 0 pour éviter de lire une valeur aléatoire qui serait restée en mémoire. Ensuite nous allons déclencher notre émetteur pour envoyer une vague d’ultrasons :

    echo.clear()

    trig.value = True
    time.sleep(0.00001)
    trig.value = False

“echo.clear()” sert à purger la mémoire, ainsi on commence bien notre mesure à zéro.
Après cela on définit la valeur de notre pin “trig” à “True”, on attend un dix-millième de seconde puis on redéfinit sa valeur à “False”. On vient en fait d’envoyer du courant à l’émetteur afin qu’il puisse fonctionner et ce pendant 1/10000em de seconde, pas besoin de plus.

Ensuite nous allons déclarer deux variables qui vont nous servir pour la suite :

def US_measure(trig, echo, timing):
    echo.clear()
    
    trig.value = True
    time.sleep(0.00001)
    trig.value = False

    pulselen = None
    timestamp = time.monotonic()

La valeur de “pulselen” est initialisée à None, c’est à dire nulle, cette variable nous servira à renvoyer la valeur de notre mesure en fin de fonction. La variable timestamp, elle, va nous servir de point de repère dans le temps. Avec la fonction “time.monotonic()” on lui assigne une valeur arbitraire, cette valeur va ensuite pouvoir être comparée avec une autre afin de déterminer si oui ou non du temps s’est écoulé. Je vous renvoie à la documentation de cette fonction si vous souhaitez en savoir plus.

On va maintenant ajouter la seconde partie de notre fonction qui servira à effectuer une mesure de distance et renverra le résultat obtenu :


    if _USE_PULSEIO:
        echo.resume()
        while not echo:
            # Wait for a pulse
            if (time.monotonic() - timestamp) > timing:
                echo.pause()
                return (0)
        echo.pause()
        pulselen = echo[0]
    if pulselen >= 65535:
        return (0)
    # positive pulse time, in seconds, times 340 meters/sec, then
    # divided by 2 gives meters. Multiply by 100 for cm
    # 1/1000000 s/us * 340 m/s * 100 cm/m * 2 = 0.017
    else:
        return pulselen * 0.017

On commence par activer notre récepteur ultrason, le pin ECHO, avec la fonction “echo.resume()”.

Après cela on va attendre de recevoir un signal, pour ce faire on va comparer notre variable timestamp avec un nouvel appel de la fonction time.monotonic(), si le résultat est inférieur à la valeur de "timing (qui vaut 0.1 seconde) alors on coupe le capteur avec “echo.pause()” puis on retourne une valeur de 0 car la mesure n’a pas fonctionné.

Si on a bien reçu le signal alors on coupe le capteur et on stocke la valeur obtenue dans notre variable pulselen. Cette valeur correspond au temps écoulé entre l’envoi du signal par notre émetteur TRIG et sa réception par le capteur ECHO, on peut aussi parler de temps de vol.

Si la valeur stockée dans pulselen est supérieure ou égale à 65535 alors une erreur s’est produite et la distance mesurée est trop grande ou bien le capteur a mal fonctionné, dans les deux cas on retourne simplement 0.

Enfin si tout s’est bien passé et que notre temps de vol est dans une fourchette acceptable on le multiplie par 0.017 et on retoune la valeur obtenue. Cela nous donne en sortie de fonction une valeur en centimètres.

On peut à présent terminer notre programme en complétant notre boucle principale pour effectuer une mesure à l’aide de notre fonction “US_measure()” et afficher le résultat obtenu à l’écran.

Rien de bien compliqué, notre boucle principale ressemble pour le moment à ceci :

while True:
    waitForUpdate()
    display.clear()

Començons par effectuer une mesure à l’aide de notre fonction “US_measure()” :

while True:
    waitForUpdate()
    display.clear()

    M_distance = US_measure(trig_pin, echo_pin, timeout)

On crée une variable M_distance qui appelle la fonction et stocke le résultat obtenu.

On peut ensuite afficher la valeur obtenue ou, dans le cas d’une erreur de mesure, afficher un message adéquat :


while True:
    waitForUpdate()
    display.clear()

    M_distance = US_measure(trig_pin, echo_pin, timeout)
    if M_distance:
        display.print("Distance = ")
        display.print(str(M_distance))
        display.print(" cm")
    else:
        error_count += 1
        if error_count > 9:
            display.print("Measurement Error")
            error_count = 0
    time.sleep(0.1)

On vérifie que notre variable M_distance ne soit pas nulle avec “if M_distance”. Si c’est le cas alors on affiche tout simplement un peu de texte assorti du contenu de la variable avec la fonction “display.print()”.
Si notre variable est nulle, c’est à dire égale à 0, c’est que notre fonction de mesure n’a pas fonctionné pour une raison ou une autre. Dans ce cas on incrémente notre variable “error_count” de 1, si cette variable est supérieure à 9 c’est que notre fonction de mesure a été appelée 10 fois de suite par la boucle principale sans retourner de mesure valable, on affiche alors le message “Measurement Error” grâce à notre fonction “display.print()”.

Enfin on utilise la fonction “time.sleep(0.1)” pour marquer une pause de 0.1 seconde entre chaque exécution de notre boucle principale.

Vous avez maintenant un beau programme pour tester votre capteur ultrason HCSR04 avec votre Gamebuino.
Ce tutoriel est basé sur une librairie crée par Adafruit qui n’est pas accessible sur Gamebuino, des éléments de code on été repris depuis la documentation originale de cette librairie afin d’en répliquer le fonctionnement.

1 Like