Fyzikální kabinet FyzKAB

Ultrazvukový sonar HC-SR04 a ESP32 s MicroPython

Aktualizováno: 14. dubna 2025

Senzor HC-SR04 je sonarové čidlo, které dokáže měřit vzdálenost od překážky pomocí odrazu ultrazvukových vln. Skládá se ze tří součástí: ultrazvukový vysílač, přijímač a elektronika pro jejich ovládání a vyhodnocení signálů.

ESP32 + HC-SR04
zdroj obrázku: https://www.instructables.com/Pocket-Size-Ultrasonic-Measuring-Tool-With-ESP32/
Obr. 1 – sonarové čidlo HC-SR04 a modul ESP32

Princip funkce senzoru HC-SR04

Ultrazvukový senzor používá k určení vzdálenosti odrazu ultrazvukových vln. Ultrazvukový vysílač vyšle vysokofrekvenční zvukový pulz (40 kHz), který se šíří vzduchem. Pokud narazí na překážku, odrazí se zpět a vrátí se do senzoru. Ultrazvukový přijímač přijme odražený zvuk (echo). Pro určení vzdálenosti tedy stačí změřit čas od vyslání sonarového pulzu do okamžiku jeho návratu. S přihlédnutím na rychlost zvuku ve vzduchu a dobu cesty můžeme vypočítat vzdálenost k objektu podle následujícího vzorce:

vzdálenost = ( rychlost zvuku ) × čas 2

kde rychlost zvuku ve vzduchu při 20 °C je 343 m/s

Následující obrázek (obr. 2) ukazuje celý tento proces z pohledu průběhu signálů modulu HC-SR04. TTL pulz o délce 10 μs na vstupním pinu TRIG spustí vysílání. Následuje vyslání osmi 40 kHz zvukových signálů. Po skončení posledního ze signálů se výstupní pin ECHO nastaví na úroveň HIGH, ze které klesne na úroveň LOW až po přijetí navráceného zvukového signálu. Doba trvání úrovně HIGH na pinu ECHO tedy odpovídá času, který dosadíme do předchozího vzorce. Protože zvuk letí tam a pak zpět, skutečná vzdálenost k překážce je jen polovina vzdálenosti uražené zvukem.

casovy diagram
Obr. 2 – průběh signálů modulu HC-SR04 při měření vzdálenosti

Připojení sonarového čidla k modulu ESP32

Jak jsme již v dřívějším článku ESP32 a ultrazvukový senzor HC-SR04 psali problémem klasického sonarového čidla HC-SR04 je jeho pětivoltová logika. Naštěstí od té doby se trochu ledu hnuly a nyní je na trhu již k dostání modul HC-SR04 ve verzi RCWL-9610, která je novějším provedením modulu HC-SR04 a má pracovního napětí 3,3–5 V. To je pro nás skvělá zpráva, neboť takový modul lze přímo připojit k 3,3V napájení a logice modulu ESP32. Tento novější model má také inteligentnější komunikační čip, takže nativně umí nejen UART, ale i I²C, 1Wire režimy (volí se proletováním propojek na zadní straně modulu). Ale jak ukazují ohlasy různých bastlířů, kteří experimentovali kupříkladu s I²C, je asi lepší se stále držet starého a osvědčeného ovládání přes piny TRIG a ECHO! Alespoň my to tak v tomto článku uděláme.

Nový modul HC-SR04 verze RCWL-9610 je na první pohled (a i cenou) k nerozeznání od staršího modulu. Je tedy dobré podrobně číst popisy nabízených produktů u jednotlivých prodejců. Takovým vodítkem při identifikaci nového typu sonarového čidla je tištěný popis pinů na přední straně, kde je vyveden popis pinů i pro jiné komunikační sběrnice (viz obrázek 3).

srovnaci cidel sonaru
Obr. 3 – srovnání čidla HC-SR04 verze RCWL-9610 a původní verze čidla

Technické specifikace modulu HC-SR04 (RCWL-9610)

  • Modul vyžaduje napájení 3,3–5V.
  • Spotřeba: pro správnou funkci asi 20 mA (klidový proud <2 mA).
  • Rozsah vzdálenosti: mezi 2 cm až 4 m
  • Pracovní úhel: <15 stupňů
  • Ultrazvuková frekvence: 40 kHz (neslyšitelná pro ucho)

Připojení snímače HC-SR04 (RCWL-9610) na ESP32

