How to Achieve Any Resistance/Capacitance Using Components You Already Have!

Introduction: How to Achieve Any Resistance/Capacitance Using Components You Already Have!

About: Hello, my name is Michael. I am an electrical and computer engineer turned educator. I have a lot of experience in embedded software and hardware design. I am taking my technical experiences and leveraging t...

This is not just another series/parallel equivalent resistance calculator! This program calculates how to combine resistors/capacitors that you presently have to achieve a target resistance/capacitance value that you need.

Have you ever needed a specific resistor or capacitor that you don't have or that doesn't exist? Have no fear! You can probably make that specific resistance or capacitance value using components you already have. Instead of solving a huge multivariable optimization problem with millions of different combinations, use this program!

Just select resistor or capacitor, enter the target value, input the max number of components you would like to use, enter a list of the values of the components you have, and click calculate! The program will spit out what components to use and how to connect them to achieve your target value.

To try out the calculator, visit this web application.

To view the source code, visit this Github repository.

Please let me know if you have any suggestions to further improve the usability of this design tool!

Teacher Notes

Teachers! Did you use this instructable in your classroom?
Add a Teacher Note to share how you incorporated it into your lesson.

Step 1: Background

This web application was developed out of necessity. There are many different circuits I construct that demand a very specific resistor or capacitor. A lot of times, I don't have a resistor or capacitor with that specific value. Sometimes they don't even make a component with that unique value! Instead of giving up or settling for something that's less than ideal, I decided to write a program to look at every possible combination of resistors (every possible value and whether they are in series or parallel) and return the best combination.

When designing the circuit for my organ as a part of my Battle of the Bands Instructable Project, I had to try to hand calculate the best combination of capacitors to achieve a specific frequency. This process was incredibly tedious and I eventually just gave up and went with capacitor combinations that produced any amount of audible frequency. Now with this web application, I can design my organ for a specific frequency and tune it to the notes on a keyboard! The equation below is used to calculate the specific frequency and is discussed in the other Instructables project.

f = 1 / (0.693×C×(R1 + 2×R2))

Using this equation where R1 = 100 kOhm and R2 = 10 kOhm, I calculated that a 27.33 nF capacitor will produce an A4 note (frequency 440 Hz). Using my program, I was able to calculate an equivalent capacitance value within .001 nF (much less than the tolerance on a standard capacitor) that I can create using capacitors I already had lying around. The resulting output and configuration is described below. I am now able to much more efficiently and effectively tune my organ to the exact frequencies of standard notes. I wish I had done this to begin with. My demo song on the organ probably would have sounded much better.

Closest Value: 27.329 nF
Difference: 0.001 nF
Capacitor Configuration: C0=0.068 nF || C1=30 nF + C2=300 nF

Resistor Capacitor Equivalence Equations

For reference, below are the equivalence equations for combining resistors and capacitors in a circuit.

  • Resistors in series (R1 + R2): Req = R1 + R2
  • Resistors in parallel (R1 || R2): Req = 1 / (1/R1 + 1/R2)
  • Capacitors in series (C1 + C2): Ceq = 1 / (1/C1 + 1/C2)
  • Capacitors in parallel (C1 || C2): Ceq = C1 + C2

Step 2: Inputs

There are 4 inputs you will need to provide:

  1. Whether you are calculating a value for a resistor or a capacitor.
  2. The target resistance or capacitance value and the units.
  3. The maximum number of components you would like to use to achieve the target value (i.e. I would not like to use more than 3 resistors to achieve my target resistance value).
  4. The list of values for the resistors/capacitors you presently have. These values should be in the same units as your target value (i.e. if your target value was 110 nF, all of your values should be provided in nF).

Step 3: Result

You will get 3 outputs for your result:

  1. Closest Value - the closest resistance/capacitance value you were able to achieve with your parameters.
  2. Difference - how far off your closest value was from your target value.
  3. Resistor/Capacitor Configuration - a list of values of the resistors/capacitors to use and their configuration.

Step 4: Understanding Your Result

The configuration output uses a standard notation. "+" means the components are in series and "||" means the components are in parallel. The operators have equal precedence and are left-to-right associative meaning you group terms together starting from the left and moving to the right.

For example, take a look at the following result:

Resistor Configuration: R0=15 Ohms + R1=470 Ohms || R2=3300 Ohms + R3=15000 Ohms

If you follow the guidelines discussed above, you can see that this is equivalent to the following equation and image above.

((R0+R1)||R2)+R3

Step 5: More Projects

Step 6: Source Code

To view the source code, visit this Github repository or see the JavaScript below.

