/*
Testador de Lavadoras Consul Brastemp
Criado Por Fabio Tec-2026
Ver 1.5 atual
* Melhorias para a proxima versão
- Trocar os delays por millis
*/
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// Configuração do display OLED
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
// LEDs
#define MA 2
#define MH 3
#define Bom 4
#define V2 5
#define V1 6
#define LED 10
// Botões
#define bt_OK 7
#define bt_voltar 8
#define bt_avan 9
// Buzzer
#define Buzz 11
// Porta e Níveis
#define porta 12
#define niv1 A0
#define niv2 A1
#define niv3 A2
// Variáveis de menu
int menuIndex = 0;
const int totalMenus = 9;
const int visibleMenus = 4;
int topIndex = 0;
// Variáveis para piscar LED
bool ledPiscar = false;
unsigned long previousMillis = 0;
const long interval = 500;
bool ledState = LOW;
// Controle da tela Nivel/PT
int nivelptIndex = 0; // 0 = Porta, 1 = Nivel
bool portaFechada = false;
int nivelSelecionado = 0; // 0 = Baixo, 1 = Medio, 2 = Auto
// Controle de tempo do botão OK
unsigned long okPressStart = 0;
// ---------- SETUP ----------
void setup() {
pinMode(MA, OUTPUT);
pinMode(MH, OUTPUT);
pinMode(Bom, OUTPUT);
pinMode(V2, OUTPUT);
pinMode(V1, OUTPUT);
pinMode(LED, OUTPUT);
pinMode(porta, OUTPUT);
pinMode(niv1, OUTPUT);
pinMode(niv2, OUTPUT);
pinMode(niv3, OUTPUT);
pinMode(bt_OK, INPUT_PULLUP);
pinMode(bt_voltar, INPUT_PULLUP);
pinMode(bt_avan, INPUT_PULLUP);
pinMode(Buzz, OUTPUT);
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
for(;;);
}
display.clearDisplay();
display.setTextColor(SSD1306_WHITE);
display.setTextSize(1);
display.setCursor(15, 20);
display.println("FABIO ELETRONICA");
display.setCursor(5, 35);
display.println("Auto Teste Lavadoras");
display.setCursor(48, 55);
display.println("V1.2");
display.display();
delay(1000);
}
// ---------- Função para piscar LED ----------
void piscarLed() {
if (ledPiscar) {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
ledState = !ledState;
digitalWrite(LED, ledState);
}
} else {
digitalWrite(LED, LOW);
}
}
// ---------- Função de Finalização ----------
void fimTeste() {
ledPiscar = false;
display.clearDisplay();
display.setCursor(30,30);
display.println("Fim do Teste");
display.display();
tone(Buzz, 1500, 500);
delay(1000);
}
// ---------- Funções de Teste ----------
void teste() {
ledPiscar = true;
display.clearDisplay();
display.setCursor(30,0);
display.println("Auto Teste");
display.setCursor(20,15);
display.println("Valvula de Agua");
display.display();
digitalWrite(V1, HIGH); delay(2000);
display.setCursor(20,25);
display.println("Valvula de Sabao");
display.display();
digitalWrite(V2, HIGH); delay(5000);
digitalWrite(V1, LOW); digitalWrite(V2, LOW);
display.setCursor(20,35);
display.println("Motor sentido H");
display.display();
digitalWrite(MH, HIGH); delay(1000); digitalWrite(MH, LOW);
display.setCursor(20,45);
display.println("Motor Sentido A");
display.display();
digitalWrite(MA, HIGH); delay(1000); digitalWrite(MA, LOW);
digitalWrite(MH, HIGH); delay(1000); digitalWrite(MH, LOW);
digitalWrite(MA, HIGH); delay(1000); digitalWrite(MA, LOW);
display.setCursor(20,55);
display.println("Bomba/Atuador");
display.display();
digitalWrite(Bom, HIGH); delay(7000);
digitalWrite(MH, HIGH); delay(15000);
digitalWrite(Bom, LOW); digitalWrite(MH, LOW);
fimTeste();
}
void lavar() {
display.clearDisplay();
display.setCursor(25,0);
display.println("Teste Lavar");
display.display();
for(int i=0; i<5; i++) {
display.setCursor(20,25);
display.println("Motor sentido H");
display.setCursor(20,35);
display.println("Motor sentido A");
display.display();
digitalWrite(MH, HIGH); delay(1000); digitalWrite(MH, LOW);
digitalWrite(MA, HIGH); delay(1000); digitalWrite(MA, LOW);
}
fimTeste();
}
void centrifugar() {
display.clearDisplay();
display.setCursor(12,0);
display.println("Teste Centrifugar");
display.display();
display.setCursor(20,25);
display.println("Atuador/Bomba");
display.display();
digitalWrite(Bom, HIGH); delay(8000);
display.setCursor(20,35);
display.println("Motor Sentido H");
display.display();
digitalWrite(MH, HIGH); delay(60000);
digitalWrite(Bom, LOW); digitalWrite(MH, LOW);
fimTeste();
}
void simulacao() {
display.clearDisplay();
display.setCursor(12,0);
display.println("Simular Lavagem");
display.display();
//----------------- Encher ---------------------------
digitalWrite(V1, HIGH); digitalWrite(V2, HIGH);
delay(600000);//600000
digitalWrite(V1, LOW); digitalWrite(V2, LOW);
//-------------- Começa a Lavar ----------------------
for(int i=0; i<150; i++) {//5 minutor
digitalWrite(MH, HIGH); delay(1000); digitalWrite(MH, LOW);
digitalWrite(MA, HIGH); delay(1000); digitalWrite(MA, LOW);
}
//---------- Começa a Centrifugação -------------------
digitalWrite(Bom, HIGH); delay(300000);// 3 minutos
//----------- Toque Curto -----------------
digitalWrite(MH, HIGH); delay(100);digitalWrite(MH, LOW);delay(2000);
digitalWrite(MH, HIGH); delay(200);digitalWrite(MH, LOW);delay(2000);
digitalWrite(MH, HIGH); delay(500);digitalWrite(MH, LOW);delay(2000);
digitalWrite(MH, HIGH); delay(1500);digitalWrite(MH, LOW);delay(1000);
//------- Roatacao Continua ----------------
digitalWrite(MH, HIGH); delay(300000);
digitalWrite(Bom, LOW);
digitalWrite(MH, LOW);
//----------------- Fim --------------------------
fimTeste();
}
// ---------- Função Nivel/PT ----------
void nivelpt() {
while(true) {
display.clearDisplay();
display.setCursor(20,0);
display.println("Tela Nivel/PT");
display.drawLine(0,10,127,10,SSD1306_WHITE);
// Porta
display.setCursor(0,20);
if(nivelptIndex == 0) display.print("> ");
else display.print(" ");
display.print("Porta: ");
display.println(portaFechada ? "Fechada" : "Aberta");
// Nivel
display.setCursor(0,35);
if(nivelptIndex == 1) display.print("> ");
else display.print(" ");
display.print("Nivel: ");
if(nivelSelecionado == 0) display.println("Baixo");
else if(nivelSelecionado == 1) display.println("Medio");
else display.println("Auto");
// Sair
display.setCursor(0,50);
if(nivelptIndex == 2) display.print("> ");
else display.print(" ");
display.println("Sair");
display.display();
// Avançar → próxima opção
if(digitalRead(bt_avan) == LOW) {
nivelptIndex++;
if(nivelptIndex > 2) nivelptIndex = 0;
tone(Buzz, 2000, 50);
delay(200);
}
// Voltar → opção anterior
if(digitalRead(bt_voltar) == LOW) {
nivelptIndex--;
if(nivelptIndex < 0) nivelptIndex = 2;
tone(Buzz, 1800, 50);
delay(200);
}
// OK → executa ação
if(digitalRead(bt_OK) == LOW) {
tone(Buzz, 1900, 50);
if(nivelptIndex == 0) {
// Alterna Porta
portaFechada = !portaFechada;
digitalWrite(porta, portaFechada ? HIGH : LOW);
} else if(nivelptIndex == 1) {
// Alterna Nivel
nivelSelecionado++;
if(nivelSelecionado > 2) nivelSelecionado = 0;
digitalWrite(niv1, LOW);
digitalWrite(niv2, LOW);
digitalWrite(niv3, LOW);
if(nivelSelecionado == 0) digitalWrite(niv1, HIGH);
else if(nivelSelecionado == 1) digitalWrite(niv2, HIGH);
else digitalWrite(niv3, HIGH);
} else if(nivelptIndex == 2) {
// Opção Sair → volta ao menu inicial
while(digitalRead(bt_OK) == LOW) {
delay(10);
}
return;
}
delay(300);
}
}
}
// ---------- FUNÇÃO PARA DESENHAR MENU ----------
void drawMenu() {
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(20,0);
display.println("Teste Lavadora");
display.drawLine(0,10,127,10,SSD1306_WHITE);
for(int i=0; i<visibleMenus; i++) {
int optionIndex = topIndex + i;
if(optionIndex >= totalMenus) break;
display.setCursor(0, 15 + i*10);
if(optionIndex == menuIndex) {
display.print("> ");
} else {
display.print(" ");
}
switch(optionIndex) {
case 0: display.println("Teste Rapido"); break;
case 1: display.println("Lavar"); break;
case 2: display.println("Centrifugar"); break;
case 3: display.println("Simular Lavagem"); break;
case 4: display.println("Ligar Valvula 1"); break;
case 5: display.println("Ligar Valvula 2"); break;
case 6: display.println("Ligar Bomba"); break;
case 7: display.println("Ligar Motor H"); break;
case 8: display.println("Ligar Motor A"); break;
}
}
display.display();
}
// ---------- FUNÇÃO PARA EXECUTAR AÇÃO ----------
void executeAction(int index) {
switch(index) {
case 0: teste(); break;
case 1: lavar(); break;
case 2: centrifugar(); break;
case 3: simulacao(); break;
/* Modo manual: só liga enquanto botão OK estiver pressionado
case 4: while(digitalRead(bt_OK) == LOW) { digitalWrite(V1, HIGH); } digitalWrite(V1, LOW); break;
case 5: while(digitalRead(bt_OK) == LOW) { digitalWrite(V2, HIGH); } digitalWrite(V2, LOW); break;
case 6: while(digitalRead(bt_OK) == LOW) { digitalWrite(Bom, HIGH); } digitalWrite(Bom, LOW); break;
case 7: while(digitalRead(bt_OK) == LOW) { digitalWrite(MH, HIGH); } digitalWrite(MH, LOW); break;
case 8: while(digitalRead(bt_OK) == LOW) { digitalWrite(MA, HIGH); } digitalWrite(MA, LOW); break;
*/
}
}
// Variável global para controle
bool okPressed = false;
//------------------ Loop Principal -------------
void loop() {
drawMenu();
piscarLed();
// Botão Avançar
if(digitalRead(bt_avan) == LOW) {
menuIndex++;
tone(Buzz, 2000, 50);
if(menuIndex >= totalMenus) { menuIndex = 0; topIndex = 0; }
if(menuIndex >= topIndex + visibleMenus) {
topIndex++;
if(topIndex > totalMenus - visibleMenus) topIndex = totalMenus - visibleMenus;
}
delay(200);
}
// Botão Voltar
if(digitalRead(bt_voltar) == LOW) {
menuIndex--;
tone(Buzz, 2050, 50);
if(menuIndex < 0) { menuIndex = totalMenus-1; topIndex = totalMenus - visibleMenus; }
if(menuIndex < topIndex) {
topIndex--;
if(topIndex < 0) topIndex = 0;
}
delay(200);
}
// --- Tratamento especial para cases 4–8 (modo manual) ---
if(menuIndex >= 4 && menuIndex <= 8) {
if(digitalRead(bt_OK) == LOW) {
switch(menuIndex) {
case 4: digitalWrite(V1, HIGH); break;
case 5: digitalWrite(V2, HIGH); break;
case 6: digitalWrite(Bom, HIGH); break;
case 7: digitalWrite(MH, HIGH); break;
case 8: digitalWrite(MA, HIGH); break;
}
} else {
// Soltou o botão → desliga
digitalWrite(V1, LOW);
digitalWrite(V2, LOW);
digitalWrite(Bom, LOW);
digitalWrite(MH, LOW);
digitalWrite(MA, LOW);
}
return; // não processa clique curto/long press aqui
}
// --- Botão OK com clique curto ou longo (para cases 0–3) ---
if (digitalRead(bt_OK) == LOW && !okPressed) {
okPressStart = millis();
okPressed = true;
}
if (digitalRead(bt_OK) == LOW && okPressed) {
unsigned long pressDuration = millis() - okPressStart;
if (pressDuration >= 2000) {
nivelpt(); // Clique longo → entra direto na tela Nivel/PT
okPressed = false;
}
}
if (digitalRead(bt_OK) == HIGH && okPressed) {
unsigned long pressDuration = millis() - okPressStart;
okPressed = false;
if (pressDuration < 2000) {
tone(Buzz, 1900, 50);
executeAction(menuIndex); // Clique curto → executa ação normal
}
}
}