114 lines
2.8 KiB
Python
114 lines
2.8 KiB
Python
"""
|
|
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 |