01 · Punto de partida
Sin osciloscopio, con intérprete
Generar una senoide de 50 Hz en código cuesta 3 líneas; medirle medio, RMS y frecuencia, otras diez; graficarla en texto, quince. Ese toolkit (solo biblioteca estándar, sin numpy) te acompaña todo el curso: predecir filtros, verificar comparadores y entender muestreo antes de tocar hardware.
Al terminar, cualquier señal del curso existe primero como lista de Python.
- ¿Cómo genero las 4 formas con parámetros?
- ¿Cómo estimo f sin saberla?
- ¿Cómo grafico sin librerías?
- ¿Qué pasa con ruido y pocas muestras?
02 · Generar
Cuatro formas, una función
Parámetros: amplitud, frecuencia, offset, duty, muestras por segundo (fs) y segundos. Regla de oro: fs ≥ 20×f para verla linda (Nyquist pide 2×, el ojo pide 20×).
Python en tu navegador. Generá tus ondas y ejecutá el análisis.
import math
def generar(forma="seno", amp=5.0, f_hz=50.0, offset=0.0, duty=0.5, fs=2000.0, segundos=0.1):
n = int(fs * segundos)
vals = []
for k in range(n):
t = k / fs
f = (t * f_hz) % 1.0 # fase 0..1
if forma == "seno":
v = amp * math.sin(2 * math.pi * f)
elif forma == "cuadrada":
v = amp if f < duty else -amp
elif forma == "triangular":
v = amp * (4 * abs(f - 0.5) - 1)
else: # diente
v = amp * (2 * f - 1)
vals.append(v + offset)
return vals, fs
onda, fs = generar("seno", amp=5.0, f_hz=50.0)
print(f"{len(onda)} muestras a {fs} Hz: max={max(onda):.1f} min={min(onda):.1f}")
Generá cuadrada 0–5 (amp 2.5, offset 2.5, duty 0.25): ¿max/min? ¿Y triangular ±3?
03 · Medir
Estadísticas + frecuencia por cruces
f estimada = cruces ascendentes por el medio / segundos. Con fs holgada y sin ruido, clava el valor real.
def analizar(vals, fs):
medio = sum(vals) / len(vals)
rms = math.sqrt(sum(v * v for v in vals) / len(vals))
cruces = sum(1 for a, b in zip(vals, vals[1:]) if a < medio <= b)
f_est = cruces / (len(vals) / fs)
print(f"medio={medio:.2f}V rms={rms:.2f}V cruces={cruces} f~={f_est:.1f}Hz")
return medio, rms, f_est
onda, fs = generar("seno", amp=5.0, f_hz=50.0)
analizar(onda, fs)
onda2, _ = generar("cuadrada", amp=2.5, offset=2.5, duty=0.25, f_hz=100.0, fs=5000.0, segundos=0.1)
analizar(onda2, 5000.0)
La cuadrada debe dar medio 1,25 y f ≈ 100. Si tu fs fuera 150 Hz, ¿qué estimaría? (Pista: aliasing.)
04 · Graficar
ASCII plot sin librerías
Quince líneas que muestran la forma en la consola: escala al rango y pinta una fila por muestra.
def ascii_plot(vals, ancho=60, alto=12):
lo, hi = min(vals), max(vals)
span = (hi - lo) or 1.0
paso = max(1, len(vals) // ancho)
for fila in range(alto):
nivel = hi - (fila + 0.5) / alto * span
linea = "".join("#" if v >= nivel else " " for v in vals[::paso])
print(f"{nivel:+6.1f}|{linea}")
onda, _ = generar("seno", amp=5.0, f_hz=50.0, fs=2000.0, segundos=0.06)
ascii_plot(onda)
onda2, _ = generar("cuadrada", amp=2.5, offset=2.5, duty=0.25, f_hz=50.0, fs=2000.0, segundos=0.06)
ascii_plot(onda2)
05 · Ruido
Ensuciar a propósito
Sumar gaussiano simula la mesa real: el promedio se salva, los cruces se multiplican. Lección: estimar f con histéresis o filtrando (Temas 20 y 23), no con cruces crudos.
import random
random.seed(7)
def con_ruido(vals, sigma=0.3):
return [v + random.gauss(0, sigma) for v in vals]
onda, fs = generar("seno", amp=5.0, f_hz=50.0)
limpia = analizar(onda, fs)
sucia = analizar(con_ruido(onda), fs)
print("Compará: medio y rms casi iguales, cruces disparados")
Sin ruido
Cruces exactos
f estimada clava 50 Hz: cada cruce es real y cuenta.
Con ruido
Cruces falsos
El ruido cruza y recruza el medio: f estimada se dispara. Filtrar o histéresis (Temas 20, 23).
06 · Analogía programador
Observabilidad de series
- 1Generar = fixtures.
Datos sintéticos con forma conocida para probar el análisis antes que el hardware.
- 2Cruces = eventos.
Detectar flancos como webhooks: contar transiciones en vez de promediar niveles.
- 3ASCII = logging.
Ver sin GUI: printf-debugging de señales, suficiente el 80 % de las veces.
07 · Exploración
Laboratorio: parámetros en vivo
Elegí forma y mové amplitud, frecuencia y duty: el laboratorio calcula medio, RMS, cruces y f estimada con fs fija de 2 kHz.
Generador + análisis
fs = 2000 Hz fijos
Senoide 5 V a 50 Hz con fs 2 kHz.
Preguntas para explorar
- Subí a 900 Hz. ¿Muestras/ciclo? ¿Sigue linda la estimación?
- ¿Por qué la triangular da el mismo medio que la senoide pero otro RMS?
- ¿Qué pasa si pedís f mayor que fs/2? (Probá mentalmente 1500 Hz.)
Ver respuestas sugeridas
- 2,2 por ciclo: al borde (Nyquist pide > 2). La estimación tiembla: fs 2 kHz no alcanza para 900 Hz con holgura.
- Medio 0 ambas por simetría; RMS 2,89 vs 3,54 por forma (Tema 6). La forma decide la energía.
- Aliasing: 1500 Hz con fs 2000 se ve como 500 Hz falsa. Por eso fs ≥ 20×f para trabajar tranquilo.
08 · Comprensión
Confusiones frecuentes
«Más muestras siempre mejor»
Mejor hasta sobrar (20×f): más allá solo gastan CPU sin información nueva. Muestrear de más no arregla ruido ni aliasing.
«Cruces = frecuencia siempre»
Solo sin ruido y con fs holgada. Con ruido u offset descentrado, los cruces mienten: verificar forma primero (ASCII).
«Random sin semilla da igual»
Sin seed cada corrida difiere y los experimentos no se repiten. Fijar semilla = experimento reproducible.
«ASCII no sirve para nada serio»
Sirve para el 80 %: offset, recorte, duty y ruido se ven en texto. El 20 % fino pide graficador real (curso 4+).
09 · Práctica guiada
Ejercicios de toolkit
Ejercicio 1: replicar el lab
Generá senoide ±5 V a 50 Hz con fs 2000 y ejecutá analizar(). ¿Medio/RMS/f? Compará con el laboratorio.
Ver solución razonada
Medio ≈ 0, RMS ≈ 3,54, f ≈ 50 Hz. Código y laboratorio deben coincidir: misma matemática.
Ejercicio 2: cazar aliasing
Generá senoide 1500 Hz con fs 2000 y analizá. ¿Qué f estima? Explicá con Nyquist.
Ver solución
Estima ≈ 500 Hz (2000 − 1500: reflejo en fs/2). Alias clásico: fs < 2f miente con confianza.
Ejercicio 3: duty a ojo y a número
Graficá cuadrada 0–5 duty 25 % con ascii_plot() y medí con analizar(). ¿Coinciden ojo y número?
Ver solución
ASCII muestra 1/4 en alto; análisis da medio 1,25 y f exacta. Ojo para forma, número para valor.
10 · Síntesis
Ideas para recordar
- Generar con parámetros (A, f, offset, duty, fs ≥ 20f).
- Medir: medio, RMS y f por cruces ascendentes.
- Graficar en ASCII antes de creer estadísticas.
- Ruido rompe cruces, no promedios: filtrar o histéresis.
- Seed fija = experimento repetible.
Toolkit listo para todo el curso. Ahora, a medir de verdad: en el próximo tema, medir señales con tester y osciloscopio.