at the begin of the procedure , inside the measuring loop of
EnergyMonitor::calcVI the variables
sampleV, sampleI, filteredV, filteredI
are not set but stored to their LASTxxx memory.
at the end of the batch only
sumV = 0; sumI = 0; sumP = 0;
are reset.
at first use of this procedure this variables might be "0.0"
at the next batch they contain values from last batch / in my case even from an other current line ( same emon instance )
( tested with diagnostic print )
even with the "FULL WAVE EMON" this problem might be much smaller now, i think a VARIABLE INIT is required!
one way could be at condition numberOfSamples==1
WAY A:
//-----------------------------------------------------------------------------
// A) Read in raw voltage and current samples
//-----------------------------------------------------------------------------
lastSampleV=sampleV; //Used for digital high pass filter
lastSampleI=sampleI; //Used for digital high pass filtersampleV = analogRead(inPinV); //Read in raw voltage signal
sampleI = analogRead(inPinI); //Read in raw current signalif (numberOfSamples==1) {
lastSampleV=sampleV; //Used for digital high pass filter
lastSampleI=sampleI; //Used for digital high pass filter
filteredV = sampleV; //Used for offset removal
filteredI = sampleI; //Used for offset removal
}//-----------------------------------------------------------------------------
// B) Apply digital high pass filters to remove 2.5V DC offset (centered on 0V).
//-----------------------------------------------------------------------------
lastFilteredV = filteredV; //Used for offset removal
lastFilteredI = filteredI; //Used for offset removal
filteredV = 0.996*(lastFilteredV+sampleV-lastSampleV);
filteredI = 0.996*(lastFilteredI+sampleI-lastSampleI);
but a more elegant way could be to do this remembering and sampling and filtering already while wait for the waveform to be close to 'zero',
so when the batch start a good INIT should be done already,
WAY B:
while(st==false) //the while loop...
{
//-----------------------------------------------------------------------------
// A) Read in raw voltage and current samples
//-----------------------------------------------------------------------------
lastSampleV=sampleV; //Used for digital high pass filter
lastSampleI=sampleI; //Used for digital high pass filtersampleV = analogRead(inPinV); //Read in raw voltage signal
sampleI = analogRead(inPinI); //Read in raw current signal//-----------------------------------------------------------------------------
// B) Apply digital high pass filters to remove 2.5V DC offset (centered on 0V).
//-----------------------------------------------------------------------------
lastFilteredV = filteredV; //Used for offset removal
lastFilteredI = filteredI; //Used for offset removal
filteredV = 0.996*(lastFilteredV+sampleV-lastSampleV);
filteredI = 0.996*(lastFilteredI+sampleI-lastSampleI);
// startV = analogRead(inPinV); //using the voltage waveform
// if ((startV < 550) && (startV > 440)) st=true; //check its within range
if ((sampleV < 550) && (sampleV > 440)) st=true; //check its within range
if ((millis()-start)>timeout) st = true;
}
startV = sampleV;
Re: EMON batch VARIABLES INIT?
The time constant of the filter
is long compared to the number of samples so it is necessary to carry over the values from one call to calcVI to the next.
The purpose of the section of code marked
is to assure that you start sampling at a recognisable place, and that a whole number of cycles are sampled. If you start sampling and filtering at a random place each time you call calcVI, and if you do not stop at the equivalent place on the wave an integral number of cycles later, you will introduce a level shift each time and the filter will never settle. The resulting "d.c." will give you the wrong value in the r.m.s calculations.
Re: EMON batch VARIABLES INIT?
thanks for fast answer, but i can not follow?
you want to say that sampleV, sampleI from batchend must be used at batchstart?
and my idea a INIT is needed would be wrong?
in case of the FULL WAVE EMON ( and a exact start of batch at zero crossing )
Vfiltered , I filtered, and also V shifted start values should be set to "0" pls see
http://www.editgrid.com/user/kll/EMONsimulation
a intentionally use of the values from end of last batch?
pls tell me how old you think these values are?
minimum the calculation time for the results, serial print and loop back ( 100ms== 5 waves??)
plus max half wave for search zero crossing,
and i dont run EMON batch after batch, there is a time adjustable call routine because have other things to do,
and i use same instance of emon on 5 current lines ( same volt )
( 5 EMON instances would mean 5 times all variables ? correct?)
but anyhow , the suggested WAY B, doing same,
use batchend values at start and already do sampling and filtering while search next zero crossing
this actually must be used if you are right, could call it a SOFTSTART of the batch.
The init of the LASTxxx variables with the first reading at batchstart, would be WAY A.
Re: EMON batch VARIABLES INIT?
This is WRONG. You must have an instance for each input, otherwise - as you are have found - you create problems. All your problems will go away when you create separate instances of EnergyMonitor.
The cost in extra variables is not great, 19 doubles, 8 integers and 2 boolean = 94 bytes x 4 more instances?
There are many, many people using the software as it was written and when you use it correctly, it works.
You will find a description of the software filter at https://en.wikipedia.org/wiki/High-pass_filter - scroll down to Discrete-time realization.
Re: EMON batch VARIABLES INIT?
thanks, i will try.
Re: EMON batch VARIABLES INIT?
OK, expanding on my last answer:
The time constant of the filter is the sample period x 0.996 / (1 - 0.996). The sample period will depend a little on any extra instructions you have put in the loop, I measured 53 samples in 20 mS, therefore the time constant works out at 94 mS. This is the time it takes for the step change to reach 63% of the final value. A general rule says you need 5 x time constant ( = 0.5 s) to reach within 1% of the final value, and to get a stable value to within 0.1% (1 count), you need to wait rather more than this. Any reading you make before the filter has settled will be wrong.
Now if you connect the input of the filter to different sensors, each will be at a different d.c voltage because the bias components will not all be exactly the correct value, so you will introduce a step each time and you must allow the filter to settle before you use the reading.
However, when you have one filter for each sensor, the filter "goes to sleep" while you read the remaining sensors, and continues where it left off when you next read that sensor, so it continues to settle and when it has done so (after about 8 time constants, but interrupted while the program goes away and reads other sensors) then you can use the result immediately. But you still need to discard the readings for the first 10 - 15 seconds or so after powering up while the filters settle and the reading stabilises.
Re: EMON batch VARIABLES INIT?
sorry , i have to bring up the EMON INIT Problem again.
the EMON batch uses 4 memory variables,
lastSampleV=sampleV; //Used for digital high pass filter
lastSampleI=sampleI; //Used for digital high pass filter
lastFilteredV = filteredV; //Used for offset removal
lastFilteredI = filteredI; //Used for offset removal
at Program Start sampleX and filteredX are 0.
this leads to a first batch result what can not be used.
at batch begin is a procedure what searches for the Volt signal to be near its zero,
if ((startV < 550) && (startV > 440)) st=true;
at the end of the loop inside the batch this value is used again to detect a zero crossing
if (sampleV > startV) checkVCross = true;
else checkVCross = false;
if (numberOfSamples==1) lastVCross = checkVCross;
if (lastVCross != checkVCross) crossCount++;
It will result in, that its undefined if we start at a positive half wave or not,
and that the used Start values ( from end of last batch ) come also from a positive half wave or not.
So the Start values are jumping sometimes between positive or negative values.
And the start range (440 ..550 ) allows a wide phase angle
The Call of the procedure
emon1.calcVI(40,2000);
actually means 40 half waves and not 40 sinus and was required to be a even number.
pls see att. EMON_problem.jpg
I recommend following changes:
1. change to FULL WAVE
( in Volt detect loop and in wave count loop )
2. detect a program start and replace the sampleX values (0) by actual readings,
just at batch start on a positive sinus wave of volt.
code1
while(st==false) //the while loop...
{
startV = analogRead(inPinV); //using the voltage waveform
// if ((startV < 550) && (startV > 440)) st=true; //check its within range
if ((millis()-start)>timeout) st = true; // check on timeout
// KLL new full wave search
if ( !minuswave ) {
if ( startV < 440 ) { minuswave = true; } // wait for sinus is in minus
}
if ( minuswave ) {
if ( startV > 511 ) { pluswave = true; } // and wait, now the positiv sinus starts
}
if ( minuswave && pluswave ) { // could max need 1 sinus
minuswave = false;
pluswave = false;
st = true; // only do it one time per batch
crossCount=0; // counting full waves
numberOfSamples = 0;
} // sinus starts
} // END st
code2
// program start detect:
if (sampleV == 0 ) { // program start ( or no hardware connected )
sampleV = analogRead(inPinV); // new program init not use "0" at program start
sampleI = analogRead(inPinI);
}
// batch start
code3
// lastVCross = checkVCross;
// if (sampleV > startV) checkVCross = true;
// else checkVCross = false;
// if (numberOfSamples==1) lastVCross = checkVCross;
//
// if (lastVCross != checkVCross) crossCount++;
// KLL new full wave search
if ( !minuswave ) {
if ( sampleV < 440 ) { minuswave = true; } // wait for sinus is in minus
}
if ( minuswave ) {
if ( sampleV > 511 ) { pluswave = true; } // and wait, now the positiv sinus starts
}
if ( minuswave && pluswave ) { //
crossCount++;
minuswave = false;
pluswave = false;
} // next sinus starts
pls see att. FULL_WAVE_EMON.jpg
pls find testresult, diagnostic code, full wave emon code as ZIP file
Re: EMON batch VARIABLES INIT?
FULL WAVE SHORT FORM
change:
delete all boolean memory,
in code1 use a add. int memory for startV: laststartV
laststartV = startV; // remember old value
startV = analogRead(inPinV); //using the voltage waveform
if ( laststartV < 511 && laststartV > 0 && startV >= 511 ) { st = true; } // sinus starts and NOT programstart
in code3 ( the init is taken care of in code 2 )
if ( lastSampleV < 511 && sampleV >= 511 ) { crossCount++; } // next sinus starts