Skip to content

milkmansson/toit-ina219

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

12 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Toit Library for a TI INA219 Voltage/Current Measurement Module

Toit Driver Library for an INA219 module, DC Shunt Current, Voltage, and Power Sensor.

Front and back of one version of the INA219 module

About the Device

The INA219 from Texas Instruments is a digital power monitor with an integrated ADC. It measures the voltage drop across a shunt resistor to calculate current, monitors the bus voltage directly, and internally multiplies the two to report power consumption.

Quick Start Information

Use the following steps to get operational quickly:

  • Follow Wiring Diagrams to get the device connected correctly.
  • Ensure Toit is installed on the ESP32 and operating. (Most of the code examples require the use jag monitor to show outputs.) See Toit Documentation to get started.
  • This is a device using I2C, Toit documentation has a great I2C introduction.
  • Use one of the code examples to see the driver in operation.

Core features:

  • Measures shunt voltage up to ±320 mV (programmable gain ±40 / ±80 / ±160 / ±320 mV) with a fixed 10 µV/LSB resolution.
  • Measures bus voltage from 0 V to 32 V (selectable full-scale 16 V or 32 V range) with 4 mV/LSB resolution.
  • Computes current and power using a user-programmable shunt resistor value and calibration register. (Current and Power readings remain zero until calibration is written, this is taken care of in the driver.)
  • Independent conversion settings for shunt and bus channels, each selectable from 84 µs to 68.1 ms per conversion depending on ADC resolution/averaging. (These are fixed in combination with specific sampling rates.)
  • Programmable averaging of 1 to 128 samples for improved noise performance. (These are fixed in combination with specific conversion timings.)
  • I²C interface supporting Standard (100 kHz) and Fast (400 kHz) modes. (No true High-Speed 2.94 MHz mode on the INA219.)
  • Built-in alert/flag bits for 'conversion ready' and 'math overflow'. (Unlike INA226, there are no programmable alert thresholds for over-current, etc.)
  • Operates from a single 3.0 V – 5.5 V supply.

The INA219 is suited for querying current and voltage of small devices like microcontrollers, sensors, and IoT or embedded systems loads. Many modules come with a R100 shunt resistor onboard, but this can be desoldered and changed, and new values assigned when the driver is used.

There are several modules cheaply available based on this chipset.

Comparison of Sibling Models

Given their similarity, driver library for sibling models were written at the same time:

Model INA219 (This driver) INA226 INA3221
Channels 1 1 3 (independent but require a common GND and other wiring caveats, see Datasheet.)
Bus/common-mode range 0–26 v(bus/common-mode). Bus register full-scale can be configured at 16v or 32v, with caveats (BRNG). 0–36v common-mode. Bus register full-scale 40.96v but cannot exceed 36v at pins. 0–26v common-mode; bus register full scale to 32.76v, but input cannot exceed 26v.
Shunt Voltage 320mv, depending on PGA config +/-81.92mv fixed
Device Voltage 3.0-5.5 v 2.7-5.5v 2.7-5.5v
Averaging options 8 fixed options between 1 and 128. Averaging and Conversion times are fixed to a limited set of pairs and cannot be set separately. Several options between 1 and 1024. All options available in combination with all conversion time options. Several options between 1 and 1024. All options available in combination with all conversion time options.
Current & power registers Present (Requires device calibration, performed by the driver) Present (Requires calibration, performed by the driver) Reports shunt & bus per channel but current and power are calulated in software by the driver.
ADC / resolution 9 to 12-bit depending on the register, and averaging/ sampling option selected. 16-bit 13-bit
Alerting/Alert pin None. "Conversion Ready" exists, but must be checked in software. Alerts and Alert Pin, but different features from INA3221. Alerts and Alert pin, but different features from INA226
Possible I2C addresses 16 16 4
Datasheets INA219 Datasheet INA226 Datasheet INA3221 Datasheet
Other Notes - - Has no calibration register - current/power must be calculated in the driver. Adds 'Power-Valid' window and Summation features.

