Looking for advice on driving a moderate number of LED's
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
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
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."········
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!! ]
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
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
It's Only A Stupid Question If You Have Not Googled It First!!
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)
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
People ask about thus and sundry, but one seldom knows their skill-set, so they're either overwhelmed or underwhelmed.
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.· 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
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 fCheers,
Peter (pjv)
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)
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
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."········
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
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
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)
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
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
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Greetings from Germany,
G
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."········
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
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
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"If you want more fiber, eat the package.· Not enough?· Eat the manual."········