#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;
}
}