#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Servo.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
Servo meuServo;
const int potPin = A0;
const int pinosChaves[] = {4, 5, 6, 7, 8};
const int valoresNivel[] = {10, 30, 50, 75, 90};
const int servoPin = 3;
int volumeAtualEfetivo = 10;
bool subindoAutomatico = false;
bool emPausa = false;
unsigned long tempoPausa = 0;
unsigned long ultimoPasso = 0;
const int capacidadeTotal = 10000;
void setup() {
meuServo.attach(servoPin);
lcd.init();
lcd.backlight();
for (int i = 0; i < 5; i++) {
pinMode(pinosChaves[i], INPUT_PULLUP);
}
}
void loop() {
// 1. IDENTIFICA O LIMITE DAS CHAVES
int limiteChaves = 10;
bool erroSequencia = false;
for (int i = 0; i < 5; i++) {
if (digitalRead(pinosChaves[i]) == LOW) {
if (i > 0 && digitalRead(pinosChaves[i-1]) == HIGH) erroSequencia = true;
limiteChaves = valoresNivel[i];
}
}
int leituraPot = analogRead(potPin);
int percPot = map(leituraPot, 0, 1023, 0, 100);
// 2. LÓGICA DE SUBIDA COM PARADAS NOS NÍVEIS
if (!erroSequencia) {
// Gatilho inicial: Sincronizar pot para começar
if (limiteChaves > volumeAtualEfetivo && !subindoAutomatico) {
lcd.setCursor(0, 0);
lcd.print("SYNC PARA SUBIR ");
if (abs(percPot - volumeAtualEfetivo) <= 2) {
subindoAutomatico = true;
}
}
else if (subindoAutomatico) {
// Verifica se o volume atual coincide com algum nível da tabela (exceto o final)
bool chegouNoPatamar = false;
for (int i = 0; i < 5; i++) {
if (volumeAtualEfetivo == valoresNivel[i] && volumeAtualEfetivo < limiteChaves) {
chegouNoPatamar = true;
break;
}
}
if (chegouNoPatamar && !emPausa) {
emPausa = true;
tempoPausa = millis();
}
if (emPausa) {
lcd.setCursor(0, 0);
lcd.print("PAUSA NO NIVEL ");
if (millis() - tempoPausa > 2000) { // Pausa de 2 segundos
emPausa = false;
volumeAtualEfetivo++; // Sai do valor exato do nível para continuar
}
} else {
lcd.setCursor(0, 0);
lcd.print("SUBINDO AUTO... ");
if (millis() - ultimoPasso > 80) { // Velocidade da subida
volumeAtualEfetivo++;
ultimoPasso = millis();
}
}
if (volumeAtualEfetivo >= limiteChaves) {
volumeAtualEfetivo = limiteChaves;
subindoAutomatico = false;
emPausa = false;
}
}
else {
// Modo Manual / Estabilizado
volumeAtualEfetivo = percPot;
if (volumeAtualEfetivo < 10) volumeAtualEfetivo = 10;
if (volumeAtualEfetivo > limiteChaves) volumeAtualEfetivo = limiteChaves;
lcd.setCursor(0, 0);
lcd.print("LIMITE: ");
lcd.print(limiteChaves);
lcd.print("% ");
}
} else {
lcd.setCursor(0, 0);
lcd.print("ERRO: SEQUENCIA ");
}
// 3. ATUALIZAÇÃO FÍSICA E DISPLAY
int angulo = map(volumeAtualEfetivo, 10, 90, 0, 180);
meuServo.write(angulo);
long litros = (long)volumeAtualEfetivo * capacidadeTotal / 100;
lcd.setCursor(0, 1);
lcd.print("V:");
lcd.print(litros);
lcd.print("L (");
lcd.print(volumeAtualEfetivo);
lcd.print("%) ");
delay(20);
}