Lekce 13 - Arduino - Měření vzdálenosti ultrasonickým modulem HC-SR04
V předchozí lekci, Arduino - Senzory a programování pohybového senzoru PIR, jsme si představili různé druhy senzorů a ukázali si praktický příklad použití pohybového senzoru PIR.
Dnes si v HW Arduino tutoriálu ukážeme, jak je možné měřit vzdálenost. Povíme si základní informace o ultrazvukovém senzoru pro měření vzdálenosti, konkrétně o modelu HC-SR04. Řekneme si, na jakém principu senzor funguje, ukážeme si schéma zapojení a nakonec si vytvoříme obslužný program. Propojíme v něm naše znalosti z lekce LCD displej a jeho programování a vypíšeme si hodnoty ze senzoru na LCD displej.
Ultrazvukový senzor HC-SR04
Model HC-SR04 je ultrazvukový senzor, který se používá k měření vzdálenosti pomocí ultrazvuku. Senzor funguje tak, že vysílá ultrazvukové vlny a měří dobu, která uplyne, než se vlny odrazí od předmětu a vrátí se zpět. Tato doba se použije k výpočtu vzdálenosti předmětu od senzoru.
Senzor HC-SR04 je malý a cenově dostupný, což ho činí oblíbeným pro mnoho projektů s mikrokontroléry a roboty. Má čtyři piny: VCC, TRIGGER, ECHO a GND. GND pin popisovat nemusíme. Pin VCC je napájecí pin a obvykle se napájí napětím 5V. Pin TRIGGER se použije k vyslání ultrazvukového impulsu a pin ECHO se použije k přijetí odraženého impulsu. Senzor může měřit vzdálenost v rozmezí od 2 cm do 400 cm s přesností až do 3 mm.
HC-SR04 je oblíbený pro svoji jednoduchost a cenovou dostupnost, ale má také několik omezení. Například ultrazvukové vlny se odrazí od tvrdých povrchů, ale neodrazí se od měkkých povrchů, takže senzor nemusí fungovat dobře v prostředí s mnoha měkkými předměty. Navíc je senzor citlivý na teplotní změny a může být ovlivněn silným zvukem nebo elektromagnetickými vlnami. Princip fungování lze vidět na tomto obrázku:

Schéma zapojení
K zapojení budeme potřebovat následující součástky:
- Arduino,
- nepájivé pole,
- propojovací kabely,
- ultrazvukový senzor a
- LCD displej.
Máme-li dostupné všechny součástky, znamená to, že se můžeme vrhnout na zapojení. To bude vypadat následovně:

