RP2350-Zero/ADC
ADC
ADC (Analog-to-Digital Converter) prevádza analógové napätie (spojitá hodnota, napr. 0–3,3 V) na digitálne číslo, s ktorým už vie program ďalej pracovať. Na rozdiel od digitálneho vstupu, ktorý rozlišuje iba HIGH/LOW, ADC vie povedať aj "koľko presne".
Ako to funguje – postupná aproximácia
Existuje viacero spôsobov, ako previesť analógový signál na digitálny, no najbežnejšia metóda (používa ju napr. aj ATMEGA328 v klasickom Arduine) sa volá postupná aproximácia (successive approximation).
Proces má dva kroky:
- Vzorkovanie (sample & hold) – v pravidelných intervaloch (vzorkovacia frekvencia) sa "odfotí" aktuálna hodnota napätia a na krátky čas sa podrží nezmenená (nabije sa na malý kondenzátor), aby ju obvod stihol spracovať. Čím vyššia vzorkovacia frekvencia, tým presnejšie ADC zachytí priebeh rýchlo sa meniaceho signálu.
- Postupná aproximácia – obvod (SAR, successive approximation register) postupne "hádne" binárnu hodnotu, tú si cez interný DAC (digitálno-analógový prevodník) premení späť na napätie a porovná s podrženou vzorkou pomocou komparátora. Podľa výsledku porovnania hádanie krok po kroku spresňuje (podobne ako hra "väčšie/menšie"), až kým nedostane výsledné binárne číslo.
Nameranú binárnu hodnotu vieš prepočítať naspäť na skutočné napätie podľa vzorca:
napätie = (referenčné_napätie × nameraná_hodnota) / maximálna_hodnota
Napríklad pri 10-bitovom ADC (maximálna hodnota 1023) s referenčným napätím 5 V a nameranou hodnotou 100 vychádza napätie (5 × 100) / 1023 ≈ 0,49 V.
Rozlíšenie (počet bitov) určuje, koľko rôznych úrovní vie ADC rozlíšiť – pri n-bitovom ADC je to 2n úrovní (10-bit = 1024 úrovní, 12-bit = 4096 úrovní). Viac bitov = jemnejšie "schodíky" medzi jednotlivými nameranými hodnotami.
Nie každý GPIO pin má ADC – táto funkcia je vyhradená len na niektoré piny (RP2350-Zero má 4 ADC-schopné piny). Presne ktoré to sú, over si v oficiálnom pinoute.
Obrázok ukazuje výsledok celého procesu: spojitý analógový signál (napr. napätie z páčky) sa rozdelí na diskrétne "schodíky" – konkrétne číselné hodnoty, s ktorými už vie program ďalej pracovať.
Dôležité: analógové vstupy na RP2350 sú hardvérovo 12-bitové (rozsah 0–4095), no Arduino framework ich defaultne číta ako 10-bitové (0–1023) kvôli kompatibilite s inými doskami. Ak chceš využiť celý rozsah, treba si o to výslovne povedať funkciou analogReadResolution(12) – presne to robíme v druhom príklade nižšie.
10-bitový ADC (joystick)
Joystick je presne takýto prípad: VRX a VRY vracajú analógové napätie podľa toho, ako veľmi je páčka vychýlená. V Arduino frameworku sa hodnota číta funkciou analogRead(pin), ktorá bez ďalšieho nastavenia vracia hodnotu 0–1023 (10-bit rozlíšenie, viď poznámka vyššie).
const int PIN_VRX = 26;
const int PIN_VRY = 27;
void setup() {
Serial.begin(115200);
}
void loop() {
int hodnotaX = analogRead(PIN_VRX);
int hodnotaY = analogRead(PIN_VRY);
Serial.print("VRX: ");
Serial.print(hodnotaX);
Serial.print(" VRY: ");
Serial.println(hodnotaY);
delay(200);
}
Surová hodnota (0–1023) sama o sebe veľa nepovie – v praxi si ju zvyčajne prepočítaš na užitočnejší rozsah, napríklad map(hodnotaX, 0, 1023, -100, 100), aby si dostal rýchlosť alebo výchylku v rozsahu, s ktorým sa ti ľahšie pracuje.
Poznámka: presnú hodnotu referenčného napätia si over v dokumentácii – pri práci s citlivejšími meraniami (napr. presné napätie z batérie) sa oplatí skontrolovať, či Arduino framework nepoužíva pre RP2350 iné predvolené nastavenia než klasický RP2040.
12-bitový ADC (line senzor + multiplexor)
Ako je spomenuté vyššie, ADC na RP2350 je hardvérovo 12-bitový (rozsah 0–4095), teda presnejší než predvolený 10-bit (0–1023) príklad vyššie – stačí zavolať analogReadResolution(12).
Problém je, že ADC-schopných pinov je na doske len pár (rádovo 3–4), no niektoré senzory majú oveľa viac analógových výstupov naraz – napríklad 8-kanálový line senzor QTR-8A (8 samostatných IR reflexných snímačov). Riešením je multiplexor (napr. 74HC4051, 8-kanálový analógový mux): všetkých 8 signálov sa privedie naň, a on podľa 3 digitálnych "výberových" pinov (S0, S1, S2 – binárna adresa 000 až 111) prepája vždy len jeden z nich na spoločný výstup, ktorý ide do jediného ADC pinu.
const int PIN_S0 = 13;
const int PIN_S1 = 14;
const int PIN_S2 = 15;
const int PIN_ADC = 26; // spolocny vystup z multiplexora
const int POCET_KANALOV = 8;
int hodnoty[POCET_KANALOV];
void nastav_kanal(int kanal) {
digitalWrite(PIN_S0, kanal & 0x01);
digitalWrite(PIN_S1, (kanal >> 1) & 0x01);
digitalWrite(PIN_S2, (kanal >> 2) & 0x01);
}
void setup() {
pinMode(PIN_S0, OUTPUT);
pinMode(PIN_S1, OUTPUT);
pinMode(PIN_S2, OUTPUT);
analogReadResolution(12); // vyuzijeme cely 12-bit rozsah (0-4095)
Serial.begin(115200);
}
void loop() {
for (int kanal = 0; kanal < POCET_KANALOV; kanal++) {
nastav_kanal(kanal);
delayMicroseconds(20); // kratke ustalenie signalu po prepnuti kanala
hodnoty[kanal] = analogRead(PIN_ADC);
}
for (int i = 0; i < POCET_KANALOV; i++) {
Serial.print(hodnoty[i]);
Serial.print("\t");
}
Serial.println();
delay(100);
}
Program postupne prepína všetkých 8 kanálov (binárne 000, 001, 010... 111), pri každom krátko počká, kým sa signál ustáli po prepnutí, a až potom prečíta ADC. Výsledkom je 8 hodnôt naraz, hoci fyzicky používame len jeden ADC pin.
Poznámka: presné číslo pinu s ADC funkciou a maximálny počet dostupných ADC pinov na RP2350-Zero si over v pinoute – rovnako aj to, či analogReadResolution(12) funguje v Arduino frameworku pre RP2350 rovnako ako pre RP2040.