Kontrol Kecerahan LED dengan Potensiometer - PWM dan Analog Input

Tutorial menggunakan potensiometer untuk mengatur kecerahan LED di Arduino, memahami konsep PWM, analog input, dan analogWrite().

05-06-2025
04:53 18 Juni 2025
11 min read

Setelah mempelajari kontrol LED digital dengan button, saatnya beralih ke kontrol yang lebih halus menggunakan input analog. Potensiometer memungkinkan kita mengatur kecerahan LED secara bertahap dari redup hingga terang. Tutorial ini akan mengajarkan konsep PWM (Pulse Width Modulation) dan analog input yang sangat penting dalam Arduino.

Apa itu Kontrol Kecerahan LED?

Kontrol kecerahan LED adalah kemampuan untuk mengatur intensitas cahaya LED dari 0% (mati) hingga 100% (terang penuh) secara bertahap. Berbeda dengan kontrol digital yang hanya ON/OFF, kontrol kecerahan memberikan variasi yang smooth dan natural.

Tujuan Pembelajaran

Setelah menyelesaikan tutorial ini, Anda akan memahami:

  • Konsep PWM (Pulse Width Modulation) untuk kontrol kecerahan
  • Cara menggunakan potensiometer sebagai input analog
  • Fungsi analogRead() untuk membaca nilai analog
  • Fungsi analogWrite() untuk PWM output
  • Mapping nilai dari satu range ke range lain
  • Pin PWM pada Arduino dan karakteristiknya
  • Aplikasi praktis kontrol kecerahan dalam project

Konsep PWM (Pulse Width Modulation)

Apa itu PWM?

PWM adalah teknik untuk mengontrol rata-rata daya yang diberikan ke komponen dengan mengubah lebar pulsa sinyal digital. Meskipun output tetap digital (HIGH/LOW), efek yang dihasilkan mirip dengan sinyal analog.

Cara Kerja PWM

Duty Cycle 25%: â–„â–„â–„___â–„â–„â–„___â–„â–„â–„___ (LED redup)
Duty Cycle 50%: â–„â–„â–„â–„â–„_____â–„â–„â–„â–„â–„_____ (LED medium)
Duty Cycle 75%: â–„â–„â–„â–„â–„â–„â–„â–„â–„___â–„â–„â–„â–„â–„â–„â–„â–„â–„___ (LED terang)
  • Duty Cycle: Persentase waktu sinyal HIGH dalam satu periode
  • Frekuensi: Kecepatan switching (biasanya ~490Hz pada Arduino)
  • Resolution: Arduino menggunakan 8-bit (0-255 values)

Pin PWM pada Arduino Uno

Arduino Uno memiliki 6 pin PWM yang ditandai dengan simbol ~:

  • Pin 3: Timer 2
  • Pin 5: Timer 0
  • Pin 6: Timer 0
  • Pin 9: Timer 1
  • Pin 10: Timer 1
  • Pin 11: Timer 2

Memahami Potensiometer

Apa itu Potensiometer?

Potensiometer adalah resistor variabel yang nilainya dapat diubah dengan memutar shaft (poros). Komponen ini memiliki 3 kaki dan sering digunakan sebagai pembagi tegangan (voltage divider).

Struktur Potensiometer

VCC → [Resistor Track] → GND
↑
Wiper (Middle Pin)
  • Kaki 1: Terhubung ke salah satu ujung resistor
  • Kaki 2: Wiper (output variabel)
  • Kaki 3: Terhubung ke ujung resistor lainnya

Cara Kerja sebagai Voltage Divider

Saat wiper diputar, resistansi antara kaki tengah dengan kedua ujung berubah:

  • Putar ke satu arah: Resistansi kecil ke satu sisi, besar ke sisi lain
  • Putar berlawanan: Sebaliknya
  • Output voltage: Bervariasi dari 0V hingga VCC (5V)

Komponen yang Diperlukan

