Kurz Arduino – #4 – ADC převodník

V předchozích částech kurzu jsme se zabývali čtením digitálních signálů. Mohli jsme například zkontrolovat, zda bylo stisknuto tlačítko. Svět kolem nás však není digitální, někdy 2 stavy (1/0) nestačí.

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

Elektroniku lze rozdělit na digitální a analogovou. U digitální technologie může určitý vstup nebo výstup nabýt pouze jednoho ze dvou stavů. Vysoký (1) nebo nízký (0). V praxi to znamená, že Arduino na svém vstupu rozpozná 0 V nebo 5 V (zjednodušeně řečeno).

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!

Ke zpracování analogového signálu se používá takzvaný ADC (analogově-digitální převodník). Jedná se o jedno z nejoblíbenějších periferních zařízení v mikrokontrolérech. Jeho úkolem je vzorkovat napětí přivedené na vstup systému a převádět je do digitální podoby.

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
				
			
V tomto případě je zobrazen 8bitový převodník, protože načítaná hodnota může mít 256 kombinací (počínaje 0). Ve skutečnosti existují různé převodníky, např. 12bitové nebo 16bitové. Převodník, který má více bitů, by měl být přesnější, protože jeho maximální hodnota je vyšší (pracuje ve stejném rozsahu, ale s vyšším rozlišením).

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
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 MasterRobotics 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í.

Programování ADC je jednoduché a omezuje se na použití funkce analogRead(ADC channel), ve které nahradíme vybraný pin (A0-A5) kanálem ADC.

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ů 
}
				
			
Při otáčení potenciometrem získáme na monitoru hodnoty od 0 do 1023. To znamená, že ADC v Arduino UNO má 10 bitů.

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

Tento úkol je jednoduchý a spočívá pouze v odpovídajícím převodu načtené hodnoty. Víme, že vstupní napětí kolísá mezi 0 a 5 V a z ADC dostaneme 1024 hodnot (počítáme od 0 do 1023). To znamená:

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:

  1. Připojte záporný pól (GND) akumulátoru kabelem k zásuvce.
  2. Připojte kabel od pinu A5 ke kladnému pólu baterie.
  3. 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.

Jednoduchý voltmetr na Arduino.

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í:

Úkol je jednoduchý, jednoduše vydělíme maximální hodnotu, kterou můžeme odečíst z ADC, tj. 1023, číslem 5 a použijeme ji k vytvoření spínacích podmínek jednotlivých diod. K tomu však můžeme použít také velmi pohodlnou funkci map().

Jejich použití v praxi vypadá takto:
				
					skalovanaHodnota = map(ausgelesenerWert, 0, 1023, 1, 5);
				
			
Tuto funkci lze použít k rychlému škálování určité hodnoty. První argument je zadán jako hodnota, která má být škálována. V našem případě se jedná o informace z ADC. Druhý a třetí parametr představují rozsah vstupní hodnoty, zatímco poslední dva parametry představují rozsah výstupní hodnoty (po škálování).

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

Pokud máte štěstí (hodně okolního hluku), můžete provést velkolepý experiment. Použijte obvod s 5 diodami, který jste zapojili dříve. Odpojte kabel vedoucí k potenciometru a nechte jej viset ve vzduchu.

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ě

Je čas použít nový prvek a vytvořit něco, co má praktické využití. V tomto cvičení použijeme fotorezistor, prvek, jehož odpor se mění s dopadajícím světlem (čím více jej osvětlujeme, tím je odpor menší).

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č.
Pokud na fotorezistor dopadá velké množství světla, je jeho odpor minimální a napětí v bodě připojeném k Arduinu je relativně „vysoké“. Když je světlo vypnuté, odpor fotorezistoru se zvýší a napětí na děliči je nízké.

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);
}
				
			
Jak vidíte, existuje podmínka, která je zodpovědná za zapnutí nebo vypnutí diody. Otázkou je, jak tuto přepínací hodnotu zvolit? Nejlépe manuální…

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

Tentokrát je úkol zřejmý. Stejně jako dříve chceme vytvořit světlo, které se rozsvítí ve tmě. Měla by však mnohem snadněji nastavit. Máte nějaké nápady, jak toho dosáhnout?

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?

  1. Umístěte přístroj do světla, ve kterém má být dioda vypnuta.
  2. Otočte potenciometr do polohy, ve které je dioda vypnutá.
  3. 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

Použijte dva fotorezistory jako samostatné děliče napětí. Umístěte je na nejvzdálenější strany kontaktní desky. V ideálním případě by měly být dokonce mírně nakloněny směrem ven. Zobrazení hodnot obou senzorů v terminálu. Co se stane, když před deskou plošných spojů mávnete rukou (vrhnete stín) nebo ji osvětlíte baterkou?

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í

V této části kurzu Arduino jsem popsal podle mého názoru jedno z nejzajímavějších periferních zařízení, ADC. Analogové převodníky se velmi často používají při čtení informací z prostředí. Je důležité si uvědomit, že ADC nejsou k dispozici pouze na Arduinu, takže praktické znalosti z této části budou vždy aktuální.

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 >>

Přejít nahoru