This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

EVM430-F6736: Frequency Calculation in Energy meter

Part Number: EVM430-F6736

Hello All,

I couldn't able to understand the mathematics behind the below code in file "emeter-background.c"  as provided in reference code in slaa517e

/* A mains frequency measurement procedure based on interpolating zero crossings,
                           to get a fast update rate for step changes in the mains frequency */
                        /* Interpolate the zero crossing by successive approx. */
                        z = V_sample - phase->metrology.last_V_sample;
                        x = 0;
                        y = 0;
                        for (k = 0;  k < 8;  k++)
                        {
                            y <<= 1;
                            z >>= 1;
                            x += z;
                            if (x > V_sample)
                                x -= z;
                            else
                                y |= 1;
                        }
                        /* Now we need to allow for skipped samples, due to spike detection */
                        z = y;
                        while (phase->metrology.since_last > 1)
                        {
                            z += y;
                            phase->metrology.since_last--;
                        }
                        /* z is now the fraction of a sample interval between the zero
                           crossing and the current sample, in units of 1/256 of a sample */
                        /* A lightly damped filter should now be enough to remove noise and get a
                           stable value for the frequency */
                        phase->metrology.mains_period += ((int32_t) (phase->metrology.cycle_sample_count - z) << 12) - (phase->metrology.mains_period >> 4);
                        /* Start the next cycle with the residual fraction of a sample */
                        phase->metrology.cycle_sample_count = z;

It would be helpful if anyone can provide some insight on this.

Thanks & Regards

Shahul

  • Hello Shahul,

    Please be patient as our Metering experts will need to return from the holiday season before this question can be adequately addressed.

    Regards,
    Ryan
  • Hello Shahul,

    Depending on your sampling frequency, your input frequency will be equal to a certain number of integer samples plus some fractional samples. Here, the Over Sampling Rate (OSR) is 256, which means there are 256 modulator clock cycles between each sample (think of each cycle as 1/256th of a sample).

    Now, the zero-crossing of the input sinusoidal signal may not get captured by a sample. Thus, to estimate where the zero-crossing happens (which is used to calculate the frequency), the previous (negative) sample and next (positive) sample are used to interpolate with a precision of 1/256th sample. This method allows the frequency of the input signal to be more accurately calculated.

    Does this make sense?

    Regards,

    James

    MSP Customer Applications
  • Hello James,

    Thanks James for the reply and understood the concept. I didn't get how this interpolation part works.

    z = V_sample - phase->metrology.last_V_sample;
    x = 0;
    y = 0;
    for (k = 0;  k < 8;  k++)
    {
        y <<= 1;
        z >>= 1;
        x += z;
        if (x > V_sample)
            x -= z;
        else
            y |= 1;
    }

    It would be great if you could enlighten on this.

    Thanks & Regards

    Shahul

  • Hello Shahul,

    Unfortunately, I did not write this code, and I'm unable to contact the author. However, I spent some time putting this code into MATLAB to better understand it. Based on the comments by the author in the code above, the links below, and my MATLAB testing, it's basically a combination of successive approximation (think of how SAR ADCs work) and linear interpolation.

    The code snippet above estimates the fractional sample (in units of 1/256th of a sample) between the negative-to-positive zero-crossing and the positive (integer) sample. Thus, the period (frequency) of the input signal can be calculated by adding the whole samples and fractional samples for each cycle of the input signal. Here, the result is "y" but gets set to "z" later. Using my MATLAB script, I plotted each of the eight approximations, and as you can see in the figures, the estimated zero-crossing (256 - y) gets closer each approximation. I chose amplitudes of -30 for the negative sample and 200 for the positive sample, but they can be changed in the script.

    MATLAB Script

    % Housekeeping
    close all
    clc
    
    % Define amplitudes of negative and postive samples (can be changed)
    last_V_sample = -30;    % Negative sample before zero-crossing
    V_sample = 200;         % Positive sample after zero-crossing
    
    % Arrays for plotting samples
    xArray = [0,256];
    yArray = [last_V_sample,V_sample];
    
    % Successive approximation/interpolation code
    x = uint8(0);
    y = uint8(0);
    z = uint8(V_sample - last_V_sample);
    
    for k = 0:1:7
        y = bitsll(y,1);        % Bit-shift left by 1 (multiply result by 2)
        z = bitsrl(z,1);        % Bit-shift right by 1 (divide input by 2)
        x = x + z;
        if x > uint8(V_sample)
            x = x - z;
        else
            y = bitor(y,1);     % Set a bit if limit wasn't reached
        end
        figure
        plot(xArray,yArray);
        grid ON
        xticks([0 256-double(y) 256])
        xticklabels({'0',256-y,'256'})
    end


    approximation_and_interpolation_script.m

    Figures (y-axis: sample amplitude, x-axis: time between samples in 1/256 increments)

    Regards,

    James

    MSP Customer Applications

  • Hello James,

    Thanks for your input and sounds good from explanation.

    Thanks & Regards

    Shahul

  • Hello Shahul,

    I have attached a couple of slides that explain how interpolation was used between 2 consecutive samples to find the period of each voltage sinusoid.

    In this example frequency is calculated using the period of one sinosuid. However, in the code the frequency is calculated once a second with the average period.

    Hope this helps!

    Best regards,

    Erick

**Attention** This is a public forum