#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <EEPROM.h>
#include <OneWire.h> // Library for Temp sensor
#include <DallasTemperature.h> // Library for Temp conversion
#include <PID_v1.h>
#define ONE_WIRE_BUS A0
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
DeviceAddress tempDeviceAddress;
int idle = 0;
int resolution = 12;
LiquidCrystal_I2C lcd(0x27, 20, 4); // Endereço do LCD
static int pinA = 2; // pino A do encoder
static int pinB = 3; // pino B do encoder
const int selectSwitch = 4; // pino do botão do encoder
const int RELAY = 5; //Relay
const int Sensor = 12; //Relay
const int motorPin = 8; // Defina o pino do motor
const int pumpPin = 10; // Defina o pino da bomba
const int buzzerPin = 13;
#define PWM_PIN 9 // Pino PWM
const int pinoSensorAgua = 7; // Pino do sensor de nível de água
// Variáveis de controle
unsigned long lastTempRequest = 0;
unsigned long delayInMillis = 750;
// Etapas do processo
enum Stage { RAMP_UP, PROTEASE, BETA, ALFA, MASH_OUT, SPARGE };
unsigned long motorTimer = 0; // Timer para o motor
unsigned long bombaTimer = 0; // Timer para a bomba
unsigned long currentMillis = 0;
static unsigned long timer = 0; // Timer para controle
// Variáveis de controle
int execMenu = 0;
unsigned long tempo = 0;
unsigned long timeCountDown = 0;
int seg = 0; // Contador de segundos
int min = 0; // Contador de minutos
// Variáveis para debounce e controle de estado do botão
bool buttonPressed = false;
unsigned long lastDebounceTime = 0;
const unsigned long debounceDelay = 50; // Tempo de debounce
//Variáveis cronometro Crescente
unsigned long startTime = 0; // Variável para armazenar o tempo de início
unsigned long previousMillis = 0; // Armazena o último tempo em que o cronômetro foi atualizado
const long intervalo = 1000; // Intervalo de 1 segundo (1000 milissegundos)
unsigned long totalTime = 0; // Tempo total decorrido em segundos
int lastButtonState = HIGH; // Para debouncing
bool isStarted = false; // Estado inicial do sistema
bool isPaused = false; // Estado de pausa
bool isRunning = false;
// Variaveis cronometro decrescente
int currentTimeSeconds = 0; // Tempo restante em segundos
int currentTemp = 0;
int elapsedSeconds = 0;
// Protótipo da função genérica
void ajustarParametro(const char* nome, int& valor, int coluna, int linha, int limiteMin, int limiteMax);
// Variável de controle de pulsação para diferentes valores
bool pulsou[15] = {false}; // Para até 15 valores que precisam ser controlados
byte grau[8] = {0b00110, 0b01001,0b01001, 0b00110, 0b00000, 0b00000,0b00000, 0b00000
};
//lcd.write(byte(0));: Exibe o caractere na tela.
byte timeSymbol[8] = {B00100,B01010,B10001,B00010,B01010,B00100,B00000,B00000};
//lcd.write(byte(1));: Exibe o caractere na tela.
byte termometro[8] = {B00100,B00100,B00100,B00100,B01110,B11111,B01110,B00100};
//lcd.createChar(0, termometro);: Cria o caractere na posição 0 da memória do LCD.
//lcd.write(byte(2));: Exibe o caractere na tela.
byte powerSymbol[8] = {B00100,B01110,B11111,B11111,B11111,B01110,B00100,B00010};
//lcd.write(byte(3));: Exibe o caractere na tela.
//lcd.write(byte(4));: Exibe o caractere na tela.
byte bombaSymbol[8] = {0b00000,0b00100,0b01110,0b11111,0b01110,0b00100,0b00000,0b00000};
//lcd.write(byte(5));: Exibe o caractere na tela.
byte motorSymbol[8] = { 0b00111, 0b01001,0b01111,0b01001, 0b01001,0b00111, 0b00000,0b00000
};
int estadoEnter = 0;
volatile byte aFlag = 0;
volatile byte bFlag = 0;
// has arrived at a detent (opposite direction to when aFlag is set)
int encoderPos = 0;
volatile byte oldEncPos = 0;
volatile byte reading = 0;
// Menus principais e seus submenus
const char* mainMenu[] = {"Configur","Monitorar", "Cadastrar", "Executar"};
const int mainMenuSize = sizeof(mainMenu) / sizeof(mainMenu[0]);
const char* settingsMenu[] = {"PID", "Fuzzy", "Sensor", "Back"};
const int settingsMenuSize = sizeof(settingsMenu) / sizeof(settingsMenu[0]);
const char* pidSubMenu[] = {"Kp: ", "Ki: ", "Kd: ", "Back"};
const int pidSubMenuSize = sizeof(pidSubMenu) / sizeof(pidSubMenu[0]);
const char* fuzzySubMenu[] = {"Start: ", "Ampl: ", "Back"};
const int fuzzySubMenuSize = sizeof(fuzzySubMenu) / sizeof(fuzzySubMenu[0]);
const char* sensorSubMenu[] = {"Fator 1 ", "Fator 2 ", "Back"};
const int sensorSubMenuSize = sizeof(sensorSubMenu) / sizeof(sensorSubMenu[0]);
const char* monitorarMenu[] = {"Resistencia: ", "Recipe: ","Pump" ,"Back"};
const int monitorarMenuSize = sizeof(monitorarMenu) / sizeof(monitorarMenu[0]);
const char* powerSubMenu[] = {"Power Step: ", "Power Ramp: ", "Back"};
const int powerSubMenuSize = sizeof(powerSubMenu) / sizeof(powerSubMenu[0]);
const char* recipeSubMenu[] = {"Agua ", "Malte ", "Back"};
const int recipeSubMenuSize = sizeof(recipeSubMenu) / sizeof(recipeSubMenu[0]);
const char* pumpSubMenu[] = {"Operation ", "Pause ", "Back"};
const int pumpSubMenuSize = sizeof(pumpSubMenu) / sizeof(pumpSubMenu[0]);
const char* cadastroMenu[] = { "Cad Recipe", "Back"};
const int cadastroMenuSize = sizeof(cadastroMenu) / sizeof(cadastroMenu[0]);
const char* executeMenu[] = {"Start","Back"};
const int executeMenuSize = sizeof(executeMenu) / sizeof(executeMenu[0]);
const char* paramStages[] = { "Tempo", "Temperatura", "Back"};
const int paramStagesSize = sizeof(paramStages) / sizeof(paramStages[0]);
int currentMenu = 0; // Menu atual
int currentSubMenu = 0; // Índice do submenu atual, se necessário
int currentIndex = 0; // Índice do item atualmente selecionado
// Declaração global para controle de ajuste de tempo
bool ajusteCompletado = false; // Flag que indica se o ajuste foi completado
// variaveis EEPROM
const int Pid_Kp = 0;
const int Pid_Ki = 4;
const int Pid_Kd = 8;
const int Fuzzy_Start = 12;
const int Fuzzy_Ampl = 16;
const int Sensor_F1 = 20;
const int Sensor_F2 = 24;
const int Power_Step = 28;
const int Power_Ramp = 32;
const int Rec_Agua = 36;
const int Rec_Malte = 40;
const int Pump_Oper = 44;
const int Pump_Pause = 48;
const int mashTemp_Fit = 52;
const int mashTime_Fit = 56;
const int mashTemp_SP = 60;
const int mashTime_SP = 64;
const int mashTemp_BA = 68;
const int mashTime_BA = 72;
const int mashTemp_AA = 76;
const int mashTime_AA = 80;
const int mashTemp_MO = 84;
const int mashTime_MO = 88;
const int Temp_Sparge = 92;
const int Time_Sparge = 96;
int Kp = 100; // Valor inicial do potencial
int Ki = 50;
int Kd = 10;
float fuzzyStart = 0.0;
float fuzzyAmplitude = 0.0;
int powerStep = 0;
int powerRamp = 0;
float sensorF1 = 0.0;
float sensorF2 = 0.0;
unsigned int recAgua ;
unsigned int recMalte;
unsigned int pumpOper;
unsigned int pumpPause;
unsigned int mashFitTemp;
unsigned int mashFitTime;
unsigned int mashSPTemp;
unsigned int mashSPTime;
unsigned int mashBATemp;
unsigned int mashBATime;
unsigned int mashAATemp;
unsigned int mashAATime;
unsigned int mashOutTemp;
unsigned int mashOutTime;
unsigned int SpargeTemp;
unsigned int SpargeTime;
int menuValue = 0;
int seconds = 59;
int secondsCount;
unsigned long time_countdown = 0;
static bool mensagemPHExibida = false; // Variável para controlar se a mensagem do pH já foi exibida
static bool mensagemTIExibida = false;
static bool mensagemTMExibida = false;
static bool mensagemAAExibida = false;
bool isAACheckPaused = false;
bool isPHCheckPaused = false; // Novo sinalizador para pausa do teste de pH
bool isTICheckPaused = false; // Novo sinalizador para pausa do teste de iodo
bool isTMCheckPaused = false; // Novo sinalizador para pausa transf do mosto
// Variáveis globais
float Temperature, currentTemperature;
// Parâmetros Fuzzy
float integral = 0, previousError = 0, error;
// Potências para Step e Ramp
// Estruturas para etapas
struct Etapa {
const char* nome;
int tempSetpoint;
int tempoRestante; // Tempo em minutos
};
Etapa etapas[6]; // Array para armazenar as 6 etapas
Etapa etapa; // Defina sua estrutura aqui
int indiceEtapa = 0; // Defina o índice da etapa
int tempo_piscar = 1000; // Tempo em milissegundos para piscar
// Variáveis PID
double Setpoint, Input, Output;
PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);
void setup() {
lcd.begin(20,4);
lcd.backlight();
sensors.begin();
Serial.begin(9600);
sensors.getAddress(tempDeviceAddress, 0);
sensors.setResolution(tempDeviceAddress, resolution);
sensors.setWaitForConversion(false);
sensors.requestTemperatures();
delayInMillis = 750 / (1 << (12 - resolution));
lastTempRequest = millis();
pinMode(selectSwitch, INPUT_PULLUP);
pinMode(pinA, INPUT);
pinMode(pinB, INPUT);
pinMode(RELAY, OUTPUT);
pinMode(motorPin, OUTPUT);
pinMode(pumpPin, OUTPUT);
digitalWrite(motorPin, LOW);
digitalWrite(pumpPin, LOW);
attachInterrupt(0, PinA, RISING);
attachInterrupt(1, PinB, RISING);
myPID.SetMode(AUTOMATIC);
// Carregar o valor da configuração da EEPROM
inicializaEtapas();
// Inicializa as receitas com valores padrão
lcd.setCursor (4, 0);
lcd.print("Welcome....");
lcd.setCursor (6, 2);
lcd.print("BREWBEER!");
delay(2500);
lcd.clear();
loadConfigFromEEPROM();
// Cria os caracteres personalizados
lcd.createChar(0, grau);
lcd.createChar(1, termometro);
lcd.createChar(2, timeSymbol);
lcd.createChar(3, powerSymbol);
lcd.createChar(4, bombaSymbol);
lcd.createChar(5, motorSymbol);
displayMenu();
}
void PinA() {
cli();
reading = PIND & 0xC;
if (reading == B00001100 && aFlag) {
encoderPos ++;
bFlag = 0;
aFlag = 0;
}
else if (reading == B00000100) bFlag = 1;
sei();
}
void PinB() {
cli();
reading = PIND & 0xC;
if (reading == B00001100 && bFlag) {
encoderPos --;
//increment the encoder's position count
bFlag = 0;
aFlag = 0;
}
else if (reading == B00001000) aFlag = 1;
sei();
}
// Função para salvar configurações na EEPROM
void saveSettingsToEEPROM() {
EEPROM.put(0, Kp);
EEPROM.put(4, Ki);
EEPROM.put(8, Kd);
EEPROM.put(12, fuzzyStart);
EEPROM.put(16, fuzzyAmplitude);
EEPROM.put(20, powerRamp);
EEPROM.put(24, powerStep);
}
// Função para carregar as configurações da EEPROM
void loadConfigFromEEPROM() {
EEPROM.get(0, Kp);
EEPROM.get(4, Ki);
EEPROM.get(8, Kd);
EEPROM.get(12, fuzzyStart);
EEPROM.get(16, fuzzyAmplitude);
EEPROM.get(20, powerRamp);
EEPROM.get(24, powerStep);
}
void inicializaEtapas() {
// Carrega os valores da EEPROM nas etapas
EEPROM.get(mashTemp_Fit, mashFitTemp);
EEPROM.get(mashTime_Fit, mashFitTime);
EEPROM.get(mashTemp_SP, mashSPTemp);
EEPROM.get(mashTime_SP, mashSPTime);
EEPROM.get(mashTemp_BA, mashBATemp);
EEPROM.get(mashTime_BA, mashBATime);
EEPROM.get(mashTemp_AA, mashAATemp);
EEPROM.get(mashTime_AA, mashAATime);
EEPROM.get(mashTemp_MO, mashOutTemp);
EEPROM.get(mashTime_MO, mashOutTime);
EEPROM.get(Temp_Sparge, SpargeTemp);
EEPROM.get(Time_Sparge, SpargeTime);
// Adicione as demais etapas conforme necessário
}
void loop() {
checkButton();
navigateMenu(); // Verifica a navegação no menu
}
void checkButton() {
if (digitalRead(selectSwitch) == LOW && !buttonPressed) {
buttonPressed = true;
selectMenu();
delay(300); // Debounce
} else if (digitalRead(selectSwitch) == HIGH) {
buttonPressed = false; // Reseta o estado
}
}
void navigateMenu() {
static int lastStateA = HIGH;
int stateA = digitalRead(pinA);
int stateB = digitalRead(pinB);
if (lastStateA == HIGH && stateA == LOW) {
if (stateB == HIGH) { // Girando no sentido horário
currentIndex++;
if (currentIndex >= getCurrentMenuSize()) {
currentIndex = 0;
}
} else { // Girando no sentido anti-horário
currentIndex--;
if (currentIndex < 0) {
currentIndex = getCurrentMenuSize() - 1;
}
}
delay(100); // Delay para evitar movimentos rápidos
displayMenu();
}
lastStateA = stateA;
}
void selectMenu() {
if (currentMenu == 0) { // Menu principal
if (currentIndex == 0) {
currentMenu = 1; // Acessa Configurações
currentIndex = 0; // Reseta o índice
} else if (currentIndex == 1) {
currentMenu = 5; // Acessa Monitorar
currentIndex = 0; // Reseta o índice
} else if (currentIndex == 2) {
cadRecipe(); // Chama a função de Cadastro
currentMenu = 0; // Retorna ao menu principal após cadastro
currentIndex = 0; // Reseta o índice
} else if (currentIndex == 3) {
executeRecipe(indiceEtapa); // Chama a função de Execução
currentMenu = 0; // Retorna ao menu principal após execução
currentIndex = 0; // Reseta o índice
}
} else if (currentMenu == 1) { // Menu de Configurações
if (currentIndex == 0) {
currentMenu = 2; // Acessa submenu PID
currentIndex = 0; // Reseta o índice
} else if (currentIndex == 1) {
currentMenu = 3; // Acessa submenu Fuzzy
currentIndex = 0; // Reseta o índice
} else if (currentIndex == 2) {
currentMenu = 4; // Acessa submenu Sensor
currentIndex = 0; // Reseta o índice
} else {
currentMenu = 0; // Retorna ao menu principal
currentIndex = 0; // Reseta o índice
}
} else if (currentMenu == 2) { // Submenu PID
if (currentIndex == 0) {
adjustKp(); // Ajusta Kp
} else if (currentIndex == 1) {
adjustKi(); // Ajusta Ki
} else if (currentIndex == 2) {
adjustKd(); // Ajusta Kd
} else {
currentMenu = 1; // Retorna ao menu de Configurações
currentIndex = 0; // Reseta o índice
}
} else if (currentMenu == 3) { // Submenu Fuzzy
if (currentIndex == 0) {
adjustIni(); // Ajusta Início
} else if (currentIndex == 1) {
adjustAmpl(); // Ajusta Amplitude
} else {
currentMenu = 1; // Retorna ao menu de Configurações
currentIndex = 0; // Reseta o índice
}
} else if (currentMenu == 4) { // Submenu Sensor
// Lógica para submenu Sensor
if (currentIndex == 0) {
adjustSensorFator1(); // Chama a função para ajustar o Fator 1
} else if (currentIndex == 1) {
adjustSensorFator2(); // Chama a função para ajustar o Fator 2
} else {
currentMenu = 1; // Retorna ao menu de Configurações
currentIndex = 0; // Reseta o índice
}
} else if (currentMenu == 5) { // Submenu Monitorar
if (currentIndex == 0) {
currentMenu = 6; // Acessa submenu Power
currentIndex = 0; // Reseta o índice
} else if (currentIndex == 1) {
currentMenu = 7; // Acessa submenu Recipe
currentIndex = 0; // Reseta o índice
} else if (currentIndex == 2) {
currentMenu = 8; // Acessa submenu Bomba
currentIndex = 0; // Reseta o índice
} else {
currentMenu = 0; // Retorna ao menu principal
currentIndex = 0; // Reseta o índice
}
} else if (currentMenu == 6) { // Submenu Power
// Lógica para submenu Power
if (currentIndex == 0) {
adjustPowerStep(); // Ajusta Power Step
} else if (currentIndex == 1) {
adjustPowerRamp(); // Ajusta Power Ramp
} else {
currentMenu = 5; // Retorna ao submenu Monitorar
currentIndex = 0; // Reseta o índice
}
} else if (currentMenu == 7) { // Submenu Recipe
// Lógica para submenu Recipe
if (currentIndex == 0) {
adjustRecipeAgua(); // Ajusta a Ação do Recipe
} else if (currentIndex == 1) {
adjustRecipeMalte(); //Ajusta a Pause do Recipe
} else {
currentMenu = 5; // Retorna ao submenu Monitorar
currentIndex = 0; // Reseta o índice
}
} else if (currentMenu == 8) { // Submenu Bomba
if (currentIndex == 0) {
adjustPumpOper(); // Lógica para submenu Bomba
} else if (currentIndex == 1) {
adjustPumpPause(); // Pause
} else {
currentMenu = 5; // Retorna ao submenu Monitorar
currentIndex = 0; // Reseta o índice
}
} else {
currentMenu = 0; // Retorna ao menu principal
currentIndex = 0; // Reseta o índice
}
displayMenu(); // Atualiza a exibição do menu
}
void displayMenu() {
lcd.clear();
for (int i = 0; i < getCurrentMenuSize(); i++) {
lcd.setCursor(0, i);
if (i == currentIndex) {
lcd.print("> ");
} else {
lcd.print(" ");
}
switch (currentMenu) {
case 0: // Menu Principal
lcd.print(mainMenu[i]);
break;
case 1: // Configurações
lcd.print(settingsMenu[i]);
break;
case 2: // PID
lcd.print(pidSubMenu[i]);
break;
case 3: // Fuzzy
lcd.print(fuzzySubMenu[i]);
break;
case 4: // Sensor
lcd.print(sensorSubMenu[i]);
break;
case 5: // Monitorar
lcd.print(monitorarMenu[i]);
break;
case 6: // Power
lcd.print(powerSubMenu[i]);
break;
case 7: // Motor
lcd.print(recipeSubMenu[i]);
break;
case 8: // Bomba
lcd.print(pumpSubMenu[i]);
break;
case 9: // Cadastrar
lcd.print(cadastroMenu[i]);
break;
case 10: // Executar
lcd.print(executeMenu[i]);
break;
}
}
}
int getCurrentMenuSize() {
switch (currentMenu) {
case 0: return mainMenuSize; // Menu Principal
case 1: return settingsMenuSize; // Menu de Configurações
case 2: return pidSubMenuSize; // SubMenu PID
case 3: return fuzzySubMenuSize; // SubMenu Fuzzy
case 4: return sensorSubMenuSize; // SubMenu Sensor
case 5: return monitorarMenuSize; // Menu Monitorar
case 6: return powerSubMenuSize; // SubMenu Power
case 7: return recipeSubMenuSize; // SbMenu Motor
case 8: return pumpSubMenuSize; // SubMenu Pump
case 9: return cadastroMenuSize; // Menu de Cadastro
case 10: return executeMenuSize; // Menu de Executar
default: return 0;
}
}
void adjustKp() {
EEPROM.get(Pid_Kp, Kp);
encoderPos = Kp;
bool adjusting = true; // Controle do loop de ajuste
while (adjusting) {
lcd.clear();
lcd.setCursor(6, 0);
lcd.print("Kp: ");
// Garantir que o valor esteja entre 0 e 100
if (encoderPos > 100) {
encoderPos = 100;
} else if (encoderPos < 0) {
encoderPos = 0;
}
lcd.setCursor(10, 1);
lcd.print(encoderPos);
lcd.setCursor(6, 2);
lcd.print("Press Enter");
delay(1000); // Delay para evitar piscar a tela
if (digitalRead(selectSwitch) == LOW) {
Kp = encoderPos; // Atualiza o potencial
EEPROM.put(Pid_Kp, Kp); // Salva na EEPROM
lcd.clear();
lcd.setCursor(6, 0);
lcd.print("Saved: ");
lcd.println(Kp);
adjusting = false; // Sai do loop de ajuste
lcd.clear();
// }
currentMenu = 2; // Retorna ao submenu PID
displayMenu(); // Exibe o submenu PID após voltar
}
}
}
void adjustKi() {
EEPROM.get(Pid_Ki, Ki);
encoderPos = Ki;
//int adjusted = potencial; // Começa com o valor atual
bool adjusting = true; // Controle do loop de ajuste
while (adjusting) {
lcd.clear();
lcd.setCursor(6, 0);
lcd.print("Ki: ");
// Garantir que o valor esteja entre 0 e 100
if (encoderPos > 100) {
encoderPos = 100;
} else if (encoderPos < 0) {
encoderPos = 0;
}
lcd.setCursor(10, 1);
lcd.print(encoderPos);
lcd.setCursor(6, 2);
lcd.print("Press Enter");
delay(1000); // Delay para evitar piscar a tela
if (digitalRead(selectSwitch) == LOW) {
Ki = encoderPos; // Atualiza o potencial
EEPROM.put(Pid_Ki, Ki); // Salva na EEPROM
lcd.clear();
lcd.setCursor(6, 0);
lcd.print("Saved: ");
lcd.println(Ki);
adjusting = false; // Sai do loop de ajuste
lcd.clear();
currentMenu = 2; // Retorna ao submenu PID
displayMenu(); // Exibe o submenu PID após voltar
}
}
}
void adjustKd() {
EEPROM.get(Pid_Kd, Kd);
encoderPos = Kd;
//int adjusted = potencial; // Começa com o valor atual
bool adjusting = true; // Controle do loop de ajuste
while (adjusting) {
lcd.clear();
lcd.setCursor(6, 0);
lcd.print("Kd: ");
// Garantir que o valor esteja entre 0 e 100
if (encoderPos > 10) {
encoderPos = 10;
} else if (encoderPos < 0) {
encoderPos = 0;
}
lcd.setCursor(10, 1);
lcd.print(encoderPos);
lcd.setCursor(6, 2);
lcd.print("Press Enter");
delay(1000); // Delay para evitar piscar a tela
if (digitalRead(selectSwitch) == LOW) {
Kd = encoderPos; // Atualiza o potencial
EEPROM.put(Pid_Kd, Kd); // Salva na EEPROM
lcd.clear();
lcd.setCursor(6, 0);
lcd.print("Saved: ");
lcd.println(Kd);
adjusting = false; // Sai do loop de ajuste
lcd.clear();
currentMenu = 2; // Retorna ao submenu PID
displayMenu(); // Exibe o submenu PID após voltar
}
}
}
void adjustIni() {
EEPROM.get(Fuzzy_Start, fuzzyStart);
encoderPos = fuzzyStart;
//int adjusted = potencial; // Começa com o valor atual
bool adjusting = true; // Controle do loop de ajuste
while (adjusting) {
lcd.clear();
lcd.setCursor(6, 0);
lcd.print("Ini: ");
// Garantir que o valor esteja entre 0 e 100
if (encoderPos > 10) {
encoderPos = 10;
} else if (encoderPos < 0) {
encoderPos = 0;
}
lcd.setCursor(10, 1);
lcd.print(encoderPos);
lcd.setCursor(6, 2);
lcd.print("Press Enter");
delay(1000); // Delay para evitar piscar a tela
if (digitalRead(selectSwitch) == LOW) {
fuzzyStart = encoderPos; // Atualiza o potencial
EEPROM.put(Fuzzy_Start, fuzzyStart); // Salva na EEPROM
lcd.clear();
lcd.setCursor(6, 0);
lcd.print("Saved: ");
lcd.println(fuzzyStart);
adjusting = false; // Sai do loop de ajuste
lcd.clear();
currentMenu = 3; // Retorna ao submenu Fuzzy
displayMenu(); // Exibe o submenu Fuzzy após voltar
}
}
}
void adjustAmpl() {
EEPROM.get(Fuzzy_Ampl, fuzzyAmplitude);
encoderPos = fuzzyAmplitude;
//int adjusted = potencial; // Começa com o valor atual
bool adjusting = true; // Controle do loop de ajuste
while (adjusting) {
lcd.clear();
lcd.setCursor(6, 0);
lcd.print("Ampl: ");
// Garantir que o valor esteja entre 0 e 100
if (encoderPos > 10) {
encoderPos = 10;
} else if (encoderPos < 0) {
encoderPos = 0;
}
lcd.setCursor(10, 1);
lcd.print(encoderPos);
lcd.setCursor(6, 2);
lcd.print("Press Enter");
delay(1000); // Delay para evitar piscar a tela
if (digitalRead(selectSwitch) == LOW) {
fuzzyAmplitude = encoderPos; // Atualiza o potencial
EEPROM.put(Fuzzy_Ampl, fuzzyAmplitude); // Salva na EEPROM
lcd.clear();
lcd.setCursor(6, 0);
lcd.print("Saved: ");
lcd.println(fuzzyAmplitude);
adjusting = false; // Sai do loop de ajuste
lcd.clear();
currentMenu = 3; // Retorna ao submenu Fuzzy
displayMenu(); // Exibe o submenu PID após voltar
}
}
}
void adjustSensorFator1() {
EEPROM.get(Sensor_F1, sensorF1);
encoderPos = sensorF1;
//int adjusted = potencial; // Começa com o valor atual
bool adjusting = true; // Controle do loop de ajuste
while (adjusting) {
lcd.clear();
lcd.setCursor(6, 0);
lcd.print("Fator 1: ");
// Garantir que o valor esteja entre 0 e 100
if (encoderPos > 10) {
encoderPos = 10;
} else if (encoderPos < 0) {
encoderPos = 0;
}
lcd.setCursor(10, 1);
lcd.print(encoderPos);
lcd.setCursor(6, 2);
lcd.print("Press Enter");
delay(1000); // Delay para evitar piscar a tela
if (digitalRead(selectSwitch) == LOW) {
sensorF1 = encoderPos; // Atualiza o potencial
EEPROM.put(Sensor_F1, sensorF1); // Salva na EEPROM
lcd.clear();
lcd.setCursor(6, 0);
lcd.print("Saved: ");
lcd.println(sensorF1);
adjusting = false; // Sai do loop de ajuste
lcd.clear();
currentMenu = 4; // Retorna ao submenu Sensor
displayMenu(); // Exibe o submenu após voltar
}
}
}
void adjustSensorFator2() {
EEPROM.get(Sensor_F2, sensorF2);
encoderPos = sensorF2;
bool adjusting = true; // Controle do loop de ajuste
while (adjusting) {
lcd.clear();
lcd.setCursor(6, 0);
lcd.print("Fator 2: ");
// Garantir que o valor esteja entre 0 e 100
if (encoderPos > 10) {
encoderPos = 10;
} else if (encoderPos < 0) {
encoderPos = 0;
}
lcd.setCursor(10, 1);
lcd.print(encoderPos);
lcd.setCursor(6, 2);
lcd.print("Press Enter");
delay(1000); // Delay para evitar piscar a tela
if (digitalRead(selectSwitch) == LOW) {
sensorF2 = encoderPos; // Atualiza o potencial
EEPROM.put(Sensor_F2, sensorF2); // Salva na EEPROM
lcd.println(sensorF2);
adjusting = false; // Sai do loop de ajuste
lcd.clear();
currentMenu = 4; // Retorna ao submenu Sensor
displayMenu(); // Exibe o submenu após voltar
}
}
}
void adjustPowerStep() {
EEPROM.get(Power_Step, powerStep);
encoderPos = powerStep; // Começa com o valor atual salvo na EEPROM
bool adjusting = true; // Controle do loop de ajuste
while (adjusting) {
lcd.clear();
lcd.setCursor(6, 0);
lcd.print("PowerStep: ");
// Garantir que o valor esteja entre 0 e 100
if (encoderPos > 100) {
encoderPos = 100;
} else if (encoderPos < 0) {
encoderPos = 0;
}
lcd.setCursor(10, 1);
lcd.print(encoderPos);
lcd.setCursor(6, 2);
lcd.print("Press Enter");
delay(1000); // Delay reduzido para melhorar a responsividade
// Verifica se o botão de seleção foi pressionado
if (digitalRead(selectSwitch) == LOW) {
powerStep = encoderPos; // Atualiza o valor ajustado
EEPROM.put(Power_Step, powerStep); // Salva na EEPROM
lcd.clear();
lcd.setCursor(6, 0);
lcd.print("Saved: ");
lcd.print(powerStep);
delay(1000); // Mostra mensagem de confirmação
adjusting = false; // Sai do loop de ajuste
// Retorna ao submenu
currentMenu = 6;
displayMenu();
}
}
}
void adjustPowerRamp() {
EEPROM.get(Power_Ramp, powerRamp);
encoderPos = powerRamp;
//int adjusted = potencial; // Começa com o valor atual
bool adjusting = true; // Controle do loop de ajuste
while (adjusting) {
lcd.clear();
lcd.setCursor(6, 0);
lcd.print("Power Ramp: ");
// Garantir que o valor esteja entre 0 e 100
if (encoderPos > 100) {
encoderPos = 100;
} else if (encoderPos < 0) {
encoderPos = 0;
}
lcd.setCursor(10, 1);
lcd.print(encoderPos);
lcd.setCursor(6, 2);
lcd.print("Press Enter");
delay(1000); // Delay para evitar piscar a tela
if (digitalRead(selectSwitch) == LOW) {
powerRamp = encoderPos; // Atualiza o potencial
EEPROM.put(Power_Ramp, powerRamp); // Salva na EEPROM
lcd.clear();
lcd.setCursor(6, 0);
lcd.print("Saved: ");
lcd.println(powerRamp);
adjusting = false; // Sai do loop de ajuste
lcd.clear();
currentMenu = 6; // Retorna ao submenu PID
displayMenu(); // Exibe o submenu PID após voltar
}
}
}
void adjustRecipeAgua() {
EEPROM.get(Rec_Agua, recAgua);
encoderPos = recAgua;
//int adjusted = potencial; // Começa com o valor atual
bool adjusting = true; // Controle do loop de ajuste
while (adjusting) {
lcd.clear();
lcd.setCursor(6, 0);
lcd.print("Vol.Agua: ");
// Garantir que o valor esteja entre 0 e 100
if (encoderPos > 150) {
encoderPos = 150;
} else if (encoderPos < 0) {
encoderPos = 0;
}
lcd.setCursor(10, 1);
lcd.print(encoderPos);
lcd.setCursor(6, 2);
lcd.print("Press Enter");
delay(1000); // Delay para evitar piscar a tela
if (digitalRead(selectSwitch) == LOW) {
recAgua = encoderPos; // Atualiza o potencial
EEPROM.put(Rec_Agua, recAgua); // Salva na EEPROM
lcd.clear();
lcd.setCursor(6, 0);
lcd.print("Saved: ");
lcd.println(recAgua);
adjusting = false; // Sai do loop de ajuste
lcd.clear();
currentMenu = 7; // Retorna ao submenu PID
displayMenu(); // Exibe o submenu PID após voltar
}
}
}
void adjustRecipeMalte() {
EEPROM.get(Rec_Malte, recMalte);
encoderPos = recMalte;
//int adjusted = potencial; // Começa com o valor atual
bool adjusting = true; // Controle do loop de ajuste
while (adjusting) {
lcd.clear();
lcd.setCursor(6, 0);
lcd.print("Malte: ");
// Garantir que o valor esteja entre 0 e 100
if (encoderPos > 50) {
encoderPos = 50;
} else if (encoderPos < 0) {
encoderPos = 0;
}
lcd.setCursor(10, 1);
lcd.print(encoderPos);
lcd.setCursor(6, 2);
lcd.print("Press Enter");
delay(1000); // Delay para evitar piscar a tela
if (digitalRead(selectSwitch) == LOW) {
recMalte = encoderPos; // Atualiza o potencial
EEPROM.put(Rec_Malte, recMalte); // Salva na EEPROM
lcd.clear();
lcd.setCursor(6, 0);
lcd.print("Saved: ");
lcd.println(recMalte);
adjusting = false; // Sai do loop de ajuste
lcd.clear();
currentMenu = 7; // Retorna ao submenu PID
displayMenu(); // Exibe o submenu PID após voltar
}
}
}
void adjustPumpOper() {
EEPROM.get(Pump_Oper, pumpOper);
encoderPos = pumpOper;
//int adjusted = potencial; // Começa com o valor atual
bool adjusting = true; // Controle do loop de ajuste
while (adjusting) {
lcd.clear();
lcd.setCursor(6, 0);
lcd.print("Operation: ");
// Garantir que o valor esteja entre 0 e 100
if (encoderPos > 60) {
encoderPos = 60;
} else if (encoderPos < 0) {
encoderPos = 0;
}
lcd.setCursor(10, 1);
lcd.print(encoderPos);
lcd.setCursor(6, 2);
lcd.print("Press Enter");
delay(1000); // Delay para evitar piscar a tela
if (digitalRead(selectSwitch) == LOW) {
pumpOper = encoderPos; // Atualiza o potencial
EEPROM.put(Pump_Oper, pumpOper); // Salva na EEPROM
lcd.clear();
lcd.setCursor(6, 0);
lcd.print("Saved: ");
lcd.println(pumpOper);
adjusting = false; // Sai do loop de ajuste
lcd.clear();
currentMenu = 8; // Retorna ao submenu PID
displayMenu(); // Exibe o submenu PID após voltar
}
}
}
void adjustPumpPause() {
EEPROM.get(Pump_Pause, pumpPause);
encoderPos = pumpPause;
//int adjusted = potencial; // Começa com o valor atual
bool adjusting = true; // Controle do loop de ajuste
while (adjusting) {
lcd.clear();
lcd.setCursor(6, 0);
lcd.print("Pause: ");
// Garantir que o valor esteja entre 0 e 100
if (encoderPos > 10) {
encoderPos = 10;
} else if (encoderPos < 0) {
encoderPos = 0;
}
lcd.setCursor(10, 1);
lcd.print(encoderPos);
lcd.setCursor(6, 2);
lcd.print("Press Enter");
delay(1000); // Delay para evitar piscar a tela
if (digitalRead(selectSwitch) == LOW) {
pumpPause = encoderPos; // Atualiza o potencial
EEPROM.put(Pump_Pause, pumpPause); // Salva na EEPROM
lcd.clear();
lcd.setCursor(6, 0);
lcd.print("Saved: ");
lcd.println(pumpPause);
adjusting = false; // Sai do loop de ajuste
lcd.clear();
currentMenu = 8; // Retorna ao submenu PID
displayMenu(); // Exibe o submenu PID após voltar
}
}
}
void cadRecipe(){
while (menuValue == 0)
{
menuValue++;
lcd.clear();
delay (250);
}
encoderPos = 42;
while (menuValue == 1)
{
//Display Mash Set point on LCD
lcd.setCursor(4, 0);
lcd.print("Mash: Fitase");
lcd.setCursor(4, 2);
lcd.print("Temp: ");
lcd.setCursor(13, 2);
lcd.write(byte(0)); // Mostra o símbolo de grau
lcd.print("C");
lcd.setCursor(9, 3);
lcd.print("OK");
pulsarValor(10, 2, encoderPos, 0); // Passa a posição na tela, o valor
ajustarParametro(10, 2, encoderPos, 0, 99);
if (digitalRead(selectSwitch) == LOW)
{
mashFitTemp = encoderPos;
//Serial.println(mashFitTemp);
menuValue++;
// Resetando a flag de pulsação para garantir que a pulsação ocorra novamente
pulsou[0] = false; // Resetando o controle para o index 0
lcd.clear();
}
delay (250);
}
//============================================================================================//
// Get user input time setpoint //
//============================================================================================//
if (menuValue == 2)
{
delay (250);
}
encoderPos = 1;
while (menuValue == 2)
{
//Display Mash Time Set point on LCD
lcd.setCursor(4, 0);
lcd.print("Mash: Fitase");
lcd.setCursor(4, 2);
lcd.print("Time: ");
// Garantir que o valor esteja entre 0 e 100
lcd.setCursor(13, 2);
lcd.print("min");
lcd.setCursor(9, 3);
lcd.print("OK");
// Chama a função pulsarValor para o valor de encoderPos com índice 0
pulsarValor(10, 2, encoderPos, 1); // Passa a posição na tela, o valor e o índice 0
ajustarParametro(10, 2, encoderPos, 0, 60);
if (digitalRead(selectSwitch) == LOW)
{
mashFitTime = encoderPos;
//Serial.println(mashFitTime);
menuValue ++;
// Resetando a flag de pulsação para garantir que a pulsação ocorra novamente
pulsou[1] = false; // Resetando o controle para o index 0
lcd.clear();
}
delay(250);
if (menuValue == 3)
{
delay (250);
}
}
//============================================================================================//
// Display user selected set points before starting for user to confirm //
//============================================================================================//
while (menuValue == 3)
{
lcd.setCursor(4, 0);
lcd.print("Mash: Fitase");
lcd.setCursor(2, 2);
lcd.print("Temp: ");
lcd.print(mashFitTemp);
lcd.setCursor(12, 2);
lcd.print("Time: ");
lcd.print(mashFitTime);
lcd.setCursor(4, 3);
lcd.print("Press to Save");
if (digitalRead(selectSwitch) == LOW)
{
EEPROM.put(mashTemp_Fit, mashFitTemp );
EEPROM.put(mashTime_Fit, mashFitTime);
Serial.println(mashFitTemp);
Serial.println(mashFitTime);
menuValue ++;
lcd.clear();
// mash_Fitase();
}
delay(250);
if (menuValue == 4)
{
delay (250);
}
}
// CONFIGURAR MASH STOP PROTEIC ------------//
encoderPos = 52;
while (menuValue == 4)
{
//Display Mash Set point on LCD
lcd.setCursor(2, 0);
lcd.print("Mash: Stop Proteic");
lcd.setCursor(4, 2);
lcd.print("Temp: ");
lcd.setCursor(13, 2);
lcd.write(byte(0)); // Mostra o símbolo de grau
lcd.print("C");
lcd.setCursor(9, 3);
lcd.print("OK");
// Chama a função para pulsar o valor
pulsarValor(10, 2, encoderPos,2); // Aqui são passados 3 argumentos: coluna, linha, e valor
ajustarParametro(10, 2, encoderPos, 0, 99);
if (digitalRead(selectSwitch) == LOW)
{
mashSPTemp = encoderPos;
menuValue++;
// Resetando a flag de pulsação para garantir que a pulsação ocorra novamente
pulsou[2] = false; // Resetando o controle para o index 0
lcd.clear();
}
delay (250);
}
//============================================================================================//
// Get user input for mash time setpoint //
//============================================================================================//
if (menuValue == 5)
{
delay (250);
}
encoderPos = 1;
while (menuValue == 5)
{
//Display Mash Time Set point on LCD
lcd.setCursor(2, 0);
lcd.print("Mash: Stop Proteic");
lcd.setCursor(4, 2);
lcd.print("Time: ");
lcd.setCursor(13, 2);
lcd.print("min");
lcd.setCursor(9, 3);
lcd.print("OK");
// Chama a função para pulsar o valor
pulsarValor(10, 2, encoderPos,3); // Aqui s
ajustarParametro(10, 2, encoderPos, 0, 60);
if (digitalRead(selectSwitch) == LOW)
{
mashSPTime = encoderPos;
menuValue ++;
// Resetando a flag de pulsação para garantir que a pulsação ocorra novamente
pulsou[3] = false; // Resetando o controle para o index 0
lcd.clear();
}
delay(250);
if (menuValue == 6)
{
delay (250);
}
}
//============================================================================================//
// Display user selected set points before starting for user to confirm //
//============================================================================================//
while (menuValue == 6)
{
lcd.setCursor(2, 0);
lcd.print("Mash: Stop Proteic");
lcd.setCursor(2, 2);
lcd.print("Temp: ");
lcd.print(mashSPTemp);
lcd.setCursor(12, 2);
lcd.print("Time: ");
lcd.print(mashSPTime);
lcd.setCursor(4, 3);
lcd.print("PRESS TO SAVE");
if (digitalRead(selectSwitch) == LOW)
{
EEPROM.put(mashTemp_SP, mashSPTemp );
EEPROM.put(mashTime_SP, mashSPTime);
menuValue ++;
lcd.clear();
}
delay(250);
if (menuValue == 7)
{
delay (250);
}
}
// CONFIGURAR MASH BETA AMILASE -----------------------//
encoderPos = 62;
while (menuValue == 7)
{
//Display Mash Set point on LCD
lcd.setCursor(2, 0);
lcd.print("Mash: Beta Amilase");
lcd.setCursor(4, 2);
lcd.print("Temp: ");
lcd.setCursor(13, 2);
lcd.write(byte(0)); // Mostra o símbolo de grau
lcd.print("C");
lcd.setCursor(9, 3);
lcd.print("OK");
// Chama a função para pulsar o valor
pulsarValor(10, 2, encoderPos,4); // Aqui são passados 3 argumentos: coluna, linha, e valor
ajustarParametro(10, 2, encoderPos, 0, 99);
if (digitalRead(selectSwitch) == LOW)
{
mashBATemp = encoderPos;
menuValue++;
// Resetando a flag de pulsação para garantir que a pulsação ocorra novamente
pulsou[4] = false; // Resetando o controle para o index 0
lcd.clear();
}
delay (250);
}
//============================================================================================//
// Get user input for mash time setpoint //
//======//
if (menuValue == 8)
{
delay (250);
}
encoderPos = 1;
while (menuValue == 8)
{
lcd.setCursor(2, 0);
lcd.print("Mash: Beta Amilase");
lcd.setCursor(4, 2);
lcd.print("Time: ");
lcd.setCursor(13, 2);
lcd.print("min");
lcd.setCursor(9, 3);
lcd.print("OK");
// Chama a função para pulsar o valor
pulsarValor(10, 2, encoderPos,5); // Aqui s
ajustarParametro(10, 2, encoderPos, 0, 60);
if (digitalRead(selectSwitch) == LOW)
{
mashBATime = encoderPos;
menuValue ++;
// Resetando a flag de pulsação para garantir que a pulsação ocorra novamente
pulsou[5] = false; // Resetando o controle para o index 0
lcd.clear();
}
delay(250);
if (menuValue == 9)
{
delay (250);
}
}
//============================================================================================//
// Display user selected set points before starting for user to confirm //
//============================================================================================//
while (menuValue == 9)
{
lcd.setCursor(2, 0);
lcd.print("Mash: Beta Amilase");
lcd.setCursor(2, 2);
lcd.print("Temp: ");
lcd.print(mashBATemp);
lcd.setCursor(12, 2);
lcd.print("Time: ");
lcd.print(mashBATime);
lcd.setCursor(4, 3);
lcd.print("PRESS TO SAVE");
if (digitalRead(selectSwitch) == LOW)
{
EEPROM.put(mashTemp_BA, mashBATemp );
EEPROM.put(mashTime_BA, mashBATime);
menuValue ++;
lcd.clear();
}
delay(250);
if (menuValue == 10)
{
delay (250);
}
}
// CONFIGURAR MASH ALFA AMILASE -----------------------//
encoderPos = 72;
while (menuValue == 10)
{
//Display Mash Set point on LCD
lcd.setCursor(1, 0);
lcd.print("Mash: Alfa Amilase");
lcd.setCursor(4, 2);
lcd.print("Temp: ");
lcd.setCursor(13, 2);
lcd.write(byte(0)); // Mostra o símbolo de grau
lcd.print("C");
lcd.setCursor(9, 3);
lcd.print("OK");
// Chama a função para pulsar o valor
pulsarValor(10, 2, encoderPos,6); // Aqui são passados 3 argumentos: coluna, linha, e valor
ajustarParametro(10, 2, encoderPos, 0, 99);
if (digitalRead(selectSwitch) == LOW)
{
mashAATemp = encoderPos;
menuValue++;
// Resetando a flag de pulsação para garantir que a pulsação ocorra novamente
pulsou[6] = false; // Resetando o controle para o index 0
lcd.clear();
}
delay (250);
}
//============================================================================================//
// Get user input for mash time setpoint //
//============================================================================================//
if (menuValue == 11)
{
delay (250);
}
encoderPos = 1;
while (menuValue == 11)
{
lcd.setCursor(1, 0);
lcd.print("Mash: Alfa Amilase");
lcd.setCursor(4, 2);
lcd.print("Time: ");
lcd.setCursor(13, 2);
lcd.print("min");
lcd.setCursor(9, 3);
lcd.print("OK");
// Chama a função para pulsar o valor
pulsarValor(10, 2, encoderPos,7); // Aqui s
ajustarParametro(10, 2, encoderPos, 0, 60);
if (digitalRead(selectSwitch) == LOW)
{
mashAATime = encoderPos;
menuValue ++;
// Resetando a flag de pulsação para garantir que a pulsação ocorra novamente
pulsou[7] = false; // Resetando o controle para o index 0
lcd.clear();
}
delay(250);
if (menuValue == 12)
{
delay (250);
}
}
//============================================================================================//
// Display user selected set points before starting for user to confirm //
//============================================================================================//
while (menuValue == 12)
{
lcd.setCursor(1, 0);
lcd.print("Mash: Alfa Amilase");
lcd.setCursor(2, 2);
lcd.print("Temp: ");
lcd.print(mashAATemp);
lcd.setCursor(12, 2);
lcd.print("Time: ");
lcd.print(mashAATime);
lcd.setCursor(4, 3);
lcd.print("PRESS TO SAVE");
if (digitalRead(selectSwitch) == LOW)
{
EEPROM.put(mashTemp_AA, mashAATemp );
EEPROM.put(mashTime_AA, mashAATime);
menuValue ++;
lcd.clear();
}
delay(250);
if (menuValue == 13)
{
delay (250);
}
}
// CONFIGURAR MASHOUT ---------//
encoderPos = 78;
while (menuValue == 13)
{
//Display Mash Set point on LCD
lcd.setCursor(6, 0);
lcd.print("MashOut");
lcd.setCursor(4, 2);
lcd.print("Temp: ");
lcd.setCursor(13, 2);
lcd.write(byte(0)); // Mostra o símbolo de grau
lcd.print("C");
lcd.setCursor(9, 3);
lcd.print("OK");
// Chama a função para pulsar o valor
pulsarValor(10, 2, encoderPos,8); // Aqui são passados 3 argumentos: coluna, linha, e valor
ajustarParametro(10, 2, encoderPos, 0, 99);
if (digitalRead(selectSwitch) == LOW)
{
mashOutTemp = encoderPos;
menuValue++;
// Resetando a flag de pulsação para garantir que a pulsação ocorra novamente
pulsou[8] = false; // Resetando o controle para o index 0
lcd.clear();
}
delay (250);
}
//============================================================================================//
// Get user input for mash time setpoint //
//============================================================================================//
if (menuValue == 14)
{
delay (250);
}
encoderPos = 1;
while (menuValue == 14)
{
//Display Mash Time Set point on LCD
lcd.setCursor(6, 0);
lcd.print("MashOut");
lcd.setCursor(4, 2);
lcd.print("Time: ");
lcd.setCursor(13, 2);
lcd.print("min");
lcd.setCursor(9, 3);
lcd.print("OK");
// Chama a função para pulsar o valor
pulsarValor(10, 2, encoderPos,9); // Aqui s
ajustarParametro(10, 2, encoderPos, 0, 60);
if (digitalRead(selectSwitch) == LOW)
{
mashOutTime = encoderPos;
menuValue ++;
// Resetando a flag de pulsação para garantir que a pulsação ocorra novamente
pulsou[9] = false; // Resetando o controle para o index 0
lcd.clear();
}
delay(250);
if (menuValue == 15)
{
delay (250);
}
}
//============================================================================================//
// Display user selected set points before starting for user to confirm //
//============================================================================================//
while (menuValue == 15)
{ lcd.setCursor(6, 0);
lcd.print("MashOut");
lcd.setCursor(2, 2);
lcd.print("Temp: ");
lcd.print(mashOutTemp);
lcd.setCursor(12, 2);
lcd.print("Time: ");
lcd.print(mashOutTime);
lcd.setCursor(4, 3);
lcd.print("PRESS TO SAVE");
if (digitalRead(selectSwitch) == LOW)
{
EEPROM.put(mashTemp_MO, mashOutTemp );
EEPROM.put(mashTime_MO, mashOutTime);
menuValue ++;
lcd.clear();
}
delay(250);
if (menuValue == 16)
{
delay (250);
}
}
// CONFIGURAR SPARGE ---------//
encoderPos = 78;
while (menuValue == 16)
{
//Display Mash Set point on LCD
lcd.setCursor(6, 0);
lcd.print("Sparge");
lcd.setCursor(4, 2);
lcd.print("Temp:");
lcd.setCursor(13, 2);
lcd.write(byte(0)); // Mostra o símbolo de grau
lcd.print("C");
lcd.setCursor(9, 3);
lcd.print("OK");
// Chama a função para pulsar o valor
pulsarValor(10, 2, encoderPos,10); // Aqui são passados 3 argumentos: coluna, linha, e valor
ajustarParametro(10, 2, encoderPos, 0, 100);
if (digitalRead(selectSwitch) == LOW)
{
SpargeTemp = encoderPos;
menuValue++;
lcd.clear();
}
delay (250);
}
//============================================================================================//
// Get user input for mash time setpoint //
//============================================================================================//
if (menuValue == 17)
{
delay (250);
}
encoderPos = 1;
while (menuValue == 17)
{
//Display Mash Time Set point on LCD
lcd.setCursor(6, 0);
lcd.print("Sparge");
lcd.setCursor(4, 2);
lcd.print("Time:");
lcd.setCursor(13, 2);
lcd.print("min");
lcd.setCursor(9, 3);
lcd.print("OK");
// Chama a função para pulsar o valor
pulsarValor(10, 2, encoderPos,11); // Aqui s
ajustarParametro(10, 2, encoderPos, 0, 60);
if (digitalRead(selectSwitch) == LOW)
{
SpargeTime = encoderPos;
menuValue ++;
lcd.clear();
}
delay(250);
if (menuValue == 18)
{
delay (250);
}
}
//============================================================================================//
// Display user selected set points before starting for user to confirm //
//============================================================================================//
while (menuValue == 18)
{
lcd.setCursor(5, 0);
lcd.print(" Sparge ");
lcd.setCursor(2, 2);
lcd.print("Temp: ");
lcd.print(SpargeTemp);
lcd.setCursor(12, 2);
lcd.print("Time: ");
lcd.print(SpargeTime);
lcd.setCursor(4, 3);
lcd.print("PRESS TO SAVE");
if (digitalRead(selectSwitch) == LOW)
{
EEPROM.put(Temp_Sparge, SpargeTemp );
EEPROM.put(Time_Sparge, SpargeTime);
menuValue ++;
lcd.clear();
}
delay(250);
if (menuValue == 19)
{
delay (250);
}
}
while (menuValue ==19){
lcd.setCursor(5, 1);
lcd.print(" SAVE RECIPE ");
lcd.setCursor(8, 3);
lcd.print(" OK!!! ");
if (digitalRead(selectSwitch) == LOW)
{
lcd.clear();
menuValue = 0;
currentMenu = 0;
displayMenu();
}
}
}
void executeRecipe(int &indiceEtapa) {
int estadoButton = 0; // Variável para o estado do botão (não utilizada diretamente aqui)
// Controle de menu (0 - Aguardando, 1 - Executando, 2 - Ajustes)
while (execMenu == 0) {
estadoButton = 1;
if (estadoButton == 1 && !mensagemAAExibida) {
mostrarMensagemAdAgua(); // Exibe a mensagem de adição de água
execMenu++; // Avança para o próximo estado (execução)
lcd.clear();
delay(250);
}
}
// Início da execução do processo após confirmação
while (execMenu == 1) {
checkPause(); // Verifica se o processo foi pausado
if (isPaused) {
pauseScreen(indiceEtapa); // Exibe a tela de pausa com o índice da etapa atual
continue; // Retorna para o loop sem avançar para a próxima etapa
}
executarEtapa(indiceEtapa); // Executa a etapa atual
// Avança para a próxima etapa automaticamente após a execução ou pular
if (!isPaused && execMenu == 1) { // Confirma que não está pausado
indiceEtapa++; // Avança para a próxima etapa
if (indiceEtapa > 5) { // Supondo 5 etapas no total
lcd.clear();
lcd.print("Processo concluido!");
delay(5000);
break; // Sai do loop de execução
}
}
}
// Menu de ajustes, permite alterar parâmetros durante o processo
while (execMenu == 2) {
// Menu de pausa onde o usuário pode ajustar parâmetros ou pular etapa
pauseScreen(indiceEtapa); // Passa o índice da etapa para saber qual ajustar
lcd.clear();
}
}
void checkPause() {
unsigned long currentMillis = millis();
// Se estivermos em menu de ajustes, a pausa não deve ocorrer
if (execMenu == 2) {
return; // Evita que a pausa seja ativada enquanto estamos no menu de ajustes
}
// Verifica se o botão de pausa foi pressionado e se o tempo de debounce foi atingido
if (digitalRead(selectSwitch) == LOW && (currentMillis - lastDebounceTime) > debounceDelay) {
lastDebounceTime = currentMillis; // Atualiza o tempo do último clique de debounce
// Alterna o estado de pausa
isPaused = !isPaused;
// Exibe o estado de pausa no LCD
if (isPaused) {
lcd.clear();
lcd.print("Pausado..."); // Exibe a mensagem "Pausado"
elapsedSeconds = (timeCountDown/1000 ) - currentTimeSeconds; // Calcula o tempo já executado
digitalWrite(RELAY, LOW); // Desliga a bomba ou outros dispositivos enquanto pausado
} else {
// isto nunca é executado
lcd.clear();
lcd.print("Retomando..."); // Exibe a mensagem "Retomando" ao sair da pausa
delay(1000); // Exibe por 1 segundo e volta
}
// Aguarda a liberação do botão antes de continuar
while (digitalRead(selectSwitch) == LOW) {
delay(10); // Atraso muito curto para evitar múltiplos cliques
}
}
}
void pauseScreen(int &indiceEtapa) {
int opcaoSelecionada = 0; // 0: Ajustar Parâmetros, 1: Pular Etapa, 2: Retomar
int opcaoAnterior = -1; // Inicializado com valor inválido
bool escolhaConfirmada = false;
// Exibe o menu de pausa
while (!escolhaConfirmada) {
// Apenas atualiza o LCD se a opção mudou
if (opcaoSelecionada != opcaoAnterior) {
opcaoAnterior = opcaoSelecionada; // Atualiza o estado anterior
// Atualiza o display LCD com o menu
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(opcaoSelecionada == 0 ? ">" : " "); lcd.print("Ajustar Param.");
lcd.setCursor(0, 1);
lcd.print(opcaoSelecionada == 1 ? ">" : " "); lcd.print("Pular Etapa");
lcd.setCursor(0, 2);
lcd.print(opcaoSelecionada == 2 ? ">" : " "); lcd.print("Retomar");
}
// Lê o encoder para mudar a opção selecionada
if (digitalRead(pinA) == LOW) { // Gira no sentido horário
opcaoSelecionada = (opcaoSelecionada + 1) % 3; // Incrementa e reseta após 2
delay(200); // Debounce
}
if (digitalRead(pinB) == LOW) { // Gira no sentido anti-horário
opcaoSelecionada = (opcaoSelecionada + 2) % 3; // Decrementa (mod 3 evita negativo)
delay(200); // Debounce
}
// Confirmação da escolha com o botão
if (digitalRead(selectSwitch) == LOW) {
delay(200); // Debounce
escolhaConfirmada = true;
}
}
// Executa a ação correspondente à opção escolhida
switch (opcaoSelecionada) {
case 0: // Ajustar parâmetros
lcd.clear();
ajustarTemperatura(indiceEtapa); // Chama a função de ajuste de parâmetros
break;
case 1: // Pular etapa
lcd.clear();
lcd.print("Pulando etapa...");
delay(1000);
lcd.clear();
indiceEtapa++; // Avança para a próxima etapa
// Verifica se ultrapassou o número total de etapas
if (indiceEtapa > 5) { // Supondo 5 etapas no total
lcd.clear();
lcd.print("Fim do processo!");
delay(2000);
isPaused = false;
execMenu = 1; // Retorna ao estado inicial
return;
}
execMenu = 1; // Retorna ao estado de execução
// Modificações:
isPaused = false; // Garante que a execução não está pausada após pular a etapa
ajusteCompletado = true; // Marca que o ajuste foi feito
executeRecipe(indiceEtapa); // Retome a execução da etapa atual
break;
case 2: // Retomar execução
lcd.clear();
lcd.print("Retomando...");
delay(1000);
isPaused = false;
execMenu=1;
executeRecipe(indiceEtapa); // Retome a execução da etapa atual
break;
}
}
void executarEtapa( int indiceEtapa) {
int setpoint = 0;
String nomeEtapa;
int powerRamp = 0;
int powerStep = 0;
bool reachedSetpoint = false; // Controle para detectar quando atinge o setpoint
bool timeUpdated = false; // Flag para garantir que o tempo foi ajustado
unsigned long tempoDecorrido = 0; // Armazenar o tempo decorrido
// Definindo a temperatura e o tempo de cada etapa
switch(indiceEtapa) {
case 0: setpoint = mashFitTemp; timeCountDown = mashFitTime*60000; nomeEtapa = "Mash_Fitase"; break;
case 1: setpoint = mashSPTemp; timeCountDown = mashSPTime*60000; nomeEtapa = "Protease"; break;
case 2: setpoint = mashBATemp; timeCountDown = mashBATime*60000; nomeEtapa = "Beta_Amilase"; break;
case 3: setpoint = mashAATemp; timeCountDown = mashAATime*60000; nomeEtapa = "Alfa_Amilase"; break;
case 4: setpoint = mashOutTemp; timeCountDown = mashOutTime*60000; nomeEtapa = "MashOut"; break;
case 5: setpoint = SpargeTemp; timeCountDown = SpargeTime*60000; nomeEtapa = "Sparge"; break;
default: Serial.println("Etapa desconhecida."); return;
}
// Carrega os parâmetros de potência da EEPROM
EEPROM.get(32, powerRamp);
EEPROM.get(36, powerStep);
// Armazena o tempo de início
unsigned long tempoInicial = millis();
// Lógica para controle de temperatura, motor, bomba, etc.
lcd.clear();
lcd.setCursor(2, 0);
lcd.print(nomeEtapa);
lcd.setCursor(12, 2);
lcd.print("Tp: ");
lcd.print( timeCountDown/60000);
while ( timeCountDown > 0) {
checkPause(); // Verifica se a pausa foi acionada
if (isPaused) { // Verifica se está em pausado
elapsedSeconds = timeCountDown - currentTimeSeconds;
pauseScreen(indiceEtapa);
continue;
}
float currentTemperature = sensors.getTempCByIndex(0);
// Atualiza a exibição
lcd.setCursor(2, 0);
lcd.print(nomeEtapa);
lcd.setCursor(1, 1);
lcd.write(byte(1));// Exibe o caractere na tela.
lcd.print(": ");
lcd.print(currentTemperature, 1);
lcd.setCursor(12, 1);
lcd.print("Sp: ");
lcd.print(setpoint);
lcd.write(byte(0));
lcd.print("C");
// Ajusta a potência de acordo com a etapa (rampa ou manutenção)
int powerOutput;
if (!reachedSetpoint) {
// Fase de subida de rampa: utiliza powerRamp
powerOutput = controleTemperatura(setpoint, powerRamp, powerStep);
if (currentTemperature >= setpoint) {
reachedSetpoint = true; // Marca que o setpoint foi atingido
}
} else {
// Fase de manutenção: utiliza powerStep
powerOutput = controleTemperatura(setpoint, powerRamp, powerStep);
}
// lcd.setCursor(1, 3);
displayPower(1, 3); // Exibe o símbolo de "Power"
lcd.print(": ");
lcd.print(reachedSetpoint ? powerStep : powerRamp);
lcd.setCursor(8,3);
lcd.print("%");
// Inicia o cronômetro quando a temperatura atinge o setpoint
//if (currentTemperature >= (setpoint - 1) && !timerStarted) {
// timerStarted = true;
// localSeconds = 0;
// }
int minutos = timeCountDown / 60000;
int segundos = (timeCountDown % 60000)/1000;
// Verifica se o tempo ficou negativo (overflow) e corrige
if (timeCountDown < 0) {
timeCountDown = 0; // Evita valores negativos
break;
}
timeCountDown -= 30; // Reduz o tempo restante em 1 segundo
// Exibe o tempo restante no formato MM:SS no LCD
lcd.setCursor(12, 2);
lcd.print("Tp:");
if (minutos < 10) lcd.print("0"); // Adiciona zero à esquerda se < 10
lcd.print(minutos);
lcd.print(":");
if (segundos < 10) lcd.print("0"); // Adiciona zero à esquerda se < 10
lcd.print(segundos);
// Atualiza outros controles
displayTotalTime();
// atualizaTempos();
controlaBomba();
if (indiceEtapa != 4) {
controlaMotor();
}
if (indiceEtapa == 1 && !mensagemPHExibida) {
mostrarMensagemTestePH(); // Exibe a mensagem
// Quando o ENTER for pressionado, volta à execução normal
}
if (indiceEtapa == 4 && !mensagemTIExibida ) {
mostrarMensagemTesteIodo();
}
if (indiceEtapa == 5 && !mensagemTMExibida ) {
mostrarMensagemTransferirMosto();
}
// checkPause(); // Verifica a pausa novamente
}
// Quando o tempo se esgota, a etapa é concluída
lcd.clear();
lcd.setCursor(2, 1);
lcd.print("Etapa Completa!");
actionBuzzer();
delay(10000); // Exibe por 10 segundos
}
void ajustarPotencia(int indiceEtapa) {
int ajustePotencia;
int setpoint;
String nomeEtapa;
// Define se estamos em uma fase de rampa ou em uma etapa estática
bool isPowerRamp = (abs(currentTemperature - getSetpoint()) > 1.0); // Definindo a fase de rampa se a diferença for maior que 1°C
// Ajusta o nome da etapa dependendo da fase (rampa ou etapa)
if (isPowerRamp) {
nomeEtapa = "Power Ramp";
} else {
nomeEtapa = "Power Step";
}
// Obtém o setpoint da etapa
setpoint = getSetpoint();
// Durante a rampa ou na etapa, a potência será ajustada manualmente através do encoder
if (isPowerRamp) {
// Aqui, o valor de potência será ajustado com o encoder
ajustePotencia = powerRamp; // Potência da rampa
} else {
// Durante a etapa, ajustamos a potência com o valor de powerStep
ajustePotencia = powerStep; // Potência da etapa
}
// Exibe as informações no LCD
lcd.setCursor(2, 0);
lcd.print(nomeEtapa);
lcd.setCursor(1, 1);
lcd.write(byte(2));// Exibe o caractere na tela.
lcd.print(": ");
lcd.print(currentTemperature, 1);
lcd.setCursor(12, 1);
lcd.print("Sp: ");
lcd.print(setpoint);
lcd.write(byte(0));
lcd.print("C");
displayPower(1, 3); // Exibe o símbolo de "Power"
lcd.print(": ");
lcd.print(ajustePotencia);
lcd.setCursor(8, 3);
lcd.print("%");
// Espera até que o ajuste de potência seja confirmado
while (true) {
// Ajusta a potência com o encoder
if (digitalRead(pinA) == LOW) {
ajustePotencia++; // Aumenta a potência
lastDebounceTime = millis(); // Reinicia o debounce
}
if (digitalRead(pinB) == LOW) {
ajustePotencia--; // Diminui a potência
lastDebounceTime = millis(); // Reinicia o debounce
}
// Garante que o valor de ajustePotencia esteja entre 0 e 100
if (ajustePotencia > 100) {
ajustePotencia = 100;
} else if (ajustePotencia < 0) {
ajustePotencia = 0;
}
lcd.setCursor(2, 3);
lcd.print("P:");
lcd.print(ajustePotencia);
lcd.setCursor(8, 3);
lcd.print("%");
// Lê o estado do botão "Enter"
if (digitalRead(selectSwitch) == LOW && !buttonPressed) {
if (millis() - lastDebounceTime > debounceDelay) {
buttonPressed = true; // Marca que o botão foi pressionado
// Salva o valor de potência ajustada na EEPROM dependendo da fase
if (isPowerRamp) {
powerRamp = ajustePotencia; // Atualiza a potência de rampa
EEPROM.put(Power_Ramp, powerRamp); // Salva na EEPROM (endereçamento para rampa)
} else {
powerStep = ajustePotencia; // Atualiza a potência da etapa
EEPROM.put(Power_Step, powerStep); // Salva na EEPROM (endereçamento para etapa)
}
// Exibe a confirmação de salvamento
lcd.setCursor(14, 3);
lcd.print("Save!");
delay(2000); // Aguarda 2 segundos para exibir a confirmação
lcd.setCursor(14, 3);
lcd.print(" "); // Limpa a linha onde a mensagem foi exibida
// Chama a função de ajuste de temperatura após salvar
ajustarTemperatura(indiceEtapa); // Ajuste a temperatura conforme a necessidade
break; // Sai do loop de ajuste
}
}
// Se o botão for solto, reseta a variável de controle
if (digitalRead(selectSwitch) == HIGH) {
buttonPressed = false;
}
}
}
void ajustarTemperatura(int indiceEtapa) {
Serial.print("Fase: ");
Serial.println(indiceEtapa);
int ajusteTemperatura;
int timeCountDown;
String nomeEtapa;
// Define o valor atual baseado na etapa
switch(indiceEtapa) {
case 0: ajusteTemperatura = mashFitTemp; timeCountDown = mashFitTime; nomeEtapa = "Mash_Fitase"; break;
case 1: ajusteTemperatura = mashSPTemp; timeCountDown = mashSPTime; nomeEtapa = "Protease"; break;
case 2: ajusteTemperatura = mashBATemp; timeCountDown = mashBATime; nomeEtapa = "Beta_Amilase"; break;
case 3: ajusteTemperatura = mashAATemp; timeCountDown = mashAATime; nomeEtapa = "Alfa_Amilase"; break;
case 4: ajusteTemperatura = mashOutTemp; timeCountDown = mashOutTime; nomeEtapa = "MashOut"; break;
case 5: ajusteTemperatura = SpargeTemp; timeCountDown = SpargeTime; nomeEtapa = "Sparge"; break;
default: return;
}
lcd.setCursor(2, 0);
lcd.print(nomeEtapa);
lcd.setCursor(1, 1);
lcd.write(byte(1));// Exibe o caractere na tela.
lcd.print(": ");
lcd.print(currentTemperature, 1);
lcd.setCursor(12, 1);
lcd.print("Sp: ");
lcd.print(ajusteTemperatura);
lcd.write(byte(0));
lcd.print("C");
lcd.setCursor(12, 2);
lcd.print("Tp: ");
lcd.print(timeCountDown);
displayPower(1, 3); // Exibe o símbolo de "Power"
lcd.print(": ");
lcd.print(powerRamp);
lcd.setCursor(8, 3);
lcd.print("%");
lcd.setCursor(12, 1);
lcd.print("Sp: ");
lcd.write(byte(0));
lcd.print("C");
// Resetando a flag de pulsação para garantir que a pulsação ocorra novamente
pulsou[12] = false; // Resetando o controle para o index 13, onde o valor de ajusteTempo é exibido
pulsarValor(16, 1, ajusteTemperatura, 12);
unsigned long lastEncoderPress = 0; // Controle de debounce do encoder
while (true) {
if (digitalRead(pinA) == LOW && millis() - lastEncoderPress > 200) {
ajusteTemperatura++;
lastEncoderPress = millis();
}
if (digitalRead(pinB) == LOW && millis() - lastEncoderPress > 200) {
ajusteTemperatura--;
lastEncoderPress = millis();
}
// Garante que o valor de ajusteTemperatura esteja entre 0 e 100
if (ajusteTemperatura > 100) {
ajusteTemperatura = 100;
} else if (ajusteTemperatura < 0) {
ajusteTemperatura = 0;
}
// Atualiza a exibição no LCD para refletir o nova temperatura
lcd.setCursor(12, 1);
lcd.print("Sp: ");
lcd.print(ajusteTemperatura);
lcd.write(byte(0));
lcd.print("C");
lcd.print(" "); // Limpa caracteres extras
if (digitalRead(selectSwitch) == LOW) {
delay(200); // debounce
switch(indiceEtapa) {
case 0: mashFitTemp = ajusteTemperatura; EEPROM.put(mashTemp_Fit, mashFitTemp); break;
case 1: mashSPTemp = ajusteTemperatura; EEPROM.put(mashTemp_SP, mashSPTemp); break;
case 2: mashBATemp = ajusteTemperatura; EEPROM.put(mashTemp_BA, mashBATemp); break;
case 3: mashAATemp = ajusteTemperatura; EEPROM.put(mashTemp_AA, mashAATemp); break;
case 4: mashOutTemp = ajusteTemperatura; EEPROM.put(mashTemp_MO, mashOutTemp); break;
case 5: SpargeTemp = ajusteTemperatura; EEPROM.put(Temp_Sparge, SpargeTemp); break;
}
lcd.setCursor(14, 3);
lcd.print("Save!");
delay(2000); // Aguarda 2 segundos para exibir a confirmação
// Limpa a linha onde a mensagem foi exibida
lcd.setCursor(14, 3);
lcd.print(" ");
// Chame a próxima função ou retorne à tela de execução
ajustarTempo(indiceEtapa); // Certifique-se de passar a etapa correta
break; // Sai do loop de ajuste
}
}
// Se o botão for solto, reseta a variável de controle
if (digitalRead(selectSwitch) == HIGH) {
buttonPressed = false;
}
}
void ajustarTempo(int indiceEtapa) {
int ajusteTempo;
int setpoint;
String nomeEtapa;
// Captura o tempo atual baseado na etapa
switch (indiceEtapa) {
case 0: setpoint = mashFitTemp; ajusteTempo = mashFitTime; nomeEtapa = "Mash_Fitase"; break;
case 1: setpoint = mashSPTemp; ajusteTempo = mashSPTime; nomeEtapa = "Protease"; break;
case 2: setpoint = mashBATemp; ajusteTempo = mashBATime; nomeEtapa = "Beta_Amilase"; break;
case 3: setpoint = mashAATemp; ajusteTempo = mashAATime; nomeEtapa = "Alfa_Amilase"; break;
case 4: setpoint = mashOutTemp; ajusteTempo = mashOutTime; nomeEtapa = "MashOut"; break;
case 5: setpoint = SpargeTemp; ajusteTempo = SpargeTime; nomeEtapa = "Sparge"; break;
default: return;
}
unsigned long lastButtonPress = 0; // Para controle de debounce do botão
bool buttonPressed = false; // Controle de pressionamento do botão
// Exibe o tempo atual no LCD
lcd.clear();
lcd.setCursor(2, 0);
lcd.print(nomeEtapa);
lcd.setCursor(1, 1);
lcd.write(byte(1));// Exibe o caractere na tela.
lcd.print(": ");
lcd.print(currentTemperature, 1);
lcd.setCursor(12, 1);
lcd.print("Sp: ");
lcd.print(setpoint);
lcd.write(byte(0));
lcd.print("C");
displayPower(1, 3); // Exibe o símbolo de "Power"
lcd.print(": ");
lcd.print(powerRamp);
lcd.setCursor(8, 3);
lcd.print("%");
lcd.setCursor(12, 2);
lcd.print("Tp: ");
// lcd.print(ajusteTempo);
// Resetando a flag de pulsação para garantir que a pulsação ocorra novamente
pulsou[13] = false; // Resetando o controle para o index 13, onde o valor de ajusteTempo é exibido
pulsarValor(16, 2, ajusteTempo, 13);
unsigned long lastEncoderPress = 0; // Controle de debounce do encoder
while (true) {
// Aumenta o tempo com o encoder (pinA)
if (digitalRead(pinA) == LOW && millis() - lastEncoderPress > 200) {
ajusteTempo++; // Aumenta o tempo
lastEncoderPress = millis();
}
// Diminui o tempo com o encoder (pinB)
if (digitalRead(pinB) == LOW && millis() - lastEncoderPress > 200) {
ajusteTempo--; // Diminui o tempo
lastEncoderPress = millis();
}
// Garante que o valor de ajusteTemperatura esteja entre 0 e 100
if (ajusteTempo > 60) {
ajusteTempo = 60;
} else if (ajusteTempo < 0) {
ajusteTempo = 0;
}
// Atualiza a exibição no LCD para refletir o novo tempo
lcd.setCursor(12, 2);
lcd.print("Tp: ");
lcd.print(ajusteTempo);
lcd.print(" "); // Limpa caracteres extras
// Lê o estado do botão "Enter"
if (digitalRead(selectSwitch) == LOW && !buttonPressed && millis() - lastButtonPress > 200) {
buttonPressed = true; // Marca que o botão foi pressionado
lastButtonPress = millis(); // Atualiza o tempo do último pressionamento
// Atualiza o tempo de acordo com a etapa
switch (indiceEtapa) {
case 0: mashFitTime = ajusteTempo; EEPROM.put(mashTime_Fit, mashFitTime); break;
case 1: mashSPTime = ajusteTempo; EEPROM.put(mashTime_SP, mashSPTime); break;
case 2: mashBATime = ajusteTempo; EEPROM.put(mashTime_BA, mashBATime); break;
case 3: mashAATime = ajusteTempo; EEPROM.put(mashTime_AA, mashAATime); break;
case 4: mashOutTime = ajusteTempo; EEPROM.put(mashTime_MO, mashOutTime); break;
case 5: SpargeTime = ajusteTempo; EEPROM.put(Time_Sparge, SpargeTime); break;
}
// Confirmação no LCD
lcd.setCursor(14, 3);
lcd.print("Save!");
delay(2000); // Aguarda 2 segundos para exibir a confirmação
// Limpa a linha onde a mensagem foi exibida
lcd.setCursor(14, 3);
lcd.print(" ");
unsigned long startMillis = millis();
while (millis() - startMillis < 2000) {
// Aguardar 2 segundos sem usar o delay() diretamente
// Você pode colocar qualquer outra lógica aqui que não interfira
// com o fluxo, como verificações do botão de pausa.
}
// Depois de salvar o ajuste, evite que pauseScreen seja chamada
isPaused = false; // Certifique-se de que não estamos em pausa
execMenu = 1;
ajusteCompletado = true; // Marca que o ajuste foi feito
executeRecipe(indiceEtapa); // Retome a execução da etapa atual
break; // Sai do loop de ajuste
}
// Se o botão for solto, reseta a variável de controle
if (digitalRead(selectSwitch) == HIGH) {
buttonPressed = false;
}
delay(10); // Reduz a frequência de leitura para evitar sobrecarga de CPU
}
}
// Função de controle de temperatura
int controleTemperatura(float setpoint,int powerRamp, int powerStep) {
sensors.requestTemperatures();
float currentTemperature = sensors.getTempCByIndex(0);
float error = setpoint - currentTemperature;
float integral = 0, derivative = 0, previousError = 0;
integral += error;
derivative = error - previousError;
int powerOutput = (Kp * error) + (Ki * integral) + (Kd * derivative);
previousError = error;
if (error > fuzzyStart) {
float fuzzyAdjustment = fuzzyAmplitude * (error - fuzzyStart);
powerOutput += fuzzyAdjustment;
}
powerOutput = (currentTemperature < setpoint) ? min(powerRamp, powerOutput) : min(powerStep, powerOutput);
if (currentTemperature < setpoint) {
powerOutput = min(powerRamp, powerOutput);
} else {
powerOutput = min(powerStep, powerOutput);
}
digitalWrite(RELAY, powerOutput > 0 ? HIGH : LOW);
return powerOutput; // Retorna a potência aplicada
}
void displayTotalTime() {
if (startTime == 0) { // Verifica se o cronômetro ainda não foi iniciado
startTime = millis(); // Inicializa o tempo de início com o tempo atual (primeira execução da função)
}
// Cálculo do tempo total de brassagem
// Verifica se passou 1 segundo desde a última atualização
unsigned long currentMillis = millis(); // Tempo atual
if (currentMillis - previousMillis >= intervalo) {
// Salva o tempo da última atualização
previousMillis = currentMillis;
// Incrementa o tempo total de 1 segundo
totalTime++; // Incrementa 1 segundo por vez
}
// Cálculo de minutos e segundos
int totalMins = totalTime / 60;
int totalSecs = totalTime % 60;
// Exibir no LCD
lcd.setCursor(1, 2); // Defina a linha e coluna desejadas
lcd.write(byte(2));// Exibe o caractere na tela.
lcd.print(": ");
if (totalMins < 10) lcd.print("0");
lcd.print(totalMins);
lcd.print(":");
if (totalSecs < 10) lcd.print("0");
lcd.print(totalSecs);
}
void controlaBomba() {
EEPROM.get(Pump_Oper, pumpOper);
EEPROM.get(Pump_Pause, pumpPause);
if (bombaTimer < pumpPause*60) { // Bomba ligada por 5 minutos (300 segundos)
digitalWrite(pumpPin, LOW); // bomba desligada
bombaTimer++;
} else if (bombaTimer >= pumpPause*60 && bombaTimer < (pumpOper*60 + pumpPause*60)) { // Bomba desligada por 1 minuto (60 segundos)
digitalWrite(pumpPin, HIGH); // Desliga a bomba
displayBomba(10, 3); // Exibe o símbolo de "Power"
bombaTimer++;
}
else {
bombaTimer = 0; // Reinicia o timer da bomba
}
}
void controlaMotor() {
EEPROM.get(Pump_Oper, pumpOper);
EEPROM.get(Pump_Pause, pumpPause);
if (motorTimer < pumpPause*60) { //
digitalWrite(motorPin, HIGH); // motor ligado
displayMotor(12, 3); // Exibe o símbolo de "Power"
motorTimer++;
} else if (motorTimer >= pumpPause*60 && motorTimer <(pumpOper*60+ pumpPause*60)) { // Motor desligada por 5 minuto (60 segundos)
digitalWrite(motorPin, LOW); // Desliga o motor
motorTimer++;
}
else {
motorTimer = 0; // Reinicia o timer
}
}
void actionBuzzer() {
for (int i = 0; i < 5; i++) { // Toca o buzzer 5 vezes
digitalWrite(buzzerPin, HIGH); // Ativa o buzzer
delay(1000); // Duração do beep
digitalWrite(buzzerPin, LOW); // Desativa o buzzer
delay(1000); // Pausa entre os beeps
}
}
void mostrarMensagemAdAgua() {
isAACheckPaused = true;
lcd.clear();
lcd.setCursor(3, 1);
lcd.print("Adicionou Agua?");
lcd.setCursor(5, 3);
lcd.print("Press Enter");
delay(3000); // Mostra a mensagem por 3 segundos
mensagemAAExibida = true; // Marca que a mensagem foi exibida
// Espera até que o botão seja pressionado
while (digitalRead(selectSwitch) == HIGH ) {
// Aguarda o botão ser pressionado
}
// Opcional: Aguarde um pequeno tempo para evitar múltiplas leituras
delay(200); // Delay para debouncing
lcd.clear(); // Limpa a tela ao sair da mensagem
isAACheckPaused = false; // Retira a pausa de teste de pH
}
void mostrarMensagemTesteIodo() {
isTICheckPaused = true;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Teste");
lcd.setCursor(6, 1);
lcd.print("de Iodo");
lcd.setCursor(0, 3);
lcd.print("Press Enter");
delay(3000); // Mostra a mensagem por 3 segundos
mensagemTIExibida = true; // Marca que a mensagem foi exibida
// Espera até que o botão seja pressionado
while (digitalRead(selectSwitch) == HIGH ) {
// Aguarda o botão ser pressionado
delay(100);
}
// Opcional: Aguarde um pequeno tempo para evitar múltiplas leituras
delay(200); // Delay para debouncing
lcd.clear(); // Limpa a tela ao sair da mensagem
isTICheckPaused = false; // Retira a pausa de teste de pH
}
void mostrarMensagemTransferirMosto() {
isTMCheckPaused = true; //
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" Transferir");
lcd.setCursor(0, 1);
lcd.print("o Mosto");
delay(3000); // Mostra a mensagem por 3 segundos
mensagemTMExibida = true; // Marca que a mensagem foi exibida
// Espera até que o botão seja pressionado
while (digitalRead(selectSwitch) == HIGH ) {
// Aguarda o botão ser pressionado
delay(100);
}
// Opcional: Aguarde um pequeno tempo para evitar múltiplas leituras
delay(200); // Delay para debouncing
lcd.clear(); // Limpa a tela ao sair da mensagem
isTMCheckPaused = false; // Retira a pausa de teste de pH
}
void mostrarMensagemTestePH() {
isPHCheckPaused = true; //
lcd.clear();
lcd.setCursor(5, 1);
lcd.print("Teste de pH");
lcd.setCursor(9, 3);
lcd.print(" OK");
delay(3000); // Mostra a mensagem por 3 segundos
mensagemPHExibida = true; // Marca que a mensagem foi exibida
// Espera até que o botão seja pressionado
while (digitalRead(selectSwitch) == HIGH ) {
// Aguarda o botão ser pressionado
delay(100); // Pequeno delay para evitar múltiplas leituras
}
// Opcional: Aguarde um pequeno tempo para evitar múltiplas leituras
delay(200); // Delay para debouncing
lcd.clear(); // Limpa a tela ao sair da mensagem
isPHCheckPaused = false; // Retira a pausa de teste de pH
}
bool verificarAgua() {
// Lê o estado do sensor de nível de água
int estadoSensor = digitalRead(pinoSensorAgua);
// Lê o estado do botão "Enter" do encoder
int reading = digitalRead(selectSwitch);
// Aplica debounce no botão
if (reading != lastButtonState) {
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
if (reading == LOW) { // Botão pressionado
lastButtonState = reading; // Atualiza o estado do botão
return true; // Água foi confirmada como adicionada
}
}
lastButtonState = reading;
// Exibe mensagem na tela
exibirMensagem("Adicione água e pressione Enter.");
// Retorna verdadeiro se a água foi adicionada (sensor) ou se o botão foi pressionado
return (estadoSensor == HIGH);
}
void exibirMensagem(const char* mensagem) {
lcd.clear(); // Limpa a tela
lcd.setCursor(0, 0); // Define o cursor na primeira linha
lcd.print(mensagem); // Exibe a mensagem
}
// Função para verificar se o botão "Enter" foi pressionado (exemplo)
bool botaoEnterPressionado() {
return digitalRead(selectSwitch) == HIGH; // Altere para o seu pino de entrada do botão
}
// Função para criar e exibir o símbolo de power
void displayPower(int x, int y) {
lcd.createChar(3, powerSymbol); // Cria o caractere customizado
lcd.setCursor(x, y); // Define a posição do cursor
lcd.write(byte(3)); // Exibe o caractere
}
// Função para criar e exibir o símbolo de bomba
void displayBomba(int x, int y) {
lcd.createChar(4, bombaSymbol); // Cria o caractere customizado
lcd.setCursor(x, y); // Define a posição do cursor
lcd.write(byte(4)); // Exibe o caractere
}
// Função para criar e exibir o símbolo de bomba
void displayMotor(int x, int y) {
lcd.createChar(5, motorSymbol); // Cria o caractere customizado
lcd.setCursor(x, y); // Define a posição do cursor
lcd.write(byte(5)); // Exibe o caractere
}
int getSetpoint() {
int setpoint;
int targetRampTemp;
// Define se estamos em uma fase de rampa ou em uma etapa estática
bool isPowerRamp = (abs(currentTemperature - getSetpoint()) > 1.0); // Definindo a fase de rampa se a diferença for maior que 1°C
// Determina o setpoint com base na etapa atual
if (isPowerRamp) {
setpoint = targetRampTemp; // Se estiver na rampa, o setpoint é o alvo da rampa (exemplo)
} else {
// Se estiver em uma etapa estática, definimos um setpoint de acordo com a etapa
if (indiceEtapa == 0) {
setpoint = mashFitTemp;
} else if (indiceEtapa == 1) {
setpoint = mashSPTemp;
} else if (indiceEtapa == 2) {
setpoint = mashBATemp;
} else if (indiceEtapa == 3) {
setpoint = mashAATemp;
} else if (indiceEtapa == 4) {
setpoint = mashOutTemp;
} else if (indiceEtapa == 5) {
setpoint = SpargeTemp;
}
}
return setpoint; // Retorna o setpoint para a etapa ou a rampa
}
void pulsarValor(int coluna, int linha, int valor, int index) {
// Verifica se o valor ainda não foi pulsado
if (!pulsou[index]) {
// Exibe o valor inicialmente
lcd.setCursor(coluna, linha);
lcd.print(valor); // Exibe o valor
// Pulsando o valor 3 vezes
for (int i = 0; i < 5; i++) {
lcd.setCursor(coluna, linha);
lcd.print(" "); // Limpa o valor
delay(500); // Aguarda 500ms para apagar
lcd.setCursor(coluna, linha);
lcd.print(valor); // Exibe o valor novamente
delay(500); // Aguarda 500ms para exibir
}
// Após o efeito, o valor fica fixo na tela
lcd.setCursor(coluna, linha);
lcd.print(valor); // Exibe o valor novamente
// Marca que o valor já foi pulsado
pulsou[index] = true;
}
}
void ajustarParametro(int coluna, int linha, int& valor, int min, int max) {
// Exibe continuamente o valor ajustável na tela
lcd.setCursor(coluna, linha);
lcd.print(" "); // Limpa a área do valor
lcd.setCursor(coluna, linha);
lcd.print(valor); // Mostra o valor atualizado
// Ajuste o valor com o encoder
if (encoderPos > max) {
encoderPos = max;
} else if (encoderPos < min) {
encoderPos = min;
}
valor = encoderPos; // Atualiza o valor ajustado
}