#define LATCH_PIN 9  // Latch pin of 74HC595 is connected to Digital pin 5
#define CLOCK_PIN 10  // Clock pin of 74HC595 is connected to Digital pin 6
#define DATA_PIN  8  // Data pin of 74HC595 is connected to Digital pin 4
#define OE_PIN    5   // oePin - not using this



enum RELAY_ID {
    RELAY_ID_1,
    RELAY_ID_2,
    RELAY_ID_3,
    RELAY_ID_4,
    RELAY_ID_5,
    RELAY_ID_6,
    RELAY_ID_7,
    RELAY_ID_8,
    RELAY_ID_9,
    RELAY_ID_10,
    RELAY_ID_11,
    RELAY_ID_12,
    RELAY_ID_13,
    RELAY_ID_14,
    RELAY_ID_15,
    RELAY_ID_16
};

enum RELAY_STATE {
    RELAY_STATE_OFF,
    RELAY_STATE_ON,
};


uint16_t Relays_Status_Current = 0;
uint16_t Relays_Status_Stored = 0;

void Update_Relays_State();
void Set_Relay_Status(RELAY_ID ID, RELAY_STATE STATE);
RELAY_STATE Get_Relay_Status(RELAY_ID ID);
void Init_Shifter_Pins();

void setup() {
  Serial.begin(115200);
  Init_Shifter_Pins();
}

void loop() {
  for(int i = 0; i<=15; i++)
  {
    Set_Relay_Status((RELAY_ID)i, RELAY_STATE_ON);
    Update_Relays_State();
    delay(100);
  }

  for(int i = 0; i<=15; i++)
  {
    Set_Relay_Status((RELAY_ID)i, RELAY_STATE_OFF);
    Update_Relays_State();
    delay(100);
  }
}



void Update_Relays_State()
{
  //Check if the State has changed
  if (Relays_Status_Current != Relays_Status_Stored)
  {
    //Update the EEPROM
    
    //Set Relays_Status_Stored to Relays_Status_Current
    Relays_Status_Stored = Relays_Status_Current;
    //Send data to Shifter
    digitalWrite(LATCH_PIN, LOW);
    shiftOut(DATA_PIN, CLOCK_PIN, MSBFIRST, (Relays_Status_Stored >> 8));
    shiftOut(DATA_PIN, CLOCK_PIN, MSBFIRST, Relays_Status_Stored);
    digitalWrite(LATCH_PIN, HIGH);

  }else{
    //Do nothing
  }
}

void Set_Relay_Status(RELAY_ID ID, RELAY_STATE STATE)
{
  bitWrite(Relays_Status_Current, ID, STATE);
}

RELAY_STATE Get_Relay_Status(RELAY_ID ID)
{
  return (RELAY_STATE)bitRead(Relays_Status_Current, ID);
}

void Init_Shifter_Pins()
{
  // Set all the pins of 74HC595 as OUTPUT
  pinMode(LATCH_PIN, OUTPUT);
  pinMode(DATA_PIN, OUTPUT);  
  pinMode(CLOCK_PIN, OUTPUT);
  pinMode(OE_PIN, OUTPUT);
}
74HC595
74HC595