This library for MicroPython makes it easy to leverage the complex functionality of the Texas Instruments INA219 sensor to measure voltage, current and power.
This MicroPython library for the INA219
voltage, current and power monitor sensor from Texas Instruments. The intent of
the library is to make it easy to use the quite complex functionality of this
sensor.
The functionality is currently under development and is based on my INA219 library for the Raspberry Pi.
The library currently only supports continuous reads of voltage and
power, but not triggered reads.
The library supports the detection of overflow in the current/power
calculations which results in meaningless values for these readings.
The low power mode of the INA219 is supported, so if only occasional
reads are being made in a battery based system, current consumption can
be minimised.
The library has been tested with the Adafruit INA219 Breakout and the pyboard, as well as a NodeMCU (esp8266 12e) clone. and a lolin32_lite">Lolin32 Lite (esp32). For specific instructions for the esp8266 and esp32, see sub-directories.
If you successfully use this library with an WiPy, etc, please let me know.
If you want to give it a try then copy ina219.py and logging.py onto the flash drive of your pyboard, connect the sensor to the I2C(1) or I2C(2) interfaces on the pyboard,
then from a REPL prompt execute:
from ina219 import INA219
from machine import I2C
I2C_INTERFACE_NO = 2
SHUNT_OHMS = 0.1 # Check value of shunt used with your INA219
ina = INA219(SHUNT_OHMS, I2C(I2C_INTERFACE_NO))
ina.configure()
print("Bus Voltage: %.3f V" % ina.voltage())
print("Current: %.3f mA" % ina.current())
print("Power: %.3f mW" % ina.power())
Alternatively copy ina219.py, logging.py
and example.py
to the flash drive and from the REPL prompt execute:
execfile('example.py')
The address of the sensor unless otherwise specified is the default
of 0x40.
Note that the bus voltage is that on the load side of the shunt resister,
if you want the voltage on the supply side then you should add the bus
voltage and shunt voltage together, or use the supply_voltage()
function.
This mode is great for getting started, as it will provide valid readings
until the device current capability is exceeded for the value of the
shunt resistor connected (3.2A for 0.1Ω shunt resistor). It does this by
automatically adjusting the gain as required until the maximum is reached,
when a DeviceRangeError exception is thrown to avoid invalid readings being taken.
The downside of this approach is reduced current and power resolution.
from ina219 import INA219
from ina219 import DeviceRangeError
from machine import I2C
I2C_INTERFACE_NO = 2
SHUNT_OHMS = 0.1 # Check value of shunt used with your INA219
ina = INA219(SHUNT_OHMS, I2C(I2C_INTERFACE_NO))
ina.configure()
print("Bus Voltage: %.3f V" % ina.voltage())
try:
print("Bus Current: %.3f mA" % ina.current())
print("Power: %.3f mW" % ina.power())
print("Shunt voltage: %.3f mV" % ina.shunt_voltage())
except DeviceRangeError as e:
# Current out of device range with specified shunt resister
print e
In this mode by understanding the maximum current expected in your system
and specifying this in the script you can achieve the best possible current
and power resolution. The library will calculate the best gain to achieve
the highest resolution based on the maximum expected current.
In this mode if the current exceeds the maximum specified, the gain will
be automatically increased, so a valid reading will still result, but at
a lower resolution.
As above when the maximum gain is reached, an exception is thrown to
avoid invalid readings being taken.
from ina219 import INA219
from ina219 import DeviceRangeError
from machine import I2C
I2C_INTERFACE_NO = 2
SHUNT_OHMS = 0.1 # Check value of shunt used with your INA219
MAX_EXPECTED_AMPS = 0.2
ina = INA219(SHUNT_OHMS, I2C(I2C_INTERFACE_NO), MAX_EXPECTED_AMPS)
ina.configure(ina.RANGE_16V)
print("Bus Voltage: %.3f V" % ina.voltage())
try:
print("Bus Current: %.3f mA" % ina.current())
print("Power: %.3f mW" % ina.power())
print("Shunt voltage: %.3f mV" % ina.shunt_voltage())
except DeviceRangeError as e:
# Current out of device range with specified shunt resister
print e
In this mode by understanding the maximum current expected in your system
and specifying this and the gain in the script you can always achieve the
best possible current and power resolution, at the price of missing current
and power values if a current overflow occurs.
from ina219 import INA219
from ina219 import DeviceRangeError
from machine import I2C
I2C_INTERFACE_NO = 2
SHUNT_OHMS = 0.1 # Check value of shunt used with your INA219
MAX_EXPECTED_AMPS = 0.2
ina = INA219(SHUNT_OHMS, I2C(I2C_INTERFACE_NO), MAX_EXPECTED_AMPS)
ina.configure(ina.RANGE_16V, ina.GAIN_1_40MV)
print("Bus Voltage: %.3f V" % ina.voltage())
try:
print("Bus Current: %.3f mA" % ina.current())
print("Power: %.3f mW" % ina.power())
print("Shunt voltage: %.3f mV" % ina.shunt_voltage())
except DeviceRangeError as e:
print("Current overflow")
The sensor address may be altered as follows:
ina = INA219(SHUNT_OHMS, I2C(2), MAX_EXPECTED_AMPS, address=0x41)
The sensor may be put in low power mode between reads as follows:
ina.configure(ina.RANGE_16V)
while True:
print("Voltage : %.3f V" % ina.voltage())
ina.sleep()
time.sleep(60)
ina.wake()
Note that if you do not wake the device after sleeping, the value
returned from a read will be the previous value taken before sleeping.
INA219()
constructs the class.
_I2C(1)_ or _I2C(2)_ (mandatory).
configure()
configures and calibrates how the INA219 will take measurements.voltage()
Returns the bus voltage in volts (V).supply_voltage()
Returns the bus supply voltage in volts (V). Thiscurrent()
Returns the bus current in milliamps (mA).power()
Returns the bus power consumption in milliwatts (mW).shunt_voltage()
Returns the shunt voltage in millivolts (mV).current_overflow()
Returns ‘True’ if an overflow hassleep()
Put the INA219 into power down mode.wake()
Wake the INA219 from power down mode.reset()
Reset the INA219 to its default configuration.On v1.1 pyboard reading a bus voltage in a loop, a read occurred approximately
every 270μs. Given that in continuous mode a single 12-bit ADC
conversion takes 532μs (p27 of the specification) each value returned
by the voltage() function will likely be the result of a new conversion.
If multiple ADC conversions are configured (e.g. ADC2SAMP, takes 1060μs)
then the values returned by the _voltage() function will often be the result of
the same conversion and therefore identical.
Add the following to the imports
import logging
To understand the calibration calculation results and automatic gain increases, informational output can be enabled with:
ina = INA219(SHUNT_OHMS, I2C(2), log_level=logging.INFO)
Detailed logging of device register operations can be enabled with:
ina = INA219(SHUNT_OHMS, I2C(2), log_level=logging.DEBUG)
This library adheres to the PEP8 standard and follows the idiomatic
style described in the book Writing Idiomatic Python by Jeff Knupp.