13 DecACSignal

Class Header
/*
 ACSignal.h - A simplistic way to represent a AC signal for AC AC monitoring
 Author: peter c
*/
#ifndef ACSignal_h
#define ACSignal_h

#include "WProgram.h"

#define PS_VOLTS_PER_STEP   0.0048887       // 10 bit A2D (5/1023)
#define PS_DEFAULT_DC_OFFSET 2.5             // AC signal wil be likely 2.5 +/- 2.5
#define PS_PWR_CALC_ERR     -1;
#define PS_SCALING_DEFAULT 1
#define PS_DEFAULT_PORT 1

class ACSignal
{
 public:
   ACSignal();
   ACSignal(int aPin);
   ACSignal(int aPin, float aScalingValue);
   ACSignal(int aPin, float aScalingValue, float aDCOffset);
   void beginSampling();
   void endSampling();
   float acquireSignalSample();

   // AC signal is offset by DC value. typically half-way markt of 0-5 volts
   void setDCOffset( float aDCOffset );        
   // this is the scaling value used to convert voltage to desired units
   void setScalingValue( float aScalingValye ); 

   float getDCOffset();
   // return the value of last read sample in scaled units. e.g. amps
   float getInstantaneousValue();              
   float getMaxValue();
   float getMinValue();

   float getRMSValue();               // return RMS value of signal
   // this is the scaling value used to convert voltage to desired units
   float getScalingValue();          
   float getCrestFactor();            // compute crest factor ration of peak to RMS
   float getCurrentVoltage();        // return current voltage read from input (0-5 v)
   // return number of samples taken since beginSample();
   int getSampleCount();             
   int getCurrentSampleValue();     // return current sample 0-1023

private:
   void init( int aPin, float aScalingValue, float aDCOffset );

 private:
   int   mPin;
   float mMax;
   float mMin;
   float mAverage;
   float mCurSample;
   int   mcurValue;
   float mScalingValue;
   int   mSampleCount;
   float mSumVoltageRaw;
   float mRealVoltage;
   float mSumVoltageSquared;
   float mCurVoltage;
   float mDCOffset;
};

#endif

Class Body 

/*
ACSignal.cpp - Library doing basic signal calculations
Created by Peter C, December 11, 2009
*/

#include "WProgram.h"
#include "ACSignal.h"

ACSignal::ACSignal()
{
  init(  PS_DEFAULT_PORT,  PS_SCALING_DEFAULT,  PS_DEFAULT_DC_OFFSET );
}

ACSignal::ACSignal(int aPin)
{
  init(  aPin,  PS_SCALING_DEFAULT,  PS_DEFAULT_DC_OFFSET );
}

ACSignal::ACSignal(int aPin, float aScalingValue)
{
  init(  aPin,  aScalingValue,  PS_DEFAULT_DC_OFFSET );
}

ACSignal::ACSignal(int aPin, float aScalingValue, float aDCOffset)
{
  init(  aPin,  aScalingValue,  aDCOffset );
}

float ACSignal::getRMSValue()
{
  float lRMSValue = PS_PWR_CALC_ERR;

  if( mSampleCount > 0 )
    lRMSValue = sqrt( mSumVoltageSquared / mSampleCount );

  return( lRMSValue );
}

void ACSignal::init( int aPin, float aScalingValue, float aDCOffset )
{
  mPin = aPin;
  pinMode( mPin, INPUT);
  mScalingValue = aScalingValue;
  mDCOffset = aDCOffset;
}

int ACSignal::getCurrentSampleValue()
{
  return( mCurSample );
}

float ACSignal::acquireSignalSample()
{
  float lVal;

  mCurSample = analogRead( mPin )  ;
  mCurVoltage = mCurSample * PS_VOLTS_PER_STEP;
  mSampleCount++;
  mSumVoltageRaw += mCurVoltage;
// remove DC offset from circuit voltage divider
  mRealVoltage = mCurVoltage - mDCOffset;
  lVal = getInstantaneousValue();
  mSumVoltageSquared +=  lVal * lVal;

  if( lVal > mMax )
    mMax = lVal;

  if( lVal < mMin )
    mMin = lVal;

  return( lVal );
}

float  ACSignal::getCrestFactor()
{
  return( getMaxValue()/getRMSValue() );
}

float ACSignal::getDCOffset()
{
  return( mDCOffset );
}

void ACSignal::setDCOffset( float aDCOffset )
{
  mDCOffset = aDCOffset;
}

float ACSignal::getInstantaneousValue()
{
  return( mRealVoltage * mScalingValue );
}

float ACSignal::getCurrentVoltage()
{
  return( mCurVoltage );
}

void ACSignal::setScalingValue( float aScalingValue )
{
  mScalingValue = aScalingValue;
}

float ACSignal::getMaxValue()
{
  return( mMax );
}

float ACSignal::getMinValue()
{
  return( mMin );
}

int ACSignal::getSampleCount()
{
  return( mSampleCount );
}

float  ACSignal::getScalingValue()
{
  return( mScalingValue );
}

void ACSignal::beginSampling()
{
  mSampleCount = 0;
  mSumVoltageRaw =0.0;
  mSumVoltageSquared =0.0;;
  mMax = 0;
  mMin = 0;
}

void ACSignal::endSampling()
{
  if( mSampleCount > 0 )
    mDCOffset = mSumVoltageRaw / mSampleCount;
}

One Response to “ACSignal”

  1. [...] ended creating two classes: ACSignal to help capture and compute some basic stuff like average, RMS values. The PowerSignal class takes [...]

Place your comment

Please fill your data and comment below.
Name
Email
Website
Your comment