#include <LiquidCrystal.h>
#include <avr/wdt.h>
//button press checker
#define WATCHDOG 0x04  // 0000 0100 extra
#define PAUSE 0x08 // 0000 1000 pause
#define GO_DOWN 0x10 // 0001 0000 go down
#define GO_UP 0x20 // 0010 0000 go up
#define SECONDSIGN "s"
#define STOP "STOP"
#define DOWN "COUNT_DOWN"
#define UP "COUNT_UP"
#define WAIT "wait:"
#define MILLIS "ms"
#define START "00.0s"
#define COUNTER "wait:000ms"
#define ZERO "0"
LiquidCrystal lcd(12, 11, 10, 8, 7, 6);
//COUNT_UP
int countUpBtn = PIND & 0x20;
bool UpBtnState = false;
//COUNT_DOWN
int countDownBtn = PIND & 0x10;
bool DownBtnState = false;
//STOP
int stopBtn = PIND & 0x08;
int stopCounter = 1;
int btn3State = LOW;
bool StopBtnState = false;
//WATCHDOG_COUNTER
int watchDogBtn = PIND & 0x04;
bool watchDogState = false;
int watchDogCounter = 0;
int btn4State = LOW;
//TIMER
float timer = 0;

void setup() {
  // Set up Timer1
  wdt_disable();
  lcd.begin(16, 2);
  lcd.print(STOP);
  lcd.setCursor(0, 1);
  lcd.print(START);
  lcd.setCursor(6, 1);
  lcd.print(COUNTER);
  DDRD |= 0xC3;
  noInterrupts();  // Disable all interrupts
  TCCR1A = 0;  // Reset Timer/Counter Control Register (TCCR1A) register
  TCCR1B = 0;  // Reset Timer/Counter Control Register (TCCR1B) register
  // Set the prescaler to 1024
  TCCR1B |= 0x05;
  // Set the compare match value for 1s
  OCR1A = 1562.5;  //(15625 ≒ 1s / (1 / (16MHz / 1024)))
  // Set the Clear Timer on Compare(CTC) mode
  TCCR1B |= (1 << WGM12);
  // Enable Timer1 compare match A interrupt
  TIMSK1 |= (1 << OCIE1A);
  interrupts();    // Enable all interrupts
  Serial.begin(9600);
}

ISR(TIMER1_COMPA_vect) {
  if (UpBtnState == true) {
    stopCounter = 0;
    if(timer < 20.0) {
      lcd.setCursor(0,0);
      lcd.print(UP);
      timer += 0.1;
      if (timer < 10) {
        lcd.setCursor(0,1);
      delay(watchDogCounter);
        lcd.print(ZERO + String(timer,1));
      }
      else {      
        lcd.setCursor(0,1);
        lcd.print(timer);
      }
    }
    else{
      UpBtnState = false;
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print(STOP);
      lcd.setCursor(0,1);
      timer = 20.0;
      delay(watchDogCounter);
      lcd.print(timer);
    }
    lcd.setCursor(4,1);
    lcd.print(SECONDSIGN);
  }
  else if (DownBtnState == true) {
    stopCounter = 0;
    lcd.setCursor(0,0);
    if (timer >= 0.1) {
      lcd.print(DOWN);
      lcd.setCursor(0,1);
      timer -= 0.1;
      lcd.setCursor(0,1);
      if (timer > 10) {
        lcd.print(timer);
      } else {
      delay(watchDogCounter);
        lcd.print(ZERO + String(timer,1));
      }
    }
    else {
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print(STOP);
      DownBtnState = false;
      lcd.setCursor(0,1);
      timer = 0.0;
      delay(watchDogCounter);
      lcd.print(ZERO + String(timer,1));
    }
    lcd.setCursor(4,1);
    lcd.print(SECONDSIGN);
  }
else if (StopBtnState == true) {
    delay(100);
    StopBtnState = false;
    lcd.setCursor(0,0);
    lcd.print(STOP);
    if(stopCounter == 2 || timer == 0.0) {
      stopCounter = 0;
      lcd.setCursor(0,1);
      timer = 0.0;
      delay(watchDogCounter);
      lcd.print(ZERO + String(timer,1));
    }
    else{
    stopCounter++;
      if (timer < 10) {
        lcd.setCursor(0,1);
      delay(watchDogCounter);
        lcd.print(ZERO + String(timer,1));
      }
      else {
        lcd.setCursor(0,1);
        lcd.print(timer);
      }
    }
    lcd.setCursor(4,1);
    lcd.print(SECONDSIGN);
  }
  if (watchDogState == true && btn4State == LOW) {
    watchDogState = false;
    watchDogCounter += 60;
    if(watchDogCounter < 250) {
    }
    else{
      wdt_enable(WDTO_250MS);
      wdt_reset();
      watchDogCounter = 0;
    }
    Serial.println(watchDogCounter);
  }
  if(watchDogCounter < 10) {
    lcd.setCursor(6,1);
    lcd.print(WAIT);
    lcd.setCursor(11,1);
    lcd.print(ZERO + String(ZERO + String(watchDogCounter)));
    lcd.setCursor(14,1);
    lcd.print(MILLIS);
  }
  else if(watchDogCounter < 100) {
    lcd.setCursor(6,1);
    lcd.print(WAIT);
    lcd.setCursor(11,1);
    lcd.print(ZERO + String(watchDogCounter));
    lcd.setCursor(14,1);
    lcd.print(MILLIS);
  }
  else{
    lcd.setCursor(6,1);
    lcd.print(WAIT);
    lcd.setCursor(11,1);
    lcd.print(watchDogCounter);
    lcd.setCursor(14,1);
    lcd.print(MILLIS);
  }
}
void loop() {
 // count up button press
  if (PIND & GO_UP && DownBtnState == false) {
    UpBtnState = true;
    DownBtnState = false;
    StopBtnState = false;
    lcd.clear();
  }
  // count down button press
  if (PIND & GO_DOWN && UpBtnState == false) {
    UpBtnState = false;
    DownBtnState = true;
    StopBtnState = false;
    lcd.clear();
  }
// stop button press
  if (PIND & PAUSE) {
    UpBtnState = false;
    DownBtnState = false;
    StopBtnState = true;
    lcd.clear();
  }
  if (PIND & WATCHDOG) {
    watchDogState = true;
    btn4State = HIGH;
  }
  else{
    btn4State = LOW;
  }
}
$abcdeabcde151015202530354045505560fghijfghij