Preview build — page text is a draft awaiting human review. Code badges come from real compiles. The flasher is real but not yet hardware-tested; the Playground is still a preview.

INA219 with Raspberry Pi Pico W — measure current and power in MicroPython

Measure load voltage, current, power and mAh with an INA219 on Pico W I2C0 (GP4/GP5) in MicroPython, reading the shunt and bus registers directly.

MicroPythonVerified — micropython (mpy-cross v1.29.0), 3 Nov 2026Compile-only

Community draft — report a mistake

The INA219 measures current through a small shunt resistor and the voltage on the load side, all over I2C. With the R100 shunt fitted to the common purple board, two register reads give you volts, milliamps, milliwatts and a running mAh total.

Wire the module to 3V3 and I2C0 (GP4/GP5), then put it in the positive wire of the circuit you want to measure: supply + to VIN+, VIN− to the load. Keep that circuit to DC under 26 V.

Wiring

Raspberry Pi Pico WOnly the pins used are shown · 3.3 V logicCircuit supply to measure (up to 26 V DC)INA219 DC current/voltage sensor+-GNDGP4GP53V3VCCGNDSCLSDAVIN+VIN- → Load + (load − back to supply −)
Every connection
Raspberry Pi Pico WINA219 DC current/voltage sensorWireNotes
—VIN-—To Load + (load − back to supply −) (not drawn)
3V3VCCred3V3 is pin 36. Pull-ups follow VCC.
GNDGNDblackShared ground: the INA219, the Pico and the measured circuit.
GP5SCLyellowGP5 is physical pin 7 (I2C0 SCL).
GP4SDAblueGP4 is physical pin 6 (I2C0 SDA).
Circuit supply to measure (up to 26 V DC) · +VIN+redThe current flows in through VIN+ and out of VIN− to the load (high-side measurement).
Circuit supply to measure (up to 26 V DC) · -GNDblackWithout a shared ground the bus voltage reads nonsense.

3.0–5.5 V part, 3.3 V board. Power VCC from your board's logic voltage (3.3 V or 5 V); the I2C pull-ups go to VCC, so they match your board.

Board quirks

  • No calibration register is needed: the script reads the shunt voltage (10 µV per bit) and divides by the 0.1 Ω R100 shunt. A different shunt? Change SHUNT_OHMS.
  • The default ±320 mV shunt range means up to 3.2 A with R100. The INA219 measures up to 26 V on the bus — never mains.
  • Bus voltage is measured at VIN−, i.e. what your load actually gets.
  • The mAh counter integrates current over time — run a battery-powered gadget for an hour and you have its real consumption.

Code

main.pyMicroPython
# INA219 current / voltage / power monitor on a Raspberry Pi Pico W (MicroPython, no library).
# Wiring: VCC -> 3V3 (pin 36), GND -> GND (also the measured circuit's GND), SCL -> GP5 (pin 7),
# SDA -> GP4 (pin 6). Measured circuit: supply + -> VIN+, VIN- -> load +. Max 26 V, 3.2 A.
# Assumes the usual R100 (0.1 Ohm) shunt on the purple breakout.
from machine import Pin, I2C
import time

SHUNT_OHMS = 0.1
i2c = I2C(0, sda=Pin(4), scl=Pin(5), freq=400_000)
found = i2c.scan()
addr = None
for a in (0x40, 0x41, 0x44, 0x45):
    if a in found:
        addr = a
        break
if addr is None:
    raise SystemExit("No INA219 at 0x40/0x41/0x44/0x45 - found {}".format([hex(a) for a in found]))

# Config 0x3FFF: 32 V bus range, +-320 mV shunt range, 12-bit x128 averaging, continuous.
i2c.writeto_mem(addr, 0x00, bytes([0x3F, 0xFF]))


def reg(r, signed=False):
    hi, lo = i2c.readfrom_mem(addr, r, 2)
    v = (hi << 8) | lo
    return v - 65536 if signed and v > 32767 else v


print("INA219 at", hex(addr))
mah = 0.0
last = time.ticks_ms()
while True:
    shunt_mv = reg(0x01, True) * 0.01   # 10 uV per bit, signed
    bus_v = (reg(0x02) >> 3) * 0.004    # 4 mV per bit: the voltage at VIN- (what the load sees)
    ma = shunt_mv / SHUNT_OHMS
    now = time.ticks_ms()
    mah += ma * time.ticks_diff(now, last) / 3_600_000
    last = now
    print("Load {:.3f} V  {:7.1f} mA  {:7.1f} mW  used {:.2f} mAh".format(bus_v, ma, bus_v * ma, mah))
    time.sleep(1)

Expected serial output

REPL / Thonny shellOutput
INA219 at 0x40
Load 11.912 V    142.3 mA   1695.1 mW  used 0.04 mAh
Load 11.908 V    145.0 mA   1726.7 mW  used 0.08 mAh

Common errors

Current reads negative

VIN+ and VIN− are swapped. The supply goes to VIN+, the load to VIN−.

Voltage reads 0 V but current looks right

The measured circuit’s ground is not joined to the INA219 GND.

↑↓ to move · Enter to open