Go Down

Topic: Sanity check - 8x8 RGB display with 8-bit PWM resolution (Read 5955 times) previous topic - next topic


I've seen people do a couple of RGB LEDS PWM'd, or lots of them binary switched; I've seen lots of single colour LEDs PWM'd and huge numbers binary switched, but never anything quite like this ...

So hear me out here. I'm working this idea through - already with a couple of dead end starts (ULN2803A's cannot source current, doofus).

I'm building an 8x8 grid (well it's not actually arranged like that, but it's a close enough analogy - ssshh, it's a secret!) out of RGB LEDS that I want to address individually with 8-bit (or near enough) precision - ie 256 levels for each colour. Yes, this does effectively mean that I want to PWM address 192 LEDS.

My current plan, having looked through Mike Cook's work, is to use a 74138 to demux my row select. Switching the V(led) using these demuxed lines using a TPC6108 (or similar - TBD) to drive the common anode of the 8 LEDs in that particular row.

By colour, each cathode goes to one of three TLC5916 units (8-bit shift registers that sink 120mA) with serial inputs cascaded together. This gives the us column select and colour; and it also allows me to balance the three colours against each other to set the white point.

Raster scanning across this lot, gives me the following calcs:

Assuming an update speed of 100Hz (to stop perceived flicker). With 8 rows, we need an 800Hz row clock. To give us the full 256 levels, that goes again up to 205kHz (near enough). With the arduino Uno having a clock speed of 16MHz (give or take 80 times faster), I think we might have enough cycles to get it all done.

My only concern is whether they'll be time to shift the new values into the 5916's fast enough (they claim a 30MHz I2C clock) - in fact, re-reading the datasheet now we can be shifting in the new values while the current ones are still being shown, result!

(I can't so the same way as Mike, as 3 ULN2803A darlington arrays as the sink will chew up all my pins like a neutron bowling ball, I could however use the 7442 as I don't need the enable lines or the ability to cascade them)

Any comments, advice, threats or portents of doom are greatly appreciated.


PS. There is also the pricing issue - 3 x TLC5916 @ £0.85 vs 12 x TLC5940 @ £3.31 (farnell prices as of today)


8-bit PWM will be pushing it a bit.

I've got a 8x8 red/green display controlled with one 595 shift register for rows (through PNP drivers) and one 595 register for red columns, one 595 for green columns. Thus I have to shift out 3 bytes per row update over SPI, which I seem to be able to do every 20us (50kHz) before the atmega runs out of instruction time. I have implemented 4-bit PWM (15 time slices) which means I can complete one full frame update (8 rows * 15 time slices = 120 shiftouts) in 2.4ms, or 417Hz at maximum speed. In order to leave room for processing other things, I dialed my shiftout interrupt down to only 100us (~83Hz per 4-bit-color frame) and the display is on the edge of "essentially flicker free".

8-bit PWM means 255 time slices, so you'll be shifting out 8 rows * 255 slices * 3 shift registers = 6120 bytes PER FRAME, minimum 30fps means 183kB/sec over I2C (>1.4Mbit/sec)

Consider 4-bit color gives you 4096 selectable shades (16*16*16), and the change to 8-bit will be relatively undetectable to the human eye. You want to leave some processor time for your atmega to actually perform some calculations yeah?


You could use the ULN2803s to turn off the current source for the LEDs tho, as in this crude example.
Bit more power hungry this way, the LEDs are either seeing the current or the ULN2803 output stage is seeing it.
Seems simpler at times than trying to set up switchable current sources ...
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.


A long time ago I wrote some code that did 5bit software PWM with such a matrix. It took 50% of the cpu load. Granted, the efficiency of my PWM interrupt is crap. You'll definitely need an intelligent way of producing the waveform, i.e. a bit more than just constantly switching the lines.

Good luck.


Thanks for the feedback everyone - doesn't look as if it's as cut and dry as I was hoping. Looks like a longer prototyping phase is in order  :smiley-red:

leave some processor time for your atmega to actually perform some calculations yeah?

Nah, there's nothing intensive I've got to do CPU side - everything else needs updating by the minute or by the day.

Bit more power hungry this way

Yeah, just a little. I didn't mention (I'm awful at requirements analysis) that this project is hopefully going to be battery driven, but I don't think that's going to be realistic - at 20mA I'm only going to get 25 days runtime off of alkaline D-cells.

A long time ago I wrote some code that did 5bit software PWM with such a matrix. It took 50% of the cpu load.

I guess I'll start at 1bit resolution and work my way up - see how far I can get.

Following all your posts, I did start going down one of those horrific mental tangents. "Hmm, could I make a PWM pulse train generator in 74' logic... Latching shift register, feeds DAC, Sawtooth wave generator and DAC output feed into schmit trigger/comparator and use that to drive the MOSFET switch." Then i realised I'd have to to all of that for each one of my 192 output channels. Lets not go that way.

Thinking about it some more I can add some design constraints that will give me the flexability of limiting the number of LEDS that are on at one time to a handful( <5 with error states ), so all of a sudden I'm in a different territory.

I need to think about this one... (Posting out loud here and without really thinking things through - I'll probably have a facepalm moment as soon as I've pressed post, but here goes)

2 x 74138 driving 16 MOSFET switches that act as row and column selectors deliverying V(led) (pre-LED common anode) to then simply have 3 MOSFETS switches to which all the cathodes of each colour type are linked to and then the PWM train is driven direct from the mega.

How does that sound? We can get the 8-bit resolution cycling through the lights and the limit will come as we keep adding more lights on at the same time as we may drop below 100Hz refresh rate and have some flickering come in.



I don't (yet) have much experience with LEDs but I do know that 8 bit (24 bit full color precision) is way beyond what the eye needs for most purposes. If doing PWM at 6 bits would speed up your system I'd reccommend that.

Someone else here suggested 4 bits, I think that is a bit on the low side (16 levels per color) but maybe that could be acceptable for your application.


Too much information leads to paralysis by analysis, but have you considered the PCA9626:

The PCA9626 is an I2C-bus controlled 24-bit LED driver optimized for voltage switch dimming and blinking 100 mA Red/Green/Blue/Amber (RGBA) LEDs.


I used to work as a programmer for a computer accessories manufacturer doing things with LED lights (I was never on the hardware team for that, as that isn't my professional interest) but one thing I do know is that the eye is incredibly non-linear in it's perception of colour. Even with 8-bit resolution, you can still visibly detect single bit changes at very low intensities; while anything between 0x8F and 0xFF can be undetectable.

It's on my list of future projects to have a look at the literature surrounding colour, intensity and human perception - once I've got this baby out of the way. Looking at the TLC5940 with its 12-bit resolution I think it will make an awesome testbed for playing with some of this stuff. It's just a shame that it works out at 62p per RGB channel.

Tangent Alert: Any why are some ICs cheaper at farnell in P/DIP format rather than SMT ? I would have thought the volume and economy of scale would be in favour of SMT technologies.



Too much information leads to paralysis by analysis, but have you considered the PCA9626:

The PCA9626 is an I2C-bus controlled 24-bit LED driver optimized for voltage switch dimming and blinking 100 mA Red/Green/Blue/Amber (RGBA) LEDs.

"paralysis by analysis" only applies to commites where no-one wants to make a decision, so they just keep comissioning more reports and not doing anything. This is just me! A benign autocracy of one. So bring it on, the more information the better the decision.

I remember looking at this chip a few weeks ago and dismissing it out of hand because it's only available as an LQFP48 http://www.image.micros.com.pl/_obudowy_auto/lqfp48.gif which would be a pain to hand solder.

But, looking again; it does has full 8/8/8 bit accuracy and each chip drives 24 channels (6x RGBA) to 100mA (each of which can simultaneously be driven at 100mA).

The farnell pricing is currently 1@£4.14, 10@£3.10, 100@£2.48. This brings the price per channel in at £0.69, £0.52 and £0.41 respectively. Compare this with the TLC5940 with a price per channel of £0.62, £0.53 and £0.44. Certainly comparable, but the fact that the 5940 comes in a PDIP package sells it for me :)



ive started to build a 8x8 rgb matrix, it's going more slowly than i would like. But i have decided to use 12 tl9450 chip's instead of multiplexing. Manly because of the light intensity issue and the chips are cheep enough really anyway. I've had one working for a while.
I have a feeling i'm going to run into problems maybe. Lots of decoupling i think and keeping the 12 chips quite close together.

It looked easy on paper..haha
i want 64 proximity detectors as well.


My Hexome:-
Uses only 3 TLC5940s for up to 64 RGB LEDs.
They are arranged so that one chip does one colour. That is all the red LEDs are handled by one TLC5940. In that way you can have the different chips pulling different values of current to balance up your colours.


@EVP: Looking at it going with the TLC5940 or the NXP equivalent is the smart way to go, it's just a shame that it bumps up the BOM by £33 just in silicon.

I'm kinda tempted to draw up some boards, send them off to PCB train and start selling daisy-chainable 16-channel RGB 120mA per line driver boards if I thought anyone would buy them. I think the I2C addressing lets you get a fair few in on one bus without any hastle. Like the Octobar LED controllers (http://arduino.cc/forum/index.php/topic,62510.0.html) but better because I made them :)

For the moment I'm going to persevere with a 74138 / p-chan MOSFET as the row driver into three darlington arrays as the sink, until I blow out the darlingtons and have to replace them with TLC5916 current sinks.

Much more fun to be had.



... and Mike, that video is awesome. You deserve some kinda Make BAFTA for it.

I was watching thinking, "meh, no PWM here it's all just red, green and blue booooring" and then you took off with the light show. Top work.



polhemic if you could get the board your talking about up to 350/400 mA for 1 watt rgb led's i would be interested.


polhemic if you could get the board your talking about up to 350/400 mA for 1 watt rgb led's i would be interested.

Hmm,  it almost sounds like you'd need some kind of current amplification device. I'll call the 50's and see if they're still carrying stock :)

Shouldn't be too much hastle to add on, but there might be better driver solution chips out there - I know that NXP have made more recent changes to their portfolio that 5940, so a quick bit of research might be in order


Go Up