New method for measuring lots of resistors using very few wires – part 2 – Theory

The Matrix

Continuing from part 1 the matrix form used needs to be described.

If you need a quick “tutorial” in systems of linear equations, take a look at this text I wrote.

First, the vector of the unknowns – x . The vector is:

\large \mathbf{x} = [ G_1 , G_2 , G_3 , \cdots , G_N ]

where GN is the conductance of the respective resistor. We do not know the values of the individual conductances (we know the values of some of the conductances, the reference resistors, but for the purposes of the calculation we do not know them).

The coefficients matrix and the right hand side vector go hand in hand. In the matrix form of equations each equation can be transcribed into one row of the A matrix and one number in the b vector. So for every measured situation we will generate the following equation:

\large (U_1 - U_C) G_1 + (U_2 - U_C)G_2 + ... + (U_N - U_C)G_N = 0

The particular number in b will be 0. As for the row in the matrix A the values will be 0 for the resistors that are not involved in that particular resistive divider and (UN – UC), where UN is the voltage on the node that is connected by RN to the center node and UC is the node on the center voltage

So, let’s use the following 8 node system as an example:

Example 8 node system

The resistors are numbered. We will apply a situation to it – the measurement system will connect some of the nodes to the low excitation voltage, some to the high excitation voltage and set one to be a high impedance node. Red markers on the image will represent nodes connected to a high excitation voltage, blue nodes represent the ones connected to the low excitation voltage and the green one is the high impedance one that will be the center node for the voltage divider.

NodeState
AHigh +5V
BHigh +5V
CHigh +5V
DLow GND (0V)
EHigh impedance (HiZ analog input)
FLow GND (0V)
GLow GND (0V)
HLow GND (0V)

Connecting the nodes turns the whole setup into a voltage divider. As was discussed previously, we can safely ignore all of the resistors that do not connect directly to the divider center node (E). So, let’s connect the nodes. The voltages on the individual nodes will be something like this:

Example situation in an 8 node system

We can safely omit the resistors that are not connected to the center node (E) for clarity. The resistance values are not needed for the actual calculation or matrix formation. Node voltages have been measured as follows:

NodeVoltage to ground [V]Resistor connecting to center node (E)
A5.00010k
B5.00011k
C5.00012k
D0.00013k
E2.710N/A
F0.00014k
G0.00020k
H0.00030k

Only resistors 4, 10, 15, 19, 23, 24, and 25 are involved in the divider. So let’s formulate the equation:

(note: Since the equations are getting very long and I’m having trouble fitting them into latex in any way that makes them look good, some will not be written in latex. Appologies to the font nazis.)

0G1 + 0G2 + 0G3 + (UA-UE)G4 + 0G5 + 0G6 + 0G7 + 0G8 + 0G9 + (UB-UE)G10 + 0G11 + 
0G12 + 0G13 + 0G14 + (UC-UE)G15 + 0G16 + 0G17 + 0G18 +
(UF-UE)G23 + (UG-UE)G24 + (UH-UE)G25 + 0G26 + 0G27 + 0G28 = 0

Nasty, isn’t it? Note however that most of the conductances have a zero coefficient, as such we can remove them.

(U_A - U_E)G_{4} + (U_B - U_E)G_{10} + (U_C - U_E)G_{15} + (U_D - U_E)G_{19} +
(U_F - U_E)G_{23} + (U_G - U_E)G_{24} + (U_H - U_E)G_{25} = 0

Adding the specific numbers we get:

(5-2.710)G_{4} + (5-2.710)G_{10} + (5-2.710)G_{15} + (0-2.710)G_{19} +
(0-2.710)G_{23} + (0-2.710)G_{24} + (0-2.710)G_{25} = 0

Which equals:

2.29 G_{4} + 2.29 G_{10} + 2.29 G_{15} -2.71 G_{19} -2.71 G_{23} -2.71 G_{24} -2.71 G_{25} = 0

So this particular row of the equation will be:

x = (G1 G2 G3 G4   G5 G6 G7 G8 G9 G10  G11 G12 G13 G14 G15  G16 G17 G18 G19   G20 G21 G22 G23   G24   G25   G26 G27 G28)
A = [0  0  0  2.29 0  0  0  0  0  2.29 0   0   0   0   2.29 0   0   0   -2.71 0   0   0   -2.71 -2.71 -2.71 0   0   0]

and that row in b will be 0.

This was the process for creating one single line of the final matrix. For a complete measurement this will have to be repeated many times over for different situations, with the high impedance node set to different nodes.

The absolutely minimal number of different measured situations would be equal to the number of unknown resistances. However, the more situations are measured, the better. With a low number of measured situations the error of the system can be very large (hundreds of percent even, depending on the noise and various other factors, will be discussed in another part). With more measured situations, the error drops down.




