← Articles

The voltage follower (op-amp buffer)

By Uma Kandan · May 2026

Why a unity-gain op-amp buffer is the simplest way to drive a low-impedance load from a high-impedance source.

You wire up a sensor, read the voltage with your Arduino, and the number is completely wrong. You double-check your wiring. Everything looks fine. What happened? Chances are, your circuit has an impedance mismatch problem — and the fix is one of the simplest, most useful circuits in all of electronics: the voltage follower, also called a buffer.

A voltage follower copies a voltage from one part of your circuit to another without stealing current from the source. It is the electronic equivalent of looking at a thermometer without touching the mercury — you get the reading without disturbing it.

1. The impedance problem — why you need a buffer

Imagine trying to fill a swimming pool using a garden hose. The hose delivers water just fine. Now imagine someone connects a fire-truck pump to the same garden hose to suck water out faster than the hose can supply it. The pressure drops to almost nothing. That is exactly what happens when a high-impedance source (like a sensor or a voltage divider) tries to drive a low-impedance load (like an Arduino ADC pin or a speaker).

Impedance is a measure of how much a component resists the flow of current. A source with high output impedance can only supply a tiny amount of current. If the load demands more current than the source can provide, the voltage sags — and your reading becomes inaccurate.

When do you need a buffer?

  • High-impedance sensors — piezoelectric pickups, pH probes, capacitive touch sensors
  • Voltage dividers — any resistive divider feeding an ADC, especially with resistors above 10 kΩ
  • Signal-conditioning chains — between filter stages where loading would change the filter response
  • Reference voltages — sharing one reference across multiple loads without sagging
  • Audio circuits — between a guitar pickup and an amplifier input

2. How a voltage follower works

A voltage follower is an op-amp (operational amplifier) wired in the simplest possible configuration: the output is connected directly back to the inverting (−) input, and the signal you want to copy goes into the non-inverting (+) input.

Here is the key insight: the op-amp will do whatever it takes to make its two inputs equal. Since the output is wired to the − input, the op-amp drives its output to match the + input. The result? Vout = Vin. The output voltage is an exact copy of the input voltage.

Why not just connect a wire?

A wire copies the voltage too, but it also connects the source directly to the load. The load’s current demand flows back through the source, pulling the voltage down. The op-amp buffer isolates the source from the load. It has:

  • Very high input impedance (10 MΩ to 1 TΩ) — draws almost zero current from the source
  • Very low output impedance (typically <1 Ω) — can supply current to the load without voltage drop
  • Unity gain — output equals input (gain = 1)

The math (simple version)

For a non-inverting amplifier, the gain formula is:

Gain=1+RfRi\text{Gain} = 1 + \frac{R_f}{R_i}

In a voltage follower, Rf = 0 (a direct wire) and Ri = ∞ (no resistor at all), so:

Gain=1+0=1Vout=Vin\text{Gain} = 1 + \frac{0}{\infty} = 1 \quad\Rightarrow\quad V_{\text{out}} = V_{\text{in}}

3. Choosing an op-amp for your buffer

Not all op-amps are created equal. The right choice depends on your supply voltage, signal frequency, and whether you need the output to reach 0 V (ground).

Op-ampSupplyRail-to-railInput typeBandwidthBest for
LM3583–32 VOutput only (to GND)Bipolar1 MHzGeneral purpose, DC signals, cheapest
TL072±6–18 VNoJFET3 MHzAudio, higher-impedance sources
MCP60021.8–6 VYes (in & out)CMOS1 MHz3.3 V / 5 V single-supply, battery
OPA23402.7–5.5 VYes (in & out)CMOS5.5 MHzPrecision ADC buffering, low noise
LM3243–32 VOutput only (to GND)Bipolar1 MHzQuad op-amp, multiple buffers in one chip
NE5532±5–15 VNoBipolar10 MHzAudio preamps, low-noise applications

JFET vs CMOS vs bipolar input

The op-amp’s input stage determines how much current it steals from your source:

  • Bipolar (LM358, NE5532) — input bias current around 20–200 nA. Fine for sources below 100 kΩ.
  • JFET (TL072) — input bias current around 20–200 pA. Good for sources up to 10 MΩ.
  • CMOS (MCP6002, OPA2340) — input bias current around 1 pA. Essential for extremely high-impedance sources like pH probes or piezo sensors.

4. Building a voltage follower on a breadboard

Let’s build a practical buffer using the LM358 — the most common and cheapest op-amp available. It comes in a DIP-8 package with two independent op-amps inside.

LM358 pinout

PinFunction
1OUT_A
2−IN_A (inverting input A)
3+IN_A (non-inverting input A)
4GND
5+IN_B
6−IN_B
7OUT_B
8VCC

