from machine import Pin, I2C, ADC
from ssd1306 import SSD1306_I2C
import time
import math
WIDTH = 128
HEIGHT = 64
# Configuración del display SSD1306
i2c = I2C(0, scl=Pin(5), sda=Pin(4), freq=400000)
oled = SSD1306_I2C(WIDTH, HEIGHT, i2c)
# Entradas ADC joystick y potenciómetro
joy_x = ADC(0) # GP26
joy_y = ADC(1) # GP27
adc_range = ADC(2) # GP28, para rango de la función seno
def escalar(valor, max_display):
return int((valor / 65535) * max_display)
def draw_axes():
# Dibuja ejes X e Y en el centro
oled.hline(0, HEIGHT//2, WIDTH, 1)
oled.vline(WIDTH//2, 0, HEIGHT, 1)
def graficar_seno(rango_y):
# Grafica la función seno en el display
dx = (2 * math.pi) / WIDTH
for px in range(WIDTH):
x = dx * px
fx = math.sin(x)
# Escala fx al rango_y y a la pantalla
yp = int(HEIGHT//2 - fx * (HEIGHT//2 - 2) / rango_y)
if 0 <= yp < HEIGHT:
oled.pixel(px, yp, 1)
def mapear(valor, in_min, in_max, out_min, out_max):
# Mapea 'valor' del rango [in_min, in_max] al rango [out_min, out_max]
return (valor - in_min) * (out_max - out_min) / (in_max - in_min) + out_min
while True:
oled.fill(0)
x.mapear
# Leer ADCs del joystick
val_x = joy_x.read_u16()
val_y = joy_y.read_u16()
# Leer ADC del rango para seno
val_range = adc_range.read_u16()
rango_y = 0.5 + (val_range / 65535) * 2.5 # Rango de 0.5 a 3.0
# Graficar ejes y seno
draw_axes()
graficar_seno(rango_y)
# Escalar joystick a coordenadas del display
x = escalar(val_x, WIDTH-3)
y = escalar(val_y, HEIGHT-3)
# Limitar bordes
x = max(2, min(x, WIDTH-3))
y = max(2, min(y, HEIGHT-3))
# Dibujar cruz (5 píxeles)
oled.pixel(x, y, 1) # centro
oled.pixel(x-1, y, 1) # izquierda
oled.pixel(x+1, y, 1) # derecha
oled.pixel(x, y-1, 1) # arriba
oled.pixel(x, y+1, 1) # abajo
# Mapeo a escala matemática
x_matematico = mapear(x, 0, WIDTH-1, -10, 10)
y_matematico = mapear(y, 0, HEIGHT-1, 10, -10)
# Mostrar coordenadas y rango
oled.text("X:{:3}".format(x), 0, 0)
oled.text("Y:{:3}".format(y), 64, 0)
oled.text("Xm:{:4.2f}".format(x_matematico), 0, 10)
oled.text("Ym:{:4.2f}".format(y_matematico), 64, 10)
oled.text("R:{:.1f}".format(rango_y), 0, 56)
oled.show()
time.sleep(0.05)