Energy Moniotr

I’m Working on a energy monitor using an ADS115 to read the AC voltage an Current, This part seems to working good.

I’ve converted the watts in to killowatts and got tis displaying all ok, I’ve got a timer running to work out the cost of the killowatts but I’ve found a slight problem with it.

While the kWh remain stable, Like a constant 10Amps (2.45kWh) the kWh cost is all good but when I lower the current the kWh costs goes down( which is correct in away which I understand). Has the load I’m monitoring draws a small constant current while the main heater is off then draws 10amps while the heater is on. And this can be on for 2 hours or more depending how quick it heats up then the heater goes off, Now this can be 3-18hrs before it come back on.

What I would is some how display and record the total running cost no matter on the current draw change, This will be over an 5 day period. Eventually the data will be sent out to an SD card but I wan to complete it in stages first rather then run before I’ve learnt to walk kind of speak :slight_smile:

At the moment it’s only working as a killowatts calculator.

Here is my code so far, Hopefully you can understand what I’m trying to do/explain.

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <TimedAction.h>
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address
#include <EEPROMex.h>//Include EEPROMX writes float values
#include <Adafruit_ADS1015.h> //Include the libarary for 16Bit A/D converter
Adafruit_ADS1115 ads1115;  //Sets' 16bit mode
#define ADS1115_REG_CONFIG_DR_860SPS//Set A/D converter regisiters
#define VOLTS_CHAN0 0 //Cylinder Pressure voltage channel 
#define VOLTS_CHAN1 1 //Angle transducer channel 
Adafruit_ADS1115 ads;  /* Use this for the 16-bit version */
float Vmultiplier = 0.0001875F;  // used to convet readings this is calculated
const unsigned long intervaloLectura = 200;      //inervalo de lectura de sensores [milisegundos]
float P;
//####### AV VOLTS #####################
uint16_t Read_AC_volts;
float AC_volts;
float AC_volt_temp;
float AC_Volts_Result;
//####### AV AMPS #####################
uint16_t Read_AC_amps;
float AC_amps;
float AC_Amp_temp;
float AC_amps_Result;
//########################
float bill_amount = 0;   // 30 day cost as present energy usage incl approx PF
float energyTariff = 17.58; // Energy cost in INR per unit (kWh)
float cost;
float Killo_watts;
//==========================================================================================
void TimerService01();// ADC ROUTINE Timed action
TimedAction Timedact01 = TimedAction(80, TimerService01);// mS
void TimerService02();//LCD timed actions
TimedAction Timedact02 = TimedAction(250, TimerService02);// mS
long day1 = 86400000; // 86400000 milliseconds in a day
long hour1 = 3600000; // 3600000 milliseconds in an hour
long minute1 = 60000; // 60000 milliseconds in a minute
long second1 =  1000; // 1000 milliseconds in a second
unsigned long  startMillisec;
int days;
int hours = 1;
int mins, secs;
int tMins;
void setup() {
  ads.setGain(GAIN_TWOTHIRDS);  // 2/3x gain +/- 6.144V  1 bit = 3mV      0.1875mV (default)
  ads.begin();  //start the 16bit A/D converter
  lcd.begin(20, 4);


}

void loop() {
  getTime();
  Timedact01.check(); // Read ADC values
  P = AC_Volts_Result * AC_amps_Result; // convert to whats
  Killo_watts = P / 1000; // convert to killowatss
  cost =  energyTariff / 100; //set the cost of electric
  bill_amount = hours * ( Killo_watts) * cost;
  Timedact02.check(); // Display the data

}
/* === Generic routine for hours, minutes and seconds between two millis() values.===*/
void getTime() {




  unsigned long timeNow =  millis() - startMillisec;
  tMins = timeNow / minute1;

  days = timeNow / day1 ;
  hours = (timeNow % day1) / hour1 + 1;
  mins = ((timeNow % day1) % hour1) / minute1 ;
  secs = (((timeNow % day1) % hour1) % minute1) / second1;
  //  secs = ((timeNow % day1) % hour1)/ second1;//

}

//###### Read trhe ADS115
void TimerService01() {
  //############
  //# Battery V #
  //#############
  Read_AC_volts = ads.readADC_SingleEnded(VOLTS_CHAN0)  ;   // Ch.0 (3) 16bit 16bit
  AC_volts =  map(Read_AC_volts, 0, 32767, 0, 32767);
  AC_volt_temp = AC_volts * Vmultiplier;
  AC_Volts_Result =   AC_volt_temp * 50.51;
  //############
  //# amps in  #
  //############
  Read_AC_amps = ads.readADC_SingleEnded(VOLTS_CHAN1)  ;   // Ch.0 (3) 16bit 16bit
  AC_amps =  map(Read_AC_amps, 0, 32767, 0, 32767);
  AC_Amp_temp = AC_amps * Vmultiplier;
  AC_amps_Result =  AC_Amp_temp * 10.0;

}
//##Dipslay the data
void TimerService02() {
  lcd.setCursor(0, 0);
  lcd.print(AC_Volts_Result);
  lcd.print("AC ");
  lcd.print(AC_amps_Result);
  lcd.print("AMP  ");
  lcd.setCursor(0, 1);          // Displays all current data
  lcd.print(Killo_watts);
  lcd.print(" kWh HOURS");

  lcd.setCursor(0, 2);
  lcd.print(days);
  lcd.print(":");
  lcd.print(hours);
  lcd.print(":");
  lcd.print(mins); //second1
  lcd.print(":");
  lcd.print(secs); //second1
  lcd.print(" TIME");
  lcd.setCursor(0, 3);
  lcd.print(bill_amount, 3);
  lcd.print(" kWh COST");

}

