Go Down

Topic: ShiftPWM support topic. Latest update: Schematics, high power LED's, LED strips (Read 142747 times) previous topic - next topic


There are more issues with using a 1280. Because the memory is 16 bit wide, extra instructions are added. I can only look at the assembly now, but I'll try to get my hands on a 1280.

Hum, I think you have a misconception about the 1280 Vs 328 chips. Both have the same number of instructions, same memory widths. 1280 just has more memory size in length, not width for flash, sram, eeprom, more I/O pins, more timers, more serial ports, etc. But both use the same AVR 8 bit instruction set.


You are right. The addresses can be 16 bit, because the memory is longer. I was confusing the data and the addresses.


Hi Hernandi, I don't  understand. the result of xor get false with RGB == PWM, other is true.

00001000 rgb
01000000 pwm
01001000 result rgb < pwm

01000000 pwm
00000000 result rgb == pwm

01100000 rgb
01000000 pwm
00100000 result rgb > pwm


I got it working with SPI today and got it twice as fast.
I will do some more testing en code cleanup before I upload it here.

I took steene's advice and used rotation over carry (ror) to calculate the output byte in 32 cycles (4 per pin).

Adding a shift register now costs 43 interrupt clock cycles, which is about 5.4 clock cycles per pin   8)


Thanks for all your input. You can check out the new version at www.elcojacobs.com/shiftpwm.

You can still ask support questions in this thread though.


Jul 25, 2011, 08:01 pm Last Edit: Jul 27, 2011, 01:19 am by salsaman Reason: 1
This is fantastic-- thank you Elco!

I spent a while yesterday trying to interface with a PCA9685 to get reliable PWM output and was getting nowhere, but your library is just what I need!  It's also easier to manage 8-channel output boards for my project since I need 24 channels and want to use pretty big MOSFETs.

I wonder: is there a magic multiplier (or divisor) for the PWM frequency?  I'd like to go faster than 75Hz to avoid artifacting when in motion, but tried 150Hz in the test sketch and had odd flickering, not fading.


Hi Salsaman,

Can you be a bit more specific? then I'll try to help you.
- A schematic is easier to read than the board file
- What are you pwming? Big LED's? Motors?
- Are the shift registers running at 5v? (big mosfets often need a bit more (a small mosfet to switch the bigger mosfet).

It seems you have found a bug, thanks!
Up to 127Hz, 256 levels, 6 shift registers its all good. 128 Hz, 256 levels -> crap.
When the interrupt frequency exceeds 32768 (max of int), a variable overflows and the interrupt frequency is set to a way to low value.

I am sleepy now, more tomorrow!


Jul 26, 2011, 12:50 am Last Edit: Jul 26, 2011, 08:02 am by salsaman Reason: 1
I put together a test sketch on a breadboard with two 74HC595's driving 16 red LED's-- worked great.  I removed the RGB calls since I was just using red LED's and it worked fine.

Then I tried changing the frequency from 75 to 150, and it didn't fade, but instead flashed the LED's in an odd pattern.  Putting it back to 75, it worked great.

Should I be able to change the frequency?

The board is just for my application, sending the 595's outputs to N-channel MOSFETs to drive LED strips, not specific to ShiftPWM.  The 595 is running at 5V but I might want to run it at 3.3V later.

Update:  I posted about my successful test on my blog along with links to design files for the shift register MOSFET board.  THANK YOU ELCO!!


keep levels*frequency below 32768, until I have fixed the bug.




This library is amazing and has saved me a TON of work, thank you VERY much for all of your hard work.  Great stuff!  I would absolutely love to see some articles from you regarding optimizing and performance tweaking for Arduino. 


This library is amazing and should have been written as soon as shift registers were introduced on the Arduino website. It will save me plenty of time now that I wanted to do a high-power LED project. What I would like however is a "get" function for the array that stores the PWM values. I notice that in CShiftPWM.h there is a public variable named "unsigned char * m_PWMValues;". However I am not sure how to access this value.


You could add this to CShiftPWM.cpp:

unsigned char CShiftPWM::GetOne(int output){
    return m_PWMValues[output];

And add to CShiftPWM.h the prototype for the public member function:

unsigned char GetOne(int output);

I have designed a 24 channel LED driver board for high power LED's. The constant current outputs can be adjusted from 60 to 350 mA and it is directly compatible with the library. Size is about the same as the Arduino. The first prototype will arrive in a week. Would you be interested in such a board? It is not in production at the moment, but will be soon.


Excellent. I will make use of that get function immediately. And I would love to take a look at the board when it is done.


Loving the library, but I'm finding that I can't get decent output on serial LCDs-- character LCD backpacks from both SparkFun and Modern Device (LCD117) are printing odd characters.  I've tried using the ATmega328's built-in serial port and softwareSerial, and I get the same strange results.

Regular serial reporting seems OK though, so I'm confused.  Any clues would be appreciated!

I'm going to try stripping all serial reporting out of the library and see if I get any different results...

Go Up