Controlling RGBW Light Strips With an Arduino

We have been asked before for LED strips that can change color and be dimmed at the same time. While we don’t have a product that can do this by itself, you can certainly set up a way to accomplish this. Specifically, I found a way to drive a 24V strip using MOSFETs utilizing the Arduino development board. There are a few topics to cover before I provide my example.

MOSFET Selection

MOSFETs are incredibly versatile components and it can be challenging at first knowing what to get or how to use them. Since this post is specifically using Arduino as a processing unit for control, you have to select a MOSFET capable of being driven by 5V or less Vgs (voltage from gate to source). Next, be aware of how much current and voltage the MOSFET can handle. If you are driving something with more current or voltage than the transistor, it will burn up both the transistor and potentially the Arduino if the gate insulation layer fails. Next, there is a formula to know when to use a heatsink on the FET. First, you have to calculate the power that will be passing through the transistor from drain to source.

P_{ds}=I_{ds}^{2}*R_{dson}

In other words, Ids is going to be how much current the load will draw while Rdson is the value of resistance across drain to source when activated using the gate voltage applied. The following information is then needed: maximum junction temperature rating (datasheet), ambient temperature (room temperature), and something in the datasheet called junction to ambient to thermal resistance. Here is the equation:

P_{Max}=\frac{(T_{JMax}-T_{Ambient})}{R_{\theta JA}}

Pmax is the maximum power the transistor can handle before needing a heatsink. Note that at most FETs have some maximum rating at a specific ambient temperature listed. This means that you have to force that temperature before you can get that maximum wattage across Rdson. The equation above is for derating above that temperature. Once you know what you are going to control, it’s important to check how hot the FET will become depending on what the application needs. You can also calculate the maximum current using the Pmax equation using the same power equation since you have a power rating and Rdson. Other factors include pinout and size of transistors (if that matters to you) and the value of Rdson. Rdson will be highly application-specific, however, in general, a lower Rdson means you are looking for a minimal current reduction while a higher Rdson means you don’t care as much about current reduction.

Circuit Design: Discussion on Values

Here is my setup:


In my diagram, I connected the gates of the MOSFETs to pins capable of PWM so that I can control dimming. Here is a blog article I wrote about PWM if you are unfamiliar with the technology: What is PWM? I found out 300 Ohms was sufficient by accident. I first bought 500 Ohm resistors but they were far too large as the current and voltage dropped too much to activate the MOSFETs. Luckily, I had extra smaller resistors lying around and kept trying different values. I would recommend a 1kOhm potentiometer in line with one transistor gate and adjust it until one of the colors on the LED strip works for those who are just learning to use FETs. I tested each strip color one at a time through each wire to make sure I understood the MOSFETs.

I chose FQP30N06L-ND since the Rdson is pretty low and the driving voltage can be 5VDC. As for the power supply, I only wanted to test one light color at a time. The strip has built-in resistors to control the current so I just needed to match the voltage and get a supply with enough capacity. 993-1302-ND is capable of 24VDC with a maximum rating of 0.650mA. If you want to use all four colors at the same time, you will need a supply at least capable of 2.36A or more (for the part I bought). Each LED strip will have different ratings, but here is what to look for as an overview:

  • Forward Voltage: You need a supply that matches this voltage or above, but if it is above you need to regulate or reduce it to the right voltage.
  • Recommended LED Current: This usually is listed as a "test" current in our parameters. Be aware if there is a max current listed too. If you want to use one color at a time, you only need to know the current rating of that color. If you want to use all the colors, you need to know all the current ratings of each color (you need to add them if you are using them at the same time).
  • Power Consumed: Remember the max power equation I discussed to make sure you don't need a heat-sink.
  • MOSFET Drive Voltage: Whatever you are using to drive the FET needs to match Vgs parameters or come close to that.
  • Rdson: Value for MOSFET to look at to see how much current will drop (important for some applications).
  • Power Supply: I just used a basic wall supply, however, it may be better to get an LED driver with a constant voltage. Be aware of the current required, I just designed my programs to only use one color at a time so I never exceeded my supply's max.
