In this tutorial, I’ll show you how to build three different capacitance meters using an Arduino. After finishing this project, you’ll be able to use your Arduino to measure the capacitance values of your capacitors.

With the many different ways capacitors are labeled, determining capacitor values can be challenging. This project will help, especially if you don’t have a digital multi-meter. It doesn’t take much time to measure the values of all of your capacitors and label them for future reference.

When I was testing the capacitance meters described in this post, I couldn’t find one that is able to accurately measure the full range of commonly used capacitors. One Arduino capacitance meter would accurately measure capacitors with values in the 1000 μF range, but it would fail with values in the nF and pF range. A capacitance meter that accurately measured values in the nF and pF ranges failed in the μF range. So, I will show you three different Arduino capacitance meters that together will cover the range of most commonly used capacitors, from about 10 pF to over 3900 μF.

In case you are interested, I tested the outputs of the three capacitance meters (described below) against capacitors of known values to compare the error in their measurements. Here are the results:

Capacitance Meter Comparison

The graph above shows the range of values each capacitance meter is able to measure accurately. Since no single meter measures capacitance across the full range of common capacitors, I will explain how to set up and operate each one.

But first a little background information on how the Arduino is able to measure capacitance…

Arduino Capacitance Measurement

Capacitance is a measure of the ability of something to store electrical charge. Each Arduino capacitance meter relies on the same basic property of capacitors- the time constant. The time constant of a capacitor is defined as the time it takes for the voltage across the capacitor to reach 63.2% of its voltage when fully charged. Larger capacitors take longer to charge, and therefore have larger time constants. An Arduino can measure capacitance because the time a capacitor takes to charge is directly related to its capacitance by the equation:

TC = R x C

TC is the time constant of the capacitor (in seconds).

R is the resistance of the circuit (in Ohms).

C is the capacitance of the capacitor (in Farads).

Relationship between voltage and time on a charging capacitor

Rearranging the equation above gives:

C = TC / R

The Arduino measures the capacitance of the unknown capacitor by recording the time it takes for the capacitor to reach 63.2% of its voltage when fully charged, then dividing that value by the known resistance of the circuit.

Now we should be ready to set up the capacitance meters and start measuring some capacitors. The following are three capacitance meters, each ideal for a certain range of capacitance values.

Capacitance Meter for 1 μF to 3900 μF Capacitors

Arduino Capacitance Meter with LCD Output

This capacitance meter is from the Arduino.cc website. After testing this meter I found that it can measure values from about 0.1 μF to 3900 μF (I didn’t test it above 3900 μF) with reasonable accuracy.

The Circuit

Follow this diagram to set up this capacitance meter:

Arduino capacitance meter circuit diagram

R1 = 10K Ohms

R2 = 220 Ohms

The Code

To display the readings with the Arduino serial monitor, connect the Arduino to your PC, open the Arduino IDE, and upload this code to it:

#define analogPin      0          
#define chargePin      13         
#define dischargePin   11        
#define resistorValue  10000.0F   

unsigned long startTime;
unsigned long elapsedTime;
float microFarads;                
float nanoFarads;

void setup(){
  pinMode(chargePin, OUTPUT);     
  digitalWrite(chargePin, LOW);  
  Serial.begin(9600);             
}

void loop(){
  digitalWrite(chargePin, HIGH);  
  startTime = millis();
  while(analogRead(analogPin) < 648){       
  }

  elapsedTime= millis() - startTime;
  microFarads = ((float)elapsedTime / resistorValue) * 1000;   
  Serial.print(elapsedTime);       
  Serial.print(" mS    ");         

  if (microFarads > 1){
    Serial.print((long)microFarads);       
    Serial.println(" microFarads");         
  }

  else{
    nanoFarads = microFarads * 1000.0;      
    Serial.print((long)nanoFarads);         
    Serial.println(" nanoFarads");          
    delay(500); 
  }

  digitalWrite(chargePin, LOW);            
  pinMode(dischargePin, OUTPUT);            
  digitalWrite(dischargePin, LOW);          
  while(analogRead(analogPin) > 0){         
  }

  pinMode(dischargePin, INPUT);            
} 

