Código
#include <LiquidCrystal.h>
#include <IRremote.h>
#include <Stepper.h>
/* ───────── Pines ───────── */
const int RECV_PIN = 2;
const int LED_OK = A0;
const int LED_FAIL = A1;
const int BUZZER_PIN = A2;
const int TRIG_PIN = A5;
const int ECHO_PIN = A4;
const int IN1 = 3, IN2 = 4, IN3 = 5, IN4 = 6;
const int LED_LIBRE = 7; // verde
const int LED_OCUPADO = A3; // rojo
/* ───────── Contraseñas ───────── */
const int CODE_IN[4] = { 1, 1, 1, 1 }; // Entrada
const int CODE_OUT[4] = { 0, 0, 0, 0 }; // Salida
/* ───────── Variables ───────── */
String inputCode = "";
byte digitsRead = 0;
bool barreraAbierta = false;
bool modoAlerta = false;
int intentosFallidos = 0;
unsigned long ultimoBuzzer = 0;
bool buzzerEstado = false;
unsigned long ultimoPing = 0;
long distanciaCM = 999;
/* ───────── Objetos ───────── */
LiquidCrystal lcd(8, 9, 10, 11, 12, 13);
IRrecv receiver(RECV_PIN);
Stepper motor(2500, IN1, IN3, IN2, IN4);
/* ───────── Prototipos ───────── */
void pedirClave(const char* etiqueta);
long medirDistancia();
void actualizarSensorYLeds();
bool claveCorrecta(const int clave[4]);
void abrirBarrera(bool esEntrada);
/* ───────── Setup ───────── */
void setup() {
lcd.begin(16, 2);
pinMode(LED_OK, OUTPUT);
pinMode(LED_FAIL, OUTPUT);
pinMode(BUZZER_PIN, OUTPUT);
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
pinMode(LED_LIBRE, OUTPUT);
pinMode(LED_OCUPADO, OUTPUT);
receiver.enableIRIn();
motor.setSpeed(10);
actualizarSensorYLeds();
pedirClave("Entrada/Salida");
}
/* ───────── Funciones ───────── */
void pedirClave(const char* etiqueta) {
lcd.clear();
lcd.print("Insert ");
lcd.print(etiqueta);
lcd.setCursor(0, 1);
lcd.print("Clave: ");
inputCode = "";
digitsRead = 0;
}
/* ---------- HC‑SR04 ---------- */
long medirDistancia() { // cm
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
long dur = pulseIn(ECHO_PIN, HIGH, 30000); // 30 ms máx.
return dur * 0.034 / 2;
}
void actualizarSensorYLeds() {
if (millis() - ultimoPing >= 60) { // ≤ 16 Hz
ultimoPing = millis();
distanciaCM = medirDistancia();
}
bool cochePresente = (distanciaCM <= 4);
digitalWrite(LED_LIBRE, cochePresente ? LOW : HIGH);
digitalWrite(LED_OCUPADO, cochePresente ? HIGH : LOW);
}
bool claveCorrecta(const int clave[4]) {
return (inputCode[0] - '0' == clave[0] && inputCode[1] - '0' == clave[1] && inputCode[2] - '0' == clave[2] && inputCode[3] - '0' == clave[3]);
}
/* esEntrada = true -> clave CODE_IN
* esEntrada = false -> clave CODE_OUT
*/
void abrirBarrera(bool esEntrada) {
barreraAbierta = true;
lcd.clear();
lcd.print(esEntrada ? "Coche entrando..." : "Coche saliendo...");
digitalWrite(LED_OK, HIGH);
motor.step(512); // abre 1/4 vuelta
delay(500);
unsigned long t0 = millis();
if (esEntrada) {
while (millis() - t0 < 8000) {
actualizarSensorYLeds();
if (distanciaCM <= 4) break; // coche detectado
delay(100);
}
} else {
while (millis() - t0 < 8000) {
actualizarSensorYLeds();
if (distanciaCM > 8) break; // coche se fue
delay(100);
}
}
motor.step(-512); // cierra
digitalWrite(LED_OK, LOW);
barreraAbierta = false;
}
/* ───────── Loop ───────── */
void loop() {
/* —— Alarma —— */
if (modoAlerta) {
if (millis() - ultimoBuzzer >= 1000) {
ultimoBuzzer = millis();
buzzerEstado = !buzzerEstado;
digitalWrite(BUZZER_PIN, buzzerEstado);
}
}
/* —— Lectura IR —— */
if (receiver.decode()) {
int code = receiver.decodedIRData.command;
char digit = '\0';
if (code == 12) digit = '1';
if (code == 24) digit = '2';
if (code == 94) digit = '3';
if (code == 8) digit = '4';
if (code == 28) digit = '5';
if (code == 90) digit = '6';
if (code == 66) digit = '7';
if (code == 82) digit = '8';
if (code == 74) digit = '9';
if (code == 22) digit = '0';
if (digit != '\0' && digitsRead < 4) {
inputCode += digit;
lcd.setCursor(7 + digitsRead, 1); // tras "Clave: "
lcd.print('*'); // oculta dígitos
digitsRead++;
}
receiver.resume();
}
/* —— Tras 4 dígitos —— */
if (digitsRead == 4) {
delay(100);
bool estabaEnAlerta = modoAlerta; // recordar si había alarma
if (claveCorrecta(CODE_IN)) { // Entrada
intentosFallidos = 0;
modoAlerta = false;
digitalWrite(BUZZER_PIN, LOW);
if (estabaEnAlerta) {
lcd.clear();
lcd.print("ALARMA DESACTIVADA");
delay(1000);
}
abrirBarrera(true);
} else if (claveCorrecta(CODE_OUT)) { // Salida
intentosFallidos = 0;
modoAlerta = false;
digitalWrite(BUZZER_PIN, LOW);
if (estabaEnAlerta) {
lcd.clear();
lcd.print("ALARMA DESACTIVADA");
delay(1000);
}
abrirBarrera(false);
} else { // Incorrecta
intentosFallidos++;
lcd.clear();
lcd.print("CLAVE ERRONEA");
digitalWrite(LED_FAIL, HIGH);
delay(1000);
digitalWrite(LED_FAIL, LOW);
if (intentosFallidos >= 3) modoAlerta = true;
}
pedirClave("Entrada/Salida");
}
actualizarSensorYLeds();
}