/*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; }