Zapojíme vše podle následujícího schéma a rovnou se přesuneme k psaní kódu.
Naprogramování senzoru
Máme-li zapojeno podle schématu, znamená to, že se můžeme pustit do programování.
Přidání knihovny, konstant a proměnných
Ukažme si a popišme první část kódu:
// Knihovna pro používání LCD displeje s I2C sběrnicí #include <Adafruit_LiquidCrystal.h> Adafruit_LiquidCrystal LCD(0); // Definování pinu echo #define PIN_ECHO 2 // Definování pinu trig #define PIN_TRIG 3 // Proměnná pro ukládání vzdálenosti unsigned long vzdalenost;
Jako první si přidáme knihovnu pro práci s LCD displejem, příkaz
#include <Adafruit_LiquidCrystal.h> známe již z odkazované
lekce o práci s LCD displejem. Stejně tak víme, že příkazem
Adafruit_LiquidCrystal LCD(0) vytvoříme instanci LCD displeje a
že číslo v parametru udává adresu displeje. Použili jsme hodnotu
0, protože pracujeme ve vývojovém prostředí Tinkercad a naše
adresa LCD displeje je virtuální.
Víme též, že při práci na reálném projektu mívá
obvykle adresa reálného LCD displeje hodnotu 0x27.
Posuneme-li se v kódu, tak se dostaneme k našemu ultrazvukovému čidlu.
Pomocí klíčového slova #define si definujeme jednotlivé piny
čidla. V našem případě máme ECHO pin v Arduinu na pinu 2 a TRIGGER pin na
pinu 3.
Nakonec jsme si vytvořili proměnnou typu unsigned long, kterou
jsme nazvali vzdalenost. Do této proměnné uložíme výpočet
vzdálenosti, který spočítáme ve funkci.
Inicializace komponent
Nyní se pojďme podívat do naší funkce setup():
void setup() { pinMode(PIN_TRIG, OUTPUT); pinMode(PIN_ECHO, INPUT); Serial.begin(9600); LCD.begin(16, 2); LCD.setCursor(0, 0); LCD.setBacklight(1); LCD.print("itnetwork.cz"); }
Zde si nastavíme pinMode() pro náš ultrazvukový senzor,
konkrétněji náš TRIGGER nastavíme na OUTPUT, protože se
jedná o vysílač a pro ECHO zvolíme roli INPUT, protože se
jedná o přijímač. Jako další si pomocí příkazu
Serial.begin(9600) nastavíme Baudovou rychlost pro sériový
monitor, kam pro jistotu naměřené údaje vypíšeme také.
Poté nás čeká nastavování LCD displeje, kde uvedeme velikost, polohu kurzoru a následně jej rozsvítíme a necháme na něj vypsat "itnetwork.cz". Jedná se o příkazy, které již známe, tudíž je nemusíme dále vysvětlovat.
Funkce loop()
Další část kódu se nachází ve funkci loop(). Jako první
v ní ukládáme do naší proměnné vzdalenost výsledek z
pomocné funkce vypocet_vzdalenost(), kterou do projektu vzápětí
doplníme. Poté pouze konkrétní hodnoty ze senzoru vypisujeme do sériového
monitoru a na LCD displej. Tyto hodnoty se aktualizují s každou proběhlou
smyčkou:
void loop() { // Volání funkce pro výpočet vzdálenosti vzdalenost = vypocet_vzdalenost(PIN_TRIG, PIN_ECHO); // Výpis vzdálenosti na sériový monitor Serial.print("Vzdalenost: "); Serial.print(vzdalenost); Serial.println(" cm"); // Výpis vzdálenosti na LCD displej LCD.setCursor(0, 1); LCD.print("Namereno: "); LCD.print(vzdalenost); LCD.println(" cm "); }
U LCD displeje jsme limitováni počtem znaků na řádku. Mezera za připojenou jednotkou pro centimetry je zde schválně, aby se na displeji přepsal celý řádek i v případě, že naměříme nižší hodnoty.
Pomocná funkce pro výpočet
Doplňme poslední část, slíbenou pomocnou funkci:
// Funkce pro výpočet vzdálenosti unsigned long vypocet_vzdalenost(int trig, int echo) { // Proměnné pro využívání při výpočtu vzdálenosti unsigned long vzdalenost_cidlo, cas_cidlo; // Vyšle ultrazvukové vlny pomocí TRIG pinu digitalWrite(trig, HIGH); delay(5); digitalWrite(trig, LOW); cas_cidlo = pulseIn(echo, HIGH); // Převedení času na dálku vzdalenost_cidlo = (cas_cidlo / 2) / 29.1; // Návratová hodnota funkce pro vypočítání vzdálenosti return vzdalenost_cidlo; }
Funkce vrací hodnotu unsigned long a v parametrech bere dvě
int hodnoty pro TRIGGER a ECHO. Nejdříve deklarujeme proměnné
potřebné pro výpočet. Poté na 5 ms vyšleme signál z TRIGGERU. Dále
uvidíme pro nás novou funkci pulseIn(). Je to funkce z knihovny
Arduino, která se používá k měření doby trvání pulsu na určitém pinu.
Je užitečná pro měření vzdálenosti pomocí ultrazvuku, detekci kódů IR
vysílačů a další aplikace, které zahrnují detekci a měření pulzů.
Funkce pulseIn() přijímá dva argumenty. První je pin, na
kterém má být impuls čten, druhý je stav, který se má hledat. Může to
být buď HIGH, nebo LOW. Funkce
pulseIn() vrátí dobu trvání pulsu v mikrosekundách. Získanou
hodnotu vydělíme dvěma, protože signál jde tam a zase zpátky. Poté
ještě vezmeme v úvahu rychlost zvuku a máme výsledek. Pomocí příkazu
return vypočítanou hodnotu nastavíme jako návratovou.
Projekt je nyní hotový, můžeme jej spustit a vyzkoušet přesnost ultrazvukového měření.
V příští lekci, Arduino - Měření vzdálenosti infračerveným senzorem VL53L0X, si představíme senzor VL53L0X, kterým měříme vzdálenost pomocí infračervených paprsků a porovnáme si tento způsob měření s ultrasonickým modulem.
