Martin's corner on the web

Cheap DIY power monitor

My father asked me to create a standalone power monitor for him, he’d like attach it to some appliance and see its momentary and accumulated over time power consumption. Using OpenEnergyMonitor’s resources that was an easy task to do. I used a SCT-013-000 current transformer to sense the current and a 9V transformer to sense the voltage:

IMG_2278

 

I used one of the 1.8″ TFTs that I have toyed with earlier as a status display. The computing power comes from my el-cheapo Arduino compatible on veroboard that I described here. The whole thing is quite bulky because of the transformers, but would fit nicely in a project box:

IMG_2294

IMG_2288

 

IMG_2290

 

#define cs 6
#define dc 10
#define rst 8 // you can also connect this to the Arduino reset

#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library
#include 

#include "EmonLib.h"             // Include Emon Library
EnergyMonitor emon1;             // Create an instance

float accpower=0;
unsigned long lastmillis;

Adafruit_ST7735 tft = Adafruit_ST7735(cs, dc, rst);

void setup(void) {
  Serial.begin(9600);
  tft.initR(INITR_REDTAB);   // initialize a ST7735R chip, red tab

  tft.setTextWrap(false);

  tft.fillScreen(ST7735_WHITE);
  tft.setCursor(0, 0);
  tft.setTextColor(ST7735_BLACK);
  tft.setRotation(3);
  tft.setTextSize(1);
  tft.println("Starting up system..");
  tft.println("http://harizanov.com");

//  emon1.voltage(2, 234.26, 1.7);  // Voltage: input pin, calibration, phase_shift
  emon1.voltage(2, 224.26, 1.7);  // Voltage: input pin, calibration, phase_shift
  emon1.current(1, 111.1);       // Current: input pin, calibration.

 for(int i=0; i<10; i++) { 
   emon1.calcVI(20,2000);       
 }

 tft.fillScreen(ST7735_WHITE);

 tft.setCursor(0, 0);
 tft.setTextColor(ST7735_BLACK);

 tft.setTextSize(2);
 tft.println("Accum: ");
 tft.setTextSize(1); 
 tft.println("Voltage: "); 
 tft.println("Current: "); 
 tft.println("P.F.: "); 

 lastmillis=millis(); 
}

void loop() {

//  emon1.serialprint();           // Print out all variables (realpower, apparent power, Vrms, Irms, power factor)

  float realPower       = emon1.realPower;        //extract Real Power into variable
  float apparentPower   = emon1.apparentPower;    //extract Apparent Power into variable
  float powerFactor     = emon1.powerFactor;      //extract Power Factor into Variable
  float supplyVoltage   = emon1.Vrms;             //extract Vrms into Variable
  float Irms            = emon1.Irms;             //extract Irms into Variable

 tft.fillRect(70, 0 , 128, 160, ST7735_WHITE);

 tft.setTextColor(ST7735_BLACK);
 tft.setCursor(70, 0);
 tft.setTextSize(2);
 tft.print(accpower,2);  tft.print("kWh");
 tft.setTextSize(1); 
 tft.setCursor(70, 16); tft.print(supplyVoltage,0);
 tft.setCursor(70, 24); tft.print(Irms); 
 tft.setCursor(70, 32); tft.print(powerFactor); 

 tft.fillRect(0, 60 , 128, 160, ST7735_WHITE);
 tft.setCursor(0, 60);
 tft.setTextSize(4);
 tft.setTextColor(ST7735_BLUE); 
 tft.print(realPower,0);  tft.print("W");

 emon1.calcVI(20,2000);         // Calculate all. No.of half wavelengths (crossings), time-out

 accpower += (((millis()-lastmillis) * emon1.realPower) / 3600000000);
 lastmillis=millis();

 delay(2000); 
}