Compare commits

..

2 Commits

Author SHA1 Message Date
8f9584a818 GyverPID 2024-09-06 11:27:26 +07:00
673fbc03d8 dallas/max switch 2024-09-06 02:15:52 +07:00

View File

@ -1,8 +1,8 @@
#define useEEPROM 1 #define useEEPROM 1
// #define TempSensorMax
#define TempSensorDallas
#include <max6675.h>
#include <Wire.h> #include <Wire.h>
#include <PID_v1.h>
#include <GyverOLED.h> #include <GyverOLED.h>
#include "GyverEncoder.h" #include "GyverEncoder.h"
@ -10,11 +10,26 @@
#include <EEPROM.h> #include <EEPROM.h>
#endif #endif
#ifdef TempSensorMax
#include <max6675.h>
// MAX6675 configuration // MAX6675 configuration
int max_SO = 12; int max_SO = 12;
int max_CS = 10; int max_CS = 10;
int max_SCK = 13; int max_SCK = 13;
MAX6675 thermocouple(max_SCK, max_CS, max_SO); MAX6675 thermocouple(max_SCK, max_CS, max_SO);
#endif
#ifdef TempSensorDallas
#include <OneWire.h>
#include <DallasTemperature.h>
// Data wire is plugged into port 2 on the Arduino
#define ONE_WIRE_BUS 9
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
#endif
// OLED configuration // OLED configuration
// GyverOLED<SSD1306_128x64> oled; // GyverOLED<SSD1306_128x64> oled;
@ -44,12 +59,12 @@ struct Profile {
// Profiles definition // Profiles definition
Profile profiles[] = { Profile profiles[] = {
{"Chickpeas", 3, {{47, 120}, {53, 120}, {65, 180}, {72, 90}, {90, 90}}, 5}, {"Chickpeas", 2, {{30, 1}, {47, 120}, {55, 60}, {65, 150}, {70, 60}, {90, 105}}, 6},
{"Lentils", 3, {{47, 120}, {53, 120}, {65, 180}, {72, 90}, {90, 15}}, 5}, {"Lentils", 3, {{47, 120}, {53, 120}, {65, 180}, {72, 90}, {90, 15}}, 5},
{"Lentils gradual", 10, {{48, 120}, {80, 60}}, 2}, {"Lentils gradual", 10, {{48, 120}, {80, 60}}, 2},
{"Wheat", 3, {{47, 60}, {53, 60}, {65, 20}, {72, 20}, {85, 20}}, 5}, {"Wheat", 1, {{47, 60}, {53, 60}, {65, 20}, {72, 20}, {85, 20}}, 5},
{"Sous Vide 55+120", 1, {{55, 30}, {85, 120}}, 2}, {"55-30&85-120", 1, {{55, 30}, {85, 120}}, 2},
{"46 (45)", 0, {{46, 45}}, 1}, {"46-45", 0, {{46, 45}}, 1},
{"Test", 1, {{49, 1}, {51, 1}}, 2}, {"Test", 1, {{49, 1}, {51, 1}}, 2},
}; };
@ -64,9 +79,12 @@ bool isInTransition = false;
bool inSelectionMode = true; bool inSelectionMode = true;
// PID Control variables // PID Control variables
// double Kp = 0.5, Ki = 1, Kd = 0.05;
// PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);
#include "GyverPID.h"
double Setpoint, Input, Output; double Setpoint, Input, Output;
double Kp = 0.5, Ki = 1, Kd = 0.05; GyverPID regulator(1, 0.5, 0, 1000);
PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);
// Timing variables // Timing variables
long phaseStartTime; long phaseStartTime;
@ -90,8 +108,10 @@ uint32_t timer = 0;
#define T_PERIOD 1000 // period of Execution processing #define T_PERIOD 1000 // period of Execution processing
uint32_t timerSSR = 0; uint32_t timerSSR = 0;
#define T_PERIOD_SSR 500 // period of heater handling #define T_PERIOD_SSR 500 // period of heater handling
uint32_t timerDallas = 0;
#define T_PERIOD_DALLAS 1000 // period of dallas sensor requesting
#define PARTS 10 #define PARTS 4
void setup() { void setup() {
pinMode(ssrPin, OUTPUT); pinMode(ssrPin, OUTPUT);
@ -100,9 +120,19 @@ void setup() {
oled.init(); // Initialize the OLED oled.init(); // Initialize the OLED
oled.clear(); // Clear the display oled.clear(); // Clear the display
readEEPROM(); readEEPROM();
myPID.SetMode(AUTOMATIC); regulator.setDirection(NORMAL); // направление регулирования (NORMAL/REVERSE). ПО УМОЛЧАНИЮ СТОИТ NORMAL
myPID.SetOutputLimits(0, 1); regulator.setLimits(0, 100); // пределы (ставим для 8 битного ШИМ). ПО УМОЛЧАНИЮ СТОЯТ 0 И 255
regulator.setpoint = 0;
#ifdef TempSensorDallas
sensors.begin();
DeviceAddress tempDeviceAddress;
sensors.getAddress(tempDeviceAddress, 0);
sensors.setResolution(tempDeviceAddress, 12);
sensors.setWaitForConversion(false);
#endif
// Serial.println("Input, Output, Real Output");
} }
void loop() { void loop() {
@ -115,8 +145,27 @@ void loop() {
} }
handleExecution(); handleExecution();
handleHeaterAdv(); handleHeaterAdv();
#ifdef TempSensorDallas
handleDallasTemperatureSensor();
#endif
} }
#ifdef TempSensorDallas
void handleDallasTemperatureSensor() {
long time = millis();
static int currentPart = 0;
if (time - timerDallas < T_PERIOD_DALLAS) {
return;
}
timerDallas = time;
Input = (double) sensors.getTempCByIndex(0);
sensors.requestTemperatures(); // Send the command to get temperatures
}
#endif
void handleHeaterSimple() { void handleHeaterSimple() {
long time = millis(); long time = millis();
static int currentPart = 0; static int currentPart = 0;
@ -164,7 +213,7 @@ void handleHeaterAdv() {
} }
timerSSR = time; timerSSR = time;
int current = Output * PARTS; int current = Output/100 * PARTS;
int last = 0; int last = 0;
for (int i = 1; i < PARTS; i++) { for (int i = 1; i < PARTS; i++) {
@ -173,11 +222,12 @@ void handleHeaterAdv() {
states[i-1] = states[i]; states[i-1] = states[i];
} }
} }
bool next = current > last ? true : false; bool next = current >= last ? true : false;
if (Output < 0.05) next = false;
states[PARTS-1] = next; states[PARTS-1] = next;
oled.setCursor(128-6*PARTS, 7); oled.setCursor(128-6*PARTS, 7);
sprintf(timeBuffer, "%3d", (int)(Output*100)); sprintf(timeBuffer, "%3d", (int)(Output));
char symbol; char symbol;
for (int i = 0; i < PARTS; i++) { for (int i = 0; i < PARTS; i++) {
int index = i - (PARTS - 3); int index = i - (PARTS - 3);
@ -192,6 +242,14 @@ void handleHeaterAdv() {
if (currentPart >= PARTS) { if (currentPart >= PARTS) {
currentPart = 0; currentPart = 0;
} }
Serial.print(Setpoint);
Serial.print(",");
Serial.print(Input);
Serial.print(",");
Serial.print(Output);
Serial.println(",0,100");
} }
void handleEncoder() { void handleEncoder() {
@ -233,11 +291,17 @@ void handleExecution() {
getPhaseAndTemperature(); getPhaseAndTemperature();
#ifdef TempSensorMax
Input = thermocouple.readCelsius(); Input = thermocouple.readCelsius();
#endif
if (isnan(Input)) { if (isnan(Input)) {
Input = 0; Input = 0;
} }
myPID.Compute(); regulator.input = (float)Input;
regulator.setpoint = Setpoint;
regulator.getResult();
Output = regulator.output;
if (isComplete && currentPhase >= activeProfile.numPhases && !finishTime) { if (isComplete && currentPhase >= activeProfile.numPhases && !finishTime) {
finishTime = currentTime; finishTime = currentTime;
@ -252,8 +316,7 @@ void startExecution() {
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;
myPID.SetMode(AUTOMATIC); regulator.setpoint = 0;
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(); calculateTotalTime();