Multiple resistor dividers BOM optimisation - Page 1
Forum section: electronics / projects

author: bobof
author_rank: Contributor
timestamp: July 21, 2021, 01:57:55 pm
content: I'm wondering if any program exists that could solve:1) You have a bunch of dividers you need (eg SMPSU voltage setting)2) You'd like to achieve these ratios with the minimum number of distinct resistor values possible to an acceptable level of tollerance (I hate BOM singletons)3) There are already some resistors in your design you "get for free" as they are already in use elsewhere, which could be used with a lesser cost on your design.So far I'm yet to find anything that attempts to solve such a problem. Sure, there are a bunch of simple calculators available that will work out for a single ratio required what are optimal resistors in a given series, but nothing to try and optimise several ratios at once.Anyone know if such a thing exists?

author: Terry Bites
author_rank: Super Contributor
timestamp: July 21, 2021, 03:13:49 pm
content: Kill me now! Excel goal seek....

author: bobof
author_rank: Contributor
timestamp: July 21, 2021, 03:24:45 pm
content: Kill you? It would probably kill me. I think you'd likely find me hanging from my excess reels of 38K3 and 124K resistors...!I'm really imagining something more powerful than that, that takes a list of the ratios you want to hit (along with tolerances, maybe some other parameters for selection like max current through divider), the values of the "free" resistors from elsewhere in the CCTs, and provides you with BOM options, ranked by number of new, unique lines and closeness to target ratios.

author: David Hess
author_rank: Super Contributor
timestamp: July 21, 2021, 04:37:10 pm
content: In the past I have written a program as needed to find the minimum number of different resistance values to make a specific number of dividers.

author: bobof
author_rank: Contributor
timestamp: July 21, 2021, 05:42:58 pm
content: Quote from: David Hess on July 21, 2021, 04:37:10 pmAm just in the process of doing exactly that, as google search for something prepacked turned up nothing obviously directly suitable. Did find some python with most of the resistor series defined, though, which will save me that particular bit of drudgery...

author: David Hess
author_rank: Super Contributor
timestamp: July 21, 2021, 08:56:12 pm
content: Quote from: bobof on July 21, 2021, 05:42:58 pmI am sure the way I have done it is not even close to ideal, but personal computers have been fast enough now for decades that brute force is not too much of a problem. First I generate an exhaustive table indexed on the values calculated from every potential combination, and then for every value that I want to produce, I can index back into the table to find the various combinations and do something like a traveling salesman search to find some smaller set of resistors which produce all of the values that I want.

author: bobof
author_rank: Contributor
timestamp: July 21, 2021, 09:05:01 pm
content: Quote from: David Hess on July 21, 2021, 08:56:12 pmThat's pretty much what I'm doing now. Will be useful in future to have in the library...

author: Benta
author_rank: Super Contributor
timestamp: July 21, 2021, 09:25:26 pm
content: You're overlooking the main problem, which is how the E-series is defined.It's basically an exponential function of values with the same increment in the exponent.This means, that if you try to find resistor values for, say, a ratio of 27/40, and no resistor ratio will give you this, you can scale the resistor values up and down until the end of time, but you'll NOT find a match. Sorry.For certain voltage division ratios you need a third resistor (just a small one on one of the legs).

author: Benta
author_rank: Super Contributor
timestamp: July 21, 2021, 09:56:01 pm
content: BTW, if you want to generate your own E48/96/192 resistor tables, here are the equations (easier than typing them in).E48:x = 10^(n/48) n=0...47E96:x = 10^(n/96) n=0...95E192:x = 10^(n/192) n=0...191All rounded to to 2 decimals. Very easy to do in a spreadsheet.For E3/6/12/24, they deviate from this formula and need to be typed manually.

author: bobof
author_rank: Contributor
timestamp: July 21, 2021, 10:23:03 pm
content: Quote from: Benta on July 21, 2021, 09:25:26 pmFor me this is not likely to be a practical problem. I'm assuming I'm happy for the ratio to be +/- some tolerance. Do I care if my DDR voltage is defined as 1.347V instead of 1.35V assuming "perfect" resistors? Of course not.So far I've made something that takes in CSV of input voltage, output voltage and tolerance. It then goes through some chosen value set (E12,24,48,96,192,or ALL) to find which resistor pairs can satisfy the chosen tolerance. For the moment it is just a "helper" - it counts how many times each value is able to be used, and tells you which ones have highest usage, which you can use to assist making manual selection pretty quickly.I'm just now working out how python itertools works so that I can brute force all the combinations that satisfy the tolerance. By taking into account resistor values I already have elsewhere in my design I will be able to work out what is the least number of extra values I can add to the design and hit my tolerance targets.That's the plan, anyhow...