Kromě napájecích pinů použijeme pro ovládání modulu další dva piny. Volba těchto pinů může být téměž libovolná. Pro pin TRIG je třeba použít pin, který lze nakonfigurovat a používat jako digitální výstup, pro pin ECHO naopak jako digitální vstup. Prý existuje i možnost, kdy použití jen jeden pin, ale nyní není třeba (patrně to lze využít v případě, kdy by na modulu ESP32 již byly ostatní piny obsazené). Při pojíme tedy sonarové čidlo k modulu ESP32 podle následující tabulky.

Čidlo HC SR04
(RCWL-9610)
Modul ESP32
TRIG GPIO5
ECHO GPIO18
GND GND
VCC 3,3V

Tab. č. 1 – Propojení pinů sonarového čidla a modulu ESP32

schema sonar a ESP32
Obr. 4 – schéma zapojení sonarového čidla HC-SR04 (RCWL-9610) k modulu ESP32

Měříme vzdálenosti v MicroPythonu (bez knihovny)

Jednoduchost celého ovládání sonarového čidla HC-SR04 nám umožní změřit modulem ESP32 vzdálenost od překážky, aniž bychom potřebovali nějakou externí knihovnu. I když je možné, že by se při pečlivém pátrání po internetu nějaký pomocný modul asi našel. My vyjdeme ze základního vzorce, který jen trochu modifikujeme pro zadání času v mikrosekundách a získání vzdálenosti v centimetrech:

d vzdálenost ( cm ) = t ultrazvuk ( μs ) × v zvuku ( m/s ) × 10 –4 2

Níže uvedený kód v MicroPythonu bude postupovat přesně podle výše uvedeného časového diagramu (obr. 2). Nejdříve odstartuje vyslání měřicího signálu pomocí deset mikrosekund dlouhého pulzu na pinu TRIG, pak se překlopí do čekací smyčky, kdy bude vyčkávat návrat sonarového signálu, který způsobí změnu na pinu ECHO. Pro vyčkávání na odezvu na pinu ECHO využijeme zvláštní metodu time_pulse_us().

Metoda time_pulse_us()

V MicroPythonu je metoda time_pulse_us() (součást modulu machine) slouží ke změření délky pulsu na určitém pinu. Návratová hodnota je čas v mikrosekundách. Metoda měří čas mezi změnami logického stavu z LOW na HIGH, nebo z HIGH na LOW. Tato metoda je tedy přesně určená pro naše účely čekání na odezvu signálu ECHO, kdy čekáme na okamžik přechodu pinu ECHO z hodnoty HIGH na LOW.

Metoda time_pulse_us() má následující vstupní argumenty:

  1. pin: Objekt typu Pin, který reprezentuje pin, na kterém chcete měřit čas. Tento pin by měl být nastaven na vstupní režim (Pin.IN).
  2. level: Úroveň signálu, kterou chcete měřit. Může být:
    • 1 – pro měření pulzu, kdy je pin na logické úrovni HIGH.
    • 0 – pro měření pulzu, kdy je pin na logické úrovni LOW.
  3. timeout (volitelný): Maximální čas v mikrosekundách, během kterého má funkce čekat na detekci změny stavu. Pokud signál během této doby nezmění úroveň, metoda vrátí zápornou hodnotu (viz dále). Výchozí hodnota je 1 milion mikrosekund (1 sekunda).

Kromě běžné kladné hodnoty určující počet mikrosekund čekání zadanou změnu může být vrácena i záporná hodnota, konkrétně –1 nebo –2. Tyto hodnoty mají specifické významy a mohou indikovat různé chyby při měření pulzu.

Hodnota –1 je navrácena, pokud je sledovaný pin již na začátku v požadovaném stavu, ale během samotného měření do vypršení časového limitu nebyl detekován žádný pulz. Naopak hodnota –2 se vrací, pokud sledovaný pin není v požadovaném stavu a timeout vyprší, než pin přejde do požadovaného stavu (tedy nedojde ke změně stavu na požadovanou hodnotu).

Nyní, když víme, jak funguje metoda time_pulse_us, napíšeme následující kód:

from machine import Pin, time_pulse_us
import time

SOUND_SPEED = 343     # rychlost zvuku ve vzduchu (20°C)
TRIG_PULSE_DURATION_US = 10

trig_pin = Pin(5, Pin.OUT)
echo_pin = Pin(18, Pin.IN)

