Measuring capacitance is the task every Arduino owner has to deal with sooner or later. This is especially true once you move from thru-hole components to SMD ones – smaller capacitors, unlike resistors of the same size, are not marked at all. How do you make sure they didn’t get mixed up in the package? And, well, how do you measure these salvaged thingies that you unsoldered somewhere? Not to mention the fact that it is a good idea to check your capacitors before placing them on a board, because errors caused by malfunctioning ones are extremely hard to nail down.
The basic multimeter doesn’t measure capacitance, and you may not want to buy a dedicated IC meter just to play around with a couple of capacitors once in a while. Thankfully Arduino has everything on board to easily make a capacitance meter – with reliable results on capacitors of 20pF and up to at least 220uF and rather good results for smaller ones, even on a breadboard. Just add some resistors and wires.
This came out as a rather lengthy instructable, so, if in hurry, you may want to jump to Step 4. The first steps are dealing with the basic idea and implementations-in-process.
Step 1: The Basics
There are lots of ways to make a capacitance meter on the net, starting with minimalistic no-external-components experimentation and up to measure-almost-everything sadly cancelled project. There are three basic approaches to capacitance measurement that can be used on Arduino – check a detailed description in the “Inductance/Capacitance Saga” instructable. I chose the time constant way because it’s the most understandable and easy to make. Sure, it has some error margin on the plus side due to stray resistance, but it’s noticeable mostly on big capacitors, especially tantalum ones.
The time constant approach calculates capacitance based on the amount of time it takes to charge a capacitor to some pre-defined voltage. Arduino provides us with the 16MHz timer and an analog comparator on pins 6 and 7 (note: while this is an analog comparator and its leads are called AIN0 and AIN1, it sits on digital pins of Arduino, namely D6 and D7). The latter can call an interrupt when the voltage on one of the pins rises above/falls below the voltage on the other.
To make this work we’ll need a breadboard, some wires and three resistors that will be called Rc, R1 and R2 from now on. Rc is the charging resistor, it sits between an Arduino pin and the capacitor being tested. The bigger it is, the slower the charging process, the more accurate results, the more time for discharge. For nF and uF capacitors you’ll need a 10K or 20K Rc resistor; a 1M and more is better for pF capacitors, but we’ll get to that later, so grab a 10K resistor for now. R1 and R2 provide the reference voltage according to the following:
Vref = Vin * (R2 / (R1 + R2))
Vin is the Arduino 5V supply, but in fact is around 4.8V. I used 1K for R1 and 2K for R2, which gave me around 3.2V of Vref, which is perfect, but you may use different resistor values if you wish.
To make the first version of Arduino capacitance meter head to Nick Gammon’s site and grab the last sketch on the page (the third one); you may also check the detailed explanation of the time constant workings while you are there.
Now, connect the resistors as shown there (or on a photo above), change these lines according to your setup
const byte pulsePin = 2; // the pin used to pulse the capacitor const float Rc = 10000; // charging resistor const float R1 = 1000; // between ground and D7 const float R2 = 1800; // between +5V and D7
insert some capacitor (I would suggest something like 100nF for a start) into test location and upload the sketch to Arduino.
You should get some readings in the serial monitor. If not – check the monitor settings, it should work at 115200 baud.
Step 2: Improve the Sketch
Now we have a basic capacitance meter on Arduino. It does work, but some improvements are due. The most obvious ones are:
- Controllable capacitor discharge. In Nick’s sketch the discharge is handled via a simple 3-second delay; too much wait between readings.
- Start the charging directly through port manipulation, because digitalWrite is too slow. This is exactly one of the rare situations where this is meaningful – in 99% other cases digitalWrite is perfectly ok, don’t believe purists who say otherwise. But here it’s important – we don’t want to lose timer ticks between charging and timer starts. And, let’s face it; this code is full of port manipulation in any case, so readability doesn’t matter much here.
Thankfully you don’t have to edit Nick’s code because someone else already has done it. In fact, someone called tmd3 from Arduino forums wrote his own version, and it handles both problems. Get the sketch on the second page of this thread in post#21 (and you may also want to read the discussion there, as it explains a lot of stuff).
Now, some changes on the breadboard are due. Pins 6 and 7 are reversed in the new sketch, so now pin 6 gets reference voltage feed and voltage on pin 7 is being tested. The charging pin is pin 9 (instead of pin 2 previously) and we also get a new discharge pin and resistor: connect a resistor of around 200 to 1K Ohms between pins 8 and 7 (I use 510 Ohms).
Ok, connect everything and upload the sketch (don’t forget to change the resistor values to your ones). Note that this sketch measures capacitance in uFs, so the numbers on screen are different. In fact, you should change the line
Serial.print(C,6); Serial.print(" uF"); Serial.println();
Serial.print(C,6); Serial.print(" uF --- "); Serial.print((C*1000),3); Serial.print(" nF"); Serial.println();
to get more readable results (I keep two figures in the output not to confuse uFs and nFs).
This meter is quick and also lets us see the actual ‘stray capacitance’ of our setup when no capacitor is under test to substract it from the result. Also, the addition of a discharge resistor makes discharge faster and independent of the charging resistor value. This particular change will let us use a rather big charging resistor for Rc.
Step 3: Measure PF and SMD Capacitors
The above setup is good for measuring capacitors of 1nF and upwards. As for the smaller value caps, it will provide rather approximate results. When I was measuring a bunch of unknown capacitors, I just put these smaller value caps aside for later, because to get their capacitance we’ll have to replace the Rc resistor with a much bigger one (don’t forget to change the define in the sketch accordingly). I had a 1M Ohm resistor, but 3M is even better. 1M resistor provided reliable results on capacitors of 20 pF and up, and helped identify even smaller ones, but here you can’t be sure about the exact value because of the constant jitter – in my setup it was around 0.5pF, which made 1pF measuring resolution unavailable.
Let’s now make a simple contraption for measuring SMD capacitors right on the breadboard. To do it you’ll need two straight male pin headers. Remove the black plastic supports from them and then bend the things to an L shape as shown (don’t use pre-bent headers as you’ll need one leg to be longer than the other). Insert the resulting L-headers into the adjacent breadboard rows and measure SMD capacitors between the protruding ends. It’s excellent for small capacitors of 0603 and 0805 sizes (you may need to help the ends connect to the cap with plastic tweezers). For bigger caps move the L-pins a bit further apart and put the caps either between or on top of them.
The third thing I’d like to suggest in this step is understanding the actual possible capacitance values. There are standard values that are widely available, and the caps you’ll measure will most certainly comply with these standards with a tolerance like 10%; so if the meter shows, say, 700pF you may be pretty sure you’re dealing with a 680pF capacitor. Standard values can be found, for example, here, but this list is not full; for fuller list head to a big online store like Digikey.
Step 4: Final Improvements
Since I was rather satisfied with the measurement algorithm I decided to finalize sketch improvement. Most notably, I wanted it to be able to work with both big and small Rc resistors and switch between them automatically depending on the value of the capacitor under test, to avoid unnecessary reloading of the sketch. Other changes include automatic ‘stray capacitance’ adjustment for both modes, bigger board setup options (pin selection, explained in the next step) and a readable display.
Before I get to the code I’d like to suggest you get a good serial monitor program, if you haven’t already. The ones present in IDEs (both Arduino and UECIDE) are rather primitive. The Arduino one can’t display CR (carriage return) properly and the UECIDE doesn’t recognize tabulation; both ASCII symbols are present in my sketch. I use RealTerm, but you may prefer something else. If you get RealTerm, make sure to select Ansi in the Display As tab; also use the Open button on the Port tab to turn port input on and off (can be used as a reset too). If you want to get the readings in a list, not in one line, switch the Display As back to ascii. If you wish to stick to Arduino/UECIDE serial monitor, you may just comment/uncomment a couple of lines in the defines setup section of the sketch.
The new board setup is above (hope I didn’t mess it up) and the code is at the bottom of this step, as it's impossible to include it properly in an instructable.
Try to make the connections as short as possible to minimize stray capacitance; don’t follow the Fritzing schematics to the letter, it’s drawn this way just because Fritzing can’t squeeze resistors into adjacent rows. But you can.
This sketch takes some time to start up: it calculates ‘stray capacitance’ for both Rc resistors, then it tests jitter on the big one. This step is needed to make sure the adjustment was correct; if I see that the jitter leans too much to – or + side, I just restart Arduino (I tried to average this jitter and include it in the pF adjustment but didn’t like the result). It is possible to disable nF or pF mode if needed by grounding the corresponding pin (11 and 12 by default); this can be done both before starting up and on the working device (you may wish to connect some switches). It may be necessary when measuring some very small caps, like 15pF or less, as the program will consider their value insignificant in normal mode. Automatic switch from nF (default) mode to pF doesn’t happen instantly to avoid errors while you are putting a capacitor on a test bed (some random results are generated in this process).
First 60 lines of the code are a ‘setup defines’ section that can be easily changed according to your layout. Hopefully, the comments there are enough to understand the workings. Test voltage pins (the ones supplying 5V to charge the capacitor via Rc resistors) are limited to one of the two combinations: pins 9 and 10 or pins 3 and 4. The reason for these two sets will be explained later; if you need to use completely different pins you’ll have to play around with port manipulation macro VPIN_HIGH (or even discard it completely and write something different).
Step 5: Make a PCB
As this project is simple and useful I wanted to make a PCB out of it, just to make it easier to setup my meter later, without the need to remember the schematics, search for resistors and connect everything. I did make two in the end, but didn’t find them more convenient or error-free than the breadboard setup. There is less stray capacitance, but it is still present because it is generated right on the Arduino board. Still, if you never made any PCBs and want to have an easy project to start, this one is good.
If you use Arduino Uno or any other big board with female pin headers you can see that it has a gap between pins 7 and 8. You can either duplicate this gap in your PCB design, thus making the resulting board incompatible with a breadboard, or use different pins for Rc and Rd resistors – this is why the sketch above has the option of switching from pins 9/10 to 3/4. Note that using pins 3 and 4 (and 5 for that matter) generates rather huge ‘stray capacitance’ for some reason. It seems that adjustment still works and the results are still good, but I didn’t test this setup a lot.
Ok, here are the board layouts for a simpler one-Rc design and the final two-Rc-and-switches one. The smaller is 15x10mm, the larger 23x10mm. To produce a simple home-made PCB you’ll need:
- one-sided copper clad board;
- a soldering iron;
- a small drill – I use a cheap 5V motor with small drill chuck;
- a 0,8mm paint marker like Edding 780;
- SMD resistors and male pin headers;
- 3% hydrogen peroxide from a drug store, citric acid from your kitchen, salt.
Cut the board to the size you need, clean it thoroughly (sandpaper and dishwashing liquid), mark and drill the holes. Draw the circuit with the paint marker. Pour some hydrogen peroxide into an appropriate-sized glass or plastic container (I used a shot glass), add citric acid (for this size half a teaspoon) and a pinch of salt. Stir thoroughly. Put the board in the resulting solution and wait half an hour, removing the emerging bubbles with a brush or a feather periodically. Once the disposed copper melts away, get the board out, remove the paint with white spirit and dry it. Check all the connections with a multimeter, if some traces are shorted that shouldn’t be – find the problem and remove it with a scalpel. Apply tin coating, place and solder everything. Note that for a bigger board you’ll have to connect two holes with a wire on the back (blue on schematics).
The pads for a capacitor can be just coated with more tin or you can place some holding contraption there. I didn’t find the perfect solution here, so it’s up for your experimentation.
The resulting board can be plugged into Arduino Uno directly or connected to a Nano on a breadboard. If your PCB is 10mm wide, you can plug it in a breadboard two ways to use either pins 3-4 or 9-10 for Rc (see pictures above).
Step 6: What’s More?
Hereby concludes this instructable. If you’re thinking of experimenting with the meter more, here is a couple of ideas. You may wish to make an inductance meter based on the same principle. You may wish to make a bare-minimum meter by removing resistors R1 and R2 and using an interrupt from a pin going from LOW to HIGH when the input voltage passes the threshold (around 2.41V supposedly). You may want to add a display to the board. Or you are dissatisfied with the precision and want to get rid of ‘stray capacitance’ by using a bare microcontroller, not an Arduino. In this latter case I’d suggest going for a faster one than Atmega, say, a Cortex M0 running at 48MHz, as it should provide more accurate results.
Comments, corrections and suggestions welcome!