AccueilAteliersMesure de distance
ATELIER 06 Intermédiaire

Mesure de distance

Le capteur ultrason HC-SR04 mesure la distance d’un obstacle et affiche une barre de progression sur l’écran OLED. Une LED et un buzzer alertent en cas de proximité.

3h

ESP32HC-SR04UltrasonOLEDTiming

Ce que tu vas créer

Un système de détection de proximité qui :


Matériel nécessaire

ComposantQuantitéNotes
ESP321Fourni en atelier
Capteur HC-SR041Alimentation 5V, signal ECHO en 5V !
Résistances pont diviseur1 kΩ + 2 kΩAdapter le 5V de ECHO vers 3.3V
Écran OLED SSD1306 128x641Interface I2C
LED + résistance 220 Ω1Indicateur de proximité
Buzzer passif1Alerte sonore
Câble micro-USB1Fourni en atelier

Connexions

câblage
HC-SR04 :
HC-SR04 VCC  ──── ESP32 5V (VIN)
HC-SR04 GND  ──── ESP32 GND
HC-SR04 TRIG ──── ESP32 GPIO12
HC-SR04 ECHO ──── résistance 1kΩ ──┬──── ESP32 GPIO14
                                    └──── résistance 2kΩ ──── GND
(pont diviseur 5V → 3.3V obligatoire sur ECHO)

OLED SSD1306 :
OLED SDA ──── ESP32 GPIO21
OLED SCL ──── ESP32 GPIO22

Le code

Mesure de distance MicroPython — main.py .python
atelier6-distance/main.py
109 lignes GitHub
# Atelier 06 — Mesure de distance (HC-SR04 + OLED)
# Fablab Ardèche — MicroPython
#
# Le capteur ultrason HC-SR04 mesure la distance d'un obstacle.
# Le résultat s'affiche sur l'écran OLED avec une barre de progression.
# Une LED et un buzzer alertent quand on est trop proche.
#
# Matériel : ESP32, HC-SR04, OLED SSD1306, LED, buzzer
# Connexions :
#   HC-SR04 TRIG → GPIO12
#   HC-SR04 ECHO → GPIO14  (attention : l'ECHO sort en 5V, diviser par 2 avec résistances)
#   OLED SDA     → GPIO21
#   OLED SCL     → GPIO22
#   LED alerte   → GPIO2
#   Buzzer       → GPIO5

from machine import Pin, PWM, I2C, time_pulse_us
import ssd1306
import time

# --- Configuration ---
DIST_ALERTE = 20   # cm — en dessous : alerte
DIST_MAX    = 200  # cm — distance maximale affichée

# --- Initialisation ---
trig  = Pin(12, Pin.OUT)
echo  = Pin(14, Pin.IN)
led   = Pin(2, Pin.OUT)
buz   = PWM(Pin(5))
buz.duty(0)

i2c  = I2C(0, scl=Pin(22), sda=Pin(21), freq=400_000)
oled = ssd1306.SSD1306_I2C(128, 64, i2c)

def mesurer_cm():
    """Déclenche une mesure et retourne la distance en cm."""
    # Impulsion TRIG de 10 µs
    trig.off()
    time.sleep_us(2)
    trig.on()
    time.sleep_us(10)
    trig.off()

    # Mesurer la durée de l'impulsion ECHO (timeout = 30 ms)
    duree = time_pulse_us(echo, 1, 30000)

    if duree < 0:
        return None   # timeout = pas d'obstacle détecté

    # Vitesse du son : 343 m/s → 0.0343 cm/µs → diviser par 2 (aller-retour)
    return duree * 0.0343 / 2

def barre(valeur, maxi, largeur=100):
    """Calcule la largeur d'une barre de progression en pixels."""
    return min(largeur, int(valeur / maxi * largeur))

def afficher(dist):
    oled.fill(0)
    oled.text("Distance", 0, 0)
    oled.hline(0, 10, 128, 1)

    if dist is None:
        oled.text("Hors portee", 0, 24)
        oled.text("> 2 m", 0, 38)
    else:
        # Valeur numérique
        if dist < 100:
            oled.text(f"{dist:.1f} cm", 0, 16)
        else:
            oled.text(f"{dist/100:.2f} m", 0, 16)

        # Barre de progression
        l = barre(min(dist, DIST_MAX), DIST_MAX, 120)
        oled.fill_rect(4, 30, l, 10, 1)
        oled.rect(4, 30, 120, 10, 1)

        # Indicateur d'alerte
        if dist < DIST_ALERTE:
            oled.text("!! TROP PROCHE !!", 0, 50)

    oled.show()

# --- Boucle principale ---
print("Capteur ultrason démarré")
print(f"Alerte sous {DIST_ALERTE} cm")

while True:
    dist = mesurer_cm()

    if dist is not None:
        print(f"Distance : {dist:.1f} cm")

        # Alerte sonore + LED
        if dist < DIST_ALERTE:
            led.on()
            freq_buz = int(2000 - dist * 50)   # plus proche = plus aigu
            buz.freq(max(200, freq_buz))
            buz.duty(200)
        else:
            led.off()
            buz.duty(0)
    else:
        print("Hors portée")
        led.off()
        buz.duty(0)

    afficher(dist)
    time.sleep_ms(100)

Comment ça marche

La fonction mesurer_cm

Le HC-SR04 fonctionne en envoyant une impulsion ultrasonique et en mesurant le temps de retour de l’écho. La fonction time_pulse_us de MicroPython mesure précisément ce temps :

from machine import Pin, time_pulse_us
import time

trig = Pin(12, Pin.OUT)
echo = Pin(14, Pin.IN)

def mesurer_cm():
    # Envoyer impulsion TRIG de 10µs
    trig.value(0)
    time.sleep_us(2)
    trig.value(1)
    time.sleep_us(10)
    trig.value(0)

    # Mesurer la durée de l'écho
    duree = time_pulse_us(echo, 1, 30000)  # timeout 30ms

    if duree < 0:
        return None   # pas d'écho (hors portée)

    # Vitesse du son : 343 m/s = 0.0343 cm/µs
    # Diviser par 2 car aller-retour
    distance_cm = duree * 0.0343 / 2
    return round(distance_cm, 1)

Afficher une barre de progression sur l’OLED

def barre_progression(oled, valeur, maxi, x, y, largeur, hauteur):
    rempli = int(valeur / maxi * largeur)
    oled.rect(x, y, largeur, hauteur, 1)          # contour
    oled.fill_rect(x, y, rempli, hauteur, 1)      # remplissage

Pour aller plus loin

Radar de recul voiture

Monte le HC-SR04 à l'arrière d'un véhicule RC et fais biper plus vite à l'approche d'un obstacle.

Mesure de vitesse

Utilise deux capteurs espacés pour calculer la vitesse d'un objet qui passe devant.

Niveau d'eau dans un réservoir

Pointe le capteur vers le bas pour mesurer le niveau d'eau — envoie une alerte WiFi quand c'est vide.