from machine import Pin, I2C
from ssd1306 import SSD1306_I2C
import utime, math
# --- OLED (I2C0 en GP16=SDA, GP17=SCL) ---
# Asegúrate de que estos pines coincidan con tu conexión en Wokwi
i2c = I2C(0, scl=Pin(17), sda=Pin(16), freq=400000)
oled = SSD1306_I2C(128, 64, i2c)
# --- Parámetros Fourier ---
T = 4.0
w0 = math.pi / 2
F_MIN, F_MAX = -2.2, 1.2 # Rango de valores de la función
# --- Coeficientes de Fourier ---
def a0():
return -0.25
def an(n):
if n == 0: return 0
return (-1 / (n * math.pi)) * math.sin(n * math.pi / 2)
def bn(n):
if n == 0: return 0
return (3 / (n * math.pi)) * (1 - math.cos(n * math.pi / 2))
def f_fourier(x, N):
"""Calcula la suma de la serie de Fourier hasta N armónicos"""
suma = a0()
for n in range(1, N + 1):
suma += an(n) * math.cos(n * w0 * x) + bn(n) * math.sin(n * w0 * x)
return suma
def escalar_y(valor):
"""Escala un valor de la función al rango de píxeles del OLED (0-63)"""
# Normaliza el valor (0.0 a 1.0)
ratio = (valor - F_MIN) / (F_MAX - F_MIN)
# Invierte y escala a 63 píxeles (0 es arriba, 63 es abajo)
y = int(63 - ratio * 63)
# Asegura que esté dentro de los límites
return max(0, min(63, y))
# --- Inicio pantalla ---
oled.fill(0)
oled.text("Serie de Fourier", 2, 0)
oled.text("T=4, w0=pi/2", 0, 12)
oled.show()
utime.sleep_ms(1000) # Pequeña pausa al inicio
# --- Preparación de buffers ---
dx = T / 128.0 # Incremento de x para 128 puntos
buffer_y = [32] * 128 # Buffer para los valores Y del OLED
# --- Bucle principal ---
while True:
for N in range(1, 13): # Itera de N=1 hasta 12 armónicos
print(f"Calculando {N} armonicos")
# --- 1. FASE DE CÁLCULO ---
# Calcula la forma de onda para N armónicos
x = -T / 2
for i in range(128):
val = f_fourier(x, N)
buffer_y[i] = escalar_y(val)
x += dx
# --- 2. FASE DE REPORTE (Dibujar en OLED) ---
oled.fill(0)
oled.text("Serie de Fourier", 2, 0)
oled.text("N = " + str(N), 0, 12) # Muestra el número de armónicos
# Dibuja la línea conectando los puntos
for i in range(127):
oled.line(i, buffer_y[i], i + 1, buffer_y[i + 1], 1)
oled.show()
print(f"Mostrando N={N}")
utime.sleep_ms(500) # Pausa entre cada armónico