Shiftregister,PWM and RGB LED I need help

Hello everyone!!!

I had some diffucties while driving my LEDs. First of all pay attention at my sketch:

The main idea is: that write a certain bit/channel to a shiftregister. This open or close the power supply for a certain led. You might ask how I want to manage the color, the answer is using the pwm on my 3 transistors. Each transistor stands for a certain color.

Lets talk about my problem. I was using shiftout-function to control my shiftregisters. To control my transistors i used until now the analogwrite function.

So as result my leds flickering.

I'm expecting that I'm forced to used instead of analogWrite, the digitalWrite-function but really fast. I also saw other methods like here

But for the beginner like me it's difficult to understand completely the code. Do someone know any page where it's explained really clearly step by step how to do this?

please help me


p.s. I would prefer not to use any libraries because they limit the area of action.

  1. That’s an error.

Your client does not have permission to get URL /kNpFOmYtsLMfNiOz_jdSZurYwFdw3KH_1AcmKcwki-d2df2TcXSPFCHe1c95nRIFMlrHjrDjhs8L_w8 from this server. (Client IP address:

Forbidden That’s all we know.

Have you share file?

yes it is

i hope it's works now

I can't see resistors in bases and collectors of transistors. So it's not clear what exactly the cause of flickering, could be "beating" two frequencies (PWM and RGB scan), and it's not clear what is RGB scan freq. is, how do you define it? Just running in a loop? For myself I find a code from this link really helpful for starting: For my project, I improved a speed of the SPI subroutine approximately x10 times, code posted here: LED's PWM-ed but no RGB or any other multiplexing.

There are some more links in my bookmarks, which could be usefull:

Hmm, the only solution I've heard for flickering is to throw a .1uF capacitor to ground. Why not throw one on each of your transistor sinks. If that doesn't work, then make sure you have the one that the ShiftOut diagram shows for the 74HC595's.

Now obviously you should have your PWM hooked up the the actual PWM pins. If you have that then you should not be forced to use digitalWrite "really fast". Unless you are doing your PWM in software because you don't have any PWM pins left, then you shouldn't need to use digitalWrite.

I found that when using a row/column scanned matrix of LED's that neither the analogWrite, nor shiftPWM would work very well and that the LED's would blink a lot.

What worked for me was creating my own PWM that was synchronized with the row/column scanning.


This version doesn't use shift registers, so your mileage may vary.

thanks for your quick answers. I intend to study your links.

I was able to solve the problem. The reason was bad timing. This means not that the topic is closed. There will be a lot of stuff to ask. just wait a bit.

The interesting thing I randomly found out is: > The frequency of the PWM signal is approximately 490 Hz.

source: If I devide 1 by 490 Hz I recieve ?2ms. In comparison to the refreshtime of my shiftregisters, which is 0,2ms, the analogWrite-function waste a lot of time. Does it have any sense to replace analogWrite by digitalWrite- function, which refreshes really fast? The problem is it makes really difficult to adjust the brightness

johnnycanuck the video you showed is about charlie plexing? isn't it?

Magician I'm sorry that my sketch is not precise enough, it isn't up to date. But you can be sure that I use resistors. I use a 470? resistors for each base of my 3 trasistor and I also use some for the emitters.

In comparison to the refreshtime of my shiftregisters, which is 0,2ms,

How do you know? I asked you earlier:

“and it’s not clear what is RGB scan freq. is, how do you define it? Just running in a loop?”

Does it have any sense to replace analogWrite by digitalWrite- function, which refreshes really fast?

Questin doesn’t have any sense to me. There is a way speed up analogWrite for 62.5 kHz, or even more with lower brightness resolution (<256).
If you keep current hardware configuration, multiplexing RGB, PWM frequency must be at least 256 times higher than RGB scan freq, but you need to know one to set properly another.

I used a delayMicroseconds() after shiftout. The delay time was 200µs. Why this values? It's near to the delay time of the code written by marklar.

I used a delayMicroseconds() after shiftout. The delay time was 200µs

It’s time to shift out one bit-train from SPI. Time depends on the size of train, for example with 6 shift registers it’s probably ~200 usec, in my tests with 9 SR it was close to 300 usec.
This is not a refresh rate, which is defined as “#define TIMER_DELAY 280” in his code. 280 useconds translates into 1/280 = 3.57 kHz.
Time to shift out, of course, should be less than TIMER_DELAY, or code wouldn’t be able to shift one bit-train in time before next one has to be shift.
marklar doesn’t use multiplexing, F = 3.57 / 256 = 13.95 Hz only for 256 brightness levels. That is too low (14 Hz), because code is slow, this is why only 32 brightness levels. F = 3.57 / 32 = 111.6 Hz - to avoid flickering.
With multiplexing 3x for RGB, this requirements goes up 3x, though 111.6 / 3 = 34 Hz is low again, and only way to bring it up to 60-70 (minimum) is decreasing brightness levels available to 16.
Or avoid multiplexing, and stay with 32 levels, which is o’k for most applications.
Or use faster code w/o multiplexing, which is linked in my reply above - tears of rainbow project.

if 490 Hz isn't fast enough, which I don't see why it wouldn't be. look at this, taken from SecretsOfArduino

Fast PWM Mode The following code fragment sets up fast PWM on pins 3 and 11 (Timer 2). To summarize the register settings, setting the waveform generation mode bits WGM to 011 selects fast PWM. Setting the COM2A bits and COM2B bits to 10 provides non-inverted PWM for outputs A and B. Setting the CS bits to 100 sets the prescaler to divide the clock by 64. (Since the bits are different for the different timers, consult the datasheet for the right values.) The output compare registers are arbitrarily set to 180 and 50 to control the PWM duty cycle of outputs A and B. (Of course, you can modify the registers directly instead of using pinMode, but you do need to set the pins to output.) pinMode(3, OUTPUT); pinMode(11, OUTPUT); TCCR2A = _BV(COM2A1) | _BV(COM2B1) | _BV(WGM21) | _BV(WGM20); TCCR2B = _BV(CS22); OCR2A = 180; OCR2B = 50; On the Arduino Duemilanove, these values yield: Output A frequency: 16 MHz / 64 / 256 = 976.5625Hz Output A duty cycle: (180+1) / 256 = 70.7% Output B frequency: 16 MHz / 64 / 256 = 976.5625Hz Output B duty cycle: (50+1) / 256 = 19.9% The output frequency is the 16MHz system clock frequency, divided by the prescaler value (64), divided by the 256 cycles it takes for the timer to wrap around. Note that fast PWM holds the output high one cycle longer than the compare register value.

I don't understand why you feel the need to use digitalWrite "really fast". Even the arduino reference page only uses it to do PWM at 200uS intervals, just like your math says analogWrite does, the only difference is that analogWrite is so much easier and you can do much more PWM with it than a "really fast" digitalWrite HIGH LOW switching program.

thank you funkyguy4000 and Magician. Now it's more clear to me.

Can you explain me something about the SPI Library? How can I control 10 shiftregisters with SPI? Is it the right way to do this? In the moment I have just 2 shiftreg. so it's a bit difficult for me to find out whether it works or not.

And my second question is: Does the SPI Library works only with 8-bit shiftregister? If it's true than I' can not use tlc5940. right?

digitalWrite(latchPin, LOW);


  digitalWrite(latchPin, HIGH);

Thanks in ahead

I'm not familiar with SPI library. Is there any advantages, that I'm not aware of, in using:

Instead of :
 SPDR = curBt;            // Start the transmission


As far as I understood SPI provide a simple communication in comparison to shiftout. You can also set the speed of SPI by using the setClockDivider() - function.

There is a much faster version of SPI, this is what marklar used. But in my opinion at the beginning it's difficult to have overview about the whole code.

Note: shiftreg_1, shiftreg_2, etc. are only variable which has to be shiftout to a certain shiftregister.

p.s. here is the content of the spi library. can you find out something about the bit limitation? I'm not sure but I think there is something. The author of the code used variables of the type "uint8_t" (it's a unsigned 8-bit integer -> the same as byte). What do you think?




