Kurz Arduino – #9 – HC-SR04 Distanční senzor, funkce

V této části kurzu Arduino budeme používat senzor vzdálenosti HC-SR04, který je mezi kutily velmi oblíbený.

Je také čas začít psát vlastní funkce. Nakonec se budeme zabývat také velmi jednoduchým akustickým prvkem – bzučákem.

Objednejte si sadu prvků a začněte se učit v praxi! Kliknutím sem přejdete do obchodu >>

Doufám, že tato sekce bude zajímat konstruktéry robotů a všechny, kteří by rádi ve svých projektech použili senzor vzdálenosti, jako je ten, který je uveden níže.

Ještě předtím se však naučíme nové programátorské triky, díky kterým budou naše programy ještě lepší – jak pro Arduino, tak pro osobu zodpovědnou za vytvoření programu, tedy pro vás!

Hotové sady pro kurzy Forbot
Sada prvků   Zaručená podpora   Odeslání do 24 hodin

U našich prodejců si nyní můžete zakoupit sadu více než 70 elementů potřebných pro cvičení v kurzu!

Populární sada: Arduino Master – Robotics Master

Vlastní funkce bez argumentů

Dosud jsme náš kód vkládali do funkcí setup() {} nebo loop() {}. První funkce sloužila k nastavení a druhá byla nekonečná hlavní smyčka, která běžela neustále. Například, aby LED dioda připojená na pin 13 blikala, museli jsme napsat program takto:

Nezapomeňte, že v Arduinu je trvale nainstalována dioda, která je připojena na pin 13!

				
					void setup() {
  pinMode(13, OUTPUT); //Konfigurace pinu 13 jako výstupu
}

void loop() {
  digitalWrite(13, HIGH); //Zapnutí diody
  delay(1000); //Čekání 1 sekundu
  digitalWrite(13, LOW); //Vypnutí diody
  delay(1000); //Čekání 1 sekundu
}
				
			

Představte si situaci, kdy je náš program velmi složitý a my chceme pomocí blikání potvrdit vybrané operace. Rychle se ukáže, že opakované duplikování části zodpovědné za zapínání a vypínání LED diody je pro programátora časově náročné. Ještě horší je, že to také ztěžuje analýzu celého programu.

Pokud deklarujeme proměnnou, můžeme se na ni jednoduchým způsobem několikrát odvolat. Kdybychom mohli ukládat celé řetězce operací pod jednoduchým názvem, byly by programy mnohem přehlednější. Případné změny by byly také jednodušší. Zde mohou pomoci funkce.

Při programování Arduino používáme mnoho hotových funkcí, např.: digitalWrite(13, HIGH);. Víme, že tento příkaz nastaví na pinu 13 vysoký stav (logickou 1), ale nepotřebujeme vědět, jak je realizován. Analogicky můžeme vytvořit vlastní funkce. Podívejme se například na výše zmíněný blesk.

Za tento proces je zodpovědný následující úryvek kódu:

				
					digitalWrite(13, HIGH); //Zapnutí diody
delay(1000); //Čekání 1 sekundu
digitalWrite(13, LOW); //Vypnutí diody
delay(1000); //Čekání 1 sekundu
				
			

Můžeme ji vyjmout z funkce loop() {} a vytvořit z ní samostatnou funkci. Jak to uděláme?

Nejprve musíme deklarovat název funkce a její typ. Provedeme to například takto: pod funkcí loop() {}:

				
					void setup() {
  pinMode(13, OUTPUT); //Konfigurace pinu 13 jako výstupu
}

void loop() {
}

void blikaciLED() {
  //Obsah funkcí
}
				
			

Jak vidíte, před názvem funkce je uveden typ funkce, což je v tomto případě flashingLED. Není to nic jiného než údaj o tom, zda funkce po dokončení vrací hodnotu. Pokud by tomu tak bylo, musel by se tam zadat odpovídající typ (odpovídající typům proměnných). Může to být například: Celé číslo (int), znak (char), necelé číslo (float) atd.

