The 3-digit code for a 0.1µF (100nF) capacitor is 104. The first two digits ("10") represent the significant figures, and the third digit ("4") is the multiplier ($10^4$ picofarads), equaling 100,000 pF or 0.1µF. If you are breadboarding an ESP32 and experiencing random resets, missing this exact component is your prime suspect. Below, we decode the capacitor marking system, diagnose the exact brownout errors caused by poor decoupling, and build a bench tool to verify your power rail integrity.
Decoding the 104: Capacitor Codes and Dielectric Selection
Ceramic capacitors use a standardized 3-digit EIA code because they are too small to print full microfarad values. While 104 is the universal standard for logic-level decoupling, not all "104" capacitors are built the same. The dielectric material dictates how the capacitance drops under DC bias and temperature shifts.
| Code | Picofarads (pF) | Nanofarads (nF) | Microfarads (µF) | Primary Use Case |
|---|---|---|---|---|
| 103 | 10,000 | 10 | 0.01 | High-frequency RF bypass |
| 104 | 100,000 | 100 | 0.1 | Standard IC logic decoupling |
| 224 | 220,000 | 220 | 0.22 | Secondary bulk bypass |
| 474 | 470,000 | 470 | 0.47 | Low-frequency filtering |
Dielectric Decision Path
When ordering 104 capacitors, you must select the correct dielectric. Use this decision tree to terminate on the exact part you need:
- IF you are decoupling a digital logic rail (ESP32, Arduino, 555 timer) AND ambient temperature stays between -20°C and +85°C → Pick X7R.
- IF you are building a precision analog filter or audio DAC output where microphonics and voltage coefficient will distort the signal → Pick C0G/NP0.
- IF you see Y5V or Z5U on the datasheet → Reject immediately. These lose up to 80% of their capacitance at room temperature under DC bias.
The "Brownout detector was triggered" Error: Ranked Causes
When an ESP32 reboots unexpectedly, the serial monitor frequently spits out this exact fatal error string:
Brownout detector was triggered
This is not a software bug. The ESP32's internal brownout detection (BOD) circuit monitors the 3.3V rail. If the voltage dips below ~2.4V for even a few microseconds, the BOD triggers a hardware reset to prevent flash memory corruption. Here are the ranked hardware causes:
- Missing or misplaced 0.1µF (104) decoupling capacitor. The ESP32 Wi-Fi PA (Power Amplifier) draws current spikes exceeding 500mA during TX bursts. Without a 104 capacitor placed within 2mm of the VCC/GND pins, the parasitic inductance of breadboard wires causes a massive voltage droop ($V = L \frac{di}{dt}$).
- Undersized USB cable. Cheap promotional USB cables use 28AWG or thinner power wires, dropping 1V+ across the cable when the ESP32 pulls 300mA.
- Onboard LDO thermal throttling. The AMS1117-3.3 LDO on cheap DevKit clones has a high dropout voltage and poor transient response, failing to recover from fast current spikes.
The First Three Things to Check When It Fails
- Probe the 3V3 pin with an oscilloscope during Wi-Fi initialization. Set the trigger to a falling edge at 2.8V. If you see a droop >300mV, your decoupling is inadequate.
- Verify physical placement. Ensure the 104 capacitor is physically bridging the 3V3 and GND pins on the exact same breadboard rows as the ESP32 module. A capacitor placed 5 rows away adds enough parasitic inductance to render it useless at RF frequencies.
- Swap the USB cable for a known-good, short (under 1 meter), 20AWG or 22AWG data cable.
Project Build: ESP32 Power Rail Noise Debugger
To catch microsecond voltage droops without a $1,000 oscilloscope, we will build a dedicated Power Rail Integrity Monitor. This tool uses an Arduino Nano to sample the ESP32's 3.3V rail via a voltage divider, calculating peak-to-peak noise and triggering an alert if the decoupling fails.
Difficulty Rating: ⭐⭐☆☆☆ (Beginner/Intermediate)
Time to Build: 20 minutes
Parts List
- 1x Arduino Nano v3 (ATmega328P, 5V logic) - Acts as the monitor
- 1x ESP32 DevKit v1 (Target board under test)
- 2x 10kΩ 1/4W Metal Film Resistors (For 2:1 voltage divider)
- 1x 0.1µF (Code 104) X7R Ceramic Capacitor (To test with/without)
- 1x 5mm Red LED with 220Ω current limiting resistor
- Breadboard and 22AWG solid core jumper wires
Pin Mapping Table
| Arduino Nano Pin | Connected To | Function |
|---|---|---|
| 5V | Voltage Divider Top (R1) | Reference / Power |
| GND | ESP32 GND & Divider Bottom | Common Ground |
| A0 | Voltage Divider Midpoint | Analog Rail Monitor |
| D13 | LED Anode (via 220Ω) | Brownout / Noise Alert |
Wiring and Calibration Steps
- Build the Voltage Divider: Connect the two 10kΩ resistors in series between the Arduino Nano's 5V and GND pins. The midpoint should output exactly 2.5V. Connect this midpoint to the Nano's A0 pin.
- Tap the Target Rail: Disconnect the 5V feed to the divider. Instead, wire the top of the divider to the ESP32's 3V3 pin. With the ESP32 powered on, the 2:1 divider will step the 3.3V rail down to ~1.65V, safely within the Nano's 5V ADC range.
- Wire the Alert LED: Connect the 220Ω resistor to D13, then to the LED anode. Connect the cathode to GND.
- Verify with a DMM: Power the ESP32 via USB. Use a multimeter to measure the voltage at the Nano's A0 pin. It should read between 1.60V and 1.68V. If it reads 0V, check your ESP33 power. If it reads 2.5V, you forgot to move the divider feed from the Nano 5V pin.
- Common Ground: Ensure the Arduino Nano GND and ESP32 GND are tied together on the same breadboard power rail. Without a shared ground, the ADC will float and trigger false brownout alerts.
Complete Power Rail Monitor Code
This code targets the Arduino Nano v3 (ATmega328P). It samples the ADC at roughly 9kHz, tracking the minimum and maximum voltage over a 50ms window. If the peak-to-peak delta exceeds a threshold (indicating a massive Wi-Fi TX droop due to a missing 104 cap), it latches the LED and prints the droop millivolts to the serial monitor.
/*
* Power Rail Integrity Monitor
* Target Board: Arduino Nano v3 (ATmega328P, 5V/16MHz)
* Purpose: Detect missing 0.1uF (104) decoupling capacitors on 3.3V rails
*/
#define PIN_ANALOG_IN A0
#define PIN_ALERT_LED 13
// Calibration constants for 10-bit ADC with 5V reference
// 5000mV / 1024 steps = 4.88mV per step
const float MV_PER_STEP = 4.88;
// Threshold for peak-to-peak noise (in ADC steps)
// 60 steps * 4.88mV = ~293mV droop (Indicates missing 104 cap)
const int NOISE_THRESHOLD_STEPS = 60;
// Error handling thresholds
const int ADC_SHORT_CIRCUIT_LIMIT = 15; // Near 0V
const int ADC_OPEN_CIRCUIT_LIMIT = 1008; // Near 5V (floating or short to 5V)
void setup() {
Serial.begin(115200);
pinMode(PIN_ALERT_LED, OUTPUT);
digitalWrite(PIN_ALERT_LED, LOW);
// Allow power rails to settle
delay(500);
Serial.println("Power Rail Integrity Monitor Initialized.");
Serial.println("Monitoring 3.3V rail via 2:1 divider...");
}
void loop() {
int minVal = 1023;
int maxVal = 0;
int currentVal = 0;
// Sample rapidly for ~50ms to catch Wi-Fi TX burst envelopes
// analogRead takes ~112us, 500 iterations = ~56ms
for (int i = 0; i < 500; i++) {
currentVal = analogRead(PIN_ANALOG_IN);
if (currentVal < minVal) minVal = currentVal;
if (currentVal > maxVal) maxVal = currentVal;
}
// Error Handling: Check for wiring faults
if (maxVal <= ADC_SHORT_CIRCUIT_LIMIT) {
Serial.println("ERROR: ADC reads near 0. Check for short to GND or unpowered target.");
blinkErrorPattern();
return;
}
if (minVal >= ADC_OPEN_CIRCUIT_LIMIT) {
Serial.println("ERROR: ADC reads near 1023. Check for floating A0 pin or short to 5V.");
blinkErrorPattern();
return;
}
int peakToPeak = maxVal - minVal;
float noiseMv = peakToPeak * MV_PER_STEP;
// Calculate nominal voltage (average of min and max)
float nominalV = ((minVal + maxVal) / 2.0) * MV_PER_STEP * 2.0; // *2 for divider
if (peakToPeak > NOISE_THRESHOLD_STEPS) {
digitalWrite(PIN_ALERT_LED, HIGH);
Serial.print("BROWNOUT RISK: Noise = ");
Serial.print(noiseMv, 1);
Serial.print("mV | Nominal: ");
Serial.print(nominalV, 2);
Serial.println("V (Missing 104 Cap?)");
} else {
digitalWrite(PIN_ALERT_LED, LOW);
// Uncomment below for verbose logging
// Serial.print("Stable. Noise: "); Serial.print(noiseMv, 1); Serial.println("mV");
}
delay(100); // Brief pause before next sample window
}
void blinkErrorPattern() {
for (int i = 0; i < 4; i++) {
digitalWrite(PIN_ALERT_LED, HIGH);
delay(150);
digitalWrite(PIN_ALERT_LED, LOW);
delay(150);
}
delay(2000); // Long pause on hard fault
}
Decision Tree: Extending or Simplifying the Build
Depending on your bench requirements, you may need to adapt this tool. Use this decision matrix to choose your next step:
| Condition / Goal | Action | Required Hardware |
|---|---|---|
| IF you need to capture nanosecond RF spikes from the ESP32 antenna matching network. | Abandon the Arduino ADC. The 9kHz sample rate cannot see 2.4GHz harmonics. Use a dedicated oscilloscope with a 50Ω RF probe. | Rigol DS1054Z + 500MHz Passive Probe |
| IF you want to log intermittent brownouts over a 24-hour soak test. | Add an SPI SD card module to the Nano and append timestamps to a CSV file when the threshold is crossed. | Adafruit MicroSD Breakout (150) |
| IF you just need a quick visual pass/fail for factory flashing jigs. | Keep the current build, but replace the serial output with an I2C OLED display to make it a standalone, PC-free tool. | SSD1306 128x64 I2C OLED |
Default Recommendation: For 95% of hobbyist and embedded engineering bench triage, stick to the base Arduino Nano + LED setup. It costs under $8, builds in 20 minutes, and instantly proves whether your breadboard parasitic inductance is killing your 3.3V rail.
Real-World Bench Failures and Edge Cases
Even when you place the correct 104 X7R capacitor, you can still encounter power integrity issues. Here are three non-obvious failure modes I have diagnosed on the bench:
1. The Piezoelectric "Singing" Capacitor
Ceramic capacitors with X7R and Y5V dielectrics exhibit piezoelectric properties. If your circuit has a periodic current draw in the audible range (e.g., a 2kHz PWM motor driver or a 1kHz switching regulator), the 104 capacitor will physically vibrate and emit a high-pitched whine. This is called microphonics. If this acoustic noise couples into a nearby analog microphone trace, it will ruin your audio SNR. Fix: Swap the X7R 104 for a C0G/NP0 104, or use a larger physical package size (1206) which lowers the resonant frequency out of the audible band.
2. Counterfeit Capacitance Values
Cheap bulk capacitor kits from unbranded marketplace vendors often contain mislabeled parts. A capacitor stamped "104" might actually measure 40nF due to severe manufacturing tolerances or counterfeit dielectrics. According to All About Circuits, always verify critical bypass caps with an LCR meter before soldering them into high-speed digital boards.
3. Via Inductance in PCB Layouts
When transitioning from breadboards to custom PCBs, placing the 104 capacitor on the opposite side of the board and routing it through vias adds roughly 1nH to 2nH of parasitic inductance per via. For an ESP32 drawing 500mA in 10 nanoseconds, that inductance generates a $V = L \frac{di}{dt}$ spike that defeats the purpose of the capacitor. The Espressif Hardware Design Guidelines explicitly mandate that decoupling capacitors be placed on the same layer as the IC, as close to the VCC/GND pads as physically possible, with wide, short traces.






