Using ShiftPWM to control RGB LED strips with Arduino

ShiftPWM can be used to let an Arduino control many LED strips individually. The available RGB and HSV functions make it very easy to do color fades and rainbow effects. Because LED strips have a higher current than single LED’s, have integrated resistors and run on 12V, they require transistors to control them.

In this article I will use my RGB book shelves as an example to explain the details of driving LED strips with ShiftPWM.

First, here is a video of my Ikea Expedit book shelves. I have glued an LED strip in every shelve and 8 strips around the top, for a total of 24 LED strips and 72 PWM channels.

What’s in an LED strip?

LED strips are very simple. An LED strip has parallel segments of 3 LED’s of a color in series with one resistor. The forward voltage, for example, of 3 green LED’s in series is 9.6V, leaving 2.4V over the resistor to control the current. Lady Ada has a great explanation of LED strips on here website here.

Because LED strips already have current limiting resistors on them, you only have to connect a 12V power supply to the ends of the LED strip. The positive 12V connection is shared by all colors and each color has a separate ground connection. If you want to turn a color on and off or use PWM to control the brightness, you have to switch this ground connection. The best way to do that is with a transistor.

Using LED strips with ShiftPWM

Shift register can only sink 20mA per pin, so they cannot be connected to LED strips directly, but they can control the transistors that switch the ground connections. You will have to use one transistor per color, just like the Lady Ada article, but you will use ShiftPWM to generate the PWM signals instead of AnalogWrite.

The main thing you will have to take into account when picking a transistor is this:

  • The maximum collector current (BJT) or drain current (MOSFET) should be higher than the maximum current of the LED strip. This current is 20mA multiplied by the number of segments.
  • The collector-emitter breakdown voltage (BJT) or drain-source breakdown voltage should be higher than the LED strip voltage.

My ShiftPWM Led Strip Driver board

Soldering a transistor behind every pin of your shift registers is a lot of work, especially if you are using a lot of channels like in my book shelves project. To save you the trouble of doing that, I have designed a board with 3 shift registers, 24 MOSFET’s and screw terminals for every input and output:

My ShiftPWM LED strip driver board: 24 PWM outputs to control 8 RGB LED strips or 24 single color LED strips.


Schematic of my ShiftPWM LED strip driver board

My board uses MOSFET’s, because they have 2 benefits over BJT’s: they don’t require a base resistor and they have a very low on resistance. They leave the full 12V for the LED strips and produce very little heat.

This board can switch 2.5A per output. The MOSFET’s have a breakdown voltage of 20V, so it is great for controlling 12V LED strips. Multiple boards can chained together to get as many outputs as you like. You can find the board in my web shop here.

The pin numbers for data, clock and latch can be found in the table below.

  • Connect VDD to 5V (NOT 12V!!)
  • and connect GND to your power supply ground directly. Your Arduino should also be connected to the same power supply GND, but don’t let the high current flow through your Arduino, use two separate wires for the Arduino and the LED strip driver.
  • Do not use the SS pin, unless you only use it as output and understand possible effects on the SPI port.
  • SDI stands for Serial Data In, this is connected to the Arduino SPI data pin
  • SDO stands for Serial Data Out, this pin can go to another LED driver board. All other signals are available on the SDO side as well, for easy chaining.
Regular Arduino / LilyPad (atmega328) Arduino Leonardo Arduino Mega Teensy 2.0 Teensy++ 2.0
Data pin (MOSI) 11 ICSP 4 51 2 (B2) 22 (B2)
Clock pin(SCK) 13 ICSP 3 52 1 (B1) 21 (B1)
Default Latch pin 8 8 8 8 8
Slave select (SS) 10 - (RX LED) 53 0 (B0) 20 (B0)
MISO pin(do NOT use!) 12 ICSP 1 50 3 (B3) 23 (B3)

Wiring and powering my book shelves

There is a total of 8 meters of LED strip in the book shelves, with 60 LED’s per meter. That is a total of 480 LED’s or 1360 single color LED’s. The LED’s are connected in series per 3, so the total current is 1360/3*20mA = 9.6A. At 12V that makes the total power 115.2W.

The LED strips are driven with 3 of my LED driver boards. The first board drives the bottom 8 shelves. The next board drivers the left side of the top (viewed from the back) and the last board drivers the right side. The boards are just sitting on the shelves and are hidden from view by the books. The wires run along the edges of the shelves and are held in place with cable clips.

The 12V wire and GND wire have to conduct 9.6A. You will have to use thick wire, otherwise you will have a voltage drop over the wire. I recommend using at least a 1.5 mm2 diameter. I used 2.5 mm2, but it will take some force to get that into a screw terminal. All wires are

