microscope-ring-light/pcb/lp8867-calc.py

101 lines
2.8 KiB
Python
Executable File

#!/bin/python
import numpy as np
import eseries as es
def calc_fsw_from_r_fset(r_fset):
fsw = 67600 / (r_fset / 1e3 + 6.4)
fsw = fsw * 1e3
return fsw
def calc_r_fset_from_fsw(fsw):
fsw = fsw / 1e3
r = 67600 / (fsw) - 6.4
r = r * 1e3
return r
def calc_r_iset_from_i(i):
i = i * 1e3
r = 2000 * 1.2 / i
r = r * 1e3
return r
def calc_i_from_r_iset(r):
r = r * 1e-3
i = 2000 * 1.2 / r
i = i * 1e-3
return i
def calc_vout(r1, r2, k):
r1 = r1 / 1000
r2 = r2 / 1000
v = (1.2 / r2 + k * 0.0387) * r1 + 1.2
return v
switching_freq = 1.1e6
output_voltage_nom = 24 + 0.9
inductor_value = 22e-6
input_voltage = 12
output_current_per_lane = 110e-3
desired_e_series = es.E12
r1 = 560e3
r2 = 100e3
# Calculate the parameters
print('Calculating for the given parameters:')
print(f'{switching_freq = }')
print(f'{output_voltage_nom = } and {input_voltage = }')
print(f'{inductor_value =}')
print(f'{desired_e_series = }')
print('')
rfset = calc_r_fset_from_fsw(switching_freq)
print(f'{rfset = }')
# Find the nearest value in the e series
rfset = es.find_nearest(desired_e_series, rfset)
f_sw = calc_fsw_from_r_fset(rfset)
print(f'The nearest value from the E series is: {rfset = }')
freq_error = (f_sw - switching_freq) / switching_freq * 100
print(f'Resulting switching frequency is {f_sw} (Error: {freq_error:.1f} %)')
print(f"Desired output current per lane is {output_current_per_lane} A")
r_iset = calc_r_iset_from_i(output_current_per_lane)
print(f'Resulting in {r_iset = }')
r_iset = es.find_nearest(desired_e_series, r_iset)
output_current_per_lane = calc_i_from_r_iset(r_iset)
print(f'Nearest e series value {r_iset = } resulting in an LED current of {output_current_per_lane} A')
d = (output_voltage_nom - input_voltage) / output_voltage_nom
d_inv = 1-d
print(f"Expected duty cycle: {d}")
i_ripple = (output_voltage_nom- input_voltage) / (2 * inductor_value * f_sw) * (input_voltage / output_voltage_nom)
print(f'Ripple current: {i_ripple} A')
i_sat_min = output_current_per_lane * 4 / d_inv + i_ripple
print(f'Minimum saturation current of inductor: {i_sat_min:.3f} A')
print(f'Voltage divider {r1 = } | {r2 = }')
print(f'Output voltage initial: {calc_vout(r1, r2, 0.88)} V')
print(f'Output voltage maximum: {calc_vout(r1, r2, 1)} V')
print(f'Output voltage minimum: {calc_vout(r1, r2, 0)} V')
ovp = output_voltage_nom + (r1/r2 + 1)*(2.3 - 1.2)
print(f'Over voltage protection: {ovp} V')
ratio = r1/r2
print(f'Resistance ratio is {ratio}')
if f_sw <= 1150e3:
ratio_range = (5, 10)
else:
ratio_range = (10, 20)
if ratio < ratio_range[0] or ratio > ratio_range[1]:
print('Ratio is outside recommended limits!')
else:
print('Resistance ratio is inside recommended limits')
# Loop stability
cfb = 1 / (2 * np.pi * 20e3 * r1 )
print(f'Loop stability capacitor value: {cfb} F')