Compare commits

..

No commits in common. "adffdc48c598a98c702b181299f720d52849eae5" and "d4a564cea3a9c517448ee201af82dc70788ec8a5" have entirely different histories.

8 changed files with 480 additions and 429 deletions

View File

@ -1,36 +0,0 @@
LP_TIMER((long)10*60*1000, writeEEPROM);
void writeEEPROM() {
#if useEEPROM
lastEEPROMWriteTime = millis();
EEPROM.put(0, activeProfileIndex); // Store the active profile index
EEPROM.put(4, totalElapsedTime); // Store the total elapsed time
Serial.print("EEPROM written: ");
Serial.print(activeProfileIndex);
Serial.print(" ");
Serial.println(totalElapsedTime);
#endif
}
void readEEPROM() {
#if useEEPROM
long time = 0;
EEPROM.get(0, activeProfileIndex); // Store the active profile index
EEPROM.get(4, time); // Store the total elapsed time
if (activeProfileIndex != 100) {
totalStartTime = millis() - time*1000;
calculateTotalTime();
getPhaseAndTemperature();
inSelectionMode = false;
}
else {
oled.clear();
displaySelection();
}
Serial.print("EEPROM read: ");
Serial.print(activeProfileIndex);
Serial.print(" ");
Serial.println(time);
#endif
}

View File

