Learn

An INA219 on an Arduino: current, voltage and power

Advanced

Or see every lesson.

  • 465parts on the bench
  • 43boards running now
  • 1.00xreal time, on every board
Arduino Uno: an INA219 on a solar panellive0.000 s 0.00x
Press Run, then drag the light on the solar panel
An INA219 between a 6 V panel and a 36 ohm load, read every 40 ms by a solar tracker on a simulated ATmega328P.

The INA219 is a current sensor on a small purple breakout. You put it in series with a load, and over I2C it tells the Arduino how much current flows, at what voltage, and how much power that is. Unlike a hall effect module, it reads small currents well, down to a tenth of a milliamp, and it measures the voltage too.

The circuit above is an Uno running a solar tracker, and the INA219 is the part that keeps score: it sits between a small 6 V panel and a 36 ohm load and reports what the panel makes. Press Run, then drag the light slider on the panel and watch the volts, milliamps and milliwatts follow on the serial monitor. Further down is a short sketch that reads the INA219 on its own.

What you need

  • An Arduino Uno
  • An INA219 breakout
  • A load to measure: here a 6 V solar panel and a 36 ohm resistor
  • Jumper wires and a breadboard

Wiring

Part and pinGoes toNote
INA219 VCC5 VThe chip’s own supply, 3 to 5.5 V
INA219 GNDGNDShared with the circuit you measure
INA219 SDASDA (A4)The Uno’s I2C data pin
INA219 SCLSCL (A5)The Uno’s I2C clock pin
INA219 VIN+Panel +The supply side of the shunt
INA219 VIN-36 ohm loadThe load side; the load’s other end goes to GND

How the INA219 measures current

On the breakout there is a 0.1 ohm resistor called the shunt, between the VIN+ and VIN- pins. All the load’s current goes through it, and by Ohm’s law it drops 0.1 volts for every amp. The chip measures that tiny voltage, in steps of 10 microvolts, and divides by the shunt to get the current.

It also measures the bus voltage, from VIN- to ground, in steps of 4 millivolts. Multiply the two and you have the power. The chip does that sum itself, so the Arduino just reads three registers.

That is why the wiring matters. The INA219 goes in series, in the wire from the supply to the load, never across the supply. Put it in backwards and the current reads negative. Leave out the shared ground and the bus voltage means nothing.

The Adafruit INA219 library and example code

Adafruit_INA219.h is the library most tutorials use. begin() finds the chip at address 0x40 and writes its calibration, and then four calls do everything: getBusVoltage_V(), getShuntVoltage_mV(), getCurrent_mA() and getPower_mW(). If begin() finds nothing, this sketch prints "No INA219" and stops.

The sketch below is the short test every INA219 guide starts with. Here the INA219 sits between the Uno’s 5 V pin and a 100 ohm resistor to ground. Run it and each second it prints "5.00 V 4.99 mV 49.90 mA 248.00 mW". 4.99 millivolts across 0.1 ohm is 49.9 milliamps, and 5 volts across about 100 ohms is 50 milliamps, so the numbers agree. The power comes in steps of 2 milliwatts at the library’s default calibration, which is why it says 248 and not 249.5.

Swap VIN+ and VIN- and the same circuit reads "-49.90 mA": the chip is fine, the current is just flowing the other way through it.

INA219 example sketch
#include <Wire.h>
#include <Adafruit_INA219.h>

Adafruit_INA219 ina219;

void setup() {
  Serial.begin(115200);
  if (!ina219.begin()) {
    Serial.println("No INA219");
    while (1);
  }
}

void loop() {
  Serial.print(ina219.getBusVoltage_V());
  Serial.print(" V  ");
  Serial.print(ina219.getShuntVoltage_mV());
  Serial.print(" mV  ");
  Serial.print(ina219.getCurrent_mA());
  Serial.print(" mA  ");
  Serial.print(ina219.getPower_mW());
  Serial.println(" mW");
  delay(1000);
}

Reading a solar panel

The solar tracker reads the INA219 every 40 milliseconds and prints a line each second. Its panel voltage is the bus voltage plus the shunt’s drop, which gives the voltage at the panel itself, on the VIN+ side.

In full sun, 1000 watts per square meter on the slider, it prints "panel 5.93 V 164.4 mA 972 mW". Drag the light down to 500 and it reads "panel 3.46 V 95.8 mA 330 mW": half the light, about a third of the power, because the panel’s voltage falls along with its current. Drag it to 0 and it reads "panel 0.00 V 0.0 mA 0 mW".

The rest of the sketch adds those readings up over twenty seconds of tracking and twenty seconds parked, to compare the two. That part is just power times time. The INA219 part is the three calls in readPanel().

From the solar tracker sketch
#include <Wire.h>
#include <Adafruit_INA219.h>

Adafruit_INA219 ina;
float volts = 0, milliamps = 0, milliwatts = 0;

void readPanel() {
  volts = ina.getBusVoltage_V() + ina.getShuntVoltage_mV() / 1000.0;
  milliamps = ina.getCurrent_mA();
  milliwatts = ina.getPower_mW();
}

Range, addresses and more than one INA219

Through a 0.1 ohm shunt the INA219 reads up to 3.2 amps on its widest range. setCalibration_32V_1A() and setCalibration_16V_400mA() trade range for finer steps, as in the Adafruit library. A current past the range reads as the end of it.

The address is 0x40 as the board ships. Close the solder jumpers and it moves to 0x41, 0x44 or 0x45, so up to four boards can share one bus. Give each its own object, such as Adafruit_INA219 second(0x41).

Common mistakes

Wiring it across the supply like a voltmeter. The shunt is 0.1 ohm: across a battery it is close to a short circuit. It always goes in series.

VIN+ and VIN- the wrong way around, so the current reads negative.

Forgetting that the bus voltage is measured at VIN-, the load side. It is the supply less the shunt’s drop, which is why the solar sketch adds the shunt voltage back.

No common ground. The INA219, the Arduino and the circuit you measure must share GND.

Writing your own driver and getting a steady zero. The chip powers up with its calibration register empty, and until something writes it the current and power read zero. begin() writes it for you.

Questions

What library do I use for the INA219 on Arduino?

Adafruit INA219 (Adafruit_INA219.h), from the Library Manager. Mokxi has it built in, so the example on this page runs as it is.

How do I wire an INA219 current sensor?

VCC to 5 V, GND to GND, SDA to A4 and SCL to A5. Then break the wire from your supply to your load and put VIN+ on the supply side and VIN- on the load side.

What is the maximum current an INA219 can measure?

With the usual 0.1 ohm shunt, 3.2 amps on its widest range, 0.4 A on its narrowest. Past the range the reading stops at the end of it.

Why does my INA219 read a negative current?

VIN+ and VIN- are swapped. Current is flowing from VIN- to VIN+, so the chip reports it with a minus sign.

Build this for real

Open the editor, change a value and watch the number move with it. Nothing to install, and no account needed.