#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// Pin Definitions
const int relayPin = 5;
const int buzzerPin = 4;
const int setButtonPin = A3;
const int upButtonPin = A2;
const int downButtonPin = A1;
const int startButtonPin = A0;
// Variables
int timerSeconds = 0;
bool setupMode = false;
bool timerRunning = false;
// ============================================================================
// BEEP FUNCTION
// ============================================================================
void beepButton() {
digitalWrite(buzzerPin, HIGH);
delay(50);
digitalWrite(buzzerPin, LOW);
}
// ============================================================================
// SETUP
// ============================================================================
void setup() {
pinMode(relayPin, OUTPUT);
pinMode(buzzerPin, OUTPUT);
pinMode(setButtonPin, INPUT_PULLUP);
pinMode(upButtonPin, INPUT_PULLUP);
pinMode(downButtonPin, INPUT_PULLUP);
pinMode(startButtonPin, INPUT_PULLUP);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
// Splash Screen ------------------------------------------------------------
display.clearDisplay();
display.setTextColor(SSD1306_WHITE);
display.setTextSize(2);
display.setCursor(45, 0);
display.print("SAN");
display.setCursor(10, 20);
display.print("Creations");
display.setTextColor(SSD1306_BLACK, SSD1306_WHITE);
display.setTextSize(1);
display.setCursor(20, 50);
display.print(" SANTOSH MISHRA ");
display.display();
delay(3000);
// Welcome Screen -----------------------------------------------------------
display.clearDisplay();
display.setTextColor(SSD1306_WHITE);
display.setTextSize(2);
display.setCursor(23, 0);
display.print("UV CURE");
display.setCursor(23, 15);
display.print("STATION");
display.drawLine(0, 30, 127, 30, SSD1306_WHITE);
display.drawLine(0, 35, 127, 35, SSD1306_WHITE);
display.setTextSize(1);
display.setCursor(15, 43);
display.print(" Press SETUP to ");
display.setCursor(33, 53);
display.print(" set TIME ");
display.display();
delay(2000);
display.clearDisplay();
}
// ============================================================================
// MAIN LOOP
// ============================================================================
void loop() {
checkButtons();
if (setupMode) {
displaySetupMode();
} else if (timerRunning) {
displayTimer();
}
}
// ============================================================================
// CHECK FOR SETUP BUTTON
// ============================================================================
void checkButtons() {
if (digitalRead(setButtonPin) == LOW) {
beepButton(); // *** SOUND FEEDBACK ***
setupMode = true;
while (digitalRead(setButtonPin) == LOW) delay(10);
}
}
// ============================================================================
// SETUP MODE SCREEN
// ============================================================================
void displaySetupMode() {
displaySetupScreen();
unsigned long pressStart = 0;
bool upPressed = false;
bool downPressed = false;
while (setupMode) {
// ------------------------------------------------------------------------
// UP BUTTON → short press = +30 sec, long press = +60 sec
// ------------------------------------------------------------------------
if (digitalRead(upButtonPin) == LOW && !upPressed) {
upPressed = true;
pressStart = millis();
}
if (digitalRead(upButtonPin) == HIGH && upPressed) {
unsigned long duration = millis() - pressStart;
beepButton(); // *** SOUND ***
if (duration < 600) timerSeconds += 30;
else timerSeconds += 60;
displaySetupScreen();
upPressed = false;
}
// ------------------------------------------------------------------------
// DOWN BUTTON → short press = -30 sec, long press = -60 sec
// ------------------------------------------------------------------------
if (digitalRead(downButtonPin) == LOW && !downPressed) {
downPressed = true;
pressStart = millis();
}
if (digitalRead(downButtonPin) == HIGH && downPressed) {
unsigned long duration = millis() - pressStart;
beepButton(); // *** SOUND ***
if (duration < 600)
timerSeconds = max(0, timerSeconds - 30);
else
timerSeconds = max(0, timerSeconds - 60);
displaySetupScreen();
downPressed = false;
}
// ------------------------------------------------------------------------
// START BUTTON
// ------------------------------------------------------------------------
if (digitalRead(startButtonPin) == LOW) {
beepButton(); // *** SOUND ***
setupMode = false;
timerRunning = true;
digitalWrite(relayPin, HIGH);
beepButton(); // start beep
delay(200);
}
delay(20); // debounce
}
}
// ============================================================================
// DRAW SETUP SCREEN
// ============================================================================
void displaySetupScreen() {
display.clearDisplay();
// Draw Box
display.drawLine(25, 30, 120, 30, SSD1306_WHITE);
display.drawLine(25, 45, 120, 45, SSD1306_WHITE);
display.drawLine(25, 30, 25, 45, SSD1306_WHITE);
display.drawLine(120, 30, 120, 45, SSD1306_WHITE);
// Title
display.setTextSize(2);
display.setCursor(30, 0);
display.print("Setup");
display.drawLine(0, 25, 127, 25, SSD1306_WHITE);
display.setTextSize(1);
display.setCursor(30, 50);
display.print("Press Start");
// Timer Value
display.setCursor(30, 35);
display.print("Seconds: " + String(timerSeconds));
display.display();
}
// ============================================================================
// TIMER RUNNING SCREEN
// ============================================================================
void displayTimer() {
display.clearDisplay();
display.setTextSize(4);
display.setTextColor(SSD1306_WHITE);
display.setCursor(20, 15);
display.print(timerSeconds / 60);
display.print(":");
if (timerSeconds % 60 < 10) display.print("0");
display.print(timerSeconds % 60);
display.display();
delay(1000);
if (--timerSeconds < 0) {
digitalWrite(relayPin, LOW);
digitalWrite(buzzerPin, HIGH);
delay(2000);
digitalWrite(buzzerPin, LOW);
timerRunning = false;
timerSeconds = 0;
setupMode = true;
}
}