How to use INA219 current sensor with arduino and Make DIY wattmeter with it

If you want sense electric DC current, then you will have some current sensors options. The current sensor can vary depends on what needed. We can decide which sensor to use based on its capability to sense the current. In this tutorial we will learn how to use INA219.

INA219 current sensor
INA219 current sensor

So why INA219?

In my opinion, INA219 is accurate sensor that can sense current to miliampere. It’s a huge different than ACS712, which is can only sense stable current at about 500mA without op amp or ampilifer. Besides current this sensor can sense the voltage too.

So if you want to sense an Direct Current (DC) with high accuracy and voltage too, I suggest you to use this sensor. It has cheap price too. So here’s the short specification of this sensor.

  • 0.1 ohm 1% 2W current sense resistor
  • Up to +26V target voltage
  • Up to ±3.2A current measurement, with ±0.8mA resolution
  • 0.9″ x 0.8″ PCB
  • PCB (no header or terminal block): 1.9g

INA219 and Arduino Wiring Diagram

INA219 current sensor wiring with arduino
INA219 current sensor wiring with arduino
Arduino and INA219 current sensor pin mapping
Arduino and INA219 current sensor pin mapping

In picture above, that is the wiring diagram of INA219 and arduino. Like usual, I2C sensor can easily interfaced with arduino. It uses 4 pins only. And there a load that connect to the sensor. So this sensor will sense current and voltage at the load.

Library and Code

This sensor need library called adafruit INA219. You can download the library here. We can use the code example straight from library without any modification to sense the current, voltage even the power. The file example name is getcurrent. Or you can copy the code below.

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

Adafruit_INA219 ina219;


void setup(void) 
{
  Serial.begin(115200);
  while (!Serial) {
      // will pause Zero, Leonardo, etc until serial console opens
      delay(1);
  }

  uint32_t currentFrequency;
    
  Serial.println("Hello!");
  
  // Initialize the INA219.
  // By default the initialization will use the largest range (32V, 2A).  However
  // you can call a setCalibration function to change this range (see comments).
  if (! ina219.begin()) {
    Serial.println("Failed to find INA219 chip");
    while (1) { delay(10); }
  }
  // To use a slightly lower 32V, 1A range (higher precision on amps):
  //ina219.setCalibration_32V_1A();
  // Or to use a lower 16V, 400mA range (higher precision on volts and amps):
  //ina219.setCalibration_16V_400mA();

  Serial.println("Measuring voltage and current with INA219 ...");
}

void loop(void) 
{
  float shuntvoltage = 0;
  float busvoltage = 0;
  float current_mA = 0;
  float loadvoltage = 0;
  float power_mW = 0;

  shuntvoltage = ina219.getShuntVoltage_mV();
  busvoltage = ina219.getBusVoltage_V();
  current_mA = ina219.getCurrent_mA();
  power_mW = ina219.getPower_mW();
  loadvoltage = busvoltage + (shuntvoltage / 1000);
  
  Serial.print("Bus Voltage:   "); Serial.print(busvoltage); Serial.println(" V");
  Serial.print("Shunt Voltage: "); Serial.print(shuntvoltage); Serial.println(" mV");
  Serial.print("Load Voltage:  "); Serial.print(loadvoltage); Serial.println(" V");
  Serial.print("Current:       "); Serial.print(current_mA); Serial.println(" mA");
  Serial.print("Power:         "); Serial.print(power_mW); Serial.println(" mW");
  Serial.println("");

  delay(2000);
}

Upload the code to arduino and when you open the serial monitor you should see the Bus Voltage, Shunt Voltage, Load Voltage, Current and Power.

Now we will try to give the sensor a load, we will use an LED as a load.

INA219 wiring with arduino and LED as a load

In this example we will use an LED as a load, and will sense the current and voltage at LED. So the wiring diagram become like this

INA219 current sensor wiring with arduino and LED as a load
INA219 current sensor wiring with arduino and LED as a load

Open the Serial monitor again and now you should see the Load Voltage about 3.7V and current about 70mA. The current will depends on the load we use. In this example, the LED draw about 70mA of current.

DIY Wattmeter with INA219 and Arduino

We have successfully use INA219 to measure the current and voltage. Now how if we display the current, voltage and power to an OLED display so it will looks interesting and we can call it a wattmeter!

DIY Wattmeter wiring

Wattmeter wiring, arduino INA219 and OLED display
Wattmeter wiring, arduino INA219 and OLED display

DIY Wattmeter Arduino Code

#include <Wire.h>
#include <Adafruit_INA219.h>
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Fonts/FreeSerifItalic12pt7b.h>

Adafruit_INA219 ina219;

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
float current_mA = 0;
float loadvoltage = 0;
float power_mW = 0;

void setup(void)
{
  Serial.begin(115200);
  while (!Serial) {
    // will pause Zero, Leonardo, etc until serial console opens
    delay(1);
  }
  uint32_t currentFrequency;

  if (! ina219.begin()) {
    Serial.println("Failed to find INA219 chip");
    while (1) {
      delay(10);
    }
  }

  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
    Serial.println(F("SSD1306 allocation failed"));
    for (;;); // Don't proceed, loop forever
  }
  // Clear the buffer
  display.clearDisplay();
  Serial.println("Measuring voltage and current with INA219 ...");
}

void loop(void)
{
  float shuntvoltage = 0;
  float busvoltage = 0;
  current_mA = 0;
  loadvoltage = 0;
  power_mW = 0;

  shuntvoltage = ina219.getShuntVoltage_mV();
  busvoltage = ina219.getBusVoltage_V();
  current_mA = ina219.getCurrent_mA();
  power_mW = ina219.getPower_mW();
  loadvoltage = busvoltage + (shuntvoltage / 1000);

  Serial.print("Load Voltage:  "); Serial.print(loadvoltage); Serial.println(" V");
  Serial.print("Current:       "); Serial.print(current_mA); Serial.println(" mA");
  Serial.print("Power:         "); Serial.print(power_mW); Serial.println(" mW");
  Serial.println("");
  display.clearDisplay();
  voltCurrent();
  delay(2000);
  display.clearDisplay();
  powerr();
  delay(2000);
}

void voltCurrent() {
  display.setFont();
  display.setTextSize(2); // Draw 2X-scale text
  display.setTextColor(WHITE);
  display.setCursor(0, 0);            // Start at top-left corner
  display.print(loadvoltage);
  display.print("V");
  display.setCursor(0, 18);
  display.print(current_mA);
  display.print("mA");
  display.display();
}

void powerr() {
  display.setFont(&FreeSerifItalic12pt7b);
  display.setTextSize(1); // Draw 2X-scale text
  display.setTextColor(WHITE);
  display.setCursor(0, 20);            // Start at top-left corner
  display.print(power_mW);
  display.print("mW");
  display.display();
}

Upload the code, and now you should see the Voltage and current on OLED display and power consecutively. Here’s the result.

You can see the full video tutorial on my YouTube channel below