DIY Power Meter project by using Arduino Pro Mini

Introduction

Hello, electronics community! Today I will present you a project which lets you measure the voltage and current of an appliance, and display it together with the power and energy values.

A current/Voltage measuring

If you wanted to measure voltage and current of a circuit with an Arduino, the procedure is pretty straight forward. You use the analog input to measure the voltage across the load and use a shunt to measure the current via the voltage drop of the shunt resistor. Now, this method is rather crude, and it works only for voltages within 0-5 V, and the ADC of the Arduino which is used to read the voltage drop of the resistor is a bit inaccurate for measuring hundreds of mV only which will drop across the shunt. Luckily, there are modules out there, which make our lives easier. For this project, I will be using an INA219 IC, which uses a 0.1R resistor as a shunt and can measure voltages up to 32V, and has a current range of 0-3.2A.

This IC offers an I2C interface, to communicate with the Arduino, and by studying the datasheet, we can use specific commands over the I2C interface, in order to read the voltage and current values. We are lucky again because we don’t have to go through that trouble. There are libraries from Adafruit which you can download, and use premade functions to read the voltage and current | Click Here To Download Library

OLED Display

The next component which I will be using is a display. This way we can actually display the values we’re measuring. I have been working with the “96 inch OLED display for a while now, and it works beautifully. We can use the already made Adafruit library once again in order to send data we want to show on the display | Click Here To Download Adafruit library | you will also need the Adafruit GFX library.

SD Card reader

Now, to make this project complete, we will add a final component. A micro SD card reader, in order to store the measured data as text files, from where you can copy them into a program like Excel to make nice looking plots, and calculate the power and energy used, by multiplying the current and voltage with the time respectively.  This module communicates via an SPI interface, which also uses commands to write/read data. This module is not 5V compatible, so we cannot just wire it up to the Arduino interface since the 5V will destroy the 3.3V chip. For that, I made voltage dividers out of resistors to drop the 5V signals to appropriate 3.3V signals for the chip (MOSI, CS and CLK lines respectively and to drop down the 5V to 3.3V to power the module).

Functional principle

Finally, we program the Arduino using the Adafruit library for the INA219 module, to read the voltage and current values. Furthermore, we multiply current with the voltage in order to obtain the power used. Then, we can use the milis() function to store the time passed, and multiply it with the power, in order to calculate the energy that has been used. For the SD card reader, I used the “SdFat” library, because the standard SD libraries from Arduino didn’t work that well | Click Here To Download Sdfat Library

You can power the board using the DC jack and by applying a voltage between 7 and 12V to the Arduino, which powers the other components via the 5V VCC.

Schematic Diagram:

Source Code:

#include <Wire.h>
#include <Adafruit_INA219.h>
#include <Adafruit_SSD1306.h>
#include <Fonts/FreeMono9pt7b.h>
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
Adafruit_INA219 ina219;
#include "SdFat.h"
SdFat SD;

File TimeFile;
File VoltFile;
File CurFile;

unsigned long previousMillis = 0;
unsigned long interval = 100;
const int chipSelect = 10;
float shuntvoltage = 0;
float busvoltage = 0;
float current_mA = 0;
float loadvoltage = 0;
float energy = 0;



void setup() {
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  ina219.begin();
  
  SD.begin(chipSelect);
}

void loop() {
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval)
  {
    previousMillis = currentMillis;
    ina219values();
    TimeFile = SD.open("TIME.txt", FILE_WRITE);
    if (TimeFile) {
      TimeFile.println(currentMillis);
      TimeFile.close();
    }

    VoltFile = SD.open("VOLT.txt", FILE_WRITE);
    if (VoltFile) {
      VoltFile.println(loadvoltage);
      VoltFile.close();
    }

    CurFile = SD.open("CUR.txt", FILE_WRITE);
    if (CurFile) {
      CurFile.println(current_mA);
      CurFile.close();
    }
    displaydata();
  }
}

void displaydata() {
  display.clearDisplay();
  display.setTextColor(WHITE);
//  display.setTextSize(1);
  display.setFont(&FreeMono9pt7b);
  display.setCursor(0, 10);
  display.println(loadvoltage,1);
  display.setCursor(45, 10);
  display.println("V");
  

if(current_mA > 1000){
  display.setCursor(0, 25);
  display.println(current_mA/1000,2);
  display.setCursor(50, 25);
  display.println("A");
}
else{
  display.setCursor(0, 25);
  display.println(current_mA);
  display.setCursor(65, 25);
  display.println("mA");
}

if( ((loadvoltage*current_mA) > (1000-10)) ){
display.setCursor(0, 45);
  display.println(loadvoltage * current_mA/1000);
  display.setCursor(60, 45);
  display.println("W");
}
else{
  display.setCursor(0, 45);
  display.println(loadvoltage * current_mA);
  display.setCursor(85, 45);
  display.println("mW");
}
if(energy >900){
  display.setCursor(0, 60);
  display.println(energy/1000);
  display.setCursor(65, 60);
  display.println("Wh");
}
else{
   display.setCursor(0, 60);
  display.println(energy);
  display.setCursor(65, 60);
  display.println("mWh");
}
  display.display();
}

void ina219values() {
  shuntvoltage = ina219.getShuntVoltage_mV();
  busvoltage = ina219.getBusVoltage_V();
  current_mA = ina219.getCurrent_mA();
  loadvoltage = busvoltage + (shuntvoltage / 1000);
  energy = energy + loadvoltage * current_mA / 3600;
}


PCB Arrived:

A sponsor of this project

The sponsor of this project is PCBGOGO which delivered us 10 PCB’s for this project.  PCBGOGO produce high-quality PCBs in a very short time and delivers them very quick too. So, if you are thinking of making your project professional, don’t hesitate to upload your Gerber files to PCBGOGO to receive 10 PCBs for a very low price.


Project Video Demonstration


Related posts

Arduino Opta PLC Pros & Cons

Breakthrough of Ardino-Pro Opta: Micro-PLC with industrial IoT proficiency

Top Arduino sensors – the ultimate list 2021

2 comments

pcba May 22, 2019 - 10:54 am

yes ,That is very cool

Brother Maff March 13, 2020 - 12:27 am

@Robert Poloboc: Magnificent piece of Arduino artistry (and the proto boards look simply amazing)!

Add Comment