

Práctica educativa del Circular FAB para controlar una barrera de aparcamiento con Arduino Mega, Stepper 28BYJ-48, display TM1637 y sensores ultrasónicos HC-SR04. Entrada, salida y conteo de vehículos.
| COMPONENTE | PIN ARDUINO MEGA | DESCRIPCIÓN |
|---|---|---|
| TM1637 CLK | 6 | Reloj del display |
| TM1637 DIO | 7 | Datos del display |
| Stepper IN1 | 8 | Bobina A1 del motor |
| Stepper IN2 | 9 | Bobina A2 del motor |
| Stepper IN3 | 10 | Bobina B1 del motor |
| Stepper IN4 | 11 | Bobina B2 del motor |
| Sensor Abrir TRIG | 47 | Trigger sensor entrada |
| Sensor Abrir ECHO | 49 | Echo sensor entrada |
| Sensor Cerrar TRIG | 51 | Trigger sensor salida |
| Sensor Cerrar ECHO | 53 | Echo sensor salida |
| Botón RESET | 22 | Reinicia el contador (INPUT_PULLUP) |
| Alimentación | 5V / GND | Fuente común motor + sensores + Mega |
// ════════════════════════════════════════════════════════ // BARRERA AUTOMÁTICA — Arduino Mega // Hardware: // · Arduino Mega 2560 // · Stepper 28BYJ-48 + driver ULN2003 // · Display TM1637 (4 dígitos) // · 2× Sensor ultrasónico HC-SR04 // · 1× Botón RESET (INPUT_PULLUP) // // Conexión Stepper: IN1=D8, IN3=D10, IN2=D9, IN4=D11 // Display TM1637: CLK=D6, DIO=D7 // Sensor Abrir: TRIG=47, ECHO=49 // Sensor Cerrar: TRIG=51, ECHO=53 // Botón RESET: D22 → GND // ════════════════════════════════════════════════════════ #include <TM1637Display.h> #include <Stepper.h> // ── Display TM1637 ──────────────────────────────────── #define CLK 6 #define DIO 7 TM1637Display display(CLK, DIO); // ── Stepper + ULN2003 ───────────────────────────────── #define IN1 8 #define IN2 9 #define IN3 10 #define IN4 11 const int PASOS_POR_VUELTA = 2048; Stepper motor(PASOS_POR_VUELTA, IN1, IN3, IN2, IN4); // ── Sensores HC-SR04 ────────────────────────────────── #define TRIG_ABRIR 47 #define ECHO_ABRIR 49 #define TRIG_CERRAR 51 #define ECHO_CERRAR 53 #define PIN_RESET 22 int distanciaUmbral = 10; int contadorCoches = 0; int pasosAbrir = 512; int pasosCerrar = -512; bool barreraAbierta = false; bool resetAnterior = HIGH; bool modoSalida = false; void setup() { Serial.begin(9600); pinMode(TRIG_ABRIR, OUTPUT); pinMode(ECHO_ABRIR, INPUT); pinMode(TRIG_CERRAR, OUTPUT); pinMode(ECHO_CERRAR, INPUT); pinMode(PIN_RESET, INPUT_PULLUP); motor.setSpeed(10); display.setBrightness(7); mostrarContador(); Serial.println("=== Barrera Automática ==="); Serial.println("28BYJ-48 | TM1637 | HC-SR04 x2"); Serial.println("Comandos: 'a'=abrir 'c'=cerrar 'r'=reset"); } void loop() { revisarSerial(); revisarBotonReset(); int dAbrir = medirDistancia(TRIG_ABRIR, ECHO_ABRIR); int dCerrar = medirDistancia(TRIG_CERRAR, ECHO_CERRAR); // ── DETECCIÓN ───────────────────────────────────── if (!barreraAbierta) { if (dAbrir > 0 && dAbrir < distanciaUmbral) { modoSalida = false; abrirBarrera(); Serial.println("[ABRIR] Sensor entrada detectado"); } else if (dCerrar > 0 && dCerrar < distanciaUmbral) { modoSalida = true; abrirBarrera(); Serial.println("[ABRIR] Sensor salida detectado"); } } // ── CIERRE Y CONTEO ─────────────────────────────── if (barreraAbierta) { if (!modoSalida && dCerrar > 0 && dCerrar < distanciaUmbral) { cerrarBarrera(); contadorCoches++; mostrarContador(); Serial.print("[CONTAR] Entró. Total: "); Serial.println(contadorCoches); delay(1000); } else if (modoSalida && dAbrir > 0 && dAbrir < distanciaUmbral) { cerrarBarrera(); if (contadorCoches > 0) contadorCoches--; mostrarContador(); Serial.print("[CONTAR] Salió. Total: "); Serial.println(contadorCoches); delay(1000); } } delay(150); } // ── Funciones auxiliares ────────────────────────────── void abrirBarrera() { motor.step(pasosAbrir); barreraAbierta = true; apagarBobinas(); } void cerrarBarrera() { motor.step(pasosCerrar); barreraAbierta = false; apagarBobinas(); } long medirDistancia(int trig, int echo) { digitalWrite(trig, LOW); delayMicroseconds(3); digitalWrite(trig, HIGH); delayMicroseconds(10); digitalWrite(trig, LOW); long dur = pulseIn(echo, HIGH, 30000); return (dur == 0) ? -1 : dur * 0.034 / 2; } void mostrarContador() { display.showNumberDec(contadorCoches, true); } void revisarBotonReset() { bool estado = digitalRead(PIN_RESET); if (resetAnterior == HIGH && estado == LOW) { contadorCoches = 0; mostrarContador(); Serial.println("[RESET] Contador a cero"); delay(250); } resetAnterior = estado; } void revisarSerial() { if (Serial.available() > 0) { char cmd = Serial.read(); if (cmd == 'r') { contadorCoches = 0; mostrarContador(); Serial.println("[RESET]"); } if (cmd == 'a' && !barreraAbierta) { abrirBarrera(); Serial.println("[MANUAL] Abriendo"); } if (cmd == 'c' && barreraAbierta) { cerrarBarrera(); Serial.println("[MANUAL] Cerrando"); } } } void apagarBobinas() { digitalWrite(IN1, LOW); digitalWrite(IN2, LOW); digitalWrite(IN3, LOW); digitalWrite(IN4, LOW); }