@ -1,12 +1,9 @@
#include <Arduino.h>
#include <Looper.h>
#define useEEPROM 1 #define useEEPROM 1
// #define TempSensorMax // #define TempSensorMax
#define TempSensorDallas #define TempSensorDallas
// #define PlotValues // #define PlotValues
// #include <Wire.h> #include <Wire.h>
#include <GyverOLED.h> #include <GyverOLED.h>
#include "GyverEncoder.h" #include "GyverEncoder.h"
@ -66,14 +63,12 @@ struct Profile {
Profile profiles[] = { Profile profiles[] = {
{"Chickpeas", 1, {{46, 120}, {55, 60}, {65, 150}, {70, 60}, {90, 105}}, 5}, {"Chickpeas", 1, {{46, 120}, {55, 60}, {65, 150}, {70, 60}, {90, 105}}, 5},
{"Lentils", 3, {{46, 120}, {53, 120}, {65, 180}, {72, 90}, {90, 15}}, 5}, {"Lentils", 3, {{46, 120}, {53, 120}, {65, 180}, {72, 90}, {90, 15}}, 5},
{"Gradual", 10, {{46, 120}, {90, 30}}, 2}, {"Gradual", 10, {{46, 120}, {80, 60}}, 2},
{"Long gradual", 15, {{46, 120}, {80, 60}, {90, 15}}, 3}, {"Long gradual", 10, {{46, 120}, {80, 60}, {90, 15}}, 3},
{"Wheat", 1, {{46, 120}, {53, 40}, {65, 40}, {72, 40}, {85, 40}}, 5}, {"Wheat", 1, {{46, 60}, {53, 60}, {65, 20}, {72, 20}, {85, 20}}, 5},
{"Amazake", 1, {{51, 480}}, 1}, {"SV1", 1, {{55, 30}, {85, 120}}, 2},
{"SV", 0, {{46, 45}}, 1}, {"SV2", 0, {{46, 45}}, 1},
{"Tempeh magic", 1, {{46, 300}, {55, 180}, {72, 20}, {90, 15}}, 4}, {"Yoghurt maker", 0, {{40, 300}, {40, 300}, {30, 300}}, 3},
// {"Yoghurt maker", 0, {{40, 300}, {40, 300}, {30, 300}}, 3},
// {"TEST", 0, {{46, 1}}, 1},
}; };
// Global variables for profile selection and execution // Global variables for profile selection and execution
@ -114,6 +109,15 @@ const int ssrSwitchInterval = 1000; // SSR switching interval in milliseconds
// Buffer for formatted time strings // Buffer for formatted time strings
char timeBuffer[10]; char timeBuffer[10];
uint32_t timerExecution = 0;
#define T_PERIOD_EXEC 1000 // period of Execution processing
uint32_t timerSSR = 0;
#define T_PERIOD_SSR 500 // period of heater handling
uint32_t timerTemp = 0;
#define T_PERIOD_TEMP 1000 // period of dallas sensor requesting
uint32_t timerChecks= 0;
#define T_PERIOD_Checks 1000 // period of additional checks
bool boolLastCompletedState = false; bool boolLastCompletedState = false;
float failedReadingLastValue = 0; float failedReadingLastValue = 0;
@ -143,6 +147,469 @@ void setup() {
} }
void loop() { void loop() {
Looper.loop(); enc1.tick();
isLeft = enc1.isLeft();
isRight = enc1.isRight();
isClick = enc1.isClick();
if (isLeft || isRight || isClick) {
handleEncoder();
}
handleTemperatureSensor();
handleExecution();
handleHeaterAdv();
handleAdditionalChecks();
} }
void handleAdditionalChecks() {
long time = millis();
if (time - timerChecks < T_PERIOD_Checks) {
return;
}
timerChecks = time;
if (isComplete && !boolLastCompletedState) {
boolLastCompletedState = true;
for(int i=0; i<10; i++) {
digitalWrite(activeBuzzerPin, HIGH);
delay(100);
digitalWrite(activeBuzzerPin, LOW);
delay(100);
}
}
}
void handleTemperatureSensor() {
long time = millis();
static int currentPart = 0;
if (time - timerTemp < T_PERIOD_TEMP) {
return;
}
timerTemp = time;
#ifdef TempSensorDallas
Input = (double) sensors.getTempCByIndex(0);
sensors.requestTemperatures(); // Send the command to get temperatures
#endif
#ifdef TempSensorMax // to go into the read temp function, rename from dallas temp
Input = thermocouple.readCelsius();
#endif
if (isnan(Input) || Input < 20 || Input > 95) {
failedReadingLastValue = (float) Input;
failedReadingCount++;
temperatureSensorError = true;
}
else {
temperatureSensorError = false;
}
}
void handleHeaterSimple() {
long time = millis();
static int currentPart = 0;
if (time - timerSSR < T_PERIOD_SSR) {
return;
}
if (inSelectionMode) {
digitalWrite(ssrPin, LOW);
return;
}
timerSSR = time;
int current = Output * PARTS;
oled.setCursor(104, 7);
char symbol;
for (int i = 0; i < PARTS; i++) {
symbol = current > i ? '=' : '-';
if (currentPart == i) {
oled.invertText(true);
}
oled.print(symbol);
oled.invertText(false);
}
digitalWrite(ssrPin, currentPart < current ? HIGH : LOW);
currentPart++;
if (currentPart >= PARTS) {
currentPart = 0;
}
}
void handleHeaterAdv() {
long time = millis();
static int currentPart = 0;
static bool states[PARTS];
if (time - timerSSR < T_PERIOD_SSR) {
return;
}
if (inSelectionMode) {
digitalWrite(ssrPin, LOW);
return;
}
timerSSR = time;
int current = Output/100 * PARTS;
int last = 0;
for (int i = 1; i < PARTS; i++) {
last += states[i] ? 1 : 0;
if (i) {
states[i-1] = states[i];
}
}
bool next = current >= last ? true : false;
if (Output < 1) next = false;
states[PARTS-1] = next;
oled.setCursor(128-6*PARTS, 7);
sprintf(timeBuffer, "%3d", (int)(Output));
char symbol;
for (int i = 0; i < PARTS; i++) {
int index = i - (PARTS - 3);
symbol = index < 0 ? ' ' : timeBuffer[index];
oled.invertText(states[i]);
oled.print(symbol);
oled.invertText(false);
}
if (temperatureSensorError) {
next = 0;
}
digitalWrite(ssrPin, next);
currentPart++;
if (currentPart >= PARTS) {
currentPart = 0;
}
#ifdef PlotValues
Serial.print(Setpoint);
Serial.print(",");
Serial.print(Input);
Serial.print(",");
Serial.print(Output);
Serial.println(",0,100");
#endif
}
void handleEncoder() {
if (inSelectionMode) {
handleProfileSelection();
}
else {
handleExecutionSelection();
}
}
void handleExecutionSelection() {
if (isClick) {
activeProfileIndex = 100;
activeProfile = profiles[activeProfileIndex];
inSelectionMode = true;
writeEEPROM();
oled.clear();
displaySelection();
return;
}
}
void handleExecution() {
currentTime = millis();
if (inSelectionMode || (currentTime - timerExecution < T_PERIOD_EXEC)) { // таймер на millis()
return;
}
timerExecution = currentTime;
totalElapsedTime = (currentTime - totalStartTime) / 1000; // Total elapsed time in seconds
if ((currentTime - lastEEPROMWriteTime) >= (long)10*60*1000) {
writeEEPROM();
}
getPhaseAndTemperature();
regulator.input = (float)Input;
regulator.setpoint = Setpoint;
regulator.getResultNow();
Output = regulator.output;
if (isComplete && currentPhase >= activeProfile.numPhases && !finishTime) {
finishTime = currentTime;
}
// Display all phases and highlight the current one
printPhases();
}
void startExecution() {
activeProfile = profiles[activeProfileIndex];
inSelectionMode = false; // Switch to execution mode
phaseStartTime = totalStartTime = millis(); // Start the timer
totalElapsedTime = 0;
regulator.setpoint = 0;
// digitalWrite(ssrPin, HIGH); // Start with heater on
ssrLastSwitchTime = millis();
calculateTotalTime();
getPhaseAndTemperature();
writeEEPROM();
oled.clear();
boolLastCompletedState = isComplete = false;
}
void handleProfileSelection() {
if (!isClick && !isLeft && !isRight) {
return;
}
// Handle encoder input for selecting the profile
if (isRight) {
selectedProfileIndex = (selectedProfileIndex + 1) % (sizeof(profiles) / sizeof(profiles[0]));
} else if (isLeft) {
selectedProfileIndex = (selectedProfileIndex - 1 + (sizeof(profiles) / sizeof(profiles[0]))) % (sizeof(profiles) / sizeof(profiles[0]));
}
displaySelection();
// Start the selected profile on button press
if (isClick) {
activeProfileIndex = selectedProfileIndex;
startExecution();
}
}
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 calculateTotalTime() {
// Calculate total process time, including transitions
activeProfile = profiles[activeProfileIndex];
totalProcessTime = 0;
for (int i = 0; i < activeProfile.numPhases; i++) {
totalProcessTime += activeProfile.phases[i].duration * 60;
if (i < activeProfile.numPhases - 1) {
int tempDiff = abs(activeProfile.phases[i + 1].temperature - activeProfile.phases[i].temperature);
totalProcessTime += tempDiff * 60 * activeProfile.transitionMinutesPerDegree;
}
}
}
void getPhaseAndTemperature() {
long accumulatedTime = 0;
for (int i = 0; i < activeProfile.numPhases; i++) {
int phaseDuration = activeProfile.phases[i].duration * 60;
// Check for transition
if (i > 0) {
int previousTemp = activeProfile.phases[i - 1].temperature;
int targetTemp = activeProfile.phases[i].temperature;
int tempDiff = abs(targetTemp - previousTemp);
int transitionDuration = tempDiff * 60 * activeProfile.transitionMinutesPerDegree;
if (totalElapsedTime < accumulatedTime + transitionDuration) {
isInTransition = true;
currentPhase = i - 1; // Keep currentPhase as the previous phase
int timeInTransition = totalElapsedTime - accumulatedTime;
Setpoint = previousTemp + (double)timeInTransition / (60 * activeProfile.transitionMinutesPerDegree) * (targetTemp > previousTemp ? 1 : -1);
phaseStartTime = totalStartTime + accumulatedTime * 1000; // Set phase start time
return;
}
accumulatedTime += transitionDuration;
}
// Check if we're within the current phase
if (totalElapsedTime < accumulatedTime + phaseDuration) {
isInTransition = false;
currentPhase = i;
Setpoint = activeProfile.phases[i].temperature;
phaseStartTime = totalStartTime + accumulatedTime * 1000; // Set phase start time
return;
}
accumulatedTime += phaseDuration;
}
// If the elapsed time exceeds the total duration, indicate completion
currentPhase = activeProfile.numPhases; // Indicate completion
Setpoint = 45; // Default to 45°C after completion
isInTransition = false;
isComplete = true; // Mark the process as complete
phaseStartTime = totalStartTime + accumulatedTime * 1000; // Set phase start time to the end
}
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 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);
}
}
void writeEEPROM() {
#if useEEPROM
lastEEPROMWriteTime = millis();
EEPROM.put(0, activeProfileIndex); // Store the active profile index
EEPROM.put(4, totalElapsedTime); // Store the total elapsed time
Serial.print("EEPROM written: ");
Serial.print(activeProfileIndex);
Serial.print(" ");
Serial.println(totalElapsedTime);
#endif
}
void readEEPROM() {
#if useEEPROM
long time = 0;
EEPROM.get(0, activeProfileIndex); // Store the active profile index
EEPROM.get(4, time); // Store the total elapsed time
if (activeProfileIndex != 100) {
totalStartTime = millis() - time*1000;
calculateTotalTime();
getPhaseAndTemperature();
inSelectionMode = false;
}
else {
oled.clear();
displaySelection();
}
Serial.print("EEPROM read: ");
Serial.print(activeProfileIndex);
Serial.print(" ");
Serial.println(time);
#endif
}

