Close

Arduino základy – 5. Read Analog Voltage

Schéma pro použití sériového monitoru ke čtení analogových pinů

Tento příklad vám předvede, jak číst analogový vstup pinu A0, převést hodnoty z analogRead() na napětí a poslat je na sériový monitor.

Potřebný hardware

  • Arduino
  • Proměnný rezistor, tj. potenciometr

Obvod

AnalogReadSerial_BB

Arduino s potenciometrem

Jeden z vnějších pinů potenciometru připojíme ke GND, druhý krajní pin připojíme k +5V. Prostřední pin potenciometru připojíme k analogovému vstupu A0.
Odpor mezi krajními a prostředním pinem můžeme měnit otáčením osy potenciometru. Tím změníte také napětí na středním pinu. Jakmile je odpor mezi středem a stranou připojenou k 5 voltům blízko nule (a odpor na druhé straně je blízko 10 kΩ), napětí u středního pinu se blíží 5 voltům. Když potenciometr otočíme na druhou stranu, odpory se obrátí, napětí u středního pinu je blízko 0V. Pomocí potenciometru tedy můžeme generovat spojité analogové napětí mezi 0 a 5V.

Arduino obsahuje tzv. analog-to-digital converter, který toto měnící se napětí čte a převádí na čísla mezi 0 a 1023 (je tedy desetibitový – rozlišuje 210 možných hodnot). Když je osa zcela otočena jedním směrem, tak je na střením pinu napětí 0V a hodnota měřená na vstupu je 0. Je-li naopak osa otočena druhým směrem, napětí na pinu je 5V a naměřená hodnota je 1023. Pokud se pohybujeme někde mezi, funkce analogRead() nám vrací číslo mezi 0 a 1023, které odpovídá poměrné hodnotě napětí na pinu.

Schéma

AnalogReadSerial_sch

Schéma zapojení potenciometru

Kód

Jako obvykle na začátku programu zahájíme sériovou komunikaci s rychlostí 9600 baud.

Serial.begin(9600);

Ve funkci loop vytvoříme proměnnou obsahující naměřenou hodnotu napětí přicházející od vašeho potenciometru:

int sensorValue = analogRead(A0);

Pro přepočet hodnot naměřených funkcí analogRead() na skutečné hodnoty požijeme jednoduchý vzorec. Jelikož naměřené hodnoty mohou být mezi 0 a 1023 a víme, že maximální napětí je 5V, provedeme přepočet tak, že 5V vydělíme 1023. Tak zjistíme, kolika voltům odpovídá jedna jednotka funkce analogRead(). Tuto hodnotu vynásobíme naměřenou hodnotou a tím získáme skutečné napětí naměřené na analogovém vstupu. Výsledek uložíme do proměnné datového typu float (může to totiž být i desetinné číslo).

float voltage= sensorValue * (5.0 / 1023.0);

Vypočtenou hodnotu pošleme po sériové lince do PC pomocí funkce Serial.printIn().

Serial.println(voltage);

Celý program tedy vypadá takto:

/*
    ReadAnalogVoltage
    Čte analogový vstup A0, hodnotu převádí na napětí a výsledek posílá po sériovém portu.
*/

//Jakmile zmáčknete reset, spustí se funkce setup:
void setup() {
    // inicializujte sériovou komunikaci na 9600 bitech za sekundu:
    Serial.begin(9600);
}

// proces smyčky se teď neustále opakuje:
void loop() {
    // přečte vstup A0:
    int sensorValue = analogRead(A0);
    // Převede analogový vstup (od 0 do 1023) na napětí (0 - 5V):
    float voltage = sensorValue * (5.0 / 1023.0);
    // Odešle přečtenou hodnotu:
    Serial.println(voltage);
}

Přeloženo z https://arduino.cc/en/Tutorial/HomePage a mírně upraveno.

Kamila Ježková

21 Comments on “Arduino základy – 5. Read Analog Voltage

Jan Jenyk los Fialas
5.5.2022 at 9:55

Rozjel jsem na tomto arduinu roblox na 50 fps

wecko
25.4.2018 at 12:20

Dobrý den,
je možné měřit tímto způsobem vyšší napětí než 5V? Potřeboval bych měřit napětí na autobaterii a v případě podpětí chci „nějak“ (přes stykač?) odpojit baterii. Bude to pak pokračovat dál odesláním infa o odpojení baterie. Atd. například spuštění nabájení, ale to už jsou další kroky. V prvním kroku musím napětí nějak změřit 🙂

Děkuji moc
David

Oldřich Horáček
11.6.2018 at 14:49

