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?
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.
|show 3 more comments|
Bruno gave a good answer, but I'd like to make a few notes.
The infamous 70 mA
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
What happens then? The table on page 5 of the datasheet says:
(highlighting by me)
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.
|show 3 more comments|
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.
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.
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:
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:
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:
Multiplexing (no current limiting resistors shown):
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")
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.
Alternative (neater) schematic layout (suggested by Supercat):
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.
These techniques can work in reverse for inputs too.