author: bobof
author_rank: Contributor
timestamp: July 21, 2021, 10:26:11 pm
content: Quote from: Benta on July 21, 2021, 09:56:01 pmThanks, I didn't know that; but as soon as one of them is special and needs to be typed, it's probably easier to just type them all! I found the lists online in comma separated format so it was very easy to copy / paste into a python list.

author: Mr. Wizard
author_rank: Unknown
timestamp: July 21, 2021, 10:33:10 pm
content: If you only care about the number of distinct resistorvaluesand not the total number of resistors you’re using, I’d say just use 1 Ω resistors. If you need a 1000 Ω resistor, simply put a thousand of them in series, etc.

author: bobof
author_rank: Contributor
timestamp: July 21, 2021, 10:40:36 pm
content: Quote from: Mr. Wizard on July 21, 2021, 10:33:10 pmNot sure how that would help given the title of the thread (...BOM optimisation). The aim I thought was pretty obviously to optimise both the number of different resistors and the total number of resistors to achieve BOM optimisation (along with incidental reductions in assembly / setup costs). But I'm sure you knew that...

author: Mr. Wizard
author_rank: Unknown
timestamp: July 21, 2021, 10:52:09 pm
content: Quote from: bobof on July 21, 2021, 10:40:36 pmThose may not necessarily be congruent goals. To make it work, you will need to assign some cost to adding a new line to your bill of materials versus adding more of any particular item.Do you happen to have a real-world problem with actual values you need and an actual resistors BOM that you could share here?

author: Benta
author_rank: Super Contributor
timestamp: July 21, 2021, 11:04:22 pm
content: Quote from: bobof on July 21, 2021, 10:26:11 pmI don't think so.Attached is a spreadsheet thrown together in 10 minutes. I hope it's helpful. The anomalies are highlighted.

author: wizard69
author_rank: Super Contributor
timestamp: July 21, 2021, 11:47:06 pm
content: So how far do you go here with the BOM optimization? It sounds like you would be dramatically increasing the cost of you boards if you did this too much. Cost here being money + complexity. I understand the goal to an extent but would you seriously replace one standard resistor with a whole bank of series parallel resistors to achieve the same thing, just too avoid adding one resistor to a BOM?This is truly interesting to me as I wonder where is the proper cut off point. I often see this in the automation world where engineers will use their favorite fiber optic unit instead of looking for one that fits the application at hand. That is just an example but such approaches often lead to sub optimal behavior.Quote from: bobof on July 21, 2021, 10:40:36 pm

author: SiliconWizard
author_rank: Super Contributor
timestamp: July 22, 2021, 12:13:40 am
content: I don't think such a program exists per se (although you never know what people may have done for their own use), but you could write it yourself in your favorite language.I myself have written functions (in Lua) for determining resistor values for a divider, taking the ratio, an acceptable range for the values (there is often a required range, you can't just pick any random values depending on the application), and the range of E-series to choose from. It yields the closest match for the ratio. I suppose I could elaborate on it to write something that would list all possible values given a max allowed error for the ratio, instead of just the closest match, and then call it for all dividers in a design. Then there would be a table of tables of values. Another function would just go through that and minimize the total number of distinct values required.I have a feeling that in many cases, it would not find many repeated values, unless you're very lucky, but at least it would help you know that you can't do better.

author: bobof
author_rank: Contributor
timestamp: July 22, 2021, 12:17:59 am
content: Quote from: wizard69 on July 21, 2021, 11:47:06 pmI wouldn't, no. I wouldn't probably even replace one standard resistor with two parallel or series resistors to optimise, as the schematic is usually done by this point, and I'm usually short of space. Though I can see in some applications it might well make sense. This is for me a very simple exercise - using a single part per position, how few distinct new parts can I add to the BOM and achieve desired dividers to acceptable quality.

author: bobof
author_rank: Contributor
timestamp: July 22, 2021, 12:30:09 am
content: Quote from: SiliconWizard on July 22, 2021, 12:13:40 amI've just made a Python script that does this based on a very dirty hack of something I found on github (https://github.com/efosmark/voltage-divider), though it doesn't do the checking of valid ranges - that's an exercise for the engineer at the moment.CSV file format is each line has desired voltage, supply voltage, tolerance (%).command line is something like:python3 ./divider3.py --value_set ALL values.csvNo error checking or even checking for tolerance being too tight. It's the barest of minimum...

author: mc172
author_rank: Frequent Contributor
timestamp: July 22, 2021, 01:11:50 am
content: This one I found a while ago lets you select which values you have available:http://jahonen.kapsi.fi/Electronics/ResOptimizer/

