Mostrar las plazas libres en un display de 7 segmentos
Recorrido del nivel
Esa barra de arriba te dice en qué paso estás. Tocala para ver el índice completo y saltar a cualquier paso.
Conectar el display de 7 segmentos
El display de 7 segmentosDisplay de 7 segmentosComponente que representa números encendiendo o apagando siete LED con forma de línea, identificados con letras de la «a» a la «g». No tiene circuito de control propio: cada segmento se maneja desde una salida digital de la placa. es un componente que representa números encendiendo o apagando siete LED con forma de línea. Cada segmento se identifica con una letra, de la a a la g: por ejemplo, el segmento g es el trazo horizontal del centro. Como cada segmento es un LED, cada uno necesita su resistencia de 220 Ω en serie, y el pin común del display va a GND.
En el Arduino UNO, los siete segmentos se conectan a los pines a=12, b=13, c=5, d=6, e=7, f=11, g=10 (las constantes del código). Son los mismos pines del esquema original.
En el ESP32, los siete segmentos se conectan a los GPIO a=16, b=17, c=18, d=19, e=21, f=22, g=23 (las constantes del código), todos GPIO de salida seguros. La alimentación del display se toma de 3,3 V y GND.
Programar el display: la tabla de segmentos
Programar el display es igual que encender y apagar LED: para mostrar una cifra hay que prender los segmentos correctos y apagar el resto. Si queremos representar un 8, encendemos los siete; para un 4, solo los segmentos b, c, f y g.
Cada carácter tiene su combinación de segmentos prendidos y apagados. En lugar de escribir el encendido a mano para cada número, conviene guardar esa correspondencia en una tabla dentro del código: una fila por cada cifra (del 0 al 9) y una columna por cada segmento (a, b, c, d, e, f, g), con un 1 si el segmento va encendido y un 0 si va apagado. Esa tabla se parece mucho a la de lápiz y papel donde marcamos, para cada número, qué segmentos se dibujan.
Escribir cualquier cifra con escribir_numero()
Con la tabla lista, necesitamos una función que reciba un número y encienda o apague los
segmentos que le corresponden. La llamamos escribir_numero(): recibe un valor (por ejemplo, 2) y
usa la fila de la tabla de ese número para escribir cada segmento. Así, en vez de repetir siete
instrucciones cada vez, con una sola línea —escribir_numero(2)— mostramos el 2 en el display.
Como prueba, se puede recorrer del 0 al 9 con una demora de un segundo entre cada número: el display irá mostrando la cuenta y, al terminar, volverá a empezar. Ese ejercicio confirma que la tabla y la función están bien antes de conectarlas al estacionamiento.
Incorporar el display al estacionamiento
Ahora conectamos el display al sistema del nivel inicial para que muestre cuántas plazas libres
quedan y reemplace a los dos LED verde y rojo. La lógica de las barreras y el conteo es la
misma: lo único que cambia es que, cada vez que lugares sube o baja, llamamos a
escribir_numero(lugares) para actualizar la pantalla. La variable arranca en 8, así que al
encender el display muestra un 8.
Ver el código completo · contador-display.ino
// Estacionamiento automatizado — Nivel Intermedio (Arduino UNO).
//
// Igual que el nivel inicial (dos barreras + contador de lugares), pero los dos
// LED verde/rojo se reemplazan por un DISPLAY DE 7 SEGMENTOS que muestra el
// numero EXACTO de lugares libres (0 a 8), como pide la situacion-problema
// (Juana quiere saber cuantos lugares quedan, no solo si hay o no hay).
//
// Display de 7 segmentos de CATODO COMUN: cada segmento (a..g) se enciende con
// un HIGH en su pin. La tabla segmentos[10][7] define que segmentos van
// prendidos para cada digito, y escribir_numero() la aplica.
//
// Plataforma: Arduino UNO. Proyecto de BAJA TENSION (servos 5 V, display,
// pulsadores): no hay 220 V ni agua, no lleva advertencias electricas.
//
// Nivel intermedio: se permite delay() (fiel a la progresion del original).
//
// Basado en: Fragmentos de codigo del Nivel Intermedio (Pasos 3 y 4) —
// Estacionamiento Automatizado, Saberes Digitales (INET/EDUCAR 2019).
// CORRECCION DE BUG CRITICO (ver README): servoEntrada/servoSalida se
// remapean de los pines 0/1 (RX/TX del USB, que rompen la carga y el serial)
// a los pines 4 y 8.
#if defined(ESP32)
#include <ESP32Servo.h>
#else
#include <Servo.h>
#endif
// --- Capacidad del estacionamiento ---
const int CAPACIDAD = 8;
// --- Pines de las barreras (servos) — REMAPEADOS (bug del original) ---
const int PIN_SERVO_ENTRADA = 4; // original: pin 0 (RX) = BUG
const int PIN_SERVO_SALIDA = 8; // original: pin 1 (TX) = BUG
// --- Pines de los pulsadores (10K como pulldown, del original) ---
const int PIN_PULSADOR_ENTRADA = 2;
const int PIN_PULSADOR_SALIDA = 3;
// --- Pines del display de 7 segmentos (segmentos a..g), fieles al original ---
const int PIN_A = 12;
const int PIN_B = 13;
const int PIN_C = 5;
const int PIN_D = 6;
const int PIN_E = 7;
const int PIN_F = 11;
const int PIN_G = 10;
// --- Angulos de la barrera ---
const int ANGULO_ABIERTA = 90;
const int ANGULO_CERRADA = 0;
// Espera (ms) a que el auto cruce antes de bajar la barrera.
const unsigned long TIEMPO_PASO_MS = 3000;
// Lugares disponibles. Arranca vacio: 8 lugares libres.
int lugares = CAPACIDAD;
// Vector de 10x7 con la configuracion de los segmentos {a,b,c,d,e,f,g} de cada
// caracter numerico (1 = segmento encendido). Es la tabla del original.
int segmentos[10][7] = { { 1, 1, 1, 1, 1, 1, 0 }, // 0
{ 0, 1, 1, 0, 0, 0, 0 }, // 1
{ 1, 1, 0, 1, 1, 0, 1 }, // 2
{ 1, 1, 1, 1, 0, 0, 1 }, // 3
{ 0, 1, 1, 0, 0, 1, 1 }, // 4
{ 1, 0, 1, 1, 0, 1, 1 }, // 5
{ 1, 0, 1, 1, 1, 1, 1 }, // 6
{ 1, 1, 1, 0, 0, 0, 0 }, // 7
{ 1, 1, 1, 1, 1, 1, 1 }, // 8
{ 1, 1, 1, 1, 0, 1, 1 } }; // 9
Servo servoEntrada;
Servo servoSalida;
// escribir_numero recibe un valor (0 a 9) y enciende/apaga los segmentos
// correspondientes segun la tabla "segmentos".
void escribir_numero(int num) {
digitalWrite(PIN_A, segmentos[num][0]);
digitalWrite(PIN_B, segmentos[num][1]);
digitalWrite(PIN_C, segmentos[num][2]);
digitalWrite(PIN_D, segmentos[num][3]);
digitalWrite(PIN_E, segmentos[num][4]);
digitalWrite(PIN_F, segmentos[num][5]);
digitalWrite(PIN_G, segmentos[num][6]);
}
void setup() {
pinMode(PIN_PULSADOR_ENTRADA, INPUT);
pinMode(PIN_PULSADOR_SALIDA, INPUT);
pinMode(PIN_A, OUTPUT);
pinMode(PIN_B, OUTPUT);
pinMode(PIN_C, OUTPUT);
pinMode(PIN_D, OUTPUT);
pinMode(PIN_E, OUTPUT);
pinMode(PIN_F, OUTPUT);
pinMode(PIN_G, OUTPUT);
servoEntrada.attach(PIN_SERVO_ENTRADA);
servoSalida.attach(PIN_SERVO_SALIDA);
servoEntrada.write(ANGULO_CERRADA);
servoSalida.write(ANGULO_CERRADA);
// Mostramos el valor inicial de lugares (8) en el display.
escribir_numero(lugares);
}
void loop() {
// --- ENTRADA: solo se abre si hay al menos un lugar libre ---
if (digitalRead(PIN_PULSADOR_ENTRADA) == HIGH && lugares >= 1) {
servoEntrada.write(ANGULO_ABIERTA);
while (digitalRead(PIN_PULSADOR_ENTRADA) == HIGH) {
}
delay(TIEMPO_PASO_MS);
servoEntrada.write(ANGULO_CERRADA);
lugares = lugares - 1;
escribir_numero(lugares);
}
// --- SALIDA: guard lugares < CAPACIDAD evita superar 8 (y un indice fuera
// de rango en la tabla segmentos[]) ---
if (digitalRead(PIN_PULSADOR_SALIDA) == HIGH && lugares < CAPACIDAD) {
servoSalida.write(ANGULO_ABIERTA);
while (digitalRead(PIN_PULSADOR_SALIDA) == HIGH) {
}
delay(TIEMPO_PASO_MS);
servoSalida.write(ANGULO_CERRADA);
lugares = lugares + 1;
escribir_numero(lugares);
}
} // Estacionamiento automatizado — Nivel Intermedio (ESP32 DevKit v1).
//
// Igual que el nivel inicial (dos barreras + contador de lugares), pero los dos
// LED verde/rojo se reemplazan por un DISPLAY DE 7 SEGMENTOS que muestra el
// numero EXACTO de lugares libres (0 a 8).
//
// Display de 7 segmentos de CATODO COMUN: cada segmento (a..g) se enciende con
// un HIGH. La tabla segmentos[10][7] define que segmentos van prendidos para
// cada digito y escribir_numero() la aplica.
//
// Plataforma: ESP32 (DevKit v1). Servo con ESP32Servo. Proyecto de BAJA
// TENSION: sin 220 V ni agua. Nota electrica: el ESP32 trabaja a 3,3 V; los
// servos se alimentan desde 5 V con GND comun.
//
// Nivel intermedio: se permite delay() (fiel a la progresion del original).
//
// Basado en: Fragmentos de codigo del Nivel Intermedio (Pasos 3 y 4) —
// Estacionamiento Automatizado, Saberes Digitales (INET/EDUCAR 2019).
#if defined(ESP32)
#include <ESP32Servo.h>
#else
#include <Servo.h>
#endif
// --- Capacidad del estacionamiento ---
const int CAPACIDAD = 8;
// --- Pines de las barreras (servos) — GPIO del contrato ---
const int PIN_SERVO_ENTRADA = 25;
const int PIN_SERVO_SALIDA = 26;
// --- Pines de los pulsadores (con resistencia de 10K como pulldown) ---
const int PIN_PULSADOR_ENTRADA = 32;
const int PIN_PULSADOR_SALIDA = 33;
// --- Pines del display de 7 segmentos (segmentos a..g) — GPIO del contrato ---
const int PIN_A = 16;
const int PIN_B = 17;
const int PIN_C = 18;
const int PIN_D = 19;
const int PIN_E = 21;
const int PIN_F = 22;
const int PIN_G = 23;
// --- Angulos de la barrera ---
const int ANGULO_ABIERTA = 90;
const int ANGULO_CERRADA = 0;
// Espera (ms) a que el auto cruce antes de bajar la barrera.
const unsigned long TIEMPO_PASO_MS = 3000;
// Lugares disponibles. Arranca vacio: 8 lugares libres.
int lugares = CAPACIDAD;
// Vector de 10x7 con la configuracion de los segmentos {a,b,c,d,e,f,g}.
int segmentos[10][7] = { { 1, 1, 1, 1, 1, 1, 0 }, // 0
{ 0, 1, 1, 0, 0, 0, 0 }, // 1
{ 1, 1, 0, 1, 1, 0, 1 }, // 2
{ 1, 1, 1, 1, 0, 0, 1 }, // 3
{ 0, 1, 1, 0, 0, 1, 1 }, // 4
{ 1, 0, 1, 1, 0, 1, 1 }, // 5
{ 1, 0, 1, 1, 1, 1, 1 }, // 6
{ 1, 1, 1, 0, 0, 0, 0 }, // 7
{ 1, 1, 1, 1, 1, 1, 1 }, // 8
{ 1, 1, 1, 1, 0, 1, 1 } }; // 9
Servo servoEntrada;
Servo servoSalida;
void escribir_numero(int num) {
digitalWrite(PIN_A, segmentos[num][0]);
digitalWrite(PIN_B, segmentos[num][1]);
digitalWrite(PIN_C, segmentos[num][2]);
digitalWrite(PIN_D, segmentos[num][3]);
digitalWrite(PIN_E, segmentos[num][4]);
digitalWrite(PIN_F, segmentos[num][5]);
digitalWrite(PIN_G, segmentos[num][6]);
}
void setup() {
pinMode(PIN_PULSADOR_ENTRADA, INPUT);
pinMode(PIN_PULSADOR_SALIDA, INPUT);
pinMode(PIN_A, OUTPUT);
pinMode(PIN_B, OUTPUT);
pinMode(PIN_C, OUTPUT);
pinMode(PIN_D, OUTPUT);
pinMode(PIN_E, OUTPUT);
pinMode(PIN_F, OUTPUT);
pinMode(PIN_G, OUTPUT);
servoEntrada.attach(PIN_SERVO_ENTRADA);
servoSalida.attach(PIN_SERVO_SALIDA);
servoEntrada.write(ANGULO_CERRADA);
servoSalida.write(ANGULO_CERRADA);
escribir_numero(lugares);
}
void loop() {
// --- ENTRADA: solo se abre si hay al menos un lugar libre ---
if (digitalRead(PIN_PULSADOR_ENTRADA) == HIGH && lugares >= 1) {
servoEntrada.write(ANGULO_ABIERTA);
while (digitalRead(PIN_PULSADOR_ENTRADA) == HIGH) {
}
delay(TIEMPO_PASO_MS);
servoEntrada.write(ANGULO_CERRADA);
lugares = lugares - 1;
escribir_numero(lugares);
}
// --- SALIDA: guard lugares < CAPACIDAD evita superar 8 (indice fuera de
// rango en segmentos[]) ---
if (digitalRead(PIN_PULSADOR_SALIDA) == HIGH && lugares < CAPACIDAD) {
servoSalida.write(ANGULO_ABIERTA);
while (digitalRead(PIN_PULSADOR_SALIDA) == HIGH) {
}
delay(TIEMPO_PASO_MS);
servoSalida.write(ANGULO_CERRADA);
lugares = lugares + 1;
escribir_numero(lugares);
}
} Podés ver el comportamiento —los autos entrando y saliendo y el display mostrando la cuenta— en el simulador:
Simulación del comportamiento
La misma máquina de estados del firmware, portada a TypeScript, maneja el
comportamiento del dispositivo. No se ejecuta el binario real: la ejecución
del .hex con avr8js está en el roadmap.
Simulación lista. Presioná «Iniciar» para arrancar la secuencia.
¿Y si fueran más de 9 plazas?
Este display muestra un solo dígito, así que llega hasta el 9. Pregunten en grupo: ¿qué harían si el estacionamiento tuviera 12 plazas? ¿Cuántos displays harían falta y cómo repartirían las decenas y las unidades? No hace falta programarlo: alcanza con esbozar la idea y darse cuenta de que la tabla de segmentos ya la tienen resuelta.
Verificá
Con el programa cargado, el display tiene que arrancar mostrando 8. Presioná el pulsador de entrada: al ingresar un auto, la cuenta baja a 7, después a 6, y así. Presioná el de salida: la cuenta sube. Al llegar a 0, la barrera de entrada no debe abrirse (aunque el display no tenga LED de “lleno”, la regla de bloqueo del nivel inicial sigue vigente). Si el display muestra un número equivocado, revisá la tabla de segmentos y que cada segmento esté en el pin correcto.
Cierre del nivel
Al terminar este nivel, el estacionamiento ya no solo dice si hay lugar: muestra cuántos. En el camino aprendiste a manejar un display de 7 segmentos, a guardar datos en una tabla y a encapsular la lógica en una función reutilizable. Pero la información sigue estando solo en el lugar: para saber si hay plazas hay que ir hasta el estacionamiento y mirar el display. En el nivel avanzado vamos a publicar esa información en internet, para poder consultarla a distancia desde un dispositivo móvil.
Evidencia de cierre
Al terminar este nivel, esto tiene que estar funcionando:
- El display de 7 segmentos está conectado: cada segmento (a–g) a su salida digital con una resistencia de 220 Ω, y el común a GND.
- Entendés cómo se representa una cifra encendiendo y apagando segmentos, y podés escribir cualquier número de 0 a 9 con la función escribir_numero() apoyada en la tabla de segmentos.
- El display reemplaza a los dos LED del nivel inicial y muestra en todo momento la cantidad exacta de plazas libres, que baja al entrar un auto y sube al salir.