How about combining some components? - Page 1
Forum section: electronics / projects

author: HendriXML
author_rank: Super Contributor
timestamp: March 06, 2022, 11:17:19 pm
content: I've created "simulators" for all the different configurations one can have with 4 passive components. Those just take a bunch of input values, combine and compare them to a desired target value and then keeping the best combination.At first I wanted to precalculate all possibilities and store them in an efficient data format. Target values could then be searched in this file. But after some tests, doing them on the fly is fast enough. The files would have been in the hundreds of MB for the 4 component combinations. So I'm glad not needing them (an unwanted extra dependency).The imput values are taken from the E-series. But are ranging from decade -3 to +4 (kind of) relative to the target value. Not every decade will have the same E-serie. For example it could something be like:Code:E012-E024-E024--E024-E024-E012-E001Where  would be decade 0. (However a small/large result can shift the input values, Just like the target is shifted in the value range 1..10 before simulating).What sets of E-serie values are taken can be controlled using an granularity parameter (ExtraCoarse, Coarse, Fine, ExtraFine) and the maximum E-serie (E1..E192).The granularity is used to limit the possible combinations to: 500.000, 5.000.000, 50.000.000, 500.000.000 (ExtraCoarse, Coarse, Fine, ExtraFine).The next post is a simulation with the following parameters:Code:[ElectronicsTasks.CombinationTarget]Value= 1234.56789 Ω[ElectronicsTasks.CombinationParameters]Tolerance= 0.000001%MaxESerie= E24Granularity= ExtraFine

author: HendriXML
author_rank: Super Contributor
timestamp: March 06, 2022, 11:19:19 pm
content: Electronic workbenchTime :6-3-2022 23:27:49Interpreter version :6.28.865Script version :6.20.1.0.2.42Filename :Electronics workbench.xmlSimulation values managerTask "Simulation values manager" was successfully executed (13,5 μs)Combination target configurationTarget value :1,234567890 kΩ ± 5 μΩTask "Combination target configuration" was successfully executed (61,7 μs)Combinations configurationTolerances :0,000001%Granularity :ExtraFineMaxESerie :E24Task "Combinations configuration" was successfully executed (83,9 μs)Component configuration 1 - (A)Matches specs :NO!Used E-series :Relative difference :2,8807%Result :1,200000000 kΩ ± 12 μΩA :1,200000000 kΩ ± 12 μΩTask "Component configuration 1 - (A)" was successfully executed (175,7 μs)Component configuration 2 - (A~B)Matches specs :NO!Used E-series :E012-E024-E024--E024-E024-E012-E001Relative difference :0,116%Result :1,236000000 kΩ ± 12 μΩA :36,0000000 Ω ± 400 nΩB :1,200000000 kΩ ± 12 μΩTask "Component configuration 2 - (A~B)" was successfully executed (2,5634 ms)Component configuration 3 - (A|B)Matches specs :NO!Used E-series :E012-E024-E024--E024-E024-E012-E001Relative difference :0,11079%Result :1,233201581 kΩ ± 12 μΩA :1,300000000 kΩ ± 13 μΩB :24,0000000 kΩ ± 200 μΩTask "Component configuration 3 - (A|B)" was successfully executed (2,6918 ms)Component configuration 4 - (A~B~C)Matches specs :NO!Used E-series :E012-E024-E024--E024-E024-E012-E001Relative difference :0,0026009%Result :1,234600000 kΩ ± 12 μΩA :1,600000000 Ω ± 16 nΩB :33,0000000 Ω ± 300 nΩC :1,200000000 kΩ ± 12 μΩTask "Component configuration 4 - (A~B~C)" was successfully executed (122,0467 ms)Component configuration 5 - (A|B|C)Matches specs :NO!Used E-series :E012-E024-E024--E024-E024-E012-E001Relative difference :0,00000091%Result :1,234567901 kΩ ± 10 μΩA :1,500000000 kΩ ± 15 μΩB :7,50000000 kΩ ± 80 μΩC :100,0000000 kΩ ± 1,0 mΩTask "Component configuration 5 - (A|B|C)" was successfully executed (132,1277 ms)Component configuration 6 - ((A|B)~C)Matches specs :NO!Used E-series :E012-E024-E024--E024-E024-E012-E001Relative difference :0,00049929%Result :1,234561726 kΩ ± 12 μΩA :1,200000000 kΩ ± 12 μΩB :1,000000000 MΩ ± 10 mΩC :36,0000000 Ω ± 400 nΩTask "Component configuration 6 - ((A|B)~C)" was successfully executed (389,6991 ms)Component configuration 7 - ((A~B)|C)Matches specs :NO!Used E-series :E012-E024-E024--E024-E024-E012-E001Relative difference :0,00000091%Result :1,234567901 kΩ ± 11 μΩA :150,0000000 Ω ± 1,5 μΩB :1,100000000 kΩ ± 11 μΩC :100,0000000 kΩ ± 1,0 mΩTask "Component configuration 7 - ((A~B)|C)" was successfully executed (393,0845 ms)Component configuration 8 - (A~B~C~D)Matches specs :NO!Used E-series :E012-E024-E024--E024-E024-E012-E001Relative difference :0,00000891%Result :1,234568000 kΩ ± 12 μΩA :68,0000000 mΩ ± 0,7 nΩB :1,500000000 Ω ± 15 nΩC :33,0000000 Ω ± 300 nΩD :1,200000000 kΩ ± 12 μΩTask "Component configuration 8 - (A~B~C~D)" was successfully executed (4,5768623 s)Component configuration 9 - (A|B|C|D)Matches specs :NO!Used E-series :E012-E024-E024--E024-E024-E012-E001Relative difference :0,00000091%Result :1,234567901 kΩ ± 10 μΩA :1,500000000 kΩ ± 15 μΩB :15,00000000 kΩ ± 150 μΩC :15,00000000 kΩ ± 150 μΩD :100,0000000 kΩ ± 1,0 mΩTask "Component configuration 9 - (A|B|C|D)" was successfully executed (4,897420 s)Component configuration 10 - ((A|B)~C~D)Matches specs :NO!Used E-series :E012-E024-E024--E024-E024-E012-E001Relative difference :0,0000041151%Result :1,234567839 kΩ ± 9 μΩA :390,000000 Ω ± 4 μΩB :1,600000000 kΩ ± 16 μΩC :11,00000000 Ω ± 110 nΩD :910,000000 Ω ± 9 μΩTask "Component configuration 10 - ((A|B)~C~D)" was successfully executed (28,590074 s)Component configuration 11 - ((A~B)|C|D)Matches specs :NO!Used E-series :E012-E024-E024--E024-E024-E012-E001Relative difference :0,00000091%Result :1,234567901 kΩ ± 11 μΩA :150,0000000 Ω ± 1,5 μΩB :1,100000000 kΩ ± 11 μΩC :110,0000000 kΩ ± 1,1 mΩD :1,100000000 MΩ ± 11 mΩTask "Component configuration 11 - ((A~B)|C|D)" was successfully executed (28,558708 s)Component configuration 12 - (((A~B)|C)~D)Matches specs :NO!Used E-series :E012-E024-E024--E024-E024-E012-E001Relative difference :0,0000010791%Result :1,234567877 kΩ ± 12 μΩA :4,30000000 kΩ ± 40 μΩB :1,000000000 MΩ ± 10 mΩC :1,200000000 kΩ ± 12 μΩD :36,0000000 Ω ± 400 nΩTask "Component configuration 12 - (((A~B)|C)~D)" was successfully executed (57,13552 s)Component configuration 13 - (((A|B)~C)|D)Matches specs :NO!Used E-series :E012-E024-E024--E024-E024-E012-E001Relative difference :0,00000086778%Result :1,234567879 kΩ ± 11 μΩA :150,0000000 Ω ± 1,5 μΩB :1,000000000 GΩ ± 10 ΩC :1,100000000 kΩ ± 11 μΩD :100,0000000 kΩ ± 1,0 mΩTask "Component configuration 13 - (((A|B)~C)|D)" was successfully executed (59,13981 s)Component configuration 14 - ((A~B~C)|D)Matches specs :NO!Used E-series :E012-E024-E024--E024-E024-E012-E001Relative difference :0,00000091%Result :1,234567901 kΩ ± 10 μΩA :10,00000000 Ω ± 100 nΩB :240,000000 Ω ± 2 μΩC :1,000000000 kΩ ± 10 μΩD :100,0000000 kΩ ± 1,0 mΩTask "Component configuration 14 - ((A~B~C)|D)" was successfully executed (19,562633 s)Component configuration 15 - ((A|B|C)~D)Matches specs :NO!Used E-series :E012-E024-E024--E024-E024-E012-E001Relative difference :0,0000074071%Result :1,234567981 kΩ ± 10 μΩA :1,100000000 kΩ ± 11 μΩB :27,0000000 kΩ ± 300 μΩC :470,000000 kΩ ± 5 mΩD :180,0000000 Ω ± 1,8 μΩTask "Component configuration 15 - ((A|B|C)~D)" was successfully executed (19,611336 s)Component configuration 16 - ((A~B)|(C~D))Matches specs :NO!Used E-series :E012-E024-E024--E024-E024-E012-E001Relative difference :0,00000091%Result :1,234567901 kΩ ± 11 μΩA :150,0000000 Ω ± 1,5 μΩB :1,100000000 kΩ ± 11 μΩC :18,00000000 kΩ ± 180 μΩD :82,0000000 kΩ ± 800 μΩTask "Component configuration 16 - ((A~B)|(C~D))" was successfully executed (14,648670 s)Component configuration 17 - ((A|B)~(C|D))Matches specs :NO!Used E-series :E012-E024-E024--E024-E024-E012-E001Relative difference :0,0000027054%Result :1,234567857 kΩ ± 12 μΩA :39,0000000 Ω ± 400 nΩB :18,00000000 kΩ ± 180 μΩC :1,200000000 kΩ ± 12 μΩD :330,000000 kΩ ± 3 mΩTask "Component configuration 17 - ((A|B)~(C|D))" was successfully executed (14,608783 s)Component configurationsTask "Component configurations" was successfully executed (3,9 μs)DoneTime :6-3-2022 23:32:28

