""" Physical unit conversions for laser control module. Converts between physical quantities (°C, mA, V) and raw ADC/DAC integer values used by the device firmware. All formulas are taken directly from the original device_conversion.py. """ import math from .constants import ( VREF, R1, R3, R4, R5, R6, R7, R8, R9, R10, RREF, BETA_INTERNAL, BETA_EXTERNAL, T0_K, R0, ADC_BITS_16, ADC_BITS_12, U3V3_COEFF, U5V_COEFF, U7V_COEFF, ) def temp_c_to_n(temp_c: float) -> int: """ Convert temperature (°C) to 16-bit DAC integer (Wheatstone bridge setpoint). Args: temp_c: Temperature in degrees Celsius. Returns: Integer in [0, 65535] for the DAC. """ rt = R0 * math.exp(BETA_INTERNAL / (temp_c + 273) - BETA_INTERNAL / T0_K) u = VREF / (R5 * (R3 + R4)) * ( R1 * R4 * (R5 + R6) - rt * (R3 * R6 - R4 * R5) ) / (rt + R1) n = int(u * ADC_BITS_16 / VREF) n = max(0, min(ADC_BITS_16, n)) return n def temp_n_to_c(n: int) -> float: """ Convert 16-bit ADC integer to temperature (°C). Args: n: Raw ADC value in [0, 65535]. Returns: Temperature in degrees Celsius. """ u = n * VREF / ADC_BITS_16 rt = R1 * (VREF * R4 * (R5 + R6) - u * R5 * (R3 + R4)) / ( u * R5 * (R3 + R4) + VREF * R3 * R6 - VREF * R4 * R5 ) t = 1 / (1 / T0_K + 1 / BETA_INTERNAL * math.log(rt / R0)) - 273 return t def temp_ext_n_to_c(n: int) -> float: """ Convert 12-bit ADC integer to external thermistor temperature (°C). Args: n: Raw 12-bit ADC value in [0, 4095]. Returns: Temperature in degrees Celsius. """ u = n * VREF / ADC_BITS_12 * 1 / (1 + 100000 / R10) + VREF * R9 / (R8 + R9) rt = R7 * u / (VREF - u) t = 1 / (1 / T0_K + 1 / BETA_EXTERNAL * math.log(rt / R0)) - 273 return t def current_ma_to_n(current_ma: float) -> int: """ Convert laser drive current (mA) to 16-bit DAC integer. Args: current_ma: Current in milliamps. Returns: Integer in [0, 65535] for the DAC. """ n = int(ADC_BITS_16 / 2000 * RREF * current_ma) n = max(0, min(ADC_BITS_16, n)) return n def current_n_to_ma(n: int) -> float: """ Convert raw ADC integer to photodiode current (mA). Args: n: Raw ADC value in [0, 65535]. Returns: Current in milliamps. """ return n * 2.5 / (ADC_BITS_16 * 4.4) - 1 / 20.4 def voltage_3v3_n_to_v(n: int) -> float: """Convert 3.3V rail ADC count to volts.""" return n * U3V3_COEFF def voltage_5v_n_to_v(n: int) -> float: """Convert 5V rail ADC count to volts (both 5V1 and 5V2).""" return n * U5V_COEFF def voltage_7v_n_to_v(n: int) -> float: """Convert 7V rail ADC count to volts.""" return n * U7V_COEFF