// output shift register IC 74HC595
const uint8_t srOpData = 0; // 74HC595 pin-14 (DS)
const uint8_t srOpLatch = 1; // 74HC595 pin-12 (STCP)

// CLK is common between ICs 74HC595 and 74HC165
const uint8_t srClk = 2; // 74HC595 pin-11 (SHCP) //74HC165 pin-2 (CP)

// input shift register IC 74HC165
const uint8_t srInpData = 3; // 74HC165 pin-9 (Q7)
const uint8_t srInpLatch = 4; // 74HC165 pin-1 (PL)

uint16_t inpVal = 0;
uint16_t opVal = 0;

// for 1 input shift register 74HC165 IC numBits = 8
// for 2 input shift register 74HC165 ICs numBits = 16
uint8_t numBits = 16;
void setup() {
  // PORTB output configuration
  DDRB |= (1 << DDB0) | (1 << DDB1) | (1 << DDB2) | (1 << DDB4) | (1 << DDB5);
  // PORTB input configuration
  DDRB &= ~(1 << DDB3);
}
void updateInpSRVal() {
  digitalWrite(srInpLatch, LOW);
  digitalWrite(srInpLatch, HIGH);
  // Step 2: Shift
  for (int i = 0; i < numBits; i++) {
    inpVal = digitalRead(srInpData) ? (inpVal | (1 << (numBits - 1 - i))) : (inpVal & ~(1 << (numBits - 1 - i)));
    digitalWrite(srClk, HIGH); // shift out the next bit
    digitalWrite(srClk, LOW);
  }
}
void updateOpSRVal(uint16_t opWord) {
  digitalWrite(srOpLatch, LOW); // latch low
  for (uint8_t x = 0; x < 16; x++) {
    digitalWrite(srOpData, (bool)((opWord >> (15 - x)) & (0b1)));
    digitalWrite(srClk, HIGH);  // clock high
    digitalWrite(srClk, LOW);   // clock low
  }
  digitalWrite(srOpLatch, HIGH); // latch high
}

//individual pins read status
bool readInp(uint8_t inpNo) {
  updateInpSRVal();
  return (bool)((inpVal >> inpNo) & (0b1));
}
//individual pins write control
void writeOp(uint8_t opNo, bool bitStatus) {
  opVal = bitStatus ? opVal | (1 << opNo) : opVal & ~(1 << opNo);
  updateOpSRVal(opVal);
}
void loop() {
  updateInpSRVal();
  updateOpSRVal(inpVal);
}





ATTINY8520PU
74HC595
74HC595
74HC165
74HC165