Robot battery and current monitor with INA219: design worksheet and code

A ₹1,230 design worksheet for an INA219 and OLED monitor that shows pack voltage, peak current and charge used, with wiring, a sketch and a test plan.

About the author · Sources, testing and AI policy

  • Parts₹1,230
  • Bench time3–4 h
  • LevelIntermediate
  • ReviewedNov 2026

A ₹1,230 battery and motor-current monitor that shows what your robot actually draws. An INA219 module sits in the positive lead of a 2S lithium pack and reports voltage and current over I2C. An Arduino Uno shows both on a small OLED, keeps a peak-current reading and adds up the charge used. The page includes the wiring, a complete sketch, a way to check the readings against a multimeter, and a test plan for the mistakes that make current readings meaningless.

Scope: beginner to intermediate. This is a design worksheet with illustrative costs. It has not been bench-tested by this site, and the sketch uses the Adafruit INA219, SSD1306 and GFX libraries, which you install from the Arduino Library Manager. The monitor is a separate instrument: it sits between the battery and any robot, so you can move it from one build to the next.

What it tells you

Most robot problems that look like software are power problems: a pack that sags under a motor stall, a driver that drops more voltage than expected, a servo that browns out the controller. This monitor makes those visible. You read the pack voltage at rest and under load, the peak current during a stall or a hard turn, and a running total of charge used in milliamp-hours, so you can estimate run time from a real measurement.

Bill of materials

PartQtyUnitTotal
Arduino Uno R31₹520₹520
INA219 current sensor module1₹150₹150
0.96 inch SSD1306 I2C OLED1₹220₹220
2×18650 holder with cells1₹200₹200
Small breadboard1₹60₹60
Jumper wire set1₹50₹50
Switch1₹30₹30
Parts total₹1,230

Scroll the table sideways to see every column.

Prices checked Nov 2026. Shipping and tools are not included.

Prices are illustrative figures for Indian sellers in November 2026, before shipping, and have not been checked against current listings. The battery holder is included so the monitor can run on its own while you test; if you already have a robot pack, you do not need to buy it again.

Know the limits of the module first

The INA219 guide gives the datasheet figures: bus voltage up to 26 V, and shunt ranges up to ±320 mV. Many breakout boards use a 0.1 Ω shunt, which as a calculation puts the top current near 3.2 A. Check the marking on your board. A 2S pack at 8.4 V is well inside the voltage limit, but a stalled pair of motors can ask for more than 3.2 A, and the reading will clip. If your robot draws more, use a lower-value shunt or a different sensor; do not trust a reading that sits at the limit.

Wiring

ModuleArduino UnoNote
INA219 VCC / GND5V / GNDLogic supply for the chip
INA219 SDA / SCLA4 / A5I2C bus, shared with the OLED
OLED VCC / GND5V or 3.3V / GNDCheck your module; many accept both
OLED SDA / SCLA4 / A5Same bus as the INA219
INA219 Vin+Battery positive (through the switch)Supply side of the shunt
INA219 Vin-Robot or load positiveLoad side of the shunt
Battery negativeLoad ground and Uno GNDAll grounds joined
The shunt goes in the positive lead only. Wiring it into the ground side or bypassing it gives wrong readings.
  1. Power the Uno from USB while you build and test the display, with the pack disconnected.
  2. Connect the INA219 and OLED to the I2C pins, then run an I2C scanner sketch. You should see the OLED at 0x3C and the INA219 at 0x40 on most boards.
  3. Wire the pack through the switch to Vin+, and Vin- to the load. Join the pack negative to the Uno GND.
  4. Start with a small known load, such as a resistor or a single LED with a resistor, before connecting motors.

The sketch

// Robot battery and current monitor: Uno + INA219 + SSD1306 OLED (I2C)
// Libraries: Adafruit INA219, Adafruit SSD1306, Adafruit GFX.

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

Adafruit_INA219 ina219;
Adafruit_SSD1306 display(128, 64, &Wire, -1);

const float LOW_PACK_VOLTS = 6.4;   // example for a 2S pack; choose from your cell datasheet

float peakMilliamps = 0;
float usedMilliampHours = 0;
unsigned long lastMs = 0;

void setup() {
  Serial.begin(9600);
  if (!ina219.begin()) {
    Serial.println("INA219 not found");
    while (true) { }
  }
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println("OLED not found");
    while (true) { }
  }
  display.setTextColor(SSD1306_WHITE);
  lastMs = millis();
}

