Przetwornik ADC (analogowo‑cyfrowy) w Arduino to kluczowy moduł pozwalający mierzyć sygnały analogowe, takie jak napięcie z czujników, potencjometrów czy ogniw. Dzięki niemu ATmega328P (serce Arduino Uno) konwertuje ciągłe napięcie 0–5 V na wartości cyfrowe 0–1023, umożliwiając precyzyjny pomiar i sterowanie w robotyce oraz elektronice.

W tym przewodniku poznasz zasady działania, programowanie i praktyczne zastosowania ADC w Arduino. Omówimy podstawowe pomiary, kalibrację, dzielniki napięciowe do wyższych napięć oraz techniki zwiększania dokładności. Jeśli mierzysz napięcie akumulatora, odczytujesz analogowe sensory lub tworzysz stację pomiarową – zrozumienie ADC to podstawa.

Zasady działania przetwornika ADC w Arduino

W Arduino Uno przetwornik w ATmega328P ma 10‑bitową rozdzielczość, co daje 1024 poziomy (0–1023). Mierzy on stosunek napięcia wejściowego V_IN do napięcia odniesienia V_REF, które domyślnie równa się napięciu zasilania (ok. 5 V z USB).

Do przeliczenia odczytu na napięcie użyj wzoru: V_IN = (ADC × V_REF) / 1023. Dla V_REF = 5 V rozdzielczość wynosi ok. 4,88 mV/LSB (5 V / 1023).

Konwersja odbywa się automatycznie i jest dostępna z poziomu funkcji Arduino analogRead(), bez konieczności ręcznego ustawiania rejestrów (np. ADMUX, ADCSRA).

Ważne ograniczenia wejścia analogowego

Najważniejsze parametry wejść analogowych to:

  • zakres: 0–5 V (napięcie wyższe grozi uszkodzeniem),
  • piny: A0–A5 (6 niezależnych kanałów),
  • prędkość próbkowania: ok. 10 kSPS (około 10 tys. próbek/s).

Podstawowy program do pomiaru napięcia

Na początek użyj potencjometru jako dzielnika napięcia. Podłącz: jeden skrajny pin do 5 V, drugi do GND, środkowy (suwak) do A0. Oto przykładowy program do odczytu i przeliczenia napięcia:


const int analogPin = A0; // pin analogowy
const float voltageReference = 5.0; // napięcie referencyjne
const int resolution = 1024; // 2^10 = 1024 (0-1023)

void setup() {
Serial.begin(9600);
pinMode(analogPin, INPUT);
}

void loop() {
int adcValue = analogRead(analogPin); // odczyt ADC (0-1023)
float voltage = (adcValue * voltageReference) / (resolution - 1); // przeliczenie

Serial.print("ADC: ");
Serial.print(adcValue);
Serial.print(" | Napięcie: ");
Serial.print(voltage, 3); // 3 miejsca po przecinku
Serial.println(" V");

delay(500);
}

Po uruchomieniu obserwuj wartości w Serial Monitor – obracanie potencjometrem zmienia wynik w zakresie 0–5 V.

Pomiar wyższych napięć – dzielnik napięciowy i kalibracja

Standardowe wejście Arduino nie mierzy powyżej 5 V. Rozwiązaniem jest dzielnik napięciowy z dwóch rezystorów R1 i R2: V_WY = V_WE × R2 / (R1 + R2). Przykładowo dla pomiaru pakietu 2S (ok. 7,4–8,4 V) lub wyższych napięć skalujesz je do bezpiecznego poziomu wejścia.

Do niskich napięć warto użyć wewnętrznego V_REF = 1,1 V, które jest stabilniejsze od zasilania USB. Ustaw je poleceniem analogReference(INTERNAL). Dobierając rezystory dzielnika, zmierz ich rzeczywiste wartości i tak dobierz R1/R2, by prąd był niski (np. rzędu mikroamperów); przykładowo R1 = 1 MΩ i R2 = 100 kΩ skalują 0–11 V do ok. 0–1 V.