Hardware Wajib

  • Arduino Uno (atau varian Arduino lainnya)
  • LED (5mm, warna bebas)
  • Potensiometer (10kΩ linear taper)
  • Resistor 220Ω (untuk LED)
  • Breadboard
  • Kabel jumper (male-to-male)
  • Kabel USB untuk programming

Software

  • Arduino IDE (sudah terinstall dan dikonfigurasi)

Rangkaian Dasar

Koneksi Potensiometer

Potensiometer:
- Kaki 1 (ujung) → 5V
- Kaki 2 (tengah) → Arduino Pin A0
- Kaki 3 (ujung) → GND

Koneksi LED

LED:
Arduino Pin 9 → Resistor 220Ω → LED (Anoda) → LED (Katoda) → GND

Diagram Lengkap

5V → Potensiometer Kaki 1
Potensiometer Kaki 2 → A0
Potensiometer Kaki 3 → GND
Pin 9 → Resistor 220Ω → LED Anoda
LED Katoda → GND

Program Dasar: Kontrol Kecerahan

1. Program Sederhana

// Pin definitions
const int potPin = A0; // Pin analog untuk potensiometer
const int ledPin = 9; // Pin PWM untuk LED
// Variables
int potValue = 0; // Nilai dari potensiometer (0-1023)
int brightness = 0; // Nilai brightness untuk LED (0-255)
void setup() {
// Initialize pin
pinMode(ledPin, OUTPUT);
// Initialize serial untuk monitoring
Serial.begin(9600);
}
void loop() {
// Baca nilai potensiometer
potValue = analogRead(potPin);
// Konversi dari range 0-1023 ke 0-255
brightness = map(potValue, 0, 1023, 0, 255);
// Set brightness LED menggunakan PWM
analogWrite(ledPin, brightness);
// Display nilai di Serial Monitor
Serial.print("Pot Value: ");
Serial.print(potValue);
Serial.print(" -> Brightness: ");
Serial.println(brightness);
delay(10); // Small delay untuk stabilitas
}

Penjelasan Kode

analogRead(potPin)

  • Membaca nilai analog dari pin A0
  • Return value: 0-1023 (10-bit resolution)
  • 0 = 0V, 1023 = 5V (atau VCC)

map() Function

brightness = map(potValue, 0, 1023, 0, 255);
  • Mengkonversi nilai dari satu range ke range lain
  • map(value, fromLow, fromHigh, toLow, toHigh)
  • Hasil: Linear mapping dari input range ke output range

analogWrite(ledPin, brightness)

  • Menghasilkan sinyal PWM pada pin yang mendukung
  • Parameter: 0-255 (8-bit resolution)
  • 0 = 0% duty cycle (LED mati)
  • 255 = 100% duty cycle (LED terang penuh)

Program Lanjutan dengan Smoothing

2. Smoothing untuk Mengurangi Flicker

const int potPin = A0;
const int ledPin = 9;
// Smoothing variables
const int numReadings = 10;
int readings[numReadings];
int readIndex = 0;
int total = 0;
int average = 0;
int brightness = 0;
void setup() {
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
// Initialize semua readings dengan 0
for (int i = 0; i < numReadings; i++) {
readings[i] = 0;
}
}
void loop() {
// Subtract reading lama
total = total - readings[readIndex];
// Baca nilai baru
readings[readIndex] = analogRead(potPin);
// Add reading baru ke total
total = total + readings[readIndex];
// Advance ke next position
readIndex = readIndex + 1;
// Wrap around ke awal array
if (readIndex >= numReadings) {
readIndex = 0;
}
// Calculate average
average = total / numReadings;
// Map ke brightness
brightness = map(average, 0, 1023, 0, 255);
// Set LED brightness
analogWrite(ledPin, brightness);
Serial.print("Raw: ");
Serial.print(readings[readIndex == 0 ? numReadings-1 : readIndex-1]);
Serial.print(" -> Smooth: ");
Serial.print(average);
Serial.print(" -> Brightness: ");
Serial.println(brightness);
delay(1);
}

Variasi Program Kontrol Kecerahan