The number of possible combinations of node settings (situations) can be pretty large. Assuming that every combination with a single floating node is used, for an 8 node system, assuming two power rails, this comes to 8*128=1024 possible situations. However, not all of them are actually useful – a combination where all of the powered nodes are connected to GND will not yield anything useful, since the resulting divider will be completely connected to one excitation voltage, giving no clues as to the ratios of the resistors. Also, using all of the combinations would cause the measurement to be very long and memory hungry – it’s possible, but not needed. So a limited subset is sufficient for an actual measurement. Of the 1024 combinations possible for an 8 node system, I have chosen to use 248 situations, but other numbers of combinations would work as well.

The visual representation of the situations for an 8 node system follows:

Visual representation of situation node settings in 8 node system

This is a representation of 248 situations in the 8 node system. Each “row” represents one situation, each “column” represents one of the nodes. Blue represents a node that is set into a high impedance state, green represents a node tied to GND (low excitation) and red represents a node tied to VCC (high excitation). If you with to see situation visualizations and their source files, please download the following file.

So that’s the main part of the matrix – the measurement values. At the moment there are no absolutes present in the matrix. So the reference part of the matrix needs to be added. This is a very different format of an equation. This just assigns a known value to the known resistors. So, assuming that we know the resistances (conductances) of resistors R1, R14 and R28, we will have three reference equations. These are in the following format:

1 G_{N} = g_{N}

where g_{N} is the actual conductance, placed into the right hand side. For the example case, where we know the resistances of R1 (330050 Ohms = 3.029844E-06 S), R14 (329280 Ohms = 3.036929E-06 S) and R28 (329580 Ohms = 3.034165E-06 S)  the equations would look as follows:

1 G_{1}=3.029844*10^{-6}
1 G_{14}=3.036929*10^{-6}
1 G_{28}=3.034165*10^{-6}

These lines can be duplicated to further “enforce” this “rule” for the solver. These are the precisely measured values of three 330k resistors that are used as reference resistors on one particular measurement board I made.

That’s that as far as the linear equations are concerned. All that is needed is to solve them.

The actual solving is done using a linear equations solver. In the software I made I use Math.NET, but any should do. Basically, the solver searches for a set of values (the x vector) that satisfies all of the equations that are structured into the \textbf{Ax=b} . If no exact solution is possible (which is certainly the case for equations generated this measurement), it searches for a set of values for x that is closest to fitting the equations. The output of a solver is a filled x vector that is the closest solution to the generated measurement.

Now the x vector is filled with the conductivities of the individual resistors. To get the resistances, the reciprocal value of the vector is needed. Once that is gained, we are done – we have the resistances of the individual measured elements. And all it took was a lot of GPIO twiddling and a load of math. Enjoy!

Example

An example matrix, from an actual measurement done using an ATMega32 (the actual implementation of the measurement will be talked about in another part of this series), including an Octave script can be downloaded here:

Unzip the directory somewhere and run the LoadAndCalculate.m script. This is the result of a measurement of a board with resistors of a fixed value, three of which were known reference resistors (R1, R14 and R28).

#Demonstration to load an example resistor net 
#matrix and calculate the resistances
#Load the A matrix and the b vector
A = csvread('A.csv'); 
b = csvread('b.csv');

#Do the actual calculation
x = A\b;

Conductances = x;
#convert the conductances into resistances
Resistances = 1./Conductances;

Resistances' %Display the resistance vector

How the actual calculation works is outside of the scope of this text. See my other post for a very simplified explanations that’s probably full of errors, or better yet – read a different text from someone who is actually a mathematician.

The visual representation of such a matrix (done by PlotMatrix.m ) can be seen here:

Visual representation of a measurement matrix

Visual representation of a measurement matrix

This is a visualization of a single matrix. The upper few lines are the reference part of the matrix, the rest are the actual measurement. All lines of the b vector are zero, aside from the ones in the reference part of the matrix. This particular matrix is 260 rows long and 28 columns wide. Of the 260 rows, 12 are the reference part of the equations. The particular pattern that the matrix looks like is explained by how the situation generator generates the situations.

Executing this script should yield the resistances of the individual resistors. In this case they were 25 thermistors, with a 680k resistance at 25 °C, as well as three 330k reference resistors.

Conclusion – method

So, that’s that! With this method you can do a measurement of a large quantity of resistors, using a minimal amount of cabling. This is not exactly useful for most areas, and it won’t be replacing Kelvin resistance measurements any time soon, but there are niche areas where this method can be actually useful.

Space constrained applications are one area – imagine you have to measure a lot of temperature sensors on the length of a very thin, long rod – any other method would require more cabling or intelligent (capable of connecting to a data bus) sensors. This method just requires say, 16 signals running through the inside of the shaft and you can measure over a hundred thermistors along the length of the shaft. MEMS systems could also benefit from this. Or just a sensor array.

Another interesting usage of this might be using it to measure small quantities of resistors using a lot of known resistors – this actually yielded some interesting results – thanks to the insane amount of oversampling, this can actually provide a resolution well beyond that of the ADC (I’m still working on this area, but the preliminary results are interesting).

