13 DecPower Measurement

/*
AC Power Calculations
Average Power, Apparent Power, Reactive Power, Irms, Vrms, Power Factor, Power Factor Angle
Date: Dec. 11, 2009
Line Current is measured using a current transformer from CR Magnetics.
CR8410-1000 @ http://www.crmagnetics.com/8400.pdf
Line voltage measurement via a standard AC step down transformer
Author: peter c
*/
#include <string.h>
#include <LCD4Bit.h>
#include <ACSignal.h>
#include <PowerSignal.h>
#define LCD_DISPLAY_WIDTH  16
#define LCD_DEGREE_CHAR 0xF2
#define CURRENT_BLACK_PIN 1               // current 1st 100 AMP input pin (black )
#define CURRENT_RED_PIN   3               // current 1st 100 AMP input pin (red )
#define VOLTAGEPIN 2                      // voltage signal input pin
#define DC_OFFSET 2.5                     // signal shifted 2.5 above ground
#define Te            2011                // current transformer effective turns ratio from speck sheet
#define CT_VMAX       2.5                 // maximum level shifted voltage from CT to input e.g. 7.2 v rms to 2.5 v-pp offset
#define CT_VRATED     10.1823             // Max rated RMS voltage * sqrt(2) of CT from spec sheed
#define CT_LOAD_RES   2000                // current transformer load resistor to create a voltage drop
#define MAX_SAMPLES   2000                // Samples per Calculation
#define PEAK_LINE_VOLTAGE   170           //120 * sqrt(2)
#define PEAK_VOLTAGE_TRANSFORMER   2.5    // input to A2D max AC value
#define BLACK_INDEX 0                     // offsets into array for holding power values
#define RED_INDEX   1
#define MAX_PRECISION 5
//create object to control an LCD.
//number of lines in display=1
LCD4Bit lcd = LCD4Bit(2);
ACSignal voltageSignal( VOLTAGEPIN, PEAK_LINE_VOLTAGE/PEAK_VOLTAGE_TRANSFORMER, DC_OFFSET );
ACSignal currentSignalBlack( CURRENT_BLACK_PIN, Te / CT_LOAD_RES * CT_VRATED / CT_VMAX, DC_OFFSET );
//ACSignal currentSignalRed( CURRENT_RED_PIN, Te / CT_LOAD_RES * CT_VRATED / CT_VMAX, DC_OFFSET );
PowerSignal panelBlack( voltageSignal, currentSignalBlack );
// Simplistic Float to Alhpa used for displaying floats on the LCD
// decimal is good for 1 to 5. no error checks. garbage in - garbage out.
// problem: number like 1.01 => 1.009 need to look into that later.
char *poor_ftoa( char *a_buffer, float a_number, int a_decimals )
{
  int l_decPart;
  int l_precision = a_decimals;
  char l_buffer[ MAX_PRECISION + 1];
  int l_multiplier;
  float x;
  l_multiplier = 10;
  x=a_number - (int)a_number;
  if( x < 0 )
    x *= -1;
  for( int i=0; i<a_decimals; i++ )
  {
    x  *= l_multiplier;
    l_buffer [ i ] =  '0' + (int) ( x );
    x -= (int) x;
  }
  l_buffer[ a_decimals  ] = '\0';
  sprintf(a_buffer,"%0d.%s", (int)a_number, l_buffer);
  return( a_buffer );
}
void setup()
{
  lcd.init();
  Serial.begin(9600); // start serial communication
  //debugging info. comma separated  to make it easier to import into excel
  Serial.print(  "currentSignalBlack.getDCOffset()," );
  Serial.print( "currentSignalBlack.getRMSValue( )," );
  Serial.print(  "voltageSignal.getDCOffset()," );
  Serial.print( "voltageSignal.getRMSValue()," );
  Serial.print( "l_averagePower," );
  Serial.print( "l_apparentPower," );
  Serial.print( "l_reactivePower," );
  Serial.print( "l_powerFactor," );
  Serial.print( "l_powerFactorAngle *180 / PI,"  );
  Serial.print( "Voltage Crest factor," );
  Serial.println( "CurrentBlack Crest factor," );
}
void loop()
{
  float l_sumForAveragePower[2];
  float l_averagePower[2];
  float l_apparentPower[2];
  float l_powerFactor[2];
  float l_powerFactorAngle[2];
  float l_reactivePower[2];
  voltageSignal.beginSampling();
  currentSignalBlack.beginSampling();
  panelBlack.reset();
  for( int i=0; i<MAX_SAMPLES; i++)
  {
    voltageSignal.acquireSignalSample();
    currentSignalBlack.acquireSignalSample();
    panelBlack.updateAccumulator();
  }
  voltageSignal.endSampling();
  currentSignalBlack.endSampling();
  l_averagePower[ BLACK_INDEX ] =  panelBlack.computeAveragePower();
  l_apparentPower[ BLACK_INDEX ] = panelBlack.computeApparentPower();
  l_powerFactor[ BLACK_INDEX ] = panelBlack.computePowerFactor();
  l_powerFactorAngle[ BLACK_INDEX ] = panelBlack.computePowerFactorAngle( PS_RADIANS );
  l_reactivePower[ BLACK_INDEX ] = panelBlack.computeReactivePower();
  ...
  ...
  ...

One Response to “Power Measurement”

Place your comment

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