8
\$\begingroup\$

For instance, if you had an Arduino with 4 digital IO pins, how could you independently light > 4 LEDs, or read the state of > 4 buttons?

\$\endgroup\$
  • \$\begingroup\$ You ask about PICs in the title, and then refer to an Arduino! \$\endgroup\$ – Leon Heller Aug 19 '12 at 0:42
  • 2
    \$\begingroup\$ @LeonHeller: Then ask for clarification and/or edit the question yourself. Though in this case one could just sub "uC" for PIC/Arudino. \$\endgroup\$ – Chris Laplante Aug 19 '12 at 1:43
  • 2
    \$\begingroup\$ I agree hardware is cheaper to maintain. \$\endgroup\$ – jippie Aug 19 '12 at 9:37
  • 3
    \$\begingroup\$ @jippie - And then the geek reply is: "What's a girlfriend?" :-) \$\endgroup\$ – stevenvh Aug 19 '12 at 9:43
  • 1
    \$\begingroup\$ I would suggest to reconsider your accepted answer. Ignacio's is incorrect (there are three signals, not two), Bruno's is more complete (Ignacio doesn't mention input for instance), and has an original solution for saving an extra pin. \$\endgroup\$ – stevenvh Aug 20 '12 at 18:14
4
\$\begingroup\$

A shift register such as the 74595 will allow you to have many outputs with only 2 connections: a data pin and a clock pin. You set the data pin to the next value you want to move into the register, and then pulse the clock pin.

\$\endgroup\$
  • \$\begingroup\$ That's great. So I've read up on it and just to clarify, with one of those I can have 8 outputs running from using up 2 arduino pins? I assume I can't use them as inputs too? \$\endgroup\$ – cheesysam Aug 18 '12 at 23:05
  • 3
    \$\begingroup\$ @cheesysam - "With two you can have 16 outputs. With three, 24, and so on,". That's not correct. You need 3 pins: data, clock and latch, no matter how many devices you want to connect. Bruno's answer is more accurate. Also, don't talk about the 74595, that's the original TTL technology, which has been dead and buried for decades. You want the 74HC595. \$\endgroup\$ – stevenvh Aug 19 '12 at 0:05
  • 1
    \$\begingroup\$ @stevenvh: "... with one of those I can have 8 outputs...". Also, are you sure they don't want the 74AC595? 74F595? 74LVX595? \$\endgroup\$ – Ignacio Vazquez-Abrams Aug 19 '12 at 0:15
  • 1
    \$\begingroup\$ @Ignacio - "with two.." is confusing, as can be read as "with two I/Os", like I did. Sorry. 74F595? For clocking by a 16 MHz controller? I don't think so. 74F is very power-hungry, and the speed doesn't give you any benefits. 74LVX is 3.3 V only, so doesn't interface with Arduino. What's wrong with 74HC? It's the standard logic family. \$\endgroup\$ – stevenvh Aug 19 '12 at 0:18
  • 2
    \$\begingroup\$ "What's wrong with 74HC?" Absolutely nothing. What's wrong with omitting the "XX"? \$\endgroup\$ – Ignacio Vazquez-Abrams Aug 19 '12 at 0:52
7
\$\begingroup\$

Bruno gave a good answer, but I'd like to make a few notes.

The infamous 70 mA
The 74HC595 is often used as I/O extended, and as often used to control a series of LEDs. What is often overlooked is that you may operate it out of spec this way. The datasheet says that the total supply current shouldn't be more than 70 mA, Absolute Maximum Ratings (AMR), so you better stay away from that by some margin. Therefore 8 LEDs at 10 mA is too much, and at 20 mA you'll exceed AMR by no less than 130 %! The limit is probably due to the current capacity of the bonding wires, and then the too high current may not just deteriorate the part's performance, but permanently put it out of order if that wire would break.

But last night I woke up because I had An Idea. The 70 mA limit goes for both Icc and ground current, then why not split our total or 80 mA and let Icc have half of it and ground current the other half? All you have to do is reference 4 of the LEDs to ground (active high), and the other 4 to Vcc (active low). Then the current of the former comes from Icc, the current of the others goes to ground. You'll be able to use 15 mA LEDs this way. (It's so simple that I feel like an idiot not to have thought of it sooner.)

The combined clocks
I thought Bruno saved an extra I/O pin by combining the shift register's clock with the latch's. Seems I misinterpreted his answer. I still want to expand on this option.

