Circular FAB
CIRCULAR FAB Jarandilla de la Vera · Arduino Week 2026
Circular FAB
CIRCULAR FAB
Jarandilla de la Vera · Práctica educativa de fabricación digital

PROYECTO
BARRERA
AUTO

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.

Arduino Mega 28BYJ-48 TM1637 HC-SR04 ×2 Pines 6·7·8·9·10·11 Pines 47·49·51·53
Objetivo: aprender el control de motores paso a paso, sensores de distancia y displays en un proyecto aplicado, documentado y replicable con materiales accesibles.
0000 HC-SR04 ABRIR HC-SR04 CERRAR TM1637
STEPPER 28BYJ-48 + ULN2003
01 / MATERIALES

LO QUE USAMOS

🎛️
Arduino Mega 2560
Gran número de pines digitales y analógicos. Mismo sketch funciona con UNO/NANO ajustando los pines de los sensores.
⚙️
Stepper 28BYJ-48 + ULN2003
Motor paso a paso de 5V con driver ULN2003 integrado. 2048 pasos/vuelta. Silencioso y preciso para controlar el ángulo de la barrera.
🔢
Display TM1637 4 dígitos
Display de 7 segmentos con solo 2 pines (CLK+DIO). Muestra en tiempo real el número de vehículos dentro del aparcamiento.
📡
HC-SR04 ×2 Ultrasónico
Sensor de distancia por ultrasonido. Alcance 2–400cm. Uno para detectar la entrada, otro la salida. Umbral ajustable en el código.
🔘
Botón RESET INPUT_PULLUP
Reinicia el contador a cero sin subir código. Usa la resistencia interna de pull-up del Mega: no necesita resistencia externa.
🔌
Alimentación 5V estable
Fuente capaz de suministrar el pico de arranque del motor (~300mA) y la electrónica. Se recomienda fuente externa, no solo el USB.
02 / CONEXIONES

TABLA DE PINES

COMPONENTEPIN ARDUINO MEGADESCRIPCIÓ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ón5V / GND Fuente común motor + sensores + Mega
// DIAGRAMA DE SEÑALES
── DISPLAY TM1637 ─────────────────
Mega D6
TM1637 CLK
Mega D7
TM1637 DIO
── STEPPER 28BYJ-48 ───────────────
Mega D8-D11
IN1–IN4 ULN2003
── SENSORES HC-SR04 ───────────────
Mega 47/49
TRIG/ECHO Abrir
Mega 51/53
TRIG/ECHO Cerrar
── BOTÓN + ALIMENTACIÓN ───────────
Mega D22
BTN RESET
GND
5V / GND
ULN2003 Vcc/GND
⚠ ORDEN DE BOBINAS DEL STEPPER El 28BYJ-48 requiere el orden IN1, IN3, IN2, IN4 en el constructor Stepper para girar correctamente. Si la barrera vibra sin moverse, revisa este orden.
✓ INPUT_PULLUP EN EL BOTÓN RESET El pin 22 usa la resistencia interna del Mega. Conecta el botón entre D22 y GND directamente, sin resistencia externa. Lógica activa-baja.
⚡ ALIMENTACIÓN DEL STEPPER El 28BYJ-48 puede consumir hasta 300mA al arrancar. Usa una fuente de 5V de al menos 1A. Con solo el USB del PC puede haber resets inesperados.
ℹ APAGAR BOBINAS TRAS MOVIMIENTO El código llama a apagarBobinas() tras cada movimiento para evitar calentamiento innecesario. El motor mantiene la posición por fricción mecánica.
03 / LÓGICA

CÓMO FUNCIONA

// DIAGRAMA DE ESTADOS
BARRERA CERRADA ABRE (ENTRADA) ABRE (SALIDA) CIERRA + CUENTA Sensor Abrir <10cm Sensor Cerrar <10cm Sensor Cerrar pasa Sensor Abrir pasa vuelve a esperar
✓ DETECCIÓN DE ENTRADA Si la barrera está cerrada y el sensor "Abrir" (pin 47/49) detecta un objeto a menos de 10cm, se activa el modo entrada y la barrera se abre.
✓ DETECCIÓN DE SALIDA Si el sensor "Cerrar" (pin 51/53) detecta primero, se activa el modo salida. La lógica de conteo se invierte: decrementará al final del ciclo.
⚡ CIERRE Y CONTEO Cuando el coche pasa el segundo sensor (según modo), la barrera se cierra y el contador se incrementa o decrementa. El display TM1637 actualiza en tiempo real.
ℹ CONTROL POR SERIAL MONITOR Desde el Serial Monitor a 9600 baud: 'a' abre, 'c' cierra, 'r' resetea el contador. Ideal para pruebas sin coche real.
04 / CÓDIGO

SKETCH ARDUINO MEGA

barrera_automatica.ino
// ════════════════════════════════════════════════════════
//  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);
}
05 / SIMULADOR

PRUEBA EL SISTEMA

BARRERA VIRTUAL — 28BYJ-48
0000
SERIAL MONITOR — 9600 baud
// Arduino Mega 2560 booting...
// pinMode() — D6·D7·D8·D9·D10·D11 → OUTPUT
// HC-SR04 TRIG: D47·D51 → OUTPUT
// HC-SR04 ECHO: D49·D53 → INPUT
// D22 → INPUT_PULLUP (BTN RESET)
=== Barrera Automática ===
28BYJ-48 | TM1637 | HC-SR04 x2
Comandos: 'a'=abrir 'c'=cerrar 'r'=reset
// Sistema listo. Esperando vehículos...