Project Overview

This project walks you through building a PWM-based LED dimmer using an Arduino Uno and a potentiometer. You'll control LED brightness smoothly by turning a knob — and in the process, you'll learn about Pulse Width Modulation (PWM), analog-to-digital conversion, and basic circuit assembly.

Difficulty: Beginner | Time: 30–60 minutes | Cost: Under $10

What Is PWM?

Pulse Width Modulation (PWM) is a technique for simulating analog output using digital signals. Instead of varying voltage directly, PWM rapidly switches the output ON and OFF. The ratio of ON time to total cycle time is called the duty cycle:

  • 100% duty cycle = LED fully ON
  • 50% duty cycle = LED at half brightness
  • 0% duty cycle = LED fully OFF

The Arduino's analogWrite() function handles this automatically on PWM-capable pins (marked with ~).

Components You'll Need

  • Arduino Uno (or compatible board)
  • 1× LED (any color; 5mm standard)
  • 1× 220Ω resistor (protects the LED)
  • 1× 10kΩ potentiometer
  • Breadboard
  • Jumper wires
  • USB cable for Arduino

Circuit Wiring

  1. Connect the potentiometer: left pin to 5V, right pin to GND, middle (wiper) pin to Arduino A0.
  2. Connect the 220Ω resistor from Arduino pin ~9 (a PWM pin) to the LED's anode (longer leg).
  3. Connect the LED's cathode (shorter leg) to GND.
  4. Double-check: GND on the Arduino connects to the breadboard's negative rail.

Tip: Always include the current-limiting resistor with your LED. Without it, you risk burning out both the LED and the Arduino's output pin.

The Arduino Code

Open the Arduino IDE and enter the following sketch:


int potPin = A0;     // Potentiometer connected to analog pin A0
int ledPin = 9;      // LED connected to PWM pin 9
int potValue = 0;    // Variable to store pot reading
int brightness = 0;  // Variable for LED brightness

void setup() {
  pinMode(ledPin, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  potValue = analogRead(potPin);           // Read pot: 0–1023
  brightness = map(potValue, 0, 1023, 0, 255); // Scale to 0–255
  analogWrite(ledPin, brightness);         // Set LED brightness
  Serial.println(brightness);             // Optional: monitor values
  delay(10);
}

How the Code Works

  • analogRead(A0) reads the potentiometer and returns a value from 0 to 1023.
  • map() scales that range to 0–255, which is what analogWrite() expects.
  • analogWrite(9, brightness) sets the PWM duty cycle on pin 9, controlling LED brightness.
  • The optional Serial.println() lets you watch values change in the Serial Monitor.

Upload and Test

  1. Connect your Arduino to your computer via USB.
  2. Select the correct board and port in the Arduino IDE (Tools menu).
  3. Click Upload.
  4. Turn the potentiometer knob — the LED should smoothly dim and brighten.

Taking It Further

Once you have this working, try these enhancements:

  • Replace the single LED with an RGB LED and control each color channel independently.
  • Add a push button to cycle through preset brightness levels.
  • Control multiple LEDs to create a simple lighting controller.
  • Use a MOSFET (like the 2N7000) to control higher-power LED strips from the same PWM signal.

Key Concepts Learned

  • How PWM simulates analog control with digital signals
  • Reading analog sensors with analogRead()
  • Protecting components with current-limiting resistors
  • Using map() to scale value ranges in Arduino sketches