View File

@ -1,132 +0,0 @@
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);
}
}

View File

@ -1,28 +0,0 @@
LP_THREAD({
if (isComplete && !boolLastCompletedState) {
boolLastCompletedState = true;
for(int i=0; i<10; i++) {
digitalWrite(activeBuzzerPin, HIGH);
delay(100);
digitalWrite(activeBuzzerPin, LOW);
delay(200);
}
}
LP_DELAY(10);
});
// LP_TIMER(1000, AdditionalChecks);
// void AdditionalChecks() {
// if (isComplete && !boolLastCompletedState) {
// boolLastCompletedState = true;
// for(int i=0; i<5; i++) {
// digitalWrite(activeBuzzerPin, HIGH);
// delay(100);
// digitalWrite(activeBuzzerPin, LOW);
// delay(500);
// }
// }
// }

View File

@ -1,51 +0,0 @@
LP_THREAD({
enc1.tick();
isLeft = enc1.isLeft();
isRight = enc1.isRight();
isClick = enc1.isClick();
if (!isLeft && !isRight && !isClick) {
return;
}
if (inSelectionMode) {
handleProfileSelection();
}
else {
handleExecutionSelection();
}
LP_DELAY(10);
});
void handleExecutionSelection() {
if (isClick) {
activeProfileIndex = 100;
activeProfile = profiles[activeProfileIndex];
inSelectionMode = true;
writeEEPROM();
oled.clear();
displaySelection();
return;
}
}
void handleProfileSelection() {
if (!isClick && !isLeft && !isRight) {
return;
}
// Handle encoder input for selecting the profile
if (isRight) {
selectedProfileIndex = (selectedProfileIndex + 1) % (sizeof(profiles) / sizeof(profiles[0]));
} else if (isLeft) {
selectedProfileIndex = (selectedProfileIndex - 1 + (sizeof(profiles) / sizeof(profiles[0]))) % (sizeof(profiles) / sizeof(profiles[0]));
}
displaySelection();
// Start the selected profile on button press
if (isClick) {
activeProfileIndex = selectedProfileIndex;
startExecution();
}
}

