/*
/*
PowerSignal.h - A simplistic way to represent a power signal for AC power monitoring
Author: peter c
*/
#ifndef PowerSignal_h
#define PowerSignal_h
#include "WProgram.h"
#include "ACSignal.h"
#define PS_DEGREES 1
#define PS_RADIANS 2
class PowerSignal
{
public:
PowerSignal(ACSignal& aVoltageSignal, ACSignal& aCurrentSignal);
void setPercentFromCoal( float aPercentFromCoal );
void setLbsOfCO2PerKWH( float aLbsOfCO2PerKWH );
void setAverageCostPerKWH( float aAverageCostPerKWH );
float computeApparentPower();
double computeAveragePower();
float computePowerFactor();
float computePowerFactorAngle( int aMode );
float computeReactivePower();
void beginSampling();
void updateAccumulator();
void endSampling();
double getKiloWattsHrs();
void resetTotalizers();
unsigned long getDeltaT(); // time since between updates in ms
// char* toString( char *aBuffer );
// char* toDbgString( char* aBuffer );
private:
ACSignal& mVoltageSignal;
ACSignal& mCurrentSignal;
double mSumVoltageTimesCurrent;
unsigned long mPreviousSampleTime;
short int mSignalSampled;
unsigned long mDeltaT;
double mAccumulatedkWHr;
float mPercentFromCoal;
float mLbsCO2PerKWH;
float mAvgCostPerKWH;
};
#endif
Class Body
/*
PowerSignal.cpp - Library doing basic signal calculations
Created by Peter Chrapchynski, December 11, 2009
*/
#include "WProgram.h"
#include "ACSignal.h"
#include "PowerSignal.h"
#define PS_TRUE 1
#define PS_FALSE 0
PowerSignal::PowerSignal(ACSignal& aVoltageSignal, ACSignal& aCurrentSignal):mVoltageSignal( aVoltageSignal ), mCurrentSignal( aCurrentSignal )
{
mSignalSampled = PS_FALSE;
mAccumulatedkWHr = 0;
mDeltaT = 0;
}
void PowerSignal::resetTotalizers()
{
mAccumulatedkWHr = 0.0;
}
float PowerSignal::computeApparentPower()
{
return ( mVoltageSignal.getRMSValue() * mCurrentSignal.getRMSValue() );
}
float PowerSignal::computePowerFactor()
{
float l_powerFactor = 1.0;
float l_apparentPower = computeApparentPower();
if( l_apparentPower > 0.01 )
l_powerFactor = computeAveragePower() / l_apparentPower;
return( l_powerFactor );
}
float PowerSignal::computePowerFactorAngle( int aMode )
{
float l_PowerFactorAngle = acos( computePowerFactor() );
if( aMode == PS_DEGREES )
l_PowerFactorAngle *= 180 / PI;
return( l_PowerFactorAngle );
}
float PowerSignal::computeReactivePower()
{
return( computeApparentPower() * sin( computePowerFactorAngle( PS_RADIANS ) ) );
}
void PowerSignal::beginSampling()
{
mSumVoltageTimesCurrent = 0;
}
void PowerSignal::endSampling()
{
unsigned long l_t;
if( mSignalSampled == PS_TRUE )
{
l_t = millis();
mDeltaT = l_t - mPreviousSampleTime;
mAccumulatedkWHr += computeAveragePower() / 3600.0 /1000.0 * mDeltaT / 1000.0 ;
mPreviousSampleTime = l_t;
}
else
{
mSignalSampled = PS_TRUE;
mPreviousSampleTime = millis();
}
}
void PowerSignal::updateAccumulator()
{
mSumVoltageTimesCurrent += mVoltageSignal.getInstantaneousValue() * mCurrentSignal.getInstantaneousValue();
}
double PowerSignal::computeAveragePower()
{
return( mSumVoltageTimesCurrent / mVoltageSignal.getSampleCount() );
}
unsigned long PowerSignal::getDeltaT()
{
return( mDeltaT );
}
double PowerSignal::getKiloWattsHrs()
{
// return(1001);
return( mAccumulatedkWHr );
}