To use this meter with an LCD screen, connect the LCD to your Arduino (see How to Set Up an LCD Display on an Arduino if you need instructions). Pin 11 is already connected the LCD, so wire the capacitance meter using pin 8 instead of pin 11. Here’s the code:

#define analogPin      0          
#define chargePin      13         
#define dischargePin   8        
#define resistorValue  10000.0F  
#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

unsigned long startTime;
unsigned long elapsedTime;
float microFarads;                
float nanoFarads;

void setup(){
  pinMode(chargePin, OUTPUT);     
  digitalWrite(chargePin, LOW); 
  lcd.begin(16, 2); 
}

void loop(){
  digitalWrite(chargePin, HIGH);  
  startTime = millis();
  while(analogRead(analogPin) < 648){       
  }

  elapsedTime= millis() - startTime;
  microFarads = ((float)elapsedTime / resistorValue) * 1000;   
  lcd.print(elapsedTime);       
  lcd.print(" mS");
  delay(2000);  
  lcd.clear();
  delay(500);

  if (microFarads > 1){
    lcd.print(microFarads);       
    lcd.print(" uF");   
    delay(2000);    
  }

  else{
    nanoFarads = microFarads * 1000.0;      
    lcd.print(nanoFarads);         
    lcd.print(" nF");          
    delay(2000); 
  }

  lcd.clear();
  digitalWrite(chargePin, LOW);            
  pinMode(dischargePin, OUTPUT);            
  digitalWrite(dischargePin, LOW);          
  while(analogRead(analogPin) > 0){         
  }

  pinMode(dischargePin, INPUT);      
}

Measurement

Now we’re ready to start measuring some capacitors. Insert an unknown capacitor into the breadboard as shown in the diagram above. Then open the serial monitor on your computer. This is the output I got from measuring a 470 μF electrolytic capacitor:

Arduino Capacitance Meter Serial Monitor

In the first column are the times it took for the capacitor to charge to 63.2% total voltage. The second column is the capacitance measurement. The units will change automatically from microFarads to nanoFarads. If you are using an LCD to output the readings, the display will alternate between the charge time reading and the capacitance reading.

After you test different values of resistors, you will notice that it takes longer for the Arduino to output a value with larger value resistors. This is because larger capacitors take longer to reach the 63.2% voltage at which the Arduino takes its measurement. The 3900 μF capacitor I tested took several minutes between readings.

Capacitance Meter for 180 μF to 0.0047 μF Capacitors

High Accuracy Capacitance Meter with LCD Output

This is a “high accuracy” capacitance meter developed by Nick Gammon.

The Circuit

Follow the diagram below to build this capacitance meter:

High Accuracy Capacitance Meter Arduino Circuit

R1= 10K Ohm

R2= 3.1K Ohm

R3= 1.8K Ohm

The Code

To use this capacitance meter using the serial monitor for data output, connect the Arduino to your PC, open the Arduino IDE, and upload this code to the Arduino:

const byte pulsePin = 2;
const unsigned long resistance = 10000;

volatile boolean triggered;
volatile boolean active;
volatile unsigned long startTime;
volatile unsigned long duration;

ISR (ANALOG_COMP_vect)
  {
  unsigned long now = micros ();
  if (active)
    {
    duration = now - startTime;
    triggered = true;
    digitalWrite (pulsePin, LOW); 
    }
  }

void setup ()
  {
  pinMode(pulsePin, OUTPUT);
  digitalWrite(pulsePin, LOW);
  Serial.begin(9600);
  Serial.println("Started.");
  ADCSRB = 0;          
  ACSR =  _BV (ACI)     
        | _BV (ACIE)    
        | _BV (ACIS0) | _BV (ACIS1);  
   }  

void loop ()
  {
  if (!active)
    {
    active = true;
    triggered = false;
    digitalWrite (pulsePin, HIGH); 
    startTime = micros ();  
    }

  if (active && triggered)
    {
    active = false;
    Serial.print ("Capacitance = ");
    Serial.print (duration * 1000 / resistance);
    Serial.println (" nF");
    triggered = false;
    delay (3000);
    }
} 

To use this meter with an LCD output instead of the serial monitor, use the code below. Since the LCD uses pin 2, use pin 8 instead of pin 2 in the diagram above. Upload this code to the Arduino:

#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
const byte pulsePin = 8;
const unsigned long resistance = 10000;

volatile boolean triggered;
volatile boolean active;
volatile unsigned long startTime;
volatile unsigned long duration;

ISR (ANALOG_COMP_vect)
  {
  unsigned long now = micros ();
  if (active)
    {
    duration = now - startTime;
    triggered = true;
    digitalWrite (pulsePin, LOW); 
    }
  }

void setup ()
  {
  pinMode(pulsePin, OUTPUT);
  digitalWrite(pulsePin, LOW);
  lcd.begin(16, 2);
  lcd.print("Starting");
  delay(1000);
  lcd.clear();
  ADCSRB = 0;          
  ACSR =  _BV (ACI)     
        | _BV (ACIE)    
        | _BV (ACIS0) | _BV (ACIS1);  
   }  

void loop ()
  {
  if (!active)
    {
    active = true;
    triggered = false;
    digitalWrite (pulsePin, HIGH); 
    startTime = micros ();  
    }

  if (active && triggered)
    {
    active = false;
    lcd.print("Capacitance = ");
    lcd.setCursor(0,1);
    lcd.print(duration * 1000 / resistance);
    lcd.print(" nF");
    triggered = false;
    delay (3000);
    lcd.clear();
    }
} 

Measurement

This is the reading I got from a 10 nF (0.01 μF) polyester film capacitor:

High Accuracy Capacitance Meter Serial Monitor

The value always reads in nF, even when reading capacitors in the μF range.

Capacitance Meter for 470 μF to 18 pF Capacitors

Two Pin Capacitance Meter with LCD Output

This capacitance meter had the greatest range of the three I tested. It also had the highest accuracy with smaller capacitors. It is also the simplest to make, needing only two pins from the Arduino.

The Circuit

Two Pin Capacitance Meter

Note: It is important to make sure that the positive lead of the capacitor under test is connected to the A2 pin of the Arduino.

The Code

This code will output the capacitance readings to the Arduino serial monitor:

const int OUT_PIN = A2;
const int IN_PIN = A0;
const float IN_STRAY_CAP_TO_GND = 24.48;
const float IN_CAP_TO_GND  = IN_STRAY_CAP_TO_GND;
const float R_PULLUP = 34.8;  
const int MAX_ADC_VALUE = 1023;

void setup()
{
  pinMode(OUT_PIN, OUTPUT);
  pinMode(IN_PIN, OUTPUT);
  Serial.begin(9600);
}

void loop()
{
    pinMode(IN_PIN, INPUT);
    digitalWrite(OUT_PIN, HIGH);
    int val = analogRead(IN_PIN);
    digitalWrite(OUT_PIN, LOW);

    if (val < 1000)
    {
      pinMode(IN_PIN, OUTPUT);

      float capacitance = (float)val * IN_CAP_TO_GND / (float)(MAX_ADC_VALUE - val);

      Serial.print(F("Capacitance Value = "));
      Serial.print(capacitance, 3);
      Serial.print(F(" pF ("));
      Serial.print(val);
      Serial.println(F(") "));
    }
    else
    {
      pinMode(IN_PIN, OUTPUT);
      delay(1);
      pinMode(OUT_PIN, INPUT_PULLUP);
      unsigned long u1 = micros();
      unsigned long t;
      int digVal;

      do
      {
        digVal = digitalRead(OUT_PIN);
        unsigned long u2 = micros();
        t = u2 > u1 ? u2 - u1 : u1 - u2;
      } while ((digVal < 1) && (t < 400000L));

      pinMode(OUT_PIN, INPUT);  
      val = analogRead(OUT_PIN);
      digitalWrite(IN_PIN, HIGH);
      int dischargeTime = (int)(t / 1000L) * 5;
      delay(dischargeTime);   
      pinMode(OUT_PIN, OUTPUT);  
      digitalWrite(OUT_PIN, LOW);
      digitalWrite(IN_PIN, LOW);

      float capacitance = -(float)t / R_PULLUP
                              / log(1.0 - (float)val / (float)MAX_ADC_VALUE);

      Serial.print(F("Capacitance Value = "));
      if (capacitance > 1000.0)
      {
        Serial.print(capacitance / 1000.0, 2);
        Serial.print(F(" uF"));
      }
      else
      {
        Serial.print(capacitance, 2);
        Serial.print(F(" nF"));
      }

      Serial.print(F(" ("));
      Serial.print(digVal == 1 ? F("Normal") : F("HighVal"));
      Serial.print(F(", t= "));
      Serial.print(t);
      Serial.print(F(" us, ADC= "));
      Serial.print(val);
      Serial.println(F(")"));
    }
    while (millis() % 1000 != 0)
      ;    
}

To output the values of this capacitance meter to an LCD display, use this code:

#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
const int OUT_PIN = A2;
const int IN_PIN = A0;
const float IN_STRAY_CAP_TO_GND = 24.48;
const float IN_CAP_TO_GND  = IN_STRAY_CAP_TO_GND;
const float R_PULLUP = 34.8;  
const int MAX_ADC_VALUE = 1023;

void setup()
{
  pinMode(OUT_PIN, OUTPUT);
  pinMode(IN_PIN, OUTPUT);
  lcd.begin(16, 2);
  }

void loop()
{
    pinMode(IN_PIN, INPUT);
    digitalWrite(OUT_PIN, HIGH);
    int val = analogRead(IN_PIN);
    digitalWrite(OUT_PIN, LOW);

    if (val < 1000)
    {
      pinMode(IN_PIN, OUTPUT);

      float capacitance = (float)val * IN_CAP_TO_GND / (float)(MAX_ADC_VALUE - 

val);

      lcd.setCursor(0,0);
      lcd.print(F("Capacitance = "));
      lcd.setCursor(0,1);
      lcd.print(capacitance, 3);
      lcd.print(F("pF "));
      lcd.print(val);
      lcd.print("mS");
    }
    
    else
    {
      pinMode(IN_PIN, OUTPUT);
      delay(1);
      pinMode(OUT_PIN, INPUT_PULLUP);
      unsigned long u1 = micros();
      unsigned long t;
      int digVal;

      do
      {
        digVal = digitalRead(OUT_PIN);
        unsigned long u2 = micros();
        t = u2 > u1 ? u2 - u1 : u1 - u2;
      } 
      
      while ((digVal < 1) && (t < 400000L));

      pinMode(OUT_PIN, INPUT);  
      val = analogRead(OUT_PIN);
      digitalWrite(IN_PIN, HIGH);
      int dischargeTime = (int)(t / 1000L) * 5;
      delay(dischargeTime);   
      pinMode(OUT_PIN, OUTPUT);  
      digitalWrite(OUT_PIN, LOW);
      digitalWrite(IN_PIN, LOW);

      float capacitance = -(float)t / R_PULLUP
                              / log(1.0 - (float)val / (float)MAX_ADC_VALUE);

      lcd.setCursor(0,0);
      lcd.print(F("Capacitance = "));
      if (capacitance > 1000.0)
      {
        lcd.setCursor(0,1);
        lcd.print(capacitance / 1000.0, 2);
        lcd.print(F("uF "));
        lcd.print(val);
        lcd.print("mS");
      }
        
      else
      {
        lcd.setCursor(0,1);
        lcd.print(capacitance, 2);
        lcd.print(F("nF "));
        lcd.print(val);
        lcd.print("mS");
      }
  }
    while (millis() % 1000 != 0);
}

Measurement

These are the readings I got from a 22 pF ceramic disc capacitor:

Two Pin Capacitance Meter Serial Monitor

The units will change automatically between pF, nF and μF. The values in parentheses are the charge times for each reading (in milliseconds).

Here’s a video of this tutorial, so you can watch me set up the capacitance meters and see the Arduino measure capacitance in real time:

That’s about all there is to it! I hope you found this project as useful as I did. Just let me know in the comments if you have any questions, or need help setting it up. Also, don’t forget to subscribe to keep updated on all of our future posts!

Need an easy-to-use way to design circuits and layout PCBs?