/* --------------------------------------------------------------- */
/*                   r/c calculator scripting                      */
/* ----------------------------------------------------------------*/
var closest_val; // closest value so far
var closest_diff = 1000000.00; // diff of val and target
var closest = []; // array detailing values of components
var ser_par_config = []; // array detailing serial/parallel

var outputStr = "";

function calculatorClick() {
	// clear out global values for each new click
	closest_val = 0;
	closest_diff = 1000000.00;
	closest = [];
	ser_par_config = [];

	var resultDisplay = document.getElementById("resultRow");
	var exampleDisplay = document.getElementById("exampleRow");
	var calcOutput = document.getElementById("calcOutput");
	var targetTextObj = document.getElementById('targetText');
	var numCompTextObj = document.getElementById('numCompText');
	var compValsTextObj = document.getElementById('compValsText');
	var target = parseFloat(targetTextObj.value);
	var numComp = parseInt(numCompTextObj.value);
	var compValsStr = compValsTextObj.value;

	var compVals = [];
	compVals[0] = "";
	var i = 0;
	var errFlag = 0;

	// error in parsing target value
	if (isNaN(target)) {
		outputStr = "Error check 'Target Value' input! <br>"
	}
	// error in parsing number of components
	else if (isNaN(numComp)){
		outputStr = "Error check 'Number of Components' input! <br>"
	}
	// else if no error in target or numComp
	else if (!isNaN(target) && !isNaN(numComp)) {
		while (compValsStr.indexOf(",") != -1) {
			var comma = compValsStr.indexOf(",");
			var newInt = parseFloat(compValsStr.substring(0,comma));
			// error in parsing component value list, set flag
			if (isNaN(newInt)) {
				errFlag = 1;
				break;
			}
			compValsStr = compValsStr.substring(comma+1,compValsStr.length);
			compVals[i] = newInt;
			i++;
		}
		var newInt = parseFloat(compValsStr);
		// error in parsing component value list, set flag
		if (isNaN(newInt)) {
			errFlag = 1;
		}
		compVals[i] = newInt;
		if (errFlag == 0) {
			if (document.getElementById("resRadio").checked) {
				resistor(target, numComp, compVals);
			}
			else if (document.getElementById("capRadio").checked) {
				capacitor(target, numComp, compVals);
			}
		}
		// error in parsing component value list
		else {
			outputStr = "Error check 'Component Values List' input! <br>"
		}
	}

	calcOutput.innerHTML = outputStr;
	resultDisplay.style.display = "block";
	exampleDisplay.style.display = "flex";

	// scroll down to result
	window.scrollTo(0,exampleDisplay.scrollHeight);
}

/*
Retrieves and prints the best resistor configuration
	* target - target resistance value
	* numComp - total number of resistors allowed to be used to achieve target val
	* compVals - array of resistor values
*/
function resistor(target, numComp, compVals) {
	// length of resistance values
	var num_res = compVals.length;

	// run through all possible number of components
	for (var i=1; i<=numComp; i++) {
		var data = [];
		resCombination(compVals, num_res, i, 0, data, target);
	}

	var units = document.getElementById("selected_unit").value;

	// print results
	outputStr = "Closest Value: " + closest_val.toFixed(3) + " " + units + " <br>";
	outputStr += "Difference: " + closest_diff.toFixed(3) + " " + units + " <br>";
	outputStr += "Resistor Configuration: ";
	for (var i=0; i<numComp; i++) {
		if (i<closest.length) {
			outputStr += "R" + i + "=" + closest[i] + " " + units + " ";
			if (i+1<closest.length) {
				if (ser_par_config[i+1]) outputStr += "|| ";
				else outputStr += "+ ";
			}
		}
		else break;
	}
}

