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
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