Calculating the RMS of the fundamental component from an unknown periodic signal sampled every 50μs poses challenges, particularly in defining "real-time" measurements. The RMS value is meaningful only over complete cycles, and sudden changes in the signal can lead to misleading results if not properly filtered. Establishing the frequency of the signal can simplify the process, allowing for more accurate filtering and analysis. A rolling mean approach could be used, but it risks introducing noise and ambiguity in the results. Ultimately, a clear understanding of the signal's characteristics and a well-defined measurement strategy are essential for accurate RMS calculations.
hmmmm, RMS you say ?
you square most recent of the individual readings, then a new mean of all your accumulated squares, then take square root of that mean ?
I suppose one could , every 50 usec, do something akin to that
Yes, ... but no. That would give the RMS of the signal, but OP does not want that. Rather, it's the RMS of the fundamental component in the signal that is being sought. The harmonics and noise need first be discarded.
Because it may also be used in some controls applications where the frequency of the input signal is not 60 or 50 +- 0.1 Hz.
If that spec was fixed, it would eliminate the need for some sort of adaptive self-tuning filter, something which will take multiple cycles to establish.
I need the fundamental component. The reason I was given is that this is a commonly used index in a variety of applications.
If that spec was fixed, it would eliminate the need for some sort of adaptive self-tuning filter, something which will take multiple cycles to establish.
Sorry NascentOxygen, but I haven't been given any information regarding the percentage of maximum power contained within the fundamental.
#35
jegues
1,085
3
Here's my first attempt at writing some code. I'll show the header file followed by the actual code file.
Header file:
Code:
/* DO NOT EDIT THIS FILE */
MODEL_TYPE: CTL
#define PI 3.1415926535897932384626433832795 // definition of PI
#define TWOPI 6.283185307179586476925286766559 // definition of 2.0*PI
#define E 2.71828182845904523536028747135266 // definition of E
#define EINV 0.36787944117144232159552377016147 // definition of E Inverse (1/E)
#define RT2 1.4142135623730950488016887242097 // definition of square root 2.0
#define RT3 1.7320508075688772935274463415059 // definition of square root 3.0
#define INV_ROOT2 0.70710678118654752440084436210485
INPUTS:
double NA;
double NB;
double NC;
double N1;
OUTPUTS:
double Out;
PARAMETERS:
int Mode; //Operation Mode
int pu; //Scale Output to per unit?
double Sc; //Rated L-L (3Ph) or L-N (1Ph) Input
int LL; //For 3 Phase display output as
int unit; //Units to display on meter
int solMethod; //Single Phase Solution Method
double fn; //Nominal Frequency of Input Signal
Component Code:
Code:
VERSION:
3.001
/* Include file below is generated by C-Builder */
/* and contains the variables declared as - */
/* PARAMETERS, INPUTS, OUTPUTS . . . */
#include "myRMSwfund.h"
STATIC:
/* ----------------------------------------------- */
/* Variables declared here may be used in both the */
/* RAM: and CODE: sections below. */
/* ----------------------------------------------- */
/* double dt; */
///////////////////////////////////////////////////////
double dt;
double T;
double integral;
int numdt;
int index;
int i;
int N;
double inputSamples[8];
int dtSampleDivisor;
int currSampleIndex;
double ReX;
double ImX;
double WR1[8];
double WI1[8];
double C1;
//////////////////////////////////////////////////////
/* - E n d o f S T A T I C : S e c t i o n - */
RAM_FUNCTIONS:
/* ----------------------------------------------- */
/* This section should contain any 'c' functions */
/* to be called from the RAM section (either */
/* RAM_PASS1 or RAM_PASS2). Example: */
/* */
/* static double myFunction(double v1, double v2) */
/* { */
/* return(v1*v2); */
/* } */
/* ----------------------------------------------- */
///////////////////////////////////////////////////////////////////////
static int round(double num){
int temp;
if (num > 0)
temp = (int)floor(num + 0.5);
else
temp = (int)ceil(num - 0.5);
return temp;
}
///////////////////////////////////////////////////////////////////////
RAM:
/* ----------------------------------------------- */
/* Place C code here which computes constants */
/* required for the CODE: section below. The C */
/* code here is executed once, prior to the start */
/* of the simulation case. */
/* ----------------------------------------------- */
/* dt= getTimeStep(); */
/////////////////////////////////////////////////////////////
dt= getTimeStep();
T = 1/fn;
numdt = round(T/dt);
index = 1; //Should index start at 1 or 0?
integral = 0;
ReX = 0;
ImX = 0;
N = 8;
currSampleIndex = 0;
dtSampleDivisor = trunc(numdt/N);
C1 = 2.0/N;
for (i = 0; i < N; i++){
WR1[i] = C1*cos((TWOPI/N)*i);
WI1[i] = C1*sin((TWOPI/N)*i);
}
/////////////////////////////////////////////////////////////
/* ---- E n d o f R A M : S e c t i o n ---- */
CODE:
/* ----------------------------------------------- */
/* Place C code here which runs on the RTDS. The */
/* code below is entered once each simulation */
/* step. */
/* ----------------------------------------------- */
//double rms3Ph(float nodeA, float nodeB, float nodeC, double scale)
if(index > numdt){ //If it has been a full cycle of the input, reset indices
index = 1;
currSampleIndex = 0;
}
if(index % dtSampleDivisor == 0){ //If it's time to take a sample, take one and compute the Re and I am parts in f domain
ReX = 0;
ImX = 0;
inputSamples[currSampleIndex] = N1;
for(i = 0; i < N; i++){
ReX = ReX + inputSamples[i]*WR1[i];
ImX = ImX - inputSamples[i]*WI1[i];
}
currSampleIndex++;
Out = sqrt(ReX*ReX + ImX*ImX)/sqrt(2);
}
index++;
/* ---- E n d o f C O D E : S e c t i o n --- */
Here is the test case I've developed for the testing of fundamental RMS component. As you can see I generate three sinusoidal harmonics and add them together to create my input signal.
Here are the simulation results, Legend:
Input - Input Signal
fRMSOutput - Fundamental RMS component output
tRMSOutput - Regular RMS component output (computes the total RMS)
With a short simulation time (0.2s) we observe the following waveforms,
From these results I'm thinking the smaller deviations visible in the short simulation time results are because the samples aren't being taken at the same points each cycle. This is happening because the peroid of the waveform does not fit into an integer multiple of timesteps.
Another weird result I found is that with the fundamental frequency set to 60Hz (i.e. not an integer multiple of the timestep) if I increase the number of samples per cycle from 8 to 32 the deviations disappear completely, but the results still aren't entirely accurate.
If you don't know about the noise, then whatever you calculate may be completely meaningless.
Your simulation seems to assume that the signals are sinusoidal and of fixed frequency, which contradicts what you say about lack of knowledge about the signals.
I see don't see in the code where you are taking the mean (average) of the squares of all the samples in one or more whole cycles. RMS means square root of the MEAN of the squares. Did you understand that part?
You also never answered the question about what the application is. Please don't post again until you answer that.
Your earlier answer as to why fundamental component sounds bogus.
I think that you and perhaps the person giving you the requirements are in over your heads. You should hire an engineer to straighten it out. The purpose of this forum is not to read and debug your code.