/*
Calculates the best combination of resistors to achieve a target value.
	* res[] - input array of resistor values
	* num_res	- size of input array of resistor values
	* num_comb	- number of resistors allowed
	* index - index of comb[]
	* comb[] - array of current combination
	* target - the target value
	* No return value - passes current best combination to global values
*/
function resCombination(res, num_res, num_comb, index, comb, target) {
	// current combination is complete
	if (index == num_comb) {
		var ser_par_size = Math.pow(2,num_comb); // 2^(number of components)
		var ser_par = []; // bool array specifying serial or parallel for each component
		var calc; // calculated equivalent resistance value

		// step through every possible series/parallel config of current combination
		for (var j=0; j<ser_par_size; j++) {
			calc = 0.0;
			// creates a boolean array of 0s & 1s for all possible combinations
			for (var k=0; k<num_comb; k++) {
				ser_par[k] = (j >> k) & 1;
			}
			// do the calculations for the combination based on series/parallel combo
			for (var k=0; k<num_comb; k++) {
				// first number, just add
				if (k==0) calc = comb[k];
				// zero means series, add resistance values
				else if (!ser_par[k]) calc += comb[k];
				// one means parallel, inverse of the sum of reciprocals
				else if (ser_par[k]) calc = (calc*comb[k])/(calc+comb[k]);
			}

			// check to see if difference is less than previous best
			if (Math.abs(calc - target) < closest_diff) {
				// it is less, so update global values
				closest_val = calc;
				closest_diff = Math.abs(calc - target);
				// clear to zero
				for (var k=0; k<num_comb; k++) {
					closest[k] = 0;
				}
				// update closest value & series/parallel arrays
				for (var k=0; k<num_comb; k++) {
					closest[k] = comb[k];
					ser_par_config[k] = ser_par[k];
				}
			}
		}
		return 0;
	}

	// recursively call and replace the index with all possible values
	for (var i=0; i<=num_res && num_res-i+1 >= num_comb-index; i++) {
		comb[index] = res[i];
		resCombination(res, num_res, num_comb, index+1, comb, target);
	}
}

/*
Retrieves and prints the best capacitor configuration
	* target - target capacitance value
	* numComp - total number of capacitors allowed to be used to achieve target val
	* compVals - array of capacitor values
*/
function capacitor(target, numComp, compVals) {
	// length of capacitance values
	var num_cap = compVals.length;

	// run through all possible number of components
	for (var i=1; i<=numComp; i++) {
		var data = [];
		capCombination(compVals, num_cap, i, 0, data, target);
	}

	var units = document.getElementById("selected_unit").value;

	// print results
	outputStr = "Closest Value: " + closest_val.toFixed(3) + " " + units + " <br>";
	outputStr += "Difference: " + closest_diff.toFixed(3) + " " + units + " <br>";
	outputStr += "Capacitor Configuration: ";
	for (var i=0; i<numComp; i++) {
		if (i<closest.length) {
			outputStr += "C" + i + "=" + closest[i] + " " + units + " ";
			if (i+1<closest.length) {
				if (ser_par_config[i+1]) outputStr += "|| ";
				else outputStr += "+ ";
			}
		}
		else break;
	}
}

/*
Calculates the best combination of capacitors to achieve a target value.
	* cap[] - input array of capacitor values
	* num_cap	- size of input array of capacitor values
	* num_comb	- number of capacitors allowed
	* index - index of comb[]
	* comb[] - array of current combination
	* target - the target value
	* No return value - passes current best combination to global values
*/
function capCombination(cap, num_cap, num_comb, index, comb, target) {
	// current combination is complete
	if (index == num_comb) {
		var ser_par_size = Math.pow(2,num_comb); // 2^(number of components)
		var ser_par = []; // bool array specifying serial or parallel for each component
		var calc; // calculated equivalent capacitance value

		// step through every possible series/parallel config of current combination
		for (var j=0; j<ser_par_size; j++) {
			calc = 0.0;
			// creates a boolean array of 0s & 1s for all possible combinations
			for (var k=0; k<num_comb; k++) {
				ser_par[k] = (j >> k) & 1;
			}
			// do the calculations for the combination based on series/parallel combo
			for (var k=0; k<num_comb; k++) {
				// first number, just add
				if (k==0) calc = comb[k];
				// zero means series, inverse of the sum of reciprocals
				else if (!ser_par[k]) calc = (calc*comb[k])/(calc+comb[k]);
				// one means parallel, add capacitance values
				else if (ser_par[k]) calc += comb[k];
			}

			// check to see if difference is less than previous best
			if (Math.abs(calc - target) < closest_diff) {
				// it is less, so update global values
				closest_val = calc;
				closest_diff = Math.abs(calc - target);
				// clear to zero
				for (var k=0; k<num_comb; k++) {
					closest[k] = 0;
				}
				// update closest value & series/parallel arrays
				for (var k=0; k<num_comb; k++) {
					closest[k] = comb[k];
					ser_par_config[k] = ser_par[k];
				}
			}
		}
		return 0;
	}

	// recursively call and replace the index with all possible values
	for (var i=0; i<=num_cap && num_cap-i+1 >= num_comb-index; i++) {
		comb[index] = cap[i];
		capCombination(cap, num_cap, num_comb, index+1, comb, target);
	}
}

Be the First to Share

    Recommendations

    • LED Strip Speed Challenge

      LED Strip Speed Challenge
    • Sculpting Challenge

      Sculpting Challenge
    • Clocks Contest

      Clocks Contest

    Discussions