Pulse-width modulation (PWM) merupakan sinyal kotak dengan durasi HIGH dan LOW yang bervariasi seperti pada Figure 1. Sinyal PWM akan menghasilkan tegangan rata-rata yang merupakan tegangan pseudo analog. Semakin lama durasi HIGH-nya, maka tegangan rata-rata yang dihasilkan akan semakin besar, dan berlaku sebaliknya.
Tegangan pseudo analog ini dapat digunakan untuk aplikasi pengontrolan kecerahan LED, kecepatan motor DC, atau motor servo. Sinyal PWM ini dibuat dengan menggunakan timer, tetapi pada Arduino sudah terdapat library untuk men-generate sinyal PWM tanpa harus berurusan dengan low-level hardware-nya.
Figure 2 menampilkan contoh detail sinyal PWM. Sinyal tersebut memiliki frekuensi 1kHz dan duty cycle 70\%. Karena frekuensinya adalah 1kHz, maka periodenya adalah 1ms. Duty cycle merupakan persentase sinyal tersebut bernilai HIGH dari total periodenya. Karena duty cycle-nya 70\%, maka durasi HIGH selama 0.7ms dan durasi LOW selama 0.3ms. Jika tegangan supply V_S=3.3V, maka tegangan rata-rata dari sinyal PWM ini adalah 70\%\cdot 3.3V=2.31V.
Dengan memvariasikan nilai duty cycle PWM terhadap waktu, maka kita dapat membuat sinyal analog seperti contohnya sinyal sinusoid pada Figure 3. Sinyal analog seperti ini dapat digunakan untuk pengontrolan LED ataupun kecepatan motor DC.
Timer dapat digunakan untuk men-generate timing untuk sinyal PWM seperti pada Figure 4. Timer akan menghitung dari 0 sampai 2^{n}-1 dimana n adalah resolusi timer yang digunakan.
Titik a merupakan hitungan timer untuk nilai duty cycle, sedangkan titik b merupakan hitungan timer untuk periode. Dari kedua titik tersebut, maka kita bisa menentukan kapan GPIO output harus bernilai HIGH dan LOW. Pada titik a GPIO berubah dari HIGH menjadi LOW, sedangkan pada titik b GPIO berubah dari LOW menjadi HIGH.
Pada ESP32, blok untuk men-generate sinyal PWM bernama LED control (LEDC). Fungsi utama blok ini yaitu untuk mengontrol kecerahan LED, akan tetapi sinyal PWM ini juga bisa digunakan untuk kebutuhan lain. ESP32 memiliki 16 channel PWM yang dapat men-generate 16 sinyal PWM yang berbeda.
Ada beberapa fungsi utama yang diperlukan untuk mengkonfigurasi PWM pada ESP32 seperti pada Listing 1.
Fungsi ledcSetup
berfungsi untuk mengkonfigurasi channel PWM.
Fungsi ledcAttachPin
berfungsi untuk menghubungkan channel PWM dengan pin GPIO output.
Fungsi ledcWrite
berfungsi untuk menulis nilai duty cycle untuk channel PWM.
double ledcSetup(uint8_t channel, double freq, uint8_t resolution_bits);
void ledcAttachPin(uint8_t pin, uint8_t channel);
void ledcWrite(uint8_t channel, uint32_t duty);
Duty cycle pada program dinyatakan dalam integer (bukan percent) sesuai resolusi yang digunakan. Sebagai contoh jika resolusi PWM 8-bit, maka range nilai duty cycle dari 0-255, sedangkan jika resolusi PWM 10-bit, maka range nilai duty cycle dari 0-1023.
Pada contoh program ini, kita akan mempelajari contoh penggunaan PWM. Contoh program ini menggunakan satu buah LED. Kita akan mengatur kecerahan LED tersebut.
Untuk dapat menjalankan contoh program ini diperlukan beberapa komponen:
Listing 2 menampilkan contoh program pengontrolan LED dengan PWM. Berikut ini penjelasan cara kerja program tersebut:
// LED pin
#define LEDPIN 25
// Parameter untuk PWM
const int channel = 0;
const int freq = 1000;
const int res = 10;
void setup()
{
// Inisialisasi PWM
ledcSetup(channel, freq, res);
// Hubungkan channel PWM ke LED
ledcAttachPin(LEDPIN, channel);
}
void loop()
{
// Decrease brightness LED (active-low LED)
for (int i = 0; i <= 1023; i += 20)
{
ledcWrite(channel, i);
delay(25);
}
// Increase brightness LED (active-low LED)
for (int i = 1023; i >= 0; i -= 20)
{
ledcWrite(channel, i);
delay(25);
}
}
Figure 6 menampilkan hasil dari program pengontrolan kecerahan LED dengan PWM. Kecerahan LED akan perlahan-lahan naik dari kondisi mati sampai menyala penuh, kemudian akan perlahan-lahan kembali ke kondisi mati.
Figure 7 menampilkan animasi pengaruh sinyal PWM terhadap kecerahan LED. Pada contoh kasus ini rangkaian yang digunakan yaitu active-high, sehingga semakin besar duty cycle, maka LED akan semakin terang.
Kode program untuk pengontrolan LED dengan PWM dapat didapatkan di repository ini: pwm-led.