looks ready to use
This commit is contained in:
parent
c626cc904a
commit
955ed4f727
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user