The EIA 3-digit code for a 1 nanofarad (1nF) capacitor is 102. This translates to 10 × 10² picofarads (1,000pF), which equals 1nF or 0.001µF. In embedded systems like the ESP32, this specific "102" ceramic disc or SMD capacitor is the go-to component for building high-frequency RC low-pass filters to smooth out ADC (Analog-to-Digital Converter) readings and eliminate high-frequency switching noise.

Project Difficulty: Intermediate | Time to Build: 20 Minutes | Cost: ~$8 USD

Why the 102 (1nF) Capacitor Code Matters in Embedded Design

When sourcing components from your bin or a distributor like Digi-Key, you will rarely see "1nF" printed on a small ceramic through-hole capacitor. Instead, manufacturers use the EIA (Electronic Industries Alliance) 3-digit coding system. Here is how the math works for the 102 code:

  • First digit (1): The first significant figure.
  • Second digit (0): The second significant figure.
  • Third digit (2): The multiplier (number of zeros to add), in picofarads (pF).

Calculation: 10 × 10² pF = 1,000 pF. Since 1,000 pF equals 1 nanofarad (1nF), the code 102 is your target. You may also see it marked as 102J (where J indicates a ±5% tolerance) or 1n0 on slightly larger SMD packages.

Why use a 1nF (102) capacitor specifically for an ESP32 ADC? The ESP32's internal SAR (Successive Approximation Register) ADC is notoriously noisy, often exhibiting a ±100mV fluctuation on raw reads due to internal switching and RF interference from the WiFi/Bluetooth radios. By pairing a 102 capacitor with a 10kΩ resistor, we create a hardware low-pass filter that physically blocks high-frequency noise before it reaches the GPIO pin.

The Physics of the Filter: The cutoff frequency ($f_c$) of an RC filter is calculated as $f_c = 1 / (2\pi RC)$. With R = 10,000Ω and C = 1 × 10⁻⁹ F, the cutoff frequency is roughly 15.9 kHz. This allows slow-moving sensor data (like a thermistor or potentiometer) to pass through while aggressively shunting 2.4GHz RF noise and high-frequency PWM ripple to ground.

Project Specs: ESP32 RC Low-Pass Filter Build

This build targets the ESP32 DevKit V1 (30-pin variant, ESP32-WROOM-32 module) running the Arduino core. We will use GPIO 34, which is an input-only pin hardwired to ADC1 Channel 6. Never use ADC2 pins (like GPIO 25 or 26) for analog readings if you plan to enable WiFi, as the ESP32's WiFi driver monopolizes ADC2.

Component Specification / Part Number Quantity
Microcontroller ESP32 DevKit V1 (30-pin, ESP32-WROOM-32) 1
Capacitor 1nF Ceramic Disc (Code: 102 or 102J), 50V 1
Resistor 10kΩ Carbon Film or Metal Film (1/4W) 1
Signal Source 10kΩ Potentiometer (for testing) or Analog Sensor 1
Prototyping Solderless Breadboard & Jumper Wires 1 set

Step-by-Step Wiring Procedure

Safety & Hardware Warning: The ESP32 ADC pins are strictly limited to 3.3V. Feeding 5V into GPIO 34 through the RC filter will permanently damage the silicon. Ensure your potentiometer or sensor signal is referenced to the ESP32's 3V3 pin, not the VIN/5V pin.
  1. Power the Breadboard: Connect the ESP32 3V3 pin to the red power rail and GND to the blue ground rail.
  2. Wire the Signal Source: Connect your potentiometer's outer legs to 3V3 and GND. The center wiper pin is your raw analog signal.
  3. Insert the Resistor: Plug one leg of the 10kΩ resistor into the same row as the potentiometer wiper. Plug the other leg into an empty row (this will be your "filtered" node).
  4. Insert the 102 Capacitor: Plug one leg of the 1nF (102) capacitor into the "filtered" node row alongside the resistor. Plug the other leg directly into the blue GND rail.
  5. Connect to the ESP32: Run a jumper wire from the "filtered" node (where the resistor and capacitor meet) to GPIO 34 on the ESP32.
  6. Verify Connections: Use a multimeter in continuity mode to verify the capacitor's ground leg has a direct path to the ESP32 GND pin. Read < 1 ohm to confirm.

Complete ESP32 Arduino Code with ADC Calibration

The ESP32's raw ADC readings are non-linear and vary from chip to chip due to internal reference voltage variations. The code below uses Espressif's esp_adc_cal library to characterize the ADC and convert raw readings into accurate millivolts, combined with software oversampling to complement our hardware 102 capacitor filter.

#include <Arduino.h>
#include <esp_adc_cal.h>

// --- PIN DEFINITIONS ---
#define ADC_PIN 34
#define ADC_CHANNEL ADC1_CHANNEL_6 // GPIO 34 maps to ADC1 Channel 6
#define ADC_ATTEN ADC_ATTEN_DB_11  // 0-3.3V range
#define ADC_WIDTH ADC_WIDTH_BIT_12 // 12-bit resolution (0-4095)
#define NUM_SAMPLES 64             // Software oversampling factor

esp_adc_cal_characteristics_t adc_chars;
const uint32_t DEFAULT_VREF = 1100; // Default eFuse Vref in mV (if calibration fails)

