How to Control LED Strips With Arduino – Part 2: RGB LED Strips

by dziubym in Circuits > Arduino

366 Views, 5 Favorites, 0 Comments

How to Control LED Strips With Arduino – Part 2: RGB LED Strips

3 colors.png

In Part 1, we learned how to control single-color LED strips using Arduino, MOSFETs, buttons, and potentiometers. Now in Part 2, we’re diving into RGB LED strips — how they work, how to wire them, and how to use Arduino to create vibrant, full-color lighting effects.

We’ll start with a single RGB LED segment directly powered by the Arduino and finish with a full-length RGB strip controlled via MOSFETs and external power, including smooth color transitions and PWM-based brightness control.

If you'd rather watch a step-by-step walkthrough, I've also made a video tutorial you can follow here:

🎥 https://youtu.be/PEiDzPVk-9g

Supplies

  1. Arduino Uno or Nano
  2. RGB LED strip (5V or 12V, common anode)
  3. 3 × N-channel MOSFETs (e.g., IRLZ44N)
  4. 3 × 220Ω resistors
  5. 3 × 10kΩ resistors
  6. Breadboard
  7. Jumper wires
  8. Potentiometer
  9. External power supply (5V or 12V depending on your strip)
  10. DC barrel jack adapter (female)
  11. Screw terminal block (optional)

Understanding RGB LED Strip Segments

RGB.png

Just like single-color strips, RGB LED strips are divided into cuttable segments. Each segment appears to contain one LED, but that “LED” is actually three tiny LEDs in one package: red, green, and blue.


Each channel (R, G, B) has its own resistor, which limits the current. The strip operates using common anode logic:

  1. 5V pad is shared positive
  2. Color channels are lit by connecting GND (LOW) to the R, G, or B pads

So to light red, you connect the R pad to GND while keeping G and B HIGH.

Wiring a Single RGB LED Segment to the Arduino

single_segment.png
1segoff.png

To begin, we’ll power just one segment of the RGB LED strip directly from the Arduino. This works because each channel only draws ~20mA, which is safe for a single pin.

🔌 Connections:

  1. 5V pad → Arduino 5V
  2. R pad → Arduino D6
  3. G pad → Arduino D9
  4. B pad → Arduino D3
🧠 Be aware: pad labels may be incorrect on cheaper strips. If color channels don’t behave as expected, swap pin assignments in code to match reality.


Simple Code to Cycle Primary Colors

1seggreen.png
1segred.png
1segblue.png

We'll now cycle through red, green, and blue, one at a time.

const int redPin = 6;
const int greenPin = 9;
const int bluePin = 3;

void setup() {
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);

// Turn all channels off (common anode: HIGH = off)
digitalWrite(redPin, HIGH);
digitalWrite(greenPin, HIGH);
digitalWrite(bluePin, HIGH);
}

void loop() {
// Red
digitalWrite(redPin, LOW);
digitalWrite(greenPin, HIGH);
digitalWrite(bluePin, HIGH);
delay(1000);

// Green
digitalWrite(redPin, HIGH);
digitalWrite(greenPin, LOW);
digitalWrite(bluePin, HIGH);
delay(1000);

// Blue
digitalWrite(redPin, HIGH);
digitalWrite(greenPin, HIGH);
digitalWrite(bluePin, LOW);
delay(1000);
}

🔍Code Highlights:

  1. Common anode strip means HIGH = off, LOW = on
  2. Colors are created by pulling just one pin LOW at a time
  3. Each color displays for 1 second


Mixing Colors Using PWM and AnalogWrite()

1segcyan.png
1segmagenta.png

To create colors like yellow, magenta, cyan, or orange, we combine PWM signals on each channel.

🔧 Understanding PWM:

  1. analogWrite(pin, value) sets PWM signal
  2. value = 255 → fully off for common anode
  3. value = 0 → fully on
  4. Intermediate values control brightness

🎨 Example: Displaying Orange

Orange is made by mixing:

  1. Red = 255
  2. Green = 160
  3. Blue = 16

Invert for common anode:

  1. Red = 0
  2. Green = 95
  3. Blue = 239
analogWrite(redPin, 0);
analogWrite(greenPin, 95);
analogWrite(bluePin, 239);
With this approach, you can generate millions of colors using different combinations!

With this approach, you can generate millions of colors using different combinations!

Now that you understand how PWM works and how we use it to mix brightness and color on common anode RGB LED strips, here’s a sketch that puts it all into practice.

#define RED_PIN 6
#define GREEN_PIN 3 // Controls actual green
#define BLUE_PIN 9 // Controls actual blue