Zdravím,
pokud je měřené napětí vyšší než 5V, tak ho můžete lehce snížit zapojením přes dělič napětí.
Z důvodu bezpečnosti se vyplatí ještě napětí na měřícím pinu omezit například Zenerovou diodou nebo transilem, aby nedošlo ke zničení procesoru.

Otakar
22.4.2017 at 0:24

Dobrý den.
Prosím – jak je možné, že v tomto zapojení je napětí na všech analog vstupech (u mě Arduino Mega)? Myslím tím po přidání analogRead (A1 až x) se mi vyskytuje napětí shodné s A0 ? Pokud přidám tedy příkaz u nezapojeného pinu A1 ař Ax, po jeho přečtení a zobrazení, je totožná hodnota se zapojeným pinem A0

Zbyšek Voda
23.4.2017 at 11:59

Dobrý den, řekl bych, že to bude souviset s tím, že analogové piny u Arduina sdílí jeden převodník z analogových na digitální hodnoty (ADC).
Tento převodník je postupně připojovaný k pinům pomocí multiplexoru.

Na vstupu ADC je kondenzátor (tzv. hold), který je přes připojený pin A0 nabitý na určitou hodnotu. Pak provádíte měření na dalších pinech, které ale nejsou nikam připojeny, takže kondenzátor nemůže být nabitý ani vybitý, takže měříte všude stejné hodnoty.

Aspoň takto si to vysvětluji 🙂
Když připojíte třeba na A1 další potenciometr, řekl bych, že ostatní piny budou mít hodnotu A1 (respektive naposledy měřeného pinu přes analogRead, ke kterému je něco připojeno).

hrc
1.3.2019 at 22:17

Viz. koment p. Vody, naprosto vyčerpávající. Také záleží na tom, zda jsou porty definovány.
Je slušností a také doporučeným postupem nevyužité piny procesoru (a nejen procesoru, obecně IC) uzemnit.

Triste
18.8.2016 at 13:24

Hezký den, chtěl jsem se zeptat, jak jednoduše při měření analogových veličin vytvořit časovou osu? Chtěl bych třeba číst a ukládat analogové hodnoty po 1/100 s. Díky za námět.

Zbyšek Voda
18.8.2016 at 14:19

Dobrý den. Zkuste trochu více specifikovat otázku 🙂
Pokud vám stačí zobrazovat veličiny v reálném čase, dejte si do kódu mezi měření delay(10) a posílejte si hodnoty přes sériovou linku. Na straně PC je můžete pomocí Serial Plotteru zobrazit. Nebo také dále zpracovávat jiným programem.

Pokud potřebujete hodnoty ukládat přímo na straně Arduina, doporučuji nějaký SD shield a pomocí delay(10) ukládat do souboru. Navíc můžete přidat modul reálného času a mít přehled o aktuálním čase měření.

Triste
18.8.2016 at 21:06

Děkuji za odpověď, chtěl bych změřit jednokanálové datovou sérii v čase. Tedy jako třeba zvukové karty nebo měřící karty, jen asi pomaleji, cca 1/100 a6 1/1000 s a pak samozřejmě uložit na SD kartu. Nevím jaké je zpoždění u této instrukce. A nevím, jak rychlý je přenos přes I2C sběrnici (moduly reálného času) .

Zbyšek Voda
19.8.2016 at 10:04

O časech zápisu, čtení… nemám přehled. Napadají mě ale 3 cesty.

Nejjednodušší je použít delay(1) (pro 1/1000s), nebo delay(10) mezi jednotlivými čteními a zápisy. Tam ale nemáte zaručeno přesné časování. V některých případech to ale nemusí vadit a stačí měřit přibližně.

Druhou možnosti je použít vnitřní přerušení na základě časovače – viz http://www.instructables.com/id/Arduino-Timer-Interrupts/. To je o něco přesnější.

Třetí možnosti, co mě napadá, je použít nějaký vnější hardware, který vám bude každých 1/100, nebo 1/1000s na pin s přerušením posílat pulz. Vy na základě pulzu na pinu obsloužíte přerušení tím, že změříte hodnotu a uložíte ji na kartu. Viz https://www.arduino.cc/en/Reference/AttachInterrupt.

Triste
20.8.2016 at 9:04

Díky moc za rady, vyzkouším všechny varianty, nad externím časováním jsem také přemýšlel. Protože to možnost vnitřní ho časování jsem nikde nenašel.

Marcela
25.8.2016 at 20:52

Dobrý večer, syn dostal téma Bc práce Dálkové měření elektrické energie pomocí systému arduino. Prosím o radu, kde najít nějaké materiály k tomuto tématu? Moc děkuji. Marcela

Zbyšek Voda
26.8.2016 at 9:22

