Breadboard power current monitor with INA219 sensor wired to a small DC cooling fan

Intermediate

Build a Power & Current Monitor

SensorsAutomation

Stop guessing how much power your project actually draws -- measure real current and voltage together, without ever breaking your circuit apart.

6 real parts included

Total for this kit: 1,400.00 ฿

Doesn't include any order discount you may get at checkout.

What you'll need

Project Goal

Most projects that draw power just draw it, with no easy way to see how much. This project adds a real measurement instrument to the mix: a sensor that reports voltage and current together, so you can see actual power draw (in watts) rather than guessing at it or breaking the circuit apart to probe it with a separate multimeter. A small DC fan stands in as the load, giving you a real, visibly meaningful current draw to watch change as the fan spins up.

What the Controller Does

The controller's job here is simple but continuous: poll the current/voltage sensor over I2C on a loop, pull back the latest readings, and report them (over serial, on a display, or however your version of the project outputs them). The controller does not do any of the actual current sensing itself -- that work happens entirely on the sensor chip.

What the Current & Voltage Sensor Does

The INA219 measures voltage and current at the same time. It measures the tiny voltage drop across its own internal shunt resistor to calculate current, and separately measures bus voltage, then combines the two on-chip to calculate real power (P = I x V). All of this is read back over I2C as ready-to-use numbers -- you never have to manually probe the circuit mid-operation the way you would with a handheld multimeter.

What the Demo Load Does

The 5V mini DC fan exists purely to give the sensor something real to measure. Unlike an LED or a resting microcontroller, a small motor draws a current that's easy to see change -- from near-zero at rest to a clearly higher, stable draw once it's spinning -- which makes it a good, visible way to confirm your readings are actually tracking reality.

Measuring In-Line: Series vs Parallel

This is the one wiring concept that matters more than any other in this project: to measure current, the sensor has to sit directly in the current's path. That means wiring the INA219 in series between the power supply and the load -- power in on one side, power out to the load on the other -- not in parallel across the load the way you'd measure voltage alone. Wire it in parallel by mistake and the sensor will read zero current, because no current is actually flowing through it.

Software and Library Concepts

Use a working INA219 library for your controller platform rather than talking to the registers by hand. The library needs to be calibrated with the actual shunt resistor value on your specific board -- most libraries default to a common value, but if your board differs, either update the calibration constant or double-check the board's datasheet before trusting the numbers. Once calibrated, reading current, voltage, and power is typically three simple function calls per loop.

Testing and Troubleshooting

  • Readings show zero -- by far the most common real mistake is wiring the sensor in parallel with the load instead of in series. The sensor must sit directly in the current path between the power supply and the load, or no current will flow through it to measure at all.
  • Readings look wildly inaccurate -- confirm the shunt resistor value your code is calibrated for actually matches the value printed or documented for your specific sensor board.
  • Sensor not detected on I2C -- if other I2C devices already share the same bus, do the standard address-conflict check; the INA219 has a default address but many boards let you change it via solder jumpers if it collides with something else.
  • Readings jump around erratically -- check for a loose connection in the series path first; an intermittent connection in a current-carrying wire causes much noisier readings than a loose signal wire would.

Optional Future Upgrade: Data-Logging Power Monitor

Once basic readings are working reliably, a natural next step is logging power draw over time instead of only watching it live -- see the wireless data logger project for the concepts involved in storing and reporting readings on a schedule rather than one at a time.

Wiring

  • INA219 VCC → ESP32-C3 SuperMini 3.3V
  • INA219 GND → GND
  • INA219 SDA → GPIO8 (`SDA_PIN`)
  • INA219 SCL → GPIO9 (`SCL_PIN`)
  • 5V supply (ESP32-C3 5V/VBUS pin) → INA219 VIN+ — power flows into the sensor first
  • INA219 VIN− → Fan + lead — then out to the load
  • Fan − lead → GND, common with the ESP32-C3 and supply GND

INA219 measures whatever flows through it, so it must sit in-line in the fan's positive supply wire (VIN+ from the source, VIN- out to the fan) — it is not simply tapped onto the rail. A small 40mm fan draws little enough current that powering it from the ESP32-C3's own 5V pin is fine for this demo (unlike higher-draw loads such as multiple servos, which need a separate supply). No OLED is in this project's parts list, so results print to Serial Monitor; adding a 0.96" I2C OLED later is a straightforward extension since it would share the same I2C bus.

Wiring Diagram

VCC → 3.3V GND SDA → GPIO8 SCL → GPIO9 VIN+ ESP32-C3 SuperMini INA219 GND 5V supply Fan − lead Fan + lead INA219 VIN−

Starter Code

#include <Wire.h>
#include <Adafruit_INA219.h>

#define SDA_PIN 8   // ESP32-C3 default I2C SDA - adjust if your board differs
#define SCL_PIN 9   // ESP32-C3 default I2C SCL - adjust if your board differs

Adafruit_INA219 ina219;

void setup() {
  Serial.begin(115200);
  Wire.begin(SDA_PIN, SCL_PIN);

  if (!ina219.begin(&Wire)) {
    Serial.println("INA219 not found - check I2C wiring/address");
    while (true) delay(1000);
  }

  Serial.println("Power & Current Monitor ready");
  Serial.println("time_s,loadVoltage_V,shuntVoltage_mV,current_mA,power_mW");
}

void loop() {
  float busVoltage_V = ina219.getBusVoltage_V();
  float shuntVoltage_mV = ina219.getShuntVoltage_mV();
  float current_mA = ina219.getCurrent_mA();
  float power_mW = ina219.getPower_mW();

  // Actual voltage across the load is bus voltage plus the (tiny) shunt drop
  float loadVoltage_V = busVoltage_V + (shuntVoltage_mV / 1000.0);

  Serial.printf("%.1f,%.3f,%.3f,%.2f,%.2f\n",
                millis() / 1000.0, loadVoltage_V, shuntVoltage_mV, current_mA, power_mW);

  delay(1000);
}

Not sure about a step? Ask us