ESP32: Magnetické nebo zvukové čidlo v MicroPythonu
Dneska začneme trochu jako z nějakého vtipu: „Víte, co mají společného magnetický a zvukový senzor?“ Nevíte? Tak čtěte dál – možná vás překvapí, že na první pohled vlastně vůbec nic… ale při bližším zkoumání se ukáže, že toho mají víc společného, než by se zdálo.
Různé experimentální sady pro mikrokontroléry, ať už pro Arduino nebo pro náš oblíbený ESP32, často obsahují spoustu různých čidel. Pokud si vezmete jednu takovou sadu a začnete se v ní trochu „vrtat“, najdete v ní spoustu zajímavých senzorů, které přímo vyzývají k tomu, abyste je vyzkoušeli.
V tomto článku se tedy pustíme do zapojování čidel k modulu ESP32 a ukážeme si, jak je oživit pomocí MicroPythonu. Začneme jednoduššími moduly – konkrétně si dnes posvítíme na dva, které sice vypadají podobně, ale měří úplně jiné věci. Řeč bude o Hallově senzoru KY-024 (citlivém na magnetické pole) a zvukovém senzoru KY-037. Přestože fungují na úplně jiném principu, zjistíme, že jejich použití v MicroPythonu je překvapivě podobné.


Už na první pohled si nemůžeme nevšimnout, že KY-024 (magnetický senzor) a KY-037 (zvukový senzor) jsou si docela podobné. Když je položíte vedle sebe (viz obr. 1), zjistíte, že jsou osazené na velmi podobných deskách plošných spojů a mají téměř totožné rozložení součástek i výstupních pinů – viz rozkreslení na obrázku č. 2.


Magnetický senzor KY-024 (nahoře) a zvukové čidlo KY-037 (dole)
Ale jak to tak bývá, zdání někdy klame. Abychom zjistili, co tyhle dva senzory opravdu umí, musíme se podívat na to, jak fungují uvnitř – tedy na princip měření a samozřejmě i na elektronické schéma.
Schéma senzoru
Oba senzory zachycují určitou fyzikální veličinu (magnetické pole nebo zvuk) a převádějí ji na elektrický signál. Ten pak zpracovávají dvěma způsoby – jako analogový výstup (na pinu A0
) a jako digitální výstup (na pinu D0
). Detailní schéma zapojení najdete na obrázku č. 3. A tady už se to začíná zajímavě sbližovat. Pokud se podíváme na zapojení obou senzorů, zjistíme, že jsou si nejen podobné navenek, ale i uvnitř. Oba používají dvojici operačních zesilovačů, a jejich úloha je v podstatě stejná.