What happens then? The table on page 5 of the datasheet says:

contents of shift register shifted through; previous contents of the shift register is transferred to the storage register and the parallel output stages

(highlighting by me)
So it's not the new data but the previous which is being latched. Not a real problem, just make sure to shift in an extra dummy bit to latch the last data, or everything will be one pin wrong.

Combining the clocks also means that the outputs will toggle all the time while you're shifting new data in. The latch's function was actually to avoid that. In many cases this won't be a problem, if you can do it fast, but in worst case situations you may get undesired effects. Worst case could be using the 74HC595 to multiplex a display at a very high scan frequency + have a very long chain of shift registers + have all 1's except for one 0, a LED that's off + a dark room. Since that LED sees all the 1's passing every so often in a dark room it may light very faintly.

Or if you combine that high frequency multiplexing with a relay control output. All zeros and then a 1 for the relay may mean that the relay's output is not long enough high to pull-in.

Granted, those are extreme cases, but I would keep the serial and latch clock separate whenever possible if you want to multiplex, or otherwise have high update rates.

\$\endgroup\$
  • 1
    \$\begingroup\$ +1 Great idea you had last night! Never saw this mentioned anywhere till now. On the other hand, I think you misinterpreted Bruno's answer. He meant combining the clock signal of the 74XX595 and 74XX165 together & combining the latch signal of the 74XX595 and 74XX165 together. \$\endgroup\$ – m.Alin Aug 19 '12 at 8:02
  • \$\begingroup\$ @m.Alin - Yes, seems I did. Thanks for pointing that out. I'll edit my answer, but leave it as a possibility. \$\endgroup\$ – stevenvh Aug 19 '12 at 8:12
  • \$\begingroup\$ Of course, it's definitely a possibility which others have recommended. It's worth addressing it. \$\endgroup\$ – m.Alin Aug 19 '12 at 8:16
  • \$\begingroup\$ @m.Alin - I think the reason it was not used before is that either users didn't know about the 70 mA limit, or didn't care :-(. I'm off to the patent office now! ;-) \$\endgroup\$ – stevenvh Aug 19 '12 at 8:18
  • 3
    \$\begingroup\$ Back already. The office was closed. They were all in church. \$\endgroup\$ – stevenvh Aug 19 '12 at 9:13
6
\$\begingroup\$

I agree with Ignacio regarding the use of a 74XX595, serial in parallel out shift register for output expansion, but actually you will need 3 connections, one for data, one for clock and one latch enable that will transfer the data from the internal shift register to the output latches.

Diagram of 74LS595

For the expansion of the inputs you could use a 74XX165, parallel in serial out shift register, this will allow to have up to 8 buttons per 74XX165.

enter image description here

The good thing about this approach is that you can daisy chain several shift registers allowing a increased number of inputs or outputs, and better, you can mix 74XX595 and 74XX165 allowing and you to have any number of input or outputs.

Besides that you can share the clock and latch signals reducing the number of connections needed and greatly simplifying the software. This way you will only need 4 connections for any number of any of this shift registers:

  • Clock (Shared with all shift registers)
  • Latch Enable (Shared with all shift registers)
  • Data In (Connected to the serial output of the last shift register in the chain)
  • Data Out (Connected to the serial input of the first shift register in the chain)

Edit

As I was searching for a diagram I found on this website a very clever way to reduce to 3 the number of required connections. It consists in using the same pin for data input and output.

The software will do something like this for each clock pulse:

  1. Configure pin as an output
  2. Set the data value
  3. Send a clock pulse
  4. Configure pin as an input
  5. Read the data

Diagram

\$\endgroup\$
  • 1
    \$\begingroup\$ The excessively keen can control shift register output only strings like this with a single output pin, and probably input-output ones as wel. Ask me how I know :-). This is achieved by using R/C delays on data and latch, with clock connected to the output pin directly. Exact sequencing depends on relative edge trigger polarity for clock and latch but these are usually designed so as to work together in this manner. \$\endgroup\$ – Russell McMahon Aug 19 '12 at 1:49
  • \$\begingroup\$ And like I said in my answer you can combine both clocks as well, so that you only need two pins. It's a clever idea, but I'm not going to upvote this a second time. Once is enough :-) \$\endgroup\$ – stevenvh Aug 19 '12 at 11:48
  • \$\begingroup\$ I don't see the need of shifting the last output of the 74HC595 into the 74HC165. Could anyone explain this? As far as I understand, 16 clock pulses would be enough to both, set the outputs of the 2 x 74HC595 (16 outputs) and read the inputs of the 2 74HC165 (16 inputs), without this connection. \$\endgroup\$ – user17395 Dec 31 '12 at 6:55
  • \$\begingroup\$ @Dario: Having the last output from the 74HC595 feed into the 74HC165 is a "freebie" way of allowing a controller which knows that the chain won't be longer than a certain length to determine that the chain is connected and how long it is. If it would be acceptable to clock all the '595's low on start-up, and if the first '165 will have at least one input high, code may even determine how many '595's and '165's there are. \$\endgroup\$ – supercat Dec 31 '12 at 19:48
