#include <Stepper.h>
#include <LiquidCrystal.h>
#include <Keypad.h>
#include <HX711.h>
// Motor de Passo
const int stepsPerRevolution = 200;
Stepper motor(stepsPerRevolution, 39, 40, 41, 42);
// LCD
LiquidCrystal lcd(12, 11, 10, 9, 8, 7);
// Keypad
char keys[4][3] = {
{'1', '2', '3'}, // 1: Pausar | 2: Início | 3: Cancelar
{'4', '5', '6'}, // 4: Rápido | 5: Completo | 6: Resetar
{'7', '8', '9'}, // 7: Centrifugação | 8: Secagem | 9: Temperatura
{'*', '0', '#'} // *: Esquerda | 0: Confirmação | #: Direita
};
byte rowPins[4] = {37, 36, 35, 34};
byte colPins[3] = {33, 26, 21};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, 4, 3);
// Load Cell
#define DT_loadCell 17
#define SCK_loadCell 16
HX711 loadCell;
// --- Variáveis Globais ---
float pesoAtual = 0.0;
int temperaturaAgua = -1;
int velocidadeCentrifugacao = 800;
bool isCompleteProgram = false;
bool water = false;
int tempoTotal = 0;
int tempo = 0;
int tempoPesagem = 8;
int tempoInjecaoAgua = 8;
int tempoAquecimentoAgua = (temperaturaAgua / 10) * 5;
int tempoPreLavagem = 20;
int tempoEscoamentoAgua = 8;
int tempoLavacao = -1; //isCompleteProgram ? 60 : 30
int tempoEnxague = 20;
int tempoCentrifuga = 30;
int tempoSecagem = -1;
// --- Funções Auxiliares ---
void showMessage(String msg, int linha = 0) {
lcd.clear();
lcd.setCursor(0, linha);
lcd.print(msg);
}
void showTime(int tempoRestante, int linha = 2) {
lcd.setCursor(0, linha);
lcd.print("Tempo: ");
lcd.setCursor(7, linha);
lcd.print(" ");
lcd.setCursor(7, linha);
lcd.print(tempoRestante);
lcd.print("s");
}
void showTotalTime() {
isCompleteProgram ? tempoTotal = tempoPesagem + (3 * tempoInjecaoAgua) + (2 * tempoAquecimentoAgua) +
tempoPreLavagem + (3 * tempoEscoamentoAgua) + tempoLavacao + tempoEnxague +
tempoCentrifuga + tempoSecagem - tempo
: tempoTotal = tempoPesagem + (2 * tempoInjecaoAgua) + tempoAquecimentoAgua +
tempoLavacao + (2 * tempoEscoamentoAgua) + tempoEnxague +
tempoCentrifuga + tempoSecagem - tempo;
lcd.setCursor(0, 3);
lcd.print("Tempo Estimado: ");
lcd.setCursor(16, 3);
lcd.print(" ");
lcd.setCursor(16, 3);
lcd.print(tempoTotal);
lcd.print("s");
}
void reset() {
pesoAtual = 0.0;
temperaturaAgua = -1;
velocidadeCentrifugacao = 800;
tempoSecagem = -1;
tempoLavacao = -1;
showMessage("Resetando", 1);
delay(1000);
lcd.print(".");
delay(1000);
lcd.print(".");
delay(1000);
lcd.print(".");
delay(500);
start();
}
void getPeso() {
pesoAtual = loadCell.get_units() / 420;
}
void setTemperature() {
int temperaturas[] = {0, 30, 40, 60, 90}; // 0 para "fria"
int index = isCompleteProgram ? 2 : 1;
showMessage("Ajuste a Temp:");
lcd.setCursor(0, 1);
lcd.print("Temp: ");
if (index == 0) {
lcd.print("Fria");
} else {
lcd.print(temperaturas[index]);
lcd.print((char)223);
lcd.print("C");
}
while (true) {
char key = keypad.getKey();
if (key == '*') {
if (index > 0) index--;
} else if (key == '#') {
if (index < 4) index++;
} else if (key == '0') {
temperaturaAgua = temperaturas[index];
tempoAquecimentoAgua = (temperaturaAgua / 10) * 5;
break;
}
lcd.setCursor(6, 1);
lcd.print(" ");
lcd.setCursor(6, 1);
if (index == 0) {
lcd.print("Fria");
} else {
lcd.print(temperaturas[index]);
lcd.print((char)223);
lcd.print("C");
}
delay(1);
}
start();
}
void setCentrifugeSpeed() {
int speed[] = {800, 1000, 1200, 1400};
int index = 0;
showMessage("Ajuste a Vel:");
lcd.setCursor(0, 1);
lcd.print("Vel: ");
lcd.print(speed[index]);
lcd.print(" RPM");
while (true) {
char key = keypad.getKey();
if (key == '*') {
if (index > 0) index--;
} else if (key == '#') {
if (index < 3) index++;
} else if (key == '0') {
velocidadeCentrifugacao = speed[index];
break;
}
lcd.setCursor(5, 1);
lcd.print(" ");
lcd.setCursor(5, 1);
lcd.print(speed[index]);
lcd.print(" RPM");
delay(1);
}
start();
}
void setDryingTime() {
int tempos[] = {0, 10, 20, 30, 40};
int index = isCompleteProgram ? 3 : 0;
showMessage("Ajuste o Tempo:");
lcd.setCursor(0, 1);
lcd.print("Tempo: ");
lcd.print(tempos[index]);
lcd.print("s");
while (true) {
char key = keypad.getKey();
if (key == '*') {
if (index > 0) index--;
} else if (key == '#') {
if (index < 4) index++;
} else if (key == '0') {
tempoSecagem = tempos[index];
break;
}
lcd.setCursor(7, 1);
lcd.print(" ");
lcd.setCursor(7, 1);
lcd.print(tempos[index]);
lcd.print("s");
delay(1);
}
start();
}
// --- Lista de Operações ---
bool pesagem() {
int tempoRestante = tempoPesagem;
int rpm = 30;
motor.setSpeed(rpm);
water = false;
getPeso();
showMessage("Pesando roupas...");
showTime(tempoRestante);
showTotalTime();
bool spin = true;
unsigned long inicio = millis();
int lastSpin = tempoRestante;
while (tempoRestante > 0) {
pausar();
cancelar();
unsigned long agora = millis();
unsigned long intervalo = agora - inicio;
if (intervalo >= 1000) {
tempoRestante--;
tempo++;
showTime(tempoRestante);
showTotalTime();
inicio = agora;
if (tempoRestante > 0 && tempoRestante % 4 == 0 && tempoRestante != lastSpin) {
spin = !spin;
lastSpin = tempoRestante;
}
}
int passosPorSegundo = (rpm * stepsPerRevolution) / 60;
spin ? motor.step(passosPorSegundo / 10) : motor.step(-passosPorSegundo / 10);
delay(1);
}
showMessage("Pesagem concluida!");
if (isCompleteProgram) {
if (pesoAtual > 10.0) {
showMessage("Peso excede 10kg!");
delay(2000);
return false;
}
} else {
if (pesoAtual > 5.0) {
showMessage("Peso excede 5kg!");
delay(2000);
return false;
}
}
return true;
}
void injecaoAgua() {
int tempoRestante = tempoInjecaoAgua;
int rpm = 20;
motor.setSpeed(rpm);
water = true;
showMessage("Injetando Agua...");
showTime(tempoRestante);
showTotalTime();
unsigned long inicio = millis();
while (tempoRestante > 0) {
pausar();
cancelar();
unsigned long agora = millis();
unsigned long intervalo = agora - inicio;
if (intervalo >= 1000) {
tempoRestante--;
tempo++;
showTime(tempoRestante);
showTotalTime();
inicio = agora;
}
int passosPorSegundo = (rpm * stepsPerRevolution) / 60;
motor.step(passosPorSegundo / 10);
delay(1);
}
showMessage("Injecao concluida!");
}
void aquecimentoAgua() {
int tempoRestante = tempoAquecimentoAgua;
int rpm = 60;
motor.setSpeed(rpm);
water = true;
showMessage("Aquecendo Agua...");
showTime(tempoRestante);
showTotalTime();
unsigned long inicio = millis();
while (tempoRestante > 0) {
pausar();
cancelar();
unsigned long agora = millis();
unsigned long intervalo = agora - inicio;
if (intervalo >= 1000) {
tempoRestante--;
tempo++;
showTime(tempoRestante);
showTotalTime();
inicio = agora;
}
int passosPorSegundo = (rpm * stepsPerRevolution) / 60;
motor.step(passosPorSegundo / 10);
delay(1);
}
showMessage("Aquecimento Concluido!");
}
void preLavagem() {
int tempoRestante = tempoPreLavagem;
float rpm = 60;
motor.setSpeed(rpm);
water = true;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Realizando");
lcd.setCursor(0, 1);
lcd.print("Pre-Lavagem...");
showTime(tempoRestante);
showTotalTime();
bool spin = true;
unsigned long inicio = millis();
int lastSpin = tempoRestante;
while (tempoRestante > 0) {
pausar();
cancelar();
unsigned long agora = millis();
unsigned long intervalo = agora - inicio;
if (intervalo >= 1000) {
tempoRestante--;
tempo++;
showTime(tempoRestante);
showTotalTime();
inicio = agora;
if (tempoRestante > 0 && tempoRestante % 10 == 0 && tempoRestante != lastSpin) {
spin = !spin;
lastSpin = tempoRestante;
}
}
int passosPorSegundo = (rpm * stepsPerRevolution) / 60;
spin ? motor.step(passosPorSegundo / 10) : motor.step(-passosPorSegundo / 10);
delay(1);
}
showMessage("Pre-Lavagem Concluida!");
}
void escoamentoAgua(bool cancel = false) {
int tempoRestante = tempoEscoamentoAgua;
water = true;
showMessage("Escoando Agua...");
showTime(tempoRestante);
if (!cancel) {
showTotalTime();
}
unsigned long inicio = millis();
while (tempoRestante > 0) {
pausar();
cancelar();
unsigned long agora = millis();
unsigned long intervalo = agora - inicio;
if (intervalo >= 1000) {
tempoRestante--;
tempo++;
showTime(tempoRestante);
if (!cancel) {
showTotalTime();
}
inicio = agora;
}
delay(1);
}
water = false;
showMessage("Escoamento Concluido!");
}
void lavacao() {
int tempoRestante = tempoLavacao;
float rpm = isCompleteProgram ? 100 : 60;
motor.setSpeed(rpm);
water = true;
showMessage("Lavando...");
showTime(tempoRestante);
showTotalTime();
bool spin = true;
unsigned long inicio = millis();
int lastSpin = tempoRestante;
while (tempoRestante > 0) {
pausar();
cancelar();
unsigned long agora = millis();
unsigned long intervalo = agora - inicio;
if (intervalo >= 1000) {
tempoRestante--;
tempo++;
showTime(tempoRestante);
showTotalTime();
inicio = agora;
bool inverter = isCompleteProgram ? tempoRestante % 15 == 0 : tempoRestante % 10 == 0;
if (tempoRestante > 0 && inverter && tempoRestante != lastSpin) {
spin = !spin;
lastSpin = tempoRestante;
}
}
int passosPorSegundo = (rpm * stepsPerRevolution) / 60;
spin ? motor.step(passosPorSegundo / 10) : motor.step(-passosPorSegundo / 10);
delay(1);
}
showMessage("Lavagem Concluida!");
}
void enxague() {
int tempoRestante = tempoEnxague;
int rpm = 60;
motor.setSpeed(rpm);
water = true;
showMessage("Enxaguando...");
showTime(tempoRestante);
showTotalTime();
bool spin = true;
unsigned long inicio = millis();
int lastSpin = tempoRestante;
while (tempoRestante > 0) {
pausar();
cancelar();
unsigned long agora = millis();
unsigned long intervalo = agora - inicio;
if (intervalo >= 1000) {
tempoRestante--;
tempo++;
showTime(tempoRestante);
showTotalTime();
inicio = agora;
if (tempoRestante > 0 && tempoRestante % 10 == 0 && tempoRestante != lastSpin) {
spin = !spin;
lastSpin = tempoRestante;
}
}
int passosPorSegundo = (rpm * stepsPerRevolution) / 60;
spin ? motor.step(passosPorSegundo / 10) : motor.step(-passosPorSegundo / 10);
delay(1);
}
showMessage("Enxague Concluido!");
}
void centrifuga() {
int tempoRestante = tempoCentrifuga;
motor.setSpeed(velocidadeCentrifugacao);
water = false;
showMessage("Centrifugando...");
showTime(tempoRestante);
showTotalTime();
unsigned long inicio = millis();
while (tempoRestante > 0) {
pausar();
cancelar();
unsigned long agora = millis();
unsigned long intervalo = agora - inicio;
if (intervalo >= 1000) {
tempoRestante--;
tempo++;
showTime(tempoRestante);
showTotalTime();
inicio = agora;
}
int passosPorSegundo = (velocidadeCentrifugacao * stepsPerRevolution) / 60;
motor.step(passosPorSegundo / 10);
delay(1);
}
showMessage("Centrifugacao Concluida!");
}
void secagem() {
int tempoRestante = tempoSecagem;
int rpm = 60;
motor.setSpeed(rpm);
water = false;
showMessage("Secando...");
showTime(tempoRestante);
showTotalTime();
unsigned long inicio = millis();
while (tempoRestante > 0) {
pausar();
cancelar();
unsigned long agora = millis();
unsigned long intervalo = agora - inicio;
if (intervalo >= 1000) {
tempoRestante--;
tempo++;
showTime(tempoRestante);
showTotalTime();
inicio = agora;
}
int passosPorSegundo = (rpm * stepsPerRevolution) / 60;
motor.step(passosPorSegundo / 10);
delay(1);
}
showMessage("Secagem Concluida!");
}
// --- Programas ---
void programaRapido() {
isCompleteProgram = false;
if (temperaturaAgua < 0) {
temperaturaAgua = 30;
}
if (tempoLavacao < 0) {
tempoLavacao = 30;
}
if (tempoSecagem < 0) {
tempoSecagem = 0;
}
if (pesagem()) {
injecaoAgua();
aquecimentoAgua();
lavacao();
escoamentoAgua(false);
injecaoAgua();
enxague();
escoamentoAgua(false);
centrifuga();
secagem();
tempo = 0;
temperaturaAgua = -1;
tempoLavacao = -1;
tempoSecagem = -1;
showMessage(" Concluido :)", 1);
delay(2000);
}
start();
}
void programaCompleto() {
isCompleteProgram = true;
if (temperaturaAgua < 0) {
temperaturaAgua = 40;
}
if (tempoLavacao < 0) {
tempoLavacao = 60;
}
if (tempoSecagem < 0) {
tempoSecagem = 30;
}
if (pesagem()) {
injecaoAgua();
aquecimentoAgua();
preLavagem();
escoamentoAgua(false);
injecaoAgua();
aquecimentoAgua();
lavacao();
escoamentoAgua(false);
injecaoAgua();
enxague();
escoamentoAgua(false);
centrifuga();
secagem();
tempo = 0;
temperaturaAgua = -1;
tempoLavacao = -1;
tempoSecagem = -1;
showMessage(" Concluido :)", 1);
delay(2000);
}
start();
}
void start() {
showMessage("Selecione uma");
lcd.setCursor(0, 1);
lcd.print("opcao...");
}
void pausar() {
char key = keypad.getKey();
if (key) {
if (key == '1') {
lcd.setCursor(19, 0);
lcd.print("P");
while (true) {
char key = keypad.getKey();
if (key) {
if (key == '2') {
lcd.setCursor(19, 0);
lcd.print(" ");
break;
}
}
delay(1);
}
}
}
}
void cancelar() {
char key = keypad.getKey();
if (key) {
if (key == '3') {
showMessage("Cancelando", 1);
delay(1000);
lcd.print(".");
delay(1000);
lcd.print(".");
delay(1000);
lcd.print(".");
delay(500);
if (water) {
escoamentoAgua(true);
}
start();
}
}
}
// --- Configuração e Loop Principal ---
void setup() {
lcd.begin(20, 4);
loadCell.begin(DT_loadCell, SCK_loadCell);
showMessage("Bem Vindo!");
delay(2000);
start();
}
// 1: Pausar | 2: Início | 3: Cancelar
// 4: Rápido | 5: Completo | 6: Resetar
// 7: Centrifugação | 8: Secagem | 9: Temperatura
// *: Esquerda | 0: Confirmação | #: Direita
void loop() {
char key = keypad.getKey();
if (key) {
switch (key) {
case '1':
lcd.setCursor(19, 0);
lcd.print("P");
while (true) {
char key = keypad.getKey();
if (key) {
if (key == '2') {
lcd.setCursor(19, 0);
lcd.print(" ");
break;
}
}
delay(1);
}
break;
case '2':
tempo = 0;
isCompleteProgram ? programaCompleto() : programaRapido();
break;
case '3':
water = true;
showMessage("Cancelando", 1);
delay(1000);
lcd.print(".");
delay(1000);
lcd.print(".");
delay(1000);
lcd.print(".");
delay(500);
if (water) {
escoamentoAgua(true);
}
start();
break;
case '4':
isCompleteProgram = false;
if (temperaturaAgua < 0) {
temperaturaAgua = 30;
}
if (tempoLavacao < 0) {
tempoLavacao = 30;
}
if (tempoSecagem < 0) {
tempoSecagem = 0;
}
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" Programa Rapido");
showTotalTime();
lcd.setCursor(2, 2);
lcd.print(" Aperte Start!");
break;
case '5':
isCompleteProgram = true;
if (temperaturaAgua < 0) {
temperaturaAgua = 40;
}
if (tempoLavacao < 0) {
tempoLavacao = 60;
}
if (tempoSecagem < 0) {
tempoSecagem = 30;
}
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" Programa Completo");
showTotalTime();
lcd.setCursor(2, 2);
lcd.print(" Aperte Start!");
break;
case '6':
reset();
break;
case '7':
setCentrifugeSpeed();
break;
case '8':
setDryingTime();
break;
case '9':
setTemperature();
break;
}
}
delay(1);
}