INA226
Arduino library for INA226 power sensor
Install / Use
/learn @RobTillaart/INA226README
INA226
Arduino library for the INA226 power sensor.
Description
Experimental
Experimental library for the INA226 power sensor. Not all functionality is tested / investigated.
Read datasheet for details.
==> USE WITH CARE
The INA226 is a voltage, current and power measurement device. A few important maxima, see datasheet, chapter 6.
| description | max | unit | notes | |:----------------|-------:|---------:|:--------| | bus voltage | 36 | Volt | unclear for how long. | shunt voltage | 81.9 | mVolt | datasheet 81.92 mV | current | 20 | Ampere |
Feedback as always is welcome.
0.5.0 Breaking change
Version 0.5.0 introduced a breaking change. You cannot set the pins in begin() any more. This reduces the dependency of processor dependent Wire implementations. The user has to call Wire.begin() and can optionally set the Wire pins before calling begin().
Special characters
- Ω == Ohm = ALT-234 (Windows)
- µ == micro = ALT-0181 (Windows)
Related
- https://www.ti.com/product/INA226#tech-docs
- https://www.ti.com/product/INA226#params
- https://www.ti.com/document-viewer/INA226/datasheet
- https://github.com/RobTillaart/INA219 26 Volt, I2C, 12 bit
- https://github.com/RobTillaart/INA226 36 Volt, I2C, 16 bit
- https://github.com/RobTillaart/INA228 85 Volt, I2C, 20 bit
- https://github.com/RobTillaart/INA229 85 Volt, SPI, 20 bit
- https://github.com/RobTillaart/INA236 48 Volt, I2C, 16 bit
- https://github.com/RobTillaart/INA239 85 Volt, SPI, 16 bit
- https://github.com/RobTillaart/INA260 36 Volt, I2C, 16 bit
- https://github.com/RobTillaart/INA3221_RT 26 Volt, I2C, 13 bits (3 channel)
- https://www.adafruit.com/product/5832
- https://www.mateksys.com/?portfolio=i2c-ina-bm
- https://github.com/RobTillaart/printHelpers (for scientific notation)
I2C
Address
The sensor can have 16 different I2C addresses, which depends on how the A0 and A1 address lines are connected to the SCL, SDA, GND and VCC pins.
See table - from datasheet table 2, page 18.
| A1 | A0 | Addr | HEX | |:-----:|:-----:|:------:|:------:| | GND | GND | 64 | 0x40 | | GND | VS | 65 | 0x41 | | GND | SDA | 66 | 0x42 | | GND | SCL | 67 | 0x43 | | VS | GND | 68 | 0x44 | | VS | VS | 69 | 0x45 | | VS | SDA | 70 | 0x46 | | VS | SCL | 71 | 0x47 | | SDA | GND | 72 | 0x48 | | SDA | VS | 73 | 0x49 | | SDA | SDA | 74 | 0x4A | | SDA | SCL | 75 | 0x4B | | SCL | GND | 76 | 0x4C | | SCL | VS | 77 | 0x4D | | SCL | SDA | 78 | 0x4E | | SCL | SCL | 79 | 0x4F |
Performance
To be elaborated, example sketch available.
(From Datasheet)
The INA226 supports the transmission protocol for fast mode (1 kHz to 400 kHz)
and high-speed mode (1 kHz to 2.94 MHz).
All data bytes are transmitted most significant byte first.
About Measurements
Calibration with setMaxCurrentShunt() or configure() is mandatory to get getCurrent() and getPower() to work. Using configure() user has flexibility of setting desired current least significant bit value. Use either of configure() or setMaxCurrentShunt().
An easy procedure to accurately calibrate shunt resistance, current zero offset and bus voltage scaling has been provided under examples in INA226_calibration example.
Some initial tests shows that the readings do not 100% add up. I expect this is caused by fluctuations in my power supply used and more important that the ADC is multiplexed so there is time between the bus voltage measurement and the shunt voltage measurement. If the current has changed a bit these values are not necessary in line.
Did some measurements with a load of 194 ohm and a shunt of 0.002 ohm that is a factor 10e5 Being on the edge of the sensitivity of the ADC measurements of current were up to ~9% too low. Possible cause is that some maths is done in 16 bit so numbers are truncated, not rounded.
(see issue #2) Sensors may have a different shunt resistor than the 0.002 I have. You should always check and verify what is on the shunt and even verify with a DMM that this value is correct. With the calibration function setMaxCurrentShunt() one can just set the actual value and even compensate slightly if readings are structural too low or too high.
I noted that the getPower() function does not always equal getBusVoltage() times getCurrent(). Cause is rounding/trunking maths and time of measurement. You might prefer to multiply those values yourself to get extra digits. Please be aware that more digits is not always more exact (think significant digits).
The example sketch INA226_setMaxCurrentShunt.ino switches between two calibration modes. It shows the INA226 sensor needs time to accommodate to this change. In practice you should call setMaxCurrentShunt() only once in setup().
Also see #30 for another typical deviation problem.
Interface
#include "INA226.h"
Constructor
- INA226(const uint8_t address, TwoWire *wire = Wire) Constructor to set the address and optional Wire interface.
- bool begin() initializes the class. returns true if the INA226 address is on the I2C bus. Note: one needs to set Wire.begin() before calling begin().
- bool isConnected() returns true if the INA226 address is on the I2C bus.
- uint8_t getAddress() returns the address set in the constructor.
Core Functions
Note the power and the current are not meaningful without calibrating the sensor. Also the value is not meaningful if there is no shunt connected.
- float getShuntVoltage() idem, in volts.
- float getBusVoltage() idem. in volts. Max 36 Volt.
- float getCurrent() is the current through the shunt in Ampere.
- float getPower() is the current x BusVoltage in Watt.
- bool isConversionReady() returns true if conversion ready flag is set.
- bool waitConversionReady(uint32_t timeout = INA226_MAX_WAIT_MS) active waiting for ready flag. Polling for max timeout time, default 600 milliseconds, for wake up time.
The library has helper functions to convert above output to a more appropriate scale of units.
Helper functions for the milli scale.
- float getBusVoltage_mV() idem, in milliVolts.
- float getShuntVoltage_mV() idem, in milliVolts.
- float getCurrent_mA() idem, in milliAmpere.
- float getPower_mW() idem, in milliWatt.
Helper functions for the micro scale.
- float getBusVoltage_uV() idem, in microVolts.
- float getShuntVoltage_uV() idem, in microVolts.
- float getCurrent_uA() idem, in microAmpere.
- float getPower_uW() idem, in microWatt.
Configuration
Note: The internal conversions runs in the background in the device. If a conversion is finished the measured value is stored in the appropriate register. The last obtained values can always be read from the registers, so they will not block. Result can be that you get the very same value if no new data is available yet. This is especially true if you increase the number of samples. (See also discussion in INA219 issue 11).
Using more samples reduces the noise level, but one will miss the faster changes in voltage or current. Depending on your project needs you can choose one over the other.
As a rule of thumb one could take the time between two I2C reads of a register as an upper limit. This would result in a fresh measurement every time one reads the register. NB it is always possible to average readings fetched from the device in your own code.
- bool reset() software power on reset. This implies calibration with setMaxCurrentShunt() needs to be redone. Returns true upon success.
- bool setAverage(uint8_t avg = INA226_1_SAMPLE) see table below. (0 = default ==> 1 read), returns false if parameter > 7.
- uint8_t getAverage() returns the value set. See table below. Note this is not the count of samples.
- bool setBusVoltageConversionTime(uint8_t bvct = INA226_1100_us) see table below. (4 = default ==> 1.1 ms), returns false if parameter > 7.
- uint8_t getBusVoltageConversionTime() return the value set. Note the value returned is not a unit of time.
- bool setShuntVoltageConversionTime(uint8_t svct = INA226_1100_us) see table below. (4 = default ==> 1.1 ms), returns false if parameter > 7.
- uint8_t getShuntVoltageConversionTime() return the value set. Note the value returned is not a unit of time.
| enum description | value | # samples | notes | |:--------------------:|:-----:|----------:|--------:| | INA226_1_SAMPLE | 0 | 1 | default | INA226_4_SAMPLES | 1 | 4 | | INA226_16_SAMPLES | 2 | 16 | | INA226_64_SAMPLES | 3 | 64 | | INA226_128_SAMPL
