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.
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;
}