#include <LiquidCrystal_I2C.h>
#include <Stepper.h>
#include "HX711.h"
// Configuração do display LCD
LiquidCrystal_I2C lcd(0x27, 20, 4);
// Configuração do motor de passo
#define STEPS_PER_REV 200
Stepper motor(STEPS_PER_REV, 13, 12, 11, 10);
// Configuração do sensor HX711
#define DOUT_PIN A1
#define SCK_PIN A0
HX711 balanca;
// Pinos dos botões
int btnRed = 3;
int btnYellow = 4;
int btnEnter = 6;
int opcaoAtual = 0; // 0 = Rápido, 1 = Completo
int opcoesTotais = 2;
int estadoMenu = 0; // 0: Seleção de modo, 1: Seleção de temperatura...
int temperaturaSelecionada = 30;
int velocidadeCentrifugacao = 800;
int secagemAtiva = 0;
int tempoSecagem = 0;
void setup() {
delay(3000);
lcd.init();
lcd.backlight();
pinMode(btnRed, INPUT_PULLUP);
pinMode(btnYellow, INPUT_PULLUP);
pinMode(btnEnter, INPUT_PULLUP);
motor.setSpeed(60);
balanca.begin(DOUT_PIN, SCK_PIN);
balanca.set_scale(420.0);
updateLCD();
}
void loop() {
if (digitalRead(btnRed) == LOW) { //cima
if (estadoMenu == 0) {
opcaoAtual--; // Decrementa a opção atual
if (opcaoAtual < 0) {
opcaoAtual = 2 - 1;
}
updateLCD();
} else if (estadoMenu == 1) {
if (temperaturaSelecionada == 30) {
temperaturaSelecionada = 90;
} else {
temperaturaSelecionada -= 10;
}
updateLCD();
} else if (estadoMenu == 2) {
// 800 -> 1000 -> 1200 -> 1400
if (velocidadeCentrifugacao == 800) {
velocidadeCentrifugacao = 1400;
} else {
velocidadeCentrifugacao -= 200;
}
updateLCD();
} else if (estadoMenu == 3) {
secagemAtiva = (secagemAtiva == 0) ? 1 : 0;
updateLCD();
} else if (estadoMenu == 4) {
if (tempoSecagem == 10) {
tempoSecagem = 40;
} else {
tempoSecagem -= 10;
}
updateLCD();
}
delay(200);
}
if (digitalRead(btnYellow) == LOW) {
if (estadoMenu == 0) {
opcaoAtual++;
if (opcaoAtual >= 2) {
opcaoAtual = 0;
}
updateLCD();
} else if (estadoMenu == 1) {
if (temperaturaSelecionada == 90) {
temperaturaSelecionada = 30;
} else {
temperaturaSelecionada += 10;
}
updateLCD();
} else if (estadoMenu == 2) {
if (velocidadeCentrifugacao == 1400) {
velocidadeCentrifugacao = 800;
} else {
velocidadeCentrifugacao += 200;
}
updateLCD();
} else if (estadoMenu == 3) {
secagemAtiva = (secagemAtiva == 0) ? 1 : 0;
updateLCD();
} else if (estadoMenu == 4) {
if (tempoSecagem == 40) {
tempoSecagem = 10;
} else {
tempoSecagem += 10;
}
updateLCD();
}
delay(200);
}
if (digitalRead(btnEnter) == LOW) {
if (estadoMenu == 0) {
estadoMenu = 1;
updateLCD();
} else if (estadoMenu == 1) {
estadoMenu = 2;
updateLCD();
} else if (estadoMenu == 2) {
estadoMenu = 3;
updateLCD();
} else if (estadoMenu == 3) {
estadoMenu = 4;
updateLCD();
} else if (estadoMenu == 4) {
executeProgram(opcaoAtual);
delay(500);
estadoMenu = 0;
updateLCD();
}
delay(500);
}
}
void updateLCD() {
lcd.clear();
if (estadoMenu == 0) { // Menu de seleção de modo
lcd.setCursor(0, 0);
lcd.print("Selecione o modo:");
lcd.setCursor(0, 1);
lcd.print(opcaoAtual == 0 ? "> Rapido" : " Rapido ");
lcd.setCursor(0, 2);
lcd.print(opcaoAtual == 1 ? "> Completo" : " Completo ");
}
else if (estadoMenu == 1) { // Menu de seleção de temperatura
lcd.setCursor(0, 0);
lcd.print("Selecione Temp:");
lcd.setCursor(15, 0);
lcd.print(temperaturaSelecionada == 30 ? "> 30C" : " 30C");
lcd.setCursor(15, 1);
lcd.print(temperaturaSelecionada == 40 ? "> 40C" : " 40C");
lcd.setCursor(15, 2);
lcd.print(temperaturaSelecionada == 60 ? "> 60C" : " 60C");
lcd.setCursor(15, 3);
lcd.print(temperaturaSelecionada == 90 ? "> 90C" : " 90C");
}
else if (estadoMenu == 2) { // Menu de seleção de velocidade de centrifugação
lcd.setCursor(0, 0);
lcd.print("Selec Veloc:");
lcd.setCursor(10, 0);
lcd.print(velocidadeCentrifugacao == 800 ? "> 800 RPM" : " 800 RPM");
lcd.setCursor(10, 1);
lcd.print(velocidadeCentrifugacao == 1000 ? "> 1000 RPM" : " 1000 RPM");
lcd.setCursor(10, 2);
lcd.print(velocidadeCentrifugacao == 1200 ? "> 1200 RPM" : " 1200 RPM");
lcd.setCursor(10, 3);
lcd.print(velocidadeCentrifugacao == 1400 ? "> 1400 RPM" : " 1400 RPM");
}
if (opcaoAtual == 0) { // Menu de confirmação de secagem no modo rápido
if (estadoMenu == 3) {
lcd.setCursor(0, 0);
lcd.print("Ligar Secagem?");
lcd.setCursor(0, 1);
lcd.print(secagemAtiva == 0 ? "> Nao" : " Nao");
lcd.setCursor(0, 2);
lcd.print(secagemAtiva == 1 ? "> Sim" : " Sim");
}
if (estadoMenu == 4 && secagemAtiva == 1) {
lcd.setCursor(0, 0);
lcd.print("Tempo Secagem:");
lcd.setCursor(15, 0);
lcd.print(tempoSecagem == 10 ? "> 10s" : " 10s");
lcd.setCursor(15, 1);
lcd.print(tempoSecagem == 20 ? "> 20s" : " 20s");
lcd.setCursor(15, 2);
lcd.print(tempoSecagem == 30 ? "> 30s" : " 30s");
lcd.setCursor(15, 3);
lcd.print(tempoSecagem == 40 ? "> 40s" : " 40s");
}
} else if (opcaoAtual == 1 && estadoMenu == 4) { // Menu de seleção do tempo de secagem
lcd.setCursor(0, 0);
lcd.print("Tempo Secagem:");
lcd.setCursor(15, 0);
lcd.print(tempoSecagem == 10 ? "> 10s" : " 10s");
lcd.setCursor(15, 1);
lcd.print(tempoSecagem == 20 ? "> 20s" : " 20s");
lcd.setCursor(15, 2);
lcd.print(tempoSecagem == 30 ? "> 30s" : " 30s");
lcd.setCursor(15, 3);
lcd.print(tempoSecagem == 40 ? "> 40s" : " 40s");
}
}
void executeProgram(int option) {
int tempoTotal = 0;
float limitePeso = (option == 0) ? 5.0 : 10.0;
int temperatura = temperaturaSelecionada;
int velocidade = velocidadeCentrifugacao;
int resultadoPesagem = pesagem(limitePeso);
if (resultadoPesagem == -1) {
return;
}
lcd.setCursor(0, 0);
lcd.print("Temperatura:");
lcd.setCursor(13, 0);
lcd.print(temperaturaSelecionada);
lcd.print("C");
lcd.setCursor(0, 1);
lcd.print("Centrifug.:");
lcd.setCursor(12, 1);
lcd.print(velocidadeCentrifugacao);
lcd.print("RPM");
if (secagemAtiva == 1) {
lcd.setCursor(0, 2);
lcd.print("Secagem:");
lcd.setCursor(10, 2);
lcd.print(tempoSecagem);
lcd.print("s");
} else {
lcd.setCursor(0, 2);
lcd.print("Secagem:");
lcd.setCursor(10, 2);
lcd.print(" Desligado");
}
delay(5000);
updateLCD();
if (option == 0) { // Programa Rápido
tempoTotal = resultadoPesagem + injecaoAgua() + aquecimentoAgua(temperatura) + preLavagem() +
lavagem("Rapido") + escoamentoAgua() + injecaoAgua() +
enxague() + escoamentoAgua() + centrifugacao(velocidade);
if (secagemAtiva) {
tempoTotal += secagem(tempoSecagem);
}
} else if (option == 1) { // Programa Completo
tempoTotal = resultadoPesagem + injecaoAgua() + aquecimentoAgua(temperatura) +
preLavagem() + escoamentoAgua() + injecaoAgua() +
aquecimentoAgua(temperatura) + lavagem("Completo") + escoamentoAgua() +
injecaoAgua() + enxague() + escoamentoAgua() +
centrifugacao(velocidade) + secagem(tempoSecagem);
}
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Tempo Total:");
lcd.setCursor(13, 0);
lcd.print(tempoTotal);
lcd.print("s");
delay(10000);
updateLCD();
}
int pesagem(float limitePeso) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Pesagem...");
motor.setSpeed(40);
motor.step(STEPS_PER_REV * 2);
motor.step(-STEPS_PER_REV * 2);
float peso = balanca.get_units(10);
lcd.setCursor(0, 3);
lcd.print("Peso: ");
lcd.print(peso, 2);
lcd.print(" kg");
if (peso > limitePeso) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Peso excedido!");
delay(3000);
lcd.clear();
updateLCD();
return -1;
}
return 8;
}
int injecaoAgua() {
//8 segundos
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Injecao Agua");
motor.setSpeed(15);
motor.step(-STEPS_PER_REV * 2);
return 8;
}
int aquecimentoAgua(int temperatura) {
int tempoAquecimento = (temperatura / 10) * 5;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Aquecendo agua");
lcd.setCursor(0, 1);
lcd.print("Temp: ");
lcd.print(temperatura);
lcd.print(" C");
lcd.setCursor(0, 2);
lcd.print("Tempo aquec:");
lcd.print(tempoAquecimento);
delay(tempoAquecimento * 1000);
return tempoAquecimento;
}
int preLavagem() {
// Tempo total de pré-lavagem (20 segundos)
unsigned long TEMPO_TOTAL = 20000;
unsigned long TEMPO_ALTERNANCIA = 10000;
unsigned long inicio = millis();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Pre-Lavagem");
motor.setSpeed(60);
while (millis() - inicio < TEMPO_TOTAL) {
unsigned long tempoDecorrido = millis() - inicio;
if (tempoDecorrido < TEMPO_ALTERNANCIA) {
// Primeiros 10 segundos: Sentido horário
motor.step(STEPS_PER_REV * 2);
} else {
motor.step(-STEPS_PER_REV * 2);
}
}
return 20; // Retorna o tempo total de operação
}
int escoamentoAgua() {
//8 segundos
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Escoar Agua");
delay(8000);
return 8;
}
int lavagem(String modo) {
unsigned long TEMPO_TOTAL;
unsigned long TEMPO_ALTERNANCIA;
int velocidade;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Lavagem: ");
lcd.print(modo);
if (modo == "Rapido") {
TEMPO_TOTAL = 30000; // 30 segundos
TEMPO_ALTERNANCIA = 10000; // Alterna a cada 10 segundos
velocidade = 60; // 60 RPM
} else if (modo == "Completo") {
TEMPO_TOTAL = 60000;
TEMPO_ALTERNANCIA = 15000;
velocidade = 100;
}
motor.setSpeed(velocidade);
unsigned long inicio = millis();
while (millis() - inicio < TEMPO_TOTAL) {
unsigned long tempoDecorrido = millis() - inicio;
if ((tempoDecorrido / TEMPO_ALTERNANCIA) % 2 == 0) {
// Primeira metade do intervalo: Sentido horário
motor.step(STEPS_PER_REV * 2);
} else {
// Segunda metade do intervalo: Sentido anti-horário
motor.step(-STEPS_PER_REV * 2);
}
}
return TEMPO_TOTAL / 1000;
}
int enxague() {
// Tempo total enxague (20 segundos)
const unsigned long TEMPO_TOTAL = 20000;
const unsigned long TEMPO_ALTERNANCIA = 10000;
unsigned long inicio = millis();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Pre-Lavagem");
motor.setSpeed(60);
while (millis() - inicio < TEMPO_TOTAL) {
unsigned long tempoDecorrido = millis() - inicio;
if (tempoDecorrido < TEMPO_ALTERNANCIA) {
// Primeiros 10 segundos: Sentido horário
motor.step(STEPS_PER_REV * 2);
} else {
// Últimos 10 segundos: Sentido anti-horário
motor.step(-STEPS_PER_REV * 2);
}
}
return 20;
}
int centrifugacao(int rpm) {
// Configurações
const unsigned long TEMPO_TOTAL = 30000;
unsigned long inicio = millis();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Centrifugacao");
motor.setSpeed(rpm);
while (millis() - inicio < TEMPO_TOTAL) {
motor.step(STEPS_PER_REV * 2);
}
return TEMPO_TOTAL / 1000;
}
int secagem(int tempoSecagem) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Secagem ativa");
lcd.setCursor(0, 1);
lcd.print("Tempo: ");
lcd.print(tempoSecagem);
lcd.print("s");
motor.setSpeed(60);
unsigned long startTime = millis();
while (millis() - startTime < tempoSecagem * 1000) {
motor.step(STEPS_PER_REV);
}
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Secagem concluida");
delay(2000);
return tempoSecagem;
}