I haven't used the SPI library directly but your code looks proper as to what it would be.

Only two? If you wish to get some more, this website has free shipping, maybe its only on orders over $5 but its cheap still. Just make sure you select the 74HC595 in the dropdown menu.

The TLC5940 doesn't use the SPI library directly, even though it uses that protocol. The TLC5940 has its own library, so that wouldn't be an issue. Personally its my favorite IC for leds. The library makes it very easy to use the commands and, aw so amazing. One thing is that its outputs can get used up very quickly, it has 16 channels which seems like a lot, but they go quickly. How many RGB leds were you hoping on using again? They must be common anode if you wish to use the TLC5940.

To be honest I'm not sure about the right IC. On the one hand the TLC5940 seems to be a good one,but on the other hand it has it's own "illness"

look here

Also a negative aspect is, you can't use SPI library, tlc5940 needs it's own. Additionally the current limitation goes only up to 130mA is not enough.

If I devide 130mA by 16 outputs, I receive 8,125mA per each output. Normally if you just write at only one channel while the other are still off you can consume more current. But I want have some free space for mistakes, because I'm not perfect in C++. (Note I use RGB LED with common anode which need up to 60mA (20mA for each color) ). If turn on all RGB LED accidentally it becomes damaged.

I saw a modification of 74HC595. It's current limitation goes up to 500mA. But the problem is

