#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
HX711 balanca;
// Pinos dos botões
const int btnRed = 4; // Botão vermelho (esquerda)
const int btnYellow = 5; // Botão amarelo (direita)
const int btnEnter = 6; // Botão Enter
// Variáveis para controle
int currentOption = 0; // 0 = Rápido, 1 = Completo
const int totalOptions = 2;
void setup() {
// Configuração inicial do LCD
lcd.init();
lcd.backlight();
// Configuração inicial dos botões
pinMode(btnRed, INPUT_PULLUP);
pinMode(btnYellow, INPUT_PULLUP);
pinMode(btnEnter, INPUT_PULLUP);
// Configuração do motor de passo
motor.setSpeed(60); // Velocidade inicial do motor em RPM
// Configuração da balança
balanca.begin(A1, A0);
// Exibe as opções iniciais no LCD
updateLCD();
}
void loop() {
// Navegação entre opções
if (digitalRead(btnRed) == LOW) {
currentOption = (currentOption - 1 + totalOptions) % totalOptions;
updateLCD();
delay(200);
}
if (digitalRead(btnYellow) == LOW) {
currentOption = (currentOption + 1) % totalOptions;
updateLCD();
delay(200);
}
// Seleção de opção
if (digitalRead(btnEnter) == LOW) {
executeProgram(currentOption);
delay(500);
}
}
void updateLCD() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Selecione o modo:");
lcd.setCursor(0, 1);
lcd.print(currentOption == 0 ? "> Rapido" : " Rapido ");
lcd.setCursor(0, 2);
lcd.print(currentOption == 1 ? "> Completo" : " Completo ");
}
void executeProgram(int option) {
int totalTime = 0;
if (option == 0) { // Programa Rápido
totalTime = pesagem() + injecaoAgua() + aquecimentoAgua() + preLavagem() +
lavagem("Rapido") + escoamentoAgua() + injecaoAgua() +
enxague() + escoamentoAgua() + centrifugacao(800);
} else if (option == 1) { // Programa Completo
totalTime = pesagem() + injecaoAgua() + aquecimentoAgua() +
preLavagem() + escoamentoAgua() + injecaoAgua() +
aquecimentoAgua() + lavagem("Completo") + escoamentoAgua() +
injecaoAgua() + enxague() + escoamentoAgua() +
centrifugacao(800) + secagem();
}
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Tempo Total:");
lcd.setCursor(0, 1);
lcd.print(totalTime);
lcd.print(" segundos");
delay(3000); // Exibe o tempo total antes de retornar à seleção
updateLCD();
}
int pesagem() {
const float LIMITE_PESO = 5.0; // Limite máximo em kg
const int CALIBRACAO = 2000; // Fator de calibração, ajustar conforme necessário
float peso = 0.0; // Variável para armazenar o peso medido
// Configuração do display
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Pesagem");
// Rotação do motor
motor.setSpeed(30);
motor.step(STEPS_PER_REV * 2); // 2 voltas para a direita
motor.step(-STEPS_PER_REV * 2); // 2 voltas para a esquerda
// Configurar o módulo HX711
balanca.begin(A1, A0);
balanca.set_scale(CALIBRACAO);
balanca.tare(); // Zerar a balança
// Realizar a leitura do peso
peso = balanca.get_units(10); // Média de 10 leituras para maior precisão
Serial.println(peso);
lcd.setCursor(0, 1);
lcd.print("Peso: ");
lcd.print(peso);
lcd.print(" kg");
delay(1000);
// Verificar se o peso excede o limite
if (peso > LIMITE_PESO) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Peso excedido!");
delay(5000); // Exibir mensagem por 5 segundos
return -1; // Retornar código de erro
}
return 8; // Tempo total da função em segundos
}
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() {
//5 segundos para cada 10 graus
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Aquec. Agua");
//AQUECIMENTO
delay(1000);
return 1;
}
int preLavagem() {
// Tempo total de pré-lavagem (20 segundos)
const unsigned long TEMPO_TOTAL = 20000;
const unsigned long TEMPO_ALTERNANCIA = 10000; // Alterna o sentido a cada 10 segundos
unsigned long inicio = millis(); // Marca o tempo inicial
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Pre-Lavagem");
// Configura a velocidade do motor
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; // 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);
// Configurações para os modos
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; // 60 segundos
TEMPO_ALTERNANCIA = 15000; // Alterna a cada 15 segundos
velocidade = 100; // 100 RPM
}
// Configura a velocidade do motor
motor.setSpeed(velocidade);
// Marca o tempo inicial
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; // Retorna o tempo total de operação em segundos
}
int enxague() {
// Tempo total enxague (20 segundos)
const unsigned long TEMPO_TOTAL = 20000;
const unsigned long TEMPO_ALTERNANCIA = 10000; // Alterna o sentido a cada 10 segundos
unsigned long inicio = millis(); // Marca o tempo inicial
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Pre-Lavagem");
// Configura a velocidade do motor
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; // Retorna o tempo total de operação
}
int centrifugacao(int rpm) {
// Configurações
const unsigned long TEMPO_TOTAL = 30000; // 30 segundos
unsigned long inicio = millis(); // Marca o tempo inicial
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Centrifugacao");
// Configura a velocidade do motor
motor.setSpeed(rpm);
// Executa a centrifugação pelo tempo total
while (millis() - inicio < TEMPO_TOTAL) {
motor.step(STEPS_PER_REV * 2); // Faz o motor rodar continuamente
}
return TEMPO_TOTAL / 1000; // Retorna o tempo total em segundos
}
int secagem() {
//usuario seleciona segundos
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Secagem");
//selecionado pelo usuário
//motor gira apenas para a direita na velocidade de 60RPM
//deve ter realizado a centrifugação e escoamento da água antes
motor.setSpeed(60);
delay(1000);
return 5;
}