- #1
jegues
- 1,097
- 3
Every 50μs I have access to one sample of an unknown peroidic input signal and I am looking to calculate the RMS of the fundamental component. Is there any convenient ways one can think of doing this?
The implication being that 50μs sampling is sufficient to adequately represent the waveform for this purpose?jegues said:Every 50μs I have access to one sample of an unknown peroidic input signal and I am looking to calculate the RMS of the fundamental component. Is there any convenient ways one can think of doing this?
NascentOxygen said:The implication being that 50μs sampling is sufficient to adequately represent the waveform for this purpose?
In software. One limitation is that the code used to do so must be executed to completion every 50μs timestep.NascentOxygen said:Are you wanting to perform the task in software or as a hardware implementation?
But if the waveform is periodic, there will be only one answer, one RMS value. Once that is established, to acceptable tolerance, what is there to update every 50μs?jegues said:Yes.
In software. One limitation is that the code used to do so must be executed to completion every 50μs timestep.
Any ideas?
NascentOxygen said:But if the waveform is periodic, there will be only one answer, one RMS value. Once that is established, to acceptable tolerance, what is there to update every 50μs?
NascentOxygen said:You have no prior knowledge whether the cyclic period extends for some days, hours, or just milliseconds?? Your software will first have to establish this, undoubtedly.
NascentOxygen said:What is the source of such a signal?
If you know the frequency of the fundamental you'll know where to set your z domain filter to separate the fundamental from its harmonics. If you know the period, you know how many samples are needed to compute over, if using the FFT.jegues said:Does the problem become more manageable if I have the user provide the frequency of their periodic signal?
Averagesupernova said:How is 'real time' to be defined? The OP hasn't said just what type of results are expected. Generally one has expectations of what the results will be before attempting to measure.
anorlunda said:A sudden jump from M1 to M2 makes the signal non-sinusoidal which conflicts with your assumptions. Root-mean-square only has meaning for whole cycles, it has no instantaneous meaning.
as quickly as possible.
jegues said:I specifically used the wording,
above because this could mean a cycle later.
jegues said:Every 50μs I have access to one sample of an unknown peroidic input signal and I am looking to calculate the RMS of the fundamental component. Is there any convenient ways one can think of doing this?
anorlunda said:Why don't you start again from scratch? Tell in more detail what you do know about the frequency range and noise in the signal
anorlunda said:and what you hope to accomplish in terms of frequency of RMS calculations and tolerance for noise.
jegues said:I am trying to make the program work for the most general set of signals possible, so I'm intentionally not making any assumptions about what is known about the frequency range or noise in the input signal. The one limitation that is known is that the maximum rate at which I can sample the input signal is every 50μs.
Does assuming the fundamental frequency is within the range 0Hz < f < 1000Hz simplify the problem at all?
I want to calculate the RMS of only the fundamental component after every cycle of the input signal.
May sound simpler in principle, but not in practice.jegues said:Does assuming the fundamental frequency is within the range 0Hz < f < 1000Hz simplify the problem at all?
thankz said:I just multiply by .707, I guess this only works for 60hz
NascentOxygen said:What would be the lowest useful frequency, for seeable practical purposes?
If we knew the signal and noise you were expecting and why you wanted the RMS result, then we might be able to resolve the multiple ambiguities in your question and propose a viable solution.
How do you define the fundamental? Is it the greatest amplitude sine wave component present?
Consider the signal Sin(t) + 2*Sin(2t); where the fundamental is smaller amplitude than the second harmonic.
anorlunda said:If the "power system" means the grid, then the frequency will be 60 (or 50) +- 0.1 or so. Why would you need 0.1 to 1000 Hz?
anorlunda said:Your answer as to why fundamental component is vague and sounds false. In most applications, the RMS of the complete signal is more useful and easier to calculate. In most locations on the power grid, the harmonic content is small, so that the RMS of the total signal and the RMS of the fundamental component are almost the same value.
anorlunda said:In an earlier post, you said that you would be willing to wait for a whole cycle or more to be sure that a change is not just a spike. Now you say the calculation must finish every 50 microseconds. Why?
anorlunda said:A google search on "digital voltmeter rms algorithm" finds this http://http://www.ni.com/white-paper/2966/en/, plus hundreds more web pages on the subject. Start there.
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.jim hardy said: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
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.jegues said: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.
My unanswered question from back here https://www.physicsforums.com/showpost.php?p=4791783&postcount=7 still needs to be addressed.I need the fundamental component. The reason I was given is that this is a commonly used index in a variety of applications.
NascentOxygen said: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.
My unanswered question from back here https://www.physicsforums.com/showpost.php?p=4791783&postcount=7 still needs to be addressed.
/* 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
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 --- */