Dobrý den, zkuste téma prosím trochu specifikovat. Předpokládám, že není zadání takhle o jedné větě.
Má se jednat o nějaký modul, který bude měřit něco v el. skříni a odesílat někam data bezdrátově?

Marcela
28.8.2016 at 19:00

Dobrý večer, syn dostal téma Bc práce Dálkové měření elektrické energie pomocí systému arduino. Prosím o radu, kde najít nějaké materiály k tomuto tématu? Moc děkuji. Marcela ano, má to měřit el. Napětí v zásuvkách a přenášet přes arduino do pc, ale nevím, kde k tomu najít materiály.

Má to měřit napětí a přes arduino přenášet do tabulky v pc.
Osnovu Bc práce má
1. technologická analýza jevů
2. Měření daného jevu
3. Popis technologií dálkového měření
4. Návrh dálkového měření
5. Realizace dálkového měření
6.pilotni provoz a hodnocení

Můžete mi zslat prosím i nějaké materiály na můj email. předem moc děkuji.

Zbyšek Voda
28.8.2016 at 20:24

Dobrý den, musím udělat to samé, co by měl udělat váš syn – začít hledat.
Začneme tím, jak měřit napětí v zásuvce: http://goo.gl/26qr2N
Potom bude potřeba nějak vyřešit bezdrátový přenos: http://goo.gl/2MzBLE
a nakonec hodnoty zalogovat do tabulky: http://goo.gl/keTzz7.

Má už syn nějakou představu o technickém řešení? Třeba bychom se potom mohli posunout dále.

Triste
15.2.2016 at 13:44

Dotaz: zajímalo by mě, jakou vzorkovací frekvenci je při měřeních analogových veličin možné dosáhnout? Kolik vzorků za vteřinu? Nikdo nezmiňuje tento údaj. Děkuji za odpověď.

Zbyšek Voda
15.2.2016 at 15:39

Dobrý den,
na stránkách Arduino.cc (https://www.arduino.cc/en/Reference/AnalogRead) píší
„It takes about 100 microseconds (0.0001 s) to read an analog input, so the maximum reading rate is about 10,000 times a second.“,
takže vzorkovací frekvence je asi 10 kHz

Honza
16.5.2015 at 19:22

Dobrý den. Určitě je možné volat analogové vstupy dynamicky (vybírat si konkrétní vstup až za běhu programu). Ale jak, když se jmenují A0 – A… ? Jejich jméno (adresa) je int nebo char? Je mi jasné, že by to šlo ošidit cyklem, ale to mi příjde jako drbání pravou rukou za levým uchem 😀

Díky za odpověď

Zbyšek Voda
16.5.2015 at 21:57

Dobrý den,

A0 až Ax jsou konstanty, kterým je přiřazena nějaká hodnota. Jména proměnných ani konstant nejde volat jako string/char. Jaká hodnota je přiřazena jakému pinu na jaké desce to se můžete dočíst v umístění:

hardware/arduino/avr/variants/typ_desky/pins_arduino.h

pro desky jako UNO a podobné v souboru ‚hardware/arduino/avr/variants/standard/pins_arduino.h‘ naleznete:
static const uint8_t A0 = 14;
static const uint8_t A1 = 15;
static const uint8_t A2 = 16;
static const uint8_t A3 = 17;
static const uint8_t A4 = 18;
static const uint8_t A5 = 19;
static const uint8_t A6 = 20;
static const uint8_t A7 = 21;

pro mega je to:
static const uint8_t A0 = 54;
static const uint8_t A1 = 55;
static const uint8_t A2 = 56;
static const uint8_t A3 = 57;
static const uint8_t A4 = 58;
static const uint8_t A5 = 59;
static const uint8_t A6 = 60;
static const uint8_t A7 = 61;
static const uint8_t A8 = 62;
static const uint8_t A9 = 63;
static const uint8_t A10 = 64;
static const uint8_t A11 = 65;
static const uint8_t A12 = 66;
static const uint8_t A13 = 67;
static const uint8_t A14 = 68;
static const uint8_t A15 = 69;

Poté stačí volat analogRead(69) a je to to samé, jako kdybyste volal analogRead(A15).

Jirka
30.12.2014 at 19:02

supr návod díky,
ale všude píšete 1023, nemá být náhodou 1024?

Zbyšek Voda
30.12.2014 at 21:07

Dobrý večer Jirko.

1023 je opravdu správně. Převodník většiny desek Arduino je desetibitový. To znamená, že může rozlišit celkem 2^10 různých hodnot. Výstupem tedy mohou být čísla mezi 0 a 1023 (celkem 1024 možností).

Napsat komentář