Multi element resistor divider - optimization and construction - Page 1
Forum section: electronics / general

author: ch_scr
author_rank: Frequent Contributor
timestamp: August 04, 2023, 12:27:31 pm
content: Ever since someone mentioned the use of dismantled Peltier element as cheap ceramic PCB, the thought stuck with me. Turns out, 0805 smd resistors fit quite well to the provided grid. The copper pads are big, thick and very firmly attached. Upsides seem obvious: Good thermal contact between elements; good match between ceramic material of PCB and resistors, yielding low force on resistors from thermal expansion; no humidity effect on PCB. Only downside is usually prohibitive price of such PCB. To insulate from environmental influence and aging effects on resistors (humidity, oxygen, etc.), special resistors or hermetic case is still needed though. So why not construct resistor divider of arbitrary ratio from equal elements to try idea? Resistor tempco should get better by statistical averaging in creating compounding resistors like this as well. But divider ratio will never be perfect, especially with cheap 0.5% resistors. Trimming by soldering elements afterwards is awkward on ceramic PCB and might introduce stress. But with 6 1/2 digit meter, resistors can be measured with quite high resolution - since all are close in value, measured at the same time and temperature, and in the end only division ratio is what counts; it seems like errors of offset, linearity, tempco of meter should cancel out? Sure, soldering will affect resistors, but hopefully in somewhat equal manner, especially on ceramic PCB when all are re-flowed at the same time.A generalized python program was devised to find optimum arrangement and selection of resistors for divider, series and parallel connection (as shown below) are supported. It can just optimize the grouping of resistors, but if spare resistors are specified it will also make optimal selection. Program works by trying all combinationsConnection legend:Integrated help:Example prompt for hamon divider, with many spare resistors initial error can be virtually eliminated and other effects (measuring error, soldering shift, residual tempco, connection resistance, ...) should dominate:Here is how ceramic divider looks:Here is another example with case:

author: manganin
author_rank: Regular Contributor
timestamp: August 05, 2023, 02:32:19 pm
content: Rigid mechanical connection on both sides of the resistor not a good idea. The large substrate always beats the tiny resistor. Strain gauge sensors built the same way.Even if the thermal expansion coefficient of the base matches the resistor body, the temperature change rate doesn't. And the system is not ceramic only, also the solder material is part of the "closed" chain.Connecting one side of the resistor with a thin copper wire allows free expansion.

author: iMo
author_rank: Super Contributor
timestamp: August 05, 2023, 04:51:48 pm
content: I've been looking for an app which can find a divider where the upper and lowerresistorslegs can have any arbitrary wiring of theelementsresistors - ie parallel or serial or any combination of. Would be great if your tool could be modified somehow, even the computation would take much longer..

author: ch_scr
author_rank: Frequent Contributor
timestamp: August 05, 2023, 05:26:20 pm
content: But you think more about a tool finding the topology, if I understand right? Yeah, that would be nice too. Quite a bit harder to make it seems, maybe easier to implement (but with limited "might") if it had a selection of topologies to go through.The idea behind this was: "I need a divider to 0.198755, this topology with ideal resistors gives 0.2, can I measure and arrange the real resistors in a way to get there anyway" And it seems so! Obviously there is only "so much" wiggle room, but in my trial with "20 measured 0.5% resistors, 15 of which to be used" the error was basically zero, at least in theory - heaven't finished and measured the resulting divider yet.I used an earlier version of the tool, that could only optimize the grouping, with 6 THT resistors (measured for lowest deviation relative to each other from a box of maybe 30) to build a hammon divider. The optimizer gave an error of ~10ppm, and the resulting divider seems to do as well, when measured as a voltage divider (please don't mind the mess).

author: iMo
author_rank: Super Contributor
timestamp: August 05, 2023, 06:03:11 pm
content: There is a tool called"Resistor Optimizer 0.58"(it could pick up resistors from E6-E192 series, was discussed in past) but it works similarly as your app (legs serial or parallel with some limit like 4 pieces max).I think Monte Carlo could be perhaps the easiest solution, the "max" topology with N resistors in hand the upper leg is (N-1) resistors in parallel x (N-1) resistors in series, and the same for lower leg. The wiring will be "empty" and you shoot two to N resistors into the wiring randomly, till you get the best fit..PS: in the thread I mentioned there is a post on matrix math - perhaps useful.https://www.eevblog.com/forum/projects/resistor-combination-calculator/