Wiring (single buffer using op-amp A)

  • Voltage divider output → pin 3 (+IN_A)
  • Pin 1 (OUT_A) tied directly to pin 2 (−IN_A) — this is the feedback wire
  • Pin 1 (OUT_A) → Arduino A0
  • Pin 8 → +5 V, pin 4 → GND
  • 100 nF ceramic bypass capacitor between pin 8 and pin 4

5. Arduino code: buffered vs unbuffered reading

This sketch reads the same voltage divider through two paths — one direct (unbuffered) and one through the LM358 voltage follower — so you can see the difference on the Serial Monitor.

// Voltage follower (buffer) demo
// Compares buffered vs unbuffered ADC readings
//
// Wiring:
//   Voltage divider (2x 100k) output -> LM358 pin 3 (+IN)
//   LM358 pin 2 (-IN) tied to LM358 pin 1 (OUT)  [feedback]
//   LM358 pin 1 (OUT) -> Arduino A0  (buffered)
//   Voltage divider output -> Arduino A1  (unbuffered, direct)
//   LM358 pin 8 -> 5V,  pin 4 -> GND
//   100nF cap between pin 8 and pin 4

const int BUFFERED_PIN   = A0;  // Through voltage follower
const int UNBUFFERED_PIN = A1;  // Direct from divider

void setup() {
    Serial.begin(115200);
    Serial.println("Voltage Follower Buffer Demo");
    Serial.println("----------------------------");
    Serial.println("Pin\t\tRaw ADC\t\tVoltage");
}

void loop() {
    // Take multiple samples and average for stability
    long sumBuffered   = 0;
    long sumUnbuffered = 0;
    const int SAMPLES  = 16;

    for (int i = 0; i < SAMPLES; i++) {
        sumBuffered   += analogRead(BUFFERED_PIN);
        sumUnbuffered += analogRead(UNBUFFERED_PIN);
        delayMicroseconds(100);
    }

    int avgBuffered   = sumBuffered   / SAMPLES;
    int avgUnbuffered = sumUnbuffered / SAMPLES;

    float vBuffered   = avgBuffered   * (5.0 / 1023.0);
    float vUnbuffered = avgUnbuffered * (5.0 / 1023.0);

    Serial.print("Buffered:\t");
    Serial.print(avgBuffered);
    Serial.print("\t\t");
    Serial.print(vBuffered, 3);
    Serial.println(" V");

    Serial.print("Unbuffered:\t");
    Serial.print(avgUnbuffered);
    Serial.print("\t\t");
    Serial.print(vUnbuffered, 3);
    Serial.println(" V");

    Serial.print("Error:\t\t");
    float errorMv = (vBuffered - vUnbuffered) * 1000.0;
    Serial.print(errorMv, 1);
    Serial.println(" mV");
    Serial.println();

    delay(1000);  // Print once per second
}

With 100 kΩ divider resistors, you will typically see the unbuffered reading 50–150 mV lower than the buffered reading. With 1 MΩ resistors, the error can exceed 500 mV — a massive 10% error on a 5 V range.

6. Voltage follower variations

The basic unity-gain buffer is the starting point, but there are several practical variations you will encounter in real circuits.

A. Basic unity-gain buffer

The standard configuration we have been discussing. Output equals input, no gain, no attenuation. This is what you use 90% of the time.

V_out = V_in
Gain  = 1

B. Buffer with DC offset

Sometimes you need to shift a signal up or down. For example, a sensor outputs −1 V to +1 V but your ADC only accepts 0–3.3 V. Add a voltage divider to the non-inverting input to set a DC bias, then AC-couple the signal through a capacitor. The buffer isolates the bias network from the load.

C. Bootstrapped buffer (ultra-high impedance)

For sources with impedances above 100 MΩ (like glass pH electrodes), even a CMOS op-amp’s input leakage can cause errors. A bootstrapped guard ring on the PCB — driven by the buffer output — surrounds the input trace, keeping the voltage on both sides of the insulation equal. This eliminates surface leakage currents.

D. Dual-supply vs single-supply

FeatureSingle supply (0 V & +5 V)Dual supply (−12 V & +12 V)
Output swing~0 V to ~4 V (rail-to-rail: 0 to 4.9 V)−10.5 V to +10.5 V (typ.)
Can buffer signals near 0 V?Only with rail-to-rail op-ampYes, easily
Power supply complexitySimple — one regulatorNeeds positive + negative rails
Typical op-ampsLM358, MCP6002, OPA340TL072, NE5532, OPA2134
Common use caseMCU / sensor projectsAudio, analog signal processing

7. Real-world applications

Voltage followers are everywhere — hiding inside almost every electronic device you use. Here are some places where they do critical work.

8. ESP32 example: buffering a thermistor for accurate temperature

Thermistors are popular temperature sensors, but their resistance changes with temperature — meaning the voltage divider they form has a varying output impedance. Buffering the divider output gives you stable, accurate ADC readings on an ESP32.

