#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <RTClib.h>
// Pin definitions
const int BTN_PINS[] = {26, 25, 33, 32}; // Green, Yellow, Red, Blue
const int LED_PINS[] = {13, 12, 14, 27}; // Green, Yellow, Red, Blue
const int NUM_COLORS = 4;
// LCD setup
LiquidCrystal_I2C lcd(0x27, 16, 2);
// RTC setup
RTC_DS1307 rtc;
// Variables
const char* COLOR_NAMES[] = {"GREEN", "YELLOW", "RED", "BLUE"};
int currentColor = 0; // Start with green (index 0)
unsigned long stopwatchStart = 0;
unsigned long lastUpdate = 0;
// Variables to store previous values for comparison
char prevStopwatchStr[9] = "";
char prevBottomLine[17] = "";
void setup() {
for (int i = 0; i < NUM_COLORS; i++) {
pinMode(BTN_PINS[i], INPUT_PULLUP);
pinMode(LED_PINS[i], OUTPUT);
}
Wire.begin();
lcd.init();
lcd.backlight();
if (!rtc.begin()) {
lcd.print("RTC failed");
while (1);
}
// Uncomment to set the RTC time
// rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
// Set initial color to green
setColor(0);
updateDisplay();
}
void loop() {
for (int i = 0; i < NUM_COLORS; i++) {
if (digitalRead(BTN_PINS[i]) == LOW) {
delay(50); // Debounce
if (digitalRead(BTN_PINS[i]) == LOW) {
setColor(i);
while (digitalRead(BTN_PINS[i]) == LOW); // Wait for release
}
}
}
if (millis() - lastUpdate >= 1000) {
updateDisplay();
lastUpdate = millis();
}
}
void setColor(int color) {
digitalWrite(LED_PINS[currentColor], LOW);
currentColor = color;
digitalWrite(LED_PINS[currentColor], HIGH);
stopwatchStart = millis();
}
void updateDisplay() {
// Stopwatch
unsigned long elapsed = (millis() - stopwatchStart) / 1000;
int hours = elapsed / 3600;
int minutes = (elapsed % 3600) / 60;
int seconds = elapsed % 60;
char stopwatchStr[9];
sprintf(stopwatchStr, "%02d:%02d:%02d", hours, minutes, seconds);
// Color and current time
DateTime now = rtc.now();
char bottomLine[17];
sprintf(bottomLine, "%-5s - %02d:%02d",
COLOR_NAMES[currentColor],
now.hour(), now.minute());
// Update the LCD only if the content has changed
if (strcmp(stopwatchStr, prevStopwatchStr) != 0) {
lcd.setCursor((16 - strlen(stopwatchStr)) / 2, 0);
lcd.print(stopwatchStr);
strcpy(prevStopwatchStr, stopwatchStr);
}
if (strcmp(bottomLine, prevBottomLine) != 0) {
lcd.setCursor((16 - strlen(bottomLine)) / 2, 1);
lcd.print(bottomLine);
strcpy(prevBottomLine, bottomLine);
}
}