from machine import Pin, PWM  # type: ignore
from micropython import const  # type: ignore
from time import sleep_ms
import struct
import random

# Definiciones de constantes
BAUDRATE = const(19200)
FREQUENCY_PWM = const(10)
VEL_RANGE = (-5000, 5000)  # Velocidad en mm/s (máx. +-5000)
TEMP_RANGE = (0, 3000)  # Temperatura en centésimas de grado (0.01°C por unidad)
MAX_VEL_TOTAL = 20000  # Ahora el 100% de PWM es a 20000 mm/s

# Inicializar PWM
velocity_pwm = PWM(Pin(0))
velocity_pwm.freq(FREQUENCY_PWM)
temperature_pwm = PWM(Pin(1))
temperature_pwm.freq(FREQUENCY_PWM)

# Fake UART con generación cíclica de tramas ADCP
class FakeUART:
    def __init__(self):
        self.index = 0
    
    def generate_trama(self):
        """Genera una trama ADCP de 57 bytes con valores aleatorios dentro del rango"""
        trama = bytearray(57)
        
        # Generar valores de velocidad en mm/s (byte 3-8)
        vx = random.randint(*VEL_RANGE)
        vy = random.randint(*VEL_RANGE)
        vz = random.randint(*VEL_RANGE)
        trama[3:5] = struct.pack('<h', vx)  # LSB primero
        trama[5:7] = struct.pack('<h', vy)
        trama[7:9] = struct.pack('<h', vz)
        
        # Generar temperatura en centésimas de grado (byte 52-53)
        temp = random.randint(*TEMP_RANGE)
        trama[52:54] = struct.pack('<h', temp)
        
        return trama
    
    def readline(self):
        return self.generate_trama()

# Inicializar UART simulado
uart = FakeUART()

def map_to_16bits(value: float, value_range: tuple) -> int:
    """Mapea un valor dentro de un rango dado al rango de 16 bits (0-65535)."""
    mapped = int(((value - value_range[0]) / (value_range[1] - value_range[0])) * 65535)
    return max(0, min(mapped, 65535))  # Asegurar que está entre 0 y 65535

# Bucle principal
while True:
    sample = uart.readline()  # Leer trama ADCP simulada
    
    # Extraer velocidades y temperatura (corrección de índices)
    vx, vy, vz = struct.unpack('<hhh', sample[3:9])
    temp = struct.unpack('<h', sample[52:54])[0] / 100  # Convertir a °C
    
    # Calcular módulo de la velocidad total
    v_total = (vx**2 + vy**2 + vz**2) ** 0.5
    
    # Mapear a rango PWM con el nuevo límite de 20,000 mm/s
    velocity_u16 = map_to_16bits(v_total, (0, MAX_VEL_TOTAL))  
    temperature_u16 = map_to_16bits(temp * 100, TEMP_RANGE)  
    
    # Enviar señal PWM
    velocity_pwm.duty_u16(velocity_u16)
    temperature_pwm.duty_u16(temperature_u16)

    # Calcular duty cycle
    duty_velocity = (velocity_u16 / 65535) * 100
    duty_temperature = (temperature_u16 / 65535) * 100

    # Mostrar en consola (mejorado)
    print(f"""
Velocidades (mm/s):
    X: {vx:6}, Y: {vy:6}, Z: {vz:6}
    Módulo total: {v_total:8.2f} mm/s
    PWM Duty Cycle (Velocidad): {duty_velocity:6.2f} %

Temperatura:
    °C: {temp:8.2f}
    PWM Duty Cycle (Temperatura): {duty_temperature:6.2f} %
--------------------------------------------""")
    
    sleep_ms(125)  # Esperar 125ms antes de la próxima muestra
BOOTSELLED1239USBRaspberryPiPico©2020RP2-8020/21P64M15.00TTT
D0D1D2D3D4D5D6D7GNDLOGIC