Corregir un circuito con LTspice es básicamente como planear un viaje con Google Maps sin saber si las calles existen. El mapa dice que todo va a funcionar. El terreno dice otra cosa. Y vos estás parado en una esquina que no aparece en ningún lado.
Ese es exactamente el problema que tengo con un proyecto de electrónica parado desde hace meses: la simulación da perfecta, el circuito físico no funciona igual, y la distancia entre esos dos mundos me parece un abismo sin puente.
Cuando vi el proyecto SPICE + Claude Code + osciloscopio, literalmente dije "esto es lo que estaba buscando" en voz alta. Solo. En mi oficina. A las 11pm.
Te cuento por qué me pareció importante — y qué aprendí de mirarlo con ojo crítico.
Simulación SPICE con Claude Code verificación automática: qué es este proyecto
El setup es conceptualmente elegante. Tres piezas encadenadas:
- LTspice / ngspice corre la simulación del circuito y exporta los resultados (voltajes, corrientes, formas de onda) como archivos de texto o CSV.
- Un osciloscopio con salida digital (USB, GPIB, o un script de Python con PyVISA) captura la señal real del circuito físico.
- Claude Code recibe ambas cosas — simulación y medición real — y tiene que decidir si coinciden, dónde divergen, y qué cambio en el circuito o en el modelo explicaría la diferencia.
El agente no está adivinando. Está comparando datos estructurados de dos fuentes y razonando sobre la discrepancia. Eso es diferente.
Lo interesante no es que "la IA hace la electrónica por vos". Lo interesante es el momento exacto donde el agente toca el mundo físico y tiene que procesar que la realidad es más complicada que el modelo.
# verificacion_spice.py
# Estructura básica del pipeline de verificación
import subprocess
import pandas as pd
import anthropic
from pathlib import Path
def correr_simulacion_spice(netlist_path: str) -> pd.DataFrame:
"""
Corre ngspice con el netlist dado y parsea la salida.
Devuelve un DataFrame con tiempo, voltaje, corriente.
"""
resultado = subprocess.run(
["ngspice", "-b", "-o", "salida.raw", netlist_path],
capture_output=True,
text=True
)
if resultado.returncode != 0:
raise RuntimeError(f"ngspice falló: {resultado.stderr}")
# Parser básico de la salida raw de ngspice
# En producción esto es más complejo
return parsear_raw_ngspice("salida.raw")
def capturar_osciloscopio(canal: int = 1) -> pd.DataFrame:
"""
Captura datos del osciloscopio vía PyVISA.
Asume que el osciloscopio está conectado por USB-TMC.
"""
import pyvisa
rm = pyvisa.ResourceManager()
# Busca el primer instrumento disponible
instrumentos = rm.list_resources()
if not instrumentos:
raise RuntimeError("No encontré ningún instrumento conectado")
scope = rm.open_resource(instrumentos[0])
scope.timeout = 5000 # 5 segundos de timeout
# Identifica el instrumento primero
idn = scope.query("*IDN?")
print(f"Osciloscopio conectado: {idn}")
# Captura la forma de onda del canal pedido
scope.write(f":WAV:SOUR CHAN{canal}")
scope.write(":WAV:MODE NORM")
scope.write(":WAV:FORM ASCII")
datos_raw = scope.query(":WAV:DATA?")
# Parsea la respuesta y construye el DataFrame
return parsear_waveform_ascii(datos_raw, scope)
def verificar_con_claude(
sim_data: pd.DataFrame,
real_data: pd.DataFrame,
contexto_circuito: str
) -> dict:
"""
Le manda ambos datasets a Claude y pide análisis de discrepancias.
Devuelve dict con: coincide, divergencias, hipótesis, siguiente_paso.
"""
client = anthropic.Anthropic()
# Construye el resumen estadístico para no mandar millones de puntos
resumen_sim = {
"vmax": float(sim_data["voltaje"].max()),
"vmin": float(sim_data["voltaje"].min()),
"frecuencia_hz": calcular_frecuencia(sim_data),
"rise_time_us": calcular_rise_time(sim_data)
}
resumen_real = {
"vmax": float(real_data["voltaje"].max()),
"vmin": float(real_data["voltaje"].min()),
"frecuencia_hz": calcular_frecuencia(real_data),
"rise_time_us": calcular_rise_time(real_data)
}
prompt = f"""
Estás analizando la discrepancia entre una simulación SPICE y una medición real.
Contexto del circuito:
{contexto_circuito}
Resultados de simulación SPICE:
{resumen_sim}
Medición real del osciloscopio:
{resumen_real}
Analizá:
1. ¿Las señales coinciden dentro de un margen razonable (±10%)?
2. ¿Qué parámetros divergen más?
3. ¿Cuáles son las hipótesis más probables para explicar la diferencia?
4. ¿Qué cambio en el netlist o en el circuito físico deberías probar primero?
Sé específico. Dame valores, no generalidades.
"""
respuesta = client.messages.create(
model="claude-opus-4-5",
max_tokens=2048,
messages=[{"role": "user", "content": prompt}]
)
# En un sistema real, esto se parsea con structured output
return {
"analisis": respuesta.content[0].text,
"sim_stats": resumen_sim,
"real_stats": resumen_real
}
# Pipeline completo
def pipeline_verificacion(
netlist: str,
descripcion_circuito: str,
canal_osciloscopio: int = 1
):
print("▶ Corriendo simulación SPICE...")
sim = correr_simulacion_spice(netlist)
print("▶ Capturando señal del osciloscopio...")
real = capturar_osciloscopio(canal_osciloscopio)
print("▶ Enviando a Claude para análisis...")
resultado = verificar_con_claude(sim, real, descripcion_circuito)
print("\n=== ANÁLISIS ===")
print(resultado["analisis"])
return resultado
Este pipeline no es ficción. Con ngspice (open source), PyVISA (estándar de instrumentación), y la API de Anthropic, esto funciona hoy. El hardware más accesible para empezar es un Rigol DS1054Z — tiene interfaz USB-TMC, PyVISA lo maneja sin drivers raros, y cuesta menos de 400 dólares.
Qué pasa cuando la realidad no coincide con la simulación
Este es el momento que me interesa. No el happy path donde todo coincide. El momento donde el agente recibe dos datasets que dicen cosas diferentes y tiene que razonar.
Las divergencias más comunes entre simulación SPICE y circuito físico son predecibles si sabés dónde mirar:
Componentes reales vs. modelos ideales. Un capacitor de 100nF en SPICE es perfecto. El físico tiene ESR (resistencia serie equivalente) y ESL (inductancia serie equivalente). A frecuencias altas, eso importa mucho. El modelo SPICE de un BJT estándar generalmente no incluye capacitancias parásitas del encapsulado.
Ground plane y resistencias de trace. En SPICE tu GND es un nodo ideal. En el PCB o protoboard, el ground tiene resistencia, inductancia, y puede tener bucles que generan ruido. Una pista de cobre de 1mm de ancho y 10cm de largo tiene alrededor de 16mΩ de resistencia — que normalmente no modelás.
Temperatura. Los parámetros de semiconductores cambian con la temperatura. La simulación corre a 27°C por default. Tu circuito físico puede estar a 45°C después de 20 minutos encendido.
Tolerancias. Resistencias al 5% de tolerancia significa que un valor nominal de 10kΩ puede ser entre 9.5kΩ y 10.5kΩ. En circuitos sensibles, eso cambia el comportamiento.
Lo que hace Claude en ese momento es exactamente lo que haría un ingeniero experimentado: jerarquiza las hipótesis por probabilidad, sugiere qué medir primero para descartar causas, y propone cambios específicos al netlist para modelar mejor la realidad.
# Ejemplo de contexto enriquecido que le mandás al agente
contexto_circuito = """
Amplificador inversor con op-amp LM741.
Ganancia de diseño: -10 (R_feedback = 100kΩ, R_input = 10kΩ).
Señal de entrada: sinusoidal, 1kHz, 100mV pico.
Alimentación: ±15V.
Montado en protoboard. Cables de prueba de ~20cm.
Medición en la salida del op-amp.
Observación subjetiva: la señal real parece más 'redondeada' en los picos
que la simulación. El nivel DC en reposo también es levemente diferente.
"""
Esa observación subjetiva importa. Le das contexto cualitativo además de los números. El LLM puede cruzar eso con las discrepancias numéricas y afinar la hipótesis.
Los errores que vas a cometer (los cometí yo leyendo el proyecto)
Error 1: Confiar en que el osciloscopio y la simulación tienen la misma referencia temporal.
Ngspice te da datos empezando en t=0. El osciloscopio te da datos del buffer de captura, que puede tener un offset de trigger. Si comparás frecuencia, amplitud y rise time está bien. Si comparás fase directamente, vas a ver divergencias que no existen.
Error 2: Mandar demasiados puntos al LLM.
Una captura de osciloscopio a 1MSa/s por 100ms son 100.000 puntos. Eso es tokens caros y respuestas lentas. El código de arriba lo resume en estadísticas clave. Para la mayoría de los análisis, eso alcanza y sobra.
Error 3: No darle contexto del circuito al agente.
Si le mandás dos arrays de números sin decirle qué circuito es, vas a recibir análisis genérico. Cuanto más contexto específico le das — topología, componentes, condiciones de montaje — más útil es la hipótesis que devuelve. Esto es lo mismo que aprendí con cualquier herramienta de IA: el output es proporcional a la calidad del input. Lo que discutí en el post sobre opacidad de token usage aplica acá también: vas a usar más créditos de los que pensás si no optimizás el contexto.
Error 4: Asumir que el modelo SPICE del fabricante es correcto.
Algunos modelos SPICE de componentes son viejos, aproximados, o directamente incorrectos. He visto netlists con modelos de BJTs que no reflejan el comportamiento real a frecuencias altas. Si la discrepancia es sistemática y grande, el problema puede ser el modelo, no el circuito.
Error 5: Saltear la verificación del setup de medición.
Antes de correr el pipeline, verificá que la punta del osciloscopio esté calibrada (el ajuste de compensación de la punta), que el canal esté en la escala correcta, y que el trigger sea estable. Claude no puede detectar que tu medición está mal si los datos parecen coherentes pero son incorrectos. Garbage in, garbage out — eso no lo resuelve ningún LLM.
FAQ: simulación SPICE con Claude Code y verificación automática
¿Necesito un osciloscopio caro para hacer funcionar esto?
No. Cualquier osciloscopio con interfaz USB-TMC o LAN y soporte VISA funciona. El Rigol DS1054Z (alrededor de 350-400 USD) es el punto de entrada más popular — PyVISA lo detecta directamente, tiene 4 canales y 50MHz de ancho de banda. Para señales de audio o circuitos digitales lentos, hasta un osciloscopio de 20MHz alcanza. También existe la opción de usar una placa de adquisición tipo Red Pitaya, que además de osciloscopio es generador de señal y tiene API Python nativa.
¿Qué versión de SPICE funciona mejor para este pipeline?
Ngspice es open source, tiene buena documentación, y se puede correr por línea de comandos fácilmente — ideal para automatizar. LTspice de Analog Devices es más popular entre hobbyistas pero su interfaz de automatización es menos directa (aunque existe). Para el pipeline que describí, ngspice es la opción más limpia. Si ya usás LTspice, podés exportar los resultados en formato raw y parsearlos con Python sin correr la simulación desde el pipeline.
¿Claude puede modificar el netlist automáticamente en base al análisis?
Sí, y ese es el siguiente nivel. Con Claude Code tenés acceso a herramientas de filesystem — puede leer el netlist, proponer cambios específicos ("aumentá R3 de 10kΩ a 12kΩ para compensar la caída de ganancia"), escribir el netlist modificado, correr la simulación de nuevo y comparar. Es un loop de refinamiento automático. El límite es que todavía necesitás a una persona para hacer el cambio físico en el circuito real — ahí el agente no puede actuar solo. Por ahora.
¿Qué pasa si la divergencia entre simulación y realidad es muy grande?
Es una señal de que algo fundamental está mal: o el modelo SPICE del componente es incorrecto, o hay un componente dañado, o hay un error de diseño que la simulación no capturó (problema de grounding, oscilaciones parásitas, latch-up en un CMOS). En esos casos, Claude puede ayudarte a jerarquizar qué probar, pero el debugging físico lo tenés que hacer vos. El agente es bueno para hipótesis, no reemplaza manos en el hardware.
¿Se puede usar esto con simulaciones de RF o circuitos de alta frecuencia?
Con cuidado. SPICE es un simulador de circuitos concentrados — asume que las dimensiones físicas son mucho menores que la longitud de onda. A frecuencias altas (digamos, por encima de 100MHz) los efectos de línea de transmisión, radiación, y capacitancias parásitas del layout importan, y SPICE no los modela bien sin modelos específicos. Para RF serio, necesitás herramientas de simulación electromagnética (EMsim, HFSS, o similar). El pipeline de verificación automática aplica igual, pero las discrepancias van a ser más grandes y más difíciles de explicar solo con parámetros de componentes.
¿Hay riesgos de seguridad en automatizar la interacción con instrumentos físicos?
Sí, y vale mencionarlo. Un agente que puede escribir comandos SCPI a un instrumento de medición también podría, en principio, mandar comandos que dañen el equipo (cambiar rangos de forma abrupta, deshabilitar protecciones). El pipeline siempre debería tener la capa de captura en modo read-only — solo queries, nunca comandos que modifiquen el estado del instrumento salvo los necesarios para la captura. Y si el agente tiene acceso a modificar netlists y correr simulaciones automáticamente, fijá límites en los parámetros que puede cambiar. Es el mismo principio de seguridad como proof of work que aplica a cualquier sistema automatizado.
Lo que este proyecto me destrabó (y lo que todavía falta)
Tengo un circuito de control de motor parado desde hace meses. La simulación dice que el loop de control es estable. El circuito físico oscila a 3kHz cada vez que pongo carga. Nunca encontré el tiempo de sentarme a debuggearlo sistemáticamente.
Mirar este proyecto me hizo ver que el problema no es tiempo — es método. Estaba intentando debuggear sin estructura: medía una cosa, cambiaba otra, no registraba nada. Un pipeline como este me fuerza a hacer lo que debería haber hecho desde el principio: capturar datos, comparar con el modelo, generar hipótesis, verificar.
El LLM no es magia. Pero es un interlocutor que no se cansa, no tiene ego, y puede cruzar síntomas con hipótesis más rápido que yo buscando en foros de electrónica a las 2am. Eso tiene valor real.
Lo que todavía falta en este tipo de proyectos es el loop completo. Hoy el agente analiza y sugiere, pero la intervención física sigue siendo manual. El siguiente paso interesante — que ya existe en contextos industriales — es conectar el agente a actuadores: relés, fuentes programables, generadores de señal controlables. Ahí el agente realmente "toca" el mundo físico y puede iterar sin humano en el loop.
Eso tiene implicancias que van más allá de la electrónica. Un agente que puede modificar un circuito real basándose en sus propias observaciones es un sistema con agencia física. Es diferente a uno que solo procesa texto. Y esa diferencia importa — en términos de qué conversaciones guardás, en términos de responsabilidad, en términos de qué datos comparte sin que te des cuenta.
Por ahora, el pipeline manual ya tiene valor suficiente. Y yo tengo un proyecto de motor que finalmente voy a retomar este fin de semana.
¿Tenés algún circuito parado por el mismo problema — simulación vs. realidad — que esto podría ayudarte a debuggear? Contame. Quiero saber si el problema es tan común como me parece.
Este artículo fue publicado originalmente en juanchi.dev
Top comments (0)