3. Non-Linear Brightness (Gamma Correction)

const int potPin = A0;
const int ledPin = 9;
// Gamma correction table untuk LED yang lebih natural
const uint8_t gamma8[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2,
2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5,
5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10,
10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16,
17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 24, 24, 25,
25, 26, 27, 27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 35, 35, 36,
37, 38, 39, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 50,
51, 52, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 66, 67, 68,
69, 70, 72, 73, 74, 75, 77, 78, 79, 81, 82, 83, 85, 86, 87, 89,
90, 92, 93, 95, 96, 98, 99,101,102,104,105,107,109,110,112,114,
115,117,119,120,122,124,126,127,129,131,133,135,137,138,140,142,
144,146,148,150,152,154,156,158,160,162,164,167,169,171,173,175,
177,180,182,184,186,189,191,193,196,198,200,203,205,208,210,213,
215,218,220,223,225,228,231,233,236,239,241,244,247,249,252,255
};
void setup() {
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
}
void loop() {
int potValue = analogRead(potPin);
// Map ke index array (0-255)
int index = map(potValue, 0, 1023, 0, 255);
// Apply gamma correction
int correctedBrightness = gamma8[index];
analogWrite(ledPin, correctedBrightness);
Serial.print("Pot: ");
Serial.print(potValue);
Serial.print(" -> Index: ");
Serial.print(index);
Serial.print(" -> Corrected: ");
Serial.println(correctedBrightness);
delay(10);
}

4. Multiple LED dengan Satu Potensiometer

const int potPin = A0;
const int led1Pin = 3;
const int led2Pin = 5;
const int led3Pin = 6;
void setup() {
pinMode(led1Pin, OUTPUT);
pinMode(led2Pin, OUTPUT);
pinMode(led3Pin, OUTPUT);
Serial.begin(9600);
}
void loop() {
int potValue = analogRead(potPin);
if (potValue < 341) {
// Range bawah: hanya LED 1
int brightness = map(potValue, 0, 340, 0, 255);
analogWrite(led1Pin, brightness);
analogWrite(led2Pin, 0);
analogWrite(led3Pin, 0);
Serial.println("LED 1 active");
} else if (potValue < 682) {
// Range tengah: hanya LED 2
int brightness = map(potValue, 341, 681, 0, 255);
analogWrite(led1Pin, 0);
analogWrite(led2Pin, brightness);
analogWrite(led3Pin, 0);
Serial.println("LED 2 active");
} else {
// Range atas: hanya LED 3
int brightness = map(potValue, 682, 1023, 0, 255);
analogWrite(led1Pin, 0);
analogWrite(led2Pin, 0);
analogWrite(led3Pin, brightness);
Serial.println("LED 3 active");
}
delay(50);
}

5. RGB LED Control

const int potPin = A0;
const int redPin = 3;
const int greenPin = 5;
const int bluePin = 6;
void setup() {
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
Serial.begin(9600);
}
void loop() {
int potValue = analogRead(potPin);
// Bagi range pot menjadi 3 zona warna
if (potValue < 341) {
// Red zone
int red = map(potValue, 0, 340, 0, 255);
analogWrite(redPin, red);
analogWrite(greenPin, 0);
analogWrite(bluePin, 0);
} else if (potValue < 682) {
// Green zone
int green = map(potValue, 341, 681, 0, 255);
analogWrite(redPin, 0);
analogWrite(greenPin, green);
analogWrite(bluePin, 0);
} else {
// Blue zone
int blue = map(potValue, 682, 1023, 0, 255);
analogWrite(redPin, 0);
analogWrite(greenPin, 0);
analogWrite(bluePin, blue);
}
delay(10);
}

Advanced: Breathing Effect

6. Auto Breathing dengan Speed Control