// Buffered NTC thermistor temperature reading (ESP32)
// Uses LM358 voltage follower between divider and ADC
//
// Wiring:
//   3.3V -> 10k fixed resistor -> junction -> NTC thermistor -> GND
//   Junction point -> LM358 pin 3 (+IN)
//   LM358 pin 2 (-IN) -> LM358 pin 1 (OUT)  [feedback]
//   LM358 pin 1 (OUT) -> ESP32 GPIO 34 (ADC1_CH6)
//   LM358: Vcc = 3.3V, GND = GND
//   100nF bypass cap on LM358 Vcc-GND

const int THERM_PIN = 34;        // ADC input (buffered)
const float SERIES_R  = 10000.0; // 10k series resistor
const float NOMINAL_R = 10000.0; // NTC resistance at 25C
const float NOMINAL_T = 25.0;    // Reference temp (C)
const float B_COEFF   = 3950.0;  // Beta coefficient (datasheet)
const float V_REF     = 3.3;     // ESP32 ADC reference

void setup() {
    Serial.begin(115200);
    analogReadResolution(12);       // ESP32: 12-bit ADC (0-4095)
    analogSetAttenuation(ADC_11db); // Full 0-3.3V range
    Serial.println("Buffered Thermistor Demo");
}

void loop() {
    // Average 32 samples for noise reduction
    long sum = 0;
    for (int i = 0; i < 32; i++) {
        sum += analogRead(THERM_PIN);
        delayMicroseconds(50);
    }
    float adcAvg = sum / 32.0;

    // Convert ADC to resistance using voltage divider formula
    float voltage = adcAvg * (V_REF / 4095.0);
    float thermR  = SERIES_R * (voltage / (V_REF - voltage));

    // Steinhart-Hart simplified (Beta equation)
    float tempK = 1.0 / (
        (1.0 / (NOMINAL_T + 273.15)) +
        (1.0 / B_COEFF) * log(thermR / NOMINAL_R)
    );
    float tempC = tempK - 273.15;
    float tempF = tempC * 9.0 / 5.0 + 32.0;

    Serial.print("ADC: ");
    Serial.print((int)adcAvg);
    Serial.print("  R: ");
    Serial.print(thermR, 0);
    Serial.print(" ohm  Temp: ");
    Serial.print(tempC, 1);
    Serial.print(" C / ");
    Serial.print(tempF, 1);
    Serial.println(" F");

    delay(1000);
}

9. Common mistakes & troubleshooting

10. When NOT to use a voltage follower

Buffers are incredibly useful, but they are not always the right answer.

  • When you need gain — a voltage follower has a gain of exactly 1. If your signal is too small, use a non-inverting amplifier instead (same circuit, but add two resistors to set gain > 1).
  • When speed matters and impedance is already low — the op-amp introduces a small delay (propagation delay) and bandwidth limit. If your source already has low impedance, the buffer adds complexity for no benefit.
  • Very high frequency signals (>1 MHz) — standard op-amps struggle above a few MHz. For RF or video signals, use a dedicated buffer IC (like the BUF634) or a discrete transistor emitter follower.
  • When you need to drive heavy loads (>20 mA) — most op-amps max out at 20–40 mA output current. For driving motors, LEDs, or speakers, use the buffer to feed a power transistor or driver IC.

11. Quick reference: transistor-based buffers

Before op-amps became cheap, engineers used discrete transistors as buffers. You may still encounter these in legacy designs or high-speed applications.

Buffer typeGainInput ZOutput ZNotes
Op-amp follower1.00010 M–1 TΩ<1 ΩMost accurate, easiest to use
BJT emitter follower~0.99~β × RE~10–50 ΩFast, introduces ~0.6 V drop (VBE)
MOSFET source follower~0.8–0.95>10 GΩ~50–200 ΩVery high input Z, gain less than 1
Darlington pair~0.982 × RE~5–20 ΩVery high current gain, ~1.2 V drop

For most maker projects, the op-amp voltage follower is the best choice. It has unity gain with no voltage offset, extremely high input impedance, and costs under a dollar in DIP-8 form.

  • A voltage follower copies a voltage without loading the source — it has very high input impedance and very low output impedance.
  • Use it whenever a high-impedance source (sensor, voltage divider, piezo) feeds a low-impedance load (ADC, cable, next stage).
  • For single-supply Arduino/ESP32 projects, use the LM358 or MCP6002 (rail-to-rail).
  • For audio circuits with dual supply, use the TL072 or NE5532.
  • Always add a 100 nF bypass capacitor on the supply pins.
  • Do not leave unused op-amp channels floating — wire them as followers tied to a mid-rail voltage.
  • The voltage follower is the foundation for more complex circuits: active filters, instrumentation amps, and sample-and-hold stages all rely on buffer stages internally.