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