Connecting a standard 5mm indicator LED on Arduino requires nothing more than a 220Ω resistor and a GPIO pin. However, when you scale up to drive a high-power LED on Arduino—such as a 40W architectural COB strip or a 100W high-bay fixture—you immediately leave the realm of simple logic circuits and enter the domain of power electronics. You cannot source this current directly from a microcontroller; an ATmega328P pin maxes out at 20mA, and the total package limit is 200mA.

The direct answer for scaling up is to use the Arduino’s PWM output to switch a logic-level MOSFET (like the IRLZ44N) or a dedicated constant-current sink IC (like the TLC5940), which in turn controls a switched-mode constant-current LED driver (such as the Mean Well XLG series). But specifying the right driver and dimming topology requires understanding circuit impact math, inrush current, and thermal constraints. Here is the bench-tested blueprint for doing it right.

Sizing the Driver and Understanding Circuit Math

LEDs are current-driven devices. While you can use a simple resistor for low-power indicators, high-power fixtures require a constant-current driver to prevent thermal runaway. When selecting a driver, you must match the fixture's forward voltage (Vf) and required current, while also accounting for luminous efficacy.

Fixture Type Nominal Wattage Efficacy (lm/W) Total Lumens Recommended Driver (120V AC In)
24V COB LED Strip (per 5m reel) 50W 115 lm/W 5,750 lm Mean Well XLG-50-H (2.1A)
High-Bay UFO Industrial 150W 140 lm/W 21,000 lm Mean Well HBG-150-1050 (1.05A)
Architectural Downlight 12W 90 lm/W 1,080 lm Mean Well PCD-16-350 (350mA)
Horticulture Grow Light Bar 80W 130 lm/W (PAR weighted) N/A (PPFD metric) Mean Well ELG-100-C-2100 (2.1A)

When wiring these drivers to your mains supply, you must account for circuit impact math, specifically Power Factor (PF) and inrush current. LED drivers are switched-mode power supplies (SMPS). A 50W driver with a 0.9 PF draws 55.5 VA from the wall. On a 120V AC circuit, that is a steady-state RMS current of roughly 0.46A.

However, the internal bulk capacitors of the SMPS act as a dead short the moment AC voltage is applied. According to DigiKey's technical guidelines on LED drivers, inrush current can easily spike to 20 to 50 times the steady-state current for the first 1 to 3 milliseconds. For our 50W driver, a 30x inrush multiplier means a momentary spike of nearly 14A. This is why you should never use a standard mechanical relay or a cheap 5V relay module to switch the AC side of an LED driver; the contacts will weld shut or pit rapidly. Instead, switch the DC output side using a MOSFET, or use a zero-crossing Solid State Relay (SSR) rated for high inrush loads if AC switching is mandatory.

Dimmer Compatibility and Fixing PWM Flicker

Dimming a high-power LED on Arduino is where most hobbyist builds fail. You have two choices: dim the AC mains side, or dim the DC low-voltage side. Dimming the DC side via PWM is vastly superior for microcontroller integration, but both have strict compatibility criteria.

AC Dimmer Compatibility Criteria:
If you are retrofitting a smart-home wall switch to control the AC input of your driver, you must use a trailing-edge (ELV) dimmer. Leading-edge (TRIAC) dimmers chop the leading edge of the sine wave, which causes harsh inrush spikes and audible buzzing in SMPS transformers. Crucially, you must verify the dimmer's minimum load requirement. Many ELV dimmers require a 10W to 20W minimum load to keep their internal switching transistors latched. If your Arduino-controlled fixture draws only 8W at low dim levels, the dimmer will drop out, causing severe strobing.

For 95% of Arduino and ESP32 projects, you should leave the AC side fully energized and use the microcontroller to apply a PWM signal to the driver’s dimming wire (often labeled DIM+ and DIM-).

Why Flicker Happens and the Fix

If your high-power LED flickers on camera, or if you see visible banding when moving your eyes quickly across the room, you are experiencing PWM aliasing or control-loop instability.

  • The Cause: The default analogWrite() function on an Arduino Uno runs at roughly 490Hz on pins 5 and 6, and 980Hz on other PWM pins. This frequency is too low for modern camera shutters and can sometimes conflict with the internal feedback loop of cheap constant-current drivers, causing a beat-frequency flicker.
  • The Fix (Arduino Uno/Nano): Use the TimerOne library to override the hardware timer and push the PWM frequency to 2kHz or 3kHz. Timer1.initialize(500); sets a 500µs period (2kHz), which is well above the visible flicker fusion threshold and safe for most drivers.
  • The Fix (ESP32): The ESP32’s LED Control (LEDC) peripheral is purpose-built for this. Use ledcSetup(channel, 3000, 10) to set a 3kHz frequency with 10-bit resolution, yielding smooth, flicker-free dimming.

If your driver does not accept PWM and instead requires a 0-10V analog dimming signal, you cannot just filter a PWM pin with a simple RC low-pass filter and connect it directly. The driver's dimming input has a specific input impedance that will load down your RC filter, skewing the voltage. You must buffer the filtered PWM signal using a rail-to-rail op-amp (like the MCP6002) or use a dedicated I2C DAC like the MCP4725 to generate a clean 0-10V reference.

Thermal Constraints and Enclosure Rules

Power electronics generate heat, and embedding an Arduino, a MOSFET, and an LED driver inside a sealed enclosure is a common point of failure. You must calculate the thermal budget before printing your enclosure or wiring your junction box.

Let’s look at the switching element. If you use an IRLZ44N logic-level MOSFET to switch the 2.1A output of a Mean Well XLG-50-H driver, you need to check the Rds(on) (drain-source on-resistance). At a gate-source voltage (Vgs) of 5V (standard Arduino GPIO output), the IRLZ44N has an Rds(on) of approximately 22mΩ (0.022Ω).

The power dissipated as heat in the MOSFET is calculated as:
P = I² × Rds(on)
P = (2.1A)² × 0.022Ω = 4.41 × 0.022 = 0.097W

At 2.1A, the MOSFET will barely get warm. However, if you scale up to a 150W high-bay fixture pulling 10A, the math changes drastically:
P = (10A)² × 0.022Ω = 100 × 0.022 = 2.2W

Dissipating 2.2W through a TO-220 package without a heatsink will cause the silicon junction to rise roughly 62°C above ambient (based on a typical 62°C/W junction-to-ambient thermal resistance). If your enclosure ambient is 35°C, the MOSFET case will sit at nearly 100°C, risking solder joint failure and thermal throttling. The fix: Always use a small clip-on heatsink for loads above 5A, or parallel two MOSFETs to halve the effective Rds(on) and split the thermal load.

Furthermore, constant-current LED drivers have strict ambient temperature derating curves. As noted in All About Circuits' guide to LED drivers, most premium drivers maintain 100% output up to 40°C or 50°C ambient, after which they linearly derate their current output to protect internal electrolytic capacitors from drying out. If you are mounting the driver and the Arduino in a sealed NEMA 4X outdoor enclosure or a 3D-printed PETG box, you must provide passive ventilation slots (covered with breathable IP68 membrane vents) or a thermal pad bridging the driver's aluminum casing to the outside environment. Never pot a high-power LED driver in epoxy unless it is specifically rated for potted applications; the trapped heat will destroy the switching IC.

By respecting the circuit math, selecting the correct trailing-edge or DC-side PWM topology, and managing your thermal envelope, you can reliably scale your microcontroller projects from breadboard blink tests to permanent, architectural-grade lighting installations.