while True:
    # priprava pulz
    trig_pin.value(0)
    time.sleep_us(5)     # nastavení LOW před pulzem
    trig_pin.value(1)
    time.sleep_us(TRIG_PULSE_DURATION_US)     # vytvoreni 10us pulzu
    trig_pin.value(0)

    ultrason_duration = time_pulse_us(echo_pin, 1, 30000)     # cekani na ECHO (merime cas)
    distance_cm = SOUND_SPEED * ultrason_duration / 20000     # vypocet vzdalenosti

    print(f"Distance (cm) : {distance_cm}")
    time.sleep_ms(500)

Na samém začátku hlavní nekonečné smyčky program vytvoří 10 µs impuls na výstupním pinu GPIO5 (TRIG).

Funkce time_pulse_us() pozastaví program, dokud neobdrží impuls odezvy z HC-SR04 připojeného na vstupní pinu GPIO18 (ECHO). Aby nedošlo k „zaseknutí“ programu, pokud by se sonarové signály nevracely (např. sonarové čidlo ve volném prostoru), je zde nastaven timeout na hodnotu 0,03 s (30000 μs), což odpovídá vzdálenosti asi 5 metrů. Všimněme si, že v tomto jednoduchém kódu vůbec nejsou ošetřeny možné záporné návratové hodnoty funkce time_pulse_us().

To zde opět necháváme jako možný dobrovolný domácí úkol. 😉

Jakmile získáme počet mikrosekund, za které se sonarový signál vrátil, vypočítáme vzdálenost. Program pak zobrazí vzdálenost mezi sonarovým modulem a objektem (překážkou) na sériový výstup (viz obrázek 5).

namerene vzdalenosti
Obr. 5 – výstup naměřené vzdálenosti na výstupu v prostředí Thonny IDE
Poznámka:
Na obrázku č. 5 vidíme mimo jiného i zápornou hodnotu ( Distance: -0.017 cm), která znamená, jak jsme dříve naznačili, že ultrazvukový modul nepřijal vlnu, kterou vyslal. Důvodem je vypršení časového limitu funkce time_pulse_us(). K tomuto efektu nemusí dojít jen v případě volného prostoru před detektorem, ale i v případě šikmé překážky, která signál odrazí pryč od detektoru.
sonar a ESP32
zdroj obrázku: https://randomnerdtutorials.com/esp32-hc-sr04-ultrasonic-arduino/
Obr. 6 – čidlo HC-SR04 řízené modulem ESP32

Měříme vzdálenosti v MicroPythonu (s knihovnou)

Jestliže jsme si ukázali princip základního načítání modulu HC-SR04 deskou ESP32 pomocí MicroPythonu, zkusíme využít některé z již hotových knihoven. Uvidíme, že toto použití knihovny (modulu) kód trochu zjednoduší, ale na druhou stranu vůbec nebudeme tušit, co se při načítání sonaru HC-SR04 děje. Pro účel tohoto článku použijeme knihovnu HC-SR04 pro MicroPython (autor: Roberto Sánchez), která nám poskytne slíbené usnadnění komunikace se senzorem a získání výsledku měření.

Tato knihovna není součástí standardního firmware MicroPython, takže ji musíme ke svému projektu přidat jako externí soubor. Přidání externí knihovny k projektu jsme si již ukazovali, takže nyní si ukážeme nejjednodušší způsob, jak to co nejrychleji udělat v prostředí Thonny IDE.

  1. Stáhneme kód knihovny z výše uvedeného odkazu a otevřeme jej v prostředí Thonny IDE.
  2. Uložíme soubor knihovny do zařízení (nejlépe do složky lib)
    1. Přejdeme na v menu SouborUložit jako…
    2. Vybereme v dialogu Uložit do… volbu MicroPython zařízení .
    3. Zvolíme složku lib (pokud v zařízení neexistuje, tak ji vytvoříme) a soubor uložíme pod názvem hcsr04.py
  3. Po nahrání knihovny do našeho zařízení ji můžeme importovat a používat její funkce ve svém kódu.

Jestliže můžeme importovat a použít knihovnu/modul hcsr04, pojďme na kód!

from hcsr04 import HCSR04
import time

# deklarace objektu senzoru
sensor = HCSR04(trigger_pin=5, echo_pin=18, echo_timeout_us=10000)

while True:
    # nacteni vzdalenosti
    distance = sensor.distance_cm()

    print(f"Distance (cm) : {distance_cm}")
    time.sleep_ms(500)

A to je vše!

Všimněte si, že při použití knihovny hcsr04.py ani nemusíme importovat objekt Pin a time_pulse_us z modulu machine. Protože tato knihovna oba tyto objekty využívá, importuje si je sama.

Podrobnosti o knihovně HC-SR04 pro MicroPython

