looks ready to use
This commit is contained in:
parent
c626cc904a
commit
955ed4f727
@ -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
|
||||
|
||||
@ -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(Setpoint, 1); // Print with 1 decimal place
|
||||
}
|
||||
oled.print("c ");
|
||||
oled.print(timeBuffer);
|
||||
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
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user