Skip to Content
Arduino EğitimleriPWM ve analogWrite

PWM ve analogWrite

Arduino’nun dijital pinleri yalnızca 0 V veya 5 V verebilir. Peki bir LED’i yarı parlaklıkta yakmak veya bir motoru yarı hızda döndürmek nasıl mümkün oluyor?

Cevap PWM (Pulse Width Modulation — Darbe Genişlik Modülasyonu).

PWM Nasıl Çalışır?

PWM, pini çok hızlı bir şekilde açıp kapatarak ortalama gerilimi değiştirir.

Bir saniyede yüzlerce kez açılıp kapanan bir LED’i göz sürekli yanıyor gibi algılar. Ancak açık kalma süresi kısaltılırsa LED daha sönük görünür.

Anahtar kavram duty cycle (görev döngüsü): sinyalin bir periyot içinde ne kadar süre HIGH kaldığının yüzdesidir.

Duty cycleOrtalama gerilim (5 V’ta)analogWrite değeri
%00 V0
%251,25 V64
%502,5 V127
%753,75 V191
%1005 V255

analogWrite() Kullanımı

analogWrite(pin, deger); // deger: 0 - 255

İsmine rağmen bu fonksiyon gerçek analog çıkış üretmez; PWM sinyali üretir. Bu ayrımın neden önemli olduğunu aşağıda açıklıyoruz.

