Una bailarina con ALS subió al escenario. No movió los brazos. No habló. Pero la performance ocurrió igual — controlada por sus ondas cerebrales en tiempo real.
La comunidad de neurociencia lo aplaudió. Los de accesibilidad lo citaron. Y yo lo vi pasar en mi feed, empecé a scrollear, y me detuve. Volví. Lo leí dos veces. Lo dejé abierto en una pestaña todo el día.
Tengo algo para decir sobre esto. Y probablemente no sea lo que esperás de un dev que escribe sobre Next.js y Docker.
BCI + ALS + arte: qué pasó técnicamente
Lo que se presentó es una aplicación de Brain-Computer Interface (BCI) en un contexto que casi nadie en el mundo del desarrollo está mirando: performance artística con usuarios que tienen ELA (Esclerosis Lateral Amiotrófica, ALS en inglés).
El setup en términos generales — porque el paper completo todavía está circulando — combina tres capas:
1. Captura de señal EEG
Electrodos no invasivos sobre el cuero cabelludo. No es ciencia ficción quirúrgica. Es electroencefalografía estándar, el mismo principio que existe desde los años 20. Lo que cambió es la miniaturización y el procesamiento en tiempo real.
2. Clasificación de señal
Aquí es donde se pone interesante desde el punto de vista técnico. Los patrones de ondas cerebrales — específicamente ritmos mu (8-12 Hz) y beta (12-30 Hz) asociados a motor imagery, la imaginación de movimiento — se clasifican con modelos entrenados para esa persona específica.
3. Traducción a output artístico
La señal clasificada controla parámetros: iluminación, música generativa, proyecciones visuales. No es un joystick binario. Es modulación continua.
El resultado: la artista imagina el movimiento. La sala responde.
# Esto es una simplificación del pipeline típico de una BCI para arte
# No es el código exacto del proyecto, pero ilustra la arquitectura
import numpy as np
from scipy import signal
def extraer_bandas_frecuencia(eeg_raw, fs=256):
"""
Extraemos las bandas de frecuencia relevantes para motor imagery.
fs = frecuencia de muestreo en Hz
"""
# Banda mu: imaginación de movimiento
mu_low, mu_high = 8, 12
# Banda beta: procesamiento motor activo
beta_low, beta_high = 12, 30
# Filtro butterworth pasabanda
b_mu, a_mu = signal.butter(
4,
[mu_low, mu_high],
btype='band',
fs=fs
)
b_beta, a_beta = signal.butter(
4,
[beta_low, beta_high],
btype='band',
fs=fs
)
banda_mu = signal.filtfilt(b_mu, a_mu, eeg_raw)
banda_beta = signal.filtfilt(b_beta, a_beta, eeg_raw)
return banda_mu, banda_beta
def calcular_potencia_relativa(banda, eeg_total):
"""
Potencia relativa: qué porcentaje de la señal total
corresponde a esta banda. Métrica clave para clasificación.
"""
potencia_banda = np.mean(banda ** 2)
potencia_total = np.mean(eeg_total ** 2)
return potencia_banda / potencia_total
def mapear_a_parametro_artistico(potencia_mu, potencia_beta):
"""
Acá es donde el dev toma decisiones artísticas.
No hay una sola forma correcta de hacer este mapeo.
"""
# Ejemplo: mu alto → más luz, beta alto → tempo más rápido
intensidad_luz = np.clip(potencia_mu * 10, 0, 1)
velocidad_musica = 80 + (potencia_beta * 1000) # BPM base 80
return {
'luz': intensidad_luz,
'tempo': velocidad_musica
}
Este es el corazón del asunto: el problema técnico de una BCI artística no es tan diferente a cualquier sistema reactivo en tiempo real. La señal entra, se procesa, algo cambia en el mundo. Lo que cambia el contexto es quién está del otro lado del sensor.
El hardware open source que los devs estamos ignorando
Aquí viene el 'pero'. El ecosistema BCI open source existe, funciona, y casi nadie en el mundo del desarrollo web lo está mirando.
OpenBCI es el nombre que más aparece. Tienen la placa Cyton (8 canales, ~$500 USD) y la Ganglion (4 canales, ~$200 USD). Ambas tienen SDK en Python, Java, y conexión vía Bluetooth o WiFi. Hay un ecosistema alrededor de OpenBCI GUI que permite visualizar señal en tiempo real sin escribir una línea de código.
BrainFlow es la librería que unifica el acceso a múltiples headsets — OpenBCI, Muse, Emotiv, y otros — bajo una API común:
# Conexión a un headset OpenBCI Cyton con BrainFlow
# Esto SÍ es código real que podés correr hoy
from brainflow.board_shim import BoardShim, BrainFlowInputParams, BoardIds
from brainflow.data_filter import DataFilter, FilterTypes
import time
import numpy as np
def conectar_y_leer_eeg():
params = BrainFlowInputParams()
# Puerto serie donde está conectada la placa
# En Linux típicamente /dev/ttyUSB0, en Mac /dev/cu.usbserial-*
params.serial_port = '/dev/ttyUSB0'
# BoardIds.CYTON_BOARD = 0
board = BoardShim(BoardIds.CYTON_BOARD, params)
board.prepare_session()
board.start_stream()
print("Leyendo EEG... (5 segundos)")
time.sleep(5)
# get_board_data() vacía el buffer y devuelve numpy array
datos = board.get_board_data()
board.stop_stream()
board.release_session()
# Los canales de EEG están en filas específicas según la placa
canales_eeg = BoardShim.get_eeg_channels(BoardIds.CYTON_BOARD)
señal_eeg = datos[canales_eeg, :]
print(f"Capturados {señal_eeg.shape[1]} samples de {len(canales_eeg)} canales")
return señal_eeg
# Frecuencia de muestreo del Cyton: 250 Hz
# O sea: 250 muestras por segundo por canal
Con esto y un headset de ~$200 tenés señal EEG real. El problema no es el hardware. El problema es el siguiente paso: la clasificación.
Aquí está el gotcha que nadie te cuenta cuando empieza a leer sobre BCI: los modelos son altamente dependientes del usuario. Un clasificador entrenado con mi EEG no funciona con el tuyo. La variabilidad entre personas — y en la misma persona entre días — es enorme. Por eso los proyectos de BCI artística requieren sesiones de calibración previas a cada performance.
Los errores que vas a cometer si arrancás con esto
Error 1: Comprar el headset más barato
El Muse (~$300) es popular porque tiene SDK y comunidad, pero tiene 4 electrodos y está optimizado para meditación, no para motor imagery. Si querés hacer algo serio con BCI, el Cyton de 8 canales es el piso mínimo razonable.
Error 2: Saltear la etapa de preprocesamiento
El artefacto ocular (parpadeo, movimiento de ojos) contamina señal EEG de forma masiva. Hay un artefacto muscular de mandíbula que arruina canales frontales. Antes de clasificar cualquier cosa, necesitás filtrado y eliminación de artefactos. BrainFlow tiene algo básico. Para algo más robusto, MNE-Python es el estándar de la industria:
import mne
import numpy as np
def limpiar_señal_eeg(raw_data, sfreq=250, nombres_canales=None):
"""
Pipeline básico de preprocesamiento con MNE.
Esto es lo mínimo antes de intentar clasificar.
"""
if nombres_canales is None:
nombres_canales = [f'EEG{i:03d}' for i in range(raw_data.shape[0])]
# Crear objeto Raw de MNE
info = mne.create_info(
ch_names=nombres_canales,
sfreq=sfreq,
ch_types='eeg'
)
raw = mne.io.RawArray(raw_data, info)
# Filtro pasabanda: eliminar DC offset y ruido de alta frecuencia
# 1 Hz evita la deriva lenta, 40 Hz corta ruido muscular y eléctrico
raw.filter(1., 40., fir_window='hamming')
# Notch filter para eliminar interferencia de red eléctrica
# 50 Hz en Argentina/Europa, 60 Hz en EEUU
raw.notch_filter(50.)
# ICA para eliminar artefactos oculares — requiere datos suficientes
# Mínimo recomendado: 20 segundos de señal limpia para calcular ICA
ica = mne.preprocessing.ICA(n_components=0.95, random_state=42)
ica.fit(raw)
# Esto requiere revisión manual o algoritmos automáticos
# para identificar qué componentes son artefactos
# ica.apply(raw, exclude=[0, 1]) # ejemplo: excluir componentes 0 y 1
return raw
Error 3: Pensar que esto es un problema de ML genérico
La transferencia de aprendizaje entre usuarios es activa área de investigación. No podés descargar un modelo de Hugging Face, fine-tunearlo con dos minutos de tu EEG, y esperar que funcione. El campo se llama EEG Foundation Models y está en pañales. Los papers existen pero los modelos deployables y confiables no.
Error 4: El problema de latencia
Para performance artística en tiempo real, necesitás latencia sub-300ms entre intención y output. El pipeline de captura → filtrado → clasificación → output tiene que ser eficiente. Python puro con NumPy es viable. Pandas no. Cualquier cosa que haga garbage collection en el momento equivocado te rompe la experiencia.
FAQ: Lo que me terminaron preguntando cuando compartí esto
¿Necesitás conocimientos de neurociencia para empezar con BCI?
No para el hardware y las APIs. Sí para entender qué estás midiendo y no cometer errores graves de interpretación. El nivel mínimo útil es entender qué son las bandas de frecuencia (delta, theta, alpha, mu, beta, gamma) y qué fenómenos se asocian a cada una. Con una semana de lectura básica ya podés trabajar con criterio.
¿Cuánto cuesta armar un setup BCI funcional para experimentar?
OpenBCI Ganglion (4 canales): ~$200 USD + electrodos (~$50 USD) + gel conductor (~$20 USD). Total: menos de $300 USD para señal real. El Muse S sale similar pero tiene menos flexibilidad. Para un proyecto artístico serio, el Cyton de 8 canales (~$500 USD) es más recomendable.
¿Qué diferencia hay entre este uso artístico y las BCI médicas que salen en las noticias?
Las BCI médicas (como el Neuralink o BrainGate) son invasivas — requieren implantes quirúrgicos y buscan restaurar función motora o comunicación. Las BCI no invasivas con electrodos de superficie son menos precisas pero no requieren cirugía. Para arte y accesibilidad en contextos no médicos, la BCI no invasiva es el camino. La artista con ALS de esta performance usó electrodos superficiales.
¿Por qué los devs web no estamos prestando atención a esto?
Porque la cadena de herramientas no pasa por npm. Pasa por Python, scipy, MNE, hardware físico, y papers de IEEE. Es un stack diferente al que la mayoría de nosotros operamos. Y porque el mercado no es masivo todavía. Pero la Web Bluetooth API existe, la Web Serial API existe, y hay proyectos que conectan headsets BCI directo al browser. El gap se está cerrando.
¿Qué tan replicable es exactamente lo que hizo esta artista?
La arquitectura general: alta replicabilidad con hardware open source y tiempo. La calibración específica que funcionó para ella: no replicable directamente. Cada usuario necesita su propio proceso de entrenamiento del clasificador. Lo que sí es replicable es el pipeline técnico. Lo que no es replicable es el calibrado personal.
¿Hay riesgo de usar estos headsets?
Los headsets EEG no invasivos son pasivos — miden, no estimulan. No hay corriente eléctrica que entre al cuerpo (a diferencia de la estimulación transcraneal, que es otra cosa completamente). Los riesgos son básicamente ninguno para usuarios sanos. Para usuarios con condiciones neurológicas, siempre con supervisión médica.
Por qué los devs deberíamos estar mirando esto — y por qué no lo hacemos
Estuve todo el día pensando en esto. Y creo que entendí por qué me pegó diferente.
En las últimas semanas escribí sobre keys hardcodeadas en código generado por IA, sobre agentes que automatizan PRs, sobre si Git va a sobrevivir a los LLMs, sobre migraciones de infraestructura. Todo eso existe en el espacio del developer experience, la productividad, el tooling.
Esta historia existe en otro espacio. El espacio donde la tecnología hace posible algo que antes era imposible para una persona específica. No "más rápido" ni "más eficiente". Literalmente posible.
Una artista que no puede mover el cuerpo. Que puede mover una sala entera.
Y el stack técnico que lo hace posible no es un modelo de $100M de parámetros corriendo en un datacenter de Microsoft. Es Python, scipy, una placa de $500, y un modelo entrenado con datos de una sola persona.
Aquí está mi crítica justa: el mundo del desarrollo web — el mío, el tuyo si llegaste hasta acá — está absurdamente concentrado en un ecosistema de herramientas que básicamente sirve para mover JSON de un lado a otro de manera cada vez más sofisticada. Y hay ramas enteras de la computación, como esta, que tienen problemas técnicos genuinamente difíciles, impacto humano directo, y ecosistemas open source activos, que no existen en nuestra conversación colectiva.
No digo que abandones Next.js. Yo no lo voy a abandonar. Pero cuando leo sobre contribuir al kernel de Linux o cuando pienso en el espacio de problemas que los devs con background de sistemas podrían atacar, me pregunto si estamos mirando demasiado hacia adentro del ecosistema.
Si algo de esto te resuena y querés experimentar: BrainFlow tiene ejemplos funcionales en Python que podés correr sin hardware real usando datos sintéticos. Es el mejor punto de entrada. No necesitás comprar nada para entender cómo funciona el pipeline.
Lo que sí vas a necesitar es tiempo. Y la disposición a trabajar en un dominio donde el feedback loop no es "hice npm install y funcionó".
Pero para una artista que subió a un escenario a controlar luz y música con la imaginación, alguien en algún momento dijo que valía la pena.
Este artículo fue publicado originalmente en juanchi.dev
Top comments (0)