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
| Part | Qty | Unit | Total |
|---|---|---|---|
| Arduino Uno R3 | 1 | ₹520 | ₹520 |
| INA219 current sensor module | 1 | ₹150 | ₹150 |
| 0.96 inch SSD1306 I2C OLED | 1 | ₹220 | ₹220 |
| 2×18650 holder with cells | 1 | ₹200 | ₹200 |
| Small breadboard | 1 | ₹60 | ₹60 |
| Jumper wire set | 1 | ₹50 | ₹50 |
| Switch | 1 | ₹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
| Module | Arduino Uno | Note |
|---|---|---|
| INA219 VCC / GND | 5V / GND | Logic supply for the chip |
| INA219 SDA / SCL | A4 / A5 | I2C bus, shared with the OLED |
| OLED VCC / GND | 5V or 3.3V / GND | Check your module; many accept both |
| OLED SDA / SCL | A4 / A5 | Same bus as the INA219 |
| INA219 Vin+ | Battery positive (through the switch) | Supply side of the shunt |
| INA219 Vin- | Robot or load positive | Load side of the shunt |
| Battery negative | Load ground and Uno GND | All grounds joined |
- Power the Uno from USB while you build and test the display, with the pack disconnected.
- 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.
- Wire the pack through the switch to Vin+, and Vin- to the load. Join the pack negative to the Uno GND.
- 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
- 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.
- 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.
- 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
- 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.
- Idle robot: connect your robot with the wheels off the ground and record the idle current with the controller running and the motors stopped.
- Motor start and run: note the peak at start-up and the steady current while running. The start-up peak is usually higher.
- 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.
- Sag: compare pack voltage at rest and under load. A large drop means a weak pack, thin wires or a driver with high losses.
- 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
| Symptom | Likely cause | Fix |
|---|---|---|
| INA219 not found | Wrong wiring or address, or no pull-ups | Run an I2C scanner, check SDA/SCL, check 3.3 V versus 5 V on the module |
| Current always zero | Shunt bypassed, or Vin+/Vin- reversed or in the ground lead | Rewire the shunt in the positive lead only |
| Current reads negative | Vin+ and Vin- swapped | Swap them |
| Reading stuck at one value under load | Over the module’s range | Use a lower-value shunt or a different sensor |
| Voltage looks right but mAh drifts | Sampling interval and noise | Sample faster, and treat mAh as an estimate |
| Display blank or garbled | Wrong OLED address or not enough RAM | Check 0x3C or 0x3D, shrink the rest of the sketch |
| Uno resets when motors start | Logic and motors sharing a weak supply | Power 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.