const int potPin = A0;
const int ledPin = 9;
float brightness = 0;
float increment = 1;
int delayTime = 10;
void setup() {
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
}
void loop() {
int potValue = analogRead(potPin);
// Map pot value ke delay time (speed control)
delayTime = map(potValue, 0, 1023, 1, 50);
// Update brightness untuk breathing effect
brightness += increment;
if (brightness >= 255 || brightness <= 0) {
increment = -increment; // Reverse direction
}
// Constrain brightness
brightness = constrain(brightness, 0, 255);
analogWrite(ledPin, (int)brightness);
Serial.print("Speed: ");
Serial.print(delayTime);
Serial.print("ms -> Brightness: ");
Serial.println((int)brightness);
delay(delayTime);
}

Kalibrasi dan Fine-tuning

7. Program dengan Kalibrasi

const int potPin = A0;
const int ledPin = 9;
int minPotValue = 1023;
int maxPotValue = 0;
bool calibrated = false;
void setup() {
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
Serial.println("Kalibrasi dimulai - putar pot ke min dan max dalam 5 detik");
// Calibration periode 5 detik
unsigned long calibrationTime = 5000;
unsigned long startTime = millis();
while (millis() - startTime < calibrationTime) {
int potValue = analogRead(potPin);
if (potValue > maxPotValue) {
maxPotValue = potValue;
}
if (potValue < minPotValue) {
minPotValue = potValue;
}
// Indikator kalibrasi dengan LED berkedip
digitalWrite(ledPin, (millis() / 250) % 2);
delay(10);
}
calibrated = true;
digitalWrite(ledPin, LOW);
Serial.print("Kalibrasi selesai - Min: ");
Serial.print(minPotValue);
Serial.print(", Max: ");
Serial.println(maxPotValue);
}
void loop() {
if (calibrated) {
int potValue = analogRead(potPin);
// Map menggunakan nilai kalibrasi
int brightness = map(potValue, minPotValue, maxPotValue, 0, 255);
brightness = constrain(brightness, 0, 255);
analogWrite(ledPin, brightness);
Serial.print("Pot: ");
Serial.print(potValue);
Serial.print(" -> Brightness: ");
Serial.println(brightness);
}
delay(10);
}

Troubleshooting Kontrol Kecerahan

LED Tidak Merespons Potensiometer

Kemungkinan Penyebab:

  • Pin bukan PWM pin (harus pin dengan tanda ~)
  • Wiring potensiometer salah
  • Kode mapping error

Solusi:

  • Gunakan pin PWM (3, 5, 6, 9, 10, 11)
  • Periksa koneksi potensiometer
  • Cek fungsi map() parameters

LED Berkedip/Flicker

Kemungkinan Penyebab:

  • Noise pada pembacaan analog
  • PWM frequency interference
  • Power supply noise

Solusi:

  • Implementasi smoothing/averaging
  • Tambah capacitor di power rail
  • Gunakan delay yang lebih kecil

Brightness Tidak Linear

Kemungkinan Penyebab:

  • Karakteristik LED tidak linear
  • Potensiometer tidak linear taper

Solusi:

  • Gunakan gamma correction table
  • Pilih potensiometer linear taper
  • Implementasi curve correction

Serial Monitor Spam

Kemungkinan Penyebab:

  • Tidak ada delay dalam loop
  • Print statement terlalu sering

Solusi:

  • Tambah delay yang sesuai
  • Print hanya saat ada perubahan signifikan

Best Practices

1. Efficient Code Structure

