phases displayed across whole screen
This commit is contained in:
parent
12f478271f
commit
24b1986dec
@ -15,29 +15,30 @@ GyverOLED<SSD1306_128x64, OLED_BUFFER> oled;
|
|||||||
// SSR pin configuration
|
// SSR pin configuration
|
||||||
const int ssrPin = 7;
|
const int ssrPin = 7;
|
||||||
|
|
||||||
// Process phases (temperatures in Celsius and duration in minutes)
|
// Profile structure definition
|
||||||
|
struct Phase {
|
||||||
|
int temperature;
|
||||||
|
int duration; // in minutes
|
||||||
|
};
|
||||||
|
|
||||||
// const int temperatures[] = {49, 51, 55, 45};
|
struct Profile {
|
||||||
// const int phaseDurations[] = {30, 30, 30, 30}; // Individual durations for each phase in minutes
|
const char* name;
|
||||||
// const int numPhases = 3;
|
Phase phases[7]; // Maximum of 6 phases per profile
|
||||||
|
int numPhases;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Profiles definition
|
||||||
|
Profile profiles[] = {
|
||||||
|
{"Test", {{49, 1}, {51, 1}, {55, 1}, {45, 1}}, 4},
|
||||||
|
{"Пшеница", {{47, 40}, {55, 40}, {65, 20}, {72, 20}, {85, 20}}, 5},
|
||||||
|
{"Veggies Sous Vide", {{85, 120}}, 1},
|
||||||
|
{"Profile 4", {{47, 120}, {53, 120}, {65, 150}, {72, 60}, {90, 105}, {50, 60}}, 6},
|
||||||
|
{"Profile 5", {{55, 60}, {65, 120}, {72, 120}, {80, 120}, {90, 30}, {10, 100}}, 6}
|
||||||
|
};
|
||||||
|
|
||||||
// const int temperatures[] = {47, 55, 65, 72, 85, 0};
|
// Select active profile (constant at this point)
|
||||||
// const int phaseDurations[] = {20, 20, 20, 20, 20, 5}; // Individual durations for each phase in minutes
|
const int activeProfileIndex = 1; // Index of the active profile, starting from 0
|
||||||
// const int numPhases = 5;
|
Profile activeProfile = profiles[activeProfileIndex];
|
||||||
|
|
||||||
// const int temperatures[] = {85, 50};
|
|
||||||
// const int phaseDurations[] = {120, 120}; // Individual durations for each phase in minutes
|
|
||||||
// const int numPhases = 1;
|
|
||||||
|
|
||||||
const int temperatures[] = {47, 53, 65, 72, 90, 50};
|
|
||||||
const int phaseDurations[] = {120, 120, 150, 60, 105, 60}; // Individual durations for each phase in minutes
|
|
||||||
const int numPhases = 5;
|
|
||||||
|
|
||||||
// const int temperatures[] = {55, 65, 72, 80, 90, 10};
|
|
||||||
// const int phaseDurations[] = {60, 120, 120, 120, 30, 100}; // Individual durations for each phase in minutes
|
|
||||||
// const int numPhases = 5;
|
|
||||||
|
|
||||||
|
|
||||||
// PID Control variables
|
// PID Control variables
|
||||||
double Setpoint, Input, Output;
|
double Setpoint, Input, Output;
|
||||||
@ -48,8 +49,13 @@ PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);
|
|||||||
unsigned long phaseStartTime;
|
unsigned long phaseStartTime;
|
||||||
unsigned long totalStartTime;
|
unsigned long totalStartTime;
|
||||||
unsigned long ssrLastSwitchTime;
|
unsigned long ssrLastSwitchTime;
|
||||||
|
unsigned long totalElapsedTime;
|
||||||
|
unsigned long totalProcessTime;
|
||||||
const int ssrSwitchInterval = 1000; // SSR switching interval in milliseconds
|
const int ssrSwitchInterval = 1000; // SSR switching interval in milliseconds
|
||||||
|
|
||||||
|
// Buffer for formatted time strings
|
||||||
|
char timeBuffer[10];
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
pinMode(ssrPin, OUTPUT);
|
pinMode(ssrPin, OUTPUT);
|
||||||
Serial.begin(9600);
|
Serial.begin(9600);
|
||||||
@ -58,12 +64,11 @@ void setup() {
|
|||||||
oled.setScale(2); // Set text scale to 2 for better visibility
|
oled.setScale(2); // Set text scale to 2 for better visibility
|
||||||
oled.print("Starting...");
|
oled.print("Starting...");
|
||||||
oled.update();
|
oled.update();
|
||||||
delay(2000);
|
oled.setScale(1); // Set text scale back to 1 for more detailed information
|
||||||
oled.setScale(0); // Set text scale to 2 for better visibility
|
|
||||||
|
|
||||||
// Begin the first phase
|
// Begin the first phase
|
||||||
phaseStartTime = totalStartTime = millis();
|
phaseStartTime = totalStartTime = millis();
|
||||||
Setpoint = temperatures[0];
|
Setpoint = activeProfile.phases[0].temperature;
|
||||||
myPID.SetMode(AUTOMATIC);
|
myPID.SetMode(AUTOMATIC);
|
||||||
myPID.SetOutputLimits(0, 1); // SSR is either ON or OFF
|
myPID.SetOutputLimits(0, 1); // SSR is either ON or OFF
|
||||||
digitalWrite(ssrPin, HIGH); // Start with heater on
|
digitalWrite(ssrPin, HIGH); // Start with heater on
|
||||||
@ -84,48 +89,85 @@ void loop() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Display time calculations
|
// Display time calculations
|
||||||
unsigned long totalElapsedTime = (currentTime - totalStartTime) / 1000; // Total elapsed time in seconds
|
totalElapsedTime = (currentTime - totalStartTime) / 1000; // Total elapsed time in seconds
|
||||||
unsigned long totalProcessTime = 0;
|
totalProcessTime = 0;
|
||||||
for (int i = 0; i < numPhases; i++) {
|
for (int i = 0; i < activeProfile.numPhases; i++) {
|
||||||
totalProcessTime += phaseDurations[i] * 60;
|
totalProcessTime += activeProfile.phases[i].duration * 60;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the phase duration is complete
|
// Check if the phase duration is complete
|
||||||
if ((currentTime - phaseStartTime) / 1000 >= phaseDurations[currentPhase] * 60) {
|
if ((currentTime - phaseStartTime) / 1000 >= activeProfile.phases[currentPhase].duration * 60) {
|
||||||
currentPhase++;
|
currentPhase++;
|
||||||
if (currentPhase >= numPhases) {
|
if (currentPhase >= activeProfile.numPhases) {
|
||||||
oled.clear();
|
oled.clear();
|
||||||
oled.print("Complete");
|
oled.print("Complete");
|
||||||
digitalWrite(ssrPin, LOW); // Turn off the heater
|
digitalWrite(ssrPin, LOW); // Turn off the heater
|
||||||
return; // Stop further execution
|
return; // Stop further execution
|
||||||
}
|
}
|
||||||
phaseStartTime = currentTime; // Reset the start time for the new phase
|
phaseStartTime = currentTime; // Reset the start time for the new phase
|
||||||
Setpoint = temperatures[currentPhase];
|
Setpoint = activeProfile.phases[currentPhase].temperature;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Display data on the OLED
|
|
||||||
oled.clear();
|
|
||||||
oled.setCursor(0, 0);
|
|
||||||
oled.print(formatTime(totalElapsedTime));
|
|
||||||
oled.print(" (");
|
|
||||||
oled.print(formatTime(totalProcessTime));
|
|
||||||
oled.print(")");
|
|
||||||
|
|
||||||
oled.setCursor(0, 1);
|
// Display all phases and highlight the current one
|
||||||
oled.print(currentPhase + 1);
|
printPhases(currentPhase, currentTime - phaseStartTime);
|
||||||
oled.print(". ");
|
|
||||||
oled.print((int)Input);
|
|
||||||
oled.print("C ");
|
|
||||||
oled.print((int)Setpoint);
|
|
||||||
oled.print("C ");
|
|
||||||
oled.print(formatTime((phaseDurations[currentPhase] * 60) - ((currentTime - phaseStartTime) / 1000)));
|
|
||||||
oled.update();
|
oled.update();
|
||||||
|
|
||||||
delay(1000); // Update every second
|
delay(1000); // Update every second
|
||||||
}
|
}
|
||||||
|
|
||||||
String formatTime(long seconds) {
|
void printPhases(int currentPhase, unsigned long phaseElapsedTime) {
|
||||||
long mins = seconds / 60;
|
oled.clear();
|
||||||
int secs = seconds % 60;
|
|
||||||
return (mins < 10 ? "0" : "") + String(mins) + ":" + (secs < 10 ? "0" : "") + String(secs);
|
oled.setCursor(0, 0);
|
||||||
|
oled.print(activeProfile.name);
|
||||||
|
// Display the totals and current state on the OLED
|
||||||
|
oled.setCursor(18, 1);
|
||||||
|
formatTime(totalElapsedTime, timeBuffer);
|
||||||
|
oled.print(timeBuffer);
|
||||||
|
oled.print(" / ");
|
||||||
|
formatTime(totalProcessTime, timeBuffer);
|
||||||
|
oled.print(timeBuffer);
|
||||||
|
|
||||||
|
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
|
||||||
|
unsigned long timeRemaining = (activeProfile.phases[i].duration * 60) - (phaseElapsedTime / 1000);
|
||||||
|
formatTime(timeRemaining, timeBuffer);
|
||||||
|
oled.print(i + 1);
|
||||||
|
oled.print(". ");
|
||||||
|
oled.print((int)Input);
|
||||||
|
oled.print("C ");
|
||||||
|
oled.print((int)Setpoint);
|
||||||
|
oled.print("C ");
|
||||||
|
oled.print(timeBuffer);
|
||||||
|
} 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.invertText(false); // Ensure text inversion is off after the loop
|
||||||
|
}
|
||||||
|
|
||||||
|
void formatTime(long seconds, char* buffer) {
|
||||||
|
long hours = seconds / 3600;
|
||||||
|
long mins = (seconds % 3600) / 60;
|
||||||
|
int secs = seconds % 60;
|
||||||
|
|
||||||
|
if (hours > 0) {
|
||||||
|
sprintf(buffer, "%ld:%02ld:%02d", hours, mins, secs);
|
||||||
|
} else {
|
||||||
|
sprintf(buffer, "%ld:%02d", mins, secs);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user