Jak senzory fungují?
První zesilovač slouží jako komparátor – tedy obvod, který porovnává dvě napětí. Na jeho invertující vstup (označený „–“) přichází signál ze senzoru – buď napětí z mikrofonu, nebo z Hallovy sondy. Na neinvertující vstup („+“) je přivedeno referenční napětí, které je nastavené pomocí potenciometru (odporového děliče). Jakmile napětí ze senzoru klesne pod tuto referenční hodnotu, komparátor „překlopí“ svůj výstup – a na digitálním pinu D0
se objeví signál HIGH
. Pokud je vstupní napětí vyšší než referenční, výstup je LOW
.
Konkrétně u zvukového senzoru to funguje tak, že mikrofon má při tichu vysoký odpor, takže na vstupu zesilovače je napětí blízké napájecímu napětí (Vcc
) – a výstup je v klidovém stavu LOW. Jakmile ale zaznamená hluk, odpor klesne, napětí na vstupu se sníží a v určitém bodě dojde k překlopení výstupu na HIGH
. U magnetického senzoru je princip stejný – jen místo mikrofonu je použit Hallův snímač, který reaguje na změnu magnetického pole.
Pomocí potenciometru na modulu lze nastavit, jak silný musí být vstupní signál, aby došlo k překlopení – například jak hlasitý zvuk spustí alarm.
A co ten druhý zesilovač? Ten má trochu méně slavnou roli – jeho hlavním úkolem je jen rozsvítit LED diodu, která indikuje, že digitální výstup (D0
) je právě na úrovni logické jedničky. I to se ale při ladění senzoru hodí.
Připojení senzorů k modulu ESP32
Datové listy obou senzorů uvádějí, že fungují jak při napájení 5 V (což se hodí třeba pro Arduino), tak i při 3,3 V – což je přesně napětí, se kterým pracuje náš ESP32. To znamená, že moduly můžeme napájet přímo z pinu 3V3
na ESP32 a k jejich výstupům připojit některý z GPIO pinů, který podporuje analogové nebo digitální čtení.
A protože si chceme v MicroPythonu ulehčit život a použít stejný kód pro oba senzory, připojíme je v našich ukázkách ke stejným pinům. Díky tomu pak můžeme jednoduše přepojit jeden za druhý, aniž bychom museli upravovat program.
Menší háček s napájením
Teď ale pozor – i když moduly oficiálně zvládají napájení 3,3 V, v praxi to není vždy ideální. Zvlášť zvukový senzor se při napájení z pinu 3V3 chová dost nestabilně – má sklony k šumu, náhodnému spínání a celkově není úplně spolehlivý. Magnetický senzor je na tom podstatně lépe a funguje bez větších potíží.
Možná vás při tom napadne tak trochu „kacířská“ myšlenka: co kdybychom tedy zvukový senzor napájeli z 5 V? Ano, jeho výstupní signál by byl pak mnohem stabilnější a citlivější. Jenže pozor – ESP32 není stavěné na 5V logiku. Pokud připojíme jeho vstupní pin přímo na 5V výstup senzoru, riskujete poškození modulu ESP32.
- Upozornění:
- Na internetu se bohužel objevují návody, které právě tohle dělají – tedy napájejí senzor z 5 V a výstup (
A0
neboD0
) připojují rovnou na GPIO pin ESP32. Jenže ve chvíli, kdy výstup senzoru přejde na úroveňHIGH
(5 V), dostane se plné napětí na pin mikrokontroléru – bez jakékoliv ochrany. A to může znamenat jeho trvalé poškození! - Pokud tedy opravdu potřebujeme napájet senzor 5 V, nezapomeňme na ochranný odporový dělič nebo jinou formu napěťové úpravy výstupu na bezpečných 3,3 V.
Zvukový signál – rychlý a neklidný
Další problém u zvukového senzoru nesouvisí ani tak s napájením, jako spíše s povahou samotného signálu. Zvuk je proměnlivý, obsahuje špičky a výkyvy – a právě ty na digitálním výstupu D0
vytvářejí velmi krátké pulzy. Pokud se signál nachází blízko rozhodovací hranice komparátoru, může výstup silně a rychle kmitat.
Pro serióznější použití (například pro spolehlivou detekci hlasitého tlesknutí) by bylo dobré výstup senzoru doplnit o jednoduchý monostabilní klopný obvod s vhodnou časovou konstantou, který každý impuls trochu „protáhne“ a vytvaruje. Alternativně lze použít Schmittův klopný obvod, který zamezí kmitání v přechodové oblasti a výstupní signál tak ještě lépe vytvaruje.
Následující schémata ukazují zapojení obou senzorů. Pro další pokusy už budeme pokračovat jen s magnetickým senzorem, protože je při napájení z ESP32 stabilnější. Nicméně veškerý kód, který si ukážeme, funguje úplně stejně i pro zvukový senzor.


