Multiputs - 74HC595 monitor many buttons

Use a 74HC595 to monitor many digital inputs

Microcontrollers have a limited number of digital inputs. There are times when you want to use more than the board supports or want to consolidate the logic of monitoring which input was used. You can use a 74HC595 to monitor many digital inputs. Consider a modern keyboard with 104 keys. Certainly, you wouldn’t want to create a microcontroller with 104 digital input pins.

Here, I’ll show the control of 8 inputs using a single 74HC595 and a Gadgeteer FEZ Raptor using .NET Micro Framework. Using this technique, you can control a ton of inputs using only a series of 74HC595 chips and 4 pins on your board.

Here’s a video of the final output:

For fun, I’m outputting the results to a display screen. However, you can use your creativity to output however you want. Maybe you’ll create a digital piano using a piezo speaker similar to my Gadgeteer Touch Piano. You can see it’s super responsive. There are few issues which would be nice to handle. I’ll discuss those at the end.

Here’s the parts list:

  • FEZ Raptor (from GHI)
    • Any GHI mainboard can be used
  • Breadboard
  • Breadboard X1 module (from GHI)
  • Button module (from GHI)
  • Display module (from GHI)
  • 8 Tactile buttons
  • 8 N4148 diodes
  • Addicore 74HC595 8-bit shift register IC

The Gadgeteer assembly looks like this:

Multiputs Assembly

Wiring is fairly straight forward. All the outputs from the IC need to lead to a diode then to one side of a button. The other side of the button leads to an interrupt pin. Here’s the logical step you’ll need to understand:

On startup:

  • Set all 74HC595 output pins high
  • The un-pressed buttons prevent current from flowing to the interrupt pin
  • Once a button, current flows to the interrupt pin firing the interrupt event
  • In side the interrupt event, you’ll do the following:
    • Turn all 74HC595 pins low
    • Loop through each 74HC595 output pin turning it high, and checking the status of the interrupt pin.
      • If the pin is low, that button isn’t pressed.
      • If the pin is high, that button IS pressed.

Looping through each output pin in the 74HC595 is very fast as long as you’re not doing too much in the loop.

The code for this project is located in my Multiputs GitHub repository.

private int onPins = 0; 
ArrayList onPinsArray = new ArrayList(); 
void interruptInput_Interrupt(InterruptInput sender, bool value)
    int check = 1; 
    for (int i = 0; i <= 7; i++) 
        if (interruptInput.Read()) 
            onPins = onPins + 1; 
        onPins = onPins << 1; 
        check = check << 1; 
    onPins = 0; 

Here are some issues which need fixing. I need to do something about the bounce in the buttons though. A very small sleep (10ms?) at the top of the interrupt event should handle the button bounce. Also, it would be good have the interrupt event not fire while the event handler is running… there’s always room for improvement.

Let me know if you have any problems. There are many resources out there covering this technique. I can help out or point you in a good direction. Enjoy!