← Edu Herraiz Ars Magna Lab

Un futbolín Córdoba restaurado

Domotizando un futbolín(con Home Assistant)

Barreras de infrarrojos en los carriles de recogida y un ESP32 con ESPHome que lleva la partida. El marcador es un dashboard en la tablet, con locutor y música, se controla por voz con Assist y los goles se celebran con WLED. Va a batería, escondido en el mueble, y la portería no se ha tocado.

ESPHomeWLEDAssistDashboardESP32Barreras IR
El futbolín en plena partida, con la tablet al lado marcando 2-1

01

Lo que hace

Se juega con 11 bolas y gana quien llega a 6. Con 5-5, la última bola se tira en el centro: es «la buena». El ESP32 conoce estas reglas y publica la fase de la partida en sensor.futbolin_fase. Todo lo demás (marcador, sonido y luces) reacciona a esa fase.

Saque

«Nueva partida» por voz. Marcador a cero y el locutor presenta el clásico.

normal
Gol

Suma solo. Ola de luz del color del equipo y una frase del locutor.

event.futbolin_gol
Bola de partido

Al llegar a 5, las tiras respiran en el color de quien la tiene.

bola_partido_a
La buena

5-5: duelo de olas, latido dorado y cartel en el marcador.

la_buena
Victoria

Fiesta de luces y pantalla del ganador. Los goles que sobran ya no cuentan.

fin_a

02

Un Córdoba de toda la vida

Es un futbolín Córdoba antiguo, negro y restaurado. Eso fijó las reglas del montaje:

  • Por fuera, igual que siempre. Sin pantallas pegadas ni botones nuevos. Lo único que se ve es un interruptor general, por debajo.
  • La portería no se toca. La bola es maciza y sale disparada: cualquier sensor dentro de la portería acabaría roto o devolviendo la bola al campo.
  • Sin cables mientras se juega. Todo va a batería.
  • Sin botones en el futbolín. Todo se maneja desde Home Assistant.

El ábaco de cuentas rojas y azules sigue en su sitio, por si acaso.

El futbolín Córdoba restaurado, negro, con los muñecos blancos y granates
El Córdoba, ya restaurado. Por fuera no se ve nada nuevo.
Placa de latón de la Delegación de Industria de Barcelona: marca Justo A. Córdoba, fútbol de salón, tipo mesa, aprobado en 1950
La placa original: «fútbol de salón», tipo mesa, aprobado por la Dirección General de Seguridad en 1950.
El mismo futbolín antes de restaurarlo, pintado de rojo y con los muñecos gastados
Así estaba en 2022, antes de restaurarlo.
Detalle de los muñecos antes de la restauración, con la pintura gastada
Los muñecos, con décadas de partidos encima.

03

¿Cómo sabe que es gol?

Lo intuitivo sería mirar en la portería, pero es mejor mirar después. Cuando la bola entra, cae por una ranura a un carril de madera que la lleva rodando hasta el cajetín. Ahí ya no va a cien por hora: rueda despacio y siempre por el mismo camino.

En cada carril hay una barrera de infrarrojos, con un emisor a un lado y un receptor enfrente. Cuando la bola pasa, corta el haz unas decenas de milisegundos, y eso es un gol.

Lo menos intrusivo posible

Cero taladros

Dos cuñas de madera pegadas con cola dentro del carril. No se ha agujereado ni la portería ni el carril.

Se quita

Las cuñas se despegan y los sensores van con conectores. El futbolín vuelve a estar como antes.

Fuera del camino

Cada sensor está a cubierto detrás de su cuña. La bola nunca lo toca y la rampa la guía sin frenarla.

No se escapa

El haz cruza el carril de pared a pared, así que la bola lo corta pase por donde pase.

Lo que hace el firmware

Corte del carril con el emisor y el receptor a cada lado de la bola, y la señal en el GPIO 32: el haz se corta unos 35 ms con el gol, el bloqueo de 400 ms ignora los rebotes y los cortes muy cortos se descartan como ruido
La barrera vista de frente y la señal que llega al ESP32 con un gol.
El carril de recogida con las dos cuñas de madera pegadas a las paredes y los sensores detrás
Las dos cuñas en el carril, con un sensor detrás de cada una.
La bola pasa entre las cuñas y corta el haz. A velocidad real.