Here is a Bill of Materials for my setup for experimenting:
Brief Description Digi-Key Part Number Manufacturer Part Number Quantity
Res 300 Ohm 1/2W 5% Axial CF12JT300RCT-ND CF12JT300R 4
MOSFET N-CH 60V 32A TO-220 FQP30N06L-ND FQP30N06L 4
IP20 Light Strip 24V RGBW 3000K 2007-AB-FA02408-19712-8A1-ND AB-FA02408-19712-8A1 1
AC/DC Wall Mount Adapter 24V 16W 993-1302-ND PSA15A-240P6 1
Conn Jack R/A PCB 5.5X2.1MM 839-1516-ND 54-00133 1
Pot 10K Ohm 1/2W Plastic Linear 987-1665-ND P260P-D1AS2AB10K 1
Note: The next three parts are recommended if you are using an Arduino and for making wiring to a solderless breadboard easier.
Brief Description Digi-Key Part Number Manufacturer Part Number Quantity
Conn Barrier Strip 5Circ. 0.375" WM5723-ND 0387200205 1
Arduino Uno R3 ATMEGA328P Eval 1050-1024-ND A000066 1
USB A-Male To B-Male Cable 1’ TL1205-ND UR022-001 1

Finally, for fun, here is a program I wrote to make sure I wired things correctly and if PWM works on MOSFETs:

int anPin = A0; //setup input pin for analog read
int pwm1 = 11, pwm2 = 10, pwm3 = 6, pwm4 = 5; //set var names for output pins, I am using them for PWM so I named them accordingly
bool upColor = 0; //flag for updating color
int colState = 1; //red = 1, green = 2, blue = 3, white = 4
void setup() {
  setPinStates(pwm1, pwm2, pwm3, pwm4, OUTPUT); //call function to set pwm output pins
  pinMode(anPin, INPUT);
  Serial.begin(9600);
}

void loop() {
  int val = analogRead(anPin); //update the analog value right at the beginning of loop
  val = map(val, 0, 1023, 0, 255); //map values of analog read to the available range for analogW write
  Serial.println(val);
  switchColors(val); //run function to see if the value drops to zero, I want to switch colors at 0 for fun
  Serial.println(colState);
  switch(colState) {
    case 1: //red = 1, so have the analog write pwm1 with the mapped value
      analogWrite(pwm4, val);
      multWriteOther(pwm1, pwm2, pwm3, LOW);
      break;
    case 2: //green = 2, analog write to pwm2 with mapped value
      analogWrite(pwm3, val);
      multWriteOther(pwm1, pwm2, pwm4, LOW);
      break;
    case 3: //blue = 3, analog write to pwm3 with mapped value
      analogWrite(pwm2, val);
      multWriteOther(pwm1, pwm4, pwm3, LOW);
      break;
    case 4: //white = 4, analog write to pwm4 with mapped value
      analogWrite(pwm1, val);
      multWriteOther(pwm4, pwm2, pwm3, LOW);
      break;
    default:
      break;
  }
  if(val > 0) //code to reset upColor back to 0 for the next color if the analog reaches 0.
  upColor = 0;
}

void setPinStates(int p1, int p2, int p3, int p4, bool os1) { //quick function to set pin states all at once
  pinMode(p1, os1);
  pinMode(p2, os1);
  pinMode(p3, os1);
  pinMode(p4, os1);
}

void switchColors(int value) { //function that uses the value to switch colors (uses new MOSFET basically)
  if(value == 0) { //if the value read now becomes zero, the following happens:
    while(upColor == 0 && value == 0) { //activate a loop to ensure followings steps happen; uses a boolean flag as a "check" that updates whenever a new analog value above zero is read
      int temp = analogRead(anPin); //read from the analog pin, while loop would continue forever without this check
      if(temp > 0 && upColor == 0) { //check if both the temp read and upColor flag still = 0
        if(colState < 4) { //if the color state is less than 4, we can update the count by 1 and immediately update the colorstate to 1 ending the while loop
          colState += 1;
          upColor = 1;
        } else if(colState == 4) { //if the color state is at 4, need to set it back to 1 and immediately update the colorstate to 1 ending the while loop
          colState = 1;
          upColor = 1;
        }
      } else if(temp == 0) {//extra redundancy to make sure no weird addition happens to color state; keeps upColor set to 0 so while loop can keep running
      colState = colState;
      upColor = 0;
      }
    }
  }
}

void multWriteOther(int p1, int p2, int p3, bool horl){//function to make three pins go LOW, used to make sure other lights are "off" all the way between stages, don't need to blow my power supply
  digitalWrite(p1, horl);
  digitalWrite(p2, horl);
  digitalWrite(p3, horl);
}