author: tszaboo
author_rank: Super Contributor
timestamp: March 06, 2022, 11:26:01 pm
content: You are not going to get resistors that are this accurate. E96 is about 1% accurate, E24 is somewhere between 1-5%. The best resistors that you get are going to be 0.001%, but then you are at ~20 EUR each, and for the same money, you can just order custom resistors with any value you want.

author: HendriXML
author_rank: Super Contributor
timestamp: March 06, 2022, 11:29:11 pm
content: As can be seen an 8 digit precision is doable using E24 as a max. (When using E48 values the full 1,23456789 kΩ can be matched).There's also the possibility of taking an extra step: repeatedly calculating an optimal input value for each of the inputs. This would allow for values beyond the simulated range.

author: tszaboo
author_rank: Super Contributor
timestamp: March 06, 2022, 11:30:40 pm
content: Quote from: HendriXML on March 06, 2022, 11:29:11 pmMaybe you should read what temperature coefficient and accuracy means.

author: HendriXML
author_rank: Super Contributor
timestamp: March 06, 2022, 11:32:52 pm
content: Quote from: tszaboo on March 06, 2022, 11:26:01 pmI know, but the above example is just to show this way of determing the values is more than enough for any practical use.

author: T3sl4co1l
author_rank: Super Contributor
timestamp: March 06, 2022, 11:54:43 pm
content: Related reading:http://kirr.homeunix.org/electronics/resistor-network-finder/https://sparks.gogo.co.nz/resistor_paralleler.htmlhttps://jansson.us/resistors.htmlTim

author: HendriXML
author_rank: Super Contributor
timestamp: March 07, 2022, 12:47:57 am
content: One user friendly feature is that when changing the target value unit in for example 1234.56789 μF, it will chose an "opposite" (par=ser, ser=par) configuration to do the calculations with.Like:Component configuration 1 - (A)Matches specs :NO!Used E-series :Relative difference :21,5%Result :1500,0000000 μF ± 1,5 pFA :1500,0000000 μF ± 1,5 pFTask "Component configuration 1 - (A)" was successfully executed (541,4 μs)Component configuration 2 - (A~B)Matches specs :NO!Used E-series :E003-E006-E006--E006-E006-E003-E001Relative difference :0,45994%Result :1228,9156627 μF ± 1,0 pFA :1500,0000000 μF ± 1,5 pFB :6800,000000 μF ± 7 pFTask "Component configuration 2 - (A~B)" was successfully executed (867,0 μs)Component configuration 3 - (A|B)Matches specs :NO!Used E-series :E003-E006-E006--E006-E006-E003-E001Relative difference :1,1941%Result :1220,0000000 μF ± 1,0 pFA :220,0000000 μF ± 0,2 pFB :1000,0000000 μF ± 1,0 pFTask "Component configuration 3 - (A|B)" was successfully executed (759,6 μs)

author: HendriXML
author_rank: Super Contributor
timestamp: March 07, 2022, 01:02:18 am
content: In the above examples I had to contribute unrealistically low tolerances to the input values, otherwise the calculated value would not be displayed accurate enough. The reason for that is that the scripting engine calculates with propagating uncertainties. Like this example:Electronic workbenchTime :7-3-2022 01:51:10Interpreter version :6.29.868Script version :6.28.2.0.2.51Filename :Electronics workbench.xmlSimulation values managerTask "Simulation values manager" was successfully executed (25,9 μs)Combination target configurationTarget value :1234,567890 μF ± 5 pFTask "Combination target configuration" was successfully executed (117,7 μs)Combinations configurationTolerances :10%Granularity :ExtraFineMaxESerie :E6Task "Combinations configuration" was successfully executed (196,5 μs)Component configuration 1 - (A)Matches specs :NO!Used E-series :Relative difference :21,5%Result :1500 μF ± 150 μFA :1500 μF ± 150 μFTask "Component configuration 1 - (A)" was successfully executed (476,3 μs)Component configuration 2 - (A~B)Matches specs :NO!Used E-series :E003-E006-E006--E006-E006-E003-E001Relative difference :0,45994%Result :1230 μF ± 100 μFA :1500 μF ± 150 μFB :6800 μF ± 700 μFTask "Component configuration 2 - (A~B)" was successfully executed (871,2 μs)Component configuration 3 - (A|B)Matches specs :NO!Used E-series :E003-E006-E006--E006-E006-E003-E001Relative difference :1,1941%Result :1220 μF ± 100 μFA :220 μF ± 20 μFB :1000 μF ± 100 μFTask "Component configuration 3 - (A|B)" was successfully executed (785,6 μs)The accuracy which needs to be targetted is taken from the targets significant digits, but can also specified like 100 Ω ± 1% or 100 Ω ± 10 Ω.But whether it is a good match (Matches specs) is not only determined by the value of the calculated result, but also determined by the (propagated) uncertainty of the result. (Determined by the tolerances of the input values.)

