Let’s break down the phenomenon:
-
The current loop itself is fine (setpoint ≈ measured value), indicating the closed loop with MOSFET, op-amp, and DAC is working properly;
-
Only the INA226’s “reported value” is low, and it specifically occurs when VBUS is low and current is high;
-
At 18 V, almost no error is visible.
This almost points directly to device-level measurement errors caused by “too low common-mode voltage across the shunt resistor,” rather than code or I²C timing.
-
Common-mode too low, internal PGA starts to underperform
INA226’s input stage is a ΔΣ-type ADC with a 2 MHz switched-capacitor array at the front end. The lower the common-mode voltage, the more pronounced the charge injection mismatch in the internal sample-and-hold, amplifying the equivalent offset. The datasheet clearly states: when VCM = 0 V, typical offset is 50 µV, dropping to the 10 µV range when VCM ≥ 1 V. With your 4 V input and 50 mA current, assuming a 50 mΩ shunt resistor, VBUS is actually pulled down to 4 V – 2.5 mV ≈ 3.9975 V, which is still considered “low” for common-mode. More critically, the shunt voltage is only 2.5 mV, already the same order of magnitude as the offset voltage; as current increases further, the readings start to lose accuracy.
-
Kelvin routing/pad thermocouple effects of the shunt resistor
At low voltage and high current, an additional 1 µΩ of metal resistance introduces a 1 µV error. If the top-layer copper is etched away significantly, or the sampling points are too far from the pads, the actual Vshunt reaching the INA226 will be lower than what the multimeter measures.
-
On-board ground bounce
If power ground, digital ground, and INA226’s GND share a thin trace, 50 mA switching spikes can create ground differences of several hundred µV, directly superimposing on the differential measurement.
-
I²C timing/noise
Such errors typically manifest as “jitter” or “code flickering” rather than systematic low readings, so this should be lower priority.
Improvement checklist (sorted by cost-effectiveness)
A. Move the shunt resistor to the “high side”
Let INA226’s VBUS pin sit directly on the battery positive terminal, so common-mode ≈ 4 V, far above the 1 V “comfort zone,” immediately reducing device offset by an order of magnitude. High-side measurement requires:
– Move the shunt resistor to the positive side;
– INA226’s V+ supply can be 3.3 V, since common-mode is allowed up to 36 V;
– Note that new traces must be Kelvin and separated from the power path.
B. Increase the shunt voltage
If the maximum current is 1 A, replace the 50 mΩ with 100 mΩ, giving a full-scale of 100 mV. The LSB remains 2.5 µV, but the signal-to-offset ratio doubles. Power dissipation is 100 mW, which is acceptable for a 1 A application.
C. Calibrate the “zero offset”
Perform a “zero-current” sampling in code (relay disconnected or DAC=0), store the result in EEPROM, and subtract it before each formal test. The INA226 itself has a Calibration register, but that only works for power/current calculations, not for raw shunt voltage; so directly reading the Shunt Voltage Register and subtracting the offset is the cleanest approach.
D. Minor board rework
– Partition power ground and digital ground, connect at a single point;
– Use the entire layer under INA226 as “analog ground” copper, meeting power ground only at a single point through a 0 Ω resistor or pin header;
– Place two pairs of Kelvin vias inside the shunt resistor pads, run differential traces parallel in inner layers, length <15 mm.
E. Software filtering
Collect 64 samples for averaging, then smooth the result with a second-order IIR filter, which can suppress random noise below 0.2 LSB. However, this is ineffective against systematic offset and should only be used in conjunction with A/B/C.
Quick verification methods
-
Temporarily use a lab power supply in series with a 1 Ω resistor to artificially raise VBUS above 8 V, and see if the error immediately decreases;
-
Use a precision millivolt source (or DAC+voltage divider) to inject 1 mV, 5 mV, 10 mV directly into INA226’s differential pins, read the Shunt Voltage Register, and plot the “input-code” curve to immediately see the device’s linear region.
Typically, after completing items A+B+C, you can suppress the error at the 4 V/1 A point to within ±0.5 %FS. The rest is just a software calibration issue. Good luck with debugging!