Fork me on GitHub

Project Notes

#504 INA226 High-side Monitor Basics

How to design for the INA226 current and power monitor and test with an Arduino and various libraries including raw wire I²C.

Build

Notes

I heard about the INA226 on the (sadly now defunct) SparkGap Podcast#33.

The INA226 is a “36V, Bi-Directional, High Accuracy, Low-/High-Side, I²C Out Current/Power Monitor w/Alert”. It can monitor current accross a shunt resistor and also bus voltage, allowing it to also calculate power consumption. It is a successor to the INA219, which is quie widely used in the microcontroller community.

It comes in a tiny VSSOP package with 0.5mm pitch pins. I put one on a DIP adapter for testing:

ina226_insitu

About the INA226

The INA226 operates only as an I²C or SMBus slave device:

  • supports fast mode (1 kHz to 400 kHz)
  • supports high-speed mode (1 kHz to 2.94 MHz).
  • All data bytes are transmitted most significant byte first.

Address

The A0 and A1 pins allow one of 16 addresses to be selected for the chip. Pulling both to ground sets the default address of 0x40.

Registers

Address Default Access Name Purpose
00h 4127h R/W Configuration Register All-register reset, shunt voltage and bus voltage ADC conversion times and averaging, operating mode
01h 0000h R Shunt Voltage Register Shunt voltage measurement data
02h 0000h R Bus Voltage Register Bus voltage measurement data
03h 0000h R Power Register Contains the value of the calculated power being delivered to the load
04h 0000h R Current Register Contains the value of the calculated current flowing through the shunt resistor
05h 0000h R/W Calibration Register Sets full-scale range and LSB of current and power measurements. Overall system calibration
06h 0000h R/W Mask/Enable Register Alert configuration and Conversion Ready flag
07h 0000h R/W Alert Limit Register limit value to compare to the selected Alert function
FEh 5449h R Manufacturer ID Register unique manufacturer identification number
FFh 2260h R Die ID Register unique die identification number

Configuration

The Configuration Register is used to set operating modes:

Bit Name Function
15 Reset Setting this bit to ‘1’ generates a system reset
9-11 AVG Sets averaging mode. Default = 0h (average over 1 sample. i.e. no averaging!)
6-8 VBUSCT Bus Voltage Conversion Time. Default 1.1ms
3-5 VSHCT Shunt Voltage Conversion Time. Default 1.1ms
0-2 MODE Operating mode. Default: Shunt and Bus, Continuous

Calibration

The Calibration Register is critical for accurate current and power measurements. It is explained (not very clearly!) in 7.5/7.5.1 of the data sheet.

It essentially outlines a procedure for calculating the calibration factor that will be used within the chip to pwerform current and power calculations. The calibration factor is a function of two variables:

  • Current_LSB - scaled by the user to ensure appropriate current resolution for the application
  • Rshunt - the shunt resistance

calibration

The calibration factor can be calculated on paper and fixed in code, but it seems that most libraries try to calculate the calibration factor for you. Note that to caclulate the calibration factor successfully it is important to account for the scale and order of operations, lest the calculation under/over-flow.

Reading Results

To read current:

  • multiple the value in the Current Register by current_LSB

To read power:

  • multiple the value in the Power Register by 25 * current_LSB
  • the power LSB has a fixed ratio to the Current_LSB of 25

To read bus voltage:

  • read the Bus Voltage Register and multiple by 1.25 mV
  • The Bus Voltage Register stores the most recent bus voltage reading, averaged if averaging is enabled
  • Full-scale range = 40.96 V (decimal = 7FFF); LSB = 1.25 mV

To read shunt voltage:

  • read the Shunt Voltage Register and multiple by 2.5 μV
  • Negative numbers are represented in two’s complement format
  • Full-scale range = 81.92 mV (decimal = 7FFF); LSB: 2.5 μV

Designing for Low Power Test Load

For a breadboard test, I want to keep things under control so I’m designing for a peak of 9V @ 200mA load - 1.8W.

The shunt resistance limit is dictated by the 81.92 mV full scale range of the shunt voltage register. So for 200mA, that means a shunt resistor no larger than 0.4Ω.

Under these conditions, the 0.4Ω shunt resistor will only draw 16mW, so 1/4W resistors are OK, however I’ve used a 0.22Ω 2W resistor as it is much more thermally stable and accurate than the cheap 1/4Ws I have on hand.

To keep the current within design limits, the minimum load resistance is 45Ω. I’ve chosen a 50Ω 5W resistor as fixed load, so actual current limit is 180mA. A 5W 10kΩ variable resistor is in series with the fixed load to allow the current to me adjusted all the way down to about 0.9mA.

Here’s the test circuit:

Breadboard

Schematic

Manual Calibration Calculation

I’m going to do this in code, but a first pass by hand…

Given a maximum current of 200mA:

With a 0.22Ω resistor, this yields a calibration factor of:

But maybe choose to calibrate for resolution of 8µA/bit (a nice binary number):

Code - Using the Wire Library

The WithRawWire.ino sketch is a simple monitor implentation that controlls the INA226 directly with the Wire library.

It demonstrates calibration and logging data to the console.

With the nominal shunt resistance it reports calibration in line with the hand calculations above:

INA226 High-side Monitor
Manufacturer ID : 5449
Die ID          : 2260
Calibrating for shunt resistance of 0.22Ω and maximum current of 0.200A
  * current_LSB : 0.006104mA
  * power_LSB   : 0.152593mW
  * CAL         : 3812

build_calibration

Now because I am running this on a breadboard and allowing for component variations, I don’t expect the actual shunt resistance to be exactly 0.22Ω. The first current measurements confirm there’s a problem:

  • INA226 reading: 6.055mA
  • DMM measurement: 3.35mA

Using the ratio to calculate the actual shunt resistance: 0.398Ω.

With that value plugged into the sketch, the measurements from the INA226 are remarkably good, especially considering this is just a loosey-goosey breadboard build:

console_calibrated

Swinging the pot full scale, measurements are withina few mV of what I’m reading on my DMM:

console_full_scale

So far so good - using the INA226 with the Wire Library is pretty straight-forward. Let’s now try a couple of Arduino libraries I found…

Using the Arduino-INA226 Library

The WithIna226Lib.ino sketch is a demonstration using the Arduino-INA226 library.

The Arduino-INA226 Library is a nice simple wrapper for the INA266 capabilities. Easy to use, but seems we’ve lost precision on the current and power calculations. The library does some extra rounding of the calibration factor that make it unable to handle sub-mA or mW values accurately. Fine if you are working with multi-amp loads though:

console_ina226

Using the INA Library

The WithInaLib.ino sketch is a demonstration using the INA library.

The INA Library is an ambitious attempt to combine support for multiple INA2xx power monitor devices.

Work very well, although it expects the maximum current to start from 1A, so not ideal for low-current applications.

console_ina

Credits and References

About LEAP#504 INA226Sensors
Project Source on GitHub Return to the LEAP Catalog

This page is a web-friendly rendering of my project notes shared in the LEAP GitHub repository.

LEAP is my personal collection of electronics projects, usually involving an Arduino or other microprocessor in one way or another. Some are full-blown projects, while many are trivial breadboard experiments, intended to learn and explore something interesting (IMHO!).

The projects are usually inspired by things found wild on the net, or ideas from the sources such as:

Feel free to borrow liberally, and if you spot any issues do let me know. See the individual projects for credits where due. There are even now a few projects contributed by others - send your own over in a pull request if you would also like to add to this collection.