// Pin definitions
const int POT_PIN = A0;
const int LED_PIN = 9;
// Constants
const int SMOOTHING_SAMPLES = 5;
const int UPDATE_INTERVAL = 10;
// Variables
struct SmoothingBuffer {
int values[SMOOTHING_SAMPLES];
int index;
int total;
int average;
};
SmoothingBuffer potBuffer = {{0}, 0, 0, 0};
unsigned long lastUpdate = 0;
void setup() {
pinMode(LED_PIN, OUTPUT);
Serial.begin(9600);
initializeSmoothingBuffer();
}
void loop() {
if (millis() - lastUpdate >= UPDATE_INTERVAL) {
lastUpdate = millis();
int smoothedValue = updateSmoothingBuffer(analogRead(POT_PIN));
int brightness = map(smoothedValue, 0, 1023, 0, 255);
analogWrite(LED_PIN, brightness);
Serial.print("Smooth: ");
Serial.print(smoothedValue);
Serial.print(" -> Brightness: ");
Serial.println(brightness);
}
}
void initializeSmoothingBuffer() {
for (int i = 0; i < SMOOTHING_SAMPLES; i++) {
potBuffer.values[i] = 0;
}
}
int updateSmoothingBuffer(int newValue) {
potBuffer.total -= potBuffer.values[potBuffer.index];
potBuffer.values[potBuffer.index] = newValue;
potBuffer.total += newValue;
potBuffer.index = (potBuffer.index + 1) % SMOOTHING_SAMPLES;
potBuffer.average = potBuffer.total / SMOOTHING_SAMPLES;
return potBuffer.average;
}

2. Object-Oriented Approach

class LEDBrightnessController {
private:
int potPin;
int ledPin;
int lastBrightness;
public:
LEDBrightnessController(int pot, int led) : potPin(pot), ledPin(led), lastBrightness(0) {
pinMode(ledPin, OUTPUT);
}
void update() {
int potValue = analogRead(potPin);
int brightness = map(potValue, 0, 1023, 0, 255);
// Only update if significant change
if (abs(brightness - lastBrightness) > 2) {
analogWrite(ledPin, brightness);
lastBrightness = brightness;
}
}
int getBrightness() {
return lastBrightness;
}
};
LEDBrightnessController led1(A0, 9);
LEDBrightnessController led2(A1, 10);
void setup() {
Serial.begin(9600);
}
void loop() {
led1.update();
led2.update();
Serial.print("LED1: ");
Serial.print(led1.getBrightness());
Serial.print(" LED2: ");
Serial.println(led2.getBrightness());
delay(10);
}

Proyek Tantangan

LevelNama ProyekDeskripsi
PemulaDimmer LampuKontrol kecerahan LED dengan potensiometer
PemulaColor Mixer3 potensiometer untuk RGB LED
PemulaMood LightBrightness berubah otomatis dengan speed control
MenengahMulti-Zone DimmerBeberapa LED dengan zona brightness berbeda
MenengahSunrise SimulatorLED brightness mengikuti kurva sunrise
MenengahInteractive DisplayBrightness responds to ambient light sensor
LanjutanPWM Frequency ControlKontrol frequency dan duty cycle
LanjutanLED Strip ControllerKontrol brightness LED strip
LanjutanAudio ReactiveBrightness follows audio input

Kesimpulan

Kontrol kecerahan LED dengan potensiometer adalah introduction yang excellent ke dunia analog input dan PWM output. Tutorial ini mengajarkan konsep fundamental yang akan digunakan dalam banyak project Arduino:

  • Analog Input: Membaca sensor dengan nilai variabel
  • PWM Output: Mengontrol device dengan sinyal analog-like
  • Mapping Values: Konversi antara different ranges
  • Signal Smoothing: Mengurangi noise dan jitter

Yang terpenting, project ini menunjukkan bagaimana hardware dan software bekerja sama untuk menciptakan interface yang natural dan responsif. Kontrol kecerahan adalah stepping stone menuju project yang lebih kompleks seperti motor control, audio processing, dan sensor interfacing.

Eksperimen dengan berbagai nilai mapping, smoothing algorithms, dan gamma correction akan membantu memahami nuansa dalam analog signal processing. Pengalaman ini invaluable untuk project-project future yang melibatkan sensor dan actuator.

Langkah Selanjutnya

Setelah menguasai kontrol kecerahan LED, siap untuk:

  1. Servo Motor Control: PWM untuk kontrol posisi servo
  2. Sensor Reading: Membaca various analog sensors
  3. Data Logging: Recording dan analyzing sensor data
  4. PID Control: Advanced control algorithms
  5. Communication: Sending analog data via serial/wireless

Resource Tambahan