void setup() {
    Serial.begin(115200);
    delay(1000); // Allow serial monitor to connect

    // Configure ADC1 width and channel attenuation
    adc1_config_width(ADC_WIDTH);
    adc1_config_channel_atten(ADC_CHANNEL, ADC_ATTEN);

    // Characterize ADC using eFuse values for accuracy
    esp_adc_cal_value_t val_type = esp_adc_cal_characterize(
        ADC_UNIT_1, ADC_ATTEN, ADC_WIDTH, DEFAULT_VREF, &adc_chars);

    if (val_type == ESP_ADC_CAL_VAL_EFUSE_TP) {
        Serial.println("ADC Characterized using Two Point Value (Most Accurate)");
    } else if (val_type == ESP_ADC_CAL_VAL_EFUSE_VREF) {
        Serial.println("ADC Characterized using eFuse Vref");
    } else {
        Serial.println("ADC Characterized using Default Vref (Least Accurate)");
    }
}

void loop() {
    uint32_t adc_reading = 0;
    
    // Oversampling: Read 64 times and average to reduce remaining thermal noise
    for (int i = 0; i < NUM_SAMPLES; i++) {
        int raw = adc1_get_raw(ADC_CHANNEL);
        if (raw < 0) {
            Serial.println("Error: ADC read returned negative value. Check GPIO mapping.");
            return;
        }
        adc_reading += raw;
    }
    adc_reading /= NUM_SAMPLES;

    // Convert calibrated raw value to actual voltage in millivolts
    uint32_t voltage = esp_adc_cal_raw_to_voltage(adc_reading, &adc_chars);

    Serial.printf("Smoothed Raw: %4u | Calibrated Voltage: %4u mV\n", adc_reading, voltage);
    
    delay(250); // 4 Hz update rate
}

Debugging: Resolving ADC Assertion Failures

When compiling or running ADC code on the ESP32, you may encounter a specific, frustrating runtime panic. If your serial monitor outputs the following exact error string:

Exact Error String:
assert failed: adc1_config_width adc_common.c:110 (bits <= ADC_WIDTH_BIT_12 && bits >= ADC_WIDTH_BIT_9)

This is a version-mismatch assertion failure between your code and the underlying ESP-IDF framework. Here are the first three things to check when it fails:

  1. Check your Arduino Core Version: In ESP32 Arduino Core v2.0.0 and later, Espressif updated the ADC enums. If you are using an older codebase, change ADC_WIDTH_BIT_12 to ADC_BITWIDTH_12. Conversely, if you are on an older core (v1.0.x), ensure you are using ADC_WIDTH_BIT_12.
  2. Verify ADC1 vs ADC2 Mapping: Ensure your #define ADC_PIN is strictly an ADC1 pin (GPIO 32, 33, 34, 35, 36, 39). If you accidentally pass an ADC2 pin configuration macro into an ADC1 initialization function, the underlying C driver will panic and throw this assertion.
  3. Measure the Physical Node Voltage: If the code compiles but reads a hard 0 or 4095, use your multimeter to probe the junction between the 10kΩ resistor and the 102 capacitor. If it reads 0V, your capacitor is likely shorted (a common failure mode for cheap ceramic discs if subjected to >50V) or your breadboard contact is dead.

Extending and Simplifying the Build

How to Extend (Broadband Filtering): A single 1nF (102) capacitor is excellent for high-frequency RF noise, but it won't filter out low-frequency 50/60Hz mains hum. To create a broadband filter, add a 100nF (104 code) capacitor in parallel with the 102 capacitor. The 100nF handles mid-band noise, while the 1nF handles the extreme high frequencies, creating a much cleaner DC rail for the ADC.

How to Simplify (Pure Software): If your sensor outputs a strictly slow-moving DC signal (like a soil moisture sensor read once per minute) and you lack a 102 capacitor, you can remove the hardware RC filter entirely. Increase the NUM_SAMPLES in the code from 64 to 1024. The ESP32's CPU can easily handle the math, though you will sacrifice a few milliseconds of read time and increase power consumption slightly during the read burst.

FAQ: 1 Nanofarad Capacitor Code Questions

Is a 102 capacitor always exactly 1 nanofarad?

Yes, the base value is always 1,000pF (1nF). However, the actual physical capacitance will vary based on the tolerance letter printed next to the 102 code. A 102J is guaranteed to be within ±5% (950pF to 1050pF), while a 102K is ±10%, and a 102M is ±20%. For ESP32 ADC filtering, a 20% variance is entirely acceptable, as the exact cutoff frequency of the RC filter is rarely critical for basic noise suppression.

Can I use a 1nF (102) capacitor for I2C pull-up on an ESP32?

No. I2C buses require resistors (typically 4.7kΩ) to pull the SDA and SCL lines high to 3.3V. Adding a 1nF capacitor from the I2C lines to ground will create an RC delay with your pull-up resistors, rounding off the square-wave edges of the I2C clock signal. At 400kHz (Fast Mode), a 1nF capacitor will cause severe signal degradation and result in I2C bus lockups or NACK errors.

What is the difference between a 102 and 103 capacitor code?

The third digit represents the multiplier (number of zeros). A 102 code is 10 × 10² = 1,000pF (1nF). A 103 code is 10 × 10³ = 10,000pF (10nF or 0.01µF). If you accidentally use a 103 capacitor in the ADC filter build above, your cutoff frequency will drop from 15.9 kHz to 1.59 kHz, which will start to filter out and distort faster-moving analog signals, like audio waveforms or rapid PID feedback loops.

Why does my ESP32 ADC still show noise even with a 102 capacitor?

If you still see ±20mV of jitter after installing the 102 capacitor and 10kΩ resistor, the noise is likely being introduced after the filter, or it's low-frequency thermal noise. First, ensure your jumper wire from the filter node to GPIO 34 is as short as possible; long wires act as antennas for the ESP32's own 2.4GHz RF emissions. Second, implement the software oversampling loop provided in the code block above to average out the remaining Gaussian noise.