//GLOBAL:
const int LOCKSWITCH_PIN = 5;
int lockSwitchValue = 1;
bool lockOn = false; //used for the window lock, if set to true will block all but WINDOW1


//WINDOW1:
  const int WINDOW1_UP_RELAY_PIN = 3; 
  const int WINDOW1_DOWN_RELAY_PIN = 4; 
  const int WINDOW1_SWITCH_UP_PIN = 13;
  const int WINDOW1_SWITCH_DOWN_PIN = 12;
  const int WINDOW1_AMMETER_BUTTON_PIN = 7;

  bool Window1Stop = false; //used to stop turn all relays to off.

  //hold up variables
  int window1UpHeldTimer = 0;
  bool window1HeldUpTimerActivated = false;
  int window1HeldUpTimerLength = 20;

  //hold down variables
  int window1DownHeldTimer = 0;
  bool window1HeldDownTimerActivated = false;
  int window1HeldDownTimerLength = 20;

  //initialise values
  int window1SwitchUpValue = 1;
  int window1SwitchDownValue = 1;
  int window1AmmeterValue = 1;

//WINDOW2:
  const int WINDOW2_UP_RELAY_PIN = 2; 
  const int WINDOW2_DOWN_RELAY_PIN = 1; 
  const int WINDOW2_SWITCH_UP_PIN = 11;
  const int WINDOW2_SWITCH_DOWN_PIN = 10;
  const int WINDOW2_AMMETER_BUTTON_PIN = 6;

  bool Window2Stop = false; //used to stop turn all relays to off.

  //hold up variables
  int window2UpHeldTimer = 0;
  bool window2HeldUpTimerActivated = false;
  int window2HeldUpTimerLength = 20;

  //hold down variables
  int window2DownHeldTimer = 0;
  bool window2HeldDownTimerActivated = false;
  int window2HeldDownTimerLength = 20;

  //initialise values
  int window2SwitchUpValue = 1;
  int window2SwitchDownValue = 1;
  int window2AmmeterValue = 1;







void setup() 
{

  pinMode(WINDOW1_UP_RELAY_PIN, OUTPUT);
  pinMode(WINDOW1_DOWN_RELAY_PIN, OUTPUT);
  pinMode(WINDOW1_SWITCH_UP_PIN, INPUT_PULLUP);
  pinMode(WINDOW1_SWITCH_DOWN_PIN, INPUT_PULLUP);
  pinMode(LOCKSWITCH_PIN, INPUT_PULLUP);
  pinMode(WINDOW1_AMMETER_BUTTON_PIN, INPUT_PULLUP);
  Serial.begin(9600);
  //set all relays to off
  digitalWrite(WINDOW1_UP_RELAY_PIN, LOW);
  digitalWrite(WINDOW1_DOWN_RELAY_PIN, LOW);
  delay(50);
}

void loop() 
{
  GETALLWINDOWINPUTS(); //gets all inputs from switches and ammeter.

  ERRORSTATECHECK(); //checks for any error.. e.g. both switches are pushed ammeter is tripping etc.. 

  WINDOWLOGICDRIVER(); //runs all the logic for all windows

  delay(50);
}

void WINDOWLOGICDRIVER()
{
  if(lockOn) //if the LOCK is only, only run logic for window 1
  {
    WINDOW1LOGIC();
  }
  else
  {
    WINDOW1LOGIC(); 
    WINDOW2LOGIC(); 
    WINDOW3LOGIC();
    WINDOW4LOGIC(); 
  }
}

