A current sensor schematic routes load current through a sensing element—either a precision shunt resistor or a Hall-effect plate—and conditions the resulting signal for a microcontroller. If you are building a battery monitor, solar charge controller, or motor driver with an ESP32 or Arduino, your choice of schematic topology dictates your measurement resolution, isolation safety, and software complexity. For 90% of low-voltage DC maker projects, the default recommendation is the Texas Instruments INA219 I2C shunt monitor. For high-current or AC applications requiring galvanic isolation, the Allegro ACS724 Hall-effect sensor is the correct choice.
The Sensing Principle: Shunt vs. Hall Effect
Shunt-based sensors like the INA219 rely on Ohm’s Law. Load current flows through a low-value precision resistor (typically 0.01Ω to 0.1Ω), generating a proportional millivolt drop. An internal instrumentation amplifier and analog-to-digital converter (ADC) digitize this drop and present it over an I2C bus. Shunt schematics offer exceptional DC accuracy and high resolution but require you to physically break the high-side or low-side power path to insert the resistor, meaning there is no galvanic isolation between the load and your microcontroller.
Hall-effect sensors like the ACS724 pass current through a primary internal conductor, generating a magnetic field that is measured by a Hall element on a separate silicon die. This architecture provides galvanic isolation—crucial for AC mains monitoring or high-voltage DC systems—because the load current never electrically touches the microcontroller's output pins. However, Hall sensors introduce magnetic hysteresis, external electromagnetic interference (EMI) susceptibility, and typically require the microcontroller's internal ADC to read a ratiometric analog voltage.
Decision Matrix: Picking the Right Sensor IC
Do not guess which topology you need. Use this decision path to select the exact part number for your schematic.
| Application Requirement | Recommended Topology | Specific Part Number | Typical Cost (2026) |
|---|---|---|---|
| DC < 3.2A, high precision, I2C digital output | High-Side Shunt Monitor | INA219 (Adafruit 904 or generic) | $4.00 - $9.50 |
| DC/AC up to 50A, requires galvanic isolation | Hall-Effect IC | ACS724-50AB (Bidirectional) | $6.00 - $12.00 |
| AC Mains (120V/240V) non-invasive clamping | Current Transformer (CT) | SCT-013-000 (100A/50mA output) | $8.00 - $15.00 |
| DC > 50A, high-side, minimal heat dissipation | Shunt + External INA226 | INA226 + Custom 0.001Ω Shunt | $10.00 - $18.00 |
Wiring the INA219: Pinout and Power Routing
The INA219 is a high-side monitor, meaning it sits between your power supply positive terminal and your load. The ESP32 communicates with it via I2C. Below is the standard wiring schematic for an ESP32 DevKit v1.
| INA219 Pin | ESP32 Pin | Supply Range / Notes |
|---|---|---|
| VCC | 3.3V | Logic power. Accepts 3.0V to 5.5V. Tie to ESP32 3V3. |
| GND | GND | Logic ground. Must share common ground with ESP32. |
| SCL | GPIO 22 | I2C Clock. Use 4.7kΩ pull-up to 3.3V if wires exceed 10cm. |
| SDA | GPIO 21 | I2C Data. Use 4.7kΩ pull-up to 3.3V if wires exceed 10cm. |
| V+ | Power Supply (+) | Load positive IN. Absolute max 26V. Do not exceed 26V DC. |
| V- | Load (+) | Load positive OUT. Connects directly to your device under test. |
Output Signal Math: Raw Readings to Physical Units
A common failure point in embedded projects is conflating digital register values with analog voltages. Here is the exact math for both the digital INA219 and the analog ACS724.
Digital Output: INA219 Shunt Math
The INA219 output is a digital I2C register value. The internal 12-bit ADC measures the voltage drop across the shunt resistor. The Shunt Voltage Register (Address 0x01) outputs a raw integer where 1 LSB = 10µV.
- Step 1 (Shunt Voltage):
V_shunt = Raw_Register * 0.00001 - Step 2 (Current):
I_amps = V_shunt / R_shunt
Worked Example: Your board has a 0.1Ω shunt. The ESP32 reads a raw register value of 450.
V_shunt = 450 * 0.00001 = 0.0045V (4.5mV).
Current = 0.0045V / 0.1Ω = 0.045A (45mA).
Analog Output: ACS724 Hall Math
The ACS724 output is a ratiometric analog voltage centered around VCC/2. You must read this with the ESP32's 12-bit ADC (0-4095) and scale it using the sensor's sensitivity rating from the Allegro ACS724 datasheet.
- Formula:
I_amps = (V_out - V_offset) / Sensitivity
Worked Example: Using the ACS724-5AB (±5A range, 400mV/A sensitivity) powered at 5.0V. V_offset is 2.5V. If your ESP32 ADC reads 3.3V at the output pin:
Current = (3.3V - 2.5V) / 0.4V/A = 0.8V / 0.4 = 2.0A.
Interference Sources and PCB Layout Rules
Current sensing is highly susceptible to noise. If your readings are jittery, check these three interference sources:
- Switching Regulator EMI (Hall Sensors): Hall-effect ICs like the ACS724 will couple magnetic flux from nearby buck converters or inductors. Keep the sensor IC at least 20mm away from any switching power supply inductors. If unavoidable, use a mu-metal shield.
- Ground Loops (Shunt Sensors): In high-side shunt schematics, the INA219 ground pin must return to the ESP32 ground via a dedicated, thick trace. If the I2C ground reference bounces due to high load currents returning through a shared thin ground plane, your I2C bus will lock up or corrupt register reads.
- Shunt Thermal Drift: Standard breakout boards use copper-trace shunts or cheap 1% resistors. As the shunt heats up under load, its resistance increases, causing the current reading to artificially drop over time. For precision applications, specify a 4-terminal Kelvin shunt resistor with a ±15 ppm/°C temperature coefficient.
setCalibration() function.
ESP32 Implementation: Code and Calibration
Below is the complete, compilable Arduino IDE code for the ESP32 using the INA219. It includes I2C initialization, error handling for missing chips, and the calibration setup for a standard 0.1Ω, 3.2A max configuration.
#include <Wire.h>
#include <Adafruit_INA219.h>
// Instantiate the INA219 object (default I2C address 0x40)
Adafruit_INA219 ina219;
void setup() {
Serial.begin(115200);
while (!Serial) {
delay(10); // Wait for serial monitor on native USB boards
}
// Initialize I2C and the INA219 sensor
if (!ina219.begin()) {
Serial.println("CRITICAL: Failed to find INA219 chip on I2C bus.");
Serial.println("Check SDA/SCL wiring and 4.7k pull-up resistors.");
while (1) {
delay(1000); // Halt execution to prevent phantom readings
}
}
// By default, the INA219 is calibrated for a 0.1 ohm shunt, 3.2A max.
// If using a 0.01 ohm shunt for 16A max, uncomment the line below:
// ina219.setCalibration_16V_400mA(); // Adjust based on your exact shunt
Serial.println("INA219 initialized successfully. Polling every 1s...");
}
void loop() {
float shuntvoltage = 0;
float busvoltage = 0;
float current_mA = 0;
float loadvoltage = 0;
float power_mW = 0;
// Read raw and calculated values directly from IC registers
shuntvoltage = ina219.getShuntVoltage_mV();
busvoltage = ina219.getBusVoltage_V();
current_mA = ina219.getCurrent_mA();
power_mW = ina219.getPower_mW();
// Load voltage is Bus Voltage + Shunt Voltage drop
loadvoltage = busvoltage + (shuntvoltage / 1000);
Serial.print("Bus Voltage: "); Serial.print(busvoltage); Serial.println(" V");
Serial.print("Shunt Voltage: "); Serial.print(shuntvoltage); Serial.println(" mV");
Serial.print("Load Voltage: "); Serial.print(loadvoltage); Serial.println(" V");
Serial.print("Current: "); Serial.print(current_mA); Serial.println(" mA");
Serial.print("Power: "); Serial.print(power_mW); Serial.println(" mW");
Serial.println("---------------------------------");
delay(1000);
}
When deploying this schematic in the field, always verify your I2C pull-up resistors. The ESP32's internal pull-ups are roughly 45kΩ, which is far too weak for the 400kHz I2C fast-mode edge rates required by the INA219. Solder external 4.7kΩ resistors from SDA and SCL to the 3.3V rail to ensure clean square waves and prevent intermittent I2C bus lockups.