The other little issue I may have just noticed is that when the minutes get to 60 it will rest to zero and the same for the hours and days, But I know this is how I’ve got it counting. But hopefully this can be sorted once I’ve got the issue above done.

Thanks
Steve

You need to get an accumulator in a convenient unit. e.g. watt seconds [Ws]

Then you need to measure the current and voltage once every second. We will assume the current does not change in your use case more often than every few seconds or a lot longer.

So, every second you get voltage[V] x current[A] x 1 [ s] = a number in [Ws], this gets added to your global accumulator value. This is all you need to calculate total cost. If you want averages, you need to store the time when you started measuring.

For displaying you convert your total [Ws] to [kwh] by dividing by 3,600,000

just to assert what Klaus said you need something like this

void accumulate()  {

static uint32_t sum;

static uint32_t prevMillis = millis();

if ( millis() - prevMillis >= 1000 ) {  // read it every one sec

prevMillis = millis();

sum += voltage * current * multiplier * 1;  // in Watts Second (Ws) , that 1 is one sec


}

}

Steveiboy:
but when I lower the current the kWh costs goes down

The kWh value can never go down (unless you return power to the grid or time runs backwards). The best that can happen is that it stops rising if you switch the appliance off.

The price per kWh depends on your contract with your electricity utility. It may vary with time of day or other factors.

...R

Robin2:
The kWh value can never go down (unless you return power to the grid or time runs backwards). The best that can happen is that it stops rising if you switch the appliance off.

The price per kWh depends on your contract with your electricity utility. It may vary with time of day or other factors.

...R

sorry I meant if I put it at 10amps current draw the kWh hours on the display £0.0444 so based on what I pay for the kWh price is correct. But if I was to lower the current to say 5 amps the kWh price goes down to £0.211 again which would be correct.

Like the others have mentioned I'm missing the accumulator so that it keeps adding the used kWh hours up which would never go down only up while current is been drawn.

I just need to try and figure and implement the accumulator part so that is just keeps adding up.

This is so I can work out roughly what it costs to run per day, week and month, All this depends on the water temperature heats up or drops to a pre set level and outside temperature makes a difference, The pump is on 24hrs a day so depending on how long the heater is on for and this makes it harder just to work out the maths side of things on paper for it.

Steveiboy:
sorry I meant if I put it at 10amps current draw the kWh hours on the display £0.0444 so based on what I pay for the kWh price is correct. But if I was to lower the current to say 5 amps the kWh price goes down to £0.211 again which would be correct.

No it would not. The price per kWh should stay the same, unless you have a very unusual contract with your electricity utility.

Rather than use amps in some places and kW and kWh in other places you will be less likely to make mistakes if you only use kW and kWh.

If 10 amps = 2.45kW (Note, especially it is NOT kWh), then 5 amps would be 1.225 kW. Drawing 2.45kW continuously for 1 hour uses up 2.45 kWh. Drawing 1.225kW continuously for 1 hour uses up 1.225 kWh.

...R

Robin2:
No it would not. The price per kWh should stay the same, unless you have a very unusual contract with your electricity utility.

Rather than use amps in some places and kW and kWh in other places you will be less likely to make mistakes if you only use kW and kWh.

If 10 amps = 2.45kW (Note, especially it is NOT kWh), then 5 amps would be 1.225 kW. Drawing 2.45kW continuously for 1 hour uses up 2.45 kWh. Drawing 1.225kW continuously for 1 hour uses up 1.225 kWh.

...R

Sorry Robin I understand that the kWh is the same price which is Eg. 17.58 pence per kWh and does not go up/down depending on Kw been drawn. so I f I was to run it at 2.4kW it would of cost me 0.82 pence to run and it ran for another 2 hours at 2.4Kw the cost would be £1.63 in total and if it ran for another 2 hours at 1.25kW the cost of this 2 hour period would be 85 pence this then should be added to the £1.63 which would be £2.48 but as it stands and the way the codes running at the moment it's only showing what the cost would be per kWh depending on how much kW is been drawn.
I'm trying to sort out the total kWh's that have been used over a period of time.

Hopefully I've explained it a bit better on what my problem is

Thanks
Steve

2.45 kW for 2 hours = 4.9 kWh @ 17.58p / kWh = 86.142p

1.25 kW for 2 hours = 2.5 kWh @ 17.58p = 43.95p

Or, just looking at the total kWh you would have 7.4 kWh @ 17,58p = £1.30092

If you want to accumulate the total kWh then you should sample the kW at a regular interval (perhaps every second) and at then accumulate those values as kWs. Later you can divide by 3600 to get kWh.

...R