Because the capacitance to be measured is well below 1 nF (50-100 pF), you'll encounter serious problems trying to measure it with the ADC of the Arduino due to its input capacitance (14 pF according to datasheet). Add the stray capacitances of wires, headers and the Arduino board itself and you'll easily end up with 25 pF input capacitance, which is in the same order of magnitude of what you're trying to measure (= A VERY BAD THING).
What to do, then? Well, the main options are these...
Use an external measurement circuit
This would mean including active devices (op amps, comparator, timers...) and precision passive components. A true HW-based solution.
The accuracy of the measurement in this case would be entirely up to the design (circuit topology and component selection) of the external circuit. The circuit would provide either an analog voltage or a signal whose frequency could be measured by the Arduino without introducing any additional significant errors.
An example using a 555 timer (an additional 4 pF compensation capacitor is needed between OUT and TH for improved accuracy):
Source: Use Analog Techniques To Measure Capacitance In Capacitive Sensors, an article by Martin Tomasz published in Electronic Design.
Think of the external circuit as a "sensor" or as a signal conditioning circuit for a "sensor" (the capacitance to be measured). In fact, the dynamic capacitance you're trying to measure probably comes from a sensor (moisture, humidity?), isn't it?
Connect the capacitor directly to analog pins of Uno and calibrate the readings
It may sound amazing, but something as simple as this works (at the expense of accuracy, of course):
How's that? Because the input capacitance problem that we detected at the beginning is big enough to seriously impair accuracy, but doesn't make the measurement completely unfeasible. Thus, we can calibrate that effect out and still have a valid (although with reduced accuracy) measument in the target range (50-100 pF).
The calibration is done through some hardcoded default values in the following Arduino sketch (source here from braulio777). For better accuracy you should calibrate the values of
R_PULLUP in the sketch by comparing measurements of some capacitors with their already known capacitance values (provided you can do this).
//Digital Capacitance Meter
//Measuring from 0.000pF to 1000uF
LiquidCrystal lcd(11, 9, 5, 4, 3, 2);
const int OUT_PIN = A4;
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;
int val = analogRead(IN_PIN);
if (val < 1000)
float capacitance = (float)val * IN_CAP_TO_GND / (float)(MAX_ADC_VALUE - val);
lcd.print("Capacitance = ");
lcd.print(capacitance, 3);// for the best precision
unsigned long u1 = micros();
unsigned long t;
digVal = digitalRead(OUT_PIN);
unsigned long u2 = micros();
t = u2 > u1 ? u2 - u1 : u1 - u2;
while ((digVal < 1) && (t < 400000L));
val = analogRead(OUT_PIN);
int dischargeTime = (int)(t / 1000L) * 5;
float capacitance = -(float)t / R_PULLUP
/ log(1.0 - (float)val / (float)MAX_ADC_VALUE);
lcd.print("Capacitance = ");
if (capacitance > 1000.0)
lcd.print(capacitance / 1000.0, 2);
while (millis() % 1000 != 0);
The example code above outputs measured values to an LCD display. For your intended application, the best option probably is to write data to an external SD card.
Disclosure: I have not tested the code above myself.