#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);
#define NTC_PIN A0
#define REFERENCE_RES 10000.0
#define NTC_NOMINAL 10000.0
#define TEMPERATURE_NOMINAL 25.0
#define B_COEFFICIENT 3950
#define SERIES_RES 10000.0
#define TEMP_HEATING 230.0
#define TEMP_READY 280.0
#define TEMP_OVERHEAT 290.0
unsigned long startTime = 0;
unsigned long elapsedTime = 0;
// Function prototypes
void centerText(String text, int y);
void printStopwatch(unsigned long ms);
float readNTCTemp();
void startupSequence();
void centerText(String text, int y) {
int16_t x1, y1;
uint16_t w, h;
display.getTextBounds(text, 0, 0, &x1, &y1, &w, &h);
display.setCursor((SCREEN_WIDTH - w) / 2, y);
display.println(text);
}
float readNTCTemp() {
int reading = analogRead(NTC_PIN);
float voltage = reading * (5.0 / 1024.0);
float resistance = SERIES_RES * (5.0 / voltage - 1.0);
float steinhart = resistance / NTC_NOMINAL;
steinhart = log(steinhart);
steinhart /= B_COEFFICIENT;
steinhart += 1.0 / (TEMPERATURE_NOMINAL + 273.15);
steinhart = 1.0 / steinhart;
return steinhart - 273.15;
}
void printStopwatch(unsigned long ms) {
int hours = ms / 3600000;
int minutes = (ms / 60000) % 60;
int seconds = (ms / 1000) % 60;
display.setCursor(60, 55); // Moved up slightly for better spacing
if (hours < 10) display.print("0");
display.print(hours);
display.print(":");
if (minutes < 10) display.print("0");
display.print(minutes);
display.print(":");
if (seconds < 10) display.print("0");
display.print(seconds);
}
void setup() {
Serial.begin(9600);
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 failed"));
for(;;);
}
startupSequence();
startTime = millis();
}
void loop() {
float temp = readNTCTemp();
elapsedTime = millis() - startTime;
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
centerText("XAVA FOGGER 2000", 2);
display.drawLine(0, 12, 127, 12, SSD1306_WHITE);
display.setTextSize(2);
String tempStr = String(temp, 1) + "C";
centerText(tempStr, 22);
// Heater temperature status
display.setTextSize(1);
display.setCursor(0, 45);
String status;
if (temp < TEMP_HEATING) status = "STATUS: HEATING";
else if (temp < TEMP_READY) status = "STATUS: READY";
else if (temp >= TEMP_OVERHEAT) status = "STATUS: OVERHEAT!";
else status = "STATUS: COOLING";
display.println(status);
// Operation time below heater status
display.setCursor(0, 55);
display.print("OPERATION:");
printStopwatch(elapsedTime);
display.display();
delay(100);
}
void startupSequence() {
display.clearDisplay();
display.setTextSize(1.7);
display.setTextColor(SSD1306_WHITE);
centerText("Booting XAVA", 28);
display.display();
delay(1000);
display.clearDisplay();
display.setTextSize(4);
centerText("XAVA", 20);
display.display();
delay(2000);
String checks[] = {"Power: Normal", "Heater:Normal", "RGB: Normal", "Laser: Normal"};
for (int i = 0; i < 4; i++) {
display.clearDisplay();
display.setTextSize(2);
centerText("XAVA", 5);
display.setTextSize(1.5);
display.setCursor(20, 25);
display.println("Machine Check:");
for (int j = 0; j <= i; j++) {
display.setCursor(10, 36 + j*7);
display.println(checks[j]);
}
display.display();
delay(1500);
}
display.clearDisplay();
display.setTextSize(2);
centerText("MACHINE", 20);
centerText("READY", 35);
display.display();
delay(1000);
}