author: HendriXML
author_rank: Super Contributor
timestamp: March 08, 2022, 03:36:36 pm
content: I wanted to know what difference it would make, if (coarse) simulated values where recalculated and matched with possibly finer ESerie values (Refine=Yes).One reason for this is that it is faster to calculate than it is to simulate with more values. It seems to makes only a small difference. This is good news, in the sense that the input sets taken for the simulations are adequate. However the best input set has values that are "tightly bound" together, recalculating cannot fundamentally change 2 or more components. Simulating with extra values is the way to get better fundamentally different combo's. For practical use: combining 3-4 components, even of low ESeries can already result in closely matched replacement values.Here's an nice example of 987,65432100 Ω:Electronics workbenchTime :8-3-2022 15:57:07Interpreter version :6.30.869Script version :6.30.2.0.2.51Filename :Electronics workbench.xmlSimulation values managerTask "Simulation values manager" was successfully executed (21,7 μs)Combination target configurationTarget value :987,65432100 Ω ± 50 nΩTask "Combination target configuration" was successfully executed (80,6 μs)Combinations configurationTolerances :0,0000001%Granularity :ExtraCoarseMaxESerie :E24Refine :YesTask "Combinations configuration" was successfully executed (91,8 μs)Component configuration 14 - ((A~B~C)|D)Matches specs :NO!Used E-series :E3-E6-E6--E6-E6-E3-E1Relative difference :0,000000000015432%Refined :YesResult :987,6543210 Ω ± 1,0 μΩA :82,00000000 μΩ ± 0,00008 nΩB :33,00000000 kΩ ± 30 μΩC :47,00000000 kΩ ± 50 μΩD :1,0000000000 kΩ ± 1,0 μΩTask "Component configuration 14 - ((A~B~C)|D)" was successfully executed (90,4166 ms)DoneTime :8-3-2022 15:57:12Electronics workbenchTime :8-3-2022 15:57:43Interpreter version :6.30.869Script version :6.30.2.0.2.51Filename :Electronics workbench.xmlSimulation values managerTask "Simulation values manager" was successfully executed (13,4 μs)Combination target configurationTarget value :987,65432100 Ω ± 50 nΩTask "Combination target configuration" was successfully executed (84,1 μs)Combinations configurationTolerances :0,0000001%Granularity :ExtraCoarseMaxESerie :E24Refine :NoTask "Combinations configuration" was successfully executed (100,8 μs)Component configuration 14 - ((A~B~C)|D)Matches specs :NO!Used E-series :E3-E6-E6--E6-E6-E3-E1Relative difference :0,000001542%Refined :NoResult :987,6543362 Ω ± 1,0 μΩA :100,00000000 mΩ ± 0,10 nΩB :33,00000000 kΩ ± 30 μΩC :47,00000000 kΩ ± 50 μΩD :1,0000000000 kΩ ± 1,0 μΩTask "Component configuration 14 - ((A~B~C)|D)" was successfully executed (89,2918 ms)DoneTime :8-3-2022 15:57:48But 3 resistors can be good enough as well:Electronics workbenchTime :8-3-2022 16:34:25Interpreter version :6.30.869Script version :6.30.2.0.2.51Filename :Electronics workbench.xmlSimulation values managerTask "Simulation values manager" was successfully executed (15,2 μs)Combination target configurationTarget value :987,65432100 Ω ± 50 nΩTask "Combination target configuration" was successfully executed (63,2 μs)Combinations configurationTolerances :0,0000001%Granularity :ExtraCoarseMaxESerie :E24Refine :NoTask "Combinations configuration" was successfully executed (86,1 μs)Component configuration 5 - (A|B|C)Matches specs :NO!Used E-series :E6-E24-E24--E24-E24-E6-E1Relative difference :0,00000000125%Refined :NoResult :987,6543210 Ω ± 1,0 μΩA :1,0000000000 kΩ ± 1,0 μΩB :120,00000000 kΩ ± 120 μΩC :240,0000000 kΩ ± 200 μΩTask "Component configuration 5 - (A|B|C)" was successfully executed (102,8167 ms)DoneTime :8-3-2022 16:34:29

author: HendriXML
author_rank: Super Contributor
timestamp: March 09, 2022, 12:24:49 am
content: As said, when I started this addition to my workbench script I assumed precalculating every combination would be needed. But by choosing the input values efficiently on the fly simulating is doable. But would this be used for a webservice better performance by using precalculations would be mandatory. For this reason I still shift (scale up/down by orders of 10) the target. So the same input/output combos can be reused. Just scale the input values after simulating. This greately reduce the number of combinations which would have end up in a datafile. Also this does not limit the range of values it can handle (micro farads or giga ohms) when using precalculated values.Not only for speed, but also storage wise a reduced set is key.Accessing such a file would have been done by memory mapping. With that technology the file is accessed as memory, which is "paged in" as needed. (Like a pagefile, but unidirectional.)Next step will be to filter out combinations which are not "on stock". Checking them also needs scaling, but with a preprocessed "mapping" this can be done very fast.I could use the on stock values directly for simulating, but then this would be become incompatible with a precalculated file as an option.Using a fixed set of eseries will unfortunately also rule out non eserie values, these will be discarded.

author: HendriXML
author_rank: Super Contributor
timestamp: March 11, 2022, 11:17:46 pm
content: Simulated input values can now be checked against a list of available values. These can be placed in a textbox or -more advanced- be taken from a Partkeepr database.This will be incorporated in my BOM toolhttps://github.com/HendriXML/KiCad-BOM-reporterIt is possible to specify a filter of which components to use from the database. For instance only accurate power resistors.Code:[CombinationTarget.Input.Resistor]ComponentKind=ResistorPowerRating.Min = 2 WTolerance.Max = 2%Also the inner loop code had a slow function call, which I removed, the simulation is now many times faster (>10x). Now even extra fine granularity runs within seconds, I will probably scale the max combinations for each granularity by 10.

author: HendriXML
author_rank: Super Contributor
timestamp: March 23, 2022, 02:14:59 pm
content: I've updated my BOM repository with the simulation. The process is as follows:Available values are retrieved from stock components, using user defined specificationsThose values are matched with E-serie values, unmatched e-serie values are excluded from simulationThe best combination is refined using available valuesThe best combination is matched with stock components, also reporting their location and specifications

author: HendriXML
author_rank: Super Contributor
timestamp: March 23, 2022, 04:09:17 pm
content: B.t.w. when setting UseStock=No the script can be used independently from PartKeepr. Available values can then be taken from the Input tabsheet or from a textfile.Off course it is also possible to use the full (unmatched) e-series.

author: HendriXML
author_rank: Super Contributor
timestamp: March 25, 2022, 12:22:22 pm
content: Something is bugging me, I've recently bought some aliexpress 500 mΩ which cannot be mapped to an e-series value.So they might only be picked after a refine step. This cannot be!For determing what set of e-serie value to take for a certain granularity, my code uses some precalculated values about how many variations are allowed at most.This might be something like:Code:000078 // ExtraCoarse, 000140 // Coarse, 000250 // Fine, 000446 // ExtraFineThat's for 4 component configuration 16 and 17. These limits depend on how many (groups of) interchangeable components there are within a configuration.I've got 140 different resistor values on stock, so in my case they could easily be fully simulated. However I'll implement a preprocess that limits the input values by discarding values which are most different to the target value. A bit rough, but this will in practice only hurt the 4 component configurations on lower granularities.

