Shop OBEX P1 Docs P2 Docs Learn Events
Looking for advice on driving a moderate number of LED's — Parallax Forums

Looking for advice on driving a moderate number of LED's

Chris KraftChris Kraft Posts: 20
edited 2006-12-29 17:38 in General Discussion
I have a project I am working on that needs to individually drive up to 27 LED's. The most it would turn on simultaneously is 24.

I would like to use a SX28 to store the logic but I am sure that it would not be able to drive that much current at one time. So does anyone have any advice on what I could use to drive that many outputs?

The project is a gift so usually I would not worry about the costs of the components but I can see people asking me to build more of them so I would like to keep the component costs down if I can.

The project is very similar to the TIX clock, http://www.thinkgeek.com/homeoffice/lights/7437/, but I wanted to try and build my own version so that I would be able to change the behavior as I would like.

Any advice is appreciated.

Thanks

--Chris

Comments

  • LoopyBytelooseLoopyByteloose Posts: 12,537
    edited 2006-12-26 08:54
    A shift register would be a good solution. LEDs don't like to be in parallel as one may hog more power and cause a destructive imbalance. Putting them in series requires driving with a higher voltage. That mean a dual power supply and switching transistors or MOSfets handling the control of groups.

    With the shift register [noparse][[/noparse]maybe two or three in series], you can stay with 5 volts and have each controled individually.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    "If you want more fiber, eat the package.· Not enough?· Eat the manual."········
    ···················· Tropical regards,····· G. Herzog [noparse][[/noparse]·黃鶴 ]·in Taiwan
  • PJAllenPJAllen Banned Posts: 5,065
    edited 2006-12-26 13:00
    Chris Kraft said...
    ·...I am working on that needs to individually drive up to 27 LED's
    The·SX48 has 36 I/Os.· You could drive all of your LEDs directly from it, but not at 20mA each.·
    Read up on the drive capabilities in the spec sheet.·
    You could safely do them all from an SX48 if you use a transistor buffer/driver between the SX I/Os and the LEDs, this way the current required from the SX I/O is much less (< 1mA).

    Now another matter is: what you figure "on" is.· They don't all have to be "on", per se,·at the same time.· You could strobe all of the outputs, quickly, and the viewer wouldn't know it (persistence of vision, etc.) --·and not have to employ bufferring/transistors to do so.· However, this may require some "advanced" programming.

    [noparse][[/noparse] The SX48 ProtoBoards are only $9.95!! ]
  • T&amp;E EngineerT&amp;E Engineer Posts: 1,396
    edited 2006-12-26 13:54
    I have done this before using both 595's (SX-28 and Basic Stamp II) or a 8255 PIA chip. See my attachments below. The 8255 method would offer all 24 pins as inputs or in your case and mine (outputs) for LEDs or connect to transistors/buffers for controlling higher current/voltage devices.

    If you choose the 8255 method - Here is some connection notes:

    '
    ' Program Description
    '
    ' SX-28 interface with (8) 8255 chips
    ' Connect all the RESET, /WR, A0 and A1 control lines AND all D0 and D7 databus lines together to the single SX-28
    ' Connect separate /CSx control lines to RB.0, RB.1, etc.. If only 1 8255 is used then connect CS1_8255 to GND.
    ' /RD_8255 and Vcc_8255 is connected to +5v. D0 - D7 connects to RC.0 - RC.7 respectively.
    ' Up to (8) 8255 chips can be used which provides (24 * 8 = 192 outputs) in theory.
    ' I have tested it with (3) 8255 chips (72 outputs).
    ' YOU "MAY" NEED TO ADD BUFFER CHIPS TO THE SX-28 (RA and RC OUTPUTS) MORE THAN (3) 8255 CHIPS.·



    If you need 27 LEDs you can use 1 SX-28, 1 8255 and 3 SX-28 output pins for the 3 remaining LEDs. 3 chips total.

    Post Edited (T&E Engineer) : 12/26/2006 1:59:35 PM GMT
  • Brian CarpenterBrian Carpenter Posts: 728
    edited 2006-12-26 19:33
    Maxim IC makes some great chips for just this thing

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔


    It's Only A Stupid Question If You Have Not Googled It First!!
  • pjvpjv Posts: 1,903
    edited 2006-12-26 20:08
    Hi Chris;

    The only sane way to do this is to multiplex the leds. It only takes 12 I/O pins to drive 32 LEDs, and the only other components you need are 8 resistors. So the total cost is about as low as you can get, and it works great.

    Forget all that other (in my opinion not well founded) advice about extra shift registers and transistors .... they simply are not needed, and just drive the software as well as hardware complexity up unnecessarily.

    Arrange 4 banks of 8 LEDs each, with all 8 cathodes of one bank connected together, and each of these goes to one of four port "sinking" bit. Connect one LED anode of each bank together and through a 560 (or so) ohm resistor to one of 8 port "sourcing" bits.

    This results is 8 port bits selecting which LEDs (up to 8 simultaneous) of a bank will be energized, and 4 port bits, one at a time, select which bank will be active at any moment. Then the software quickly (perhaps around 1 millisecond) steps around, activating each bank in round-robin sequence, and you get the APPEARANCE of up to all 32 LEDs being on simultaneously due to the eye's luminescent persistence, even though only up to 8 are ON at any 1 millisecond instance.

    The maximum current in this scheme would be 8 times (5 volts supply minus 1.5 volt LED forward drop) divided by the series resistor. This becomes 8*(5-1.5) / 560 = 50 mA .... easy for a bank sinking bit to handle. For greater brightness, the resistors could probably be safely reduced to 470, or possibly 390 ohms.

    The multiplexing software is quite simple and can be tackled in numerous ways. I like to employ a simple RTOS (Real Time Operating System, or actually more of a co-operative scheduler) for such tasks as it isolates other activities such as time-of-day counting, push button monitoring and alarming all as separate "simultaneous" tasks with virtually no interaction between them.

    If you are interested, I will post the code for this RTOS and multiplexing code (although I use assembly almost exclusively), and you can add your other clock or time keeping functions whatever they may be.

    Perhaps I could also add a schematic drawing, but first I'd have to figure out how to make one that can be posted here.

    Any advice on that ???

    Anyhow, that's my advice to your post.... let me know.

    Cheers,

    Peter (pjv)
  • Guenther DaubachGuenther Daubach Posts: 1,321
    edited 2006-12-26 22:53
    Hi Chris and Peter,

    I fully agree with Peter that arranging the LEDs in a multiplexed matrix is the less component-intensive method. I'm using a similar arrangement in one of my commercial applications, driving a matrix of 8 by 8 LEDs with good success.

    Nevertheless, I have some concerns about the "minimum solution" Peter has recommended:

    As the LEDs are multiplexed, an LED that shell be "on" is not actually "on" all the time. It is only on when the port "sinking" bit, or the row line is low. To avoid a visible "flicker", the scanning must be fast enough, say at least
    100 Hz, i.e. each LED will be driven every 10 ms. Driving the matrix at higher scan rates only increases the switching losses but not the quality of the display as our eyes are not capable of noticing faster on/off sequences.

    Assuming a 100 Hz scan rate, each LED that shall be "on" will be turned on every 10 ms for 2.5 ms, as there are four row lines that are periodically pulled low within the 10 ms period. IOW, an "on" LED will be pulsed at a duty-cycle of 25%.

    A standard LED requires about 10 mA forward current for an acceptable brightness. As the LEDs are driven at 25% duty cycle, the peak current should be 40 mA for an average of 10 mA. Depending on the LED type you are using, a lower average current may be fine enough, especially because pulsed LEDs seem to be brighter at lower average currents, compared to non-multiplexed LEDs. Let's assume that an average current of 5 mA would be enough, so the peak current would be 40 mA for each LED.

    The SX28 data sheet specifies the maximum current to be sourced or sinked by an output pin at 45mA, and the maximum current out of the Vss pin, and into the Vdd pin at 130 mA each.

    If we assume the absolute worst case, i.e. all LEDs in the matrix shall be "on", this means that the average current to be sourced by each of the column-driving pins is 5 mA * 4 = 20 mA. This is below the maximum for an output pin, but as eight pins need to source this current, the required current into the Vdd pin would be 8 * 20 mA = 160 mA, This is 30 mA above the absolute maximum ratings.

    The same is true for the four row-driving pins. Each of them would have to sink an average of 5 mA * 8 = 40 mA. So the total average current these four pins sink out to the Vss pin must also be 160 mA (4 * 40 mA).

    Besides the current into the Vdd pin, or out of the Vss pin for the LEDs, the SX needs do draw additional current to operate, depending on the clock frequency used, etc.

    When you can make sure that your application never needs to turn "on" more LEDs that can be driven by the SX within its maximum ratings, it is fine to use the layout, Peter had suggested. You also may use "extra bright" LEDs that require less current, allowing you to increase the value of the eight current-limiting resistors.

    The schematic I have attached shows an LED matrix similar to what Peter has suggested with additional driver transistors for the row and column lines with resistors between the bases and the port pins (about 10 kOhm each). With these transistors installed, you take away from the SX the "burden" of directly driving the LEDs. In order to activate a matrix row, one of the RB3...0 lines must be high with all other lines low. To turn an LED "on" in a row, the assigned RC port pin must be set to low.

    When your application does not drive the SX to its limits, you may discard the transistors with their base resistors, and drive the row and column lines directly from the SX. In this case, to select a row, drive the assigned RB pin low, and drive all RC pins high for the LEDs to be turned "on" in that row.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Greetings from Germany,

    G
    2101 x 1445 - 150K
  • PJAllenPJAllen Banned Posts: 5,065
    edited 2006-12-26 23:28
    Guenther -- that's splendid,·essentially what I was alluding to in the 2nd 1/2 of my post.· Chris Kraft may ask for a programming example, too.

    People ask about thus and sundry, but one seldom knows their skill-set, so they're either overwhelmed or underwhelmed.
    pjv said...
    Perhaps I could also add a schematic drawing, but first I'd have to figure out how to make one that can be posted here.
    Don't you have a flatbed (page) scanner?

    Post Edit -- It seems that Chris Kraft isn't after turning on some LEDs, simply.· He's doing some clock display trip.·
    Chris Kraft said...
    The project is very similar to the TIX clock
    Who knows what's appropriate at this stage?· Taking a look at it, it might be a bit of a bugger, in my opinion, to render it in a 8 x 4 matrix.

    Post Edited (PJ Allen) : 12/26/2006 11:52:48 PM GMT
  • pjvpjv Posts: 1,903
    edited 2006-12-27 00:02
    Hi Chris and Guenther;

    Guenther; I'm afraid I must disagree with you.

    At the current I indicated, most LEDs give off significant brightness, even when multiplexed 4 to 1. I have a set up here in front of me using 7 segment displays with segment column resistors of 1K Ohm giving plenty of brightness at about 1/2 milliAmp !· Why not try the simplest solution before assuming it's inadequate. After all he is looking for a low cost (and presumably simple) answer. My suggestion is as simple as it gets.

    For real bright industrial applications, I also have·used the 4 NPN "bank" transistors. But using segment column transistors however is way over-designed unless you are really going to silly currents. With the performance of today's LEDs, the extra circuitlry just does does't buy you that much.

    I have attached the co-operative RTOS (sequencer), multiplexing and counting (seconds and minutes) code...... it's ready to run.

    id 'LEDMux1' ; Dec 26, 2006
    ;for demonstration purposes assume 4 digits of 7 segment display; MM SS
    ;can be readily expanded to 6 digits of 7 segments; HH MM SS
      Device SX28, OscHS3, Turbo, Optionx ;new assembler
    ;  Device watchdog   ;turn the watchdog on
    ;  Device bor42    ;turn brown-out detect on
    ;  Device carryx    ;turn extended carry on
    ;  Device protect    ;turn program read protection on
       Freq 50_000_000   ;default run speed = 50MHz
       Reset Initialize   ;start at label on reset
       IRC_Cal IRC_Slow   ;
    ;Constants for the Mode register settings
    ModeComp equ $08    ;mode for port B comparator swap access
    ModeBPend equ $09    ;mode for port B change detect sawp access 
    ModeBEdge equ $0A    ;mode for port B change rising edge selection (0)
    ModeBEnable equ $0B    ;mode for port B change detection enable (0)
    ModeSchmidt equ $0C    ;mode for port  BC bit Schmidt trigger enable (0)
    ModeLevel equ $0D    ;mode for port ABC bit CMOS level selection (0)
    ModePullup equ $0E    ;mode for port ABC bit pullup selection (0)
    ModeTristate equ $0F    ;mode for port ABC bit output direction selection (0)
    ;Constants for the option register
    ;      +---------------------------- 0 for Wreg at address 1
    ;      |+--------------------------- 0 for RTCC roll over interrupt enable
    ;      ||+-------------------------- 0 for RTCC increment on instruction clock
    ;      |||+------------------------- 0 for RTCC rising edge increment
    ;      |||| +----------------------- 0 for RTCC prescaler assignment
    ;      |||| |+---------------------- Prescaler 2
    ;      |||| ||+--------------------- Prescaler 1  
    ;      |||| |||+-------------------- Prescaler 0 14kHz watchdog; 000 is 16 mSec
    ;      |||| ||||
    RTCC_Dis_Ext_H2L__WDT = %1111_1000   ;
    RTCC_Dis_Int_H2L__WDT = %1101_1000   ;
    RTCC_Ena_Ext_H2L__WDT = %1011_1000   ;
    RTCC_Ena_Int_H2L__WDT = %1001_1000   ;
    Wreg_Dis_Ext_H2L__WDT = %0111_1000   ;
    Wreg_Dis_Int_H2L__WDT = %0101_1000   ;
    Wreg_Ena_Ext_H2L__WDT = %0011_1000   ;
    Wreg_Ena_Int_H2L__WDT = %0001_1000   ;
     
    IntConst    equ -125                 ;2.5 usec base tick
    SourcePort  equ rb                   ;drives up to 8 simultaneous leds in one bank; 4 banks in parallel 
    SinkPort    equ ra                   ;sinks 4 banks, one bank per bit
    ZeroPattern equ %0011_1111           ;segments to display a 0 on seven segment display
     
      org 8
    Flags  ds 1    ;
    IntFlag  equ Flags.0
      
      org $10
    Timer100uSec ds 1     ;down counts number of 2.5 uSec ticks toward one 100 uSec tick
    Timer1mSec   ds 1     ;downcounts number of 100 uSec ticks toward one 1 mSec tick
    Timer10mSec  ds 1     ;downcounts number of 1 mSec ticks toward one 10 mSec tick
    Timer100mSec ds 1     ;downcounts number of 10 mSec ticks toward one 100 mSec tick
    Timer1Sec    ds 1     ;downcounts number of 100 mSec ticks toward one 1 Second tick
    Seconds1     ds 1     ;up count seconds
    Seconds10    ds 1     ;up count tens of seconds
    Minutes1     ds 1     ;up count minutes
    Minutes10    ds 1     ;up count tens of minutes
    MuxState     ds 1     ;round-ribin muliplexer state variable
    Bank0Leds    ds 1     ;Leds to be multiplex activated in bank 0
    Bank1Leds    ds 1     ;Leds to be multiplex activated in bank 1
    Bank2Leds    ds 1     ;Leds to be multiplex activated in bank 2
    Bank3Leds    ds 1     ;Leds to be multiplex activated in bank 3
    watch Seconds1,8,udec
    watch Seconds10,8,udec
    watch Minutes1,8,udec
    watch Minutes1,8,udec
    watch Bank0Leds,8,ubin
    watch Bank1Leds,8,ubin
    watch Bank2Leds,8,ubin
    watch Bank3Leds,8,ubin
     
      org 0                                 ;
    Interrupt   setb IntFlag                ;indicate that an interrupt has occurred
                mov w,#IntConst             ;
                retiw                       ;
     
     
    Initialize ;Program starts here on power-up and on reset; must be on page 0 ========================================================
    InitLevels  mov m,#ModeLevel            ;Set to 0 for CMOS levels
                mov !ra,#%0000              ;
                mov !rb,#%0000_0000         ;
                mov !rc,#%0000_0000         ;
    InitPullup  mov m,#ModePullup           ;Set to 0 for pullups
                mov !ra,#%0000              ;
                mov !rb,#%0000_0000         ;
                mov !rc,#%0000_0000         ;
    InitTris    mov m,#ModeTristate         ;Set to 0 for output
                clr ra                      ;
                mov !ra,#%1111_0000         ;sinking port X,X,X,X_Sink3,Sink2,Sink1,Sink0
                clr rb                      ;
                mov !rb,#%0000_0000         ;source port LED7,LED6,LED5,LED4_LED3,LED2,LED1,LED0
                clr rc                      ;  
                mov !rc,#%1111_1111         ;not used
    ClrMem      clr fsr                     ;beginning of ram
    ClrOne      setb fsr.4                  ;stay in upper half
                clr ind                     ;clear location
                incsz fsr                   ;next location
                jmp  ClrOne                 ;continue clearing
                mov Timer100uSec,#40        ;initialize down counter to 40 * 2.5 uSec = 100 uSec
                mov Timer1mSec,#10          ;initialize down counter to 10 * 100 uSec = 1 mSec
                mov Timer10mSec,#10         ;initialize down counter to 10 * 1 mSec = 10 mSec
                mov Timer100mSec,#10        ;initialize down counter to 10 * 10 mSec = 100 mSec
                mov Timer1Sec,#10           ;initialize down counter to 10 * 100 mSec = 1 Sec
    InitRTCC    clr rtcc                    ;
                mov !option,#RTCC_Ena_Int_H2L__WDT ;
                clr Flags                   ;
    InitMux     mov MuxState,#DriveBank0    ;set up the first bank to be driven
                mov Bank0Leds,#ZeroPattern  ;start by showing the pattern for zero
                mov Bank1Leds,#ZeroPattern  ;start by showing the pattern for zero
                mov Bank2Leds,#ZeroPattern  ;start by showing the pattern for zero
                setb Bank2Leds.7            ;merge in a right hand decimal point
                mov Bank3Leds,#ZeroPattern  ;start by showing the pattern for zero
     
     
    ;MainLine Task Timer  =======================================================================================================
    Main        sb IntFlag                  ; 
                jmp Main                    ;wait here until an interrupt has happened
                clrb IntFlag                ;acknowledge the interrupt
                bank 0                      ;point to timer RAM
    Tick2_5uSec decsz Timer100uSec          ;one 2.5 uSec tick off 100 uSec timer
                jmp Main                    ;timer has not expired
                mov Timer100uSec,#40        ;reload 100 uSec down counter with 40 * 2.5 uSec = 100 uSec
    Tick100uSec decsz Timer1mSec            ;one 100 uSec tick off 1 mSec timer
                jmp Main                    ;timer has not expired
                mov Timer1mSec,#10          ;reload 1 mSec down counter with 10 * 100 uSec = 1 mSec
    Tick1mSec   call Multiplexer            ;do one bank of 8 LEDs
                bank 0                      ;point to timer RAM
                decsz Timer10mSec           ;one 1 mSec tick off 10 mSec timer
                jmp Main                    ;timer has not expired
                mov Timer10mSec,#10         ;reload 10 mSec down counter with 10 * 1 mSec = 10 mSec
    Tick10mSec  decsz Timer100mSec          ;one 10 mSec tick off 100 mSec timer
                jmp Main                    ;timer has not expired
                mov Timer100mSec,#10        ;reload 100 mSec down counter with 10 * 10 mSec = 100 mSec
    Tick100mSec decsz Timer1Sec             ;one 100 mSec tick off 1 Sec timer
                jmp Main                    ;timer has not expired
                call TimeCounter            ;do a one second clock tick
                bank 0                      ;point to timer RAM
                mov Timer1Sec,#10           ;reload 1 Sec down counter with 10 * 100 mSec = 1 Sec
                jmp Main                    ;loop in this scheduler; regulated by the interrupt tick
    
     
     
    ;Multiplexer Routine ==================================================================================
    Multiplexer mov SinkPort,#%0000_1111    ;drive all bank sinkers high during mux setup to prevent ghosting
                mov pc,MuxState             ;calculated jump to next state
     
    DriveBank0  mov SourcePort,Bank0LEDs    ;load the led pattern to driver port
                clrb SinkPort.0             ;turn this group on
                mov MuxState,#DriveBank1    ;set state variable to do bank1 next
                retp                        ;return to mainline scheduler
     
    DriveBank1  mov SourcePort,Bank1LEDs    ;load the led pattern to driver port
                clrb SinkPort.1             ;turn this group on
                mov MuxState,#DriveBank2    ;set state variable to do bank2 next
                retp                        ;return to mainline scheduler
     
    DriveBank2  mov SourcePort,Bank2LEDs    ;load the led pattern to driver port
                clrb SinkPort.2             ;turn this group on
                mov MuxState,#DriveBank3    ;set state variable to do bank3 next
                retp                        ;return to mainline scheduler
    DriveBank3  mov SourcePort,Bank3LEDs    ;load the led pattern to driver port
                clrb SinkPort.3             ;turn this group on
                mov MuxState,#DriveBank0    ;set state variable to do bank0 next
                retp                        ;return to mainline scheduler
    
     
     
    ;Clock Routines ..... assume minutes and seconds of 4 digits of 7 segment LED display =========================
    ;there are better, but less obvious ways to tackle this clock function section
    TimeCounter
    Seconds     inc Seconds1                ;increment the one second time clock counter
                mov w,Seconds1              ;load one second time clock counter
                call EncodeW2Seg            ;lookup LED pattern for this number
                mov Bank0LEDs,w             ;save it to the multiplexer routine
                cjbe Seconds1,#9,TimeExit   ;test for overflow on nine
                clr Seconds1                ;reset to 0
                mov w,Seconds1              ;one second time clock counter
                call EncodeW2Seg            ;lookup LED pattern for this number
                mov Bank0LEDs,w             ;save it to the multiplexer routine
                                            ;
    TenSeconds  inc Seconds10               ;increment the ten second time clock counter
                mov w,Seconds10             ;load ten second time clock counter
                call EncodeW2Seg            ;lookup LED pattern for this number
                mov Bank1LEDs,w             ;save it to the multiplexer routine
                cjbe Seconds10,#5,TimeExit  ;test for overflow on five
                clr Seconds10               ;reset to 0
                mov w,Seconds10             ;
                call EncodeW2Seg            ;encode this digit according to 7 segment display pattern
                mov Bank1LEDs,w             ;save it to the multiplexer routine
    Minutes     inc Minutes1                ;increment the one minute time clock counter
                mov w,Minutes1              ;load one minute time clock counter
                call EncodeW2Seg            ;encode this digit according to 7 segment display pattern
                mov Bank2LEDs,w             ;save it to the multiplexer routine
                setb Bank2Leds.7            ;merge in a right hand decimal point
                cjbe Minutes1,#9,TimeExit   ;test for overflow on nine
                clr Minutes1                ;reset to 0
                mov w,Minutes1              ;
                call EncodeW2Seg            ;encode this digit according to 7 segment display pattern
                mov Bank2LEDs,w             ;save it to the multiplexer routine
    TenMinutes  inc Minutes10               ;increment the ten minute time clock counter
                mov w,Minutes10             ;load ten minute time clock counter
                call EncodeW2Seg            ;encode this digit according to 7 segment display pattern
                mov Bank3LEDs,w             ;save it to the multiplexer routine
                cjbe Minutes10,#5,TimeExit  ;test for overflow on five
                clr Minutes10               ;reset to 0
                mov w,Minutes10             ;
                call EncodeW2Seg            ;encode this digit according to 7 segment display pattern
                mov Bank3LEDs,w             ;save it to the multiplexer routine
    TimeExit    retp                        ;retunr to mainline scheduler
    
     
     
    ;Seven Segment Encoder driven from value held in w ===============================================================
    EncodeW2Seg and w,#%0000_1111   ;lower nibble only
                add pc,w    ;step into table
    
     
    SegTable   ;pgfe_dcba   ;
    Seg0  retw %0011_1111   ;segments for 0
    Seg1  retw %0000_0110   ;segments for 1
    Seg2  retw %0101_1011   ;segments for 2
    Seg3  retw %0100_1111   ;segments for 3
    Seg4  retw %0110_0110   ;segments for 4
    Seg5  retw %0110_1101   ;segments for 4
    Seg6  retw %0111_1101   ;segments for 6
    Seg7  retw %0000_0111   ;segments for 7
    Seg8  retw %0111_1111   ;segments for 8
    Seg9  retw %0110_0111   ;segments for 9
    SegA  retw %0101_1111   ;segments for a
    SegB  retw %0111_1100   ;segments for b
    SegC  retw %0011_1001   ;segments for c
    SegD  retw %0101_1110   ;segments for d
    SegE  retw %0111_1001   ;segments for e
    SegF  retw %0111_0001   ;segments for f
     
     
     
    




    Cheers,
    Peter (pjv)
  • pjvpjv Posts: 1,903
    edited 2006-12-27 00:11
    Hi PJ;

    The LEDs simply need to be electrically connected in a matrix fasion as per Guenther's layout. Physically of course they can be anywhere.

    I suggest using Guenther's drawing, but eliminate the transistors unless you want large currents. My experience is that they just aren't required, as a few milliamps is plenty bright for most indoor applications.

    Cheers,

    Peter (pjv)
  • Chris KraftChris Kraft Posts: 20
    edited 2006-12-27 03:58
    I appreciate everyone's input. I especially like the variety of ideas. Gives me plenty to think about.

    On using the SX48 to get the extra I/O. I considered that but I am not comfortable doing the SMT stuff. I am not setup to do that yet and haven't had a chance to practice doing that type of soldering. I wish I had some broken components to practice on. I know I will have to learn it sooner or later.

    Using the dev board is a great idea but for that price I would consider using the propeller which has 32 I/O on it.

    On the suggestion to use Maxim chips. They do have some great stuff. I have a few LED display drivers here that I am using for another project. The problem I have with their stuff is its hard to find distributers sometimes, plus some of those chips end up being more expensive than I was hoping to spend. I really want to see if I can do this for a really economical price.

    I really should have given more details on what I was trying to do. I will try to explain it now:

    What I am building is a clock. It uses LEDs to show the time. The number of LEDs that are lit equal the current time. The LEDs are setup like this:

    X XXX XX XXX
    X XXX XX XXX
    X XXX XX XXX

    So if the time is 9:59 the display would be (in binary):

    0 111 11 111
    0 111 11 111
    0 111 10 111

    The LEDs that are lit change every second. This is a bad example of that because the two 9's require all the LEDs to be lit, but for the 5 the unlit LED would change every few seconds.

    Its a pretty cool clock. I could just buy a second one but I really see potential to have some fun with this thing. I figure if I have complete control over the LEDs that are lit I could do transitions between changes or all kinds of interesting things.

    I am not locked into the layout above I just wanted you to understand what my inspiration is. If it worked out better to change the layout I am comfortable with that. I just want to see if I can do this without it ending up being more than $50 or so for the parts. I already have several hundred LEDs left over from another project and I also have SX28's, some Propellers and even a SX48 which I am saving until I can learn to solder the SMT stuff.

    As far as skill level goes, I am much more comfortable on the coding side than I am on the hardware side. I have done some design work but I always did better at the coding. In my own designs I usually try to keep the electronics as simple as possible and push the work onto the code because I am much stronger in that field.

    That is why I came here and asked the questions in the first place I knew that there would be plenty of folks who would have good input on the design side. Right now I am leaning towards using the 595's but I am reviewing what Peter, Guenther and PJ added recently.

    Again I appreciate all the input. Please keep it coming. I have an open mind on this and I am willing to try anything once.

    Chris
  • LoopyBytelooseLoopyByteloose Posts: 12,537
    edited 2006-12-27 10:37
    It is tempting to consider a 3X9 matrix, but it is a somewhat bad idea.

    You could easily use the above LED layout with a 4X8 matrix by having the left most column be the short segment [noparse][[/noparse]3 bits of one byte] and then the remaining 8 columns of 3 row would provide 3 rows of 8 bits [noparse][[/noparse]3x8bits = 3 bytes.

    Try staying within 8 bits because the SXes are an 8 bit processor. The code will be more efficient.

    PJV, thanks for minimalizing the additional hardware.

    Guenther, it seems your approach would be required for a 16x16 led matrix [noparse][[/noparse]I can't display Chinese in 8X8].

    I still like the Shift registers, but PJV is correct about less code being involve. Still I don't think you are going to run out of EEPROM with either choice. Also, there are 'high power shift registers' that can drive bigger lights. And in some cases, you could use MOSfets to drive bigger lights.

    I suspect it is more a question of needing the unused I/O pins or not.

    And thanks for the interesting discussion on power capabilities.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    "If you want more fiber, eat the package.· Not enough?· Eat the manual."········
    ···················· Tropical regards,····· G. Herzog [noparse][[/noparse]·黃鶴 ]·in Taiwan
  • PJAllenPJAllen Banned Posts: 5,065
    edited 2006-12-27 11:11
    As I posted, I took a look at this TIX clock.· Everybody hop over there and have a gander.· A "4", for instance,·is represented by lighting 4 LEDs, but it isn't the same LEDs lit each time; the same number in consecutive digits will be rendered differently.· It's not binary at all, it's a real hodge-podge.·
    • Getting each group to do the random lighting (but correct count) will be a challenge.·
    • Working that out with a 8x4 will get interesting, too.·
    • And shoe-horning it all into an SX_... have fun with that and let us all know how it works out.

    With the SX48 proto-boards being $9.95, I figure anybody can be,·you know,·shockingly, scandalously extravagant with I/O pins.· How can you go wrong?·

    Well, I guess you could go wrong by exceeding the device dissipation limits because you skrimped in exactly the wrong places, etc. but, I digress.


    Post Edited (PJ Allen) : 12/27/2006 11:15:48 AM GMT
  • Guenther DaubachGuenther Daubach Posts: 1,321
    edited 2006-12-27 11:23
    Hi all,

    as I had mentioned in my previous post, the additional transistors are only required when the worst-case current load exceeds the maximum limits of the SX. Insofar, I agree with Peter - when you select current-limiting resistors that keep the currents low enough, and the LEDs still have an acceptable brightness, you may just eliminate the transistors.

    In my example, I wanted to point out that it is not only important to check if any of the SX port pins sources or sinks current beyond the maximum limit (45 mA) but also to make sure that the total current through the Vdd and Vss pins does not exceed the absolute maximum of 130 mA which is often overlooked.

    Peter suggested to possibly use the four "bank" or row transistors but to omit the eight segment or column transistors. Well, each of the row drivers may need to sink the current of eight LEDs in worst case, where the column drivers need to source the current of four LEDs only. So, with four row driver transistors, the current of 8 * Iled no longer needs to be sinked by the port pins, and it is also bypassed from the Vss pin. In this configuration, the current of 8 * Iled is still distributed among eight column port pins, so the current each port pin needs to source may be below 45 mA. Nevertheless, the SUM, i.e. 8 * Iled is still sourced through the Vdd pin. So when this current is higher than 130 mA, the four row transistors alone don't solve the problem, and the eight column transiostors are required to also bypass the Vdd pin.

    BTW: I'l like to draw the attention of other readers of Peter's sample code to one line which may not look that important at first glance. It is the first line in the Multiplexer subroutine:

    Multiplexer mov SinkPort,#%0000_1111 ;drive all bank sinkers high during mux setup to prevent ghosting

    When you remove the instruction in this line, you may not notice any difference when the LEDs are driven. Nevertheless, this instruction avoids any "glitches". Without setting all row lines high before changing the column output for the next row, the LEDs in the current row would shortly be driven with that pattern until the next row line is driven low. Turning "off" all row lines before changing the column information, and then turning "on" the new row line avoids such unneccessary switching, reduces dissipation losses and EMI.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Greetings from Germany,

    G
  • pjvpjv Posts: 1,903
    edited 2006-12-27 18:18
    Hi PJ;

    I'm not understanding what your concern is. The multiplexing scheme of four banks of eight leds permits any and all leds to be 'on' at any time, so I don't follow how that is impacted by the patters the clock wants to display. The bits of the registers in my code named Bank0LEDs, Bank1LEDs, Bank2LEDs and Bank3LEDs hold the fact whether a LED is on or off. How those bits get set and altered is the 'artistic' creative function of the clock, and that really does not appear too hard to do .... just a random pattern generator making the correct count of 'on' bits per 'character'. That is the element Chris was looking to put his own 'spin' on. What LED is in which physical space is incidental.

    Guenther ... well said.

    Personally, I am a staunch minimalist ...... I strive for the absolute minimum component count to get the job reasonably well done albeit perhaps not as perfectly as possible. I also realize that method is inappropriate for commercial or safety issues, and if I were working for NASA, I certainly would over-design. For the hobby scene, I take pleasure in the minimum solution. And I guess that's OK as long as one also knows the 'proper' method, and where to draw the line.

    Cheers,

    Peter (pjv)
  • Guenther DaubachGuenther Daubach Posts: 1,321
    edited 2006-12-27 18:40
    Peter,

    I absolutely agree with you - not only for hobby use, but also for commercial projects reducing component count makes a lot sense. A component which is not there can't fail at all smile.gif . It is amazing what kind of stresses the SX controllers can stand. I don't know how often I had shorts on output pins without killing the SX. Although this is not mentioned anywhere in the data sheet, I sometimes have the impression that the output drivers have some built-in overload protection. Nevertheless, I don't want to encorage users to drive their SXes beyond the limits.

    BTW, I'm not yet working for NASA. Although I have visited Kennedy Airspace Center in Florida this year, they did not make me a job offer - maybe, I'd better asked smile.gif .

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Greetings from Germany,

    G
  • LoopyBytelooseLoopyByteloose Posts: 12,537
    edited 2006-12-28 09:22
    A few years [noparse][[/noparse]late 90s] back NASA was looking for 8088 processors to re-supply their in-use space shuttle computer systems. They may not yet be ready for you Guenther.

    But this surely demonstrates that a lot can be done with very little. In this case, I suspect the shift registers are absolutely not needed and that one would learn a lot more by choosing the matrix approach.

    I too appreciate the minimalist approach [noparse][[/noparse]it frees up a lot of building time] but pjv thinks at light speed. I have his RTO system up and running here [noparse][[/noparse]has been reliable for months], but without any introductory material on multiple threads it took months for me to begin to understand it.

    In this case, the LED matrix is a much simpler concept to understand, but a lot of people don't grasp that you can turn on and off groups of I/O in a systematic fashion. Adding that the scan must shift from 3 row of 8bits to one row of 3bits, isn't a good confidence builder for a newcomer.

    All my problems in teaching always become resolved by getting down to the student's level. Lower the learning curve and more will follow.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    "If you want more fiber, eat the package.· Not enough?· Eat the manual."········
    ···················· Tropical regards,····· G. Herzog [noparse][[/noparse]·黃鶴 ]·in Taiwan
  • Guenther DaubachGuenther Daubach Posts: 1,321
    edited 2006-12-29 10:37
    Kramer,

    ok, I'll wait a while before contacting NASA. Maybe, I can make them aware of me when I let them know that I still have a bunch of 8" floppy disks here, and I think also have an 8" floppy drive here somewhere smile.gif .

    BTW: Many years ago, I used the shift register approach to control a couple of 100 LEDs from a Z80. If you would try to arrange such a large number of LEDs in ONE matrix, the peak currents required to operate the LEDs at a reasonable brightness would be way beyond the absolute maximum for the LEDs, and such a matrix would also be a nice EMI generator.

    Therefore, I like the shift register approach when it is necessary to drive a large number of LEDs. When you use shift registers with latches, the nice fact is that you can shift in a new pattern first, and then latch this pattern out to the LEDs. So the LEDs don't flicker while the new pattern is shifted in, and all signals are steady as long as the LED pattern is not changed.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Greetings from Germany,

    G
  • LoopyBytelooseLoopyByteloose Posts: 12,537
    edited 2006-12-29 17:38
    That is the way they do it on the large scrolling LED signs. It is a combination of matrix [noparse][[/noparse]to reduce wiring] and shift registers [noparse][[/noparse]to buffer data and distribute power].

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    "If you want more fiber, eat the package.· Not enough?· Eat the manual."········
    ···················· Tropical regards,····· G. Herzog [noparse][[/noparse]·黃鶴 ]·in Taiwan
Sign In or Register to comment.