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.