I went into this project with the thought that it will be a rather small one. This certainly influenced some decisions I made along the way. Now that the project had evolved into a much larger thing than initially anticipated it’s reasonable to have another look at possible optimizations, albiet the calibration results were already pretty satifactory.

The problem with the contact resistances

From the start it was clear that the relays’ contact resistances will reduce the accuracy of the programmable decade resistor, especially in the lower two decades. (When using 0.1% resistors, for the third decade and up, the tolerance of the resistors is of the same or a higher magnitude than the contact resistance of the relays. So it’s much less important or even pointless to compensate for the contact resistance in those instances. This is especially true for the highest two decades where the algorithm described in a previous post can effectively eliminate the deviation by adjusting the “hardware setpoint” according to calibration values.)

To mitigate this issue I used high quality relays and paralleled their two poles. To further improve accuracy I added bypass relays for the lower three decades that bypass effectively shorted higher decades (Details). What I did not do though: Adding footprints to improve accuracy by measuring the actual resistance and connect a matching resistor in parallel to the precision resistors. Again, this was intentional to reduce complexity and the required board space. Also, the contact resistance is not exactly constant, so there will always be some deviation caused by the relays. With the topology I selected it’s not quite so easy to compensate for the contact resistances, because the contact resistance varies between odd and even resistance values.

And of course, shorted decades (resistance of 0 Ω0 \text{ }\Omega) will always have a residual resistance. And even though I have those bypass relays for certain situations, they have a contact resistance too. Shall we compensate for those as well to get better accuracy for the lower decades at the cost of the higher decades where the bypass relays are not available? One could argue that it would be preferable to do so, because a few milliohms do not matter for larger values: Again, the tolerance of the resistor would be much larger than that anyway.

Solutions

That being said, improvements can be achieved even if the result won’t be “perfect”. Let’s take a look at the schematic of the first decade:

Simplified decade resistor topology
Simplified decade resistor topology

There are two variants to improve the situation that I’d like to discuss:

  • Variant 1: We now connect resistors in parallel with R4 and R6 that reduce each resistance by about one relay’s contact resistance (about 25 mΩ 25\text{ m}\Omega, see calibration results).
  • Variant 2: We only use a parallel resistor for R6, so that the resistance is reduced by two times the contact resistance (50 mΩ 50\text{ m}\Omega)
ResistanceRelays in signal pathContact resistance (ca.)
(Ω\Omega)
Expected offset after modification variant 1 (ca.)
(Ω\Omega)
Expected offset after modification variant 2 (ca.)
(Ω\Omega)
0SW3, SW4, Bypass relays0.0750.0750.075
1SW4, Bypass relay0.0500.0250.050
2; 4; 6; 8SW3, (SW7; SW10; SW13; SW15), Bypass relay0.0750.0500.025
3; 5; 7; 9(SW7; SW10; SW13; SW15), Bypass relay0.0500.0000.000

Demonstration of the effect of the two modification variants for the first decade

We can clearly see that both solutions are not perfect. I would prefer variant 2, because this improves the situation significantly for all resistance values greater than 1. In contrast, with variant 1 we have a large offset of about two contact resistances for all even resistance values, whereas for odd values we have reduced the offset to close to 0: The error varies significantly between consecutive resistance values.

But how would we implement variant 2 then? The calculation is very simple. With RpR_p as the resistance of a parallel connection and Rp1R_{p1} and Rp2R_{p2} as the branches we get:

Rp1=RpRp2Rp2RpR_{p1}=\frac{R_p \cdot R_{p2}}{R_{p2}-R_p}

Let’s say we want to decrease R6 by 50 mΩ50\text{ m}\Omega, then we calculate the value of the resistor Rp1R_{p1} to be connected in parallel as follows:

Rp1=1.950 Ω2 Ω2 Ω1.950 Ω=78 ΩR_{p1}=\frac{1.950\text{ }\Omega \cdot 2\text{ }\Omega}{2\text{ }\Omega-1.950\text{ }\Omega} = 78\text{ }\Omega

Implementation

In reality, we used 4 resistors (R7 - R10) in place of R6 from the schematic above. This leaves quite some options to implement the parallel connection.

Actual topology
Actual topology

Every decade uses nine resistor of the same value. In order to get a bulk discount I ordered ten for each decade. I wonder whether I can use the tenth resistors here. Sure enough: I would simply solder the tenth 20 Ω20\text{ }\Omega resistor in parallel to one of the resistors R7 - R10. This will reduce the resistance by about 46.5 mΩ46.5\text{ m}\Omega. Since there is no exact value for the contact resistance anyway, this should be good enough. (By the way: The thermal coefficient of the ten times larger resistance connected in parallel isn’t all that critical - a ten times larger thermal coefficient of 100 ppm, compared to the 10 ppm of the precision resistors, shouldn’t degrade the overall performance significantly, but why not use a better resistor than that…)

And for the second decade we could simply use the 2 kΩ2 \text{ k}\Omega resistor for the parallel connection, reducing the 20 Ω20\text{ }\Omega nominal resistance by about 49.6 mΩ 49.6\text{ m}\Omega.

Picture of the modification
The green 20 kOhm resistor is soldered on top of the black 20 Ohm resistor. Note the similarities of the PCB layout and the schematic

And this is what I did and what can be seen in the pictures (a green 20 kΩ20\text{ k}\Omega precision resistor on top of a 20 Ω 20\text{ }\Omega resistor).