I wanted to use an Arduino as a capacitance measurement device for a coaxial wire. I started at measuring the wire capacitance using digital multi-meter UT58B. I turned the knob to 2 nF and then measured the capacitance depending on the wire length. These are the results:

Results for capacitance measurements

After the measurements I got the function (y = 0.0032x + 0.0268) on how the capacity changes depending on wire length. Now I wanted to use the Arduino to measure the capacitance and then calculate the wire length depending on the capacity. I tried following a guide to make the Arduino be able to measure the capacity.

Now the problem. I tried calculating the needed resistance using R = TC/C for one seond and got:

R = 1/(0.019*10^(-9)) = 52631578947.37 ohm

As you can see the resistance is too big. My questions:

  1. Should I decrease the time constant? And how small could it be so that arduino can still measure the time? What maximum resistance can you suggest?

  2. Maybe I wrongly read the multi-meter values? (the 2 nF scale)

  3. Maybe there are other solutions you can suggest to measuring capacity with Arduino?

  • 2
    \$\begingroup\$ 1s is an insanely long time. Use something much shorter. \$\endgroup\$ – Ignacio Vazquez-Abrams Dec 4 '15 at 12:32
  • 1
    \$\begingroup\$ On your graph, are the units nF? Are you trying to measure capacitance in the range 0 to 350pF? \$\endgroup\$ – Oliver Dec 4 '15 at 12:49
  • \$\begingroup\$ @Ignacio Vazquez-Abrams Any suggestions on what could be the most optimal resistance and time constant for arduino measurement? \$\endgroup\$ – disoderly Dec 4 '15 at 13:07
  • \$\begingroup\$ Nope. But you have the hardware in front of you, so it shouldn't be difficult to run the appropriate tests. \$\endgroup\$ – Ignacio Vazquez-Abrams Dec 4 '15 at 13:08
  • \$\begingroup\$ @Oliver On the graph are the values my multi-meter showed when it had the knob on 2nF position. So the units are nF if I am correct. \$\endgroup\$ – disoderly Dec 4 '15 at 13:08

In actuality, you can use an Arduino and you do not need to utilize an oscillator with the test capacitor in the tank. This will work quite well for capacitors of 10pF or more, and with care even below, though that is not something I would have believed until trying it. You do however need your PCB to be very clean without flux residue or remains of efforts to remove it.

The key is not to use the low impedance, slow ADC, but rather the comparator, and utilize the timer block to measure the charging time.

