UNL2003 for 12V LEDs

Total noob here. I've researched this quite a bit and think I understand, but I just want confirmation so I don't fry anything.

I am planning on using the Arduino to control a UNL2003A which will control secondary 12V circuits that will illuminate large 12V LEDs.

Do I just connect the 12V LED as usual (no resistors - just battery to LED) and run the ground to the UNL2003 so the Arduino can control it? Or do I need resistors or other electronics?

Do I need to ground all the unused pins on the UNl2003?

Can I share the ground for the Arduino curcuit (9V) and the secondary curcuit (12V), even if they have different voltages (I'd rather keep the Arduino circuit at 9V to avoid overheating issues discussed elsewhere)?

Thanks in advance, and I apologize for any glaring ignorance in my questions...

Hello,

First of all, uln2003 is a rather old-fashioned part. If you already have one, by all means use it but don't buy any more. Buy something more modern like tpic6*595.

Secondly, when you say 12V leds, I'm assuming they have built-in current limiting of some kind. Post a link for checking.

You can connect it as you described with no other components. You can leave the unused pins unconnected.

You MUST connect the 9V and 12V grounds, or it won't work.

As long as the Arduino is not supplying much current to other components, overheating should not be a problem and you can supply 12V to the Arduino. Controlling the uln chip will require almost no current.

Paul

I've looked up tpic6*595 and read the spec sheets, but i can't figure out how it is better than the UNL2003A. Can you please let me know why it is better?

Because it is a FET output device and the power dissipation of the FETs is way lower than the power dissipation of the UNL2003A.

You need seven (or eight) pins Arduino pins for every ULN2003 (or ULN2803), so for 21 ULN outputs you would need 21 Arduino outputs. However, you could put a 74hc595 shift register between the Arduino and the ULN chip. Then you would only need 3 Arduino outputs to control 7, 14, 21, or almost as many as ULN outputs you like, using only 3 Arduino outputs.

One advantage of the TPIC chips is that they combine the shift register and ULN chip into one.

Another advantage of the TPIC chips is that they use FETs as their high-current outputs. The ULN chips use Darlington transistors. The FETs have a much lower voltage drop than the Darlingtons. There are two advantages to having a lower voltage drop. One is that more of the 12V supply is available to run your LEDs. The Darlingtons probably drop around 1.5V, leaving 10.5V for your LEDs. The FETs drop only a small voltage, leaving almost the entire 12V for your LEDs. The second advantage is that, because of the higher voltage drop, the Darlingtons will dissipate more heat and get quite warm, which reduces their life, or if they get too hot, causes them to fail. The FETs will stay quite cool under the same conditions.

Thanks for that. It clears things up a bit.

Does that mean that I may not be able to power my 12V LEDs with the UNL2003, as it will only leave 10.5V for the LED? Maybe I should use a high voltage, in that case.

Any chance you can direct me to some reading about how to use it? I can't seem to find stuff on it explaining how to use the inputs as you describe. It certainly sounds promising.

Thanks again,

Fed

Fed, like i said before, if you already have a uln, use it. It will probably be fine.

Not sure what you are asking about, uln or tpic?

I found a nice video explaining the shift register:
http://make.markdereijer.nl/electronics/shift-register/

And for programming the Arduino to use it:

Btw, i set up my circuit with the UNL2003. It works fine.
Thanks for your help!

Ok, so things have expanded now that I got things working. I think I need the TPIC6*595. Any idea which I should get? A, B, or C?

I am looking to have 16 outputs. 8 on one chip local, and 8 on another at a distance of about 30ft using ethernet cable to connect the chip to the Arduino. Do you happen to know if that distance would create a problem with the signal? The signal would be at 5V, I suppose.

Also, is there any shift register for inputs as well. I am looking to have 13 inputs, 7 local, and 6 at 30ft.

Thanks again!

Feddar:
I think I need the TPIC6*595. Any idea which I should get? A, B, or C?

Depends on your leds. A and B have higher current capacity than C and D.

Feddar:
I am looking to have 16 outputs. 8 on one chip local, and 8 on another at a distance of about 30ft using ethernet cable to connect the chip to the Arduino. Do you happen to know if that distance would create a problem with the signal? The signal would be at 5V, I suppose.

I don't know. Possibly a problem. You will have to test.

Feddar:
Also, is there any shift register for inputs as well. I am looking to have 13 inputs, 7 local, and 6 at 30ft.

Maybe 74hc164?

Where do you order the TPIC from? I'm in Canada, and it looks like digikey delivers here.

The input shift register i found is 74HC165, which looks like it requires 4 inputs (in addition to the ground and 5V), and the CD4021BE which looks like it requires pnly 3 inputs (plus ground and 5V). Does anyone happen to know the diffirence between these two?

CD4021BE is older, slower technology.
74HC165 is newer, faster technology.

Can use SPI signals connected to both shift-in and shift-out registers at the same.
MISO connected to '165s, MOSI connected to '595s, SCK to both. Load connected to '165 to capture data, and to '595 to move data from input register to output register. (or use separate line for each).

CrossRoads:
CD4021BE is older, slower technology.
74HC165 is newer, faster technology.

Can use SPI signals connected to both shift-in and shift-out registers at the same.
MISO connected to '165s, MOSI connected to '595s, SCK to both. Load connected to '165 to capture data, and to '595 to move data from input register to output register. (or use separate line for each).

Sorry, but I don't understand. Are you saying you can connect to both 595s and 195s using only 5 pins?

I've looked up SPI, and it seems to be yet another level of complexity.

But it made me think, can the 165 and 595 share the same latchPin or clockPin, and then have the Arduino collect the information and send information on diffirent pins?

Yes. MISO comes from 165, MOSI goes to '595. Say you had 4 of each daisychained:

digitalWrite (latchPin, LOW);
digitalWrite (latchPin, HIGH); // capture '165 inputs
dataIn0 = SPI.transfer(dataOut0); // read 165 while load '595
dataIn1 = SPI.transfer(dataOut1); // read 165 while load '595
dataIn2 = SPI.transfer(dataOut2); // read 165 while load '595
dataIn3 = SPI.transfer(dataOut3); // read 165 while load '595
digitalWrite (latchPin, LOW);
digitalWrite (latchPin, HIGH); // move 595 outputs to output register

I still think SPI will mess me up quite a bit, considering all the issues to consider (from my limited reading about it).

You see, my problem is that I want to keep my wires to 8, so I can use a Cat5 cable to connect the Arduino to a second button/LED box in a different room. In order to use a newer input shift register, SN74HC165N, I need Vcc, ground, clock, clock enable, serial in, and latch (sorry about the terminology mixup here), which leaves me with 2 for the output shift register, TPIC6B595. I can share the Vcc and ground, and so I am only 1 short. If I can also share the latch then I am set, but I suspect I cannot, unless I use SPI. Is that correct?

If that is correct, then the older input register, CD4021BE, would be better, because it only uses clock, serial in, and latch. Again, is this correct? If so, then I could use the Cat5 cable.

The code I am planning on using for the former case is the following. Can the latch be shared somehow easily in it?

/*
 * SN74HC165N_shift_reg
 *
 * Program to shift in the bit values from a SN74HC165N 8-bit
 * parallel-in/serial-out shift register.
 *
 * This sketch demonstrates reading in 16 digital states from a
 * pair of daisy-chained SN74HC165N shift registers while using
 * only 4 digital pins on the Arduino.
 *
 * You can daisy-chain these chips by connecting the serial-out
 * (Q7 pin) on one shift register to the serial-in (Ds pin) of
 * the other.
 * 
 * Of course you can daisy chain as many as you like while still
 * using only 4 Arduino pins (though you would have to process
 * them 4 at a time into separate unsigned long variables).
 * 
*/

/* How many shift register chips are daisy-chained.
*/
#define NUMBER_OF_SHIFT_CHIPS   2

/* Width of data (how many ext lines).
*/
#define DATA_WIDTH   NUMBER_OF_SHIFT_CHIPS * 8

/* Width of pulse to trigger the shift register to read and latch.
*/
#define PULSE_WIDTH_USEC   5

/* Optional delay between shift register reads.
*/
#define POLL_DELAY_MSEC   1

/* You will need to change the "int" to "long" If the
 * NUMBER_OF_SHIFT_CHIPS is higher than 2.
*/
#define BYTES_VAL_T unsigned int

int ploadPin        = 8;  // Connects to Parallel load pin the 165
int clockEnablePin  = 9;  // Connects to Clock Enable pin the 165
int dataPin         = 11; // Connects to the Q7 pin the 165
int clockPin        = 12; // Connects to the Clock pin the 165

BYTES_VAL_T pinValues;
BYTES_VAL_T oldPinValues;

/* This function is essentially a "shift-in" routine reading the
 * serial Data from the shift register chips and representing
 * the state of those pins in an unsigned integer (or long).
*/
BYTES_VAL_T read_shift_regs()
{
    long bitVal;
    BYTES_VAL_T bytesVal = 0;

    /* Trigger a parallel Load to latch the state of the data lines,
    */
    digitalWrite(clockEnablePin, HIGH);
    digitalWrite(ploadPin, LOW);
    delayMicroseconds(PULSE_WIDTH_USEC);
    digitalWrite(ploadPin, HIGH);
    digitalWrite(clockEnablePin, LOW);

    /* Loop to read each bit value from the serial out line
     * of the SN74HC165N.
    */
    for(int i = 0; i < DATA_WIDTH; i++)
    {
        bitVal = digitalRead(dataPin);

        /* Set the corresponding bit in bytesVal.
        */
        bytesVal |= (bitVal << ((DATA_WIDTH-1) - i));

        /* Pulse the Clock (rising edge shifts the next bit).
        */
        digitalWrite(clockPin, HIGH);
        delayMicroseconds(PULSE_WIDTH_USEC);
        digitalWrite(clockPin, LOW);
    }

    return(bytesVal);
}

/* Dump the list of zones along with their current status.
*/
void display_pin_values()
{
    Serial.print("Pin States:\r\n");

    for(int i = 0; i < DATA_WIDTH; i++)
    {
        Serial.print("  Pin-");
        Serial.print(i);
        Serial.print(": ");

        if((pinValues >> i) & 1)
            Serial.print("HIGH");
        else
            Serial.print("LOW");

        Serial.print("\r\n");
    }

    Serial.print("\r\n");
}

void setup()
{
    Serial.begin(9600);

    /* Initialize our digital pins...
    */
    pinMode(ploadPin, OUTPUT);
    pinMode(clockEnablePin, OUTPUT);
    pinMode(clockPin, OUTPUT);
    pinMode(dataPin, INPUT);

    digitalWrite(clockPin, LOW);
    digitalWrite(ploadPin, HIGH);

    /* Read in and display the pin states at startup.
    */
    pinValues = read_shift_regs();
    display_pin_values();
    oldPinValues = pinValues;
}

void loop()
{
    /* Read the state of all zones.
    */
    pinValues = read_shift_regs();

    /* If there was a chage in state, display which ones changed.
    */
    if(pinValues != oldPinValues)
    {
        Serial.print("*Pin value change detected*\r\n");
        display_pin_values();
        oldPinValues = pinValues;
    }

    delay(POLL_DELAY_MSEC);
}

You say SPI will "mess you up" but then you post some code that is way more complex than the example code Crossroads gave you. Just compare those two code examples again. Which looks easier? That should tell you something. Also that code you posted is unecessarily long and slow.Crossroads' code is simple, neat & fast.

You will need 4 data lines (clock, latch, data-in and data-out) plus power & ground in your cable. Depending on your circuit, you might want 2 separate latch lines for the 595s & 165s, so that would be 5 data lines plus power & ground. The clock enable pin on the 165 is not needed and can just be connected to ground. Both chips share the clock and can either share latch or have separate latch lines.

In terms of power for the remote circuit, i assume your leds will need 12V from the cable. The chips will need a 5V supply. You can either send 12V on one line and 5V on another, or have a small 12V-5V regulator at the remote circuit such as 78L05.

You still haven't described these 12V leds. How much current will they consume? If it is significant, some of the 12V might be lost in the cable. If that is the case, you might want to use 2 lines for 12V and 2 lines for ground, to reduce the losses.

I was assuming that Crossroads' code was not complete. It seemed like a snipit of what is needed. I hope I am wrong here. Simple is definately much better.

I looked at SPI on the Arduino tutorial, SPI - Arduino Reference, and I noticed the following, among other, concerns:

To write code for a new SPI device you need to note a few things:
What is the maximum SPI speed your device can use? This is controlled by the first parameter in SPISettings. If you are using a chip rated at 15 MHz, use 15000000. Arduino will automatically use the best speed that is equal to or less than the number you use with SPISettings.
Is data shifted in Most Significant Bit (MSB) or Least Significant Bit (LSB) first? This is controlled by second SPISettings parameter, either MSBFIRST or LSBFIRST. Most SPI chips use MSB first data order.
Is the data clock idle when high or low? Are samples on the rising or falling edge of clock pulses? These modes are controlled by the third parameter in SPISettings.

This seemed like beyond full of issues. I am learning on the fly here as it is. Even more concerning to me was the last 3 words in this statement:

Serial Peripheral Interface (SPI) is a synchronous serial data protocol used by microcontrollers for communicating with one or more peripheral devices quickly over short distances.

I am planning on having the second button box in another room, 10-30 feet away.

As far as the 12V to power the LEDs, I am not planning on running it though the cable at all, but rather have each button boxes powered by their own 12V supplies (joined to the common ground of course) locally, and hooked up to the 595s in sink configuration.

The clock enable pin on the 165 is not needed and can just be connected to ground

Is this in general or only when using SPI. If it is in general, then why is it even included? Don't get me wrong, I'd be quite happy, because if it isn't needed, my problems are solved.

You still haven't described these 12V leds. How much current will they consume?

I've searched high and low, but can't figure it out. I don't even know if they have internal resistors or if I need external ones. I was assuming they had internal ones. I just love these large buttons, and they were cheap, $4 a piece. Any idea how I could find out the current and resistor issue by testing?

Thanks again for your communal help. It is greatly appreciated!

I don't even know if they have internal resistors or if I need external ones.

You could try looking at the strip. Failing that posting a picture.

If it is in general, then why is it even included?

Just because you can't see a use for it, and in your specific application there is no use for it, doesn't give you any right to question why the manufacturers put it on the chip in the first place. Learn a bit of modesty.

I am planning on having the second button box in another room, 10-30 feet away.

Plan away, just don't expect it to work reliably.

Simple is definately much better.

Are you of the mind set that thinks people make things complex just because they can? Everyone wants to make things simpler. A lack of understanding about things often makes things much more complex than they need be.

Grumpy_Mike:
You could try looking at the strip. Failing that posting a picture.

Will do, thanks.

...question why the manufacturers put it on the chip in the first place.

That was not my intention. I'm sorry if I chose my words incorrectly. I am just trying to learn more about the IC.

So, is it true that I do not you need to use the clock enable pin on the 165 for my project?

Plan away, just don't expect it to work reliably.

Any idea how I can ensure that it will work reliably?