5
\$\begingroup\$

Nick mentions I/O expanders, and they're definitely worth looking into. Digikey lists more than a thousand of them, I'll pick one with an I2C interface as an example, because that requires the least I/O pins; minimum two.

The NXP PCA9505 has 40 configurable I/O pins, the equivalent of five 74HC595s. It's a slightly more expensive solution but you get much more functionality for that:

  • Any I/O pin can be configured as input or output
  • 100 kΩ pullups on all I/O pins (the PCA9506 doesn't have the pullups, which may be relevant for low-power applications)
  • All outputs can sink 15 mA simultaneously, for a package total of 600 mA
  • An interrupt-on-change output makes continuously scanning of the inputs superfluous
  • Only two wires to connect to the microcontroller.

Further reading
GPIO expanders, NXP brochure
PCA9505 datasheet

\$\endgroup\$
4
\$\begingroup\$

For a solution with no extra ICs, you can use techniques such as Multiplexing and Charliplexing:

Multiplexing (no current limiting resistors shown):

Multiplexed LEDs

The way multiplexing works is quite simple - in the above example, if we want to light LED1, we set pin C1 to output high and PIN R1 to output low, all other pins can be high or Hi-Z (set to input, high impedance which makes them look "disconnected")
If we wish to light LED5, we set pin C2 to output high and R2 to output low.

The number of pins needed to drive x LEDs can be worked out by 2n pins for n² LEDs, so e.g. for 16 LEDs we need (√16) * 2 = 8 pins.

Charlieplexing:

Charlieplexing

Alternative (neater) schematic layout (suggested by Supercat):

Charlieplexing 2

This is a little more complex, but uses less pins to drive higher numbers of LEDs. For example, we can use just 5 pins to drive 20 LEDs as in the above example (compared with at least 10 pins with "normal" matrix multiplexing (not to be confused with using an IC in which case the number of pins needed is log2(nLED).

For an external solution, you can use things like Shift Registers or Multiplexers such as 74HC595 and 74HC151.
A shift register takes a clocked serial input stream of data and outputs parallel (Serial In Parallel Out SIPO) or the other way round (PISO)
They generally have 8 outputs (or inputs) but you can chain as many as you like together to extend things. The down side is the speed you can update is divided by the number of outputs per input (e.g. for one register of 8 outputs, if you have an 8MHz input clock you can update at 1MHz, for 16 outputs 500kHz, etc)

These techniques can work in reverse for inputs too.

\$\endgroup\$
  • \$\begingroup\$ This answer shows how to use Charlieplexing for multiplexed input push buttons: electronics.stackexchange.com/a/37362/8627 \$\endgroup\$ – jippie Aug 19 '12 at 9:25
  • \$\begingroup\$ An easier way to draw a Charlieplexed display is to simply draw it as an NxN grid with the diagonal unpopulated. \$\endgroup\$ – supercat Dec 31 '12 at 19:49
  • \$\begingroup\$ @supercat - I just pinched the first example from google images. I just added another example - is this the kind of layout you meant? \$\endgroup\$ – Oli Glaser Jan 2 '13 at 8:41
  • \$\begingroup\$ @OliGlaser: Yes, though I would suggest moving the resistors to the row-column junctions. If you do that, then it will be possible to drive nine LEDs at once, provided that either the high-side or low-side drivers can accommodate that. Alternatively, one could leave the resistors where they are but add a transistor at each row-column junction (for the schematic as shown, an NPN with the base on the row, the emitter on the column, and the collector attached to the positive rail). Adding the transistor would greatly reduce the high-side drive strength required to operate nine LEDs at once. \$\endgroup\$ – supercat Jan 2 '13 at 15:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.