View File

@ -1,54 +0,0 @@
LP_TIMER(500, HandleHeater);
void HandleHeater() {
static int currentPart = 0;
static bool states[PARTS];
if (inSelectionMode) {
digitalWrite(ssrPin, LOW);
return;
}
int current = Output/100 * PARTS;
int last = 0;
for (int i = 1; i < PARTS; i++) {
last += states[i] ? 1 : 0;
if (i) {
states[i-1] = states[i];
}
}
bool next = current >= last ? true : false;
if (Output < 1) next = false;
states[PARTS-1] = next;
oled.setCursor(128-6*PARTS, 7);
sprintf(timeBuffer, "%3d", (int)(Output));
char symbol;
for (int i = 0; i < PARTS; i++) {
int index = i - (PARTS - 3);
symbol = index < 0 ? ' ' : timeBuffer[index];
oled.invertText(states[i]);
oled.print(symbol);
oled.invertText(false);
}
if (temperatureSensorError) {
next = 0;
}
digitalWrite(ssrPin, next);
currentPart++;
if (currentPart >= PARTS) {
currentPart = 0;
}
#ifdef PlotValues
Serial.print(Setpoint);
Serial.print(",");
Serial.print(Input);
Serial.print(",");
Serial.print(Output);
Serial.println(",0,100");
#endif
}