// Array of RGB color values
const byte colors[9][3] = {
{255, 0, 0}, // Red
{ 0, 255, 0}, // Green
{ 0, 0, 255}, // Blue
{255, 160, 16}, // Orange
{255, 255, 0}, // Yellow
{ 0, 255, 255}, // Cyan
{255, 0, 255}, // Magenta
{255, 105, 180}, // Hot Pink
{255, 255, 255} // White
};

void setup() {
pinMode(RED_PIN, OUTPUT);
pinMode(GREEN_PIN, OUTPUT);
pinMode(BLUE_PIN, OUTPUT);
}

void setColorPWM(byte r, byte g, byte b) {
// Invert values for common anode strip
analogWrite(RED_PIN, 255 - r);
analogWrite(GREEN_PIN, 255 - g);
analogWrite(BLUE_PIN, 255 - b);
}

void loop() {
for (int i = 0; i < 9; i++) {
setColorPWM(colors[i][0],
colors[i][1],
colors[i][2]);
delay(2000); // Show each color for 2 seconds
}
}

What This Code Does:

  1. Defines 3 PWM pins for Red, Green, and Blue
  2. Stores 9 predefined RGB color values in a 2D array
  3. Uses a helper function setColorPWM() to:
  4. Invert values for common anode logic
  5. Apply the color using analogWrite()
  6. Loops through the entire color table, changing colors every 2 seconds
⚠️ Note: This code also takes into account the mislabeled color pads found on some cheaper RGB strips. In your case, the green and blue labels were swapped, so the GREEN_PIN and BLUE_PIN assignments reflect that correction. Always test your strip and adjust pin assignments as needed.


Controlling Longer RGB Strips With MOSFETs and External Power

MosfetRGB.png
MosfetRGB1.png

When you're ready to move beyond a single RGB segment, powering a longer strip directly from Arduino pins is no longer safe. Each additional LED segment increases current demand, and Arduino’s I/O pins can only safely supply ~20 mA per pin — not nearly enough for a full RGB strip.

To solve this, we’ll use MOSFETs to switch higher currents from an external 5V or 12V power supply, while still using Arduino to control color and brightness with PWM.

🔧 How It Works

Each RGB channel (Red, Green, Blue) gets its own N-channel logic-level MOSFET, which switches that color's negative line (the R, G, or B pad) to GND. The Arduino sends a PWM signal to the gate of each MOSFET to control brightness.


🛠️ Wiring Overview:

🔌 Power:

  1. Power Supply +V → RGB strip 5V (or 12V) pad
  2. Power Supply GND → MOSFET source pins and Arduino GND

🟢 Red Channel (example):

  1. MOSFET Drain → R pad on LED strip
  2. MOSFET Source → GND
  3. Gate → Arduino pin 6 via 220Ω resistor
  4. Gate also → GND via 10kΩ pull-down resistor

Repeat the same structure for:

  1. Green → Arduino pin 3
  2. Blue → Arduino pin 9
🧠 This time, we are not inverting the PWM signal, because the MOSFET turns the strip’s color pads on/off with a HIGH signal, not LOW like before with direct control.

🎛️ Add a Potentiometer for Brightness Control

  1. Connect potentiometer center pin to A0 (analog input)
  2. Connect sides to 5V and GND
  3. We’ll read this value to scale the brightness dynamically in the next code step

✅ Benefits of This Setup:

  1. Power-hungry LED strips draw current from a dedicated supply, not your Arduino
  2. You can safely control dozens or even hundreds of RGB LEDs
  3. Full PWM color control remains, now with safe power handling

Next, I’ll walk you through the code for smooth color transitions and potentiometer-based brightness scaling. Ready to continue?

Smooth Color Transitions With Potentiometer Dimming

xxx.png

Now that your RGB strip is controlled via MOSFETs and external power, we can take full advantage of Arduino’s PWM features. The following code creates smooth color fades and lets you adjust brightness in real time using a potentiometer.

This is a big visual upgrade over basic color cycling — the transitions are smooth, subtle, and fully responsive to your input.

💻 Code


#define RED_PIN 6
#define GREEN_PIN 3 // Swapped with blue due to labeling issue
#define BLUE_PIN 9 // Swapped with green

#define BRIGHTNESS_PIN A0 // Potentiometer analog pin

// Fade duration and step speed
const int fadeTime = 1000; // total fade time in ms
const int steps = 100;
const int delayTime = fadeTime / steps;

// Array of colors to cycle through (R, G, B)
const byte colors[][3] = {
{255, 0, 0}, // Red
{255, 160, 16}, // Orange
{255, 255, 0}, // Yellow
{ 0, 255, 0}, // Green
{ 0, 255, 255}, // Cyan
{ 0, 0, 255}, // Blue
{255, 0, 255}, // Magenta
{255, 105, 180}, // Hot Pink
{255, 255, 255} // White
};

