595 LED graphics
george miyagi
Posts: 48
Hi.
I've got 2x 595s connected to my 8x8 LED matrix.
But for the life of me I can't figure out how to draw something on it.
ie. i can get rows and columns to switch on and off.
I know in the end I'll probably have to use lookup tables etc.
but I'm just trying to get comfortable with what's going on... especially regarding mapping the horiz rows
ser CON 6
clk CON 7
latch CON 4
cmd1 VAR BYTE
cmd2 VAR BYTE
Main:
cmd1 = %01111111 'horiz off
cmd2 = %10000000 'vert off
GOSUB Send_Cmd
cmd1 = %01111111 'horiz off
cmd2 = %00000001 'vert off
GOSUB Send_Cmd
cmd1 = %11111110 'horiz off
cmd2 = %10000000 'vert off
GOSUB Send_Cmd
cmd1 = %11111110 'horiz off
cmd2 = %00000001 'vert off
GOSUB Send_Cmd
GOTO Main
Send_Cmd:
LOW latch
SHIFTOUT Ser, Clk, MSBFIRST, [noparse][[/noparse]cmd1]
SHIFTOUT Ser, Clk, MSBFIRST, [noparse][[/noparse]cmd2]
PULSOUT Latch, 100
LOW latch
RETURN
I've got 2x 595s connected to my 8x8 LED matrix.
But for the life of me I can't figure out how to draw something on it.
ie. i can get rows and columns to switch on and off.
I know in the end I'll probably have to use lookup tables etc.
but I'm just trying to get comfortable with what's going on... especially regarding mapping the horiz rows
ser CON 6
clk CON 7
latch CON 4
cmd1 VAR BYTE
cmd2 VAR BYTE
Main:
cmd1 = %01111111 'horiz off
cmd2 = %10000000 'vert off
GOSUB Send_Cmd
cmd1 = %01111111 'horiz off
cmd2 = %00000001 'vert off
GOSUB Send_Cmd
cmd1 = %11111110 'horiz off
cmd2 = %10000000 'vert off
GOSUB Send_Cmd
cmd1 = %11111110 'horiz off
cmd2 = %00000001 'vert off
GOSUB Send_Cmd
GOTO Main
Send_Cmd:
LOW latch
SHIFTOUT Ser, Clk, MSBFIRST, [noparse][[/noparse]cmd1]
SHIFTOUT Ser, Clk, MSBFIRST, [noparse][[/noparse]cmd2]
PULSOUT Latch, 100
LOW latch
RETURN
Comments
If cmd2 is the column command then 00000000 remove all voltage from the LEDs.· To turn on the LED at row1/col1 you would write
for x = 1 to 100
cmd1 = %0111111········ 'grounds row 1
cmd2 = %1000000········ 'applies 5vdc to col 1
next
To draw a diagonal from top left to lower right you would write:
for x = 1 to 100
cmd1 =·127·· same as 0111111
cmd2 = 128·· same as 1000000
gosub send_cmd
pause 10
cmd1 = 191·· same as 10111111
cmd2 = 64
gosub send_cmd
pause 10
cmd1 = 223
cmd2 = 32
gosub send_cmd
pause 10
Then continue writing row4/col4, row5/col5,row6/col6,row7/col7, row8/col8.
next
You are correct about a lookup table - once you get your patterns mapped out, then you could either use a table or a Read DATA statement.
The 10 second pause should be enough so that all LEDs will appear to be on.· If the flicker just decrease the pause little by little until they are steady.
Does this help?
Sid
Post Edited (Newzed) : 6/14/2005 6:54:15 PM GMT
Sid
Sid
x = off, o = on
C·· ·--xoxoxoxo
o··· --oxoxoxox
l···· --xoxoxoxo
u··· --oxoxoxox
m··· ...
n······ Row 595
595
to generate the first row the row must be activated, to produce xoxoxoxo you have the column loaded with 01010101, to produce the second row it's row must be activated and the column is 10101010, as you see there is no way to produce both of these lines, and there is no way to produce them using static driving.
What you need to do is operate the 595 in multiplexed mode, this involves seeding the row with an active value (lets assume your row is the cathode connection of the leds and the column is the anode connections, if the reverse is true swap the values I give with the inverse of the value), then progressing the activated row down the line.
An LED will be on if its row is 0 and its column is 1, all other combinations result in the LED being off.
The row 595 must be initialized to contain $FF (all 1's), this means regardless of the column data all LEDs are off.
Load the column 595 with the first column of data, clock a 0 into the row 595.
Now the first column is lit up according to the value placed in the column 595.
Next load the column 595 with the second column of data, then clock a 1 into the row 595, the 0 shifts one position lighting up the second column with the data in the column 595.
This process is repeated until all 8 columns are displayed in order. Then the entire process is started over.
By multiplexing, the LED matrix any pattern can be generated, and with luck the display wont flicker too badly (the stamp is a little underpowered to handle multiplexed LED matricies.
Addendum: static driving an arbitrary pattern on an 8x8 LED matrix is possible but it will require 8 595's, one output for each LED element.
Post Edited (Paul Baker) : 6/14/2005 7:17:12 PM GMT
Sid
Post Edited (Paul Baker) : 6/14/2005 7:23:32 PM GMT
Sid
Note the edit above regarding the pause.
thanks for the help.
Sid: got the diagonal line going. I presume the for...next loop is to try and speed things up.
The pause is not needed. In fact, herin lies my latest conundrum. There is quite a bit of visible flickering.
4 individual lights turned on are fine. put 5 on and the flickering starts to look bad.
Is this not a factor of the PULSEOUT period command, or is this the best i'm going to get with the 595s. could it be something to do with what size resistors i'm using?
I'm going to add a second 2803 now (actaully a TD62083) and see if this makes a difference.
Another question: what is the Common Pin on the 2803, what is it for, where does it go to? I assume to Vdd?
Paul: you mentioned that maybe i need 8 595s for each 8x8 matrix. why 8? if this is the case then it's not really feasible to go the 595 route and the max7219 route would seem neater and about the same price.
...just when i thought i was making real progress [noparse]:([/noparse]
any wise words?
addendum: when i add the second TD62083 i get no lights. nothing. nada. nix.
Post Edited (george miyagi) : 6/15/2005 5:45:43 AM GMT
You are correct the 7219 is the better choice, I was just extending the concept of a static display in the·595 vein.
Post Edited (Paul Baker) : 6/15/2005 6:04:26 AM GMT
I'm using a government issue Basic Stamp SuperCarrier board, both the matrix and 595s are connected to it's power (Vdd, Vss).
As for "correct level of complexity for questioner" - assume lowest in my case [noparse]:)[/noparse]
henceplease explain this?????...
<snip>...Second is overdrawing from the 595's, make sure that the current sourced by all 8 being lit is below the max for both the 595's since one sources and the other sinks the current...<snip>
also...
i found this home.wanadoo.nl/electro1/avr/scroll5.htm where hes driving all rows with one 595 and then each matrix column with another.
which is exactly what i'm trying to do...well almost...
Post Edited (george miyagi) : 6/15/2005 9:48:33 AM GMT
I'm a bit surprised on the flickering.· With the diagonal you are only lighting one LED at a time, which is well within the current capability of the 595.· When you light up the diagonal, are all LEDs of equal brilliance?· Just to check, insert a long pause after each Send_Cmd and make sure one LED turns off before the next on turns on.· On the BS2, each instruction takes about 250us.· You send the Cmd values (1), say GOSUB (2) then Shiftout (3), probably close to 1ms for a complete cycle.· With 8 cycles, that is only 7ms off-time for each LED - it·really shouldn't flicker.
I'm going to build up a little circuit and pulse an LED with a 7ms pause and see what happens.· I'll let you know.
Sid
If I turn on 1 LED at a time, no problem. 2 no problem. 3 no problem, but slight flickering. 4 major flickering.
So not sure if it's a current problem. because if i turn on all the lights, or combinations of them, as per my original code posting at the top, no problem. so methinks it's some kind of timing/synchronising problem. Tried every possible value of PULSEOUT but no luck there either.
Going to rip everything up and try again...
tx
george
HIGH 0
PAUSE 3
LOW 0
PAUSE 21
GOTO start
This should pretty closely approximate what you are doing.· There was no flicker with the 21ms pause, which I put in to allow the other LEDs to turn on.· 3 on and 21 off is about a 12% duty cycle.
I replaced the LED with a non-resistorized LED with no dropping resistor, and changed the pause between HIGH and LOW to 1ms, leaving the 21ms pause.· The LED burned brightly with no flicker, even though the off time is about 3 times what you would encounter.· In other words, you would have time to turn on almost 21 other LEDs during the 21ms pause.· You should be able to· create a graphic by lighting only two LEDs at once.· Using two at a time would give you 42 LEDs apparently on all the time.· Also, try momentarily shorting out your dropping resistor to see the effect on the brilliance.· At 12% duty cycle I don't think yoiu are going to hurt anything.· I've had this standard LED with no resistor running quite a while and it doesn't even get warm.
Sid
When figuring how much current your 595 is consuming you need to add all possible sources of current draw, since maximum current drain occurs when all the leds in a column are lit, you take the current drawn from a LED multiply that by 8, add in the current the 595 uses for its own operation and that is the total power consumed, if that number is greater than the maximum allowable current through Vdd/Gnd as stated in the specification for the 595 you have a current issue. If this is the case you need to add an output buffer like a darligton array, the link you posted shows one being used to drive each row.
As an aside, Sid's posted program can be sped up considerably by tightening the loops.
Do you notice that cmd1 is a number consisting of all 1's with a 0 which is shifted to the right for each iteration? Sid's code shifts the new value into 595 for each new value, but this requires 8 bit cycles·of SEROUT to load the 595 anew. Instead if you used code like this:
·I banged the code out without testing it so there may be bugs. The code above should be about twice as fast as the original code.
i'll test this out and see how it goes.
re: the power issue
i still think it is a timing issue, but i could be wrong. i can light up all 64 LEDs no problem. and combinations of rows and columns, and various patterns, no problem.
but the flickering comes when trying to address individual LEDs through multiplexing. It seems like I need to find the right frequency rather than need more power. but like i said, i could be wrong...
will build the circuit again and retest.
Sid
i have a feeling you've hit the nail on the head.
let me test that...
thanks...
i did some (allnight) tests, and i definitely seems to be a timing issue.
if i have more than 5/6 scan lines in the loop then it starts to flicker.
it seems the trick is to combine the code so that things are sped up.
but part of me suspects that it may even be the code.
as this example demonstrates...
It seems that because the same row needs to be turned on and off and on again, it produces the flicker.
putting things in a for...next loop helps slightly. As does a few other methods I've tried.
But it isn't really about optimizing the code, i feel is more of a logic problem.
Easy, when it's so obvious as in the code above, but not when you're building more complex things.
In which case scanning 1 row at a time, even though switching some lights on and off in a row may be redundant, is the obvious method.
Any ideas?
Post Edited (george miyagi) : 6/16/2005 4:42:00 AM GMT
·· The LOW command you have in your subroutine should be done during Initialization, not during the routine itself.· It's one more redundant instruction that is adding a few cycles to your code.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Chris Savage
Parallax Tech Support
csavage@parallax.com