const int LED_PIN = 9; void setup() { pinMode(LED_PIN, OUTPUT); } void loop() { // Yavasca parlaklasma for (int i = 0; i <= 255; i++) { analogWrite(LED_PIN, i); delay(8); } // Yavasca sonme for (int i = 255; i >= 0; i--) { analogWrite(LED_PIN, i); delay(8); } }

Hangi Pinler PWM Destekler?

Kart üzerinde ~ işaretiyle gösterilen pinler.

KartPWM pinleri
Arduino Uno / Nano3, 5, 6, 9, 10, 11
Arduino Mega2 – 13, 44, 45, 46
Arduino Leonardo3, 5, 6, 9, 10, 11, 13
ESP8266Tüm GPIO pinleri (yazılımsal PWM)
ESP3216 kanal, herhangi bir GPIO’ya atanabilir

PWM desteklemeyen bir pinde analogWrite() çağırmak yalnızca 128’in altı için LOW, üstü için HIGH etkisi yapar.

PWM Frekansı

Arduino Uno’da PWM frekansı pine göre değişir:

PinlerFrekansTimer
5, 6~980 HzTimer0
9, 10~490 HzTimer1
3, 11~490 HzTimer2

Bu frekanslar işitme aralığındadır. Bu yüzden PWM ile sürülen bir motor veya trafo ıslık gibi öter.

Frekansı 20 kHz üzerine çıkarmak sesi duyulmaz hale getirir, ancak bu timer register’larını doğrudan değiştirmeyi gerektirir. Timer0’a dokunmak millis() ve delay() fonksiyonlarını bozar; dokunacaksanız Timer1 veya Timer2’yi tercih edin.

ESP32’de PWM (LEDC)

ESP32’de analogWrite() yoktur (bazı çekirdek sürümlerinde eklenmiştir). Yerine LEDC birimi kullanılır ve frekans ile çözünürlük ayarlanabilir:

const int LED_PIN = 5; const int KANAL = 0; const int FREKANS = 5000; // 5 kHz const int COZUNURLUK = 8; // 8 bit -> 0-255 void setup() { ledcSetup(KANAL, FREKANS, COZUNURLUK); ledcAttachPin(LED_PIN, KANAL); } void loop() { for (int i = 0; i <= 255; i++) { ledcWrite(KANAL, i); delay(8); } }

12 bit çözünürlük seçerseniz değer aralığı 0–4095 olur; çok daha ince parlaklık kontrolü sağlar.

PWM Gerçek Analog Çıkış Değildir

Bu ayrım, birçok kafa karışıklığının kaynağıdır.

PWM çıkışı hâlâ kare dalgadır: sürekli 0 V ile 5 V arasında gidip gelir. Ortalaması istediğiniz değere eşittir, ama anlık gerilim asla ara bir değerde değildir.

Ne zaman sorun olmaz?

  • LED parlaklığı — göz ortalar
  • Motor hızı — motorun ataleti ortalar
  • Isıtıcı gücü — ısıl atalet ortalar

Ne zaman sorun olur?

  • Bir sensöre veya op-amp’a referans gerilim vermek
  • Ses sinyali üretmek
  • Bir devrenin besleme gerilimini ayarlamak

Bu durumlarda gerçek analog gerilim gerekir. İki yol vardır:

1. RC alçak geçiren filtre. PWM çıkışına seri direnç ve GND’ye kondansatör eklemek dalgayı düzleştirir:

PWM pini ──[ 10 kΩ ]──┬── analog çıkış [100 nF] GND

Filtre çıkışı yavaş tepki verir ve akım veremez; bir op-amp tampon eklemek gerekebilir.

2. Gerçek DAC kullanmak. MCP4725 (I2C, 12 bit) gibi bir DAC entegresi gerçek analog gerilim üretir. ESP32’nin GPIO25 ve GPIO26 pinlerinde dahili DAC bulunur.

Motor Hızı Kontrolü

PWM’in en yaygın kullanımlarından biridir.

const int MOTOR_PWM = 9; const int MOTOR_IN1 = 8; const int MOTOR_IN2 = 7; void motorSur(int hiz) { // -255 ile +255 arasi bool ileri = hiz >= 0; int pwm = constrain(abs(hiz), 0, 255); digitalWrite(MOTOR_IN1, ileri ? HIGH : LOW); digitalWrite(MOTOR_IN2, ileri ? LOW : HIGH); analogWrite(MOTOR_PWM, pwm); } void loop() { motorSur(150); // ileri, orta hiz delay(2000); motorSur(0); // dur delay(1000); motorSur(-200); // geri, hizli delay(2000); }

Motor düşük PWM’de dönmüyor

Motorun sürtünmeyi yenmesi için minimum bir torka ihtiyacı vardır. PWM değeri genellikle 60–100’ün altında motor sadece titrer ve ısınır.

Çözüm, kısa bir tam güç darbesiyle motoru başlatmaktır:

void motorBaslat(int hiz) { analogWrite(MOTOR_PWM, 255); delay(50); analogWrite(MOTOR_PWM, hiz); }

Alternatif olarak, kullanılabilir aralığı ölçekleyin:

int gercekPwm = map(istenenHiz, 1, 100, 80, 255); // %1 bile motoru dondursun

LED Parlaklığı ve Göz Algısı

İnsan gözü ışığı logaritmik algılar. analogWrite(128) değeri, elektriksel olarak yarı güç demektir ama göze yarı parlaklık gibi görünmez — çok daha parlak görünür.

Doğrusal görünen bir sönme efekti için değeri karesel ölçekleyin:

void ledParlaklik(int pin, int yuzde) { // 0-100 int deger = (yuzde * yuzde) * 255 / 10000; analogWrite(pin, deger); }

Bu, LED animasyonlarını gözle görülür şekilde daha doğal hale getirir.

Timer Çakışmaları

analogWrite() timer donanımını kullanır ve bazı kütüphaneler aynı timer’ları paylaşır:

KütüphaneEtkilediği PWM pinleri
ServoD9, D10 çalışmaz
tone()D3, D11 bozulur

Servo ve buzzer kullanan bir projede PWM için D5 veya D6 tercih edin.

Özet

PWM, pini çok hızlı açıp kapatarak ortalama gerilimi değiştiren bir tekniktir. analogWrite(pin, 0–255) ile kullanılır ve yalnızca ~ işaretli pinlerde çalışır.

Bu derste şunları öğrendik:

  • Duty cycle kavramını ve 0–255 karşılıklarını
  • Hangi pinlerin PWM desteklediğini
  • PWM frekansını ve motorların neden ıslık çaldığını
  • PWM’in gerçek analog çıkış olmadığını, RC filtre ve DAC alternatiflerini
  • Motor hız kontrolünü ve düşük PWM sorununu
  • Göz algısına uygun karesel parlaklık ölçeklemesini
  • Servo ve tone() ile timer çakışmalarını