If you need to measure DC load current for a battery monitor or solar charge controller without disrupting the system ground, a high-side current sense amp circuit built around a differential op-amp topology is the default engineering choice. For a standard 12V, 5A load monitored by an ESP32, you will use a 0.05Ω 2W shunt resistor and a TLV2372 op-amp configured for a gain of 10. This yields a 0-2.5V analog output perfectly scaled for the ESP32’s 12-bit ADC.
While dedicated digital ICs exist, building the discrete analog amp circuit gives you infinite bandwidth, lower quiescent current, and a fundamental understanding of common-mode rejection. Below is the exact design, failure analysis, and breadboard protocol to get it working on the first try.
The Verdict: Why High-Side Over Low-Side?
When designing a current sense amp circuit, you must choose between placing the shunt resistor on the high side (between the power source and the load) or the low side (between the load and ground).
A low-side shunt is easier to interface with because the voltage across it is already referenced to system ground. However, it introduces a critical flaw: it lifts the load’s ground potential above the system ground by the shunt’s voltage drop. If your load is a microcontroller, a communication transceiver (like an RS-485 or CAN bus), or a sensor sharing a ground plane, this shifting ground reference will cause data corruption, ground loops, and erratic behavior.
A high-side topology keeps the load firmly tied to the system ground. The trade-off is that the op-amp must reject the high common-mode voltage (the full 12V battery voltage) while amplifying the tiny differential voltage (millivolts) across the shunt. This requires a precise resistor network and an op-amp with a common-mode input range that includes the positive rail.
Topology Breakdown and Node Labels
The standard high-side discrete amp circuit uses a differential amplifier configuration. It relies on four matched resistors to set the gain and reject the common-mode voltage.
Node Definitions
- NODE_VBAT: The positive supply rail (e.g., 12V from a LiFePO4 battery).
- NODE_SHUNT_HI: The connection point between the power source and the shunt resistor.
- NODE_SHUNT_LO: The connection point between the shunt resistor and the load.
- NODE_VOUT: The amplified analog signal routed to the microcontroller ADC.
The non-inverting input (+) of the op-amp is tied to NODE_SHUNT_LO through resistor R3. The inverting input (-) is tied to NODE_SHUNT_HI through resistor R1. Feedback resistor R2 connects the output to the inverting input, and R4 ties the non-inverting input to ground.
The output voltage is defined by the equation:
V_OUT = (V_SHUNT_HI - V_SHUNT_LO) * (R2 / R1)
Assuming R1 = R3 and R2 = R4, the common-mode voltage (the 12V baseline) is mathematically canceled out, leaving only the amplified voltage drop across the shunt. According to All About Circuits' guide on shunt sensing, even a 1% mismatch in these resistor pairs will degrade the Common-Mode Rejection Ratio (CMRR) drastically, causing the 12V baseline to bleed into your output. Always use 0.1% tolerance resistors for R1-R4 in precision applications.
Component Behavior and Extreme Failure Modes
Understanding how the amp circuit reacts to component drift and catastrophic faults is what separates a working prototype from a reliable product.
| Element Changed | Direction | Effect on Circuit Behavior |
|---|---|---|
| Shunt Resistor (R_shunt) | Increases (Heat drift) | Gain effectively increases; reads higher current than actual. Copper/constantan shunts minimize this. |
| Feedback Resistors (R2/R4) | Drift apart (>0.1%) | CMRR degrades. V_OUT gains a DC offset proportional to V_BAT, ruining zero-current calibration. |
| Op-Amp VDD | Drops below V_BAT | If V_BAT exceeds the op-amp's absolute maximum common-mode rating, input stage saturates or burns. |
| Load Impedance | Decreases (Heavy draw) | V_SHUNT_LO drops slightly. If op-amp isn't rail-to-rail output, V_OUT may clip before max current is reached. |
What Breaks at the Extremes?
Scenario A: The Shunt Opens (or a wire breaks)
If the connection between NODE_SHUNT_HI and NODE_SHUNT_LO breaks, the op-amp inputs now see the full battery voltage on one side and 0V (or floating) on the other. The differential voltage spikes to 12V. The op-amp output will rail to VDD. More dangerously, if the common-mode voltage exceeds the op-amp's VDD + 0.3V absolute maximum rating, the internal ESD protection diodes will forward-bias, drawing massive current from the battery through the input pins and destroying the silicon. Fix: Always place 10kΩ series resistors on both op-amp inputs to limit fault current to < 1mA.
Scenario B: The Load Short-Circuits
If the load shorts to ground, current is limited only by the battery's internal resistance and the shunt. In a 12V LiFePO4 system, this can exceed 200A instantly. A standard 0.05Ω 2W shunt will vaporize in milliseconds, turning into an open circuit (triggering Scenario A). Fix: The shunt must be placed downstream of a properly sized fuse or a polyfuse, and the shunt's surge power rating must exceed the let-through current of the protective device.
Design Walkthrough: Sizing for a 5A, 12V System
Let’s assign real component values for an ESP32-based battery monitor measuring up to 5A continuous.
1. Shunt Resistor Selection
We want a maximum voltage drop of 50mV at 5A to minimize power loss and load voltage sag.
- Resistance: R = V / I = 0.050V / 5A = 0.01Ω.
- Power Dissipation: P = I² * R = 25 * 0.01 = 0.25W. We will use a 1W rated metal strip shunt (e.g., Bourns CSS2H-2512R-L010F) for thermal headroom.
2. Op-Amp and Gain Calculation
The ESP32 ADC is most linear between 0.1V and 2.5V. We need 50mV at the input to map to 2.5V at the output.
- Required Gain: 2.5V / 0.050V = 50 V/V.
- Op-Amp Pick: We need an op-amp that can handle a 12V common-mode voltage while powered from a single supply. The TI LMV321 (or dual LMV358) is a 5.5V max part, so it won't work directly on 12V. We will use the TLV2372, which supports up to 16V VDD and features rail-to-rail input/output. We will power it directly from the 12V battery.
3. Resistor Network Sizing
To achieve a gain of 50, the ratio of R2/R1 must be 50. To keep input bias currents low and avoid loading the shunt, we use high-value resistors.
- R1 & R3 (Input): 10kΩ (0.1% tolerance)
- R2 & R4 (Feedback/Ground): 499kΩ (0.1% tolerance) — 499k is the standard E96 value closest to 500k.
Step-by-Step Breadboard Testing Protocol
Do not connect this amp circuit to your ESP32 until you have verified the analog output with a multimeter. Follow this exact sequence to avoid frying your microcontroller's ADC pin.
- Build the Op-Amp Stage First: Insert the TLV2372. Connect VDD to the 12V rail and GND to the system ground. Do not connect the shunt yet.
- Verify Power: Use a multimeter to check the voltage across the op-amp VDD and GND pins. It should read exactly 12.0V (or your battery voltage).
- Check the Zero-Current Baseline: With the shunt unconnected, use jumper wires to tie both
NODE_SHUNT_HIandNODE_SHUNT_LOdirectly to the 12V rail. MeasureNODE_VOUT. It should read 0.00V to 0.02V. If it reads higher, your R1-R4 resistor matching is flawed. - Inject a Known Differential Voltage: Remove the jumper from
NODE_SHUNT_LO. Connect a bench power supply set to 11.95V toNODE_SHUNT_LO(keeping 12.00V onNODE_SHUNT_HI). You have just simulated a 50mV shunt drop. - Measure the Output: Read
NODE_VOUT. It must read 2.5V (± 0.05V). If it reads 12V, your op-amp is saturated or wired incorrectly. - Integrate the Shunt and Load: Power down. Solder the 0.01Ω shunt in series with your load. Power up and measure the voltage directly across the shunt with a millivolt meter, then compare it to
NODE_VOUTdivided by 50.
Final Component Selection Decision Tree
While the discrete TLV2372 amp circuit is excellent for learning and high-bandwidth analog control loops, modern embedded projects often benefit from integrated solutions. Use this decision table to finalize your BOM.
| Application Requirement | Recommended Topology | Concrete Part Number |
|---|---|---|
| High-speed analog control loop (e.g., active current limiting in a motor driver, >100kHz bandwidth) | Discrete Differential Op-Amp (as designed above) | TLV2372 + 0.1% Resistor Network |
| Simple analog read for ESP32 ADC, low BOM count, unidirectional current | Integrated High-Side Analog Sense Amp | INA180A1 (Gain = 20V/V) |
| Digital read via I2C, bidirectional current (charging/discharging), built-in power math | Digital I2C Power Monitor | INA219 or INA226 |
| Ultra-high voltage (>60V) or isolated systems | Hall-Effect Sensor (No shunt) | ACS712-20A or ACS724 |