View File

@ -1,95 +0,0 @@
LP_TIMER(1000, HandleExecution);
void HandleExecution() {
currentTime = millis();
if (inSelectionMode) {
return;
}
totalElapsedTime = (currentTime - totalStartTime) / 1000; // Total elapsed time in seconds
getPhaseAndTemperature();
regulator.input = (float)Input;
regulator.setpoint = Setpoint;
regulator.getResultNow();
Output = regulator.output;
if (isComplete && currentPhase >= activeProfile.numPhases && !finishTime) {
finishTime = currentTime;
}
// Display all phases and highlight the current one
printPhases();
}
void getPhaseAndTemperature() {
long accumulatedTime = 0;
for (int i = 0; i < activeProfile.numPhases; i++) {
int phaseDuration = activeProfile.phases[i].duration * 60;
// Check for transition
if (i > 0) {
int previousTemp = activeProfile.phases[i - 1].temperature;
int targetTemp = activeProfile.phases[i].temperature;
int tempDiff = abs(targetTemp - previousTemp);
int transitionDuration = tempDiff * 60 * activeProfile.transitionMinutesPerDegree;
if (totalElapsedTime < accumulatedTime + transitionDuration) {
isInTransition = true;
currentPhase = i - 1; // Keep currentPhase as the previous phase
int timeInTransition = totalElapsedTime - accumulatedTime;
Setpoint = previousTemp + (double)timeInTransition / (60 * activeProfile.transitionMinutesPerDegree) * (targetTemp > previousTemp ? 1 : -1);
phaseStartTime = totalStartTime + accumulatedTime * 1000; // Set phase start time
return;
}
accumulatedTime += transitionDuration;
}
// Check if we're within the current phase
if (totalElapsedTime < accumulatedTime + phaseDuration) {
isInTransition = false;
currentPhase = i;
Setpoint = activeProfile.phases[i].temperature;
phaseStartTime = totalStartTime + accumulatedTime * 1000; // Set phase start time
return;
}
accumulatedTime += phaseDuration;
}
// If the elapsed time exceeds the total duration, indicate completion
currentPhase = activeProfile.numPhases; // Indicate completion
Setpoint = 45; // Default to 45°C after completion
isInTransition = false;
isComplete = true; // Mark the process as complete
phaseStartTime = totalStartTime + accumulatedTime * 1000; // Set phase start time to the end
}
void calculateTotalTime() {
// Calculate total process time, including transitions
activeProfile = profiles[activeProfileIndex];
totalProcessTime = 0;
for (int i = 0; i < activeProfile.numPhases; i++) {
totalProcessTime += activeProfile.phases[i].duration * 60;
if (i < activeProfile.numPhases - 1) {
int tempDiff = abs(activeProfile.phases[i + 1].temperature - activeProfile.phases[i].temperature);
totalProcessTime += tempDiff * 60 * activeProfile.transitionMinutesPerDegree;
}
}
}
void startExecution() {
activeProfile = profiles[activeProfileIndex];
inSelectionMode = false; // Switch to execution mode
phaseStartTime = totalStartTime = millis(); // Start the timer
totalElapsedTime = 0;
regulator.setpoint = 0;
// digitalWrite(ssrPin, HIGH); // Start with heater on
ssrLastSwitchTime = millis();
calculateTotalTime();
getPhaseAndTemperature();
writeEEPROM();
oled.clear();
boolLastCompletedState = isComplete = false;
}

View File

@ -1,20 +0,0 @@
LP_TIMER(1000, HandleTemperatureSensor);
void HandleTemperatureSensor() {
#ifdef TempSensorDallas
Input = (double) sensors.getTempCByIndex(0);
sensors.requestTemperatures(); // Send the command to get temperatures
#endif
#ifdef TempSensorMax // to go into the read temp function, rename from dallas temp
Input = thermocouple.readCelsius();
#endif
if (isnan(Input) || Input < 20 || Input > 95) {
failedReadingLastValue = (float) Input;
failedReadingCount++;
temperatureSensorError = true;
}
else {
temperatureSensorError = false;
}
}