A cheap computer power supply is used to generate 12V for the LED strips and 5V to power the Arduino. You will have to connect the PS_ON pin (green) of the ATX connector to the GND pin (black), which is next to it. This enables the power supply to run without being connected to a motherboard. You can also switch this connection with a transistor let the Arduino turn the power supply on and off.

Here is a picture of the back of my book shelves:

Back view of my LED strip book shelves. The power supply and Arduino are in the black box at the bottom. Every LED strip has 3 GND connections to one of the LED driver boards (top left, top right, bottom) and is connected to the 12V blue wire.
Each driver board has 5 connections: 5V, GND (thick brown wire) and data, clock, latch. The data lines are as far away from the power lines as possible. They run from the Arduino in the bottom box to the first board at the bottom, then to the left and up to the second board and finally straight across to the right board.


One of the LED driver boards, connected to the LED strips, 5V, GND and the previous and next board.
The 12V wire (blue) is not connected to the board and goes directly to the LED strips.

Driving long wires with an Arduino

When I had connected everything and tried to run a rainbow effect over all LED’s for the first time, the LED strips would flicker and appear white instead of a single color. This effect was worse for the strips later in the chain and got worse as more boards were connected. The problem was that the data and clock signal where degraded too much at the end of the chain, causing the shift registers to get out of sync or clock in the wrong data.

Longer wires will create more capacitance and pick up more noise. The Arduino by itself is not powerful enough to drive these long wires strongly enough, especially for the 4MHz clock signal. A simple, two transistor push-pull line driver circuit for the clock and latch line solved the issue. The data signal is regenerated at every shift register and did not need a line driver. With the addition of this small circuit, the performance was flawless!


This push-pull line driver greatly improves the signal quality for long signal lines. If you are using ShiftPWM with long wires put this circuit in between your Arduino and signal lines.


Whats next?

For now I just used two rainbow effects to show off the RGB book shelves, but in the future I would like to add the following features:

  • A simple control panel to choose a fading mode or constant color and intensity.
  • Bluetooth control.
  • Make the LED’s respond to music.


  1. Thanks a lot Elco. This is very helpful  informative website. I have learnt a lot with it. Keep inventing! *

  2. You never fail to impress, Elco!

    All the Best,

  3. I just solder some led strips connected on your shift PWM board. When I turn it on again I discover that one channel is shorted.(green allways on on that channel. How can this happen? I have ALL DISCONNECTED during procedure.

    • Hi Jozef,

      I am certain it is a hardware fault. It can be a fault in the board or a fault in the wiring. Do you have a multimeter? If so, can you measure the resistance to ground from that pin? Can you also check for solder shorts on that pin and on the transistor connected to the pin? You can also send me high resolution pictures so I can check myself. If it is a faulty board, I will of course replace it, but lets try troubleshooting it first.

      If you want to chat with me directly for debugging, come to the BrewPi IRC channel:

  4. Hi Elco,

    this product is what Im searching for.
    One question, is it possible to react the LED-Strips to sound?
    Maybe with Processing??

    Thank you

    • Hi Martin,

      I don’t have demo code for it, but it should be possible. I had plans to program it for my book shelves, but haven’t had the time so far.
      You could let processing do the heavy lifting (fft, etc.) or use one of these IC’s: and make it stand-alone.

      I would search hack-a-day for previous projects.


  5. What kind of MOSFETS are you using?

  6. Hello, Elco! I measure output to ground and itś a short circuit. There is avideo of what this boarg was doing before malfunction. Now I have 1 channel always on ( green on one of the beams of the star. :(
    Otherwise it works like magic.

  7. Hello, Elco!

    I don´t know where to send those high resolution pictures of malfunctioning board. Have you check YOUTUBE video? Thank you!

    • I Jozef, sorry for the late response! It looks amazing in the video!
      You can send a high res pic to my name

  8. Can I substitute in slightly different spec’d N-Channel mosfets?

    • It depends a bit on the current you are switching. Almost any mosfet will do, just check that the continous current rating is high enough.
      A very common one for example is the bs170, rated at 500mA.

  9. Hi Elco, any thoughts with regards to having the ShiftPWMs close to the Arduino and then running long cables to the LED strips, as opposed to long cables (which need line drivers) from the Arduino to the ShiftPWM and then short cables to the LEDs? Other than being less efficient on cabling?

    I’m looking to wire up a 5×5 Expedit with individual RGB LED “lamps” in each cube, so no matter which way I do it, there will be a lot of cabling…

    • Hi Theo,

      Basically, you are building the exact same thing as my RGB book shelves (see LED strip page).
      Shift registers close to Arduino is the best way to do it, because the data signal is 4Mhz. However, I have my boards about 2m away from the Arduino. You do need the push-pull circuit to be able to do that though. Summary: long wires to LED is better than long wires to shift register, but with the push-pull circuit you can do both.

  10. How do I take advantage of using hardware SPI instead of using non-SPI?

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>