void WINDOW1LOGIC()//runs all logic for WINDOW1
{
  //up switch is pushed. 
  if(window1SwitchUpValue == 0 && window1SwitchDownValue == 1)
  {
    window1HeldDownTimerActivated = false;

    Window1UpRelayHigh();
    window1UpHeldTimer = window1UpHeldTimer + 1;
    if(window1UpHeldTimer > window1HeldUpTimerLength && window1HeldUpTimerActivated == false)
    {
      window1HeldUpTimerActivated = true;
    }
  }

  //down switch is pushed. 
  if(window1SwitchUpValue == 1 && window1SwitchDownValue == 0)
  {
    window1HeldUpTimerActivated = false;

    Window1DownRelayHigh();
    window1DownHeldTimer = window1DownHeldTimer + 1;
    if(window1DownHeldTimer > window1HeldDownTimerLength && window1HeldDownTimerActivated == false)
    {
      window1HeldDownTimerActivated = true;
    }
  }

  //if neither are pushed.
  if(window1SwitchUpValue == 1 && window1SwitchDownValue == 1)
  {
    if(window1HeldUpTimerActivated == true)
    {
      Window1UpRelayHigh();
    }

    if(window1HeldDownTimerActivated == true)
    {
      Window1DownRelayHigh();
    }

    if(window1HeldUpTimerActivated == false)
    {
      Window1UpRelayLow();
    }

    if(window1HeldDownTimerActivated == false)
    {
      Window1DownRelayLow();
    }
  }

}

void WINDOW2LOGIC()//runs all logic for WINDOW2
{
    //up switch is pushed. 
  if(window2SwitchUpValue == 0 && window2SwitchDownValue == 1)
  {
    window2HeldDownTimerActivated = false;

    Window2UpRelayHigh();
    window2UpHeldTimer = window2UpHeldTimer + 1;
    if(window2UpHeldTimer > window2HeldUpTimerLength && window2HeldUpTimerActivated == false)
    {
      window2HeldUpTimerActivated = true;
    }
  }

  //down switch is pushed. 
  if(window2SwitchUpValue == 1 && window2SwitchDownValue == 0)
  {
    window2HeldUpTimerActivated = false;

    Window2DownRelayHigh();
    window2DownHeldTimer = window2DownHeldTimer + 1;
    if(window2DownHeldTimer > window2HeldDownTimerLength && window2HeldDownTimerActivated == false)
    {
      window2HeldDownTimerActivated = true;
    }
  }

  //if neither are pushed.
  if(window2SwitchUpValue == 1 && window2SwitchDownValue == 1)
  {
    if(window2HeldUpTimerActivated == true)
    {
      Window2UpRelayHigh();
    }

    if(window2HeldDownTimerActivated == true)
    {
      Window2DownRelayHigh();
    }

    if(window2HeldUpTimerActivated == false)
    {
      Window2UpRelayLow();
    }

    if(window2HeldDownTimerActivated == false)
    {
      Window2DownRelayLow();
    }
  }

}
void WINDOW3LOGIC(){}; //runs all logic for WINDOW3
void WINDOW4LOGIC(){}; //runs all logic for WINDOW4

void Window1UpRelayHigh()
{
  if(Window1Stop)
  {
    digitalWrite(WINDOW1_UP_RELAY_PIN, LOW);
  }
  else
  {
    digitalWrite(WINDOW1_UP_RELAY_PIN, HIGH);
  }

}
void Window1DownRelayHigh()
{
  if(Window1Stop)
  {
    digitalWrite(WINDOW1_DOWN_RELAY_PIN, LOW);
  }
  else
  {
    digitalWrite(WINDOW1_DOWN_RELAY_PIN, HIGH);
  }

}
void Window1UpRelayLow()
{
  digitalWrite(WINDOW1_UP_RELAY_PIN, LOW);
}
void Window1DownRelayLow()
{
  digitalWrite(WINDOW1_DOWN_RELAY_PIN, LOW);
}

