Files
max668_calc/lib/max_functions.c
2021-04-14 14:37:03 +02:00

95 lines
3.5 KiB
C

/*max_functions.c*/
#include"max_functions.h"
int set_output_voltage(double setpoint_voltage, ESeries E_resistors) {
bool solution_found = false;
int decade_max = 6;
int decade_min = 1;
double R_high_resistance = 0.0;
double R_low_resistance = 0.0;
//start at 10k for low resistor and at minimum for high resistor
int R_high_decade = decade_min;
int R_low_decade = 4;
double R_high_value = 1.00;
double R_low_value = 1.00;
// voltage computed from resistor configuration used to compare new result to previous optimum
double output_voltage = 0.0;
double output_voltage_w = 0.0;
// set the max array index for given e series
unsigned int e_max_values = get_E_MAX(E_resistors);
if (e_max_values == E_NIL) {
printf("max668_calc:max_functions:set_output_voltage: Unknown E series.\n");
return EXIT_FAILURE;
}
// working variables
int R_high_decade_w = R_high_decade;
int R_low_decade_w = R_low_decade;
double R_high_value_w = R_high_value;
double R_low_value_w = R_low_value;
/*
* start at minimum given Rlow from datasheet and select optimal Rhigh for given Rlow and Vout.
* do this for all possible Rlows and choose the optimal combination
* (minimize |setpoint_voltage - output_voltage|)
*/
for(int i_low = R_low_decade; i_low <= 6; i_low++) {
R_low_decade_w = i_low;
for (int j_low = 0; j_low <= e_max_values; j_low++) {
// in the 6th decate only examine R_low = 1M, then stop
if ( i_low == 6 && j_low > 0 )
break;
// select new R_low
R_low_value_w = E_values[E_resistors][j_low];
R_low_resistance = R_low_value_w * exp(log(10)*R_low_decade_w);
// calculate corresponding R_high
R_high_resistance = R_low_resistance *((setpoint_voltage/1.25)-1);
R_high_decade_w = floor(log10(R_high_resistance));
R_high_value_w = round_to_E_series((R_high_resistance / exp(log(10)*R_high_decade_w)), E_resistors);
// calculate the acchieved outputvoltage for resistor combination from the given E series
output_voltage_w = 1.25 * ((R_high_resistance/R_low_resistance) + 1);
// if the calculated resistance is too small or too great, ignore it
if (R_high_decade_w > decade_max || R_high_decade_w < decade_min)
continue;
// if a new optimum is found -> save the values
if (fabs(output_voltage - setpoint_voltage) > fabs(output_voltage_w - setpoint_voltage)) {
R_high_decade = R_high_decade_w;
R_high_value = R_high_value_w;
R_low_decade = R_low_decade_w;
R_low_value = R_low_value_w;
output_voltage = output_voltage_w;
solution_found = true;
}
}
}
// report the found optimal resistor combination in the given E series
if (solution_found) {
printf("Found optimal combination for R_high / R_low: \n");
printf("R_low: %5.2fE%i ohms\n",R_low_resistance,R_low_decade);
printf("R_high: %4.2fE%i ohms\n",R_high_resistance,R_high_decade);
printf("Achieved output_voltage:");
printf("V_out: %4.2f",output_voltage);
}
else {
printf("max668_calc:max_functions:set_output_voltage: Unable to find valid resistance combination within given range.\n");
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}