void printPhases() { // oled.clear(); if (isComplete) { // Show completion time and current temperature instead of the title oled.setCursor(0, 0); oled.invertText(true); oled.print("Done!"); oled.invertText(false); oled.print(" "); formatTime((currentTime - finishTime) / 1000, timeBuffer); // Time since completion oled.print(timeBuffer); oled.print(" "); oled.print(Input,0); oled.print("c"); oled.print("->"); oled.print((int)Setpoint); oled.print("c "); } else { oled.setCursor(0, 0); oled.print(activeProfile.name); oled.print(" "); } // Display the totals and current state on the OLED oled.setCursor(0, 1); oled.print(" "); oled.setCursor(18, 1); formatTime(totalElapsedTime, timeBuffer); oled.print(timeBuffer); oled.print(" / "); formatTime(totalProcessTime, timeBuffer); oled.print(timeBuffer); oled.print(" "); for (int i = 0; i < activeProfile.numPhases; i++) { if (i == currentPhase) { oled.invertText(true); // Invert text for the current phase oled.setCursor(0, i + 2); // Set cursor to the row corresponding to the phase long timeRemaining = (activeProfile.phases[i].duration * 60) - ((currentTime - phaseStartTime) / 1000); formatTime(timeRemaining, timeBuffer); oled.print(i + 1); oled.print(". "); oled.print(Input, 1); oled.print("c "); if (fabs(Setpoint - round(Setpoint)) < 0.05) { oled.print(Setpoint, 0); // Print without decimals } else { oled.print(Setpoint, 1); // Print with 1 decimal place } oled.print("c "); if (!isInTransition) { oled.print(timeBuffer); } oled.print(" "); } else { oled.invertText(false); // Normal text for other phases oled.setCursor(0, i + 2); // Set cursor to the row corresponding to the phase formatTime(activeProfile.phases[i].duration * 60, timeBuffer); oled.print(i + 1); oled.print(". "); oled.print(activeProfile.phases[i].temperature); oled.print("c "); oled.print(timeBuffer); oled.print(" "); } } if (temperatureSensorError) { oled.invertText(true); oled.setCursor(0, 0); oled.setScale(2); oled.print("T = "); oled.print(Input); oled.print(" "); oled.setScale(1); digitalWrite(activeBuzzerPin, HIGH); delay(5); digitalWrite(activeBuzzerPin, LOW); } if (failedReadingCount) { oled.setCursor(0, 7); oled.print(failedReadingCount); oled.print(" ("); oled.print(failedReadingLastValue); oled.print(") "); } oled.invertText(false); // Ensure text inversion is off after the loop // oled.setCursor(110,7); // sprintf(timeBuffer, "%3d", (int)(Output*100)); // oled.print(timeBuffer); // oled.update(); } void displaySelection() { // oled.clear(); // Display all profiles with the selected one highlighted for (int i = 0; i < (int) (sizeof(profiles) / sizeof(profiles[0])); i++) { if (i == selectedProfileIndex) { oled.invertText(true); // Highlight the selected profile } oled.setCursor(0, i); // Set cursor to the correct row oled.print(profiles[i].name); oled.invertText(false); // Reset text inversion for other profiles } oled.update(); } void formatTime(long seconds, char* buffer) { long hours = seconds / 3600; long mins = (seconds % 3600) / 60; int secs = seconds % 60; buffer[0] = '\0'; // Ensure the buffer is empty if (hours > 0) { sprintf(buffer + strlen(buffer), "%ldh", hours); } if (mins > 0) { sprintf(buffer + strlen(buffer), "%ldm", mins); } if (secs > 0) { sprintf(buffer + strlen(buffer), "%ds", secs); } }