Když jsme díky knihovně hcsr04.py mohli docela rychle odbýt hlavní program, zkusíme se aspoň zaměřit na knihovnu samotnou. V programovém kódu jsme poznali metodu distance_cm(). Další metodou je ještě metoda distance_mm(). Pojďme se na obě podívat podrobněji:

distance_cm()
Metoda (jak jsme již poznali) vrací reálné číslo odpovídající vzdálenosti naměřené senzorem.
distance_mm()
Tato metoda vrací vzdálenost v milimetrech v podobě celého čísla, což má tu výhodu, že nepoužívá plovoucí desetinnou čárku. Dle autora knihovny je (prý) tato metoda navržena pro prostředí, která nepodporují operace s plovoucí desetinnou čárkou.

Před použitím těchto funkcí je potřeba deklarovat proměnnou objektu HCSR04:

sensor = HCSR04(trigger_pin=5, echo_pin=18, echo_timeout_us=10000)

Při této deklaraci zadáváme dva povinné parametry trigger_pin a echo_pin, kterými specifikujeme čísla pinů modulu ESP32, které jsou připojené k pinům TRIG a ECHO senzoru HC-SR04. Třetí (nepovinný) parametr echo_timeout_us nastavuje čas (μs), po který se čeká na návrat sonarového signálu. Výchozí hodnota je nastavena na čas pro maximální vzdálenost 4 metry. (Obdobný parametr jsme viděli dříve u time_pulse_us)

Na samý závěr se ještě podíváme na to, jak ošetřit situaci, kdy proběhne stanovený „timeout“. Zatímco v případě time_pulse_us se tato situace projevila některou ze záporných výstupních hodnot, u těchto metod se tento problém převede na OSError('Out of range'). Ošetření tedy provedeme pomocí standardní struktury tryexcept, která se pro takové případy výborně hodí:

try:
    distance = sensor.distance_cm()
    print(f"Distance (cm) : {distance_cm}")
except OSError as ex:
    print('CHYBA ziskani vzdalenosti:', ex)

Možný výstup pak vidíte na obrázku č. 7.

namerene vzdalenosti
Obr. 7 – výstup naměřené vzdálenosti pomocí knihovny hcsr04.py (výstup prostředí Thonny IDE)

Závěr

V dnešním článku jsme se seznámili s použitím ultrazvukového senzoru HC-SR04 v kombinaci s modulem ESP32, řízeným pomocí MicroPythonu. Pro naše experimenty jsme použili novější verzi senzoru HC-SR04 typ RCWL-9610, který má širší napěťový rozsah (3,3–5V), což zjednodušuje jeho použití s modulem ESP32.

V rámci zde prezentovaných programových kódů jsme se seznámili:

  • s metodu time_pulse_us(), kterou jsme využili pro měření doby trvání pulzu na pinu ECHO, která odpovídá času, který ultrazvukový signál potřeboval k návratu od překážky.
  • s knihovnou hcsr04.py, která zjednodušila zápis kódu, ale jinak funguje zcela obdobně našemu prvnímu přístupu, kde jsme sami vzdálenost počítali z doby naměřené odezvy.

Celkově nám tento dnešní projekt ukázal jednoduchost a efektivitu použití HC-SR04 s modulem ESP32 pro měření vzdálenosti v reálných aplikacích. Možné využití tohoto senzoru s modulem ESP32 jsou poměrně široké. Můžeme ho využít například pro:

  • Bezpečnostní systémy – Senzor může detekovat pohyb a vzdálenost od objektu, což je ideální pro implementaci v automatických dveřích nebo bezpečnostních systémech, kde je potřeba detekovat přítomnost osoby či objektu v určitém prostoru.
  • Robotika – Ultrazvukový senzor může sloužit k navigaci autonomních robotů, které se vyhýbají překážkám. Měření vzdálenosti je klíčové pro určování trajektorie a reakce robota na objekty v jeho okolí.
  • Automatizace a řízení – Tento senzor může být použit pro monitorování hladiny tekutin v nádržích nebo jiných kontejnerech, kdy pomocí měření vzdálenosti zjistíme aktuální hladinu materiálu.

Tyto aplikace tak mohou přispět k optimalizaci různých procesů a zjednodušení každodenního života, a to jak v průmyslových aplikacích, tak v domácnostech.

UPOZORNĚNÍ:
Nesouhlasíme s vyřazením Newtonových zákonů, Ohmova zákona a zákona zachování energie z učiva fyziky základních škol v České republice!