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 (mikrofón)
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).
Analógové výstupy vysiela samotný mikrofón KY-53. Nižšie uvedený príklad uvádza takéto čítanie z mikrofónu. Mikrofón zachytí zvuk a podla jeho intenzity a frekvencie prevedie na analógový signál, ktorý čítame na vstupe RP2350.
const int MIC_DIGITAL = 5; // digitálny výstup D0
const int MIC_ANALOG = 26; // analógový výstup A0 (ADC)
void setup() {
pinMode(MIC_DIGITAL, INPUT);
Serial.begin(9600);
analogReadResolution(12);
}
void loop() {
int digitalVal = digitalRead(MIC_DIGITAL); // 0 alebo 1
int analogVal = analogRead(MIC_ANALOG); // 0 až 4095
Serial.print("Digitálny: ");
Serial.print(digitalVal);
Serial.print(" | Analógový: ");
Serial.println(analogVal);
delay(50);
}