PDA

View Full Version : 16-Channel LED Drivers



Sponge Bob
- 13th February 2009, 02:56
Ok newbie post here and I tried searching for the answer but couldn't find any hits, and the captcha image challenge were really complicating searches. I guess my eyes are not as good as I thought.

Anyway I'm looking for what is probably some very simple code, but my serial communication programming skills are in the gutter, so I'm hoping someone can give me some basic starter code to give me a jump start.

I have the TLC5940 and MAX16809 chips for testing and I'm open to other chips as well, if someone is more familiar with a certain 16 channel LED driver chip go with that.

Basically I just want to use a 16 channel LED driver to replace multiple darlington arrays, resistors and free up ports on the micro. I'm not all that interested in the dimming and grey scale abilities of the chip. More interested in just turning on and off the LEDs independently at full level.

Also at this point I'm not tied to any chip so lets just say some generic code or pick a chip.

If anyone can toss together some code that lets say, turns on the LEDs sequentially and then turns them off sequentially I would be a happy camper as I'm sure I can figure the rest out from there. Also if I understand things correctly I need to clock the chips so that part of the code and maybe some explanation of hookup would be helpful.

Thanks in advance.

Jerson
- 13th February 2009, 03:50
Squarepants ;)

Welcome to the forum.

You havent mentioned what you really want to do and with which PIC. Will multiplexed LEDs suit your need ? What is your intended application? Why the particular chips you mention? These clarifications and I'm sure, someone will be able to help you out.

Sponge Bob
- 13th February 2009, 04:35
Squarepants ;)

Welcome to the forum.

You havent mentioned what you really want to do and with which PIC. Will multiplexed LEDs suit your need ? What is your intended application? Why the particular chips you mention? These clarifications and I'm sure, someone will be able to help you out.

What I want is independent control of the 16 (or more) LEDs while removing most of the resources from the PIC side. If that makes any sense. I want to be able to still use the majority of the other I/O ports on the pic for other things while not being burdened by constantly controlling the 16 (or more) LEDs... Also the use of a driver chips increases the source/sink levels and allows me to limit all channels current with a single resistor. Lower parts count and smaller circuit size. I figure even for basic applications the single chip replaces darlington arrays and multiple current limiting resistors, lowering the parts count almost immediately.

As for the particular chips I mentioned only because I have those on hand, any 16 channel controller will work, not picky at all right now, and I'm open to other chips... The reason I want to go this way instead of multiplexing is the ability to cascade these chips and expand to lots of LEDs while not increasing the number of used I/O pins on the chip... If my understanding is correct, I should be able to control 100s of LED independently from even a pic16f628a with plenty of left over I/O lines by cascading the controller chips. Multiplexing directly off the pic in the end (unless I'm missing some trick) will incur substantially more parts and I/O lines as the number of LEDs increase.

Hope that clarifies things.

Jerson
- 13th February 2009, 08:07
I get it now. You want a serial to parallel converter with darlington drivers to handle LEDs and you want it to be expandable. You're right in saying that the 16F628A could handle lots of LEDs with this technique. However, you should be aware that though you are saving on the pins at the PIC, you are not lowering the burden on its coding. It will keep updating the LEDS at a regular rate to let you have the moving patterns you wish for.

The commands could help you are SHIFTOUT or maybe I2C_READ depending on which is relevant to the chips you want to use and how 'low cost' you want to design.

Sponge Bob
- 13th February 2009, 08:55
You want a serial to parallel converter with darlington drivers to handle LEDs and you want it to be expandable.

Yep, exactly PICs are great but once you start compounding high numbers of LEDs at 20mA a piece you start to tax the PICs sink/source limits pretty fast.


However, you should be aware that though you are saving on the pins at the PIC, you are not lowering the burden on its coding. It will keep updating the LEDS at a regular rate to let you have the moving patterns you wish for.

Yes I'm aware of this, in applications where there is constant motion it won't save much cpu time, but vs the alternative of multiplexing where you need the tight loop just to simulate shared pin LEDs being illuminated at the same time I believe it really shines.