Tabulka propojení mezi senzory a ESP32 platí tedy pro oba moduly. Jen je potřeba dát si pozor při výběru pinů – pro analogové čtení musí jít o GPIO pin, který je v modulu ESP32 propojený s interním A/D převodníkem.
ESP32 | KY024 / KY034 |
---|---|
GPIO4 | AO |
GND | G |
3V3 | + |
GPIO19 | DO |
Řídicí program v MicroPython
V naší ukázce budeme číst oba výstupy senzoru – tedy analogový i digitální. V praxi se obvykle používá jen jeden z nich, podle potřeby – ale protože si chceme senzory pořádně „osahat“, načteme si oba zároveň.
Pro analogový výstup použijeme pin GPIO4
, na který připojíme interní A/D převodník ESP32. Pro digitální výstup využijeme GPIO19
, přepnutý do režimu digitálního vstupu.
Pokud si nejste jistí, jak pracovat s GPIO piny v MicroPythonu, můžete mrknout na naše předchozí články:
Program nebude nijak složitý. Každý cyklus:
- Načte analogový signál ze senzoru,
- Zobrazí jeho hodnotu v konzoli,
- Zkontroluje digitální výstup,
- A pokud je výstup v logické jedničce (
HIGH
), vypíše, že byla překročena prahová hodnota.
Níže najdete kód programu. V další části si pak krok po kroku vysvětlíme, co přesně jednotlivé části dělají.
from machine import Pin, ADC
import time
SENSOR_DIGITAL_PIN = 19 # diginal OUT pin
SENSOR_ANALOG_PIN = 4 # analog OUT pin
sensor_D_pin = Pin(SENSOR_DIGITAL_PIN, Pin.IN)
sensor_A_pin = ADC(Pin(SENSOR_ANALOG_PIN)) # prirazeni ADC pinu
"""
utlum maxU konst
0dB 1,2V ATTN_0DB
2,5dB 1,5V ATTN_2_5DB
6dB 2,0V ATTN_6DB
11dB 3,3V ATTN_11DB
"""
sensor_A_pin.atten(ADC.ATTN_11DB) # nastaveni utlumu
while True:
analog_value = sensor_A_pin.read()
digital_value = sensor_D_pin.value()
print("Analog:", analog_value,
"Digital:", digital_value,
"- Prahova hodnota dosazena" if digital_value else "")
time.sleep(0.1)
V úvodu programu si naimportujeme moduly, které budeme potřebovat:
Pin
pro práci s GPIO piny,ADC
pro čtení analogového signálu,- a
time
pro jednoduché časování v hlavní smyčce.
Dále si definujeme dvě konstanty: SENSOR_
a SENSOR_
, které určují čísla pinů, ke kterým máme senzor připojený. (Viz tabulka č. 1.)
SENSOR_DIGITAL_PIN = 19 # diginal OUT pin
SENSOR_ANALOG_PIN = 4 # analog OUT pin
Nastavíme pin pro digitální čtení. Pomocí třídy Pin
ho přepneme do režimu vstupu:
sensor_D_pin = Pin(SENSOR_DIGITAL_PIN, Pin.IN)
U analogového výstupu to funguje trochu jinak – musíme vytvořit objekt typu ADC
, který umožňuje přístup k vnitřnímu A/D převodníku (tedy převodníku z analogového na digitální signál).
sensor_A_pin = ADC(Pin(SENSOR_ANALOG_PIN, Pin.IN))
Jak jsme si říkali v článku o měření analogového napětí, je potřeba ještě nastavit, jaké napěťové rozmezí má převodník očekávat. Protože zatím nevíme, jak silný signál na vstupu bude, nastavíme nejvyšší možný rozsah – až do 3,3 V. Toho dosáhneme zadáním útlumu 11dB:
sensor_A_pin.atten(ADC.ATTN_11DB)
V hlavní smyčce pak pomocí metod read()
a value()
načítáme obě hodnoty: digital_value
a metodou read()
analogová hodnota do proměnné analog_value
.
analog_value = sensor_A_pin.read()
digital_value = sensor_D_pin.value()
A obě vypíšeme na výstup. Pokud je digitální výstup v logické jedničce (HIGH
), doplníme výpis o zprávu, že byla překročena prahová hodnota:
print("Analog:", analog_value, "Digital:", "- Prahova hodnota dosazena" if digital_value else "")
Možná jste si všimli zvláštní konstrukce if digital_value else
. To je takzvaný ternární výraz, typický pro Python. Funguje to tak, že se vyhodnotí podmínka (v našem případě digital_value
) – a pokud je pravdivá (tj. výstup je HIGH
), vypíše se text "Prahová hodnota dosažena". Pokud není, nevypíše se nic (jen prázdný řetězec).
Malá odbočka: Víceřádkový komentář v Pythonu
V předchozím ukázkovém kódu jsme tak trochu tiše prošli kolem jednoho zajímavého zápisu – textu uzavřeného v trojitých uvozovkách:
"""
utlum maxU konst
0dB 1,2V ATTN_0DB
2,5dB 1,5V ATTN_2_5DB
6dB 2,0V ATTN_6DB
11dB 3,3V ATTN_11DB
"""
V Pythonu (a stejně tak i v MicroPythonu) trojité uvozovky """ ... """
nebo ''' ... '''
označují tzv. víceřádkový řetězec (tzv. multiline string). Můžeme do něj zapsat libovolný počet řádků textu – což se hodí třeba při vytváření tabulek, HTML kódu nebo delších popisů.
Ale pozor – nejde o komentář v pravém slova smyslu! Na rozdíl od klasických komentářů označených znakem #
:
- Python tento text vytvoří jako řetězcový objekt (byť ho pak zahodí, pokud ho nikam nepřiřadíte),
- zabírá tedy zbytečně místo v paměti, i když ho nijak nepoužijete,
- a může v některých případech dokonce zpomalovat běh programu (byť minimálně).
Proto je dobré tento způsob „komentování“ brát spíš jako nouzové řešení než běžnou praxi.
Kdy je to v pořádku?
Použití víceřádkového řetězce má smysl například tehdy, když:
- ukládáte delší text do proměnné (např. HTML šablonu, nápovědu nebo dokumentaci),
- nebo zapisujete dokumentační řetězce (tzv. docstring) u funkcí, tříd nebo modulů.
To je v Pythonu běžná praxe. Jenže smutná zpráva je, že MicroPython na ESP32 většinu těchto dokumentačních řetězců úplně ignoruje – což znamená, že v reálném nasazení na malém mikrokontroléru se stejně nevyužijí. 😟
A kdy se tomu radši vyhnout?
Zapsat si „komentář“ takhle:
"""
Tohle je víceméně komentář,
ale v paměti vznikne zbytečný objekt...
"""
…je sice technicky možné, ale z hlediska správné praxe v MicroPythonu to není úplně čisté.
Někteří vývojáři pro to mají odborný výraz: prasárna – protože to vypadá jako komentář, ale chová se to jako řetězec bez účelu.
A ten náš předchozí příklad?
No dobře, byl to tak trochu odstrašující případ… ale co bychom pro demonstraci neudělali. 😉
Testování programu
A teď konečně přichází chvíle pravdy – jdeme si náš program vyzkoušet v reálném světě. Pokud používáte magnetický senzor (KY-024), připravte si malý magnet nebo alespoň zmagnetovaný kovový předmět – třeba hrot šroubováku nebo nůž. V nouzi stačí i klíč, pokud byl chvíli poblíž magnetu.

