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.
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.
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:
- 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)
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:
- Configure pin as an output
- Set the data value
- Send a clock pulse
- Configure pin as an input
- Read the data
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.
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")
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.
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.
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.