Just for example if I wanted a large debounce on a switch, or flat out pause in the code multiplexing would fall flat on it's face unless you slowly chunk away the pause(s) within the multiplexing loop. I would rather avoid this and simply have a driver chip keep the LEDs illuminated independent of the PIC when it take a deep breath.


The commands could help you are SHIFTOUT or maybe I2C_READ depending on which is relevant to the chips you want to use and how 'low cost' you want to design.

Yeah, but as I said I'm a little challenged on the code, so a little helper code would go a long way... It's one of those things I understand the whole concept but for some reason I can't put two and two together and actually write the code. Just one of those stupid brain blocks.

Also maybe to make this simpler I will narrow it down to the PIC16f628A and the TLC5940. That way everyone is on the same page.

sinoteq
- 13th February 2009, 09:07
Check out National's Funlight driver. http://www.national.com/mpf/LP/LP3943.html

Works like a charm but is pig to solder.

Jumper
- 13th February 2009, 09:31
If you really don't want dimming or blinking the LED why don't you go for an i/o expander chip such as MCP23016. I2C controlled and you can even use it as inports for different stuff.

Best invention since canned beer!

They do the same job as a led driver but you have alot less registers to fight with.

/me

Sponge Bob
- 13th February 2009, 10:28
why don't you go for an i/o expander chip such as MCP23016


Check out National's Funlight driver. http://www.national.com/mpf/LP/LP3943.html

I would consider the above if the source/sink wasn't so low, I would like a little more available juice. I know for most LED applications the 25mA will work but I would still prefer a little bit more.

The TLC5940 gives me 120mA a channel, part of the reason I picked that one.

elec_mech
- 13th February 2009, 13:34
Sponge_Bob,

I think I've got your solution. I've been doing similar things with LEDs lately and my favorite driver IC to date is the SP16DP05. It has 16 channels and uses a simple SPI interface to the PIC to turn LEDs on or off. I've included a schematic showing several LEDs in series per pin, but you can just as easily use one per channel. I don't immediately recall what the upper current limit of this chip is, but it is healthy. Here's a snippet of code:



SHIFTOUT SDI, CLK, 1, [16bit_value\16] ' Send data to STP16DP05
HIGH LE ' Enable the STP16DP05
LOW LE ' Disable the STP16DP05


Setting 16bit_value to $FF or %1111111111111111 would turn on all the LEDs while sending $00 or %0000000000000000 would turn off all LEDs. Each bit in the 16-bit value controls one of the 16 outputs.

I also bought an Allegro A6278 which looks to do about the same thing - upper limits are a little lower - and it's almost half the cost of the STP16DP05 on Digikey. I haven't played with it yet, but it should work and hook up nearly the same way if cost is a big concern. Otherwise go with STP16DP05. I hope this helps.

Sponge Bob
- 14th February 2009, 21:06
Thanks for the suggestion on chips, the STP16DP05 and A6278 both look like viable options, the higher mA and single max current limiting resistor are exactly what I was looking for.

I will have to order a few of them for testing.

Also thanks for the pseudo code, but is there anyway I could beg, plead or cry for a snippet of real code that I could immediately compile and load on a pic16f628a so I could be off and running without the inevitable frustration of one stupid missed syntax or dumb hardware mistake that leads me down the debugging road with no solid working basis? :D

I'll pick up the STP16DP05 and A6278 so no preference on what one the code is for...

Nothing fancy even just the all on all off example you hinted at. Just something to build upon.

I know it sounds lazy and it is no doubt, but many times the frustration takes all the fun out of the hobby and I never get things working.

elec_mech
- 16th February 2009, 01:39
Sponge_Bob,

Tsk, tsk - you're lucky I'm in a generous mode tonight. :D Alright, first thing to do is open the PBP INC file for the 16F628A and comment out the config line. Assuming you're using Windows and have everything installed in the default locations go to: C:\pbp and open the file named 16F628A.INC. Place a semicolon in front of the line starting with: __config and save the file.

I've included a schematic to try out. And here's some code to try:



INCLUDE "modedefs.bas"
asm
__config _INTOSC_OSC_NOCLKOUT & _WDT_OFF & _MCLRE_ON & _LVP_OFF & _CP_OFF & _BOREN_OFF & _PWRTE_ON
endasm