Po připojení senzoru k modulu ESP32 spustíme program a sledujeme sériový výstup v prostředí Thonny IDE. Pomalu přibližujeme a oddalujeme zmagnetovaný předmět ke snímači – a přitom pozorujeme, jak se mění analogová hodnota, kterou senzor měří, a digitální výstup, který indikuje překročení prahové hodnoty.
Chování senzoru se může lišit podle toho, jaký pól magnetu k němu přiblížíte. Může se stát, že se analogová hodnota zvětšuje, nebo naopak zmenšuje – záleží na směru magnetického pole. Hallova sonda totiž reaguje nejen na sílu pole, ale i na jeho polaritu.
Díky tomu můžete vyzkoušet chování senzoru pro obě orientace magnetu. Pokud používáte obyčejný magnet, jednoduše ho otočte a sledujte, co se změní.
Nastavení trimru
Na desce senzoru najdete malý trimr, který slouží k nastavení prahové úrovně, při které se digitální výstup přepne. Např. pokud chcete, aby se LED rozsvítila při přiblížení magnetu – nastavíte trimr tak, aby výstup přešel do stavu HIGH
při dosažení určité síly pole.
A co když testujete zvukový senzor (KY-037)? V tom případě postupujeme podobně. Trimrem nastavíme citlivost tak, aby při tichu byl digitální výstup LOW (LED nesvítí), a při hlasitějším zvuku (tlesknutí, potlesk, hlasitý hovor) se výstup přepnul do HIGH
(LED se rozsvítí).
Je dobré chvíli experimentovat – senzory nejsou vždy z výroby přesně seřízené.
Obrázek č. 6 znázorňuje ukázkový výpis naměřených výstupních hodnot v okně prostředí Thonny IDE při přiblížení magnetu k magnetickému čidlu.

