/* How many shift register chips are daisy-chained.
*/
#define NUMBER_OF_SHIFT_CHIPS 4
/* Width of data (how many ext lines).
*/
#define DATA_WIDTH NUMBER_OF_SHIFT_CHIPS * 8
/* Width of pulse to trigger the shift register to read and latch.
*/
#define PULSE_WIDTH_USEC 10
/* Optional delay between shift register reads.
*/
#define POLL_DELAY_MSEC 10
/* You will need to change the "int" to "long" If the
* NUMBER_OF_SHIFT_CHIPS is higher than 2.
*/
#define BYTES_VAL_T unsigned long
int ploadPin = 10; // Connects to Parallel load pin the 165
int clockEnablePin = 11; // Connects to Clock Enable pin the 165
int dataPin = 8; // Connects to the Q7 pin the 165
int clockPin = 9; // Connects to the Clock pin the 165
BYTES_VAL_T pinValues;
BYTES_VAL_T oldPinValues;
/* This function is essentially a "shift-in" routine reading the
* serial Data from the shift register chips and representing
* the state of those pins in an unsigned integer (or long).
*/
#define BYTES_VAL_T unsigned long long
BYTES_VAL_T read_shift_regs()
{
byte bitVal;
BYTES_VAL_T bytesVal = 0;
/* Trigger a parallel Load to latch the state of the data lines,
*/
digitalWrite(clockEnablePin, HIGH);
digitalWrite(ploadPin, LOW);
delayMicroseconds(PULSE_WIDTH_USEC);
digitalWrite(ploadPin, HIGH);
digitalWrite(clockEnablePin, LOW);
/* Loop to read each bit value from the serial out line
* of the SN74HC165N for each shift register.
*/
for (int shiftRegister = 0; shiftRegister < NUMBER_OF_SHIFT_CHIPS; shiftRegister++)
{
for (int i = 7; i >= 0; i--) // Adjusted the loop index
{
bitVal = digitalRead(dataPin);
/* Set the corresponding bit in bytesVal.
*/
bytesVal |= static_cast<BYTES_VAL_T>(bitVal) << ((shiftRegister * 8) + i);
/* Pulse the Clock (rising edge shifts the next bit).
*/
digitalWrite(clockPin, HIGH);
delayMicroseconds(PULSE_WIDTH_USEC);
digitalWrite(clockPin, LOW);
}
}
return bytesVal;
}
/* Dump the list of zones along with their current status.
*/
void display_pin_values()
{
for(int i = 0; i < DATA_WIDTH; i++)
{
if ((pinValues >> i) & 1 > (oldPinValues >> i) & 1) {
Serial.print("Button ");
Serial.print(i);
Serial.print(" Down!");
Serial.print("\r\n");
}
if ((pinValues >> i) & 1 < (oldPinValues >> i) & 1) {
Serial.print("Button ");
Serial.print(i);
Serial.print(" Up!");
Serial.print("\r\n");
}
}
}
void setup()
{
Serial.begin(9600);
/* Initialize our digital pins...
*/
pinMode(ploadPin, OUTPUT);
pinMode(clockEnablePin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, INPUT);
digitalWrite(clockPin, LOW);
digitalWrite(ploadPin, HIGH);
/* Read in and display the pin states at startup.
*/
pinValues = read_shift_regs();
display_pin_values();
oldPinValues = pinValues;
}
void loop()
{
/* Read the state of all zones.
*/
pinValues = read_shift_regs();
/* If there was a chage in state, display which ones changed.
*/
if(pinValues != oldPinValues)
{
// Serial.print("*Pin value change detected*\r\n");
display_pin_values();
oldPinValues = pinValues;
}
delay(POLL_DELAY_MSEC);
}