void setup() {
Serial.begin(9600);
pinMode(RED_PIN, OUTPUT);
pinMode(GREEN_PIN, OUTPUT);
pinMode(BLUE_PIN, OUTPUT);
pinMode(BRIGHTNESS_PIN, INPUT);
}

// Set color with PWM and brightness scaling
void setColorPWM(byte r, byte g, byte b) {
int potValue = analogRead(BRIGHTNESS_PIN); // 0 - 1023
float brightness = potValue / 1023.0; // 0.0 to 1.0
Serial.println(brightness);

analogWrite(RED_PIN, r * brightness);
analogWrite(GREEN_PIN, g * brightness);
analogWrite(BLUE_PIN, b * brightness);
}

// Smooth transition between two colors
void fadeToColor(byte r1, byte g1, byte b1, byte r2, byte g2, byte b2) {
for (int i = 0; i <= steps; i++) {
byte r = map(i, 0, steps, r1, r2);
byte g = map(i, 0, steps, g1, g2);
byte b = map(i, 0, steps, b1, b2);
setColorPWM(r, g, b);
delay(delayTime);
}
}

void loop() {
int colorCount = sizeof(colors) / sizeof(colors[0]);
for (int i = 0; i < colorCount; i++) {
int next = (i + 1) % colorCount;
fadeToColor(colors[i][0], colors[i][1], colors[i][2],
colors[next][0], colors[next][1], colors[next][2]);
}
}

🔍 What This Code Does

  1. Cycles through a list of vibrant RGB colors
  2. Smoothly fades between each color using fadeToColor()
  3. Reads a potentiometer to control brightness live
  4. Uses analogWrite() to dim each channel based on scaled brightness
  5. Works with common cathode logic (no inversion) since we’re using MOSFETs to switch GND
⚠️ Note: This sketch accounts for a common hardware issue: the green and blue pads on some RGB strips are mislabeled. The GREEN_PIN and BLUE_PIN assignments are swapped to match actual behavior.
💡 Also important: Since we are now using MOSFETs to switch the color pads, we are driving the LEDs with a HIGH signal — not LOW as we did with the directly connected common anode setup. That means we no longer need to invert the PWM signals in the code. Just use the actual RGB values directly, as this sketch does.


Switching to a 12V RGB Strip (No Circuit Changes Needed!)

RGB12v.png
RGB12vstrip.png

One of the best things about this MOSFET-based design is that it scales beautifully — including with 12V RGB strips. If you're ready to upgrade from 5V to 12V LEDs for longer runs, higher brightness, or simply because you have 12V strips on hand, you'll be happy to know that you don’t need to change the circuit at all.

🔧 What Stays the Same:

  1. The Arduino wiring and PWM control pins (D6, D3, D9)
  2. The MOSFET gate, drain, and source wiring
  3. The use of a common GND between Arduino and external power
  4. The potentiometer connection for brightness control

🔄 What You Do Need to Change:

  1. Swap the 5V power adapter for a 12V one
  2. Connect the 12V positive line to the RGB strip’s +V pad
  3. Power the Arduino through the VIN pin, not the 5V pin:
  4. The VIN pin uses Arduino’s onboard voltage regulator to safely drop 12V down to 5V
  5. Do not connect 12V directly to the Arduino’s 5V pin — it will destroy the board
  6. Keep the potentiometer powered by 5V, not 12V. It still connects to Arduino’s regulated 5V line.

🧠 Why This Works:

The strip’s internal resistors already account for the 12V supply. The color pads still work the same way — sinking current through MOSFETs connected to ground. You’re simply feeding the strip higher voltage and letting the internal circuit handle it.

Project Recap + Real Circuit + Support

col2.png
col1.png

Let’s close this project with a look at the actual working circuit and a quick summary of what you’ve accomplished.

What You Built

  1. Learned how RGB LED strips are structured
  2. Controlled a single segment directly from the Arduino
  3. Scaled up safely using MOSFETs and external power
  4. Wrote code for:
  5. Solid color display
  6. Color cycling using a table
  7. Smooth transitions with brightness control
  8. Easily upgraded from 5V to 12V strips with no circuit changes

You now have a solid, modular setup you can reuse in all sorts of Arduino lighting projects — from ambient room lights to smart home installations.

☕ Support My Work

If you enjoyed this project and want to support more tutorials like it, consider buying me a coffee over at Ko-fi.

👉 https://ko-fi.com/mariosideas

Your support helps keep these deep-dive, no-fluff Arduino tutorials coming.

📺 Coming Up Next…

This was Part 2 of my 3-part LED strip series. In Part 3, we’ll explore individually addressable RGB LEDs (like WS2812 or NeoPixels) — unlocking the ability to animate each LED independently with color effects, patterns, and more.

Follow or bookmark the LED Strip Series Playlist and stay tuned!