7. diel - Arduino - Vzdialenosť s ultrasonickým modulom HC-SR04
V minulom tutoriále o Arduino sme zapájali LCD displej. Tentoraz si konečne zmeriame vzdialenosť pomocou ultrasonického modulu HC-SR04.. Modul funguje tak, že vysiela zvukové signály, ktoré sa odrazí, modul je zaznamená a my zmeriame počet uplynulých milisekúnd. Pomocou vzorca a rýchlosti zvuku vo vzduchu vypočítame vzdialenosť. Predtým sa používala funkcia pulsein, ktorá merala počet milisekúnd, ale teraz už existuje NewPing Library,, ktorá to všetko vyrieši za nás a vráti nám hodnotu v centimetroch (ale na konci článku to vyriešime i postarom). Takže jej stiahneme a importuje do Arduino, ako sme sa už naučili vo 4. diele.. K zobrazovanie vzdialenosti použijeme LCD display z minulého dielu,, takže kód zostane zachovaný, len ho mierne pozmeníme - odoberieme DHT11 a pridáme HC-SR04.
Schéma bude vyzerať nejako takto.
Zapojíme všetko podľa nasledujúceho schému a rovno sa presunieme k písania kódu. Najskôr s knižnicou NewPing:
#include <NewPing.h> //naimportování knihovny NewPing #include <LiquidCrystal.h> int rs_pin = 2; int e_pin = 3; int d4_pin = 4; int d5_pin = 5; int d6_pin = 6; int d7_pin = 7; LiquidCrystal LCD(rs_pin, e_pin, d4_pin, d5_pin, d6_pin, d7_pin); //nám již známé nastavení LCD int trig_pin = 52; //HC-SR04 má dva datové piny - Trigger int echo_pin = 50; //a Echo int max_vzdalenost = 500; //náš modul umí měřit do 500cm. //Pro případ, že by byla vzdálenost větší, se měření ukončí, aby nedocházelo k problémům NewPing metr(trig_pin, echo_pin, max_vzdalenost); //newping vytvoří nový objekt, u nás s názvem metr. Jako parametry jsou trigpin, echopin a max vzdálenost float vzdalenost; // vzdálenost si vložíme do další proměnné void setup() { LCD.begin(16,2); LCD.setCursor(0,0); LCD.print("itnetwork.cz"); //známé spuštění LCD } void loop() { vzdalenost = metr.ping_cm(); //do proměnné vzdalenost uložíme výsledek funkce ping_cm, která za nás změří vzdálenost LCD.setCursor(0,1); LCD.print(" "); //Promazání předchozí hodnoty. Pokud bychom ze 103 cm přešli na 98, zůstane zde ta trojka //a display by napsal 983 cm LCD.setCursor(0,1); LCD.print(vzdalenost + 1); //vypíšeme vzdálenost //jedna přičteme proto, že čidlo je zhruba 1cm vysoké a když jej třeba přiložíme na stěnu, //abychom změřili vzdálenost protější, tak by byla hodnota o jeden cm menší //toto ovšem není nutné LCD.setCursor(12,1); LCD.print("cm"); //už jenom napíšeme "cm" delay(500); //a chvilku počkáme }
Takto to vyzerá s použitím knižnice NewPing. Je to oveľa jednoduchšie, ale nezobrazujú sa desatinné miesta. Tento kód má vďaka knižnici ošetrené aj veľké vzdialenosti, takže keď bude vzdialenosť až moc veľká, nemal by nám vypisovať nezmyselné hodnoty
A prečo to robiť jednoducho, keď to ide zložito, že? Bez knižnice NewPing to ide tiež, len budeme musieť počítať, posielať impulzy na piny a čakať až sa vráti:
#include <LiquidCrystal.h> int rs_pin = 2; int e_pin = 3; int d4_pin = 4; int d5_pin = 5; int d6_pin = 6; int d7_pin = 7; LiquidCrystal LCD(rs_pin, e_pin, d4_pin, d5_pin, d6_pin, d7_pin); //nám již známé nastavení LCD int trig_pin = 52; //HC-SR04 má dva datové piny - Trigger int echo_pin = 50; //a Echo float doba; //do této proměnné uložíme dobu, za kterou se zvuk vrátí float vzdalenost; // vzdálenost si vložíme do další proměnné void setup() { LCD.begin(16,2); LCD.setCursor(0,0); LCD.print("itnetwork.cz"); //známé spuštění LCD pinMode(echo_pin, INPUT); //tentokrát budeme potřebovat pinMode(trig_pin, OUTPUT); //vstupní a výstupní piny } void loop() { digitalWrite(trig_pin, LOW); delayMicroseconds(2); digitalWrite(trig_pin, HIGH); delayMicroseconds(10); digitalWrite(trig_pin, LOW); // Před měřením je třeba na trigpin vyslat několik impulsů //protože to probíhá rychle, máme zde delayMicroseconds, //která pozastaví program na mikrosekundy doba = pulseIn(echo_pin, HIGH); //punkce pulsein nám vrátí čas, za který se vrátí impuls vzdalenost = (doba / 2) / 29.1; //protože signál jde tam a zase zpátky, tak jej musíme vydělit dvěma //poté ještě vezmeme úvahu rychlost zvuku a máme výsledek //do proměnné vzdalenost uložíme výsledek funkce ping_cm, která za nás změří vzdálenost LCD.setCursor(0,1); LCD.print(" "); //Promazání předchozí hodnoty. Pokud bychom ze 103 cm přešli na 98, zůstane zde ta trojka //a display by napsal 983 cm LCD.setCursor(0,1); LCD.print(vzdalenost + 1); //vypíšeme vzdálenost //jedna odečteme proto, že čidlo je zhruba 1cm vysoké a když jej třeba přiložíme na stěnu, //abychom změřili vzdálenost protější, tak by byla hodnota o jeden cm menší LCD.setCursor(12,1); LCD.print("cm"); delay(500); //a chvilku počkáme }
Takto to vyzerá bez knižnice. Musíme posielať impulzy na piny a potom prepočítavať hodnotu. Naviac má tento spôsob tendenciu "skákať" s hodnotami, čím ďalej, tým viac. U 10 cm skáču len desatinné miesta, ale u 80 cm už skáču aj jednotky, niekedy aj viac ako o dve.
Toto meranie je samozrejme len orientačná. Ak by sme chceli presné hodnoty, budeme musieť presne zmerať výšku snímača (senzory sú zhruba v polovici), vziať do úvahy teplotu a vlhkosť, napríklad pomocou DHT11 a ďalšie faktory. To by ale bolo zložité, takže nám to bude stačiť takto.
O funkčnosti sa môžete presvedčiť v nasledujúcom videu:
Na stiahnutie sú opäť k dispozícii okomentované zdrojové kódy od oboch možností.Od budúceho dielu už začnem seriál smerovať k môjmu projektu, na ktorom momentálne robím, aby som už mohol napísať o praktickom stavanie väčších projektov. Pozreli by sme sa na to, ako s Arduino spínať väčšej záťaže než maximum pre pin, teda viac ako 20 mA.