This is what the Arduino capacitance measurement example does, and also the ATmega based kits with LED digit display which you can buy for around $11. Source resistor is typically selected be a GPIO and in the 100K - 1M type of range. Stray capacitance is calibrated out by measuring the time constant with only the meter and test fixture, but no capacitor under test. Provided you don't move the fixture or get your hands into the field of measurement, adding even a tiny test capacitor then linearly increases the time constant.

  • \$\begingroup\$ Yes this approach works quite well, I have implemented a touch sensor this way (capacitance around 10 pF) and am working on a pressure sensor with a capacitance of 47 pF to 100 pF with the same approach (but with a different kind of resolution you'd get with an Arduino). \$\endgroup\$ – Arsenal Dec 4 '15 at 14:45

The system the Arduino Example shows will probably not work for you.

You are trying to measure fractions if a nF, so either your resistor will be huge, or your time to find the point of interest is so small you only get 4 or 5 samples on your ADC. The prior is not an option, because of pin input leakage, the latter not because you won't find it.

Apart from that, your Arduino uses an internal sample and hold based on a small capacitance. Where small is much larger than what you are measuring. You could fix that with a unity-gain op-amp with very low input capacitance and input leakage, but that still won't fix your other problems.

What you will need to do is recreate what your multimeter does. A capacitor has an internal resistance plus the resistance it has for a frequency signal. Most affordable multimeters ignore the internal resistance and just measure the total at 1kHz.

We can go into the maths, with imaginary parts and results and what not, but since you're only interested in the results, and don't even need accurate calibration against correct capacitor value, you can redo your measurement experiment with your set-up. So for completeness I will only mention here that the complex impedance of a capacitor is given by:

Z(c) = 1 / (jwC) where w = small letter omega, which stands for angular velocity, or w = 2*pi*f, where f is the signal frequency. For first estimation purposes one can simplify that to the real part of the resistance being given by:

"R(c)" = 1 / ((2*pi*f)*C) <-- Ignores the imaginary parts, that may be important in some cases.

Now, what does a multimeter or RLC meter do? Simplified something like this:


simulate this circuit – Schematic created using CircuitLab

It knows it makes a 1kHz sine function at a certain voltage, so it measures the current that flows into the capacitor, then if it is sure about the voltage (either by strong drivers of the sine signal, or by measuring that as well), it can calculate an effective AC resistance and from the formula above it will turn that into capacitance.

But that's all not very relevant for you, what you probably should do, to make it as easy as possible, is create a frequency, possibly with a timer output on the Arduino and record what current flows through the cable's capacitance at what length, and just create a new formula for that, as that involves much fewer steps and calculations and calibrations than first getting the capacitance right and then transforming that.

To be able to estimate what we need, we should calculate the apparent resistance of your limiting values. From your graph it's 50pF to 350pF, so we'll take some room and make it 25pF to 500pF. So we calculate with the simplified equation I gave earlier, I'll assume 1kHz, since that allows you to adjust to 100Hz and 10kHz if needed:

"R(25pF)" = 1 / (2*pi*1000Hz * 25pF) =~ 6.37M Ohm

"R(500pF)" = 1 / (2*pi*1000Hz * 500pF) =~ 318k Ohm

Now, this assumes a sine wave, and you will most likely be making a square wave, which contains many higher frequencies, which will decrease those figures. Assuming you are using 5V, we can pretty safely say your measurement will be between 1μA and 40μA peak.

Now we need to find a trick to turn 1μA to 40μA into something your Arduino can measure. Here we go:


simulate this circuit

The first op-amp is a difference amplifier with a gain of 5. You can have 10 gain there as well, but if you add the rectifier to that stage, your leakage path will include a capacitor, and that may give you trouble when you decide to start playing with the frequency.

The first op-amp amplifies the difference across the resistor of 10k by 5, because it wants the + voltage to be on the - side. At a high going flank of your signal it will see a difference based on the current, in the positive direction. At a low going flank it will see the opposite, so it will try to create a negative voltage. Fortunately powered by +5V and ground it can't do that.

The second op-amp takes the positive pulses and amplifies them by 2 through a diode. The diode makes sure the capacitor can only be charged by the pulses and discharged by the feedback loop of R7 + R8. So the discharging of the 100nF capacitor has a time constant of about 0.44seconds to discharge to about 37%, that gives you a bit of slowness, but will get you a good rectification for 100Hz to 10kHz signals. The charging may also take a little time, because the op-amp may not be able to fully charge the capacitor the first few pulses, but I don't think you will notice that difference much.

If you need it all to be faster you can decrease the capacitor a little, just be sure the discharging RC-constant (R value times C value) is less than 1/5th the source frequency you end up using.

I chose the TL051A because it has a nice and low input bias current, low input offset voltage (less than 1mV) and a good output slew rate (20V/μs) as well as a unity gain bandwidth more than 50 times the highest frequency we were considering. Another important thing here is the fact that its inputs can go all the way up to its power supply. They don't give good results at the negative rail (so when the pulse is steady off), but from its internal schematic I expect the output to remain close enough to 0 to not be much of a bother.

It is available at farnell for about €1,- in SMD and DIP packages, so it's quite suited for hobby work. I tried searching Digikey, but the search function didn't work.

Here's the TL051A datasheet.

For the second op-amp it's important it's able to go to the 0V at the input, or at least close to it, and since the signal is already amplified a lot, input offset voltage can be a bit higher and input offset current and bias current are not that relevant, so a standard LM358 type might be suitable. Although it is possible it will give a little distortion on the highest output voltages, I expect that to be limited.

Here's the LM358N datasheet

Now you can sample a 0.1V to 4V signal to determine the measure capacitance leakage. With a 10bit ADC running on 5V you have a bit-resolution of about 5mV per LSB, so you should be able to measure quite accurately.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.