#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
const int brakePin = 12;
const int moveDownPin = 13;
const int moveUpPin = 11;
const int openDoorPin = 5;
const int floor1SensorPin = 1;
const int floor2SensorPin = 2;
const int floor3SensorPin = 3;
const int floor4SensorPin = 4;
const int callFloor1Pin = 50;
const int callFloor2Pin = 51;
const int callFloor3Pin = 52;
const int callFloor4Pin = 53;
int currentFloor = 1;
int targetFloor = 1;
unsigned long lastUpdateTime = 0;
unsigned long doorOpenTime = 0;
unsigned long brakeTime = 0;
bool doorOpen = false;
bool brakeEngaged = false;
void setup() {
pinMode(brakePin, OUTPUT);
pinMode(moveDownPin, OUTPUT);
pinMode(moveUpPin, OUTPUT);
pinMode(openDoorPin, INPUT_PULLUP);
pinMode(floor1SensorPin, INPUT_PULLUP);
pinMode(floor2SensorPin, INPUT_PULLUP);
pinMode(floor3SensorPin, INPUT_PULLUP);
pinMode(floor4SensorPin, INPUT_PULLUP);
pinMode(callFloor1Pin, INPUT_PULLUP);
pinMode(callFloor2Pin, INPUT_PULLUP);
pinMode(callFloor3Pin, INPUT_PULLUP);
pinMode(callFloor4Pin, INPUT_PULLUP);
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("Elevador");
}
void loop() {
// Verificar sensores de andar
if (digitalRead(floor1SensorPin) == LOW) {
currentFloor = 1;
handleArrival();
} else if (digitalRead(floor2SensorPin) == LOW) {
currentFloor = 2;
handleArrival();
} else if (digitalRead(floor3SensorPin) == LOW) {
currentFloor = 3;
handleArrival();
} else if (digitalRead(floor4SensorPin) == LOW) {
currentFloor = 4;
handleArrival();
}
// Verificar chamadas de andares
if (digitalRead(callFloor1Pin) == LOW) {
targetFloor = 1;
handleCall();
} else if (digitalRead(callFloor2Pin) == LOW) {
targetFloor = 2;
handleCall();
} else if (digitalRead(callFloor3Pin) == LOW) {
targetFloor = 3;
handleCall();
} else if (digitalRead(callFloor4Pin) == LOW) {
targetFloor = 4;
handleCall();
}
// Verificar se a porta está aberta
if (digitalRead(openDoorPin) == LOW) {
doorOpen = true;
doorOpenTime = millis();
digitalWrite(brakePin, LOW);
lcd.setCursor(0, 1);
lcd.print("Porta Aberta");
}
// Verificar se a porta está aberta há mais de 5 segundos
if (doorOpen && millis() - doorOpenTime >= 5000) {
doorOpen = false;
digitalWrite(brakePin, HIGH);
lcd.setCursor(0, 1);
lcd.print("Porta Fechada");
}
// Verificar o movimento do elevador de acordo com o andar atual e o chamado
if (currentFloor < targetFloor) {
digitalWrite(moveUpPin, HIGH);
digitalWrite(moveDownPin, LOW);
} else if (currentFloor > targetFloor) {
digitalWrite(moveUpPin, LOW);
digitalWrite(moveDownPin, HIGH);
} else {
// Freio é acionado quando o andar chamado é alcançado
digitalWrite(moveUpPin, LOW);
digitalWrite(moveDownPin, LOW);
if (!brakeEngaged) {
digitalWrite(brakePin, LOW);
}
}
// Atualizar o display a cada 1 segundo
if (millis() - lastUpdateTime >= 1000) {
updateDisplay();
lastUpdateTime = millis();
}
}
void handleCall() {
// Verificar se o elevador pode se mover
if (!doorOpen && !brakeEngaged) {
// Fechar a porta
digitalWrite(brakePin, HIGH);
lcd.setCursor(0, 1);
lcd.print("Porta Fechada");
doorOpen = false;
// Esperar 2 segundos
delay(2000);
}
}
void handleArrival() {
// Desligar o motor 1 segundo após o sensor de andar ser acionado
if (millis() - brakeTime >= 1000) {
brakeEngaged = true;
brakeTime = millis();
}
// Verificar se deve permanecer no andar ou seguir para o próximo
if (millis() - brakeTime >= 5000) {
brakeEngaged = false;
targetFloor = currentFloor;
handleCall();
}
}
void updateDisplay() {
lcd.setCursor(0, 0);
lcd.print("Andar Atual: ");
lcd.print(currentFloor);
lcd.setCursor(0, 1);
lcd.print("Chamado: ");
lcd.print(targetFloor);
}