// Battery power / USB chargeable?
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Bounce2.h>
const int greenLedPin = 1;
const int redLedPin = 2;
const int buzzerPin = 8;
const int finishPeriodButtonPin = 9;
const int pomodoroDuration = 1500; // Unit is seconds. 1500 secs = 25 minutes
const int breakDuration = 300; // Unit is seconds. 300 secs = 5 minutes
const long interval = 1000; // interval at which to blink (milliseconds)
long previousMillis = 0; // will store last time LED was updated
LiquidCrystal_I2C lcd(0x27, 16, 2); // I2c address, columns, rows
Bounce2::Button finishPeriodButton = Bounce2::Button(); // Instantiate a button object for the button which marks a period as finished
void setup() {
Serial.begin(115200);
Wire.begin(6,7); // For I2C, set SDA as pin 6 and SDL as pin 7
pinMode(greenLedPin, OUTPUT);
pinMode(redLedPin, OUTPUT);
finishPeriodButton.attach(finishPeriodButtonPin, INPUT_PULLUP); // Attach the button object for the Finish Period button to its input pin
finishPeriodButton.interval(5); // Use a 5ms debounce interval
finishPeriodButton.setPressedState(LOW); // The pin is low when the button's being pressed
lcd.init();
lcd.backlight();
}
void loop() {
promptPomodoro();
doPomodoro();
promptBreak();
doBreak();
}
void promptPomodoro() {
lcd.clear();
lcd.setCursor(1, 0);
lcd.print("Time to start");
lcd.setCursor(1, 1);
lcd.print("a Pomodoro...");
tone(buzzerPin, 262, 1000); // Plays 262Hz tone for 1 second
finishPeriodButton.update();
while(finishPeriodButton.pressed() == false) {
long currentMillis = millis();
if(currentMillis - previousMillis > interval) {
digitalWrite(redLedPin,!digitalRead(redLedPin));
previousMillis = currentMillis;
}
finishPeriodButton.update();
}
digitalWrite(redLedPin, LOW);
}
void doPomodoro() {
lcd.clear();
lcd.setCursor(4, 0);
lcd.print("Pomodoro");
long startTime = millis(); // Record the starting time
int remainingTime = pomodoroDuration;
char buffer[5]; // to hold the remaining time as a string - 2 "minutes" digits, a colon, and 2 "seconds" digits
while (remainingTime > 0) {
long currentTime = millis(); // Get the current time
remainingTime = pomodoroDuration - ((currentTime - startTime) / 1000); // Calculate remaining time in seconds
sprintf (buffer, "%02u:%02u", remainingTime / 60, remainingTime % 60); // Build a string in format 03:24 (with leading zeros if necessary)
lcd.setCursor(5, 1);
lcd.print(buffer);
}
}
void promptBreak() {
lcd.clear();
lcd.setCursor(2, 0);
lcd.print("Time to start");
lcd.setCursor(2, 1);
lcd.print("a break...");
tone(buzzerPin, 262, 1000); // Plays 262Hz tone for 1 second
finishPeriodButton.update();
while(finishPeriodButton.pressed() == false) {
long currentMillis = millis();
if(currentMillis - previousMillis > interval) {
digitalWrite(greenLedPin,!digitalRead(greenLedPin));
previousMillis = currentMillis;
}
finishPeriodButton.update();
}
digitalWrite(greenLedPin, LOW);
}
void doBreak() {
lcd.clear();
lcd.setCursor(5, 0);
lcd.print("Break");
long startTime = millis(); // Record the starting time
int remainingTime = breakDuration;
char buffer[5]; // to hold the remaining time as a string - 2 "minutes" digits, a colon, and 2 "seconds" digits
while (remainingTime > 0) {
long currentTime = millis(); // Get the current time
remainingTime = breakDuration - ((currentTime - startTime) / 1000); // Calculate remaining time in seconds
sprintf (buffer, "%02u:%02u", remainingTime / 60, remainingTime % 60); // Build a string in format 03:24 (with leading zeros if necessary)
lcd.setCursor(5, 1);
lcd.print(buffer);
}
}