void loop() {
  float busVolts = ina219.getBusVoltage_V();
  float milliamps = ina219.getCurrent_mA();

  unsigned long now = millis();
  float hours = (now - lastMs) / 3600000.0;
  lastMs = now;
  if (milliamps > 0) {
    usedMilliampHours += milliamps * hours;
  }
  if (milliamps > peakMilliamps) {
    peakMilliamps = milliamps;
  }

  display.clearDisplay();
  display.setTextSize(2);
  display.setCursor(0, 0);
  display.print(busVolts, 2);
  display.print(" V");
  display.setCursor(0, 20);
  display.print(milliamps, 0);
  display.print(" mA");
  display.setTextSize(1);
  display.setCursor(0, 44);
  display.print("Peak ");
  display.print(peakMilliamps, 0);
  display.print(" mA");
  display.setCursor(0, 54);
  display.print("Used ");
  display.print(usedMilliampHours, 1);
  display.print(" mAh");
  if (busVolts > 0.5 && busVolts < LOW_PACK_VOLTS) {
    display.setCursor(80, 54);
    display.print("LOW");
  }
  display.display();

  Serial.print(busVolts, 2);
  Serial.print(" V  ");
  Serial.print(milliamps, 0);
  Serial.println(" mA");
  delay(200);
}

The default library setup assumes a 32 V, 2 A range, which fits a 0.1 Ω shunt for most small robots. If your robot draws more than the board can measure, the library has other calibration calls; check its examples and the datasheet before changing them. The 128×64 OLED buffer uses 1 KB of the Uno’s 2 KB of RAM, so keep the rest of the sketch small and avoid large strings.

Check it against a multimeter

  1. Voltage: measure the pack with a multimeter at the same point as Vin+ and compare it with the display. They should agree within a small margin; if not, check your ground connection.
  2. Current: put a multimeter in series on the current range in the load lead, with a known resistor as the load, and compare. Use a resistor that keeps the current well inside both meters’ ranges.
  3. Zero: with the load disconnected, the current should read near zero. A constant offset points to wiring or a board fault; see INA219 reads zero current.

Test plan

  1. Bench load: read voltage and current with a resistor load and confirm they match Ohm’s law within the tolerance of your meter and resistor.
  2. Idle robot: connect your robot with the wheels off the ground and record the idle current with the controller running and the motors stopped.
  3. Motor start and run: note the peak at start-up and the steady current while running. The start-up peak is usually higher.
  4. Stall: hold a wheel briefly and watch the peak. If the reading sits at the module’s limit, it is clipped and the real current is higher. Release the wheel quickly; a stalled motor heats fast.
  5. Sag: compare pack voltage at rest and under load. A large drop means a weak pack, thin wires or a driver with high losses.
  6. Run time: run the robot and note the mAh used when the low-voltage warning appears. Compare it with the pack’s rated capacity.

What usually goes wrong

SymptomLikely causeFix
INA219 not foundWrong wiring or address, or no pull-upsRun an I2C scanner, check SDA/SCL, check 3.3 V versus 5 V on the module
Current always zeroShunt bypassed, or Vin+/Vin- reversed or in the ground leadRewire the shunt in the positive lead only
Current reads negativeVin+ and Vin- swappedSwap them
Reading stuck at one value under loadOver the module’s rangeUse a lower-value shunt or a different sensor
Voltage looks right but mAh driftsSampling interval and noiseSample faster, and treat mAh as an estimate
Display blank or garbledWrong OLED address or not enough RAMCheck 0x3C or 0x3D, shrink the rest of the sketch
Uno resets when motors startLogic and motors sharing a weak supplyPower the Uno separately, or add a capacitor and thicker wires

Upgrades

  • Log to a card: add a microSD module and write time, volts and milliamps once a second to compare runs.
  • Stall cut-out: have the robot controller read the same measurement and stop the motors if the current stays high for a set time.
  • Higher current: use a current-sense amplifier or a Hall sensor for a robot that draws more than the INA219 board measures.
  • Two channels: use a second module on the other I2C address to measure the motor supply and the logic supply separately.

Cost and parts notes

The ₹1,230 total is an illustration for the parts above and does not include shipping. For battery voltage alone, a resistor divider into an ADC is cheaper, as the divider fix page explains. The INA219 earns its place when you also want current, for stall detection and run-time estimates.

Common questions

Can I use an ESP32 instead of an Uno?

Yes. The libraries support it and I2C pins differ by board, so change the wiring to its SDA and SCL pins. The OLED RAM warning no longer applies.

Is the mAh figure accurate?

It is an estimate. It adds up current samples over time, so it depends on sampling speed and the sensor's accuracy. Use it to compare runs, not as a battery gauge.

Can it measure a 12 V or 24 V robot?

The datasheet allows bus voltage up to 26 V, but a 24 V system with spikes is too close to that limit. Choose a part with more margin for it.

Why not just use a multimeter?

A meter shows one instant. This logs peaks and totals while the robot moves, which is where power faults hide.

Last reviewed: November 2026. This is a design worksheet with illustrative costs. It has not been bench-tested by this site; library calls and defaults should be checked against the current library examples, and measurements from your build are welcome.

More builds

Next builds to try

Free: the final-year project pack

A shortlist with BOMs, a report outline that matches the usual chapter scheme, a costing sheet and 40 viva questions. Built for the February–April submission season.

The Build Note

One short email when something is worth your bench time.

A new build sheet, a part price that moved, or a mistake worth avoiding. No daily drip, no recycled news.

One short email when a build or a price is worth your time. Unsubscribe in one click.