looks ready to use

This commit is contained in:
Alexander Belov 2024-09-01 11:18:03 +07:00
parent c626cc904a
commit 955ed4f727
2 changed files with 76 additions and 17 deletions

View File

@ -1,4 +1,5 @@
## TODO ## TODO
* eeprom saving every 5 minutes and resuming * output temp control is not ideal (on/off does not represent values between 0 and 100)
* experiment with p,i,d

View File

@ -1,9 +1,15 @@
#define useEEPROM 1
#include <max6675.h> #include <max6675.h>
#include <Wire.h> #include <Wire.h>
#include <PID_v1.h> #include <PID_v1.h>
#include <GyverOLED.h> #include <GyverOLED.h>
#include "GyverEncoder.h" // Include the GyverEncoder library #include "GyverEncoder.h"
#if useEEPROM
#include <EEPROM.h> #include <EEPROM.h>
#endif
// MAX6675 configuration // MAX6675 configuration
int max_SO = 12; int max_SO = 12;
@ -22,7 +28,7 @@ GyverOLED<SSD1306_128x64, OLED_NO_BUFFER> oled;
Encoder enc1(CLK, DT, SW, TYPE2); Encoder enc1(CLK, DT, SW, TYPE2);
// SSR pin configuration // SSR pin configuration
const int ssrPin = 7; const int ssrPin = 2;
// Profile structure definition // Profile structure definition
struct Phase { struct Phase {
@ -39,10 +45,11 @@ struct Profile {
// Profiles definition // Profiles definition
Profile profiles[] = { Profile profiles[] = {
{"Test", 0, {{49, 1}, {51, 1}}, 2}, {"Chickpeas", 3, {{47, 120}, {53, 120}, {65, 180}, {72, 90}, {90, 90}}, 5},
{"Пшеница", 1, {{47, 40}, {55, 40}, {65, 20}, {72, 20}, {85, 20}}, 5}, {"Lentils", 3, {{47, 120}, {53, 120}, {65, 180}, {72, 90}, {90, 15}}, 5},
{"Veggies Sous Vide", 0, {{85, 120}}, 1}, {"Wheat", 3, {{47, 60}, {53, 60}, {65, 20}, {72, 20}, {85, 20}}, 5},
{"Фитаза/Протеаза", 2, {{47, 120}, {53, 120}, {65, 150}, {72, 60}, {90, 105}, {50, 60}}, 6}, {"Veggies Sous Vide", 2, {{55, 30}, {85, 120}}, 2},
{"Test", 1, {{49, 1}, {51, 1}}, 2},
}; };
// Global variables for profile selection and execution // Global variables for profile selection and execution
@ -57,7 +64,7 @@ bool inSelectionMode = true;
// PID Control variables // PID Control variables
double Setpoint, Input, Output; double Setpoint, Input, Output;
double Kp = 2, Ki = 0.5, Kd = 0.25; double Kp = 1, Ki = 2, Kd = 0.25;
PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT); PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);
// Timing variables // Timing variables
@ -80,7 +87,9 @@ void setup() {
Serial.begin(9600); Serial.begin(9600);
oled.init(); // Initialize the OLED oled.init(); // Initialize the OLED
oled.clear(); // Clear the display oled.clear(); // Clear the display
displaySelection(); readEEPROM();
myPID.SetMode(AUTOMATIC);
myPID.SetOutputLimits(0, 1);
} }
void loop() { void loop() {
@ -88,7 +97,8 @@ void loop() {
if (inSelectionMode) { if (inSelectionMode) {
handleProfileSelection(); handleProfileSelection();
} else { }
else {
handleExecution(); handleExecution();
} }
} }
@ -97,7 +107,7 @@ void handleExecution() {
currentTime = millis(); currentTime = millis();
totalElapsedTime = (currentTime - totalStartTime) / 1000; // Total elapsed time in seconds totalElapsedTime = (currentTime - totalStartTime) / 1000; // Total elapsed time in seconds
if ((currentTime - lastEEPROMWriteTime) >= (unsigned int) 10*60*1000) { if ((currentTime - lastEEPROMWriteTime) >= (long)10*60*1000) {
writeEEPROM(); writeEEPROM();
} }
@ -109,6 +119,11 @@ void handleExecution() {
} }
myPID.Compute(); myPID.Compute();
// Serial.print(Input);
// Serial.print(" ");
// Serial.print(Output);
// Serial.print(" ");
// Serial.println(Setpoint);
// Switch SSR based on PID output and interval control // Switch SSR based on PID output and interval control
if (currentTime - ssrLastSwitchTime > ssrSwitchInterval) { if (currentTime - ssrLastSwitchTime > ssrSwitchInterval) {
digitalWrite(ssrPin, Output > 0.5 ? HIGH : LOW); digitalWrite(ssrPin, Output > 0.5 ? HIGH : LOW);
@ -122,7 +137,16 @@ void handleExecution() {
// Display all phases and highlight the current one // Display all phases and highlight the current one
printPhases(); printPhases();
oled.update(); if (enc1.isClick()) {
Serial.println("clicked! resetting...");
activeProfileIndex = 100;
activeProfile = profiles[activeProfileIndex];
inSelectionMode = true;
writeEEPROM();
oled.clear();
displaySelection();
return;
}
delay(1000); // Update every second delay(1000); // Update every second
} }
@ -148,7 +172,6 @@ void handleProfileSelection() {
if (click) { if (click) {
activeProfileIndex = selectedProfileIndex; activeProfileIndex = selectedProfileIndex;
activeProfile = profiles[activeProfileIndex]; activeProfile = profiles[activeProfileIndex];
calculateTotalTime();
inSelectionMode = false; // Switch to execution mode inSelectionMode = false; // Switch to execution mode
phaseStartTime = totalStartTime = millis(); // Start the timer phaseStartTime = totalStartTime = millis(); // Start the timer
totalElapsedTime = 0; totalElapsedTime = 0;
@ -156,7 +179,10 @@ void handleProfileSelection() {
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
ssrLastSwitchTime = millis(); ssrLastSwitchTime = millis();
calculateTotalTime();
getPhaseAndTemperature();
writeEEPROM(); writeEEPROM();
oled.clear();
} }
} }
@ -178,6 +204,7 @@ void displaySelection() {
void calculateTotalTime() { void calculateTotalTime() {
// Calculate total process time, including transitions // Calculate total process time, including transitions
activeProfile = profiles[activeProfileIndex];
totalProcessTime = 0; totalProcessTime = 0;
for (int i = 0; i < activeProfile.numPhases; i++) { for (int i = 0; i < activeProfile.numPhases; i++) {
totalProcessTime += activeProfile.phases[i].duration * 60; totalProcessTime += activeProfile.phases[i].duration * 60;
@ -271,7 +298,7 @@ void printPhases() {
for (int i = 0; i < activeProfile.numPhases; i++) { for (int i = 0; i < activeProfile.numPhases; i++) {
if (i == currentPhase && !isComplete) { if (i == currentPhase) {
oled.invertText(true); // Invert text for the current phase oled.invertText(true); // Invert text for the current phase
oled.setCursor(0, i + 2); // Set cursor to the row corresponding to the phase oled.setCursor(0, i + 2); // Set cursor to the row corresponding to the phase
@ -282,12 +309,14 @@ void printPhases() {
oled.print(Input, 1); oled.print(Input, 1);
oled.print("c "); oled.print("c ");
if (fabs(Setpoint - round(Setpoint)) < 0.05) { if (fabs(Setpoint - round(Setpoint)) < 0.05) {
oled.print((int)Setpoint); // Print without decimals oled.print(Setpoint, 0); // Print without decimals
} else { } else {
oled.print(Setpoint, 1); // Print with 1 decimal place oled.print(Setpoint, 1); // Print with 1 decimal place
} }
oled.print("c "); oled.print("c ");
oled.print(timeBuffer); if (!isInTransition) {
oled.print(timeBuffer);
}
oled.print(" "); oled.print(" ");
} else { } else {
oled.invertText(false); // Normal text for other phases oled.invertText(false); // Normal text for other phases
@ -304,6 +333,11 @@ void printPhases() {
} }
oled.invertText(false); // Ensure text inversion is off after the loop oled.invertText(false); // Ensure text inversion is off after the loop
oled.setCursor(110,7);
oled.print(Output*100,0);
oled.print(" ");
oled.update();
} }
void formatTime(long seconds, char* buffer) { void formatTime(long seconds, char* buffer) {
@ -325,6 +359,7 @@ void formatTime(long seconds, char* buffer) {
} }
void writeEEPROM() { void writeEEPROM() {
#if useEEPROM
lastEEPROMWriteTime = millis(); lastEEPROMWriteTime = millis();
EEPROM.put(0, activeProfileIndex); // Store the active profile index EEPROM.put(0, activeProfileIndex); // Store the active profile index
EEPROM.put(4, totalElapsedTime); // Store the total elapsed time EEPROM.put(4, totalElapsedTime); // Store the total elapsed time
@ -332,4 +367,27 @@ void writeEEPROM() {
Serial.print(activeProfileIndex); Serial.print(activeProfileIndex);
Serial.print(" "); Serial.print(" ");
Serial.println(totalElapsedTime); 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
} }