Energey meter using SCT013 non-invasive current sensor

I've ditched the ADS115 method as it did not work and started with the basic's.

When I was just using a potentiometer to set the current and set a timer to change the value using the ADS115 so I could make sure that I was counting the kWh hours correctly and this was working really well.

But now I've changed to SCT013-000 100amp senor and using the EmonLib , I've got it reading the correct current reading give or take .7 amps or so.

But now the calculation of the kWh readings seem to be out using the calculations as the ADS115, On setting up some debugging code to test I found that my time variable is running slower that it should.

With this line highlighted out

RMSCurrent = emon1.calcIrms(1480);// TIME 33 , SECONDS:11 with this in

The time counter is 197 running for 10 seconds and with it in the code the Time counter only gets to 33, I think it may be something to do with how the RMSCurrent = emon1.calcIrms(1480) conversion ?

Here is my code just in case it's the way I have done it that is screwing things up.

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include "EmonLib.h"             // Include Emon Library
#define CURRENT_CAL 58.633 // Calculated and calibrated
EnergyMonitor emon1;             // Create an instance
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address

//########################################
//########################
float kilos = 0;
int peakPower = 0;
unsigned long time = 0; //may be 4
unsigned long previousMillis = 0;
float kWh = 0;
float traiff  = 18.36;
float costing = 0;
float msecout = 0;
float samplein = 0;
unsigned long msecin = 3;
double timein = 0;
double AC_power = 0;
double averageamps_AC = 0;
double ampsecondsin_AC = 0;
double RMSCurrent = 0;
double RMSPower;
bool flag = false;
//==========================================================================================

void setup() {
  Serial.begin(9600); //Open software serial port at 9600bps
  lcd.begin(20, 4);
  emon1.current(0, CURRENT_CAL);       // Current: input pin, calibration.
  lcd.clear();
  delay(1000);
}

void loop() {
  // ########################################################################
  // With this line taken out the conuter is much faster                    #
  RMSCurrent = emon1.calcIrms(1480);// TIME 33 , SECONDS:11 with this in    #
  // With line added TIME 33 , SECONDS:11 with this in                      #
  // with the line RMS current highlighted out TIME 197 , SECONDS:11        #
  //#########################################################################
  RMSPower = 240.0 * RMSCurrent;    //Calculates RMS Power Assuming Voltage 220VAC, change to 110VAC accordingly  #
  time ++;// increase the time
  msecin = millis();// use mills
  timein = msecin / 1000;// devide by 1000 to turn into seconds
  AC_power = AC_power + RMSPower; // add them together
  averageamps_AC = AC_power / time;//work out the avergae current draw
  ampsecondsin_AC = averageamps_AC * timein; //work out the average reading with time
  kilos  = ampsecondsin_AC / 3600;// convert into watt hours
  kWh = kilos / 1000.00; // convert it into kWh hours
  costing =  kWh * traiff / 100.00;// Calculate the rough cost to run the heater
  ///#### Just added for debugging timing issue
  if (timein > 10 & flag == false)
  {

    Serial.print("TIME ");
    Serial.print(time);
    Serial.print(" , SECONDS:");
    Serial.println(timein, 0);
    flag = true;
  }
  // Print the data
  lcd.setCursor(0, 0);          // Displays all current data
  lcd.print(RMSCurrent);
  lcd.print("A");
  //lcd.setCursor(9, 0);          // Displays all current data
  //lcd.print(Irms);
  lcd.setCursor(0, 1);
  lcd.print(traiff);
  lcd.setCursor(0, 1);
  lcd.print(kilos, 0);
  lcd.print(" WWh   ");
  lcd.setCursor(10, 1);
  lcd.print(RMSPower);
  lcd.print("W ");
  lcd.setCursor(0, 2);
  lcd.print(kWh);
  lcd.print(" kWh");
  lcd.setCursor(9, 2);
  lcd.print(costing, 3);
  lcd.print(" T ");
  lcd.setCursor(0, 3);
  lcd.print(time);
  lcd.setCursor(10, 3);
  lcd.print(timein, 0);;
}

Any pointer to help solve or speed it up would grateful

Steve

Of course it takes longer to run code than not. The way to call that function, you are asking for 1480 samples which means at least that many analogReads() plus some math.

Did you look at the example code that comes with the library? It is much simpler.

Also, your 'time' variable has nothing at all to do with time, it is just a loop counter that is incremented by 1 each time through the loop. Poor name choice.

I can change the time counter to another word, The seconds counter seems to work fine it's just the counter that is slower which I guess is due to how many samples been taken.

Is there away that I can try and stop it effecting the counter loop from slowing down ?
Yes I did look in the examples and these are the ones that I've got.

voltage and current example.

// EmonLibrary examples openenergymonitor.org, Licence GNU GPL V3

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

void setup()
{  
  Serial.begin(9600);
  
  emon1.voltage(2, 234.26, 1.7);  // Voltage: input pin, calibration, phase_shift
  emon1.current(1, 111.1);       // Current: input pin, calibration.
}

void loop()
{
  emon1.calcVI(20,2000);         // Calculate all. No.of half wavelengths (crossings), time-out
  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
}

Current only example.

// EmonLibrary examples openenergymonitor.org, Licence GNU GPL V3

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

void setup()
{  
  Serial.begin(9600);
  
  emon1.current(1, 111.1);             // Current: input pin, calibration.
}

void loop()
{
  double Irms = emon1.calcIrms(1480);  // Calculate Irms only
  
  Serial.print(Irms*230.0);	       // Apparent power
  Serial.print(" ");
  Serial.println(Irms);		       // Irms
}

Steveiboy:
I can change the time counter to another word, The seconds counter seems to work fine it's just the counter that is slower which I guess is due to how many samples been taken.

Is there away that I can try and stop it effecting the counter loop from slowing down ?

I am confused. Why do you need your counter to run faster? If you code is off measuring 1480 samples, that will take time. The millis() function uses a timer interrupt to keep track of time regardless of what your code is doing.

I think what you should be doing is measuring the time both before and after that calculation and then use that duration in your calculations so you get current and power for that time slice.

blh64:
I am confused. Why do you need your counter to run faster? If you code is off measuring 1480 samples, that will take time. The millis() function uses a timer interrupt to keep track of time regardless of what your code is doing.

I think what you should be doing is measuring the time both before and after that calculation and then use that duration in your calculations so you get current and power for that time slice.

It’s not that I want it to count faster, due to the amount of samples that is been taken it as slowed down the counter which is making the kHw readings lag behind, so I just need to work out which is the best way to achieve it as I tried before doing the time before and after reading but failed