hot-fermentation/hot_fermentation.ino
2025-01-14 12:43:13 +07:00

141 lines
3.7 KiB
C++

#include <Arduino.h>
#include <Looper.h>
#define useEEPROM 1
// #define TempSensorMax
#define TempSensorDallas
// #define PlotValues
// #include <Wire.h>
#include <GyverOLED.h>
#include "GyverEncoder.h"
#if useEEPROM
#include <EEPROM.h>
#endif
#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
// OLED configuration
// GyverOLED<SSD1306_128x64> oled;
GyverOLED<SSD1306_128x64, OLED_NO_BUFFER> oled;
// Encoder configuration
#define CLK 5
#define DT 6
#define SW 7
Encoder enc1(CLK, DT, SW, TYPE2);
const int triacPwm = 10;
const int activeBuzzerPin = 8;
// Profile structure definition
struct Phase {
int temperature;
int duration; // in minutes
};
struct Profile {
const char* name;
int transitionMinutesPerDegree;
Phase phases[6]; // Maximum of 6 phases per profile
int numPhases;
};
// Profiles definition
Profile profiles[] = {
{"Chickpeas", 1, {{46, 120}, {55, 60}, {65, 150}, {70, 60}, {90, 105}}, 5},
{"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},
{"Gradual", 10, {{46, 120}, {90, 30}}, 2},
{"Long gradual", 15, {{46, 120}, {80, 60}, {90, 15}}, 3},
{"Wheat", 1, {{46, 120}, {53, 40}, {65, 40}, {72, 40}, {85, 40}}, 5},
// {"Amazake", 1, {{51, 480}}, 1},
{"37, 3 days", 1, {{37, 1440}, {37, 1440}, {37, 1440}}, 3},
// {"SV", 0, {{46, 45}}, 1},
// {"Yoghurt maker", 0, {{40, 300}, {40, 300}, {30, 300}}, 3},
// {"TEST", 0, {{46, 1}}, 1},
};
// 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
// Global variables for current phase, setpoint, and transition state
int currentPhase;
bool isInTransition = false;
bool inSelectionMode = true;
// #include "GyverPID.h"
#include "pid.h"
double Setpoint, Input, Output;
GyverPID regulator(50, 1, 0, 1000);
bool temperatureSensorError = false;
// Timing variables
long phaseStartTime;
long totalStartTime;
long totalElapsedTime;
long totalProcessTime;
long finishTime = 0;
long currentTime = 0;
long lastEEPROMWriteTime = 0;
bool isClick = false;
bool isLeft = false;
bool isRight = false;
bool isComplete = false;
// Buffer for formatted time strings
char timeBuffer[10];
bool boolLastCompletedState = false;
float failedReadingLastValue = 0;
int failedReadingCount = 0;
void setup() {
pinMode(activeBuzzerPin, OUTPUT);
Serial.begin(9600);
oled.init(); // Initialize the OLED
oled.clear(); // Clear the display
readEEPROM();
regulator.setDirection(NORMAL); // направление регулирования (NORMAL/REVERSE). ПО УМОЛЧАНИЮ СТОИТ NORMAL
regulator.setLimits(0, 100); // пределы (ставим для 8 битного ШИМ). ПО УМОЛЧАНИЮ СТОЯТ 0 И 255
regulator.setpoint = 0;
pinMode(triacPwm, OUTPUT);
configureTimer1(1000);
setPWMDutyCycle(0);
#ifdef TempSensorDallas
sensors.begin();
DeviceAddress tempDeviceAddress;
sensors.getAddress(tempDeviceAddress, 0);
sensors.setResolution(tempDeviceAddress, 12);
sensors.setWaitForConversion(false);
#endif
}
void loop() {
Looper.loop();
}