V tomto případě se tam objevuje slovo void. (Tento typ znamená, že funkce nevrací žádnou hodnotu. Proč jsem si vybral tento typ? Funkce má za úkol vyvolat záblesk diody; tento proces nevede k žádnému výsledku (kromě toho, který je viditelný našima očima).

Pokud funkce nevrátí výsledek,
pak před něj vložte slovo prázdný!

(Další případy jsou popsány níže v tomto článku)

Za názvem funkce se zobrazí kulatá závorka. Prozatím předpokládáme, že uvnitř této závorky nic není. Poté otevřeme kulaté závorky a vložíme do nich kód, který se má po zavolání funkce provést. V praxi:

				
					void setup() {
  pinMode(13, OUTPUT); //Konfigurace pinu 13 jako výstupu
}

void loop() {
  blikaciLED();
}

void blikaciLED() {
  digitalWrite(13, HIGH); //Zapnutí diody
  delay(500); //Čekání 0,5 sekundy
  digitalWrite(13, LOW); //Vypnutí diody
  delay(500); //Čekání 0,5 sekundy
}
				
			

Všimněte si, že jsme do smyčky loop() {} zadali název naší proměnné (již bez předpony void). Taková akce se nazývá volání funkce. Nahrajte program a zkontrolujte, zda funguje tak, jak ukazuje animace níže:

Poznámka:
Názvy funkcí by měly vysvětlovat, co funkce dělá, a musí být jednoznačné! Například se nesmí překrývat s názvy proměnných.

Vraťme se k dříve předpokládané situaci, kdy používáte blikání na mnoha velmi různých místech programu (pro potvrzení operace). Co kdybyste náhle chtěli změnit pořadí světel nebo například počet blikajících signálů? Pak byste museli změnit stejný kód na desítkách míst. Pokud použijete vlastní funkci, je to poměrně jednoduché, stačí jen něco změnit na tomto jediném místě:

Domácí úkol 9.1

				
					//Rychlejší blikání
void blikaciLED() {
  digitalWrite(13, HIGH); //Zapnutí diody
  delay(200); //Čekání 0,2 sekundy
  digitalWrite(13, LOW); //Vypnutí diody
  delay(200); //Čekání 0,2 sekundy
}
				
			

Napište funkci, která pulzuje diodu (postupné stmívání a rozjasňování). Samozřejmě využijte znalosti, které jste získali v lekci o PWM signálech.

Arduino - vlastní funkce s argumenty

Je čas odhalit další funkční tajemství. Vzpomínáte si na jednu z nejčastěji volaných funkcí Arduino? Pravděpodobně jde například o změnu stavu konkrétního pinu:

				
					digitalWrite(13, HIGH);
				
			

Na rozdíl od naší funkce blikaciLED(); zde zadáváme některé údaje v kulatých závorkách. Může to být číslo pinu, požadovaný stav nebo naplnění signálu PWM. Tyto informace jsou později použity v rámci funkce k provádění určitých operací.

Jedná se o argumenty, které se předávají funkci.

Věnujte pozornost použité slovní zásobě, argumenty i transfer nejsou použity náhodně. Tyto termíny používají všichni programátoři! Nyní je čas napsat vlastní funkci, která začíná jediným argumentem.

Předpokládejme, že chceme upravit naši funkci blinkenLED tak, aby bylo možné změnit rychlost blikání při jejím volání. Do deklarace funkce musíme přidat informaci, že může přijímat argument. To provedeme v hlavičce funkce:

				
					//Původní verze
void blikaciLED(){

//Nová verze
void blikaciLED(int čas){
				
			

Od této chvíle překladač ví, že při volání funkce v kulatých závorkách očekává číslo (typ int). Toto číslo se předá funkci a objeví se v ní pod názvem Time.

Bude to proměnná, která je viditelná pouze v rámci naší funkce, tj. bude to tzv. lokální proměnná.

V praxi bude vnitřek funkce vypadat takto:

				
					void blikaciLED(int čas){
  digitalWrite(13, HIGH); //Zapnutí diody
  delay(čas); //Čekání nějakou dobu
  digitalWrite(13, LOW); //Vypnutí diody
  delay(čas); //Čekání nějakou dobu
}
				
			

Je čas na poslední prvek, tj. volání nové funkce. Pravděpodobně zde nebude nic překvapivého. Jednoduše zadáme číslo v závorce, které určuje dobu, po kterou se má LED dioda zapínat a vypínat. Celý kód vypadá takto:

				
					void setup() {
  pinMode(13, OUTPUT); //Konfigurace pinu 13 jako výstupu
}

void loop() {
  blikaciLED(50);
}

void blikaciLED(int čas){
  digitalWrite(13, HIGH); //Zapnutí diody
  delay(Zeit); //Čekání určitou dobu
  digitalWrite(13, LOW); //Vypnutí diody
  delay(čas); //Čekání určitou dobu
}
				
			

Zkontrolujte, zda můžete ovlivnit frekvenci blikání nahrazením hodnoty v závorce. Je čas na další příklad.

Funkce s jedním argumentem - Příklad 2

Až dosud bylo vidět neustálé blikání LED diody, protože jsme naši funkci volali ve funkci loop, což je smyčka. Pokud přesuneme volání funkce do sekce Setup, zobrazí se pouze blikání při spuštění systému. Zkontrolujte:

				
					void setup() {
  pinMode(13, OUTPUT); //Konfigurace pinu 13 jako výstupu
  blikaciLED(50);
}

void loop() {

}

void blikaciLED(int čas){
  digitalWrite(13, HIGH); //Zapnutí diody
  delay(čas); //Čekání určitou dobu
  digitalWrite(13, LOW); //Vypnutí diody
  delay(čas); //Čekání určitou dobu
}
				
			

Přesně tak by to fungovalo, kdybychom chtěli funkci použít například k potvrzení stisku klávesy. Volání funkce blikaciLED() způsobí, že LED dioda jednou blikne.

Je čas na revizi funkce, abyste mohli ovlivnit nejen dobu blikání, ale také počet blikajících signálů. Za tímto účelem musíme nejprve změnit deklaraci funkce:

				
					//Původní verze
void blikaciLED(int čas){

//Upravená verze
void blikaciLED(int čas, int kolik){
				
			

Přidali jsme argument kolik, bude zodpovědný za počet záblesků. Jak vidíte, byl zadán za čárkou, samozřejmě s typem („integer“, int) před ním. Tento parametr může být i jiného typu, na tom nezáleží. Důležité je pouze to, aby prohlášení bylo správné.

Funkce může přijímat několik argumentů různých typů!

Jak si asi dokážete představit, použití druhého argumentu je velmi jednoduché. Nyní máme jednoduše druhou lokální proměnnou kolik je k dispozici.

Doufám, že už víte, která smyčka je nejjednodušší způsob, jak kontrolovat počet blikajících signálů? Pokud ne, odkazuji vás na předchozí část, kde jsem se zabýval smyčkami for. Předpokládám však, že jste tento materiál zvládli (nebo jej právě doháníte), a představuji vám novou funkci blikaciLED:

				
					void blikaciLED(int kolik, int čas){
  for (int i=0; i < kolik; i++) {
    digitalWrite(13, HIGH); //Zapnutí diody
    delay(čas); //Čekání určitou dobu
    digitalWrite(13, LOW); //Vypnutí diody
    delay(čas); //Čekání určitou dobu
  }
}
				
			

Zkontrolujme celý kód:

				
					void setup() {
  pinMode(13, OUTPUT); //Konfigurace pinu 8 jako výstupu
  blikaciLED(100, 5);
}

void loop() {
}

void blikaciLED(int čas, int kolik){
  for (int i=0; i < kolik; i++) {
    digitalWrite(13, HIGH); //Zapnutí diody
    delay(čas); //Čekání určitou dobu
    digitalWrite(13, LOW); //Vypnutí diody
    delay(čas); //Čekání určitou dobu
  }
}
				
			

Vše by mělo fungovat. Po spuštění musí dioda bliknout přesně pětkrát. Jak ale Arduino umí rozlišit mezi informacemi v závorkách, časem a počtem opakování?

Princip je jednoduchý: po sobě jdoucí hodnoty oddělené čárkami jsou přiřazeny po sobě jdoucím argumentům popsaným v deklaraci funkce. Ve výše uvedeném případě se první číslo vždy považuje za čas a druhé za počet opakování.

Domácí úkol 9.2

Napište funkci, která umožňuje samostatně nastavit počet bliknutí, dobu, po kterou je LED dioda vypnutá, a dobu, po kterou je LED dioda rozsvícená.

Lze naši funkci ještě více rozšířit? Ano, samozřejmě! Nebylo by praktické, kdybyste kromě času a počtu opakování mohli zadat také pin, ke kterému je dioda připojena?

Funkce s argumenty - příklad č. 3

Vývod, ke kterému je dioda připojena, je v našem programu číslo. Používáme je na dvou místech, když deklarujeme konkrétní pin jako výstup a když nastavujeme vysoký nebo nízký stav. To znamená, že číslo může být dalším argumentem naší funkce!

Nejprve připojíme druhou diodu na jiný pin, např: č. 8:

Připojení diody k Arduino.

Nebudu zde zacházet do dalších podrobností, ale rovnou uvedu celý příklad:

				
					void setup() {
  pinMode(13, OUTPUT); //Konfigurace pinu 13 jako výstupu
  blikaciLED(100, 5, 13);
  blikaciLED(150, 4, 8);
}

void loop() {
}

void blikaciLED(int čas, int kolik, int pin){
  for (int i=0; i < kolik; i++) {
    digitalWrite(pin, HIGH); //Zapnutí diody
    delay(Zeit); //Čekání nějaký čas
    digitalWrite(pin, LOW); //Vyonutí diody
    delay(Zeit); //Čekání nějaký čas
  }
}
				
			

Uvidíme, jestli to bude fungovat. Není to moc, že? Bliká pouze dioda připojená na pin 13 a dioda pod pinem 8 nechce dát žádnou známku života. A proč? Udělali jsme velmi jednoduchou chybu, které se při psaní takových funkcí snadno dopustíme. Nikde jsme neuvedli, že ostatní piny (kromě 13) výstupy mohou být. Viz část nastavení:

				
					void setup() {
  pinMode(13, OUTPUT); //Konfigurace pinu 13 jako výstupu
  blikaciLED(100, 5, 13);
  blikaciLED(150, 4, 8);
}
				
			

To můžeme poměrně snadno napravit přesunutím konfigurace pinů do naší funkce. To by vypadalo následovně:

				
					void setup() {
  blikaciLED(100, 5, 13);
  blikaciLED(150, 4, 8);
}

void loop() {
}

void blikaciLED(int čas, int kolik, int pin){
  pinMode(pin, OUTPUT); //Konfigurace jako výstup

  for (int i=0; i < kolik; i++) {
    digitalWrite(pin, HIGH); //Zapnutí diody
    delay(čas); //Čekání nějaký čas
    digitalWrite(pin, LOW); //Vypnutí diody
    delay(čas); //Čekání nějaký čas
  }
}
				
			

Nyní vše funguje, ale musím přiznat, že to není elegantní řešení. Proto bych je nedoporučoval používat v profesionálnějších projektech. V hobby sektoru by se však nemělo stát nic špatného a my si můžeme takovou jednoduchou funkcí usnadnit život.

Než přejdeme k senzoru vzdálenosti, je čas na poslední informaci o funkcích.

Funkce, které vracejí výsledek

Dosud jsme používali pouze funkce, které provádějí určité operace, ale nemusí vracet výsledek. Úkolem nové funkce bude… vypočítat plochu čtverce o určité straně a vrátit výsledek (vypočtenou plochu). Funkci je třeba nejprve deklarovat, tentokrát hlavička vypadá takto:

				
					int ctverecPole(int a) {
				
			

Jak vidíte, kromě argumentu (strana čtverce) je před funkcí int, což znamená, že funkce vrací výsledek ve tvaru čísla.ísla. V tomto případě se samozřejmě jedná o vypočtenou plochu.

Vnitřek funkce by měl vypadat takto:

				
					int ctverecPole(int a) {
  int výsledek = 0;
  výsledek = a * a;
  
  return výsledek;
}
				
			

Zdůraznil jsem zde hranici slovem return. Poté nastavíme hodnotu (proměnnou), která je vrácena jako výsledek této funkce. To znamená, že pro argument 4 bychom měli jako výsledek funkce dostat 16, protože 4*4 = 16. Asi vás zajímá, co znamená, že funkce vrací výsledek. Kam se tato hodnota dostane?

Podívejme se na následující příklad:

				
					void setup() {
  Serial.begin(9600);
}

void loop() {
  int výsledek = ctverecPole(4);
  Serial.println(výsledek); //Zobrazit zprávu
  delay(500);
}

int ctverecPole(int a) {
  int výsledek = 0;
  výsledek = a * a;
  
  return výsledek;
}
				
			

Proveďte příklad. Monitor sériového portu by měl zobrazit výsledek operace, tj. 16. Skutečnost, že funkce vrací výsledek, znamená, že výsledek bude po provedení „nahrazen“ v místě volání. V tomto případě je SquareArea(4); nahrazena hodnotou 16, která je zapsána do proměnné result.

Deklarace samostatné proměnné však není nutná. Následující zápis funguje stejně dobře (ale je o něco méně čitelný):

				
					//Stará verze
int výsledek = ctverecPole(4);
Serial.println(Ergebnis); //Meldung anzeigen

//Nová verze
Serial.println(ctverecPole(4)); //Zobrazit zprávu
				
			

K úplnosti chybí jen to, aby se strana čtverce dala poslat z počítače do Arduino. Zde použijeme zprávy z části kurzu věnované komunikaci přes UART. Program bude následující:

				
					String prijataData = ""; //Prázdný řetězec přijatých dat

void setup() {
  Serial.begin(9600);
}

void loop() {
   if(Serial.available() > 0) { //Přijalo Arduino data
    prijataData = Serial.readStringUntil('\n'); //Pokud ano, přečtěte je až po znak konce řádku a uložte je do proměnné prijataData
    int výsledek = ctverecPole(prijataData.toInt());
    Serial.println(výsledek); //Zobrazit zprávu
  }
}

int ctverecPole(int a) {
  int výsledek = 0;
  výsledek = a * a;
  
  return výsledek;
}
				
			

Zápis receiveData.toInt() je však nový. Jak si možná pamatujete, při komunikaci přes UART jsou všechny znaky odesílány jako kódy ASCII. Proto jsme během testů nemohli do Arduino jednoduše posílat čísla.
To však lze velmi snadno změnit. Stačí k načtenému řetězci připojit .toInt(). Tím se číslo zaslané jako text převede na číslo typu int.

Změna typu jedné proměnné na jinou se nazývá modifikace.

Domácí úkol 9.1

Napište funkce pro výpočet ploch obdélníku, kruhu a trojúhelníku. Odesílejte výsledky do počítače přes UART!

Ultrazvukový senzor vzdálenosti HC-SR04

Nastal čas popsat senzor vzdálenosti, na který mnoho lidí čekalo. Senzor HC-SR04 se skládá z ultrazvukového vysílače a přijímače a několika integrovaných obvodů. Díky těmto obvodům můžeme poměrně přesně určit vzdálenost senzoru od překážky poslechem akustického signálu (který je pro člověka neslyšitelný). Stejně jako … Netopýři:

Netopýr foto: Wikipedie.

Ale vraťme se k Arduino a senzoru vzdálenosti. Nejprve se zaměříme na jeho čtyři signální piny. Dva z nich jsou určeny pro napájení čipu (Vcc, GND) a další dva (trigger a echo) pro měření.

Trigger je vstup spouštěče. Pokud je na něj přiveden vysoký stav (po dobu alespoň 10 mikrosekund), začne se měřit vzdálenost. Výstup echo naproti tomu zobrazuje naměřenou vzdálenost. Výrobce udává maximální dosah tohoto nenápadného obvodu 4 metry.

Zadní strana senzoru
Přední strana senzoru

Je čas na první jednoduchý příklad, jak lze senzor využít v praxi.

Dálkoměr

Připojte vytvořený obvod, který v pravidelných intervalech měří vzdálenost a zobrazuje ji na obrazovce počítače. K tomu je třeba sestavit obvod podle níže uvedeného schématu:

Popis kabelů najdete na senzoru, ale pro přehlednost jsem ho zde uvedl. Při pohledu shora (jako na obrázku výše) a zleva:

  1. Vcc – 5V
  2. Trig
  3. Echo
  4. Gnd

Níže je fotografie sestaveného obvodu.

Připojení senzoru HC-SR04 k počítači Arduino.

V našem případě připojíme vstup trigonometru na pin 12 a echo na pin 11. Aby nedošlo k záměně, doporučuji rovnou provést odpovídající definice:

				
					#define trigPin 12
#define echoPin 11
				
			

Víceméně víte, jak spustit měření vzdálenosti. Je na čase zapsat jej jako program:

				
					#define trigPin 12
#define echoPin 11

void setup() {
  Serial.begin (9600);
  pinMode(trigPin, OUTPUT); //Pin, ke kterému připojíme trig jako výstup
  pinMode(echoPin, INPUT); //a echo jako vstup
}

void loop() {
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  //Měření provedené
}
				
			

Všimněte si nové funkce delayMicroseconds();, která není ničím jiným než ekvivalentem známé funkce delay();. Rozdíl je pravděpodobně zřejmý. Nová funkce odpočítává čas v mikrosekundách. Chtěl bych jen připomenout, že dosud používaná funkce zpoždění měří milisekundy.

Sekvence, kterou měření začíná, je velmi jednoduchá. Nejprve přivedeme nízký signál na pin, který je připojen ke spouštěcímu vstupu senzoru. Stačí 2 mikrosekundy, pak nastavíme vysoký stav na 10 mikrosekund. Snímač provede měření a vrátí výsledky do vývodu echo.

Otázkou je, jak ji lze vyčíst. Je k tomu zapotřebí UART nebo jiné komunikační rozhraní? Ne, naštěstí je tento snímač velmi jednoduchý a měřená vzdálenost je reprezentována impulsem (vysoký stav) na echo pinu. Jeho délka je úměrná vzdálenosti. Čím delší je, tím větší je naměřená vzdálenost. Zde se používá nová funkce Arduino.

Měření doby trvání pulzu v Arduino

Naštěstí je v Arduino implementována velmi jednoduchá funkce, která dokáže měřit délku trvání impulzu na libovolném vstupu. Jeho délka musí být v rozmezí 10 mikrosekund až 3 minuty. Měření se spustí, jakmile je na některém pinu detekována změna stavu.

Design je velmi jednoduchý:

				
					int výledek = 0;
výledek = pulseIn(11, HIGH);
				
			

V nejjednodušší podobě vyžaduje funkce pouze dva argumenty. Číslo testovaného pinu a měřená logická úroveň (nízká/vysoká).

To znamená, že pro změření vzdálenosti musíme provést následující operaci:

				
					#define trigPin 12
#define echoPin 11

void setup() {
  Serial.begin (9600);
  pinMode(trigPin, OUTPUT); //Pin, ke kterému připojíme trig jako výstup
  pinMode(echoPin, INPUT); //a echo jako vstup
}

void loop() {
  long čas;

  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  Zeit = pulseIn(echoPin, HIGH);
  Serial.print(čas);
  
  delay(500);
}
				
			

Při spuštění takového programu se na obrazovce zobrazí čísla. Čím blíže umístíme překážku ke snímači, tím je menší. Jsou však na rozdíl od jednotek, které používáme my, velmi vzdálené. Aby bylo měření čitelné pro člověka, musíme výsledek vydělit „magickým číslem“.

Níže se podívejte, jak program funguje – výsledek by se nyní měl zobrazovat v centimetrech:

				
					#define trigPin 12
#define echoPin 11

void setup() {
  Serial.begin (9600);
  pinMode(trigPin, OUTPUT); //Pin, ke kterému připojíme trig jako výstup
  pinMode(echoPin, INPUT); //a echo jako vstup
}

void loop() {
  long čas, distance;

  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  čas = pulseIn(echoPin, HIGH);
  distance = čas / 58;
  
  Serial.print(distance);
  Serial.println(" cm");
  
  delay(500);
}
				
			

Hodnota, kterou dělíme (58), samozřejmě není „magická“. Vyplývá z doby, za kterou zvuk urazí vzdálenost 1 cm, a ze vzorce vzdálenosti stanoveného výrobcem.

V tuto chvíli není nutné se tím zabývat.
V případě potřeby vám téma podrobně popíšu.

Funkce vracející vzdálenost senzoru v cm

Jak vidíte, část programu, pomocí které můžete provádět měření, je poměrně dlouhá. Bylo by velmi praktické, kdybychom měli funkci, která by toto všechno dělala. Napíšeme ji. Nemusíte čekat, předložím vám hotový fragment, protože je to jen kopie výše uvedeného kódu:

				
					int zmeritVzdalenost() {
  long čas, distance;

  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  čas = pulseIn(echoPin, HIGH);
  distance = čas / 58;

  return distance;
}
				
			

Nyní stačí funkci vyvolat na příslušném místě programu:

				
					#define trigPin 12
#define echoPin 11

void setup() {
  Serial.begin (9600);
  pinMode(trigPin, OUTPUT); //Pin, ke kterému připojíme trig jako výstup
  pinMode(echoPin, INPUT); //a echo jako vstup
}

void loop() {  
  Serial.print(zmeritVzdalenost());
  Serial.println(" cm");
  
  delay(500);
} 

int zmeritVzdalenost() {
  long čas, distance ;

  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  čas = pulseIn(echoPin, HIGH);
  distance  = čas / 58;

  return distance ;
}
				
			

To je mnohem jasnější, že?

Kontrola vzdálenosti

Je čas na poslední cvičení v této části kurzu Arduino. Tentokrát chceme do našeho obvodu instalovat bzučák, součástku, která generuje zvuk. Vypadá to takto:

Bzučák s nálepkou
Bzučák bez nálepky

Tato komponenta má dva vstupy. Pokud je na jeden vstup přivedeno napětí Vcc a druhý je připojen k zemi,… Bzučák vydá hlasitý zvuk. Není to příliš příjemné, proto doporučuji nechat nálepku nalepenou (zvuk se tím ztiší). Jak je snadno patrné ze štítku, tato nálepka chrání vnitřek bzučáku při mytí desek plošných spojů. To se provádí hlavně za účelem odstranění pájecích spojů.

Bzučák je polární součástka!
Všimněte si, že jedna z nohou je delší a je na krytu,
najdete vedle něj symbol plus.

Bzučák připojíme k Arduino podle následujícího obrázku.

Instalační schéma - bzučák a Arduino.

Symbol, který jsem použil pro nakreslení schématu, se mírně liší od vzhledu bzučáku, proto si můžete mé schéma zkontrolovat také pomocí fotografie:

Bzučák dodávaný se sadami Forbot je dimenzován tak, aby jej bylo možné připojit k Arduino bez odporu. Pokud používáte bzučák, zkontrolujte, kolik odebírá proudu!

Tentokrát napíšeme funkci, která zkontroluje, zda je objekt v určité vzdálenosti od senzoru. V takovém případě se spustí alarm („bzučák“).

Funkce, která zjišťuje vzdálenost, používá předchozí funkci MeasureDistance(),

				
					void rozsah(int a, int b) {
  int jakoDaleko = zmeritVzdalenost();
  if ((jakoDaleko > a) && (jakoDaleko < b)) {
      digitalWrite(2, HIGH); //Aktivace bzučáku
  } else {
      digitalWrite(2, LOW); //Vypnutí bzučáku, když je objekt mimo dosah.
  }
}
				
			

Jako argumenty funkce zadáme dvě celá čísla. Poté zkontrolujeme, zda naměřená vzdálenost větší než počáteční hodnota našeho intervalu (a) a menší než maximální hodnota (b) je.

Mimochodem, můžete si všimnout, že pomocí symbolů && spojujeme několik podmínek do jedné.

Celý program je následující:

				
					#define trigPin 12
#define echoPin 11

void setup() {
  Serial.begin (9600);
  pinMode(trigPin, OUTPUT); //Pin, ke kterému připojíme trig jako výstup
  pinMode(echoPin, INPUT); //a echo jako vstup
  pinMode(2, OUTPUT); //Vstup pro bzučák
}

void loop() {  
  rozsah(10, 25); //Zapní alarm, pokud se ve vzdálenosti 10 až 25 cm od snímače nachází překážka.  
  delay(100);
} 

int zmeritVzdalenost() {
  long čas, distance
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  čas = pulseIn(echoPin, HIGH);
  distance = čas / 58;

  return distance;
}

void rozsah(int a, int b) {
  int jakoDaleko = zmeritVzdalenost();
  if ((jakoDaleko > a) && (jak < b)) {
      digitalWrite(2, HIGH); //Aktivace bzučáku
  } else {
      digitalWrite(2, LOW); //Vypnutí bzučáku, když je objekt mimo dosah.
  }
}
				
			

Podívejte se, jak program funguje v praxi. Podle mého názoru je to ideální základ pro vytvoření jednoduchého poplašného centra, které bude hlídat vaše drahocenné poklady!

Domácí úkol 9.3

Napište program, který zobrazí vzdálenost překážky od senzoru na pravítku z LED diod. Čím blíže je překážka k senzoru, tím více diod LED by se mělo rozsvítit. Příklad pravítka lze sestavit takto:

Zahájení konstrukce pravítka LED.

Domácí úkol 9.4

Zkontrolujte, jak se mění údaj snímače v závislosti na materiálu překážky. Vidíte rozdíly v zobrazení vzdálenosti, když je snímač namířen například na tvrdé nebo měkké objekty? Porovnejte překážky, jako je zeď, strop nebo list papíru.

Shrnutí kurzu Arduino!

Nevím, jak se mi to povedlo, ale právě jste se naučili vše, co se probírá v kurzu Arduino pro začátečníky! Doufám, že jste získali užitečné zkušenosti. Pokud budete mít zájem, slibuji, že přidám další díl a budu pokračovat v práci na kurzu pro pokročilé (dalších 9 nových dílů).

Objednejte si sadu prvků a začněte se učit v praxi! Kliknutím sem přejdete do obchodu >>

Přejít nahoru