The advantages of this measurement are obvious – you can measure a lot of resistors using just the bare minimum amount of cabling or pins of your device, without needing any intelligence in the sensors themselves.

The downside – it’s a memory and computation hungry method, it’s not exactly fast and there are unforeseeable sources of errors. As such it needs some processor capable of doing the number crunching.

The technique bears some similarity to electrical impedance tomography, but is at its core different for being used on discrete parts (resistors) rather then volumes, uses DC excitation and uses reference resistors to enable the measurement of the exact resistance values. Also, it can be used with a single, cheap microcontroller.

In the next part of this text I will show you a device I built that actually implements this measurement, the software that goes with it and the results. As a teaser I am including the results of an actual measurement of a 150kΩ resistor, which was measured with 27 other resistors 😉 Stay tuned!

Measurement of a 150kOhm resistor

Measurement of a 150kOhm resistor

And if you liked this text, donations are always welcome!

If you need any help implementing this method for your particular thingamajig, contact me!

This entry was posted in Projects, Resistance measurement method and tagged , , , , , , . Bookmark the permalink.

4 Responses to New method for measuring lots of resistors using very few wires – part 2 – Theory

  1. Joe says:

    Hi there
    I’m not a scientist and just hobbyist level in electronics but one thing struck me. Based on the schematic shown above, you cannot measure individual resistors. How can this work?
    For instance, if you try to measure the resistance between A and B, it’s not just resistor #1 you are measuring. There are lots of additional chains of unknown resistance values because in this network every point is connected to every other point, albeit through up to seven resistors. A and B are also linked by resistors 7, 28, 26, 23, 19, 14, and 8 (outer resistors, going counterclockwise beginning with A). But that is only one path. All other paths are also connecting A and B through up to six resistors in series. Resistances will never be as high as an open connection so they will disturb the measurement.
    So whatever points you choose for measuring, you will measure the entire network, variance mainly depending on the resistor that directly connects both points under test. There may be a way to still figure out the value of each resistor individually but I imagine that a lot of noise and missing precision will spoil the results. If that’s an iterative process that narrows down each value, it might be very time-consuming and require a lot of processing power.
    It might work better (in theory) if diodes are added but they have their own influence regarding resistance so it’s another impossibility there to get precise values out of it all.
    I could be completely wrong. Please excuse in that case.

    Regards
    Joe

    • daqq says:

      Dear Joe,

      Thanks for the comment, that is exactly the point of the whole nasty math, right there – to extract the individual resistances from their combined effect. You are correct that every resistor contributes to the final value. However, there is a way to extract the individual values, as per the discussed mathematics.

      Best regards,

      David

  2. Terry M. says:

    It should be possible to accomplish the same without a power source and by only doing resistance measurements. You would measure resistance between two points, while cycling through combinations of leaving the other nodes open or shorted between themselves. Of course this is not directly doable using microcontroller GPIO and ADC input measurement, but instead you would need analog switches (or reed relays for very wide dynamic range), and perhaps a constant current source. It would be interesting to see the “math” for that implementation, but as a hardware design it’s not as practical or elegant as what the author describes.

    The applications of this technique can be wherever a large number of resistive sensors are required, yet the amount of required connections/wiring needs to be as low as possible. The method described is even lower than a more conventional X-Y matrix.

    The suggestion of using this method with digital sources/sensors is made, and an example is if a fixed resistor is placed in series with a keyboard button. I would argue however, that it’s better in that case, to use binary weight resistor values, or an R2R Ladder, and measure the summing node voltage. Much less math in that case, when you only decode a binary value to it’s constituent bits/inputs that are either high or low. Albeit that each switch requires an additional pull-up resistor in that case, which increases the parts count compared to the method described by the author.

    Software and Digital Engineers too easily overlook these more “Analog” methods of multiplexing or combining of repetitive I/O, and the benefits of save on wiring/connections. The cost of high density connectors and wire harnesses usually exceeds the cost of PCB assemblies.

    Thanks for this posting!

    • daqq says:

      Hi Terry, thanks for the comment.

      This is only one of the possible implementations where you do an insane amount of muxing and construct a mathematical model of the system and then try to fill it with correct values – others are possible, something like you describe could be done as well, as well as a lot of different measurement types. There’s a lot of possible work that can be done to improve this specific method as well 🙂

      Basically in this method I was exploring one simple path, with the simplest possible hardware. On a different forum a member advised that better results could be gained by means similar to what you describe using some lovely Keithley gear, which would be true, but, again, with more costly gear. Also, the sound of a giant relay mux card switching between 200+ setups would probably drive me insane.

      As to the complex wiring – as I said, this is for a very niche set of applications, it’s not going to replace 4 wire Kelvin any time soon 😀

      Best regards!

      By the way, if you need help implementing this or have any other questions contact me 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *