EMON batch VARIABLES INIT?

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 filter

    sampleV = analogRead(inPinV);                 //Read in raw voltage signal
    sampleI = analogRead(inPinI);                   //Read in raw current signal

    if (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 filter

    sampleV = 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;

 

Robert Wall's picture

Re: EMON batch VARIABLES INIT?

The time constant of the filter

filteredV = 0.996*(lastFilteredV+sampleV-lastSampleV);

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

1) Waits for the waveform to be close to 'zero'

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.

kllsamui's picture

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.

Robert Wall's picture

Re: EMON batch VARIABLES INIT?

"and i use same instance of emon on 5 current lines ( same volt )"

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.

 

kllsamui's picture

Re: EMON batch VARIABLES INIT?

thanks, i will try.

Robert Wall's picture

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.

kllsamui's picture

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
 

kllsamui's picture

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

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.