#include <LiquidCrystal_I2C.h>
#include <Servo.h>
#include <TimerOne.h>
#define I2C_ADDR 0x27
#define LCD_COLUMNS 16
#define LCD_LINES 2
#define ESTADO_0 0
#define ESTADO_1 1
#define ESTADO_2 2
#define ESTADO_3 3
#define ESTADO_4 4
#define ESTADO_ENTRADA estado
#define ESTADO_SALIDA estado2
#define SENSOR_ENTRADA sensorEntrada1
#define SENSOR_SALIDA sensorSalida1
#define TIEMPO_DE_SUBIDA tiemposBarrera[0]
#define TIEMPO_DE_BAJADA tiemposBarrera[1]
#define ANTIBOUNCE tiemposBarrera[2]
LiquidCrystal_I2C lcd(I2C_ADDR, LCD_COLUMNS, LCD_LINES);
Servo BarreraEntrada, BarreraSalida;
const int sensorEntrada = 3;
const int sensorSalida = 2;
const int pinVerdeEntrada = 8;
const int pinRojoEntrada = 9;
const int pinVerdeSalida = 10;
const int pinRojoSalida = 11;
int lugares[3]= {0,0,0};
int estado = 0;
int estado2 = 0;
int sensorAnterior = 0;
int sensorAnterior2 = 0;
unsigned long tiempo = 0;
unsigned long tiempo2 = 0;
unsigned long tiemposBarrera[3] = {2000,3000,500};
volatile bool activarLcd = false;
bool hayLugar(){
int suma = 0;
for(int i=0 ; i < 3 ; i++){suma += lugares[i];}
return (suma < 60);
}
void sumarLugar(){
for (int i = 0; i < 3 ; i++){
if(lugares[i] < 20){lugares[i]++; break;}
}
}
void restarLugar(){
for (int i = 0; i < 3 ; i++){
if(lugares[i] > 0){lugares[i]--; break;}
}
}
void setup() {
lcd.init();
lcd.backlight();
BarreraEntrada.attach(6);
BarreraSalida.attach(5);
BarreraEntrada.write(180);
BarreraSalida.write(0);
pinMode(pinVerdeEntrada, OUTPUT);
pinMode(pinRojoEntrada, OUTPUT);
pinMode(pinVerdeSalida, OUTPUT);
pinMode(pinRojoSalida, OUTPUT);
pinMode(sensorEntrada, INPUT);
pinMode(sensorSalida, INPUT);
digitalWrite(pinRojoEntrada, HIGH);
digitalWrite(pinRojoSalida, HIGH);
Timer1.initialize(100000000);
Timer1.attachInterrupt(resfrecarLcd);
}
void loop() {
unsigned long tiempoMillis = millis();
int sensorEntrada1 = digitalRead(sensorEntrada);
int sensorSalida1 = digitalRead(sensorSalida);
//BARRERA DE ENTRADA
switch (ESTADO_ENTRADA) {
case ESTADO_0:
if(((tiempo + ANTIBOUNCE) < tiempoMillis)&& SENSOR_ENTRADA == 0){
ESTADO_ENTRADA = ESTADO_1;
}
break;
case ESTADO_1:
digitalWrite(pinRojoEntrada, HIGH);
if(SENSOR_ENTRADA == 1 && hayLugar()){
ESTADO_ENTRADA = ESTADO_2;
tiempo = tiempoMillis;
sumarLugar();
}
break;
case ESTADO_2:
BarreraEntrada.write(90);
if((tiempo + TIEMPO_DE_SUBIDA)< tiempoMillis){ESTADO_ENTRADA = ESTADO_3;}
break;
case ESTADO_3:
digitalWrite(pinVerdeEntrada, HIGH);
digitalWrite(pinRojoEntrada, LOW);
if(SENSOR_ENTRADA == 0 && ESTADO_ENTRADA == ESTADO_3){
ESTADO_ENTRADA = ESTADO_4;
tiempo = tiempoMillis;
}
break;
case ESTADO_4:
BarreraEntrada.write(180);
digitalWrite(pinVerdeEntrada, LOW);
digitalWrite(pinRojoEntrada, HIGH);
if(((tiempo + TIEMPO_DE_BAJADA)< tiempoMillis)){
ESTADO_ENTRADA = ESTADO_0;
tiempo = tiempoMillis;
}
break;
default:
break;
}
//BARRERA DE SALIDA
switch (ESTADO_SALIDA) {
case ESTADO_0:
if(((tiempo2 + ANTIBOUNCE) < tiempoMillis)&& SENSOR_SALIDA == 0){
ESTADO_SALIDA = ESTADO_1;
}
break;
case ESTADO_1:
digitalWrite(pinRojoSalida, HIGH);
if(SENSOR_SALIDA == 1){
ESTADO_SALIDA = ESTADO_2;
tiempo2 = tiempoMillis;
restarLugar();
}
break;
case ESTADO_2:
BarreraSalida.write(90);
if((tiempo2 + TIEMPO_DE_SUBIDA)< tiempoMillis){ESTADO_SALIDA = ESTADO_3;}
break;
case ESTADO_3:
digitalWrite(pinVerdeSalida, HIGH);
digitalWrite(pinRojoSalida, LOW);
if(SENSOR_SALIDA == 0 ){
ESTADO_SALIDA = ESTADO_4;
tiempo2 = tiempoMillis;
}
break;
case ESTADO_4:
BarreraSalida.write(0);
digitalWrite(pinVerdeSalida, LOW);
digitalWrite(pinRojoSalida, HIGH);
if((tiempo2 + TIEMPO_DE_BAJADA)< tiempoMillis){ESTADO_SALIDA = ESTADO_0; tiempo2 = tiempoMillis;}
break;
default:
break;
}
if(resfrecarLcd){
pantallaLcd();
activarLcd = false;
}
}
void resfrecarLcd(){
activarLcd = true;
}
void pantallaLcd(){
lcd.setCursor(0, 0); // Va al inicio de la línea 1
if(hayLugar()){
lcd.print("Hay lugar "); // Los espacios borran las letras viejas
}else{
lcd.print("COMPLETO ");
}
}