author: HendriXML
author_rank: Super Contributor
timestamp: March 26, 2022, 01:52:47 pm
content: When supplying available values and setting the config option UseESeries=0, (which is now the default setting) those values will be used in the simulation.My 141 resistors take about 100 ms, when simulating a 4 component configuration. Consider that 141^4 is still 395.254.161 combinations (without deduplication).But as can be seen the combinations expand pretty quickly, each granularity step is about 10x more time consuming.Code:000078 // ExtraCoarse, 000140 // Coarse, 000250 // Fine, 000446 // ExtraFine446 resistors would take about 100x longer: 10s.If many (> 446) of the available values where badly spread near the target value, the chosen method of selecting values could be suboptimal for 4 component configurations. But it doesn't need to be perfect.I think the screenshot also gives an idea on how specifications are matched. Its comparable when the scripts are used as a BOM reporter.

author: HendriXML
author_rank: Super Contributor
timestamp: March 27, 2022, 10:32:20 pm
content: If one takes a 10,000 values (1 <= Value < 10), spread like "E10000" and simulate each of those using 17 the different configurations, one could determine which configuration is best on average/worst difference and how they relate to one another.To do this I'll simulate these decades/values E6-E12-E12-E12--E12-E12-E12-E6-E1. Where  ranges from 1.0 until 8.2. (Because the simulation speed had improved, I added 2 decades.)This simulation could also show what precision is guaranteed when using a certain type of configuration. This could be usefull when knowing the required accuracy, but not knowing the required value yet. In that case one still can choose a configuration on forehand.

author: HendriXML
author_rank: Super Contributor
timestamp: March 28, 2022, 10:45:51 pm
content: I simulated the 10,000 target values and put the results into a xml file (as well as a 1000 values version). I let Excel calculate the average and maximum diffs for each configuration and plotted those.It shows clearly that some configurations are better in general to get a matching replacement value then others. Also a guaranteed 0.1% precision can already be achieved by using 3 components using config 6 & 7.Config 12 & 13 can be up to 100x more precise, but would then in practice need very low tolerance resistors. It should be mentioned that not all possible e-serie values where simulated (nor all target values), it could be that some configurations would benefit more from extra very low, or extra very high values to get near a target value.Have these results some meaning?To me they do, because I like to continiously (re)calulate most of schematics values while designing. If some part needs an accurate voltage, a voltage divider with one resistor and config 6 or 7 could then be chosen. The actual values could then be simulated as part of the calculations. For this I use the same tool and comparable scripts.

author: T3sl4co1l
author_rank: Super Contributor
timestamp: March 28, 2022, 11:22:12 pm
content: Obligatory:https://xkcd.com/1319/https://xkcd.com/1205/Afraid I don't have much to add as it's not a pressing matter to me and I have about enough tools handy to do what I need. But watching nonetheless.Tim

author: HendriXML
author_rank: Super Contributor
timestamp: March 29, 2022, 12:13:24 am
content: Quote from: T3sl4co1l on March 28, 2022, 11:22:12 pmVery true.I once had a nice and short conversation with an app developer. He redesigned some functionality, which made things unlogical and a bit annoying (but not the reason for the conversation). He said some feature was used more often and now it could be accessed faster. My reply was that users don't count seconds, but frustrations.In a way here also lies the power of good automation, it's not necessarily about time shaving, but also about not having to switch or divide attention, so one can keep focus on other tasks.It might also be less error prone, which can also be stress relieving.In my career as a developer I spend some good amount of time on tools and generating code. Best time spend!

author: HendriXML
author_rank: Super Contributor
timestamp: March 30, 2022, 01:12:23 pm
content: I've added some documentation in my repository:https://github.com/HendriXML/KiCad-BOM-reporter/wiki/Determine-optimal-available-combinations-for-replacement-valueThe default behavior is straight forward (with a valid inventory setup).For standalone (no stock values, no inventory database) some extra settings are required, at the least:Code:[ComponentCombinations.Stock]UseStock=NoBut also a different source of available values or activating the use of e-series.I think the functionality in the current state is quite usable, but probably mostly as a part of my personal toolset.The generated data file could also be used on itself (with scaling target and inputs when needed), the input values used are however limited to E12.About the calulating relative differences:I choose not to calculate it as: Diff = |Target-Actual|/TargetBut as:Code:if Actual > Target thenDiff = Actual/Target - 1elseDiff = Target/Actual - 1For instance if a Target of 10 has 2 actual values (combination results) 1 and 20In the used calculation the difference is:1: 900%20: 100%In the not used calculation this would be:1: 90%20: 100%For most replacement values the difference between the 2 calculation methods would be smaller.However it can matter, for instancehttp://kirr.homeunix.org/electronics/resistor-network-finder/?series=&bases=&from=&to=&gaps=&extra=1+20&target=10&max-size=1&target-error=0.1&use-serial=1&use-parallel=1&use-bridges=1seems to choose 1, where my method would choose 20 as best match.

author: T3sl4co1l
author_rank: Super Contributor
timestamp: March 30, 2022, 05:12:56 pm
content: Might be nice to have a switch for logarithmic comparisons. Whereas 20 is 200% of 10, and 10 is 50% of 20, they're simply log2(20/10, 10/20) = (1, -1) factor apart.Use whatever base you prefer, of course; for comparison purposes, it doesn't matter, as long as it's consistent. if reporting to the user, base 10 might be preferred, perhaps even as dB. dB isn't often used with resistance I think, but I don't see why not.Tim

author: HendriXML
author_rank: Super Contributor
timestamp: March 30, 2022, 07:31:53 pm
content: I'm not that mathematically skilled, but I think the comparisons are done in a logarithmic way. But I can't determine whether we're on the same page..Code:e^abs(log(actual)-log(target))$${\%e}^{\left| \log{\left( \mathrm{actual}\right) }-\log{\left( \mathrm{target}\right) }\right| }$$should be the same asCode:if Actual > Target thenDiff = Actual/TargetelseDiff = Target/ActualSubtracting 1 doesn't change comparisons.Code:if Actual > Target thenDiff = Actual/Target - 1elseDiff = Target/Actual - 1Also raising the difference to the power of e (or whatever) doesn't change comparisons as well.So my comparisons should be the same as finding the smallest:$${\left| \log{\left( \mathrm{actual}\right) }-\log{\left( \mathrm{target}\right) }\right| }$$(Please correct me if I'm wrong)On how to display the difference: I find % a bit easier to understand, but that's because I'm not that familiar with dB's.On the other way, reading very low % like 0,000000000015432% doesn't make much sense either.The most usefull info is probably the "Matches specs" determination.

author: T3sl4co1l
author_rank: Super Contributor
timestamp: March 30, 2022, 09:03:38 pm
content: If you're just doing comparisons, yeah, it doesn't matter. Log and exp are one-to-one functions, so the comparisons are ordered the same. Taking the absolute versus percentage difference is more the point I should be making.Tim

author: HendriXML
author_rank: Super Contributor
timestamp: March 31, 2022, 07:15:52 pm
content: I've been pondering about a good metric which tells how well the combination replacement value matches the target.I report whether it matches the specifications by calculating a target range:Target - Target Uncertainty ... Target +Target UncertaintyAnd a combo result range:Actual - Actual Uncertainty ... Actual + Actual UncertaintyThen I determine whether the actual range is fully covered by the target range.This shouldn't be to bad, but the best determination should I think consider a 68٪ probability. (Like the uncertainties)Besides a true or false answer, a good metric would be nice. Maybe one that takes the uncertainties into account.Comparing differences with|log(a) - log(t)|Is OK, however displaying that result could be less interesting.One way to make it meaningful is to change the logbase (suggestion by T3sl4co1l).It could be changed to a base where values < 1 would be in spec, and values larger out of spec.A value of 0 would be a perfect match (but not necessarily be within spec, if actual uncertainty is to large).For the current way of determining "within spec" I know how to get to this logbase.But maybe someone knows the right way of within spec determination. Or has another suggestion?