04

Arquitectura

La decisión clave: la partida la lleva el ESP32, no Home Assistant. Cuenta, calcula la fase y la guarda en flash (restore_value) para no perderla en un reinicio o una actualización OTA.

Desde ahí avisa por dos caminos. A HA, por la API nativa de ESPHome. A WLED, directamente por la API JSON ({"ps": 3}), sin pasar por HA, para que el efecto salga al instante.

Si cae la WiFi o Home Assistant, el ESP32 sigue contando, y al volver la tablet enseña el marcador correcto. HA no lleva ninguna lógica de la partida: solo muestra las entidades y pulsa los botones.

05

Lo que ve Home Assistant

El dispositivo ESPHome se llama futbolin, así que todas las entidades quedan como <dominio>.futbolin_*. Los equipos son A y B: en casa, A es el Madrid y B el Barça.

Estado

EntidadQué es
sensor.futbolin_goles_a / _bGoles de cada equipo, de 0 a 6
sensor.futbolin_fasereposo, normal, bola_partido_a/_b, la_buena, fin_a/_b
event.futbolin_golgol_a o gol_b, solo con los goles que ven las barreras. Es el disparador natural de las automatizaciones
sensor.futbolin_bateria% de batería, calculado con la tensión más alta de los últimos 10 min para que los picos de las tiras no lo hagan saltar
binary_sensor.futbolin_autotestResultado del autotest de las barreras

Controles

EntidadQué hace
button.futbolin_nueva_partida0-0 y a jugar
button.futbolin_gol_a_mas / _menosCorrige el marcador. La fase se recalcula: un −1 desde 6-5 devuelve la bola de partido
button.futbolin_anular_partidaVuelve a reposo
switch.futbolin_efectos_luzActiva o desactiva los efectos de las tiras
number.futbolin_luces_bateria_minima% de batería por debajo del cual se cortan las luces
switch.futbolin_modo_enchufadoPara jugar con una fuente de 12 V en lugar de baterías: oculta la batería y silencia sus avisos

06

El marcador: un dashboard con locutor

El marcador es un dashboard de HA hecho con una sola button-card con HTML propio: dígitos de matriz de puntos, la columna de las 11 bolas con el orden de los goles, la animación de «¡GOL!», el cartel de «la buena» y la pantalla del ganador. Mientras está abierto, HA quita el salvapantallas de la tablet.

El locutor

Cada gol lo canta un locutor que sigue el partido: el primer gol, el empate, la racha, la remontada, la bola de partido, el gol que salva el partido… Son 348 locuciones generadas de antemano con una voz TTS de OpenAI. HA calcula el momento del partido como atributo de un sensor y el dashboard elige una frase al azar, sin repetir la anterior.

La tablet con el marcador a 0-0, apoyada en el futbolín junto al ábaco
El marcador en la tablet, al lado del ábaco de toda la vida.

El truco de la música

Con música sonando en la tablet, el locutor tiene que bajarla y no pararla. Android solo baja la música si el sonido nuevo pide el foco de audio «temporal, se puede bajar», y el WebView solo lo pide así para medios de menos de 5 s. Con una locución más larga, la música se pausaba y no volvía.

La solución: mientras habla el locutor, suena en bucle un <audio> con 1 s de silencio, que pide el foco corto. La voz va aparte por Web Audio, que no pide foco. Al acabar, se vacía el src del silencio y se llama a load(): con pause() solo, el foco no se suelta y la música se queda baja.

07

Control por voz con Assist

El futbolín no tiene botones: todo se hace con Assist desde la tablet. Las frases son disparadores de conversación de una automatización que pulsan los botones de ESPHome. Se resuelven en local antes de llegar al LLM, así que no hace falta exponer el futbolín a Assist.

triggers:
  - trigger: conversation
    command:
      - "gol del Madrid"
      - "gol de los blancos"
actions:
  - action: button.press
    target:
      entity_id: button.futbolin_gol_a_mas
FraseAcción
«Nueva partida», «echamos una»Nueva partida y marcador en la tablet
«Gol del Barça»+1
«Ese no vale el del Madrid»−1
«¿Cómo vamos?»Responde con el marcador y la fase
«Anula la partida»Vuelta a reposo
«Pon la música»Música en la tablet

