#include <LiquidCrystal_I2C.h>
#define TRIG_CIMA 4
#define ECHO_CIMA 5
#define TRIG_BAIXO 18
#define ECHO_BAIXO 19
#define PINO_RELE 15
// Inicializa o display no endereço I2C padrão 0x27 com 16 colunas e 2 linhas
LiquidCrystal_I2C lcd(0x27, 16, 2);
const int DISTANCIA_GATILHO = 100;
const unsigned long TEMPO_MAXIMO_MOVIMENTO = 3000;
unsigned long tempoPrimeiraDeteccao = 0;
int estadoMovimento = 0;
long lerDistancia(int pinoTrig, int pinoEcho) {
digitalWrite(pinoTrig, LOW);
delayMicroseconds(2);
digitalWrite(pinoTrig, HIGH);
delayMicroseconds(10);
digitalWrite(pinoTrig, LOW);
long duracao = pulseIn(pinoEcho, HIGH, 30000);
if (duracao == 0) {
return 999;
}
return duracao * 0.034 / 2;
}
// Função auxiliar para simplificar a escrita no display
void atualizarDisplay(String linha1, String linha2) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(linha1);
lcd.setCursor(0, 1);
lcd.print(linha2);
}
void setup() {
// Configuração do Display
lcd.init();
lcd.backlight();
atualizarDisplay("Sistema Pronto", "Aguardando...");
pinMode(TRIG_CIMA, OUTPUT);
pinMode(ECHO_CIMA, INPUT);
pinMode(TRIG_BAIXO, OUTPUT);
pinMode(ECHO_BAIXO, INPUT);
pinMode(PINO_RELE, OUTPUT);
digitalWrite(PINO_RELE, LOW);
}
void loop() {
long distCima = lerDistancia(TRIG_CIMA, ECHO_CIMA);
delay(10);
long distBaixo = lerDistancia(TRIG_BAIXO, ECHO_BAIXO);
bool detectouCima = distCima < DISTANCIA_GATILHO;
bool detectouBaixo = distBaixo < DISTANCIA_GATILHO;
if (estadoMovimento != 0 && (millis() - tempoPrimeiraDeteccao > TEMPO_MAXIMO_MOVIMENTO)) {
estadoMovimento = 0;
atualizarDisplay("Timeout detec.", "Resetando...");
delay(1500);
atualizarDisplay("Sistema Pronto", "Aguardando...");
}
if (estadoMovimento == 0) {
if (detectouCima && !detectouBaixo) {
estadoMovimento = 1;
tempoPrimeiraDeteccao = millis();
} else if (detectouBaixo && !detectouCima) {
estadoMovimento = 2;
tempoPrimeiraDeteccao = millis();
}
}
else if (estadoMovimento == 1) {
if (detectouBaixo) {
acionarRele("ESQ -> DIR");
estadoMovimento = 0;
}
}
else if (estadoMovimento == 2) {
if (detectouCima) {
acionarRele("DIR -> ESQ");
estadoMovimento = 0;
}
}
delay(50);
}
void acionarRele(String direcao) {
atualizarDisplay("Movimento:", direcao);
digitalWrite(PINO_RELE, HIGH);
delay(2000); // Mantém a mensagem e o relé ativados por 2 segundos
digitalWrite(PINO_RELE, LOW);
atualizarDisplay("Sistema Pronto", "Aguardando...");
}