#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 (0x27 é o endereço I2C mais comum no Wokwi)
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;
int contadorPessoas = 0; // Mantém o número de pessoas na sala
// Função para ler a distância do sensor
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;
}
// Atualiza o display com o status atual
void atualizarDisplayStatus() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Pessoas: ");
lcd.print(contadorPessoas);
lcd.setCursor(0, 1);
if (contadorPessoas > 0) {
lcd.print("Luz: LIGADA");
digitalWrite(PINO_RELE, HIGH); // Liga a lâmpada
} else {
lcd.print("Luz: DESLIGADA");
digitalWrite(PINO_RELE, LOW); // Desliga a lâmpada
}
}
void setup() {
lcd.init();
lcd.backlight();
pinMode(TRIG_CIMA, OUTPUT);
pinMode(ECHO_CIMA, INPUT);
pinMode(TRIG_BAIXO, OUTPUT);
pinMode(ECHO_BAIXO, INPUT);
pinMode(PINO_RELE, OUTPUT);
digitalWrite(PINO_RELE, LOW);
atualizarDisplayStatus(); // Mostra o estado inicial (0 pessoas, Luz apagada)
}
void loop() {
long distCima = lerDistancia(TRIG_CIMA, ECHO_CIMA);
delay(10); // Evita interferência acústica entre os sensores
long distBaixo = lerDistancia(TRIG_BAIXO, ECHO_BAIXO);
bool detectouCima = distCima < DISTANCIA_GATILHO;
bool detectouBaixo = distBaixo < DISTANCIA_GATILHO;
// Timeout: se a pessoa não terminar de passar, reseta o estado
if (estadoMovimento != 0 && (millis() - tempoPrimeiraDeteccao > TEMPO_MAXIMO_MOVIMENTO)) {
estadoMovimento = 0;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Movimento falhou");
delay(1000);
atualizarDisplayStatus(); // Volta para a tela principal
}
if (estadoMovimento == 0) {
if (detectouCima && !detectouBaixo) {
estadoMovimento = 1; // Pessoa começou a entrar
tempoPrimeiraDeteccao = millis();
} else if (detectouBaixo && !detectouCima) {
estadoMovimento = 2; // Pessoa começou a sair
tempoPrimeiraDeteccao = millis();
}
}
else if (estadoMovimento == 1) {
// Se detectou embaixo (completou a entrada)
if (detectouBaixo) {
contadorPessoas++;
estadoMovimento = 0;
atualizarDisplayStatus();
delay(1500); // Pausa para a pessoa terminar de passar sem contar duas vezes
}
}
else if (estadoMovimento == 2) {
// Se detectou em cima (completou a saída)
if (detectouCima) {
if (contadorPessoas > 0) {
contadorPessoas--; // Garante que a contagem não fique negativa
}
estadoMovimento = 0;
atualizarDisplayStatus();
delay(1500); // Pausa para a pessoa terminar de passar
}
}
delay(50); // Estabilidade do microcontrolador
}