Shop OBEX P1 Docs P2 Docs Learn Events
595 LED graphics — Parallax Forums

595 LED graphics

george miyagigeorge miyagi Posts: 48
edited 2005-06-16 14:38 in BASIC Stamp
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

Comments

  • NewzedNewzed Posts: 2,503
    edited 2005-06-14 18:40
    George, if cmd1 is the row command then 11111111 turns all row off.

    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
  • NewzedNewzed Posts: 2,503
    edited 2005-06-14 18:45
    I just edited my previous post to correct the for/next commands.

    Sid
  • NewzedNewzed Posts: 2,503
    edited 2005-06-14 18:51
    George, you should probably add a 2803 to the column 595 like the one for the row 595.· The 595 will sink/source about 35 ma per pin.· If you turn on more than four LEDs in a single column you could be stressing the 595.

    Sid
  • Paul BakerPaul Baker Posts: 6,351
    edited 2005-06-14 19:12
    Hey guys, I don't think your quite getting the concept of driving the 8x8 matrix properly. Both of you are discussing static display on the matrix using two 595's. This is a perfectly permissible method of operation, however you cannot generate any arbitrary pattern using this method. As an example image generating a checker board pattern like this:

    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
  • NewzedNewzed Posts: 2,503
    edited 2005-06-14 19:18
    Paul, that is exactly what I was doing.· That's the reason for the for/next loop - it repeats the pattern over and over for as long as the user wants.· Whether it will flicker with a 10ms delay, I don't know.

    Sid
  • Paul BakerPaul Baker Posts: 6,351
    edited 2005-06-14 19:20
    Sorry Sid, I started writing my response before you edited your post. But if the 595's are multiplexed, inserting delays will increase the flicker becuase you are adding time to the rows not being driven off time (actually the fraction of time will be exactly the same (~1/8th duty for each column), your just adjusting the frequency in which the cycling occurs)

    Post Edited (Paul Baker) : 6/14/2005 7:23:32 PM GMT
  • NewzedNewzed Posts: 2,503
    edited 2005-06-14 19:24
    No problem, Paul.· Sometimes I get in a hurry and make errors, so please keep checking.· My biggest problem is assuming the user knows something when maybe he doesn't.

    Sid
  • Paul BakerPaul Baker Posts: 6,351
    edited 2005-06-14 19:25
    Or when you assume they don't know when they actually do. I constantly struggle placing my answers at the correct level of complexity for the questioner.

    Note the edit above regarding the pause.
  • george miyagigeorge miyagi Posts: 48
    edited 2005-06-15 04:58
    hi
    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
  • Paul BakerPaul Baker Posts: 6,351
    edited 2005-06-15 05:59
    Ok all signs point to a power issue. This is most likely one of two things, most common is the supply you are using isn't capable of handling the load. Where are you drawing the power for the matrix and 595s from? Your not using the regulator on the stamp are you? 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.
    george miyagi said...

    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]
    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
  • george miyagigeorge miyagi Posts: 48
    edited 2005-06-15 09:42
    thanks again for all your help...

    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
  • NewzedNewzed Posts: 2,503
    edited 2005-06-15 11:36
    George, you might be better off going to a TPIC6515 eventually.· This chip is a combination shift register and Darlington , and will handle about 250ma per pin.· For right now lets stick with the two 595s and the two 2803s.

    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
  • george miyagigeorge miyagi Posts: 48
    edited 2005-06-15 12:00
    Thanks 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
  • NewzedNewzed Posts: 2,503
    edited 2005-06-15 12:33
    George I wrote:

    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
  • Paul BakerPaul Baker Posts: 6,351
    edited 2005-06-15 15:56
    george miyagi said...
    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>
    The reason I think it has to do with power issues is that you claim differing behaviour depending on the number of LED's lit. The timing of your program loop is identical (each loop takes the same amount of time) the only variable is the number of LEDs lit, this points to current issues.

    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.
    Sid said...

    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
    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:

    ser CON 6
    rclk CON 7
    cclk CON 5
    latch CON 4
    LEDdata VAR BYTE(8) 
    
    
    Main:
     
    GOSUB seed_595
    for x = 1 to 8
    GOSUB Send_Cmd
    GOTO Main
     
    seed_595:
    LOW latch
    SHIFTOUT Ser, cClk, MSBFIRST, $FE
    PULSOUT latch, 100
    LOW latch
    RETURN
    
    Send_Cmd:
    LOW latch
    SHIFTOUT Ser, rClk, MSBFIRST, [noparse][[/noparse]LEDdata(x)]
    HIGH Ser
    PULSOUT cClk, 100
    LOW cClk
    PULSOUT Latch, 100
    LOW latch
    RETURN
    
    

    ·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.
  • george miyagigeorge miyagi Posts: 48
    edited 2005-06-15 16:43
    thanx paul
    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.
  • Paul BakerPaul Baker Posts: 6,351
    edited 2005-06-15 18:05
    Oh Oh Oh it just hit me, the reason this is occuring is you are addressing each LED individually, loading both serial registers in the process. So each LED lit introduces more code = more time per loop = lower duty cycle = flickering. The code I gave updates the LEDs 8 at a time, with the code being ~ twice as fast this should be equivalent to 4 LEDs being lit with your code. This is in your flickering region but close enough to non-flickering we may be able to optimise the code into non-flickering. Another thing is you should decrease the PULSOUT durations since 100 ms is pretty slow, the 595's will recognize a much smaller pulse (Im nearly positive it would recognize a 1 ms pulse width).
  • NewzedNewzed Posts: 2,503
    edited 2005-06-15 18:59
    Paul, the units ot duration for pulsout on the BS2 are 2us.· A pulsout of 10 (20 us) is plenty for the 595.

    Sid
  • george miyagigeorge miyagi Posts: 48
    edited 2005-06-15 19:19
    aaaaahhhhh! bingo.
    i have a feeling you've hit the nail on the head.
    let me test that...
    thanks...
  • george miyagigeorge miyagi Posts: 48
    edited 2005-06-16 04:15
    hi
    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...

    ser CON 1
    clk CON 0
    latch CON 2
    cmd1 VAR BYTE 
    cmd2 VAR BYTE 
    
    
    
    Main:
    cmd1 = %01111111 'horiz off
    cmd2 = %10000000 'vert on
    GOSUB Send_Cmd
    cmd1 = %11111110 'horiz off
    cmd2 = %10000000 'vert on
    GOSUB Send_Cmd
    cmd1 = %01111111 'horiz off
    cmd2 = %00000001 'vert on
    GOSUB Send_Cmd
    cmd1 = %11111110 'horiz off
    cmd2 = %00000001 'vert on
    GOSUB Send_Cmd
    cmd1 = %11100111 'horiz off
    cmd2 = %00000001 'vert on
    GOSUB Send_Cmd
    cmd1 = %11100111 'horiz off
    cmd2 = %10000000 'vert on
    GOSUB Send_Cmd
    GOTO Main
    
    Send_Cmd:
    LOW latch
    SHIFTOUT Ser, Clk, MSBFIRST, [noparse][[/noparse]cmd1\8]
    SHIFTOUT Ser, Clk, MSBFIRST, [noparse][[/noparse]cmd2\8]
    
    PULSOUT Latch, 10
    LOW latch
    'PAUSE 500
    RETURN
    
    



    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
  • Chris SavageChris Savage Parallax Engineering Posts: 14,406
    edited 2005-06-16 14:38
    George,

    ·· 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
Sign In or Register to comment.