08

Luces con WLED

Hay una tira LED a cada lado del campo (WS2811 de 12 V, 28 píxeles cada una), movidas por un controlador Gledopto con WLED. Cada tira es un segmento. A batería gastan demasiado para ir encendidas toda la partida, así que solo hacen efectos de unos segundos y vuelven a apagarse solas.

Cada momento es un preset (o una playlist de presets) que el ESP32 lanza por la API JSON. Los presets salen de un script generador, así que se versionan con el resto del código.

El bus de 12 V alimenta el Gledopto con WLED, que tiene dos salidas: la tira A en el GPIO 16 (píxeles 0 a 27) y la tira B en el GPIO 2 (píxeles 28 a 55)
Cada tira va a su propia salida del Gledopto y es un segmento de WLED.
PresetCuándoQué hace
gol_a / gol_bGolOla del color del equipo hacia la portería contraria y fuegos artificiales, 3 s
bola_partido_*Un equipo llega a 5Las tiras respiran en su color 8 s
la_buena5-5Duelo de olas, cada una desde su portería, y latido dorado
fin_a / fin_bGol que ganaFiesta del color del ganador 10 s
avisoAtasco o autotest fallidoRojo fijo hasta que se resuelve

Con batería baja, el ESP32 corta las luces solo: si el % pasa 60 s por debajo de number.futbolin_luces_bateria_minima, las apaga, y no las vuelve a encender hasta que la batería sube 10 puntos por encima del mínimo. Ese margen evita que el corte rebote, porque los propios efectos hunden la tensión.

09

Cableado y baterías

Toda la electrónica va en un panel de contrachapado junto a las baterías, en la parte fija del mueble: el ESP32, el buck que baja de 12 a 5 V, una regleta que hace de bus de 12 V y la interfaz de las barreras. Las tiras toman los 12 V directamente.

A cada carril llega un cable de 5 hilos que acaba en dos conectores JST-SM, uno para el receptor y otro para el emisor. Las resistencias de pull-up van soldadas en el extremo del cable, junto al ESP32, y un divisor de 100k/20k lleva los 12 V al GPIO 34 para calcular el % de batería.

Esquema general: dos baterías con su fusible, el interruptor, el bus de 12 V, el Gledopto con las tiras, el buck a 5 V, el ESP32 y la interfaz con los cables de los dos carriles
El esquema general. En rojo, los +12 V.

El ESP32 y las barreras

Conexión de una barrera al ESP32: 3,3 V y GND por clemas, la señal del receptor al GPIO 32 con pull-up de 5,1 kΩ y 1 kΩ en serie, el emisor al GPIO 14 y el divisor de batería al GPIO 34
Cómo se conecta una barrera al ESP32, con el divisor de batería en el GPIO 34.

Las baterías

Son dos baterías de plomo de 12 V y 7 Ah en paralelo, cada una con su fusible de 5 A, y un interruptor general por debajo del mueble. Según las cuentas, dan para unas 7 horas de juego (falta medirlo). Para jugar enchufado, se quitan las baterías y se conecta una fuente de 12 V en su lugar.

Cableado de las baterías: cada una con su portafusibles de 5 A, los dos positivos al interruptor y de ahí a las clemas de 12 V, que reparten a Gledopto, buck e interfaz; los negativos a la clema de GND
Cada batería lleva su fusible junto al borne y los dos positivos se unen en el interruptor.
El futbolín con el tablero de juego abatido y la electrónica dentro del mueble
Con el tablero levantado: todo cabe dentro del mueble.
La caja de la electrónica, con el ESP32 en su placa de bornas, el buck y las conexiones
El ESP32 en su placa de bornas, el buck y las conexiones de las barreras.
Las dos baterías de plomo y el controlador Gledopto dentro de una caja azul
Las dos baterías, con sus fusibles, y el Gledopto.
El interruptor general, un pulsador redondo con anillo rojo atornillado por debajo del mueble
El interruptor general: todo se enciende desde debajo del mueble.

El código

Todo está en GitHub, con código abierto: el firmware de ESPHome, el paquete de Home Assistant con el dashboard del marcador y las frases de Assist, los presets de WLED con su generador, el generador de las locuciones y los diagramas.