#include <Wire.h>
#include <LiquidCrystal_I2C.h>
const int buzzer = 13;
LiquidCrystal_I2C lcd(0x27, 16, 2);
// session lengths
#define FOCUS_TIME 1*60//25*60
#define SHORT_BREAK_TIME 5*60
#define LONG_BREAK_TIME 15*60
// session identifiers
typedef enum {
FOCUS_SESSION,
SHORT_BREAK,
LONG_BREAK
} session_t;
session_t session = FOCUS_SESSION;
int timerSeconds = FOCUS_TIME;
bool timerRunning = false;
#define TOTAL_FOCUS_SESSIONS 4
int session_count = 0;
int minutes = 0;
int seconds = 0;
void printTimeRemaining() {
minutes = timerSeconds / 60;
lcd.setCursor(0,0);
lcd.print("Time remaining: ");
lcd.setCursor(0,1);
if(minutes < 10) {
lcd.print("0");
}
lcd.print(minutes);
lcd.print(":");
if(seconds < 10) {
lcd.print("0");
}
lcd.print(seconds);
lcd.print(" ");
}
void setup() {
Serial.begin(115200);
cli();
TCCR1A = 0; // set entire TCCR1A register to 0
TCCR1B = 0; // set TCCR1B to 0
TCNT1 = 0; //initialize counter value to 0
// set compare match register for 1 Hz increments
OCR1A = 15624; //(16*10^6) / (1*1024) - 1 (must be <65536)
// turn on CTC mode
TCCR1B |= (1 << WGM12);
// Set CS12 and CS10 bits for 1024 prescaler
TCCR1B |= (1 << CS12) | (1 << CS10);
// enable timer compare interrupt
TIMSK1 |= (1 << OCIE1A);
sei();
pinMode(buzzer, OUTPUT);
digitalWrite(buzzer, LOW);
lcd.init();
lcd.backlight();
lcd.setCursor(0,0);
lcd.print("Start focusing!");
delay(2000);
printTimeRemaining();
timerRunning = true;
}
ISR(TIMER1_COMPA_vect){
if (timerRunning) {
--timerSeconds;
}
}
void loop() {
if (timerSeconds < 0) {
timerRunning = false;
digitalWrite(buzzer, HIGH);
switch (session) {
case FOCUS_SESSION:
session_count++;
session = ( (session_count == TOTAL_FOCUS_SESSIONS) ? LONG_BREAK : SHORT_BREAK);
timerSeconds = ( (session == SHORT_BREAK) ? SHORT_BREAK_TIME : LONG_BREAK_TIME);
lcd.setCursor(0,0);
lcd.print("Focus over, ");
lcd.setCursor(0,1);
lcd.print("break now! ");
delay(2000);
printTimeRemaining();
digitalWrite(buzzer, LOW);
timerRunning = true;
break;
case SHORT_BREAK:
session = FOCUS_SESSION;
timerSeconds = FOCUS_TIME;
lcd.setCursor(0,0);
lcd.print("Short break over");
lcd.setCursor(0,1);
lcd.print("focus now! ");
delay(2000);
printTimeRemaining();
digitalWrite(buzzer, LOW);
timerRunning = true;
break;
case LONG_BREAK:
session = FOCUS_SESSION;
timerSeconds = FOCUS_TIME;
session_count = 0;
lcd.print("Long break over,");
lcd.setCursor(0,1);
lcd.print("focus now! ");
delay(2000);
printTimeRemaining();
digitalWrite(buzzer, LOW);
timerRunning = true;
break;
default:
Serial.print("Error");
break;
}
}
minutes = timerSeconds / 60;
seconds = timerSeconds % 60;
lcd.setCursor(0,1);
if (minutes < 10) {
lcd.print("0");
}
lcd.print(minutes); // if the minutes is of length 1, print a zero at the end of it
lcd.setCursor(3,1);
if (seconds < 10) {
lcd.print("0");
}
lcd.print(seconds);
}