#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// Define pin configurations
const int startButtonPin = 27;
const int upButtonPin = 25;
const int downButtonPin = 26;
const int menuButtonPin = 33;
const int heaterControlPin = 6;
const int temperatureControlPin = 17;
const int buzzerPin = 8;
const int pressureReleaseValvePin = 9;
const int rstbtnPin = 10;
// OLED Display setup
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define SCREEN_ADDRESS 0x3C
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
const unsigned char PROGMEM myBitmap[] = {
// 'lS', 128x128px
// 'lS', 128x64px
0xff, 0xff, 0xff, 0xff, 0x55, 0xff, 0x55, 0x57, 0xf5, 0x55, 0x55, 0x55, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xaa, 0xfe, 0xaa, 0xaf, 0xfa, 0xaa, 0xaa, 0xab, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x55, 0x7d, 0x55, 0x57, 0xd5, 0x55, 0x55, 0x55, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xaa, 0xfe, 0xaa, 0xaf, 0xea, 0xaa, 0xaa, 0xab, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x55, 0x7f, 0x55, 0x57, 0xd5, 0x55, 0x55, 0x55, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xaa, 0xbe, 0xaa, 0xaf, 0xea, 0xaa, 0xaa, 0xab, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x55, 0x5d, 0x55, 0x57, 0xd5, 0x55, 0x55, 0x55, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xaa, 0xbe, 0xaa, 0xaf, 0xea, 0xaa, 0xaa, 0xab, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x55, 0x7f, 0x55, 0x57, 0xd5, 0x55, 0x55, 0x57, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xaa, 0xbe, 0xaa, 0xaf, 0xea, 0xaa, 0xaa, 0xa3, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x55, 0x5d, 0x55, 0x57, 0xd5, 0x55, 0x55, 0x57, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xaa, 0xbe, 0xaa, 0xaf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x55, 0x7f, 0x55, 0x57, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xaa, 0xbe, 0xaa, 0xaf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x55, 0x5d, 0x55, 0x57, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xaa, 0xbe, 0xaa, 0xaf, 0xfe, 0xaa, 0xaa, 0xab, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x55, 0x7f, 0x55, 0x57, 0xfd, 0x55, 0x55, 0x57, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xaa, 0xbe, 0xaa, 0xaf, 0xfa, 0xaa, 0xaa, 0xab, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x55, 0x5d, 0x55, 0x57, 0xf5, 0x55, 0x55, 0x55, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xaa, 0xbe, 0xaa, 0xaf, 0xea, 0xaa, 0xaa, 0xab, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x55, 0x7f, 0x55, 0x57, 0xd5, 0x55, 0x55, 0x57, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xaa, 0xbe, 0xaa, 0xaf, 0xea, 0xaa, 0xaa, 0xab, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x55, 0x5d, 0x55, 0x57, 0xd5, 0x55, 0x55, 0x55, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xaa, 0xbe, 0xaa, 0xaf, 0xea, 0xaa, 0xaa, 0xab, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x55, 0x7f, 0x55, 0x57, 0xd5, 0x55, 0x55, 0x57, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xaa, 0xbf, 0xaa, 0xaf, 0xea, 0xaa, 0xaa, 0xab, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x55, 0x5f, 0x55, 0x57, 0xd5, 0x55, 0x55, 0x55, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xaa, 0xbf, 0xaa, 0xaf, 0xea, 0xaa, 0xaa, 0xab, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xd5, 0x7f, 0xd5, 0x57, 0xd5, 0x55, 0x55, 0x57, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xe2, 0x3f, 0xfa, 0x27, 0xe2, 0x22, 0x22, 0x23, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xf5, 0x7f, 0xfd, 0x57, 0xd5, 0x55, 0x55, 0x57, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xbb, 0xbf, 0xff, 0xff, 0xfb, 0xff, 0xfb, 0xbf, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xd5, 0x55, 0x55, 0x57, 0xd5, 0x5f, 0xfd, 0x57, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0xaf, 0xea, 0xaf, 0xfa, 0xaf, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x55, 0x55, 0x55, 0x57, 0xd5, 0x57, 0xf5, 0x57, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0xab, 0xea, 0xab, 0xfa, 0xab, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xd5, 0x55, 0x55, 0x57, 0xd5, 0x55, 0xfd, 0x55, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0xaf, 0xea, 0xaa, 0xfa, 0xab, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x55, 0x55, 0x55, 0x57, 0xd5, 0x55, 0xf5, 0x55, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0xab, 0xea, 0xaa, 0xfa, 0xab, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xd5, 0x55, 0x55, 0x57, 0xd5, 0x55, 0xfd, 0x55, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0xaf, 0xea, 0xaa, 0xfa, 0xab, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x55, 0x55, 0x55, 0x57, 0xd5, 0x55, 0x75, 0x55, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0xaf, 0xea, 0xaa, 0xfa, 0xab, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xd5, 0x55, 0x55, 0x5f, 0xd5, 0x55, 0xf5, 0x55, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0xbf, 0xea, 0xaa, 0xfa, 0xab, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x55, 0x55, 0x55, 0x7f, 0xd5, 0x55, 0x75, 0x55, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xea, 0xaa, 0xfa, 0xab, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd5, 0x55, 0xf5, 0x55, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xea, 0xaa, 0xfa, 0xab, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xf5, 0x55, 0x55, 0x57, 0xd5, 0x55, 0x75, 0x55, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xea, 0xaa, 0xaa, 0xab, 0xea, 0xaa, 0xfa, 0xab, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xd5, 0x55, 0x55, 0x57, 0xd5, 0x55, 0xf5, 0x55, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0xab, 0xea, 0xaa, 0xfa, 0xab, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x55, 0x55, 0x55, 0x57, 0xd5, 0x55, 0x75, 0x55, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0xab, 0xea, 0xaa, 0xfa, 0xab, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x55, 0x55, 0x55, 0x57, 0xd5, 0x55, 0xfd, 0x55, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0xaf, 0xea, 0xaa, 0xfa, 0xab, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x55, 0x55, 0x55, 0x57, 0xd5, 0x55, 0x7d, 0x55, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0xaf, 0xea, 0xaa, 0xfe, 0xab, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x55, 0x55, 0x55, 0x5f, 0xd5, 0x55, 0xfd, 0x55, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xab, 0xff, 0xff, 0xff, 0xff
};
void showSplashScreen() {
display.clearDisplay();
display.drawBitmap(0, 0, myBitmap, SCREEN_WIDTH, SCREEN_HEIGHT, SSD1306_WHITE);
display.display();
delay(2000); // Adjust the delay duration as needed
display.clearDisplay();
}
// State variables
enum AutoclaveStage { IDLE, HEATING, TIMER, COOLING, CYCLE_END };
AutoclaveStage currentStage = IDLE;
// Timer variables
unsigned long startTime = 0;
unsigned long timerDuration = 3000;
unsigned long coolingDuration = 3000;
// Menu variables
enum MenuState { MAIN_MENU, TIMER_MENU, COOLING_MENU };
MenuState currentMenu = MAIN_MENU;
// Function prototypes
void updateDisplay();
void startHeater();
void stopHeater();
void startTimer();
void stopTimer();
void startCooling();
void buzzerAlarm();
void resetSystem();
void resetToIdleState();
bool isTemperatureHigh();
void handleButtonPress();
String formatTime(unsigned long timeInSeconds);
unsigned long remainingTime();
void setDuration(unsigned long &duration, const String &label);
void setTimerDuration();
void setCoolingDuration();
void setup() {
pinMode(startButtonPin, INPUT_PULLUP);
pinMode(upButtonPin, INPUT_PULLUP);
pinMode(downButtonPin, INPUT_PULLUP);
pinMode(menuButtonPin, INPUT_PULLUP);
pinMode(heaterControlPin, OUTPUT);
pinMode(temperatureControlPin, INPUT);
pinMode(buzzerPin, OUTPUT);
pinMode(pressureReleaseValvePin, OUTPUT);
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for (;;)
;
}
// Show the splash screen
showSplashScreen();
display.display(); // Clear the display buffer
display.setTextColor(SSD1306_WHITE);
display.setTextSize(1);
display.setCursor(0, 0);
Serial.begin(9600);
updateDisplay();
}
void loop() {
// Check for temperature control signal
if (isTemperatureHigh()) {
switch (currentStage) {
case IDLE:
startTimer();
break;
case HEATING:
Serial.println("Transition from HEATING to TIMER");
startTimer();
break;
case TIMER:
if (remainingTime() == 0) {
Serial.println("Transition from TIMER to COOLING");
startCooling();
}
break;
case COOLING:
if (remainingTime() == 0) {
stopHeater();
Serial.println("Transition from COOLING to CYCLE_END");
currentStage = CYCLE_END;
updateDisplay();
buzzerAlarm();
}
break;
case CYCLE_END:
digitalWrite(pressureReleaseValvePin, HIGH);
resetSystem();
break;
}
}
handleButtonPress();
updateDisplay();
}
void updateDisplay() {
display.clearDisplay();
display.setCursor(0, 0);
switch (currentMenu) {
case MAIN_MENU:
switch (currentStage) {
case IDLE:
display.setTextSize(2);
display.setCursor(0, 0);
display.println("IDLE");
display.setTextSize(1);
display.setCursor(0, 20);
display.println("AGNEY POLYSOFT");
break;
case HEATING:
display.setTextSize(1);
display.setCursor(0, 0);
display.println("Status:");
display.setTextSize(2);
display.setCursor(0, 20);
display.println("HEATING");
break;
case TIMER:
display.setTextSize(1);
display.setCursor(0, 0);
display.println("Status:");
display.setTextSize(2);
display.setCursor(0, 20);
display.println("EXPOSURE");
display.setTextSize(1);
display.setCursor(0, 40);
display.print("Remaining: ");
display.print(formatTime(remainingTime()));
break;
case COOLING:
display.setTextSize(1);
display.setCursor(0, 0);
display.println("Status:");
display.setTextSize(2);
display.setCursor(0, 20);
display.println("COOLING");
display.setTextSize(1);
display.setCursor(0, 40);
display.print("Remaining: ");
display.print(formatTime(remainingTime()));
break;
case CYCLE_END:
display.setTextSize(2);
display.setCursor(0, 0);
display.println("CYCLE END");
display.setTextSize(1);
display.setCursor(0, 20);
display.println("Check Pressure Gauge");
display.setCursor(0, 30);
display.println("Before Opening Lid");
display.setCursor(0, 40);
display.print(formatTime(timerDuration));
break;
}
break;
case TIMER_MENU:
display.setTextSize(1);
display.setCursor(0, 0);
display.println("Menu >> Timer");
display.setCursor(0, 10);
display.print("Set Timer: ");
display.print(String(timerDuration / 60000) + " min");
break;
case COOLING_MENU:
display.setTextSize(1);
display.setCursor(0, 0);
display.println("Menu >> Cooling");
display.setCursor(0, 10);
display.print("Set Cooling: ");
display.print(String(coolingDuration / 60000) + " min");
break;
}
display.display();
}
String formatTime(unsigned long timeInSeconds) {
// Convert seconds to MM:SS format
unsigned int minutes = timeInSeconds / 60;
unsigned int seconds = timeInSeconds % 60;
// Format as MM:SS
return String(minutes) + ":" + (seconds < 10 ? "0" : "") + String(seconds);
}
unsigned long remainingTime() {
if (currentStage == TIMER || currentStage == COOLING) {
unsigned long elapsedTime = millis() - startTime;
unsigned long remaining = max(0UL, (currentStage == TIMER ? timerDuration : coolingDuration) - elapsedTime) / 1000; // Convert to seconds
return remaining;
}
return 0;
}
void startHeater() {
digitalWrite(heaterControlPin, HIGH);
currentStage = HEATING;
updateDisplay();
}
void stopHeater() {
digitalWrite(heaterControlPin, LOW);
}
void startTimer() {
startTime = millis();
currentStage = TIMER;
updateDisplay();
}
void stopTimer() {
timerDuration = millis() - startTime;
}
void startCooling() {
startTime = millis();
currentStage = COOLING;
updateDisplay();
}
void buzzerAlarm() {
digitalWrite(buzzerPin, HIGH);
delay(1000); // Buzz for 1 second
digitalWrite(buzzerPin, LOW);
}
void resetSystem() {
stopHeater();
timerDuration = 0;
coolingDuration = 0;
updateDisplay();
}
void resetToIdleState() {
currentStage = IDLE;
resetSystem();
updateDisplay();
}
bool isTemperatureHigh() {
return digitalRead(temperatureControlPin) == HIGH;
}
void handleButtonPress() {
// Check for start button press
if (digitalRead(startButtonPin) == LOW) {
delay(50);
if (digitalRead(startButtonPin) == LOW) {
switch (currentStage) {
case IDLE:
startHeater();
break;
case HEATING:
// Do nothing while heating
break;
case TIMER:
stopTimer();
break;
case COOLING:
startCooling();
// Do nothing while cooling
break;
case CYCLE_END:
resetSystem();
break;
}
}
}
// Check for up button press
if (digitalRead(upButtonPin) == LOW) {
delay(50);
if (digitalRead(upButtonPin) == LOW) {
switch (currentMenu) {
case TIMER_MENU:
timerDuration += 60000; // Increment by 1 minute
break;
case COOLING_MENU:
coolingDuration += 60000; // Increment by 1 minute
break;
}
updateDisplay();
}
}
// Check for down button press
if (digitalRead(downButtonPin) == LOW) {
delay(50);
if (digitalRead(downButtonPin) == LOW) {
switch (currentMenu) {
case TIMER_MENU:
timerDuration = max(0UL, timerDuration - 60000); // Decrement by 1 minute
break;
case COOLING_MENU:
coolingDuration = max(0UL, coolingDuration - 60000); // Decrement by 1 minute
break;
}
updateDisplay();
}
}
// Check for menu button press
if (digitalRead(menuButtonPin) == LOW) {
delay(50);
if (digitalRead(menuButtonPin) == LOW) {
// Toggle through menu states
switch (currentMenu) {
case MAIN_MENU:
currentMenu = TIMER_MENU;
break;
case TIMER_MENU:
currentMenu = COOLING_MENU;
break;
case COOLING_MENU:
currentMenu = MAIN_MENU;
break;
}
updateDisplay();
}
}
// Check for Reset button press
if (digitalRead(rstbtnPin) == HIGH) {
delay(50);
if (digitalRead(rstbtnPin) == HIGH) {
// Toggle through menu states
resetToIdleState();
updateDisplay();
}
}
}