You can get an approximate measure of the capacitance with just 2 microcontroller pins, 1 resistor and 1 known capacitor. The circuit looks something like this:
C2 is the unknown capacitance you're trying to measure. C1 is a reference capacitor of known value, and about 50-1000 times the value of C2. R1 isn't too critical, 1k Ohm or so.
The idea is to charge C2 with a known voltage (5 or 3.3 V, whatever V+ is), and then transfer its charge (q = C*V) into C1. Each time we transfer the charge from C2 to C1, C1's voltage increases by a tiny amount proportional to C2. The number of times we have to transfer charge to make C1's voltage exceed some threshold (for us, the logical "1" threshold of pin A) is then inversely proportional to the value of C2.
The trick is to take advantage of the high-impedance state of the microcontroller pins. If we kept the bottom side of C1 grounded while charging C2, then we would also end up fully charging C1. Instead, we let the bottom side of C1 float by configuring pin B as high-impedance. Now, whatever the top side of C1 does, the bottom side does too, always keeping the same voltage across C1.
The measurement algorithm goes like this (in pseudo-C):
// Step 0: discharge C1 to prepare for a new measurement
PIN_A = 0;
PIN_B = 0;
delay(some_time); // long enough to discharge C1
bool under_threshold = true; // has the voltage across C1 exceeded the threshold?
int count = 0;
while (under_threshold)
{
// Step 1: Charge C2
PIN_B = Z; // Z means high-impedance
PIN_A = 1;
delay(some_time); // long enough to charge C2
// Step 2: Transfer charge from C2 to C1
PIN_A = Z;
PIN_B = 0;
delay(some_time); // long enough for C2 to discharge into C1
// Step 3: Check if the threshold is exceeded
if (PIN_A || (count > COUNT_MAX))
{
under_threshold = false;
}
}
return count;
You can see a demonstration of the circuit at https://www.circuitlab.com/circuit/uq2zs6/cap-sensing/