// How many of the shift registers
#define NUM_SHIFT_REGS_74HC165 1
#define NUM_SHIFT_REGS_74HC595 1

const uint8_t num74hc165Pins = NUM_SHIFT_REGS_74HC165 * 8;
const uint8_t num74hc595Pins = NUM_SHIFT_REGS_74HC165 * 8;

// Define Connections to 74HC165
int dataIn = 2;               // Q7 pin 09
int clockIn_clockOut = 3;     // CP pin 02
int load =4;                  // PL pin 01
int clockEnable_lachSTCP = 5; // CE pin 15

// Define Connections to 74HC595
//int latchPin = 7;       // ST_CP pin 12
int dataOut = 8;          // DS    pin 14
//int clkPin = 9;         // SH_CP pin 11
int outputEnablePin = 10; // OE  pin 13

// Variaveis
int readButton = 11;
bool status595 = 0;
bool statusButton = 0;
bool startReadWrite = 0;
bool debug = 1;

byte data74hc165 = 0;
byte last74hc165 = 0;
byte data74hc595 = 0;
//byte last74hc595 = 0;


/////////////////////////////////////
void setup() { 
  Serial.begin(15200); 
  // Setup 74HC165 connections
  pinMode(load, OUTPUT);
  pinMode(clockEnable_lachSTCP, OUTPUT);
  pinMode(clockIn_clockOut, OUTPUT);
  pinMode(dataIn, INPUT);
  // Setup 74HC595 connections
  //pinMode(latchPin, OUTPUT);
  pinMode(dataOut, OUTPUT);  
  //pinMode(clkPin, OUTPUT);
  pinMode(outputEnablePin, OUTPUT);
}
 /////////////////////////////////////
void loop() {
  // Set data to 74HC595
  write74hc595();  
  // Get data from 74HC165
  read74hc165();

  if (statusButton != digitalRead(readButton) ){
    startReadWrite = 1;
  }
  if (startReadWrite == 1) {
    status595 = !status595;
    digitalWrite(outputEnablePin, status595);
    delay(200);
    startReadWrite = 0;
  }

  if (debug) printDebug();
}


void write74hc595() {
  // ST_CP LOW to keep LEDs from changing while reading serial data
  //if (data74hc595 != last74hc595) {
    // Shift out the bits
    shiftOut(dataOut, clockIn_clockOut, LSBFIRST, data74hc595);
    // ST_CP HIGH change LEDs
    digitalWrite(clockEnable_lachSTCP, HIGH);
    digitalWrite(load, LOW);
    digitalWrite(clockEnable_lachSTCP, LOW);
    digitalWrite(load, HIGH);    
    //last74hc595 = data74hc595;
    Serial.println(" Writing 74hc595 ");
  //}
}


void read74hc165() {
  // Get data from 74HC165
  digitalWrite(clockEnable_lachSTCP, HIGH);
  digitalWrite(load, LOW);  
  digitalWrite(clockEnable_lachSTCP, LOW);
  digitalWrite(load, HIGH);  

  // Read dataIn and write data74hc165
  Serial.print("Reading 74hc165: ");
  for (int b = num74hc165Pins -1; b >= 0; b--) {
    int bit = digitalRead(dataIn);
    if (bit == HIGH) {
      Serial.print("1");
      bitWrite(data74hc165,b,HIGH);
    } else {
      Serial.print("0");
      bitWrite(data74hc165,b,LOW);
    }
    digitalWrite(clockIn_clockOut, HIGH); // Shift out the next bit
    digitalWrite(clockIn_clockOut, LOW);
  }

  if (data74hc165 != last74hc165) {
    checkPress();
    for (int b = num74hc165Pins -1; b >= 0; b--) {
      if (bitRead(data74hc165, b) != bitRead(last74hc165, b)) {
        int pressed = bitRead(data74hc165, b);
        if (pressed) {
          bool data = (false == bitRead(data74hc595, b))?HIGH:LOW;
          bitWrite(data74hc595, b, data);
          Serial.print(" Altered Position: "); Serial.print(b+1); 
          Serial.print(" Data: "); Serial.print(data);
        }
      }
    }
    last74hc165 = data74hc165;
  }
}

void checkPress() {
  switch (data74hc165) {
    case 0b00000001:
      Serial.print(" Press_01 ");
      break;
    case 0b0000010:
      Serial.print(" Press_02 ");
      break;
    case 0b00000100:
      Serial.print(" Press_03 ");
      break;
    case 0b00001000:
      Serial.print(" Press_04 ");
      break;
    case 0b00010000:
      Serial.print(" Press_05 ");
      break;
    case 0b00100000:
      Serial.print(" Press_06 ");
      break;
    case 0b01000000:
      Serial.print(" Press_07 ");
      break;
    case 0b10000000:
      Serial.print(" Press_08 ");
      break;            
    default:
      // comando(s)
      //break;
      last74hc165 = data74hc165;
  }
}


void printDebug() {
    //Print data74hc165 byte
    //for (int b = 7; b >= 0; b--) Serial.print(bitRead(data74hc165, b)); 
    Serial.print(" / 74HC595: ");
    for (int b = num74hc595Pins -1; b >= 0; b--) Serial.print(bitRead(data74hc595, b));
    Serial.print(" Dec: ");
    Serial.print(data74hc595, DEC);    
    //Serial.println();
}
74HC165
74HC595