Skip to Content
Arduino EğitimleriAnalog Okuma (analogRead)

Analog Okuma (analogRead)

Dijital pinler yalnızca “var / yok” bilgisi verir. Ancak gerçek dünya böyle çalışmaz: bir potansiyometrenin konumu, ortamın ışık şiddeti veya bir sensörün çıkışı sürekli değişen değerlerdir.

analogRead() fonksiyonu bu sürekli gerilimi sayıya çevirir.

ADC Nedir?

Arduino’nun içinde ADC (Analog-Digital Converter) adı verilen bir birim vardır. Görevi, pindeki gerilimi ölçüp sayısal bir değere çevirmektir.

Arduino Uno’nun ADC’si 10 bit çözünürlüklüdür:

2^10 = 1024 farklı değer → 0 ile 1023 arası
Pindeki gerilimOkunan değer
0 V0
1,25 V~256
2,5 V~512
3,75 V~768
5 V1023

Her birim yaklaşık 4,9 mV’a karşılık gelir (5 V / 1024).

Temel Kullanım

int deger = analogRead(A0); // 0 - 1023

Analog pinler A0–A5’tir (Uno). Bunları giriş olarak kullanmak için pinMode() çağırmanız gerekmez.

const int SENSOR_PIN = A0; void setup() { Serial.begin(9600); } void loop() { int deger = analogRead(SENSOR_PIN); Serial.println(deger); delay(200); }

Gerilime Çevirme

Ham değer bir sayıdır; gerçek gerilimi bulmak için ölçeklemek gerekir:

float volt = deger * (5.0 / 1023.0);
void loop() { int ham = analogRead(A0); float volt = ham * (5.0 / 1023.0); Serial.print("Ham: "); Serial.print(ham); Serial.print(" Gerilim: "); Serial.print(volt, 3); Serial.println(" V"); delay(200); }

5.0 yerine 5 yazarsanız tam sayı bölmesi yapılır ve sonuç sıfır çıkar. Ondalık nokta önemlidir.

Daha da doğru sonuç için gerçek besleme gerilimini ölçüp kullanın. USB ile beslenen bir Arduino’da 5V pini genellikle 4,7–4,9 V arasındadır; bu, ölçümde %5’e varan hata demektir.

map() ile Ölçekleme

Ham 0–1023 aralığını başka bir aralığa çevirmek için map() kullanılır:

map(deger, girisMin, girisMaks, cikisMin, cikisMaks)
int pwm = map(analogRead(A0), 0, 1023, 0, 255); // LED parlakligi int aci = map(analogRead(A0), 0, 1023, 0, 180); // servo acisi int yuzde = map(analogRead(A0), 0, 1023, 0, 100); // yuzde

map() tam sayı aritmetiği kullanır; ondalık sonuç vermez ve küsuratı atar.

Ters ölçekleme de mümkündür:

int ters = map(analogRead(A0), 0, 1023, 255, 0); // deger arttikca azalir

constrain() ile Sınırlama

Sensör beklenen aralığın dışına çıkarsa map() aralık dışı değer üretir. constrain() bunu keser:

int yuzde = map(analogRead(A0), 300, 800, 0, 100); yuzde = constrain(yuzde, 0, 100); // 0'in altina, 100'un ustune cikmasin

Kalibre edilmiş sensörlerde bu ikili neredeyse her zaman birlikte kullanılır.

Okuma Neden Titriyor?

Sabit bir gerilim uygulasanız bile okunan değer birkaç birim oynar. Bunun nedenleri elektriksel gürültü, besleme dalgalanması ve ADC’nin kendi hata payıdır.

Çözüm 1: Ortalama alma

int ortalamaOku(int pin, int adet) { long toplam = 0; for (int i = 0; i < adet; i++) { toplam += analogRead(pin); delay(2); } return toplam / adet; }

long kullanmak önemlidir; int ile 32 okumadan sonra taşma olur.

Çözüm 2: Üstel yumuşatma (EMA)

Bellek ve zaman açısından en verimli yöntemdir:

float filtreli = 0; const float ALFA = 0.2; // kucuk deger = daha yumusak void loop() { int ham = analogRead(A0); filtreli = ALFA * ham + (1.0 - ALFA) * filtreli; Serial.println(filtreli, 1); delay(50); }

Çözüm 3: Ölü bant

Küçük değişimleri yok sayın:

int sonDeger = 0; void loop() { int deger = analogRead(A0); if (abs(deger - sonDeger) > 5) { sonDeger = deger; // sadece anlamli degisimde islem yap } }

Çözüm 4: Donanımsal

Analog pin ile GND arasına 100 nF kondansatör koymak yüksek frekanslı gürültüyü temizler.

Ardışık Farklı Pinleri Okuma

Arduino’da tek bir ADC vardır ve pinler arasında bir çoklayıcı (multiplexer) ile geçiş yapılır. Yüksek empedanslı kaynaklarda, bir önceki pinin değeri sonrakine sızabilir (crosstalk).

Çözüm: aynı pini iki kez okumak ve ilkini atmak.

int temizOku(int pin) { analogRead(pin); // ilk okumayi at (mux yerlessin) delayMicroseconds(50); return analogRead(pin); }

Bu, özellikle LDR ve toprak nemi gibi yüksek empedanslı sensörlerde gözle görülür fark yaratır.

5 V’tan Yüksek Gerilim Ölçmek

Analog pine 5 V’un üzerinde gerilim uygulamak mikrodenetleyiciyi bozar. Daha yüksek gerilim ölçmek için gerilim bölücü kullanılır.

Vgiris ──[ R1 ]──┬──[ R2 ]── GND └── A0
V_A0 = V_giris × R2 / (R1 + R2)

Örnek: 12 V ölçmek

  • R1 = 10 kΩ, R2 = 4,7 kΩ
  • V_A0 = 12 × 4,7 / 14,7 = 3,84 V ✔ (5 V’un altında)
const float R1 = 10000.0; const float R2 = 4700.0; const float CARPAN = (R1 + R2) / R2; // 3.128 void loop() { int ham = analogRead(A0); float pinVolt = ham * (5.0 / 1023.0); float gercekVolt = pinVolt * CARPAN; Serial.print("Batarya: "); Serial.print(gercekVolt, 2); Serial.println(" V"); delay(1000); }

Bu, batarya seviyesi takibi yapmanın standart yöntemidir.

Dirençleri çok büyük seçmeyin (örneğin 1 MΩ). ADC’nin giriş empedansı yüzünden okuma kararsızlaşır. 10 kΩ mertebesi idealdir.

AREF ile Hassasiyet Artırma

Ölçtüğünüz sinyal 0–1 V arasındaysa, 0–5 V referansla okumak çözünürlüğün %80’ini boşa harcar.

analogReference(INTERNAL) ile Uno’nun dahili 1,1 V referansına geçebilirsiniz:

void setup() { analogReference(INTERNAL); // 0 - 1.1 V araligi 0-1023'e olceklenir Serial.begin(9600); } void loop() { int ham = analogRead(A0); float volt = ham * (1.1 / 1023.0); Serial.println(volt, 4); delay(200); }

Artık her birim ~1,07 mV’a karşılık gelir — beş kat daha hassas.

⚠ Bu modda pine 1,1 V’un üzerinde gerilim uygulamayın.

Okuma Hızı

Bir analogRead() çağrısı yaklaşık 100 mikrosaniye sürer. Yani saniyede en fazla ~10.000 okuma yapılabilir.

Çoğu proje için fazlasıyla yeterlidir, ancak ses işleme veya hızlı sinyal yakalama gerektiren uygulamalarda bu bir sınırdır. Bu durumda ADC prescaler ayarları değiştirilerek hız artırılabilir (doğruluk pahasına).

ESP Kartlarında Farklar

KartADC çözünürlüğüAralıkNot
Arduino Uno10 bit (0–1023)0 – 5 V6 kanal
ESP826610 bit0 – 1 VTek kanal (A0); NodeMCU’da kart üzerindeki bölücü ile 0–3,3 V
ESP3212 bit (0–4095)0 – 3,3 V18 kanal, ancak doğrusallığı zayıf
Arduino Due12 bit (0–4095)0 – 3,3 V

ESP32’nin ADC’si doğrusal değildir; hassas ölçüm için kalibrasyon tablosu veya harici ADC (ADS1115) kullanmak gerekir.

Özet

analogRead(), analog pindeki gerilimi 10 bit çözünürlükle 0–1023 arasında bir sayıya çevirir. Bu sayı map() ile istenen aralığa ölçeklenir.

Bu derste şunları öğrendik:

  • 10 bit ADC ve 0–1023 aralığını
  • Ham değeri gerilime çevirmeyi
  • map() ve constrain() kullanımını
  • Gürültüyü ortalama, EMA ve ölü bantla azaltmayı
  • Farklı pinleri okurken çift okuma tekniğini
  • Gerilim bölücü ile 5 V üstü ölçmeyi
  • analogReference(INTERNAL) ile hassasiyet artırmayı