DEFINE OSC 4 ' Tell the program the oscillator is running at 4 MHz
CMCON.0 = 1 ' Turn off comparators
CMCON.1 = 1 ' Turn off comparators
CMCON.2 = 1 ' Turn off comparators
VRCON.6 = 0 ' Disconnect Vref from RA2
VRCON.7 = 0 ' Vref is powered off
TRISA = %11111111 ' Make all port a pins inputs
TRISB = %11101000 ' Make port b pins 0-2 & 4 outputs and the rest as inputs
PORTA = $00 ' Set all port a pins to low
PORTB = $00 ' Set all port b pins to low

SPI VAR PORTB.2 ' Serial input to STP16DP05
CLK VAR PORTB.1 ' Clock input to STP16DP05
LE VAR PORTB.0 ' Enable pin for STP16DP05
OE VAR PORTB.4 ' PWM / ON & OFF for LEDs
LED_value VAR word ' Variable used to send data to STP16DP05
flip VAR bit ' Used to determine which direction to scroll LEDs

LOW OE ' Turn on LEDs
LED_value = $FFFF ' Set LED value equal to $FFFF to turn on all the LEDs
'************************************************* **********************************************
Test: ' Test Routine - Flash all LEDs once
SHIFTOUT SDI, CLK, 1, [LED_value\16] ' Send data to STP16DP05
HIGH LE ' Enable the STP16DP05
LOW LE ' Disable the STP16DP05
PAUSE 500 ' Wait for half a second
LED_value = $0000 ' Set LED value equal to zero to turn off all the LEDs
SHIFTOUT SDI, CLK, 1, [LED_value\16] ' Send data to STP16DP05
HIGH LE ' Enable the STP16DP05
LOW LE ' Disable the STP16DP05
PAUSE 500 ' Wait for half a second
'************************************************* **********************************************
' To do the same thing without sending data to STP16DP05 multiple times, try this:
LED_value = $FFFF ' Set LED value equal to $FFFF to turn on all the LEDs
SHIFTOUT SDI, CLK, 1, [LED_value\16] ' Send data to STP16DP05
HIGH LE ' Enable the STP16DP05
LOW LE ' Disable the STP16DP05
PAUSE 500 ' Wait for half a second
HIGH OE ' Turn off all LEDs regards of state of latches on STP16DP05
PAUSE 500 ' Wait for half a second
'************************************************* **********************************************
LOW OE ' Turn on all LEDs where latches are enabled
LED_Value = $0001 ' Set LED value to %0000000000000001 to turn on first LED
'************************************************* **********************************************
Main: ' Main Routine - Simple Knight Rider Effect
SHIFTOUT SDI, CLK, 1, [LED_value\16] ' Send data to STP16DP05
HIGH LE ' Enable the STP16DP05
LOW LE ' Disable the STP16DP05
IF LED_value = $8000 THEN flip = 1 ' If LED value is equal to %1000000000000000, then set flip equal to one
IF LED_value = $0001 THEN flip = 0 ' If LED value is equal to %0000000000000001, then set flip equal to zero
IF flip = 0 THEN ' If flip is equal to zero, then
LED_value = LED_value << 1 ' Shift LED value to left by one
ELSE ' If flip is not equal to zero, then
LED_value >> 1 ' Shift LED value to left by one
ENDIF ' End if statement
PAUSE 500 ' Wait for half a second
GOTO Main ' Go to Main routine
'************************************************* **********************************************
END ' End program should it run awry


Now, please note that I haven't tried this code out, but hopefully it's enough to get you started. Let me know if you have any problems and good luck!

Sponge Bob
- 16th February 2009, 04:48
Sponge_Bob,

Tsk, tsk - you're lucky I'm in a generous mode tonight

Thank you much, even though I'm a newbie here, I know it's taboo to asked for such, but I honestly learn better by example like this it gives me a much better start on figuring the rest out. I have spent countless hours trying to figure out stupid stuff, and yes I learned how to do it, but I would have learned it just as well if someone set me in the right direction.

Parts were ordered this weekend so I should have them later this week and can test this all out, hoping for the best.

Also you had mentioned Digikey for the part, Mouser has then for about $1 cheaper but they don't carry the DIP version but if the SO-24 works for you it might be considered.