Proto se nyní podíváme na analogově-digitální převodník, zkráceně ADC.
Objednejte si sadu prvků a začněte se učit v praxi! Kliknutím sem přejdete do obchodu >>
Krátký teoretický úvod
Bohužel ne všechny věci ve světě kolem nás lze popsat takto jednoduše. Když připojíme snímač vzdálenosti, chceme znát přesnou vzdálenost k překážce, a ne jen informace typu: překážka je vidět, překážka není vidět.
Takový senzor by mohl vysílat napětí úměrné vzdálenosti. Měření by pak spočívalo ve snímání napětí, např. v rozsahu 0-5 V. Jedná se o analogový přístup. Proto v následujících příkladech použijeme vhodné periferie Arduino, které nám umožní měřit napětí přivedené na konkrétní vstupy obvodu.
Pozor!
Než přejdeme k testování, nezapomeňte, že na vstupy Arduina UNO můžete připojit pouze napětí v rozsahu 0-5 V. Jiné hodnoty napětí mohou poškodit desku plošných spojů a dokonce i počítač, ke kterému čip připojíte!
Například pro lineární převodník:
Napětí => Přečtená hodnota z ADC
[V] (zaokrouhlená)
0 => 0
1 => 51
2 => 102
3 => 154
4 => 205
5 => 255
Zajímavé je, že analogově-digitální převodníky pracují relativně pomalu. V našich programech si toho samozřejmě nevšimneme, ale pokud ADC porovnáme s ostatními periferiemi mikrokontroléru, nefunguje tak dobře.
Měření pomocí ADC trvá 0,0001 s,
tj. lze provést maximálně 10 000 měření za sekundu!
Za druhé, výroba těchto měničů je nákladná. Jak si pamatujete z druhé lekce o Arduino UNO, máme k dispozici 6 analogových vstupů (A0-A5). Ve skutečnosti je v mikrokontroléru pouze jeden ADC, ke kterému je připojen multiplexor. To umožňuje měřit napětí na 6 kanálech.
Tímto končíme teoretický úvod. Nyní můžeme přejít k prvnímu programu.
Hotové sady pro kurzy Forbot
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
ADC v praxi
Je čas zjistit, jak bude ADC fungovat v praxi. Za tímto účelem nastavte obvod podle obrázku níže. Potenciometr zde vystupuje v roli děliče napětí.
Nemáme jinou možnost než použít náš první jednoduchý program. Zpočátku se omezíme na odeslání načtené hodnoty do počítače. Samozřejmě používáme UART, o kterém jsme se dozvěděli v předchozí části kurzu.
int nactenaHodnota = 0;
void setup() {
Serial.begin(9600);//Spuštění komunikace přes UART
}
void loop() {
nactenaHodnota = analogRead(A5);//Přečteme hodnotu napětí
Serial.println(nactenaHodnota);//Odesíláme ji do terminálu
delay(200);//Čekáme na pohodlnější přečtení výsledků
}
Jsou pro nás takové suché hodnoty užitečné? To je těžké říct. Bylo by lepší číst výsledek ve srozumitelných jednotkách. Například ve voltech, že?
Jednoduchý voltmetr
1024 => 5V 1 => x
1024x = 1*5
x = (1*5V)/1024 = ~0,0049V
Zjednodušeně řečeno: Každé zvýšení vstupního napětí o ~0,0049 V zvýší zobrazení ADC o jedničku. To znamená, že k získání výsledku ve voltech stačí přidat pouze jeden řádek:
int nactenaHodnota = 0;//Načtení hodnoty z ADC
float Spannung = 0;//Hodnota převedená na napětí ve V
void setup() {
Serial.begin(9600);//Spuštění komunikace přes UART
}
void loop() {
nactenaHodnota = analogRead(A5);//Načteme hodnotu napětí
Spannung = nactenaHodnota * (5.0/1024.0); //Přepočet hodnoty na napětí
Serial.println(Spannung);//Odesíláme naměřené napětí
delay(200);//Čekáme na pohodlnější přečtení výsledků
}
Všimněte si, že proměnná voltage byla deklarována jako typ float, tj. jako typ, který umožňuje ukládat čísla s pohyblivou řádovou čárkou.
Čísla, která jsou ve výše uvedeném kódu dělena sama sebou, jsou zapsána s poznámkou „.0„; to je informace pro překladač, aby s nimi zacházel jako s čísly s pohyblivou řádovou čárkou. Jinak by výsledkem takové operace bylo celé číslo!
Od této chvíle by se na obrazovce počítače měla zobrazovat hodnota 0-5 V. Právě jsme tedy sestrojili velmi jednoduchý, ale funkční voltmetr. Lze jej také použít k měření napětí místo potenciometru, například na baterii? Ano, ale pouze pokud jste velmi opatrní.
Nezapomeňte, že připojením napětí vyššího než 5 V dojde k nevratnému poškození Arduino! Proto se ani nepokoušejte připojit 9V baterii, která je součástí sady, k našemu voltmetru.
Pokud však někde najdete obyčejnou baterii AA s napětím 1,5 V (např. v dálkových ovladačích televizorů), můžete s ní trochu experimentovat:
- Připojte záporný pól (GND) akumulátoru kabelem k zásuvce.
- Připojte kabel od pinu A5 ke kladnému pólu baterie.
- Přečtěte si napětí na počítači.
V mém případě bylo napětí s novou baterií něco málo přes 1,6 V, takže vše bylo v normě. Takže je to třeba brát pouze jako experiment.
Vidíte již praktické využití měření ADC (kromě voltmetru)? Pokud ne, podívejte se na následující cvičení.
Řízení provozu programu pomocí ADC
Dřívější program měl pouze demonstrovat, jak převodník funguje. Nyní můžeme pomocí potenciometru připojeného k obvodu ovlivňovat chod programu. Za tímto účelem přidáme k Arduino jednu LED diodu.
Hodnoty převodníku se pohybují mezi 0 a 1023, což je poměrně málo. Co se stane, když použijeme odečítané číslo jako hodnotu zpoždění v programu? Nejrychlejší cestou je sestrojit zařízení, které bliká LED diodou s frekvencí řízenou potenciometrem:
int nactenaHodnota = 0; //Proměnná pro ukládání hodnot ADC
void setup() {
pinMode(2, OUTPUT); //Konfigurace výstupů pod LED
}
void loop() {
nactenaHodnota = analogRead(A5);//Načtení hodnot z ADC
digitalWrite(2, HIGH);//Zapnutí diody
delay(nactenaHodnota);//Závislost čekací doby na ADC
digitalWrite(2, LOW);//Vypnutí diody
delay(nactenaHodnota);//Závislost čekací doby na ADC
}
Domácí úkol 4.1
Sledujte, co se stane v jedné z koncových poloh potenciometru. Co si myslíte, že je toho příčinou?
Zobrazení na diodách
Je čas na trochu složitější projekt. Tentokrát budeme spínat příslušnou diodu v závislosti na poloze posuvníku potenciometru. Za prvé, všechny komponenty musí být vzájemně propojeny. Moje navrhované spojení je následující:
Jejich použití v praxi vypadá takto:
skalovanaHodnota = map(ausgelesenerWert, 0, 1023, 1, 5);
Výsledkem výše uvedeného řádku kódu je vždy hodnota v rozsahu 1-5. V praxi lze tento postup použít takto:
int nactenaHodnota = 0;
void setup() {
pinMode(8, OUTPUT); //Konfigurace výstupů pro LED diody
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
pinMode(12, OUTPUT);
}
void loop() {
nactenaHodnota = analogRead(A5);//Načtení hodnot z ADC
nactenaHodnota = map(nactenaHodnota, 0, 1023, 1, 5);//Škálování hodnot
if (nactenaHodnota == 1) { //První rozsah
digitalWrite(8, HIGH);
digitalWrite(9, LOW);
digitalWrite(10, LOW);
digitalWrite(11, LOW);
digitalWrite(12, LOW);
} else if (nactenaHodnota == 2) { //Druhý rozsah
digitalWrite(8, LOW);
digitalWrite(9, HIGH);
digitalWrite(10, LOW);
digitalWrite(11, LOW);
digitalWrite(12, LOW);
} else if (nactenaHodnota == 3) { //Třetí rozsah
digitalWrite(8, LOW);
digitalWrite(9, LOW);
digitalWrite(10, HIGH);
digitalWrite(11, LOW);
digitalWrite(12, LOW);
} else if (nactenaHodnota == 4) { //Čtvrtý rozsah
digitalWrite(8, LOW);
digitalWrite(9, LOW);
digitalWrite(10, LOW);
digitalWrite(11, HIGH);
digitalWrite(12, LOW);
} else { //Zbývající, neboli pátý rozsah
digitalWrite(8, LOW);
digitalWrite(9, LOW);
digitalWrite(10, LOW);
digitalWrite(11, LOW);
digitalWrite(12, HIGH);
}
delay(50); //Zpoždění, aby nebylo čtení ADC příliš rychlé
}
Uvědomuji si, že zkušení vývojáři si při pohledu na výše uvedené podmínky budou drbat hlavu. Ale vše máme pod kontrolou. Brzy se podíváme na konstrukci switch/case, která takové dlouhé podmínky usnadní.
Zkontrolujte, co se děje s jednotlivými LED diodami při otáčení potenciometrem. Pokud je vše správně zapojeno, měla by se při každém zapnutí regulátoru rozsvítit jiná dioda.
V jedné z koncových poloh potenciometru je vidět, že se diody chovají podivně. Pak je nejlepší změnit maximální hodnotu ADC, která je nastavena ve funkci map(), metodou pokus-omyl.
V mém případě se obvod choval správně již při změně z 1023 na 1021.
Domácí úkol 4.2
Co se stane, když přiblížíte ruku ke kabelu (aniž byste se dotkli jeho konce)? Nevíte, proč tomu tak je? V mém případě, když drát visel ve vzduchu, se rozsvítily 3 LED diody, ale stačilo přiblížit ruku na 2 cm od drátu a rozsvítily se všechny LED diody. Nevíte, proč tomu tak je?
Pokud tento efekt není ve vašem případě tak výrazný, můžete na konec kabelu připevnit „anténu“, např. z hliníkové fólie.
Tato zkušenost by vám měla zůstat v paměti jako důkaz, že nesmíte nechat žádný vstup obvodu „viset“ ve vzduchu. Podívejte se, jaké problémy to může způsobit!
Světlo aktivované ve tmě
Pomocí fotorezistoru můžeme sestavit dělič napětí, který závisí na množství světla v prostředí. Nastavte obvod podle následujícího obrázku. Fotorezistor by měl spolu s rezistorem 1k tvořit dělič.
Pomocí takového obvodu můžeme sestrojit světlo, které se rozsvítí, když se setmí. Kód je velmi jednoduchý (jako vždy):
int nactenaHodnota = 0; //Proměnná pro ukládání hodnot ADC
void setup() {
pinMode(8, OUTPUT); //Konfigurace výstupů pod LED
}
void loop() {
nactenaHodnota = analogRead(A5);//Načtení hodnot z ADC
if (nactenaHodnota < 100) {
digitalWrite(8, HIGH);//Zapnutí diody
} else {
digitalWrite(8, LOW);//Vypnutí diody
}
delay(50);
}
V mém případě jsem nejprve nastavil hodnotu 500 a pak ji postupně snižoval, dokud se dioda nezapnula ve správný okamžik (když jsem zakryl snímač rukou).
Místo modré diody nyní stačí připojit několik silnějších bílých diod (přes tranzistor) a máte funkční světlo, které ví, kdy se má rozsvítit. Ale co když ji přeneseme do jiné místnosti, kde jsou trochu jiné podmínky? Musíme pak Arduino znovu několikrát programovat, abychom zvolili správnou prahovou hodnotu? Ano, pokud…
Světlo aktivované ve tmě v2
Použil jsem potenciometr připojený k jinému analogovému vstupu (A4):
Místo toho, aby sepnutí diody záviselo na pevné mezní hodnotě, můžeme nyní nastavit práh sepnutí plynule pomocí potenciometru. Změna programu je velmi jednoduchá a omezuje se na úpravu 3 řádků kódu:
int nactenaHodnota = 0; //Proměnná pro ukládání hodnot ADC
int prog = 0; //Práh zapnutí světla - nastavitelný potenciometrem
void setup() {
pinMode(8, OUTPUT); //Konfigurace výstupů pod LED
}
void loop() {
nactenaHodnota = analogRead(A5);//Čtení hodnot z ADC
prog = analogRead(A4);//Načtení hodnot z ADC
if (Proměnná pro ukládání hodnot ADC < prog) { //Je tmavší než nastavený práh?
digitalWrite(8, HIGH);//Zapnutí diody
} else {
digitalWrite(8, LOW);//Vypnutí diody
}
delay(50);
}
Jak nejrychleji vyladit systém?
- Umístěte přístroj do světla, ve kterém má být dioda vypnuta.
- Otočte potenciometr do polohy, ve které je dioda vypnutá.
- Podařilo se!
Od této chvíle by mělo naše příkladové světlo zapnout minimální stmívání fotorezistoru!
ADC se používá velmi snadno, takže je čas udělat domácí úkoly na vlastní pěst. Nezapomeňte si dobře osvojit všechny lekce. Postupem času budeme v programech používat mnoho funkcí. Na návrat k základům už nezbývá mnoho času!
Domácí úkol 4.4
Rozšiřte program inteligentního osvětlení tak, aby při sepnutí diody odeslal do počítače napětí na děliči (jednou).
Domácí úkol 4.5
Zkuste si naprogramovat jednoduchou hru. Po spuštění programu otočte potenciometrem do libovolné polohy a stiskněte tlačítko . Arduino by pak mělo na počítači zobrazit zprávu:
Zadejte číslo:
Pokud se číslo odeslané do Arduino shoduje s hodnotou ADC o +/- 50, hráč vyhrál. Pokud ne, rozsvítí se žlutá kontrolka a hráč má další dva pokusy. Při každém zadání nesprávného čísla se na kontaktní desce rozsvítí červená kontrolka LED. Pokud však hráč vyhraje, rozsvítí se zelená kontrolka. Tip: Pro tento úkol potřebujete novou funkci, která ještě nebyla v kurzu použita – podívejte se sami do dokumentace, co funkce toInt dělá, a zamyslete se, jak vám může pomoci s tímto domácím úkolem. Nápomocný vám může být také tento příklad.
Domácí úkol 4.6
Můžete na základě analýzy rozdílu mezi hodnotami obou senzorů napsat program, který určí, na které straně desky je silnější zdroj světla? Zkuste určit směr pomocí 5 diod (více vlevo, uprostřed, více vpravo atd.)!
Shrnutí
Je třeba poznamenat, že kompletní sada komponentů potřebných pro všechna cvičení je k dispozici u společnosti Botland. Zakoupením sad podpoříte budoucí vydání kurzu Forbot!
Objednejte si sadu prvků a začněte se učit v praxi! Kliknutím sem přejdete do obchodu >>