author: iMo
author_rank: Super Contributor
timestamp: August 06, 2023, 12:54:20 pm
content: Below I've made a small mod - it searches for the best RATIO of Upper/Lower resistor, the initial residual ratio error is set to 100000 ppm (such you may see some results even when you are a bit off the optimal ratio), and it prints out all the iterations when it finds a better fit (such you may see some action on the screen while waiting until it processes all the combinations)Code:ratio-optimizer.py 0.415864785 S 12 5 2199.1 2199.2 2199.3 2199.4 2199.5 2199.6 2199.7 2199.8 2199.9 2200.0 2200.1 2200.2 2200.3 2200.4 2200.5 2200.6 2200.7 2200.8 2200.9 2201.0 2201.1 2201.2 2201.3 2201.4Code:..Residual Ratio error 1685.3720083531 ppmWith these 5 in series for upper leg:(2199.6, 2199.9, 2199.7, 2199.8, 2200.0)and these 12 in series for lower leg:(2199.1, 2199.2, 2199.3, 2199.4, 2199.5, 2200.6, 2200.9, 2201.0, 2201.1, 2201.2, 2201.3, 2201.4)Residual Ratio error 1681.5783347494 ppmWith these 5 in series for upper leg:(2199.9, 2199.6, 2199.7, 2199.8, 2200.0)and these 12 in series for lower leg:(2199.1, 2199.2, 2199.3, 2199.4, 2199.5, 2200.7, 2200.9, 2201.0, 2201.1, 2201.2, 2201.3, 2201.4)Residual Ratio error 1677.7846898810 ppmWith these 5 in series for upper leg:(2199.9, 2199.6, 2199.7, 2199.8, 2200.0)and these 12 in series for lower leg:(2199.1, 2199.2, 2199.3, 2199.4, 2199.5, 2200.8, 2200.9, 2201.0, 2201.1, 2201.2, 2201.3, 2201.4)

author: ch_scr
author_rank: Frequent Contributor
timestamp: August 07, 2023, 08:31:18 am
content: I've made a combined version, it allows to select "Ratio" or "resistive Divider" mode and also optionally shows the iterative result.The initial error was adjusted as per above as well. Caveat: Now needs at least Python 3.10

author: iMo
author_rank: Super Contributor
timestamp: August 08, 2023, 03:08:26 pm
content: How to set a resistor(s) value(s) to be taken in the Upper or in the Lower leg as a "priority resistor(s)"?For example - I've got 30x 2k2 resistors and 10x 1k5 resistors, while I know in advance I will need two 1k5 resistors for the Upper leg.Except the 2x 1k5 I will need 4x 2k2 in the Upper leg, and 12x 2k2 in the Lower leg.I want to tell to the algorithm - "include and process the search for the two 1k5 resistors from the very beginning while always keep them in the Upper leg".

author: ch_scr
author_rank: Frequent Contributor
timestamp: August 08, 2023, 07:01:33 pm
content: IthinkI've got it, please give this a try.

author: iMo
author_rank: Super Contributor
timestamp: August 09, 2023, 06:40:20 am
content: I tried, but the -pu switch with the tuple formatting is unclear for me, tried everything. Also I do not know whether to put there in -pu 2 or all 10 upper 1k5s, it should use 2x1k5 and 4x2k2 in the upper leg - see below schematics with resulting divider I want test.Without -pu I get MemoryError with below example (it runs over 8GB).QuotePython 3.11.4., Win10.Mind the underscore in the .pyHere is the test command for below schematics:Code:divider_ratio_optimizer.py -i -pu "1500.1 1500.2 1500.3 1500.4 1500.5 1500.6 1500.7 1500.8 1500.9 1501.0" 0.69119372 D S 12 6 2199.1 2199.2 2199.3 2199.4 2199.5 2199.6 2199.7 2199.8 2199.9 2200.0 2200.1 2200.2 2200.3 2200.4 2200.5 2200.6 2200.7 2200.8 2200.9 2201.0 2201.1 2201.2 2201.3 2201.4 2201.5 2201.6 2201.7 2201.8 1500.1 1500.2 1500.3 1500.4 1500.5 1500.6 1500.7 1500.8 1500.9 1501.0

author: ch_scr
author_rank: Frequent Contributor
timestamp: August 09, 2023, 07:10:46 am
content: Don't have the priority resistors also in the list, they exist entirely separate (the are pinned on the corresponding leg after getting the combinations for the remaining resistor count)Can only have as much priority resistors as will be used (not enforced by now), seems you specify 6 upper leg resistors but then 10 as priority - this will not workPriority resistors subtract internally from the series/parallel of the corresponding leg. Say you want 6 series as upper, just specify "6", you can then optionally specify e.g. 2 as priority and only the other 4 will be iterated over for that run with the 2 always fixedHope this makes it a bit clearer, does this work?Code:divider_ratio_optimizer.py 0.69119372 D S 12 6 2199.1 2199.2 2199.3 2199.4 2199.5 2199.6 2199.7 2199.8 2199.9 2200.0 2200.1 2200.2 2200.3 2200.4 2200.5 2200.6 2200.7 2200.8 2200.9 2201.0 2201.1 2201.2 2201.3 2201.4 2201.5 2201.6 2201.7 2201.8 1500.6 1500.7 1500.8 1500.9 1501.0 -i -pu 1500.1 1500.2 1500.3 1500.4 1500.5

author: iMo
author_rank: Super Contributor
timestamp: August 09, 2023, 02:57:42 pm
content: Ok, when hard setting the two 1k5 "priority resistors" with the -pu directive and with the list of twenty available 2k2 resistors it finds the correct divider as depicted in the above schematics in 50 secs.. (on my notebook)QuoteQuote

author: ch_scr
author_rank: Frequent Contributor
timestamp: August 09, 2023, 05:15:36 pm
content: Nice! I've added some basic error messages for "more priority resistors than resistors in the leg" and "no result found at all". Slight modification to make the code more readable as well. Enjoy.