Control many PWM outputs with only 3 Arduino pins
ShiftPWM is a software PWM library for Arduino that uses shift registers to expand the number of PWM outputs. With only 3 data pins, you can control an almost unlimited amount of PWM outputs. Because ShiftPWM is a software PWM library, it is not limited by the number of hardware PWM outputs on the Arduino. Shift registers are also a lot cheaper than dedicated hardware PWM IC’s, like the TLC5940.
Easy to use
The library is written to be as easy to use as possible: It provides intuitive functions like SetRGB and SetHSV to directly set an LED to a certain color. The complexity of calculating PWM values and driving the shift registers is hidden in an interrupt.
The library comes with two examples. The easiest way to get start is to just open an example from the Arduino menu and edit it to suit your application.
To SPI or not to SPI
You can use ShiftPWM with the hardware SPI or without. Using it without the hardware SPI is about 2.5x slower, but allows you to use the SPI port for something else.
For a quick demonstration of ShiftPWM, see the video below. The video is from an older version example that comes ShiftPWM. I will upload a better and more up-to-date video soon when I get my hands on a better camera. My iPhone cannot get the exposure right when filming LED’s.
To give you an idea of how easy it is to use ShiftPWM, the movie below shows the result of this example code.
The easiest way to get started with ShiftPWM is to open one of the examples that come with the library. But first you have to install ShiftPWM.
Downloading and installing ShiftPWM
- Go to the GitHub repository the download the latest version of ShiftPWM.
- Extract ShiftPWM directory from the archive to your Arduino libraries directory (for example: \???\arduino-1.0\libraries).
Extract it with the ShiftPWM directory intact, so the result will be \???\arduino-1.0\libraries\ShiftPWM).
- Restart Arduino
- Open one of the examples from the Arduino menu (File –> Examples –> ShiftPWM –> pick one)
ShiftPWM comes with a number of options to adapt it to various LED setups. These are all set before the ShiftPWM.Start(pwmFrequency,maxBrightness) is called. Using ShiftPWM with the hardware SPI port is 2.5x faster than not using the SPI port. But if you need the hardware SPI for something else, you do have the option to use any 3 digital pins. See Using ShiftPWM to control 20mA RGB LED’s for schematic and which pins to use.
unsigned char maxBrightness = 255;
This sets the number of brightness steps. More brightness steps will give a higher load on you program. The maximum you can use is 255, because the brightness for each LED is stored as a byte. The value you choose here means fully on. Choosing a lower value only decreases the number of steps, not the actual brightness.
unsigned char pwmFrequency = 75;
This sets the PWM frequency. A frequency above 75Hz makes flickering unnoticeable in most cases.
int numRegisters = 3;
Here you set the number of 8 bit shift registers that you are using. If your setting here is lower than the actual number, your pattern will be repeated. If you are using 4 bit shift registers, still enter the number of outputs divided by 8 and rounded up.
const bool ShiftPWM_invertOutputs = false;
By setting this to true, all outputs will be inverted. If you are using common anode LED’s, you’ll set this to true. When inverting is enabled, a value of 255 will mean that the shift register output is low.
The default setting is that your RGB LED’s are connected like this: RGBRGBRGBRGB. Sometimes however it makes more sense for your hardware to connect them like this: RRRRGGGGBBBBRRRR… In that case you can set the pin grouping to 4. All RGB and HSV functions will take the grouping into account.
How much CPU-time will ShiftPWM take?
ShiftPWM works with software PWM: it calculates the value (high/low) for each shift register pin and updates all shift registers 19200 times per second (at 75Hz and 256 levels). This takes about 5 clock cycles per output pin and a bit of overhead per interrupt. Your own program will be interrupt each time to update the shift registers, so this puts a load on your program. If this load gets too high, your program will become unresponsive. You will have to choose the number of brightness levels and the frequency to keep the load at an acceptable value. With the calculator below you can estimate the load. A value of 0.5 means that 50% of the CPU time will be used by ShiftPWM.
The real value of the interrupt load can be determined at run time with the function ShiftPWM.PrintInterruptLoad(), which prints the data to the serial port.
ShiftPWM has a few built-in checks to prevent errors. Whey you try to apply settings that will cause the load to be over 0.9, it will print an error to the serial port. When you try to write to an output beyond the number of shift registers you defined, it will also print an error. So keep an eye on the serial output when working with ShiftPWM.
ShiftPWM comes with a number of useful functions to control LED’s and to debug your setup. You can find all of them in the ShiftPWM function reference.
I have written 3 articles to help you build your LED circuits. Take a look at the article for normal LED’s first, because it covers some of the basics of using ShiftPWM.
I have written separate articles for high power LED’s and LED strips. You can also buy ShiftPWM compatible boards for power LED’s and LED strips in my shop.
If you have a problem getting ShiftPWM to work, please first check this support topic on the Arduino forum.
The old ShiftPWM page
This ShiftPWM documentation was updated on August 9, 2012. You can still find the old ShiftPWM page here.