ShiftPWM is a software PWM library for Arduino. It uses the SPI to drive shift registers in the most efficient way possible. This makes it possible to control 768 LED’s at 32 brightness levels for a fraction of the price of dedicated led drivers. Code for HSV to RGB conversion is included for easy color shifting.
What is ShiftPWM?
ShiftPWM is a library for Arduino to control many PWM outputs using shift registers (for example the 74HC595). I wrote it for my job at the Electronics Atelier of Industrial Design at the Technical University of Eindhoven, where I often got the request to individually control the brightness of many LED’s.
The dedicated IC’s for PWM, for example the TLC5940, are expensive. Generating the PWM in software costs a few CPU cycles, but allows you to use much cheaper hardware. ShiftPWM does this very efficiently, allowing you to control up to 768 outputs with ease.
ShiftPWM computes the outputs in a timer interrupt and uses the SPI to control the shift registers as fast as possible.
Features of the library:
- Control the duty cycle of many PWM outputs in a single shift register chain.
- Easily configure frequency, number of registers and number of brightness levels.
- Outputs can be inverted for common anode RGB LED’s
- Function to print information on timer settings and interrupt load to the serial port.
- Switches to timer2 if timer1 is in use by the servo library
- Checks for input to functions that is out of range and prints error messages to the serial port
- Can be placed in the libraries directory of Arduino
- Includes an example which can be opened in Arduino via file->examples
- Example includes HSV to RGB function for easy color shifting with RGB LED’s.
How fast is ShiftPWM?
ShiftPWM computes and transfers the bits for one shift register in just 43 clock cycles. The load on your program can be calculated by the following formula:
- Load = Interrupt frequency * interrupt duration / clock frequency
- Interrupt frequency = PWM frequency * number of brightness levels
- Interrupt duration = 112 + number of shift registers * 43 clock cycles.
- In one formula: L = F*(Bmax+1)*(112+43*N)/F_CPU
Here is an example of the load on a 16 MHz Arduino Uno:
|Shift registers||Maximum Brightness||PWM Frequency||Load|
Where can I get ShiftPWM?
ShiftPWM is hosted on Google code here. You can download an archive which you can extract in your Arduino libraries directory:
New version moved to GitHub, extract to Arduino-1.0/libraries/ShiftPWM:
11-05-2012: New version on GitHub has easier to use RGB and HSV functions, support for gaps of unused pins (offset), pin grouping (RRRGGGBBBRRR… instead of RGBRGBRGB), an option to not use the SPI (2.5x slower) and new examples. Documentation will be updated soon.
How do I use ShiftPWM?
The easiest way to get started with ShiftPWM is to start from the example that comes with ShiftPWM:
- Download ShiftPWM from Google code
- Extract the archive in the library directory of Arduino.
- Restart Arduino
- In Arduino, go to File -> Examples ->ShiftPWM
Which hardware is used with ShiftPWM?
Basically just an Arduino and a chain of Shift registers. The circuit is almost the same as in the ShiftOut tutorial on arduino.cc, but it uses pin 13 as clock and pin 11 as data. You can choose the latch pin yourself, but the data and clock pins should be connected to the SPI pins MOSI(11) and SCK(13). Leave out the latch pin capacitor!
High power led driver
I have designed a ShiftPWM compatible LED driver to drive 3W RGB LED’s. It has 6 STP04CM05 LED drivers, so it can drive 24 channels at 350 mA. That’s a total of 8A per board, but of course they can be chained. I use 3 of them in my Ambilight project go get 24 independent 3W RGB LED’s. The maximum LED current can be set with a potentiometer from 60-350 mA. I designed them for my own project, but I am considering getting a small batch (100) made to sell. Let me know if you are interested.
What’s in the example?
The example that comes with ShiftPWM demonstrates the use of all ShiftPWM functions. It also includes a function to convert HSV to RGB to make it easier to work with RGB LED’s.
Here is a video of the example with 16 RGB LED’s:
The library provides the following functions:
ShiftPWM.Start(int ledFrequency, int max_Brightness)
Enable ShiftPWM with desired frequency and brightness levels.
Set or change the amount of output registers. Can be changed at runtime.
Print information on timer usage, frequencies and interrupt load.
ShiftPWM.SetOne(int pin, unsigned char value)
Set the duty cycle of one output
ShiftPWM.SetAll(unsigned char value)
Set all outputs to the same duty cycle
Fade in and fade out all outputs fast
Fade in and fade out all outputs slowly
ShiftPWM.SetGroupOf2(int group, unsigned char v0, unsigned char v1);
ShiftPWM.SetGroupOf3(int group, unsigned char v0, unsigned char v1, unsigned char v2);
ShiftPWM.SetGroupOf4(int group, unsigned char v0, unsigned char v1, unsigned char v2, unsigned char v3);
ShiftPWM.SetGroupOf5(int group, unsigned char v0, unsigned char v1, unsigned char v2, unsigned char v3, unsigned char v4);
Set a group of outputs to the given values. SetGroupOf3 is useful for RGB LED’s: each LED will be a group then.
Assumes that all groups are size x for the function SetGroupx.
If you used ShiftPWM to create something cool, please send me a link to a video. I will create a gallery page to show off all the cool projects.
Please ask support questions in the Arduino forum here