Přerušení: (skvělý nápad… nebo slepá ulička?)
Možná si vzpomínáte na náš předchozí článek, kde jsme si v MicroPythonu hráli s přerušeními na ESP32 (článek: MicroPython: Přerušení na ESP32). A možná vás při dnešních hrátkách s modulem ESP32 napadlo: „Co kdybychom přerušení použili i tady? Vždyť digitální výstup senzoru je pro to jako dělaný!“
No jasně – proč to nezkusit? Pojďme na to!
Nahrazení kontroly stavu pinu přerušením
Upravíme náš program tak, aby hlášku „Prahová hodnota dosažena“ nevypisoval na základě přímé kontroly pinu, ale na základě informace z přerušovací rutiny. Tato rutina bude připojena na digitální výstup senzoru (sensor_D_pin
) a bude mít jediný úkol: podle aktuálního stavu pinu přepnout globální proměnnou udalost
.
def handle_irq(pin):
global udalost
if pin.value() == 1:
udalost = True
else:
udalost = False
Tato funkce tedy jednoduše aktualizuje stav proměnné udalost
, kterou pak v hlavní smyčce použijeme místo přímého čtení pinu:
print("Analog:", analog_value, "Digital:", digital_value, "- Prahova hodnota dosazena" if udalost else "")
Aktivace přerušení
Teď už jen zbývá přiřadit tuto rutinu konkrétnímu pinu:
sensor_D_pin.irq(trigger=Pin.IRQ_RISING | Pin.IRQ_FALLING, handler=handle_irq)
Tím zajistíme, že se funkce handle_irq()
spustí při jakékoliv změně stavu signálu – tedy při vzestupné i sestupné hraně.
Zde máme celá kód s využitím přerušení.
from machine import Pin, ADC, Timer
import time
SENSOR_DIGITAL_PIN = 19
SENSOR_ANALOG_PIN = 4
sensor_D_pin = Pin(SENSOR_DIGITAL_PIN, Pin.IN)
sensor_A_pin = ADC(Pin(SENSOR_ANALOG_PIN))
sensor_A_pin.atten(ADC.ATTN_11DB)
udalost = False
def handle_irq(pin):
global udalost
if pin.value() == 1:
udalost = True
else:
udalost = False
# aktivace přerušení
sensor_D_pin.irq(trigger=Pin.IRQ_RISING | Pin.IRQ_FALLING, handler=handle_irq)
while True:
analog_value = sensor_A_pin.read()
digital_value = sensor_D_pin.value()
print("Analog:", analog_value,
"Digital:", digital_value,
"- Prahova hodnota dosazena" if udalost else "")
time.sleep(0.1)
Obrázek č. 7 ukazuje výpis načtených hodnot programu založeném na přerušení.

A teď upřímně… mělo to smysl?
Funguje to. Vypadá to „mazácky“. Ale co jsme tím vlastně získali?
Upřímně – spíš jsme si přidělali práci. Místo přímého čtení hodnoty z pinu, které stejně v kódu stále provádíme, teď sledujeme kopii téže informace jen získané skrz přerušení. Žádná nová funkcionalita, žádné zrychlení, jen složitější cesta ke stejnému výsledku.
Ano, přerušení jsou důležitý nástroj a rozhodně se hodí je umět používat. Ale ne vždy vedou k lepšímu řešení. V tomto případě je jednodušší a přehlednější kontrolovat stav pinu přímo.
Na druhou stranu – pokud si přerušení chcete vyzkoušet v praxi, je tohle ideální příležitost.
I slepá ulička vás může hodně naučit. 😎
Takže až příště budete chtít sáhnout po přerušeních, vzpomeňte si na tento příklad. Někdy i ten „nejjednodušší“ kód je vlastně tím nejlepším řešením.
Závěr:
V dnešním článku jsme se podívali na dva jednoduché senzory – zvukový a magnetický – které by se daly použít s ESP32. Ať už budete detekovat magnety v šuplíku nebo tleskání v místnosti, tyto jednoduché senzory vám snad pomohly pochopit, jak v MicroPythonu fungují analogové a digitální vstupy na ESP32.
Pokud vás dnešní hraní se senzory bavilo, tak to je teprve začátek. ESP32 toho umí mnohem víc – Wi-Fi, Bluetooth, I²C, SPI, OLED displeje, teplotní čidla… a to vše bychom zde chtěli postupně prozkoumat.
Takže až se příště budete chtít ponořit do světa chytré domácnosti, bezkontaktního ovládání, nebo třeba měření teploty vašeho kaktusu, mrkněte na další články z naší série o ESP32 s MicroPythonem.
- Jak říkáme u nás na FyzKABu:
- „Každý pin dobrý – a každý byte paměti se počítá!“ 😉
Asi by se příště slušelo, podívat se na to minule slíbené Wi-Fi, že?