Poniżej znajdziesz przykładowy program z kalibracją stałej przeliczeniowej:


void setup() {
Serial.begin(115200);
pinMode(A0, INPUT);
analogReference(INTERNAL); // wewnętrzne 1,1 V
}

void loop() {
int adc_val = analogRead(A0);
float Ubit = 1.1 / 1023.0; // napięcie na 1 LSB (skoryguj po kalibracji)
float k = 11.0; // współczynnik skalowania dzielnika (przykład)
float Ubat = adc_val * Ubit * k;

Serial.print(adc_val);
Serial.print(" -> ");
Serial.print(Ubat, 3);
Serial.println(" V");

delay(1000);
}

Kalibracja: zmierz znane napięcie multimetrem i odczyt adc_val, następnie skoryguj stałą tak, by Ubat pokrywało się z wynikiem pomiaru (np. doprecyzuj Ubit lub k).

Porównanie kluczowych ustawień i sposobów poprawy dokładności:

Parametr Wartość domyślna Rekomendowana poprawa
V_REF 5 V (zależne od USB, mniej stabilne) wewnętrzne 1,1 V (stabilniejsze, tolerancja fabryczna ±10%)
Rozdzielczość efektywna 4,88 mV/LSB uśrednianie wielu próbek (lepsza powtarzalność, ±0,2–0,5%)
Źródła błędu wahania zasilania i szum pomiaru zewnętrzny precyzyjny ADC (np. ADS1115, 16‑bit)

Poprawa dokładności i zaawansowane techniki

Dokładność ADC w Arduino po kalibracji osiąga zwykle ±0,2–0,5%. Typowe źródła błędów to:

  • niestabilne V_REF (zasilanie USB może pływać o pojedyncze dziesiątki mV),
  • szumy i zakłócenia (brak filtracji, zakłócenia od silników),
  • tolerancja elementów (rezystory dzielnika, przewody, złącza).

Skuteczne wygładzanie odczytów zapewnia średnia ruchoma – przykład funkcji:


float readVoltage(int pin, int samples = 10) {
long sum = 0;
for (int i = 0; i < samples; i++) {
sum += analogRead(pin);
delay(1);
}
return (sum / (float)samples * 5.0) / 1023.0;
}

Dla wyższej precyzji rozważ zewnętrzne przetworniki, np. ADS1110/ADS1115 (16‑bit, I2C) – idealne do precyzyjnych pomiarów (np. 0–20 V po dzielniku). Wewnętrzne 1,1 V jest stabilne w obrębie pojedynczego egzemplarza mimo tolerancji między układami, dlatego po ustawieniu analogReference(INTERNAL) wykonaj kalibrację.

Praktyczne projekty w robotyce i elektronice

Poniżej znajdziesz przykłady zastosowań ADC, które szybko wdrożysz w swoich projektach:

  1. Monitor akumulatora w robocie – dzielnik dla LiPo, alarm przy spadku poniżej progu;
  2. Czujnik linii dla robota – odczyt z fotorezystorów lub fotodiod, progi decyzji;
  3. Prosty „oscyloskop” – szybki odczyt A0 i wizualizacja w Serial Plotter;
  4. Stacja pomiarowa – wielokanałowy logging z ADS1115 przez I2C;
  5. Termometr – czujnik LM35 (10 mV/°C) i przeliczenie na °C.

Pułapki i dobre praktyki

Stosuj te wskazówki, aby uniknąć błędów i podnieść wiarygodność pomiarów:

  • nie przekraczaj 5 V – zastosuj dzielnik lub diodę Zenera jako ogranicznik;
  • stabilizuj zasilanie – unikaj spadków i szumów (np. filtracja, kondensatory przy Vcc);
  • kalibruj zawsze – skoryguj V_REF i współczynnik dzielnika na podstawie multimetru;
  • Arduino Due – pamiętaj, że ADC jest 12‑bit i pracuje w zakresie 0–3,3 V;
  • oversampling – wielokrotne odczyty i uśrednianie dla efektywnie wyższej rozdzielczości.