author: bobof
author_rank: Contributor
timestamp: July 22, 2021, 07:30:25 am
content: Thanks, I see that does a much more comprehensive job of the searching side for the values, but would be much more manual for solving a bunch of dividers together.I think with a couple more bits of functionality (spanning more than 1 decade, taking advantage of "free" resistor values from the design) I'll have something pretty useful to me.

author: bobof
author_rank: Contributor
timestamp: July 22, 2021, 05:54:21 pm
content: Pretty pleased with the results I've managed to get by fiddling with the Python script. Was able to add the 5 dividers I needed - to an acceptable level of accuracy - by adding only 3 new unique E24 values to the BOM above the parts that I already needed elsewhere. So I pretty easily removed 7 BOM lines that had been added by the various DC/DC converter design tools.I can see though where the very dumb brute force approach starts to strain - as you add more dividers the problem gets much bigger and I start running out of memory; if I can be bothered I might try and work out how to optimise.

author: EPAIII
author_rank: Super Contributor
timestamp: July 23, 2021, 08:35:05 am
content: I think you are trying to optimize several different things without any way to judge just how the balance between them should work: lowest possible parts count, lowest possible number of part values. and minimize board space. Perhaps you have even more that you have not mentioned?The first thing you should do is to formulate a clear statement of just how you want this to work. Which of those is the most important? Or how does the balance between A and B operate. And then how does it operate with A, B, and C.Oh, and just how many copies of this circuit are you going to make? One? Two? Five? Ten? 1000? 10,000??? That will also have a BIG effect on how this all works.I learned a long time ago that the first step in solving a problem is a clear and complete statement of that problem. Without that you are working on quicksand. Then you refine that STATEMENT OF THE PROBLEM until what you have is actuallyaorthesolution.

author: bobof
author_rank: Contributor
timestamp: July 23, 2021, 11:27:36 am
content: Quote from: EPAIII on July 23, 2021, 08:35:05 amI don't find the above to be a problem, as I know the answers for myself... The original post wasn't a detail spec to ask someone to do the job, it was an enquiry to see if such a kind of thing exists in the public domain, to then look to see if it was appropriate for the kind of constraints I have. And the answer to that so far seems to be "not really, a pretty comprehensive solution exists for one divider, but not for multiples". It looks like the closest thing is:http://jahonen.kapsi.fi/Electronics/ResOptimizer/If I'm coding it myself then I can put in the constraints required and it will just be (initially) a special purpose thing for that particular job. No biggie, and indeed I have something that does the job with just a little bit of work.

author: viperidae
author_rank: Frequent Contributor
timestamp: July 24, 2021, 06:52:10 am
content: If you just want to remove the number of different BOM items, you could replace other less critical resistors with the same ones used in your dividers.Eg: replace all the random 10k pull-ups with a 12.4k required for a divider somewhere.

author: bobof
author_rank: Contributor
timestamp: July 24, 2021, 07:09:14 am
content: Quote from: viperidae on July 24, 2021, 06:52:10 amThanks, yes, it's on my list to do too, though in this case there ended up being hardly any, as if I recall correctly the 10K and the 47K values ended up getting used by the algorithm in dividers!. Though I think it's worth bearing in mind, as it could result in closer dividers to the required values.Sounds like the kind of thing where if you were making a fully featured program to do it, specifying which existing resistors were non-critical with a +/- tolerance for their value would be a way to go, as it could then crunch all the permutations for you.

author: Siwastaja
author_rank: Super Contributor
timestamp: July 24, 2021, 03:46:08 pm
content: Brute force shouldn't waste memory, only processing time, I have used it for similar problems. Code doesn't need to look nice or be particularly modular; you know the scope and want to solve it for yourself.Score each solution, keep track of the best solution so far, and its score. Wastes no memory, only processing power. Even tracking like 16 best solutions as a binary max heap or min heap is low-cost and wastes little CPU or memory, that is, sometimes you want to see a few more results than just the "best", for doing manual choices.Outer loop can fork bunch of threads which works fine because the problem is CPU heavy and amount of constant input data is very modest likely fitting the per-core L1 caches. Put any parameter with larger dataset in the outer loops.Consider writing in C or C++ instead of Python for higher performance, nested for loops work fine.But of course, at some point brute force stops being acceptable, but then you need to understand much more complex problem solving algorithms.

author: bobof
author_rank: Contributor
timestamp: July 24, 2021, 06:04:46 pm
content: Quote from: Siwastaja on July 24, 2021, 03:46:08 pmDo not underestimate just how lazy I was feeling!Python has some functions which I used to just multiply all the tables of possible values and then walked that... I only "program" (hack really) occasionally these days and it was the limit of what I had the energy for. I should at least fix that as it would solve the memory usage...