ShiftPWM library on Spark

I need to use the the ShiftPWM library ( on the Spark, but I once I remove the #include Arduino.h I’m getting a bunch of error. If I don’t remove the #include Arduino.h, I’m getting an error because he is looking for a files that don’t exist. I have also try to add the Arduino.h in my files, but I’m getting a lot of errors because there is a lot of files that are include in Arduino.h that don’t exist. Here’s a part of the errors that I’m getting:

CShiftPWM.cpp: In constructor 'CShiftPWM::CShiftPWM(int, bool, int, int, int)':
CShiftPWM.cpp:39:18: warning: unused variable 'm_PWMValues' [-Wunused-variable]
unsigned char * m_PWMValues=0;
CShiftPWM.cpp: In destructor 'CShiftPWM::~CShiftPWM()':
CShiftPWM.cpp:44:21: error: 'free' was not declared in this scope
free( m_PWMValues );
CShiftPWM.cpp: In member function 'bool CShiftPWM::IsValidPin(int)':
CShiftPWM.cpp:53:3: error: 'Serial' was not declared in this scope
Serial.print(F("Error: Trying to write duty cycle of pin "));
CShiftPWM.cpp:22:51: error: ISO C++ forbids declaration of 'type name' with no type [-fpermissive]
#define F(string_literal) (reinterpret_cast<const __FlashStringHelper *>(PSTR(string_literal)))
CShiftPWM.cpp:53:16: note: in expansion of macro 'F'
Serial.print(F("Error: Trying to write duty cycle of pin "));

Thanks for your help !

Although the Spark is very much like an Arduino, it isn’t a one on one copy. Due to hardware differences, a port is often required. This seems to be one of those cases. I’m not sure how difficult this would be, but I know someone who probably does. @peekay123 might be able to help you with this one, since he’s already ported a lot of libraries.
Best of luck!

@tchinou1, I looked at the library and it is VERY arduino hardware dependent. The SparkIntervalTimer library could be used for the timer interrupts and the bit I/O adapted to the Spark but it is not trivial. I have a lot on my plate already so I could not get to this library for some time. :smile:

Let’s ping the library author - @Elco! :slight_smile:

@tchinou1 - on the spark there is the Neopixel library which can address LEDs individually yet requiring only gnd, Vcc and data lines. Could that work for you?

@mdma, I believe this library avoids using more costly neopixel strings and instead drives cheaper RGB (only, not WS281x) strings. Is that the idea @tchinou1?

That’s right peekay, I just wonder if using the simpler (but more expensive) WS281x’s is an option for @tchinou1. With all the supporting hardware required for shiftPWM I wonder if that is still a cheaper solution?

Hey Guys,

I indeed wrote ShiftPWM, but have not given it much attention after BrewPi took off.

ShiftPWM is a software PWM library for AVR, that uses shift registers for outputs.
By using some clever assembly it is very efficient in comparing the duty cycle setting with a counter for each output and putting the result (1 or 0) onto the shift register pins.
This takes only 3 instructions or 5 clock cycles per LED. This allows you to software PWM for example 128 LED’s at 256 brightness levels or 512 LEDs at 64 brightness levels.

Because of this assembly hack, ShiftPWM does not easily translate to other platforms and requires porting. The same hack (rotating the compare result into a byte via the carry) might work on other platforms too, but I have not looked into it. The high level functions like SetHSV or SetRGB should be easy to port, but the setup functions and interrupts need more work and knowledge of how the AVR/ARM executes instructions.

It is also not compatible with the WS281x, it turns raw pins on and off through the shift registers, it does not control PWM drivers.

There is a teensy port here:
But using hardware SPI has not been ported to the teensy yet.

If someone is willing to pick up ShiftPWM, I am happy to open source all hardware as well. I just have not found the time to do it. I have some code lying around for a matrix version as well and made some LED matrix boards. I just don’t have time for it.

Since I was just reviewing your site @Elco I’ll give the TL,DR; version of your above post:

ShiftPWM uses Interrupts to generate SPI to continuously control shift registers (like a 74HC595) that emulates PWM outputs for driving many LEDs from a few pins.  


A lot of work went into that library! Nice job :wink:

@tchinou1 If you want to control LED strips, NeoPixels would be much easier to install, just unroll and attach power. But I can see plenty of reasons you might want to roll your own strip or cluster of LEDs. There are probably a bunch of easy SPI to I2C PWM IC’s that can do this sort of thing as well with no processor overhead.


Neopixels would indeed be a lot easier if you want to control just a strip of 20mA LEDs.

A reason for using ShiftPWM could be for example if you want to use 350mA LED’s or longer pieces of LED strips.
People might also use it for the easy to use SetRGB and SetHSV functions, but these should be easy to take out:

A HSV function is very useful for rainbow effects, as you can just increment the hue in a for loop for a color shift.

The HSV function sounds awexome… kind of like the NeoPixel color wheel function which also just takes one byte to set the color. The thing I don’t understand after looking at that HSV function for a minute is how does it work? I mean… what is top-bottom and rising and falling representing, related to the PWM duty cycle?

I think this image will clear it up. It is what I used when I implemented the function:

Top bottom and rising refers to the lines in that image.


Thank you for all your answers ! I need it to use it with multiple RGB leds, not with a led strip. As I can see, this is not going to be easy to implement on Spark. I might stick to an arduino for the led part and use a spark for a MySQL part. With a bridge between the Spark and the Arduino this should work fine.

However, if someone finally make the ShiftPWM library work on Spark let me know !

That sounds like a great solution @tchinou1!

@tchinou1, I had ported a software-based PWM library that allows any pin on the Spark to be used. Not sure if that would be helpful if it was combined with the HSV stuff. :smile: