← All projects

Capacitance Meters (Dual Platform)

Oct–Nov 2025 · Solo, ELEC 291 Module 4 · Coursework

EFM8LB1STM32555 TimerC
Capacitance meter breadboard reading 10 nF on the LCD

Two capacitance meters built on different microcontroller families: an EFM8 and an STM32. The principle is the same on both: a 555-timer astable oscillates at a frequency that depends on the capacitor under test, the MCU counts pulses on a hardware timer input, and software reverses the 555 frequency formula to recover capacitance.

As an extension I also designed a 555 equivalent from discrete blocks (two LM393 comparators with the standard 1/3 V_CC and 2/3 V_CC voltage dividers, an SR latch built from NAND gates, and a 2N3904 transistor for the discharge path), and ran the same firmware against it to compare against the IC. Operating range: 1 nF to 1 µF.

Specs

MCUs
EFM8LB12F64 (8051 family) and STM32 (ARM Cortex)
EFM8 system clock
72 MHz internal oscillator
Astable target
f = 1.44 / ((R_A + 2·R_B)·C) with R_A = R_B = 10 kΩ
Range
1 nF – 1 µF (rejected outside this band)
Frequency capture
Timer 0 input on P0.0 (EFM8); pulse counting in software
Stability filter
Δf < 5 Hz across 3 consecutive samples = stable; > 5 % rel. change = noisy
LCD modes
4 modes: instantaneous / min-max / running average / angular freq
Discrete 555
2× LM393 comparators, NAND-gate SR latch, 2N3904 discharge

Discrete 555 equivalent

The 555 internally is a pair of comparators whose thresholds are set by a 5 kΩ / 5 kΩ / 5 kΩ divider (giving 1/3 V_CC and 2/3 V_CC), an SR flip-flop, and a transistor that pulls the timing capacitor to ground when the latch is in the discharge state. I rebuilt that from parts in the kit: two channels of an LM393 dual comparator (open-collector, needed pull-ups), an SR latch from NAND gates, and a 2N3904 driven from the latch's Q output. Base resistor sized for β = 50 worst-case at 50 mA collector current.

Once the discrete circuit was oscillating at 2.88 kHz with R_A = R_B = 4.7 kΩ and C = 0.1 µF (matching the textbook 555 formula), I drew the schematic and the comparator-input / Q-output waveforms. The discrete version runs noticeably noisier than the IC near the threshold crossings (the open-collector outputs ringing into the divider), but it tracks the formula well across the full capacitance range.

Firmware

The EFM8 firmware uses Timer 0 in counter mode with the input wired to P0.0. The 555's output drives that pin, so each oscillator cycle increments the timer; sampling the count over a fixed 1 s window gives frequency directly. Capacitance falls out of the rearranged formula C = 1.44 / ((R_A + 2·R_B)·f), with R_A = R_B = 10 kΩ baked in as a constant.

There's a small stability filter on top: a reading is considered stable when three consecutive samples differ by less than 5 Hz; relative changes greater than 5 % flip a 'noisy' flag for the LCD. The user can cycle through 4 display modes with a button on P2.1: instantaneous reading, observed min/max, running average over the session, and the equivalent angular frequency.

Porting to the STM32 was mostly a matter of swapping the timer / GPIO peripheral configuration; the math and the user interface ported directly. The STM32 build feels snappier mostly because the LCD redraws are fast enough to make the readings look continuous.

#define SYSCLK 72000000L
#define BAUDRATE 115200L

// Resistor values used in 555 circuit
#define R_A 10000.0   // 10k
#define R_B 10000.0   // 10k
#define K_555 (1.44 / (R_A + 2.0 * R_B))

// Valid capacitance range
#define C_MIN 1e-9f   // 1 nF
#define C_MAX 1e-6f   // 1 uF

// Stability / signal quality
#define STABLE_DELTA_HZ 5      // Hz threshold for stable reading
#define STABLE_SAMPLES 3       // consecutive stable samples needed
#define NOISY_REL_THRESH 0.05f // 5% relative change considered noisy
Constants from the EFM8 firmware: RC values, range, and the stability thresholds