They [the chip] cannot source current so they should be connected to LED cathodes. This makes them ideal for use with LED matrices where you end up sinking 8 or more LEDs at once.

Are there other alternative ICs?

P.S. I'm not sure about the wiring of tlc5940

I read that some people used decoupling caps. Do they have any sense?

The wiring is straight-forward, you put this wire there. Since there is even a picture on google code, it makes it way easier than many other IC's. The current isn't quite an issue if you are getting the desired brightness out of your LEDs now with your setup. The TLC5940 has current supply of 120 mA for each channel when the supply voltage is above 3.6v. I've run it at 5v, i've set the Iref so that it only puts out 20mA and that is blinding for LEDs.

in reference to the "illness", why would you run it without a load in the first place. The argument doesn't make sense at all. Why would you hook up and IC entirely, turn it on, when there is no load. If there is no load, there isn't a need for the component.

The 74HC595 doesn't output any more mA than a TLC5940 can.

If you need some help with calculations and general topics, check out Grumpy_Mikes site

If you really really really actually do need a lot of current for your project, check out this video

It explains how you can up the current when using 74HC595's.

thank you very much for the links and the video, which is really helpful. I 'm sorry, I didn't mention that I used for 74HC595 additionally some transistors.

This brings me to a new question. this guy used for the columns a ULN... IC, which works as an "amplifier". I would also buy some, that can work finally with 60 mA per pin. I know that it consumes a lot of current, but in case of wrong coding, I would have some free space for mistakes. Any advice?

And finally an additional question. I already connected my arduino with TLC5940. I took a look on my arduino uno and I noticed that this connection left only 2 pwm pins over. I need 3 pwm pins to control 3 trasistors. (every transistor controls only one color).

There are two options. 1) Buy an arduino mega. (I don't need it know, mayne a bit later) 2) Redefine the pins which TLC5940 library needs. is it possible? do you have any other options?

I'm sorry, I dont understand your programming question, could you please be a bit more clear as to what you mean?

As for your pin issue, I would recommend putting the transistors on the analog pins. The analog pins can do the same thing as a PWM pin. Hence why when you want to do PWM through a digital pin, you type analogWrite(). You would do the same command I believe.

I would google "pwm on analog pins arduino". I'm not at my computer or I would do this for you. The code may be a bit different when doing it through an analog pin over a digital one, I'm not sure.

First of all lets talk about the pins. Well, driving transistors thru the analog pins is a good idea. I read in the documentation of the TLC5940 that I only need 3 pins SIN, SCLK and XLAT. TLC 5940 library use 5 pins. Can I reduce it. I don't need the pwm stuff on my tlc IC. (Page 12)

funkyguy4000 what I meant with the first question is: do you know a good "amplification" IC (sorry I don't know how they are called)? Which I can attach in addition to my tlc5940? ULN... I don't know which one. The one criteria is: it should output current more than 60 mA per pin. Is it possible ?


p.s. funkyguy I found what you meant