hot-fermentation/hot_fermentation.ino

149 lines
3.9 KiB
Arduino
Raw Normal View History

2024-10-06 22:21:02 +07:00
#include <Arduino.h>
#include <Looper.h>
2024-09-01 11:18:03 +07:00
#define useEEPROM 1
2024-09-06 02:15:52 +07:00
// #define TempSensorMax
#define TempSensorDallas
2024-09-07 23:11:57 +07:00
// #define PlotValues
2024-09-01 11:18:03 +07:00
2024-10-06 22:21:02 +07:00
// #include <Wire.h>
2024-08-31 01:38:49 +07:00
#include <GyverOLED.h>
2024-09-01 11:18:03 +07:00
#include "GyverEncoder.h"
#if useEEPROM
#include <EEPROM.h>
2024-09-01 11:18:03 +07:00
#endif
2024-09-06 02:15:52 +07:00
#ifdef TempSensorMax
#include <max6675.h>
// MAX6675 configuration
int max_SO = 12;
int max_CS = 10;
int max_SCK = 13;
MAX6675 thermocouple(max_SCK, max_CS, max_SO);
#endif
#ifdef TempSensorDallas
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 9
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
#endif
2024-08-29 12:37:31 +07:00
2024-08-29 23:01:32 +07:00
// OLED configuration
// GyverOLED<SSD1306_128x64> oled;
GyverOLED<SSD1306_128x64, OLED_NO_BUFFER> oled;
2024-08-29 12:37:31 +07:00
2024-08-31 01:38:49 +07:00
// Encoder configuration
#define CLK 5
#define DT 6
#define SW 7
Encoder enc1(CLK, DT, SW, TYPE2);
2024-12-19 23:20:33 +07:00
const int triacPwm = 10;
2024-09-07 23:11:57 +07:00
const int activeBuzzerPin = 8;
2024-08-29 12:37:31 +07:00
2024-08-29 23:58:25 +07:00
// Profile structure definition
struct Phase {
int temperature;
int duration; // in minutes
};
struct Profile {
const char* name;
2024-08-30 02:45:48 +07:00
int transitionMinutesPerDegree;
2024-08-30 00:07:12 +07:00
Phase phases[6]; // Maximum of 6 phases per profile
2024-08-29 23:58:25 +07:00
int numPhases;
};
// Profiles definition
Profile profiles[] = {
{"Chickpeas", 1, {{46, 120}, {55, 60}, {65, 150}, {70, 60}, {90, 105}}, 5},
2024-12-19 23:20:33 +07:00
{"Chickpeas long", 1, {{46, 120}, {55, 120}, {65, 120}, {72, 240}, {85, 300}}, 5},
{"Lentils", 3, {{46, 120}, {53, 120}, {65, 180}, {72, 90}, {90, 15}}, 5},
2024-10-06 22:21:02 +07:00
{"Gradual", 10, {{46, 120}, {90, 30}}, 2},
{"Long gradual", 15, {{46, 120}, {80, 60}, {90, 15}}, 3},
2024-10-06 21:36:43 +07:00
{"Wheat", 1, {{46, 120}, {53, 40}, {65, 40}, {72, 40}, {85, 40}}, 5},
2024-12-28 14:32:49 +07:00
// {"Amazake", 1, {{51, 480}}, 1},
{"37, 3 days", 1, {{37, 1440}, {37, 1440}, {37, 1440}}, 3},
// {"SV", 0, {{46, 45}}, 1},
2024-10-01 23:02:50 +07:00
// {"Yoghurt maker", 0, {{40, 300}, {40, 300}, {30, 300}}, 3},
2024-10-06 22:21:02 +07:00
// {"TEST", 0, {{46, 1}}, 1},
2024-08-29 23:58:25 +07:00
};
2024-08-31 01:38:49 +07:00
// Global variables for profile selection and execution
int activeProfileIndex = 100; // 100 indicates no profile selected yet
int selectedProfileIndex = 0; // Index of the currently selected profile in the selection mode
Profile activeProfile; // The active profile once selected
2024-08-29 12:37:31 +07:00
2024-08-30 02:45:48 +07:00
// Global variables for current phase, setpoint, and transition state
int currentPhase;
bool isInTransition = false;
2024-08-31 01:38:49 +07:00
bool inSelectionMode = true;
2024-08-30 02:45:48 +07:00
2024-08-29 12:37:31 +07:00
// PID Control variables
2024-09-06 11:27:26 +07:00
// double Kp = 0.5, Ki = 1, Kd = 0.05;
// PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);
2024-12-28 14:32:49 +07:00
// #include "GyverPID.h"
#include "pid.h"
2024-08-29 12:37:31 +07:00
double Setpoint, Input, Output;
2025-01-05 01:51:56 +07:00
GyverPID regulator(10, 2, 10, 1000);
bool temperatureSensorError = false;
2024-08-29 12:37:31 +07:00
// Timing variables
2024-08-31 12:47:54 +07:00
long phaseStartTime;
long totalStartTime;
long ssrLastSwitchTime;
long totalElapsedTime;
long totalProcessTime;
long finishTime = 0;
long currentTime = 0;
long lastEEPROMWriteTime = 0;
2024-09-03 17:20:16 +07:00
bool isClick = false;
bool isLeft = false;
bool isRight = false;
bool isComplete = false;
2024-08-29 12:37:31 +07:00
const int ssrSwitchInterval = 1000; // SSR switching interval in milliseconds
2024-08-29 23:58:25 +07:00
// Buffer for formatted time strings
char timeBuffer[10];
2024-09-07 23:11:57 +07:00
bool boolLastCompletedState = false;
2024-09-03 17:20:16 +07:00
float failedReadingLastValue = 0;
int failedReadingCount = 0;
#define PARTS 8
2024-09-03 17:20:16 +07:00
2024-08-29 12:37:31 +07:00
void setup() {
2024-09-07 23:11:57 +07:00
pinMode(activeBuzzerPin, OUTPUT);
2024-08-29 12:37:31 +07:00
Serial.begin(9600);
2024-09-02 00:39:39 +07:00
2024-08-29 23:01:32 +07:00
oled.init(); // Initialize the OLED
oled.clear(); // Clear the display
2024-09-01 11:18:03 +07:00
readEEPROM();
2024-09-06 11:27:26 +07:00
regulator.setDirection(NORMAL); // направление регулирования (NORMAL/REVERSE). ПО УМОЛЧАНИЮ СТОИТ NORMAL
regulator.setLimits(0, 100); // пределы (ставим для 8 битного ШИМ). ПО УМОЛЧАНИЮ СТОЯТ 0 И 255
regulator.setpoint = 0;
2024-09-06 02:15:52 +07:00
2024-12-19 23:20:33 +07:00
pinMode(triacPwm, OUTPUT);
configureTimer1(1000);
setPWMDutyCycle(0);
2024-09-06 02:15:52 +07:00
#ifdef TempSensorDallas
sensors.begin();
DeviceAddress tempDeviceAddress;
sensors.getAddress(tempDeviceAddress, 0);
sensors.setResolution(tempDeviceAddress, 12);
sensors.setWaitForConversion(false);
#endif
2024-08-29 12:37:31 +07:00
}
void loop() {
2024-10-06 22:21:02 +07:00
Looper.loop();
2024-09-03 17:20:16 +07:00
}