const byte clockINHB = 9;        // to latch the inputs into the registers
const byte clockPin = 13;       // I choose the SCK pin
const byte dataPin = 12;        // I choose the MISO pin
uint32_t oldOptionSwitch = 0;   // previous state of all the inputs

const int pulseWidth = 10;      // pulse width in microseconds

void setup ()
{
  Serial.begin( 115200);
  Serial.println( "Turn on and off the switches");
  Serial.println( "Top row is switch 0 (right) to switch 7 (left)");
  Serial.println( "Second row is 8 to 15, and so on");

  pinMode( clockPin, OUTPUT);   // clock signal, idle LOW
  pinMode( clockINHB, OUTPUT);   // latch (copy input into registers), idle HIGH
  digitalWrite( clockINHB, HIGH);

  // Configure SPI in Master mode
  SPCR = (1 << SPE)    // Enable SPI
       | (1 << MSTR)   // Set as Master
       | (1 << SPR0);  // Set clock to f_osc/16

  // Clock Polarity (CPOL = 0) and Phase (CPHA = 0) => SPI Mode 0

}

void loop ()
{
  // Give a pulse to the parallel load latch of all 74HC165
  digitalWrite( clockINHB, LOW);
  delayMicroseconds( pulseWidth);
  digitalWrite( clockINHB, HIGH);

  union Byte_32Bit_t {
    uint32_t uint32;
    uint8_t uint8[4];
  } optionSwitch, HC164Val;

  HC164Val.uint32 = 0xA5A5A5A5;

  for ( int i = 3; i >= 0; i--)
  {
    optionSwitch.uint8[i] = ReadOne165(HC164Val.uint8[i]);
  }

  for ( int i = 0; i < 32; i++)
  {
    if ( bitRead( optionSwitch.uint32, i) != bitRead( oldOptionSwitch, i))
    {
      Serial.println( "Read Data:");
      if ( i < 10) {
        Serial.print( " ");
      }
      Serial.print( i);
      Serial.print( " is now ");
      Serial.println( bitRead( optionSwitch.uint32, i) == 0 ? "down ↓" : "up   ↑");
      //Serial.println(optionSwitch, BIN);
    }
  }

  oldOptionSwitch = optionSwitch.uint32;
  delay(250);      // slow down the sketch to avoid switch bounce
}

uint8_t ReadOne165(uint8_t byteToSend)
{
  // Write data to SPI Data Register
  SPDR = byteToSend;  // Data sent to the HC164

  // Wait until transmission is complete
  /*
     The following NOP introduces a small delay that can prevent the wait
     loop form iterating when running at the maximum speed. This gives
     about 10% more speed, even if it seems counter-intuitive. At lower
     speeds it is unnoticed.
  */
  asm volatile("nop");
  while (!(SPSR & (1 << SPIF)));

  // Return Data received from the HC165
  return (SPDR);
}
74HC165
74HC165
74HC165
74HC165

ERC Warnings

flop1:CLK: Clock driven by combinatorial logic
flop2:CLK: Clock driven by combinatorial logic
flop3:CLK: Clock driven by combinatorial logic
flop4:CLK: Clock driven by combinatorial logic
flop5:CLK: Clock driven by combinatorial logic
flop6:CLK: Clock driven by combinatorial logic
flop7:CLK: Clock driven by combinatorial logic
flop8:CLK: Clock driven by combinatorial logic