Accurate Arduino current sensing with the INA219 opens up a world of possibilities: battery-powered devices that know their own runtime, motor controllers that detect stalls, solar charge controllers that log energy flow, and IoT devices that alert you when power consumption spikes unexpectedly. In this comprehensive tutorial, we cover the INA219 in depth, compare it with the ACS712, and build real working examples you can deploy today.
Table of Contents
- Why Current Sensing Matters in Projects
- The INA219: High-Side Current Sensor over I2C
- Wiring the INA219 to Arduino
- Complete INA219 Arduino Code
- ACS712: Hall-Effect Current Sensing Alternative
- Shunt Resistor Selection for Custom Designs
- Building a Power Consumption Logger
- Frequently Asked Questions
Why Current Sensing Matters in Projects
Most hobbyist projects ignore power consumption until it becomes a problem — a battery that dies in hours instead of days, a motor driver that overheats, or a voltage rail that sags under load. Current sensing solves all of these problems by giving your Arduino real-time visibility into power flow.
With current measurement, you can:
- Calculate battery state-of-charge by integrating current over time (Coulomb counting)
- Detect motor stalls when current exceeds normal running current
- Implement power budgeting in multi-subsystem devices
- Log energy consumption for solar and wind energy projects
- Protect circuits by triggering a shutdown when current exceeds a safe threshold
- Measure efficiency of DC-DC converters
The two dominant approaches for Arduino current sensing are: shunt-based sensing (measuring the voltage drop across a precision resistor — the INA219 approach) and Hall-effect sensing (measuring the magnetic field around a conductor — the ACS712 approach). Each has trade-offs we’ll explore in detail.
The INA219: High-Side Current Sensor over I2C
The INA219 from Texas Instruments (and widely available as breakout modules) is a precision current/power monitor that communicates over I2C. It measures both the voltage across a shunt resistor (to calculate current) and the bus voltage, then calculates power internally. All values are available as 16-bit registers over I2C.
Key Specifications
- Current measurement: ±3.2A (with the typical 0.1Ω shunt on most breakout boards)
- Voltage measurement: 0–26V bus voltage
- Resolution: 12-bit ADC, 1mA current resolution at default settings
- Interface: I2C, up to 400kHz
- Supply voltage: 3V–5.5V (logic-level compatible)
- Address range: 0x40–0x4F (configurable via A0/A1 pins)
- Operating mode: Continuous or triggered
High-Side vs Low-Side Sensing
The INA219 performs high-side current sensing — the shunt resistor sits between the power source and the load, above the load. This has a critical advantage: the load’s GND stays connected to system GND, avoiding ground loops. Low-side sensing (shunt between load and GND) is simpler but breaks the ground connection, causing issues with grounded loads like motor drivers and displays.
Wiring the INA219 to Arduino
The INA219 module has the shunt resistor built in. Connect it in series with your power supply line:
| INA219 Pin | Connection |
|---|---|
| VCC | Arduino 3.3V or 5V |
| GND | Arduino GND |
| SDA | Arduino A4 (Uno) or SDA pin |
| SCL | Arduino A5 (Uno) or SCL pin |
| VIN+ | Positive supply (power source +) |
| VIN- | Load positive terminal |
The current flows: Power source + → INA219 VIN+ → through shunt → INA219 VIN- → Load → Power source GND. The INA219 measures the tiny voltage drop across the shunt (typically 0–0.32V at full scale) and computes current from Ohm’s law: I = V_shunt / R_shunt.
Multiple INA219 modules can share the same I2C bus. Use the A0/A1 address pins to set unique addresses for each sensor:
- A0=GND, A1=GND: 0x40 (default)
- A0=VCC, A1=GND: 0x41
- A0=GND, A1=VCC: 0x44
- A0=VCC, A1=VCC: 0x45
Complete INA219 Arduino Code
Install the Adafruit INA219 library via the Library Manager (Sketch → Include Library → Manage Libraries → search “INA219”).
#include <Wire.h>
#include <Adafruit_INA219.h>
Adafruit_INA219 ina219(0x40); // Default address
void setup() {
Serial.begin(115200);
if (!ina219.begin()) {
Serial.println("INA219 not found! Check wiring.");
while (1) delay(10);
}
// Calibrate for max 2A / 3.2V shunt voltage
// ina219.setCalibration_32V_2A(); // Default
// ina219.setCalibration_32V_1A(); // Higher resolution for <1A loads
ina219.setCalibration_16V_400mA(); // Best resolution for small loads
Serial.println("Shunt V (mV) | Bus V (V) | Current (mA) | Power (mW)");
}
void loop() {
float shuntV = ina219.getShuntVoltage_mV();
float busV = ina219.getBusVoltage_V();
float current = ina219.getCurrent_mA();
float power = ina219.getPower_mW();
// Detect overflow
if (ina219.overflow) {
Serial.println("OVERFLOW — current exceeds sensor range!");
} else {
Serial.print(shuntV); Serial.print("t");
Serial.print(busV); Serial.print("t");
Serial.print(current); Serial.print("t");
Serial.println(power);
}
delay(500);
}
Calibration Modes Explained
setCalibration_32V_2A()— Up to 32V bus, 2A max, 1mA resolution (default)setCalibration_32V_1A()— Up to 32V bus, 1A max, 0.5mA resolutionsetCalibration_16V_400mA()— Up to 16V bus, 400mA max, 0.1mA resolution
Choose the calibration that best matches your load. A higher-resolution mode gives more accurate readings for small loads (like sensors drawing 10–100mA) but will overflow if the current exceeds the range.
ACS712: Hall-Effect Current Sensing Alternative
The ACS712 uses the Hall effect to measure current without being in series with the circuit — the current flows through an internal conductor and the resulting magnetic field is measured. This provides galvanic isolation between the measured circuit and the Arduino.
Specifications (ACS712-05B, most common variant)
- Range: ±5A
- Sensitivity: 185mV/A
- Output: Analog voltage (2.5V at 0A, shifts ±0.925V per ±5A)
- Supply: 5V only
- No I2C — reads directly with
analogRead()
const int ACS_PIN = A0;
const float SENSITIVITY = 0.185; // V/A for ACS712-05B
const float VREF = 5.0;
const float ZERO_CURRENT_V = VREF / 2.0; // 2.5V at 0A
void loop() {
// Average 100 samples to reduce noise
long sum = 0;
for (int i = 0; i < 100; i++) { sum += analogRead(ACS_PIN); }
float adcV = (sum / 100.0) * (VREF / 1023.0);
float current = (adcV - ZERO_CURRENT_V) / SENSITIVITY;
Serial.print(current, 3);
Serial.println(" A");
delay(100);
}
ACS712 vs INA219: The ACS712 is simpler to wire (no shunt, just pass the wire through) and provides isolation, but it’s noisier, has lower resolution, and only works with 5V Arduino. The INA219 is more accurate, offers I2C reporting of voltage AND power (not just current), supports 3.3V systems, and can run multiple sensors on one bus. For most Arduino projects, the INA219 is the better choice unless isolation is specifically required.
Shunt Resistor Selection for Custom Designs
If you design your own PCB or need to measure currents beyond the INA219 module’s 3.2A limit, you choose your own shunt resistor. The INA219 can measure shunt voltages up to 0.32V. For higher currents:
- 10A max: 0.032Ω shunt (32mΩ) — gives 0.32V drop at 10A
- 20A max: 0.016Ω shunt (16mΩ)
- 50A max: 0.006Ω shunt (6mΩ)
Use precision (0.1% or better) wirewound or metal strip shunt resistors rated for the power dissipation (P = I² × R). For a 10A, 32mΩ shunt: P = 100 × 0.032 = 3.2W — you need at least a 5W rated resistor with good thermal management.
When placing the shunt on a PCB, use a 4-wire (Kelvin) connection: two high-current traces carry the load current, and two separate sense traces connect to VIN+ and VIN- of the INA219. This eliminates the voltage drop in the connection resistance from your measurement.
Building a Power Consumption Logger
Here is a complete power logger that reads from the INA219 every second and outputs cumulative energy in watt-hours — useful for battery characterization or load profiling:
#include <Wire.h>
#include <Adafruit_INA219.h>
Adafruit_INA219 ina219;
double energyWh = 0.0;
unsigned long lastTime = 0;
void setup() {
Serial.begin(115200);
ina219.begin();
lastTime = millis();
Serial.println("Time(s),Voltage(V),Current(mA),Power(mW),Energy(mWh)");
}
void loop() {
unsigned long now = millis();
float dt = (now - lastTime) / 3600000.0; // Hours
lastTime = now;
float busV = ina219.getBusVoltage_V();
float current = ina219.getCurrent_mA();
float power = ina219.getPower_mW();
energyWh += power * dt; // mW * h = mWh
Serial.print(now / 1000.0, 1); Serial.print(",");
Serial.print(busV, 3); Serial.print(",");
Serial.print(current, 1); Serial.print(",");
Serial.print(power, 1); Serial.print(",");
Serial.println(energyWh, 2);
delay(1000);
}
Export the Serial Monitor output to a CSV and plot in Excel or Google Sheets for a complete power profile of your device. This technique is invaluable for calculating battery life: measure average power consumption over a realistic duty cycle, then divide battery capacity (mWh) by average power (mW) to get hours of runtime.
Frequently Asked Questions
What is the accuracy of the INA219 for current measurement?
The INA219 has a maximum offset error of ±0.5% and a gain error of ±0.5% of full scale. At the 400mA calibration setting, this translates to about ±2mA accuracy. For most hobby applications this is excellent. For precision energy metering, use the INA228 or INA260 which have lower offset errors and 16-bit resolution.
Can I measure both positive and negative current with the INA219?
Yes. The INA219 is bidirectional — it measures current flowing in both directions through the shunt. This makes it ideal for battery monitoring where current flows out during discharge and in during charging. The library returns negative values for reverse current flow.
What is the maximum current the INA219 module can measure?
The most common module uses a 0.1Ω shunt rated for 3.2A peak (continuous current limited by the shunt’s power rating — typically 1W, so 3.16A). For higher currents, use the INA219 chip with a custom low-value shunt resistor, or use an INA260 (which has an integrated 10mΩ shunt rated for 15A).
Can I monitor multiple loads with multiple INA219 sensors?
Yes. Connect up to 4 INA219 modules to the same I2C bus with different addresses (set via A0/A1 pins). Create a separate Adafruit_INA219 object for each with its address as the constructor argument, then poll each in turn.
How do I measure current in a 12V DC circuit with Arduino?
Use the INA219 in high-side configuration — place it in series on the positive 12V line. The INA219 VCC can still be powered from the Arduino’s 5V pin. The INA219 supports bus voltages up to 26V, so 12V systems are perfectly within range.
Start monitoring your project’s power consumption today. Find Arduino boards, sensors, and accessories in our Arduino & Microcontrollers store at Zbotic — delivered quickly across India.
Add comment