Core Concepts

"Shunt" History

"Shunt" comes from the verb to shunt, meaning to divert or to bypass. In railway terms, a shunting line diverts trains off the main track. In electrical engineering, a shunt resistor is used to divert current into a measurable path.

Originally, in measurement circuits, shunt resistors were used in analog ammeters. A sensitive meter with sensitive needle movement could only handle very tiny current. A low-value "shunt" resistor was therefore placed in parallel to bypass (or shunt) most of the current, so the meter only saw a safe fraction. By calibrating the ratio, large currents could be read with a small meter.

How it works

The INA219 measures current using a tiny precision resistor (referred to as the shunt resistor), which is placed in series with the load. When current flows through the shunt, a small voltage develops across it. Because the resistance is very low (e.g., 0.1 Ohm), this voltage is only a few millivolts even at significant currents. The INA219’s ADC is designed to sense this tiny voltage drop, precision in the microvolt range. Ohm’s Law (V = I × R) is used to compute current.

Simultaneously, the device monitors the bus voltage on the load side of the shunt. By combining the shunt voltage (for current) with the bus voltage (for supply level), the INA219 can also compute power consumption. The INA219 stores these values in its registers which the driver retrieves using I2C.

Usage

Measuring/Operating Modes

The device has two measuring modes: Continuous and Triggered, as well as combinations of measuring both the bus and shunt voltage. (Use set-measure-mode to configure these.) Alongside, set-measure-mode MODE-POWER-DOWN will turn the device off.

Continuous Mode

In continuous modes MODE-BUS-CONTINUOUS, MODE-SHUNT-CONTINUOUS and MODE-SHUNT-BUS-CONTINUOUS the INA219 loops forever:

  • It repeatedly measures bus voltage and/or shunt voltage.
  • Each conversion result overwrites the previous one in the registers.
  • The sampling cadence is set using conversion times and averaging settings.

Use cases:

  • Requiring a live stream of current/voltage/power, e.g. logging consumption of an IoT node over hours.
  • In cases where the MCU needs to poll for measurements periodically, & expects the register to always hold the freshest value.
  • Best for steady-state loads or long-term monitoring.

Triggered Mode

In triggered (single-shot) modes MODE-SHUNT-TRIGGERED, MODE-BUS-TRIGGERED, and MODE-SHUNT-BUS-TRIGGERED:

  • The INA219 sits idle until a measurement is explicitly triggered (by writing to the config register).
  • It performs exactly one set of conversions (bus + shunt, with averaging if configured).
  • Then it goes back to idle (low power).

Use cases:

  • Low power consumption: e.g. wake up the INA219 once every few seconds/minutes, take a measurement, then let both the INA219 and MCU sleep.
  • Synchronized measurement: e.g. where a measurement is necessary at the same time a load is toggled, eg, so the measurement can be triggered at the right time after.
  • Useful in battery-powered applications where quiescent drain must be minimized.

Power-Down

INA219 can enter an ultra-low-power state. In this state, no measurements happen. Supply current drops to 0.5 uA typ (2uA max). Useful for ultra-low power systems where periodic measurement isn't needed. Use set-measure-mode MODE-POWER-OFF to shutdown. Start again by setting the required measure mode using set-measure-mode MODE-TRIGGERED or set-measure-mode MODE-CONTINUOUS

Features

Shunt Resistor Configuration

Most modules seen have R100 resistors onboard, so the driver has a default of 0.100 Ohm. Set the shunt resistor to a different value when creating the instance (in Ohms) e.g.,

  ina219-driver := Ina219 ina219-device --shunt-resistor=0.100

This also takes care of configuring the calibration value. (Advanced users can set this manually using set-calibration-value.) The driver takes care of computig and configuring the calibration value based on the shunt resistor values. The device can also be configured to into the required mode using its constructor:

  ina219-driver := Ina219 ina219-device --measure-mode=MODE-SHUNT-BUS-TRIGGERED