void Window2UpRelayHigh()
{
  if(Window2Stop)
  {
    digitalWrite(WINDOW2_UP_RELAY_PIN, LOW);
  }
  else
  {
    digitalWrite(WINDOW2_UP_RELAY_PIN, HIGH);
  }

}
void Window2DownRelayHigh()
{
  if(Window2Stop)
  {
    digitalWrite(WINDOW2_DOWN_RELAY_PIN, LOW);
  }
  else
  {
    digitalWrite(WINDOW2_DOWN_RELAY_PIN, HIGH);
  }

}
void Window2UpRelayLow()
{
  digitalWrite(WINDOW2_UP_RELAY_PIN, LOW);
}
void Window2DownRelayLow()
{
  digitalWrite(WINDOW2_DOWN_RELAY_PIN, LOW);
}


void ERRORSTATECHECK()
{
  //WINDOW 1
  //if both relays earthed then turn everything off. it is a safety mechanism
  if(window1SwitchUpValue == 0 && window1SwitchDownValue == 0)
  {
    KILLALL(); //Switch all relays off
  }

  //if ameter is triggered then stop everything. 
  if(window1AmmeterValue == 0)
  {
    KILLALL(); //Switch all relays off
  }

  //if ammeter value returns to normal allow movement.
  if(window1AmmeterValue == 1)
  {
    Window1Stop = false;
  }

  //WINDOW 2
  //if both relays earthed then turn everything off. it is a safety mechanism
  if(window2SwitchUpValue == 0 && window2SwitchDownValue == 0)
  {
    KILLALL(); //Switch all relays off
  }

  //if ameter is triggered then stop everything. 
  if(window2AmmeterValue == 0)
  {
    KILLALL(); //Switch all relays off
  }

  //if ammeter value returns to normal allow movement.
  if(window2AmmeterValue == 1)
  {
    Window2Stop = false;
  }

}

void GETALLWINDOWINPUTS()
{
  LOCKSWITCHINPUT();
  WINDOW1INPUTS();
  WINDOW2INPUTS();
}

void WINDOW1INPUTS()
{
  //WINDOW1
  // 0 = switch is earthed, 1= switch is not earthed.
  window1SwitchUpValue = digitalRead(WINDOW1_SWITCH_UP_PIN);
  window1SwitchDownValue = digitalRead(WINDOW1_SWITCH_DOWN_PIN);
  window1AmmeterValue = digitalRead(WINDOW1_AMMETER_BUTTON_PIN);
}

void WINDOW1INPUTS()
{
  //WINDOW1
  // 0 = switch is earthed, 1= switch is not earthed.
  window2SwitchUpValue = digitalRead(WINDOW2_SWITCH_UP_PIN);
  window2SwitchDownValue = digitalRead(WINDOW2_SWITCH_DOWN_PIN);
  window2AmmeterValue = digitalRead(WINDOW2_AMMETER_BUTTON_PIN);
}

void KILLALL()
{
  //WINDOW 1
  Window1UpRelayLow();
  Window1DownRelayLow();
  window1UpHeldTimer = 0;
  window1HeldUpTimerActivated = false;
  window1DownHeldTimer = 0;
  window1HeldDownTimerActivated = false;
  Window1Stop = true;

  //WINDOW 2
  Window2UpRelayLow();
  Window2DownRelayLow();
  window2UpHeldTimer = 0;
  window2HeldUpTimerActivated = false;
  window2DownHeldTimer = 0;
  window2HeldDownTimerActivated = false;
  Window2Stop = true;
}

void ALLWINDOWSUP() //makes all the windows go up.
{
  window2HeldUpTimerActivated = true;
}
void ALLWINDOWSDOWN() //makes all the windows go down
{
  window2HeldDownTimerActivated = true;
}


void LOCKSWITCHINPUT()
{
  lockSwitchValue = digitalRead(LOCKSWITCH_PIN);
  if(lockSwitchValue == 0)
  {
    lockOn = true;
  }
  else
  {
    lockOn = false;
  }
}
NOCOMNCVCCGNDINLED1PWRRelay Module
NOCOMNCVCCGNDINLED1PWRRelay Module
NOCOMNCVCCGNDINLED1PWRRelay Module
NOCOMNCVCCGNDINLED1PWRRelay Module