author: T3sl4co1l
author_rank: Super Contributor
timestamp: March 31, 2022, 07:48:26 pm
content: Hm, should that include component tolerances, so that the range is statistical? You could have a span or sigma for each component, and do the math following that variance through the network to the overall result. Not exactly sure offhand how to add up all the variances, maybe just crank them by hand (you're only doing so many arrangements, right?) and use a fixed formula for each? (The math is a little more complicated than dividers, more like following the partial derivatives through. Though that only works for small tolerances, and you may need multiple sampling points, or give up and use Monte Carlo, to work through pathologically large errors like this. Not that one intends to have worse than 5% resistors inventoried, but if one could enter +100/-50% for instance, why not?)Interesting fallout of tracking sensitivity is, if you need a certain precision, but a small tweak to its overall value, then a looser-tolerance part can be added to it: a part's effect on the overall result is about proportional to its ratio to the total. That is, say you need 9 or 11k and only have 10; if the 10k is 1% and you need not much worse than 1%, then a 100k or 1k can be connected in parallel/series, with tolerance up to 5 or 10% maybe, and not worsen the resulting network too much (<2%?). It might be worth tracking min/max values as well as typical sigma here, because with enough parts involved, it will regress to the mean: rather than a truncated Gaussian, the truncation gets diluted. So the worst-case value gets worse as you would expect, but it's also very rare to occur, and the expected value gets better (assuming each resistor is independent).The main issue is that, resistors in parallel respond nonlinearly, with low values weighted more strongly than high. So it requires some cranking to know best. In series, it's trivial: the sigmas sum RMS, and worst-case tolerances add.Put another way: if you take a hundred identical resistors in series, having the same truncated-gaussian distribution, the result is a 100R value with 10σ tolerance, and the PDF being a hundredfold smoothed gaussian (in the sense of, the truncations being smeared out by superposition). If you put them in parallel instead, you don't get 1/100 R, you get less on average. Although I don't know how much less, offhand (something proportional to σ?).It would be really interesting to track the actual PDF through the process as well, but that's pretty overkill...Tim

author: HendriXML
author_rank: Super Contributor
timestamp: March 31, 2022, 09:34:38 pm
content: I kinda know that uncertainties come out of a can of worms. My scripting engine uses them in calculations. I use maxima to determine the partial diffs, for complex expressions. It would not be so hard to generate them for each configuration and import that into code. I used that technique when using refining values.In my little experience there's not a large difference in comparison to have it be calculated with the simpler rules.However I would implement it in a an more optimal way if needed, probably when variables are used more than one time in the expression (then they are not independent anymore..).I recently found this sitehttps://uncertaintycalculator.com/which might become helpful as well.The input values have a rather simple uncertainty, just one tolerance indication for all. Not using the specific ones from stock.I like to explore ways of having uncertainties help in decision making. The scripts that support my bench dmm take also the specified uncertainties in consideration which depends on a few settings and ranges. I find that very useful, it would have been nice if manufacturers would support them out of the box though.So I`m very interested in the "academic way" of checking whether something is in spec. It would be used in other scripts as well.

author: T3sl4co1l
author_rank: Super Contributor
timestamp: March 31, 2022, 09:57:20 pm
content: Oooh, neat link, will tuck that away and forget...Tim

author: HendriXML
author_rank: Super Contributor
timestamp: March 31, 2022, 10:34:12 pm
content: I did a comparison of my "internal" standard uncertainty calulations vs the website one using partial diffs.As can be seen they're close. The tool's one is rounded to 2 sig figs.

author: HendriXML
author_rank: Super Contributor
timestamp: April 01, 2022, 12:36:09 am
content: For reference..https://www.spcforexcel.com/knowledge/measurement-systems-analysis/specifications-and-measurement-errorhttps://www.ivtnetwork.com/article/measurement-uncertainty-and-specifications-kinetic-studies

author: HendriXML
author_rank: Super Contributor
timestamp: April 01, 2022, 08:23:50 pm
content: I've started a new thread, about how to validate a value against a spec.https://www.eevblog.com/forum/metrology/how-to-determine-wether-a-value-or-measurement-is-matching-a-specification/

author: amosborne
author_rank: Contributor
timestamp: April 03, 2022, 04:41:55 pm
content: As a theoretical exercise (and as a personal fan of ultra-niche software apps), this is interesting.On the other hand, I don’t understand why you would practically use this during the design process. Am I understanding your tool correctly?I am understanding your tool to be saying that there exist certain resistive networks which provide better flexibility than others when looking for alternate components to meet the same target value.Why is this a desired optimization?Also, all data you’ve presented here uses unattainable tolerances. Is the value of this tool diminished when using realistic tolerances (say 0.01% at the very smallest, 1% or 0.1% preferred)? I would imagine that given two distinct choices, the degree to which their final value tolerance zones overlap is an indicator of acceptability.

author: amosborne
author_rank: Contributor
timestamp: April 03, 2022, 04:47:51 pm
content: In case you are interested, I had developed a software tool of my own for computing worst-case tolerances, perhaps we have some overlap:https://github.com/amosborne/worstcasehttps://www.osborneee.com/worstcase/

author: HendriXML
author_rank: Super Contributor
timestamp: April 03, 2022, 09:28:31 pm
content: Thanks! (Will have a look at your repo)A bit more about the purpose of this stuff. And a bit of personal philosophy.I like to calculate my schematics using a self build interpreter. It's an ongoing process of using different techniques and structuring the calculations. Even when my electronics designs have proven to be shitt*, I still had a good time of puzzling and so the process was valuable.To combine components to very precise values is a good building block.Before calculating a part of the circuit that would need a non standard passive value a configuration needs to be chosen. In my case calculations depend on schematic structure, schematic values depend on calculations (iteratively).The number of components one would throw at this is determined by the needed precision. Probably the least that is acceptable.It's very true that the precision outmatches the accuracy very easily. 4 components might be way overkill.But that doesn't mean one should start with lousy precision. I as a hobbyist also have no issue with cherry picking some of my components. I'm not a professional, so no production line considerations. I also like to use my workbench script which allows to measure resistors with high accuracy in no time, reporting their values and difference from a target.But back to the building block:The thing should perform well on precision, it cannot influence the accuracy of the input values. As a software developer one would foremost check that, even if it means using non-existing good tolerances. Because it happens to be fast I could to run a 10.000 value simulation. Practical use? Handy to know.. Good validation: yes.But regarding to practical use, the script does take realistic tolerances into account. It shows the propagated uncertainty and significant digits. Which would normally mean (non test situation) one would see theusefulprecision. (I found just recently out there's some improvement needed regarding how tolerances are distributed vs standard uncertainty.)So this stuff mainly serves the purpose of a hobby. And as this hobby has quite some drawbacks, adding one that's called "going full pro" is not going to happen. A conscious decision, to have more degrees of freedom.

author: HendriXML
author_rank: Super Contributor
timestamp: April 03, 2022, 09:43:16 pm
content: Quote from: amosborne on April 03, 2022, 04:47:51 pmWhat you display there could be an example of how I like to calculate around a circuit. Because these calculations make use of propagated uncertainties (unlike excel) It could show that some of the "target" calculations have a too large uncertainty, leading to the improvement of some input specs (the resistor tolerances). Also one could add asserts, which guard stuff (for example tolerances vs uncertainties).Besides calculating, I often revert to simulating a part of the circuit. Not as fancy as it may sound, it's comparable to what is done here. But mostly I start with coarse iput steps, to determine the coarse optimal. And then refine the inputs around those with smaller steps. Works pretty good, but it can be "blind" for the most optimal solution. But that might just need too must combinations. Monte Carlo (not really known to me) takes random values?I'm not sure whether you simulate "within the tolerances", but sure there's also overlap in the use of uncertainties and units in the calculations where I use this building block in. But this building block uses fixed calculations (compiled) around 17 configurations. They cannot be used for anything else.

author: HendriXML
author_rank: Super Contributor
timestamp: April 05, 2022, 09:14:13 pm
content: I think I found a better metric to optimize when simulating.https://www.eevblog.com/forum/metrology/how-to-determine-wether-a-value-or-measurement-is-matching-a-specification/msg4102789/#msg4102789

author: HendriXML
author_rank: Super Contributor
timestamp: April 21, 2022, 10:41:35 pm
content: I've implemented the nonconformity metric as a simulation optimalisation criteria. (Only for the 4 compo configs for now)Instead of only search for the smallest difference, it also takes the combined uncertainty into account.It assumes a gaussian distribution of the input tolerance. Which certainly might not be the case in practice. And even if it did, only 4 components in a config does not make it something to rely upon. It's not a worst case analysis, but a decision support tool. If one wants to know which values the metric prefers one can activate its setting and have a peek.I did manage to get the simulation time less than 2x the diff mode. This is done by first simulating the diff variant. And then calculate a candidate window using its best match for the heavier metric calculation. (With each new winner in the metric mode the window gets a bit smaller.)

author: HendriXML
author_rank: Super Contributor
timestamp: April 22, 2022, 01:18:12 am
content: Al this simulating was done using input specs. When using the metric criteria, one gets a set where the weights are distributed more evenly, which can be beneficial.The next step would be to pick physical components matching the input specs.But what about taking 10-20 of each, measure them precisely and simulate those values again.This technique might be leading to a precise poor man's custom resistor in respect to its value. It's thermal stability might not be that great. But in case of a voltage divider of similar resistors this might be fine as well.I've made a another script that can measures a bunch of resistors and places the results in a file pretty fast. It's a matter of clicking the one button bluetooth keyboard for a new measurement. (=Volume up). So it wouldn't even take a lot of time.Those measurements then need to be assigned to components A, B, C, D. Then this file can be used for a new simulation where each value can only be used once.

author: HendriXML
author_rank: Super Contributor
timestamp: May 05, 2022, 09:52:22 pm
content: I added a feature which shows the power ratio of a certain resistor configuration.As can be seen the metric version picks a set of resistors with a less distributed powerratio.

author: HendriXML
author_rank: Super Contributor
timestamp: May 05, 2022, 10:38:30 pm
content: The expressions which calculate these ratio's are huge, especially the uncertainty calculation of them.Some example:Code:<Expression.T Id="prAppBssCpD_A" Expr="(A*B^2*D)/(((B^2+2*A*B+A^2)*C+A*B^2+A^2*B)*D+(B^2+2*A*B+A^2)*C^2+(2*A*B^2+2*A^2*B)*C+A^2*B^2)"/><Expression.T Id="prAppBssCpD_B" Expr="(A^2*B*D)/(((B^2+2*A*B+A^2)*C+A*B^2+A^2*B)*D+(B^2+2*A*B+A^2)*C^2+(2*A*B^2+2*A^2*B)*C+A^2*B^2)"/><Expression.T Id="prAppBssCpD_C" Expr="((B^2+2*A*B+A^2)*C*D)/(((B^2+2*A*B+A^2)*C+A*B^2+A^2*B)*D+(B^2+2*A*B+A^2)*C^2+(2*A*B^2+2*A^2*B)*C+A^2*B^2)"/><Expression.T Id="prAppBssCpD_D" Expr="((B+A)*C+A*B)/((B+A)*D+(B+A)*C+A*B)"/>Uncertainties:Code:<Expression.T Id="uprAppBssCpD_A" Expr="sqrt(((A*B^2)/(((B^2+2*A*B+A^2)*C+A*B^2+A^2*B)*D+(B^2+2*A*B+A^2)*C^2+(2*A*B^2+2*A^2*B)*C+A^2*B^2)-(A*B^2*((B^2+2*A*B+A^2)*C+A*B^2+A^2*B)*D)/(((B^2+2*A*B+A^2)*C+A*B^2+A^2*B)*D+(B^2+2*A*B+A^2)*C^2+(2*A*B^2+2*A^2*B)*C+A^2*B^2)^2)^2*Du^2+Au^2*((B^2*D)/(((B^2+2*A*B+A^2)*C+A*B^2+A^2*B)*D+(B^2+2*A*B+A^2)*C^2+(2*A*B^2+2*A^2*B)*C+A^2*B^2)-(A*B^2*D*(((2*B+2*A)*C+B^2+2*A*B)*D+(2*B+2*A)*C^2+(2*B^2+4*A*B)*C+2*A*B^2))/(((B^2+2*A*B+A^2)*C+A*B^2+A^2*B)*D+(B^2+2*A*B+A^2)*C^2+(2*A*B^2+2*A^2*B)*C+A^2*B^2)^2)^2+Bu^2*((2*A*B*D)/(((B^2+2*A*B+A^2)*C+A*B^2+A^2*B)*D+(B^2+2*A*B+A^2)*C^2+(2*A*B^2+2*A^2*B)*C+A^2*B^2)-(A*B^2*D*(((2*B+2*A)*C+2*A*B+A^2)*D+(2*B+2*A)*C^2+(4*A*B+2*A^2)*C+2*A^2*B))/(((B^2+2*A*B+A^2)*C+A*B^2+A^2*B)*D+(B^2+2*A*B+A^2)*C^2+(2*A*B^2+2*A^2*B)*C+A^2*B^2)^2)^2+(A^2*B^4*Cu^2*D^2*((B^2+2*A*B+A^2)*D+2*(B^2+2*A*B+A^2)*C+2*A*B^2+2*A^2*B)^2)/(((B^2+2*A*B+A^2)*C+A*B^2+A^2*B)*D+(B^2+2*A*B+A^2)*C^2+(2*A*B^2+2*A^2*B)*C+A^2*B^2)^4)"/><Expression.T Id="uprAppBssCpD_B" Expr="sqrt(((A^2*B)/(((B^2+2*A*B+A^2)*C+A*B^2+A^2*B)*D+(B^2+2*A*B+A^2)*C^2+(2*A*B^2+2*A^2*B)*C+A^2*B^2)-(A^2*B*((B^2+2*A*B+A^2)*C+A*B^2+A^2*B)*D)/(((B^2+2*A*B+A^2)*C+A*B^2+A^2*B)*D+(B^2+2*A*B+A^2)*C^2+(2*A*B^2+2*A^2*B)*C+A^2*B^2)^2)^2*Du^2+Au^2*((2*A*B*D)/(((B^2+2*A*B+A^2)*C+A*B^2+A^2*B)*D+(B^2+2*A*B+A^2)*C^2+(2*A*B^2+2*A^2*B)*C+A^2*B^2)-(A^2*B*D*(((2*B+2*A)*C+B^2+2*A*B)*D+(2*B+2*A)*C^2+(2*B^2+4*A*B)*C+2*A*B^2))/(((B^2+2*A*B+A^2)*C+A*B^2+A^2*B)*D+(B^2+2*A*B+A^2)*C^2+(2*A*B^2+2*A^2*B)*C+A^2*B^2)^2)^2+Bu^2*((A^2*D)/(((B^2+2*A*B+A^2)*C+A*B^2+A^2*B)*D+(B^2+2*A*B+A^2)*C^2+(2*A*B^2+2*A^2*B)*C+A^2*B^2)-(A^2*B*D*(((2*B+2*A)*C+2*A*B+A^2)*D+(2*B+2*A)*C^2+(4*A*B+2*A^2)*C+2*A^2*B))/(((B^2+2*A*B+A^2)*C+A*B^2+A^2*B)*D+(B^2+2*A*B+A^2)*C^2+(2*A*B^2+2*A^2*B)*C+A^2*B^2)^2)^2+(A^4*B^2*Cu^2*D^2*((B^2+2*A*B+A^2)*D+2*(B^2+2*A*B+A^2)*C+2*A*B^2+2*A^2*B)^2)/(((B^2+2*A*B+A^2)*C+A*B^2+A^2*B)*D+(B^2+2*A*B+A^2)*C^2+(2*A*B^2+2*A^2*B)*C+A^2*B^2)^4)"/><Expression.T Id="uprAppBssCpD_C" Expr="sqrt((((B^2+2*A*B+A^2)*C)/(((B^2+2*A*B+A^2)*C+A*B^2+A^2*B)*D+(B^2+2*A*B+A^2)*C^2+(2*A*B^2+2*A^2*B)*C+A^2*B^2)-((B^2+2*A*B+A^2)*C*((B^2+2*A*B+A^2)*C+A*B^2+A^2*B)*D)/(((B^2+2*A*B+A^2)*C+A*B^2+A^2*B)*D+(B^2+2*A*B+A^2)*C^2+(2*A*B^2+2*A^2*B)*C+A^2*B^2)^2)^2*Du^2+Au^2*(((2*B+2*A)*C*D)/(((B^2+2*A*B+A^2)*C+A*B^2+A^2*B)*D+(B^2+2*A*B+A^2)*C^2+(2*A*B^2+2*A^2*B)*C+A^2*B^2)-((B^2+2*A*B+A^2)*C*D*(((2*B+2*A)*C+B^2+2*A*B)*D+(2*B+2*A)*C^2+(2*B^2+4*A*B)*C+2*A*B^2))/(((B^2+2*A*B+A^2)*C+A*B^2+A^2*B)*D+(B^2+2*A*B+A^2)*C^2+(2*A*B^2+2*A^2*B)*C+A^2*B^2)^2)^2+Bu^2*(((2*B+2*A)*C*D)/(((B^2+2*A*B+A^2)*C+A*B^2+A^2*B)*D+(B^2+2*A*B+A^2)*C^2+(2*A*B^2+2*A^2*B)*C+A^2*B^2)-((B^2+2*A*B+A^2)*C*D*(((2*B+2*A)*C+2*A*B+A^2)*D+(2*B+2*A)*C^2+(4*A*B+2*A^2)*C+2*A^2*B))/(((B^2+2*A*B+A^2)*C+A*B^2+A^2*B)*D+(B^2+2*A*B+A^2)*C^2+(2*A*B^2+2*A^2*B)*C+A^2*B^2)^2)^2+Cu^2*(((B^2+2*A*B+A^2)*D)/(((B^2+2*A*B+A^2)*C+A*B^2+A^2*B)*D+(B^2+2*A*B+A^2)*C^2+(2*A*B^2+2*A^2*B)*C+A^2*B^2)-((B^2+2*A*B+A^2)*C*D*((B^2+2*A*B+A^2)*D+2*(B^2+2*A*B+A^2)*C+2*A*B^2+2*A^2*B))/(((B^2+2*A*B+A^2)*C+A*B^2+A^2*B)*D+(B^2+2*A*B+A^2)*C^2+(2*A*B^2+2*A^2*B)*C+A^2*B^2)^2)^2)"/><Expression.T Id="uprAppBssCpD_D" Expr="sqrt(((B+A)^2*((B+A)*C+A*B)^2*Du^2)/((B+A)*D+(B+A)*C+A*B)^4+Au^2*((C+B)/((B+A)*D+(B+A)*C+A*B)-(((B+A)*C+A*B)*(D+C+B))/((B+A)*D+(B+A)*C+A*B)^2)^2+Bu^2*((C+A)/((B+A)*D+(B+A)*C+A*B)-(((B+A)*C+A*B)*(D+C+A))/((B+A)*D+(B+A)*C+A*B)^2)^2+Cu^2*((B+A)/((B+A)*D+(B+A)*C+A*B)-((B+A)*((B+A)*C+A*B))/((B+A)*D+(B+A)*C+A*B)^2)^2)"/>When I implement these expressions in the scripting engine, this comes with 2 difficulties:In Delphi the poweroperatordoes not exists (there's a function however)There's no subexpression optimalisation when using floats, which means that the same subexpressions are recalculated each timeOne way to convert such a Maxima expressions is to parse them and create expression trees and convert those, but that would take a lot of development time.The approach I took was much less sophisticated: intelligent search and replace. Intelligent in the sense that it works on whole identifiers only and with priorities. Also there's a mechanism to protect expression parts from being replaced.For instance:Code:<Expression.P Expr="(A*B*C)" ProtectGroup="1"/><Expression.P Expr="A*B*C^2" ProtectGroup="1"/><Expression.S Expr="A*B*C" Subst="(A*B*C)" ProtectGroup="1"/><Expression.O Id="ABC" Expr="(A*B*C)"/>Expression.P = protectExpression.S = substExpression.O = Replace by identifier, which will be set with the expression(A*B*C) Must be protected, otherwise a second pass would substitute it to ((A*B*C)).So why the parentheses?There's another process which replaces subsexpressions in parentheses with an generated identifier.This how the power operator stuff is handled as well, after many passes there's only one identifier which needs to be raised to some power. This subexpression is then replaced using multiplication operators.Code:<Expression.S Expr="S_189^4" Subst="((S_189*S_189)*(S_189*S_189))"/>Which will be optimized to<Expression.O Id="S_303" Expr="(S_189*S_189)"/><Expression.O Id="S_400" Expr="(S_303*S_303)"/>When all >60 expressions are processed this way, this will lead to >580 subexpressions.Using Maxima new expressions are reconstructed using those, to check whether they match the originals. This is needed because replacing text is not fault safe.When the optimalisations are ok, the expressions can be used in the engine code:Code:procedure TConfigAppBssCpD.ResistorPowerRatioUncertainties(const A, B, C, D, Au, Bu, Cu, Du: Extended; out Apu, Bpu, Cpu, Dpu: Extended);varB2: Extended;S_011: Extended;A2: Extended;S_060: Extended;S_122: Extended;C2: Extended;S_063: Extended;S_219: Extended;S_194: Extended;S_309: Extended;S_427: Extended;S_541: Extended;Du2: Extended;Au2: Extended;S_014: Extended;S_040: Extended;S_121: Extended;S_056: Extended;S_221: Extended;S_252: Extended;S_432: Extended;S_546: Extended;Bu2: Extended;S_039: Extended;S_120: Extended;S_057: Extended;S_220: Extended;S_251: Extended;S_442: Extended;S_556: Extended;S_068: Extended;Cu2: Extended;D2: Extended;S_142: Extended;S_247: Extended;S_367: Extended;S_404: Extended;S_012: Extended;S_195: Extended;S_430: Extended;S_544: Extended;S_254: Extended;S_443: Extended;S_557: Extended;S_013: Extended;S_253: Extended;S_431: Extended;S_545: Extended;S_067: Extended;S_368: Extended;S_074: Extended;S_202: Extended;S_459: Extended;S_573: Extended;S_092: Extended;S_287: Extended;S_464: Extended;S_578: Extended;S_286: Extended;S_463: Extended;S_577: Extended;S_075: Extended;S_201: Extended;S_460: Extended;S_574: Extended;S_006: Extended;S_173: Extended;S_094: Extended;S_231: Extended;S_321: Extended;S_127: Extended;S_240: Extended;S_314: Extended;S_009: Extended;S_026: Extended;S_191: Extended;S_378: Extended;S_511: Extended;S_008: Extended;S_025: Extended;S_190: Extended;S_377: Extended;S_510: Extended;S_174: Extended;S_372: Extended;S_505: Extended;beginB2 := (B * B);S_011 := (A * B2);A2 := (A * A);S_060 := (B2 + 2 * A * B + A2);S_122 := (S_060 * C + A * B2 + A2 * B);C2 := (C * C);S_063 := (2 * A * B2 + 2 * A2 * B);S_219 := (S_122 * D + S_060 * C2 + S_063 * C + A2 * B2);S_194 := (A * B2 * S_122 * D);S_309 := (S_219 * S_219);S_427 := (S_011 / S_219 - S_194 / S_309);S_541 := (S_427 * S_427);Du2 := (Du * Du);Au2 := (Au * Au);S_014 := (B2 * D);S_040 := (2 * B + 2 * A);S_121 := (S_040 * C + B2 + 2 * A * B);S_056 := (2 * B2 + 4 * A * B);S_221 := (S_121 * D + S_040 * C2 + S_056 * C + 2 * A * B2);S_252 := (A * B2 * D * S_221);S_432 := (S_014 / S_219 - S_252 / S_309);S_546 := (S_432 * S_432);Bu2 := (Bu * Bu);S_039 := (2 * A * B * D);S_120 := (S_040 * C + 2 * A * B + A2);S_057 := (4 * A * B + 2 * A2);S_220 := (S_120 * D + S_040 * C2 + S_057 * C + 2 * A2 * B);S_251 := (A * B2 * D * S_220);S_442 := (S_039 / S_219 - S_251 / S_309);S_556 := (S_442 * S_442);S_068 := (B2 * B2);Cu2 := (Cu * Cu);D2 := (D * D);S_142 := (S_060 * D + 2 * S_060 * C + 2 * A * B2 + 2 * A2 * B);S_247 := (S_142 * S_142);S_367 := (A2 * S_068 * Cu2 * D2 * S_247);S_404 := (S_309 * S_309);Apu := Sqrt(S_541 * Du2 + Au2 * S_546 + Bu2 * S_556 + S_367 / S_404);S_012 := (A2 * B);S_195 := (A2 * B * S_122 * D);S_430 := (S_012 / S_219 - S_195 / S_309);S_544 := (S_430 * S_430);S_254 := (A2 * B * D * S_221);S_443 := (S_039 / S_219 - S_254 / S_309);S_557 := (S_443 * S_443);S_013 := (A2 * D);S_253 := (A2 * B * D * S_220);S_431 := (S_013 / S_219 - S_253 / S_309);S_545 := (S_431 * S_431);S_067 := (A2 * A2);S_368 := (S_067 * B2 * Cu2 * D2 * S_247);Bpu := Sqrt(S_544 * Du2 + Au2 * S_557 + Bu2 * S_545 + S_368 / S_404);S_074 := (S_060 * C);S_202 := (S_060 * C * S_122 * D);S_459 := (S_074 / S_219 - S_202 / S_309);S_573 := (S_459 * S_459);S_092 := (S_040 * C * D);S_287 := (S_060 * C * D * S_221);S_464 := (S_092 / S_219 - S_287 / S_309);S_578 := (S_464 * S_464);S_286 := (S_060 * C * D * S_220);S_463 := (S_092 / S_219 - S_286 / S_309);S_577 := (S_463 * S_463);S_075 := (S_060 * D);S_201 := (S_060 * C * D * S_142);S_460 := (S_075 / S_219 - S_201 / S_309);S_574 := (S_460 * S_460);Cpu := Sqrt(S_573 * Du2 + Au2 * S_578 + Bu2 * S_577 + Cu2 * S_574);S_006 := (B + A);S_173 := (S_006 * S_006);S_094 := (S_006 * C + A * B);S_231 := (S_094 * S_094);S_321 := (S_173 * S_231 * Du2);S_127 := (S_006 * D + S_006 * C + A * B);S_240 := (S_127 * S_127);S_314 := (S_240 * S_240);S_009 := (C + B);S_026 := (D + C + B);S_191 := (S_094 * S_026);S_378 := (S_009 / S_127 - S_191 / S_240);S_511 := (S_378 * S_378);S_008 := (C + A);S_025 := (D + C + A);S_190 := (S_094 * S_025);S_377 := (S_008 / S_127 - S_190 / S_240);S_510 := (S_377 * S_377);S_174 := (S_006 * S_094);S_372 := (S_006 / S_127 - S_174 / S_240);S_505 := (S_372 * S_372);Dpu := Sqrt(S_321 / S_314 + Au2 * S_511 + Bu2 * S_510 + Cu2 * S_505);end;Without generating the Maxima file, the expression optimalisations and the program code this would be all very error prone! (and a lot of work). By exploring these techniques it might be easier in the future to implement other complicated calculations in code.

author: HendriXML
author_rank: Super Contributor
timestamp: May 10, 2022, 11:43:35 am
content: One handy use of the power ratio values is that it shows the influence a component has on the resulting value.For instance whenCode:Power ratio A = 25%;Power ratio B = 50%;Power ratio C = 25%;This means that for small (relative) changes resulting value changes accordingly.So if we want a 1% increase of the resulting value, we can accomplish that by increasing:Code:Incr A = 1%/25%*100% = 4%;OrIncr B = 1%/50%*100% = 2%;OrIncr C = 1%/25%*100% = 4%;Which can be usefull when selecting alternative component values to better match the target.The functionality of simulating actual component values is ready.While using it I found out that on of the things that could happen is that components are not spread around the specified value, but are all above or below them. Which probably results in only the highest or lowest value beeing a good candidate. If that happens to more components, then adding extra component values - being higher or lower than the calculated value might be needed. The power ratio can then be used to decide which component (A,B,C,D) in the configuration is best suited.This might even need some iterations.In another thread I'll go through the process of getting a precise replacement resistor. My first (and only) attempt deviated only 0,015% of the target on room temperature. Temperature stability was not that great. But when used in a voltage divider of similar resistors this might be less of a problem. No addition of extra component values where needed, but the intended input (A,B,C,D) for 2 values did swap. So I'm hoping for an (bad luck) example where it's not that easy.

author: HendriXML
author_rank: Super Contributor
timestamp: May 10, 2022, 04:09:18 pm
content: I've renamed the power ratio to relative weight, so it has meaning to other components besides resistors as well.If we assume the following:Code:Weight A: 25%Weight B: 25%Weight C: 25%Weight D: 25%And 3 resistors sets are 1% less at best (thus for example A, B, C not greater than specified value).This would mean D should need to compensate that with being at least 3% larger. That's still is a lot smaller than the difference between values in the E12 series (20%).So it might be advantageous to pick a configuration and values in which one component has a weight that is only 10%. In that case a neighbouring E12 value can still be compensated by the 3 other components.These measures are only needed if the values of stock components are off multiple times in one direction. The scripts calculates for each component the compensating (optimal) value, which can also help deciding which component needs to stepup/stepdown.