Maker Pro
Maker Pro

Multiplexing LEDs - calculating resistor value

S

Spehro Pefhany

Having written code to drive arrays of up to 9600 bi-color LEDs a few
hundred Hz would have taken a lot of skin off the processor used. A 62.5Hz
refresh rate which required the generation and clocking of 2 600kb/s data
streams took 90% of the skin it had.

Sure. With >30x the number of LEDs, that's in a different realm.
Also many of the display 'effects' particularly the very common sideways
scrolling must be synchronised to the display multiplex so if you multiplex
too fast it scrolls too fast. Scrolling sideways at 62.5 LEDs per second is
already a bit fast for small fonts.

What happens if you don't synchronize it? All I see is visible
slanting of the characters..


Best regards,
Spehro Pefhany
 
R

roxlu

nospam said:
It sounds like you are still driving the matrix wrong. With the circuit you
linked only one bit in the row shift register should be on so only one LED
connected to that 100R resistor will be on at a time and that LED gets the
whole 21 mA.

When you start driving the matrix the right way remember all 48 LEDs could
be on and the row drivers will have to source just over 1 Amp which the
transistors you chose may not be capable of.

--

Hi nospam and John

Thanx a lot for all your comments and suggestions.
It sounds like you are still driving the matrix wrong. With the circuit you
linked only one bit in the row shift register should be on so only one LED
connected to that 100R resistor will be on at a time and that LED gets the
whole 21 mA.

Just to make clear what you mean here...... I'm driving the matrix like
this: At start I make the first column (vertical) high. Than I set
which of the eight LEDs (the "row") must be turned on. This is how I'm
driving the matrix now.

Do you mean that I need to drive it like this:
Make the first column high, than lets say that LED 2 and 4 must be
turned on, I first shift this into the shift register: 0000 0010 (LED
2), than I put LED 2 off: 0000 0000 And than I put LED 4 on: 0000 1000.
Is this correct? If so, I think this will take a lot of processing
power from my uC.

Thanks,
Greetings
 
J

John Fields

Just to make clear what you mean here...... I'm driving the matrix like
this: At start I make the first column (vertical) high. Than I set
which of the eight LEDs (the "row") must be turned on. This is how I'm
driving the matrix now.

---
That's the problem.

You need to consider the array as 8 rows with 48 LEDs in each row,
like this: (View in Courier)

COL48>-----------------------------------//----------+
|
COL02>----------------------+ |
| |
COL01>-------+ | |
| | |
[R1] [R2] [R48]
| | |
| | |
+5v>---------|----+---------|----+-------//----------|----+
| | | | | |
| E | E | E
+--B PNP1 +--B PNP2 +--B PNP48
C C C
| | |
[R49] [R50] [R96]
| | |
ROW1---+----------|---+----------|------//-----+ |
| | | | | |
+-[LED001]-+ +-[LED002]-+ +-[LED048]-+
| | |
| | |
| | |
ROW2---+----------|---+----------|------//-----+ |
| | | | | |
+-[LED049]-+ +-[LED050]-+ +-[LED096]-+
| | |
| | |
| | |
ROW8---+----------|---+----------|------//-----+ |
| | | | | |
+-[LED337]-+ +-[LED338]-+ +-[LED384]-+


Each of the column lines goes to one of the outputs of six cascaded
8 bit serial-in parallel out shift registers which are used to shift
and latch data onto the column lines.

At the same time data is latched, the row driver corresponding to
that data is enabled, causing ever how many of the 48 LEDs in that
row that are supposed to light up, to light up.

Then you shift the 48 bits of data data for the next row into the 48
column lines and enable that row driver, and on and on, like that,
endlessly.

I haven't shown it above, but the rows will be connected to the
collectors of the NPNs or NMOSFETS described in an earlier post.

For 8 lines you'll probably want to use something like an HC238 to
do the decoding, so your total load on the µC will be 6 I/Os:
clock, data, and latch for the shift registers, and the three
address bits for the decoder.

The end result of all this is that instead of shifting in 8 bits at
a time to the rows and then multiplexing 48 columns, you're shifting
in 48 bits of data to the columns and multiplexing the rows, which
will allow you to run the LEDs much brighter than you could the
other way.
 
J

Jonathan Kirwan

Hi nospam and John

Thanx a lot for all your comments and suggestions.


Just to make clear what you mean here...... I'm driving the matrix like
this: At start I make the first column (vertical) high. Than I set
which of the eight LEDs (the "row") must be turned on. This is how I'm
driving the matrix now.

Which is as I thought, and bad news if you want a consistent
intensity.
Do you mean that I need to drive it like this:
Make the first column high, than lets say that LED 2 and 4 must be
turned on, I first shift this into the shift register: 0000 0010 (LED
2), than I put LED 2 off: 0000 0000 And than I put LED 4 on: 0000 1000.
Is this correct? If so, I think this will take a lot of processing
power from my uC.