Please see below for example resistor values.

Sampling and Averaging

On INA219, the ADC settings are quite constrained. They are selected with a specific set of presets, combines resolution (9/10/11/12-bit) and averaging (1…128 samples) with a single conversion time (84us to 68.1 ms). In other words, averaging and conversion time aren’t set independently; they are picked from the predefined pairs. These are:

Configuration Constant Modes Sample rate Conversion Time
ADC-RES-AVG-M9-84 9 bit 1 84us
ADC-RES-AVG-M10-148 10 bit 1 148us
ADC-RES-AVG-M11-276 11 bit 1 276us
ADC-RES-AVG-M12-532 12 bit 1 532us
ADC-RES-AVG-S2-1060 12 bit 2 1060us (eg 1.06ms)
ADC-RES-AVG-S4-2130 12 bit 4 2130us
ADC-RES-AVG-S8-4260 12 bit 8 4260us
ADC-RES-AVG-S16-8510 12 bit 16 8150us
ADC-RES-AVG-S32-17020 12 bit 32 17020us
ADC-RES-AVG-S64-34050 12 bit 64 34050us
ADC-RES-AVG-S128-68100 12 bit 128 68100us (eg 68.1ms)

They can be set in this way:

ina219-driver.set-bus-adc-resolution-average Ina219.ADC-RES-AVG-M9-84
ina219-driver.set-shunt-adc-resolution-average Ina219.ADC-RES-AVG-S64-34050

If conversion time is especially important in your project, note that the conversion times don't interleave, they are performed one at a time and add to eachother.

Bus Voltage Range

This device allows a configuration to select a greater sensitivity, but with reduced range (Referred to as BRNG in the Datasheet):

  • 16v using set-bus-voltage-fs-range 16
  • 32v (default) using set-bus-voltage-fs-range 32

Tip: If your rail never exceeds 14v, set this to 16v for slightly improved sensitivity. Otherwise keep the full-scale range at 32v.

PGA Gain and Range

PGA (Programmable Gain Amplifier) is a small internal differential amplifier sitting between the shunt resistor and the ADC. Its job is to amplify the small voltage across the shunt so that the ADC can measure it more accurately. At a lower range, the ADC’s full 12-bit scale is used over a smaller voltage window, which means finer current resolution.

Configuration Constant Use Case Gain Range Reason
SHUNT-VOLTAGE-PGA-G1-R40 Precision micro/milliamp 1 40mv Maximum ADC sensitivity, small signals.
SHUNT-VOLTAGE-PGA-G2-R80 Low-current (<500ma) /2 80mv Better resolution, typical with 0.1–0.5 Ω shunt.
SHUNT-VOLTAGE-PGA-G4-R160 Mid-current (0.5-3 A) /4 160mv Improves ADC granularity for low currents.
SHUNT-VOLTAGE-PGA-G8-R320 (Default) High-current (>3 A) /8 320mv Prevent clipping at high drop, typical 0.1 Ω shunt.

Example configuration: Set this alongside the other values when initially instantiating the driver, like this:

ina219-driver.set-shunt-voltage-pga-gain-range Ina219.SHUNT-VOLTAGE-PGA-G1-R40

Conversion Ready/Waiting time

Although the registers can be read at any time, and the data from the last conversion is always available, the 'Conversion Ready Flag' is provided to help coordinate one-shot or triggered conversions.

The driver calculates an 'estimated conversion time' using Shunt + Bus conversion times and sampling value, and adds a 10% margin. This is used to compute a maximum wait time for a conversion before giving up.

In triggered mode, if a measurement is triggered using trigger-measurement, it will wait for a maximum of get-estimated-conversion-time-ms for a conversion to complete. If not using triggered mode, a fresh measurement can be triggered using trigger-measurement (optionally waiting by using the --wait flag.) To manually wait for measurements in other scenarios, use wait-until-conversion-completed and override the default maximum wait time estimate using flag --max-wait-time-ms=xxxx.

