from machine import Pin,I2C,Timer,ADC
from ssd1306 import SSD1306_I2C
import math
import time
# =========================================================
# CONFIGURACION GENERAL
# =========================================================
N_ARMONICOS=20
BITS=10
MAX_DAC=1023
modo=0
ultimo_boton=0
# =========================================================
# OLED SSD1306
# =========================================================
WIDTH=128
HEIGHT=64
i2c=I2C(0,scl=Pin(5),sda=Pin(4),freq=400000)
oled=SSD1306_I2C(WIDTH,HEIGHT,i2c)
# =========================================================
# DAC R-2R
# =========================================================
leds=[]
for i in range(6,16):
leds.append(Pin(i,Pin.OUT))
# =========================================================
# BOTONES
# =========================================================
boton1=Pin(16,Pin.IN,Pin.PULL_UP)
boton2=Pin(17,Pin.IN,Pin.PULL_UP)
boton3=Pin(18,Pin.IN,Pin.PULL_UP)
boton4=Pin(19,Pin.IN,Pin.PULL_UP)
# =========================================================
# BATERIA
# =========================================================
bateria=ADC(26)
# =========================================================
# VARIABLES RTC
# =========================================================
horas=22
minutos=54
segundos=0
actualizar_barra=False
# =========================================================
# TIMER
# =========================================================
def timer_callback(timer):
global segundos
global minutos
global horas
global actualizar_barra
segundos+=1
if segundos>=60:
segundos=0
minutos+=1
if minutos>=60:
minutos=0
horas+=1
actualizar_barra=True
timer=Timer()
timer.init(freq=1,mode=Timer.PERIODIC,callback=timer_callback)
# =========================================================
# CAMBIO DE MODOS
# =========================================================
def set_modo_0(pin):
global modo
global ultimo_boton
ahora=time.ticks_ms()
if time.ticks_diff(ahora,ultimo_boton)>300:
modo=0
ultimo_boton=ahora
def set_modo_1(pin):
global modo
global ultimo_boton
ahora=time.ticks_ms()
if time.ticks_diff(ahora,ultimo_boton)>300:
modo=1
ultimo_boton=ahora
def set_modo_2(pin):
global modo
global ultimo_boton
ahora=time.ticks_ms()
if time.ticks_diff(ahora,ultimo_boton)>300:
modo=2
ultimo_boton=ahora
def set_modo_3(pin):
global modo
global ultimo_boton
ahora=time.ticks_ms()
if time.ticks_diff(ahora,ultimo_boton)>300:
modo=3
ultimo_boton=ahora
boton1.irq(trigger=Pin.IRQ_FALLING,handler=set_modo_0)
boton2.irq(trigger=Pin.IRQ_FALLING,handler=set_modo_1)
boton3.irq(trigger=Pin.IRQ_FALLING,handler=set_modo_2)
boton4.irq(trigger=Pin.IRQ_FALLING,handler=set_modo_3)
# =========================================================
# MOSTRAR BINARIO
# =========================================================
def mostrar_binario(valor):
for i in range(BITS):
bit=(valor>>i)&1
leds[i].value(bit)
# =========================================================
# BATERIA
# =========================================================
def leer_bateria():
adc_raw=bateria.read_u16()
voltaje=(adc_raw*3.3)/65535
porcentaje=int((voltaje/3.3)*100)
return voltaje,porcentaje
# =========================================================
# BARRA SUPERIOR OLED
# =========================================================
def actualizar_estado():
voltaje,porcentaje=leer_bateria()
oled.fill_rect(0,0,128,16,0)
reloj="{:02}:{:02}:{:02}".format(horas,minutos,segundos)
oled.text(reloj,0,0)
oled.text(str(porcentaje)+"%",88,0)
# =========================================================
# FOURIER GENERAL
# =========================================================
def fourier(x,a0,an,bn,T):
suma=a0()/2
w0=(2*math.pi)/T
for n in range(1,N_ARMONICOS+1):
suma+=an(n)*math.cos(n*w0*x)
suma+=bn(n)*math.sin(n*w0*x)
return suma
# =========================================================
# SEÑAL 1
# =========================================================
def a0_0():
return (1+math.pi)/2
def an_0(n):
return (1/(2*math.pi))*(((-2/n)*math.sin(n*math.pi/2))+(4/(n**2))*(1+(-1)**n-2*math.cos(n*math.pi/2)))
def bn_0(n):
return (1/(2*math.pi))*(((2/n)*((-1)**n-math.cos(n*math.pi/2)))+((2*math.pi/n)*(1-(-1)**n))-(8/(n**2))*math.sin(n*math.pi/2))
# =========================================================
# SEÑAL 2
# =========================================================
def a0_1():
return -0.5
def an_1(n):
return -math.sin(n*math.pi/2)/(n*math.pi)
def bn_1(n):
return 3*(1-math.cos(n*math.pi/2))/(n*math.pi)
# =========================================================
# SEÑAL 3
# =========================================================
def a0_2():
return 1.0
def an_2(n):
return 2*math.sin(n*math.pi/2)/(n*math.pi)
def bn_2(n):
return 0
# =========================================================
# SEÑAL 4
# =========================================================
def a0_3():
return 4*(1-math.exp(-0.5))
def an_3(n):
return (4*(1-math.exp(-0.5)))/(1+16*(math.pi**2)*(n**2))
def bn_3(n):
return (16*math.pi*n*(1-math.exp(-0.5)))/(1+16*(math.pi**2)*(n**2))
# =========================================================
# ESCALAMIENTO DAC
# =========================================================
def escalar(valor,minimo,maximo):
salida=int((valor-minimo)*MAX_DAC/(maximo-minimo))
if salida<0:
salida=0
if salida>1023:
salida=1023
return salida
# =========================================================
# LOOP PRINCIPAL
# =========================================================
while True:
if actualizar_barra:
actualizar_estado()
oled.show()
actualizar_barra=False
oled.fill_rect(0,16,128,48,0)
# =====================================================
# MODO 0
# =====================================================
if modo==0:
oled.text("SENAL 1",0,20)
x=0
while x<2*math.pi and modo==0:
if actualizar_barra:
actualizar_estado()
actualizar_barra=False
suma=fourier(x,a0_0,an_0,bn_0,2*math.pi)
valor=escalar(suma,-2,5)
mostrar_binario(valor)
oled.fill_rect(0,40,128,16,0)
oled.text("N="+str(N_ARMONICOS),0,40)
oled.show()
print(valor)
x+=0.03
# =====================================================
# MODO 1
# =====================================================
elif modo==1:
oled.text("SENAL 2",0,20)
x=0
while x<2*math.pi and modo==1:
if actualizar_barra:
actualizar_estado()
actualizar_barra=False
suma=fourier(x,a0_1,an_1,bn_1,2*math.pi)
valor=escalar(suma,-3,3)
mostrar_binario(valor)
oled.fill_rect(0,40,128,16,0)
oled.text("N="+str(N_ARMONICOS),0,40)
oled.show()
print(valor)
x+=0.03
# =====================================================
# MODO 2
# =====================================================
elif modo==2:
oled.text("SENAL 3",0,20)
x=0
while x<2*math.pi and modo==2:
if actualizar_barra:
actualizar_estado()
actualizar_barra=False
suma=fourier(x,a0_2,an_2,bn_2,2*math.pi)
valor=escalar(suma,0,2)
mostrar_binario(valor)
oled.fill_rect(0,40,128,16,0)
oled.text("N="+str(N_ARMONICOS),0,40)
oled.show()
print(valor)
x+=0.03
# =====================================================
# MODO 3
# =====================================================
elif modo==3:
oled.text("SENAL 4",0,20)
x=0
while x<0.5 and modo==3:
if actualizar_barra:
actualizar_estado()
actualizar_barra=False
suma=fourier(x,a0_3,an_3,bn_3,0.5)
valor=escalar(suma,math.exp(-0.5),1)
mostrar_binario(valor)
oled.fill_rect(0,40,128,16,0)
oled.text("N="+str(N_ARMONICOS),0,40)
oled.show()
print(valor)
x+=0.03
#time.sleep_us(500)