Yes, it would but that's also not usually how it would be done. As
that wouldn't be so good as other options.

I'll assume that your schematic should be expanded so that it is
looked at this way:

row 1: 000000000000000000000000000000000000000000000000
row 2: 000000000000000000000000000000000000000000000000
row 3: 000000000000000000000000000000000000000000000000
row 4: 000000000000000000000000000000000000000000000000
row 5: 000000000000000000000000000000000000000000000000
row 6: 000000000000000000000000000000000000000000000000
row 7: 000000000000000000000000000000000000000000000000
row 8: 000000000000000000000000000000000000000000000000

col: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv

And that in this case what you use to drive each column is as you
showed, similarly for each row. In other words, staying with your own
definition of 'row' and 'column' and no one else's.

Since you are only permitted to drive zero or one LED per column at a
time, the idea would be to enable just row 1 after latching in each of
the column enables depending on your data for that row. Then disable
row 1, latch row 2's column data into the columns, enable row 2. Then
disable row 2, latch row 3's column data into the column enables, then
enable row 3. Etc. This provides a 1:8 multiplexing and that will
suggest that you will need to significantly over-drive each LED enough
so that they will appear sufficiently bright for your needs. That
affects the resistor size you were talking about before.

So let's say the image was this:

row 1: * * ***** * * *** * * * ***
row 2: * * * * * * * * * * *
row 3: * * * * * * * * * * *
row 4: ***** *** * * * * * ***** *
row 5: * * * * * * * * * * *
row 6: * * * * * * * * * * *
row 7: * * ***** ***** ***** *** * * * ***
row 8:

col: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv

You'd make sure all row drivers were off, to start. Then load in
"100010111110100000100000011100000010100010011100" into your column
shift register. Then enable row 1. Wait, as appropriate. Disable
row 1. Load "100010100000100000100000100010000100100010001000" into
your column shift register. Then enable row 2. Wait, ... Etc.

Does that make sense?

Jon
 
J

John Fields

On Tue, 27 Jun 2006 05:06:16 -0500, John Fields


COL48>-----------------------------------//----------+
|
COL02>----------------------+ |
| |
COL01>-------+ | |
| | |
[R1] [R2] [R48]
| | |
| | |
+5v>---------|----+---------|----+-------//----------|----+
| | | | | |
| E | E | E
+--B PNP1 +--B PNP2 +--B PNP48
C C C
| | |
[R49] [R50] [R96]
| | |
ROW1---+----------|---+----------|------//-----+ |
| | | | | |
+-[LED001]-+ +-[LED002]-+ +-[LED048]-+
| | |
| | |
| | |
ROW2---+----------|---+----------|------//-----+ |
| | | | | |
+-[LED049]-+ +-[LED050]-+ +-[LED096]-+
| | |
| | |
. . .
. . .
. . .

| | |
ROW8---+----------|---+----------|------//-----+ |
| | | | | |
+-[LED337]-+ +-[LED338]-+ +-[LED384]-+
 
R

roxlu

Jonathan said:
Which is as I thought, and bad news if you want a consistent
intensity.


Yes, it would but that's also not usually how it would be done. As
that wouldn't be so good as other options.

I'll assume that your schematic should be expanded so that it is
looked at this way:

row 1: 000000000000000000000000000000000000000000000000
row 2: 000000000000000000000000000000000000000000000000
row 3: 000000000000000000000000000000000000000000000000
row 4: 000000000000000000000000000000000000000000000000
row 5: 000000000000000000000000000000000000000000000000
row 6: 000000000000000000000000000000000000000000000000
row 7: 000000000000000000000000000000000000000000000000
row 8: 000000000000000000000000000000000000000000000000

col: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv

And that in this case what you use to drive each column is as you
showed, similarly for each row. In other words, staying with your own
definition of 'row' and 'column' and no one else's.

Since you are only permitted to drive zero or one LED per column at a
time, the idea would be to enable just row 1 after latching in each of
the column enables depending on your data for that row. Then disable
row 1, latch row 2's column data into the columns, enable row 2. Then
disable row 2, latch row 3's column data into the column enables, then
enable row 3. Etc. This provides a 1:8 multiplexing and that will
suggest that you will need to significantly over-drive each LED enough
so that they will appear sufficiently bright for your needs. That
affects the resistor size you were talking about before.

So let's say the image was this:

row 1: * * ***** * * *** * * * ***
row 2: * * * * * * * * * * *
row 3: * * * * * * * * * * *
row 4: ***** *** * * * * * ***** *
row 5: * * * * * * * * * * *
row 6: * * * * * * * * * * *
row 7: * * ***** ***** ***** *** * * * ***
row 8:

col: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv

You'd make sure all row drivers were off, to start. Then load in
"100010111110100000100000011100000010100010011100" into your column
shift register. Then enable row 1. Wait, as appropriate. Disable
row 1. Load "100010100000100000100000100010000100100010001000" into
your column shift register. Then enable row 2. Wait, ... Etc.

Does that make sense?

Jon

Hi John and Jonathan,

Really thanks a lot!! Now I get what you mean...I'm not a
electronics-man and still learning. When I'm using a current limiting
resitor of 100R, could I let my circuit as it is now? And what about
the speed? As suggested I need to shift in 48 bits for each row instead
of 8 (for all the rows). I can imagine this will take a lot more
processing power which will cause flickering.

Thanks,
Greetings
 
N

nospam

Spehro Pefhany said:
What happens if you don't synchronize it? All I see is visible
slanting of the characters..

You get visible slanting of the characters (one LED pitch which is a lot on
a small font) when you do synchronise. Left or right depending on if you
multiplex from top down or bottom up.

If you scroll at twice the multiplex rate the slant doubles, half the rate
you see a double (fat) image. On a font big enough to take it that can look
ok and produces a very convincing optical illusion that the display has
twice the number of LEDs. I never did any work on it but imagine it is
possible to alternate between two font images to take advantage of the
apparently doubled display resolution.

In between you see jittering slant and flickering multiple images - it just
looks garbage.
--
 
V

vic

Hi roxlu,

your intensity problem come from the fact that you used a single
resistor for you N leds (not sure if you switch on 8 or 48 at a time).
When 1 led is on, you've got x volts drops across the resistor. When you
light 2 leds, you've got 2x volts drop, and so on ...

If you switch on one *row* at a time, you'll need one resistor per *column*.

vic
 
P

Pubudu

John said:
---
Aarrgghhhhh!!!

Lowish Rds(on) 100 milli _ohms_,


P = I²RT = 7.68A² * 0.1R * 0.125 = 0.737 watts,

so it'll get warm enough to need a heat sink.



Hi,
You have be careful when u putting lower resistors. Because incase
if your scanning stopped during experimenting you may loose that
column. It is better to incorporate Frequency to voltage converter.

Pubudu
 
J

John Fields

Hi John and Jonathan,

Really thanks a lot!! Now I get what you mean...I'm not a
electronics-man and still learning. When I'm using a current limiting
resitor of 100R, could I let my circuit as it is now? And what about
the speed? As suggested I need to shift in 48 bits for each row instead
of 8 (for all the rows). I can imagine this will take a lot more
processing power which will cause flickering.

---
If you assume that a frame rate of 50Hz will be adequate to prevent
flickering, then that means you'll need to update the array every 20
milliseconds.

Since you have 8 rows which you're strobing, one at a time, during
that 20ms you'll have each one of them on for 2.5ms, and since you
have 48 pixels in each row, the longest time you can take, per
pixel, to shift in a new row before the strobe happens is 52.08µs.

You should be able to do it much faster than that, though, the limit
being how fast your µC can fill up the shift register, which will
determine how much time you've got left over to do other stuff.
Like this:

+-------------------------------------------+
| |
| |<-----------20ms----------->| |
| ____________ ________________ |
+---->|____________|________________|--+ |
FILL ROW 1 DO OTHER STUFF | |
+--------------------------------------+ |
| |<------------20ms----------->| |
| ____________ ________________ |
+---->|____________|________________|---+ |
FILL ROW 2 DO OTHER STUFF | |
. |
. |
. |
| |
+---------------------------------------+ |
| |
| |<------------20ms----------->| |
| ____________ ________________ |
+---->|____________|________________|-------+
FILL ROW 8 DO OTHER STUFF

I think I'd use an internal timer (if I could) to get the 20ms
ticks, then use the timer interrupt to jump to my ISR, which would
fill the shift register with new data, then latch it and increment
the row counter when the 48th bit clock went true, then exit and
wait for the next timer interrupt.
 
J

John Fields

Hi,
You have be careful when u putting lower resistors. Because incase
if your scanning stopped during experimenting you may loose that
column. It is better to incorporate Frequency to voltage converter.

---
No, you'd lose all of the hot LEDs in that row.

Short of some hare-brained scheme using a frequency-to-voltage
converter to turn off the supply if scanning were to stop, I have no
idea what you're talking about.
 
J

John Fields

On Tue, 27 Jun 2006 10:37:44 -0500, John Fields

Like this, actually:

+-------------------------------------------+
| 0ms |
| |<-----------2.5ms----------->| |
| ____________ ________________ |
+---->|____________|________________|--+ |
FILL ROW 1 DO OTHER STUFF | |
+--------------------------------------+ |
| |<----------2.5ms------------>| |
| ____________ ________________ |
+---->|____________|________________|---+ |
FILL ROW 2 DO OTHER STUFF | |
. |
. |
. |
| |
+---------------------------------------+ |
| 20ms |
| |<----------2.5ms------------>| |
| ____________ ________________ |
+---->|____________|________________|-------+
FILL ROW 8 DO OTHER STUFF
 
R

Rich Grise

On Tue, 27 Jun 2006 10:37:44 -0500, John Fields

Like this, actually:

+-------------------------------------------+
| 0ms |
| |<-----------2.5ms----------->| |
| ____________ ________________ |
+---->|____________|________________|--+ |
FILL ROW 1 DO OTHER STUFF | |
+--------------------------------------+ |
| |<----------2.5ms------------>| |
| ____________ ________________ |
+---->|____________|________________|---+ |
FILL ROW 2 DO OTHER STUFF | |
. |
. |
. |
| |
+---------------------------------------+ |
| 20ms |
| |<----------2.5ms------------>| |
| ____________ ________________ |
+---->|____________|________________|-------+
FILL ROW 8 DO OTHER STUFF

If the shift registers have registered outputs, i.e., if the outputs can
stay at the previous state while new data is being clocked in, and it
needs another (different) clock to transfer the new data to the output
latches, you could interleave the shifts - i.e., while row 1 is enabled
and the shift register outputs are latched, clock in row 2 data. Disable
row 1, clock the shift register output latches, and enable row 2, and so
on.

IOW, a given row wouldn't have to be blanked during the shift register
load time.

Cheers!
Rich
 
R

Rich Grise

Having written code to drive arrays of up to 9600 bi-color LEDs a few
hundred Hz would have taken a lot of skin off the processor used. A 62.5Hz
refresh rate which required the generation and clocking of 2 600kb/s data
streams took 90% of the skin it had.

Also many of the display 'effects' particularly the very common sideways
scrolling must be synchronised to the display multiplex so if you multiplex
too fast it scrolls too fast. Scrolling sideways at 62.5 LEDs per second is
already a bit fast for small fonts.

The display shouldn't care at all about scrolling - that's an entirely
different function - the scroller changes the bitmap at its rate, and the
displayer displays the (potentially scrolled) bitmap at its own rate.
There's no reason they'd have to interact.

But, then again, I've made music with interleaved loops. ;-)

Cheers!
Rich
 
J

John Fields

If the shift registers have registered outputs, i.e., if the outputs can
stay at the previous state while new data is being clocked in, and it
needs another (different) clock to transfer the new data to the output
latches, you could interleave the shifts - i.e., while row 1 is enabled
and the shift register outputs are latched, clock in row 2 data. Disable
row 1, clock the shift register output latches, and enable row 2, and so
on.

IOW, a given row wouldn't have to be blanked during the shift register
load time.

Cheers!
Rich
 
J

John Fields

If the shift registers have registered outputs, i.e., if the outputs can
stay at the previous state while new data is being clocked in, and it
needs another (different) clock to transfer the new data to the output
latches, you could interleave the shifts - i.e., while row 1 is enabled
and the shift register outputs are latched, clock in row 2 data. Disable
row 1, clock the shift register output latches, and enable row 2, and so
on.

---
You don't have to disable anything, you just increment the row
decoder at the same time that you latch the new data. Read the
earlier posts and you'll see that three inputs are provided for the
shift registers: serial data, data clock, and output latch clock.
---
 
N

nospam

John Fields said:
You don't have to disable anything, you just increment the row
decoder at the same time that you latch the new data. Read the
earlier posts and you'll see that three inputs are provided for the
shift registers: serial data, data clock, and output latch clock.

I already posted that you likely do. Unless you can perfectly match the
turn on and turn off times of the drivers regardless of load. Just banging
a new set of drives on the matrix will result in the new column momentarily
driving the old row or vica versa which creates a faint ghost image.
--
 
R

Rich Grise

In Jonathan Kirwan's post:
"You'd make sure all row drivers were off, to start. Then load in
"100010111110100000100000011100000010100010011100" into your column
shift register. Then enable row 1. Wait, as appropriate. Disable
row 1. Load "100010100000100000100000100010000100100010001000" into
your column shift register. Then enable row 2. Wait, ... Etc...."

Cheers!
Rich
 
J

John Fields

In Jonathan Kirwan's post:
"You'd make sure all row drivers were off, to start. Then load in
"100010111110100000100000011100000010100010011100" into your column
shift register. Then enable row 1. Wait, as appropriate. Disable
row 1. Load "100010100000100000100000100010000100100010001000" into
your column shift register. Then enable row 2. Wait, ... Etc...."
 
R

Rich Grise

So why didn't you address your post to JK?

Because this is USENET. The post was intended for general consumption.
Did you just find USENET this morning? Have you read any of the FAQs?

Notwithstanding, in this case, I was directly answering your quetion.

Thanks,
Rich
 
Top