Measurement Functions

The INA219 really measures two things internally:

  1. V(shunt) = IN+ - IN- (a small differential voltage across the shunt)
  2. V(bus) = the "bus/load" node/pin voltage.

From these, the driver computes current and power, and reconstructs the upstream supply. On many boards, VBUS is often internally tied to IN− (the low side of the shunt). If the module in use different (VBUS not tied to IN−), the meanings below still hold, although "bus voltage" would then refer to whatever is wired to VBUS.

  • read-shunt-voltage: The voltage drop across the shunt: Vshunt = IN+ − IN−. Given in Volts
  • read-bus-voltage: The "load node" voltage. If VBUS is not tied to IN−, the function returns whatever VBUS is wired to. Given in Volts.
  • read-supply-voltage: The upstream/source voltage before the shunt (Vsupply ≈ Vbus + Vshunt = (voltage at IN−) + (IN+ − IN−) = voltage at IN+. Given in Volts.
  • read-shunt-current: The current through the shunt and load load, in amps. Internally, the chip uses a calibration constant set from the configured shunt resistor value. Given in Amps. Caveats:
    • Accurate only if shunt value in code matches the physical shunt.
    • Choose appropriate averaging/conversion time for scenario.
  • read-load-power: Power delivered to the load, in watts. Caveats:
    • Because Vbus is after the shunt, this approximates power at the load (not at the source).
    • Depends on correct calibration. (Calibration values are care of in this driver when setting set-shunt-resistor, and set to 0.100 Ohm by default).

Changing the Shunt Resistor

Many cheap INA219 modules ship with 0.1 Ohm or 0.01 Ohm shunts.

  • For high-current applications (tens of amps), the shunt can be replaced with a much smaller value (e.g. 1–5 mOhm). This reduces voltage drop and wasted power, and raises the maximum measurable current, but makes the resolution for tiny currents coarser.
  • For low-current applications (milliamps), a larger shunt (e.g. 0.5–1.0 Ohm) increases sensitivity and resolution, but lowers the maximum measurable current (≈80 mA with a 1 Ohm shunt) and burns more power in the resistor itself.

Important

If the shunt is changed, always add a line to the beginning of the code to set the shunt resistor value every boot. The INA219 cannot detect it, and the driver does not store these values permanently.

Shunt Resistor Values

The following table illustrates consequences to current measurement using some sample shunt resistor values:

Shunt Resistor (SR) Max Measurable Current Shunt Resistor Wattage Requirement Resolution per bit Note
1.000 Ohm 0.320 mA 0.25w (min) 10 uA/bit Very fine resolution, but higher voltage drop.
0.100 Ohm (default) 3.20 A Use 2 W 100 uA/bit Common value in modules, good general purpose range.
0.050 Ohm 6.40 A 3-5 W (impractical?) 200 uA/bit Wider current range; check module copper and heating.
0.010 Ohm 32.0 A 10.2 W - heavy shunt needed 1 mA/bit For high-current rails, usually needing an external precision shunt.

Issues

If there are any issues, changes, or any other kind of feedback, please raise an issue. Feedback is welcome and appreciated!

Disclaimer

  • This driver has been written and tested with an unbranded INA226 module.
  • All trademarks belong to their respective owners.
  • No warranties for this work, express or implied.

Credits

  • Florian for the tireless help and encouragement
  • The wider Toit developer team (past and present) for a truly excellent product
  • AI has been used for code and text reviews, analysing and compiling data and results, and assisting with ensuring accuracy.

About Toit

One would assume you are here because you know what Toit is. If you dont:

Toit is a high-level, memory-safe language, with container/VM technology built specifically for microcontrollers (not a desktop language port). It gives fast iteration (live reloads over Wi-Fi in seconds), robust serviceability, and performance that’s far closer to C than typical scripting options on the ESP32. [link]

About

Toit driver library for the TI INA219 current/voltage/power sensor

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages