From 1b7a90574987a7bd4c95648a406061fe523d351c Mon Sep 17 00:00:00 2001 From: Aleksander Belov Date: Tue, 3 Sep 2024 17:20:16 +0700 Subject: [PATCH] SSR correct handling and some action --- hot_fermentation.ino | 123 +++++++++++++++++++++++++++++-------------- 1 file changed, 84 insertions(+), 39 deletions(-) diff --git a/hot_fermentation.ino b/hot_fermentation.ino index 27d1f60..3cea619 100644 --- a/hot_fermentation.ino +++ b/hot_fermentation.ino @@ -10,7 +10,6 @@ #include #endif - // MAX6675 configuration int max_SO = 12; int max_CS = 10; @@ -50,7 +49,7 @@ Profile profiles[] = { {"Lentils gradual", 10, {{48, 120}, {80, 60}}, 2}, {"Wheat", 3, {{47, 60}, {53, 60}, {65, 20}, {72, 20}, {85, 20}}, 5}, {"Sous Vide 55+120", 1, {{55, 30}, {85, 120}}, 2}, - {"Sous Vide 46", 1, {{46, 60}}, 1}, + {"Sous Vide 46", 0, {{46, 60}}, 1}, {"Test", 1, {{49, 1}, {51, 1}}, 2}, }; @@ -66,7 +65,7 @@ bool inSelectionMode = true; // PID Control variables double Setpoint, Input, Output; -double Kp = 1, Ki = 1, Kd = 0.05; +double Kp = 0.5, Ki = 1, Kd = 0.05; PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT); // Timing variables @@ -78,12 +77,21 @@ long totalProcessTime; long finishTime = 0; long currentTime = 0; long lastEEPROMWriteTime = 0; +bool isClick = false; +bool isLeft = false; +bool isRight = false; bool isComplete = false; const int ssrSwitchInterval = 1000; // SSR switching interval in milliseconds // Buffer for formatted time strings char timeBuffer[10]; +uint32_t timer = 0; +#define T_PERIOD 1000 // period of Execution processing +uint32_t timerSSR = 0; +#define T_PERIOD_SSR 500 // period of heater handling + + void setup() { pinMode(ssrPin, OUTPUT); Serial.begin(9600); @@ -98,17 +106,81 @@ void setup() { void loop() { enc1.tick(); + isLeft = enc1.isLeft(); + isRight = enc1.isRight(); + isClick = enc1.isClick(); + if (isLeft || isRight || isClick) { + handleEncoder(); + } + handleExecution(); + handleHeater(); +} +void handleHeater() { + long time = millis(); + static int currentPart = 0; + #define PARTS 4 + + 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 handleEncoder() { if (inSelectionMode) { handleProfileSelection(); } else { - handleExecution(); + handleExecutionSelection(); } } +void handleExecutionSelection() { + if (isClick) { + Serial.println("clicked! resetting..."); + activeProfileIndex = 100; + activeProfile = profiles[activeProfileIndex]; + inSelectionMode = true; + writeEEPROM(); + oled.clear(); + displaySelection(); + return; + } + +} + void handleExecution() { currentTime = millis(); + + if (inSelectionMode || (currentTime - timer < T_PERIOD)) { // таймер на millis() + return; + } + timer = currentTime; + totalElapsedTime = (currentTime - totalStartTime) / 1000; // Total elapsed time in seconds if ((currentTime - lastEEPROMWriteTime) >= (long)10*60*1000) { @@ -123,57 +195,30 @@ void handleExecution() { } myPID.Compute(); - // Serial.print(Input); - // Serial.print(" "); - // Serial.print(Output); - // Serial.print(" "); - // Serial.println(Setpoint); - // Switch SSR based on PID output and interval control - if (currentTime - ssrLastSwitchTime > ssrSwitchInterval) { - digitalWrite(ssrPin, Output > 0.5 ? HIGH : LOW); - ssrLastSwitchTime = currentTime; - } - if (isComplete && currentPhase >= activeProfile.numPhases && !finishTime) { finishTime = currentTime; } // Display all phases and highlight the current one printPhases(); - - if (enc1.isClick()) { - Serial.println("clicked! resetting..."); - activeProfileIndex = 100; - activeProfile = profiles[activeProfileIndex]; - inSelectionMode = true; - writeEEPROM(); - oled.clear(); - displaySelection(); - return; - } - - delay(1000); // Update every second } void handleProfileSelection() { - - bool click = enc1.isClick(); - bool turn = enc1.isTurn(); - if (!click && !turn) { + if (!isClick && !isLeft && !isRight) { return; } // Handle encoder input for selecting the profile - if (enc1.isRight()) { + if (isRight) { selectedProfileIndex = (selectedProfileIndex + 1) % (sizeof(profiles) / sizeof(profiles[0])); - } else if (enc1.isLeft()) { + } 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 (click) { + if (isClick) { activeProfileIndex = selectedProfileIndex; activeProfile = profiles[activeProfileIndex]; inSelectionMode = false; // Switch to execution mode @@ -337,10 +382,10 @@ void printPhases() { 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(); + // oled.setCursor(110,7); + // sprintf(timeBuffer, "%3d", (int)(Output*100)); + // oled.print(timeBuffer); + // oled.update(); } void formatTime(long seconds, char* buffer) {