Here’s a crisp, engineer-friendly guide to how a microcontroller (MCU) drives LEDs—from a single status LED to RGB strips—plus drop-in code snippets.

1) The basics: one LED on one GPIO
Idea: A GPIO pin switches current through an LED with a series resistor to set the current.
-
Wiring (sourcing): MCU pin → resistor → LED → GND
-
Wiring (sinking): VCC → resistor → LED → MCU pin (pin pulls low)
Choose the resistor
R=(VCC−VF)/ILED
-
Example @ 5 V, red LED VF≈2.0 V, I=10 mA=0.01 A:
R=(5.0−2.0)/0.01=300 Ω (pick 300–330 Ω) -
Example @ 3.3 V, red LED VF≈2.0 V, I=10 mA:
R=(3.3−2.0)/0.01=130 Ω (pick 150 Ω to be safe)
Notes
-
Don’t exceed per-pin current (often 2–20 mA) or per-port / package totals.
-
“Sinking” often lets you drive slightly more current on some MCUs.
-
Use push-pull outputs for normal LEDs; open-drain needs an external pull-up.
2) Brightness control: PWM
Idea: Keep the LED on for a fraction of time (duty cycle).
-
Frequency: ≥ 500 Hz for no flicker by eye; 1–4 kHz plays nicer with cameras.
-
Duty: 0% (off) … 100% (full bright).
Arduino (Uno, etc.)
STM32 HAL (concept)
Raspberry Pi Pico (MicroPython)
3) RGB LEDs (3 channels)
Common-cathode/anode package: drive R, G, B separately with three GPIOs + three resistors.
-
Color = mix of PWM duties on each channel.
Arduino example
4) Many LEDs: multiplex, charlieplex, or drivers
-
Row/column multiplexing: Scan rows fast; each LED sees a duty slice.
-
Charlieplexing: Uses tri-state pins; great pin efficiency, trickier firmware.
-
Driver ICs (recommended):
Use NPN/N-MOSFETs to switch rows/columns when current per line > MCU pin rating.
5) High-power LEDs (1–3 W and up)
Don’t drive directly from GPIO. Use:
-
A constant-current LED driver (buck/linear) set to the LED’s current (e.g., 350 mA).
-
MCU controls EN/PWM pin of the driver for dimming.
-
Provide heatsinking; observe LED forward voltage (often 2.8–3.6 V for white/blue).
6) Addressable LED strips (WS2812B/NeoPixel, SK6812, etc.)
-
One data wire; 5 V power; each LED has an internal driver.
-
Level shifting 3.3 V → 5 V recommended; budget power (e.g., 60 mA/LED worst case).
-
Use libraries to meet tight timings.
Arduino (Adafruit_NeoPixel)
7) Common pitfalls (and quick fixes)
-
LED reversed (flat edge/cathode to GND in sourcing topology) → flip it.
-
No resistor → LED or pin damage; always add one unless driver is constant-current.
-
Pin left as input → LED dim/always off; set OUTPUT/push-pull.
-
Too much current → lower duty/drive, increase resistor, or add a transistor/driver.
-
Flicker in videos → raise PWM frequency (2–4 kHz), or use constant-current drivers.
8) Minimal reference circuits
-
Simple indicator (sourcing): MCU pin → 330 Ω → LED → GND (5 V red LED @ ~9 mA).
-
Transistor switch (for >20–40 mA):
MCU pin → 1–10 kΩ base/gate resistor → NPN/N-MOSFET → LED chain to +V; add current-set resistor in LED path. -
Driver IC: MCU I²C/SPI → constant-current driver → LEDs (no per-LED resistors needed with many drivers).
