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
* 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 <Wire.h>
#include <PID_v1.h>
#include <GyverOLED.h>
#include "GyverEncoder.h" // Include the GyverEncoder library
#include "GyverEncoder.h"
#if useEEPROM
#include <EEPROM.h>
#endif
// MAX6675 configuration
int max_SO = 12;
@ -22,7 +28,7 @@ GyverOLED<SSD1306_128x64, OLED_NO_BUFFER> oled;
Encoder enc1(CLK, DT, SW, TYPE2);
// SSR pin configuration
const int ssrPin = 7;
const int ssrPin = 2;
// Profile structure definition
struct Phase {
@ -39,10 +45,11 @@ struct Profile {
// Profiles definition
Profile profiles[] = {
{"Test", 0, {{49, 1}, {51, 1}}, 2},
{"Пшеница", 1, {{47, 40}, {55, 40}, {65, 20}, {72, 20}, {85, 20}}, 5},
{"Veggies Sous Vide", 0, {{85, 120}}, 1},
{"Фитаза/Протеаза", 2, {{47, 120}, {53, 120}, {65, 150}, {72, 60}, {90, 105}, {50, 60}}, 6},
{"Chickpeas", 3, {{47, 120}, {53, 120}, {65, 180}, {72, 90}, {90, 90}}, 5},
{"Lentils", 3, {{47, 120}, {53, 120}, {65, 180}, {72, 90}, {90, 15}}, 5},
{"Wheat", 3, {{47, 60}, {53, 60}, {65, 20}, {72, 20}, {85, 20}}, 5},
{"Veggies Sous Vide", 2, {{55, 30}, {85, 120}}, 2},
{"Test", 1, {{49, 1}, {51, 1}}, 2},
};
// Global variables for profile selection and execution
@ -57,7 +64,7 @@ bool inSelectionMode = true;
// PID Control variables
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);
// Timing variables
@ -80,7 +87,9 @@ void setup() {
Serial.begin(9600);
oled.init(); // Initialize the OLED
oled.clear(); // Clear the display
displaySelection();
readEEPROM();
myPID.SetMode(AUTOMATIC);
myPID.SetOutputLimits(0, 1);
}
void loop() {
@ -88,7 +97,8 @@ void loop() {
if (inSelectionMode) {
handleProfileSelection();
} else {
}
else {
handleExecution();
}
}
@ -97,7 +107,7 @@ void handleExecution() {
currentTime = millis();
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();
}
@ -109,6 +119,11 @@ 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);
@ -122,7 +137,16 @@ void handleExecution() {
// Display all phases and highlight the current one
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
}
@ -148,7 +172,6 @@ void handleProfileSelection() {
if (click) {
activeProfileIndex = selectedProfileIndex;
activeProfile = profiles[activeProfileIndex];
calculateTotalTime();
inSelectionMode = false; // Switch to execution mode
phaseStartTime = totalStartTime = millis(); // Start the timer
totalElapsedTime = 0;
@ -156,7 +179,10 @@ void handleProfileSelection() {
myPID.SetOutputLimits(0, 1); // SSR is either ON or OFF
// digitalWrite(ssrPin, HIGH); // Start with heater on
ssrLastSwitchTime = millis();
calculateTotalTime();
getPhaseAndTemperature();
writeEEPROM();
oled.clear();
}
}
@ -178,6 +204,7 @@ void displaySelection() {
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;
@ -271,7 +298,7 @@ void printPhases() {
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.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("c ");
if (fabs(Setpoint - round(Setpoint)) < 0.05) {
oled.print((int)Setpoint); // Print without decimals
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
@ -304,6 +333,11 @@ void printPhases() {
}
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) {
@ -325,6 +359,7 @@ void formatTime(long seconds, char* buffer) {
}
void writeEEPROM() {
#if useEEPROM
lastEEPROMWriteTime = millis();
EEPROM.put(0, activeProfileIndex); // Store the active profile index
EEPROM.put(4, totalElapsedTime); // Store the total elapsed time
@ -332,4 +367,27 @@ void writeEEPROM() {
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
}