Multi I/O Library (16 Inputs and Outputs)

YES! It is possible. I just ported my MIDI Drum-Machine code so it uses less I/Os, making it compatible with the UNO board. :wink:

Here's the code, which reads and outputs to 16 buttons and LEDs using only 5 pins! (shares the same clock pin)

C165_595.h

/*
 
      Created by WilliamK @ Wusik Dot Com (c) 2010
      http://arduino.wusik.com

*/

#ifndef C165_595_h
#define C165_595_h

#include <inttypes.h>
#include "HardwareSerial.h"

class C165_595
{
public:
    C165_595(uint8_t _loadPin, uint8_t _latchPin, uint8_t _dataPinInput, uint8_t _dataPinOutput, uint8_t _clockPin);
      unsigned int tick(unsigned int output);
      void reset(void);

private:
      uint8_t loadPin;
      uint8_t latchPin;
      uint8_t dataPinInput;
      uint8_t dataPinOutput;
      uint8_t clockPin;

      unsigned int values;
      unsigned int prevvalues;
      unsigned int prevhigh;
};

#endif

C165_595.cpp

/*
 
      Created by WilliamK @ Wusik Dot Com (c) 2010
      http://arduino.wusik.com

      Check the C165_595.h file for instructions
 
*/

#include "WConstants.h"
#include "C165_595.h"

// ------------------------------------------------------------------------------------------- //
C165_595::C165_595(uint8_t _loadPin, uint8_t _latchPin, uint8_t _dataPinInput, uint8_t _dataPinOutput, uint8_t _clockPin)
{
      loadPin = _loadPin;
      latchPin = _latchPin;
      dataPinInput = _dataPinInput;
      dataPinOutput = _dataPinOutput;
      clockPin = _clockPin;

      pinMode(loadPin, OUTPUT);
      pinMode(latchPin, OUTPUT);
      pinMode(clockPin, OUTPUT);
      pinMode(_dataPinInput, INPUT);
      pinMode(_dataPinOutput, OUTPUT);
      digitalWrite(clockPin, LOW);
      digitalWrite(latchPin, LOW);
      digitalWrite(loadPin, HIGH);

      reset();            
}

// ------------------------------------------------------------------------------------------- //
unsigned int C165_595::tick(unsigned int output)
{
      uint8_t tempInputs;
      prevvalues = values;

      digitalWrite(latchPin, LOW);
      digitalWrite(loadPin, LOW);
      digitalWrite(loadPin, HIGH);

      for(int i=15; i >= 0; i--)
      {
            digitalWrite(clockPin, LOW);

            tempInputs = digitalRead(dataPinInput);
            if (tempInputs == LOW && bitRead(prevhigh,i) > 0) bitSet(values,i);
            bitWrite(prevhigh,i,tempInputs);

            if (bitRead(output,i)) digitalWrite(dataPinOutput, HIGH); else digitalWrite(dataPinOutput, LOW);

            digitalWrite(clockPin, HIGH);
      }

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

      return values ^ prevvalues;      // X-or
}

// ------------------------------------------------------------------------------------------- //
void C165_595::reset() 
{ 
      values = prevvalues = prevhigh = 0;
}