Measuring frequency from the EmonLib

Hi guys,

I've written some code for measuring frequency based on zero crossings. You can add the code to the EmonLib.cpp file. It basically works like this; first it searches for a zero crossing, after that it measures the time for 'x' zero crossings that passes. The 'x' is the amount of crossings you want to measure, the higher this value the more accurate it is. It searches only for positive values; by that I mean values greater than 2.5V (ADC > 512 and < 528). On the end the frequency is calculated. Here is the code to add to the EmonLib.cpp file. Make sure to adjust the EmonLib.h appropriately!

=============================================

void EnergyMonitor::calcF(int crossings)
{
boolean stf = false;
unsigned long first, second;
unsigned long delta = 0;

while(stf == false)                                   //wait for first crossing
{
  startF = analogRead(inPinV);                    //using the voltage waveform
  if ((startF > 512) && (startF < 520))
  {
   stf = true;  //check its within range
   first = millis();
   delay(4); //Make sure no second read is in this range
  }
}

stf = false;

for(int i = 0 ; i < crossings ; i++)
{
  while(stf == false)                                   //wait for next crossing
  {
   startF = analogRead(inPinV);                    //using the voltage waveform
   if ((startF > 512) && (startF < 528))
   {
    stf = true;
    second = millis();
    delta += (second - first); //Add time between crossings
    first = second;
    delay(4); //Make sure no second read is in this range
   }
  }
  stf = false;
}

frequency = (crossings / 2) / ((double)delta / 1000);
}

=============================================

 

The main file looks like this:

=============================================

#include "EmonLib.h"             // Include Emon Library
EnergyMonitor emon1;             // Create an instance

void setup()

  Serial.begin(38400);
 
  emon1.voltage(4, 200.8, 0.5);  // Voltage: input pin, calibration, phase_shift

void loop()

  emon1.calcF(50);     // 50 zero crossings
  float freq = emon1.frequency;
 
  Serial.print("Frequency: ");
  Serial.println(freq);
 
  delay(1000);
}

=============================================

Regards,

Mathieu

darrepac's picture

Re: Measuring frequency from the EmonLib

I have always heard that electricity can change in volt but nearly never in frequency... Thanks to your change above, do you confirm it (frequency is stable) or not?

Mathieu De Zutter's picture

Re: Measuring frequency from the EmonLib

Well we all know that the frequency of the power grid is 50Hz (or 60Hz). But if there is a huge change in power the frequency will change slightly dependent of the grid-constant. Yes, over time this will be corrected so that the mean frequency is always 50Hz.

What if you only have a generator as main power supply whose frequency is dependent of the load and want to measure it frequency? Well now you can measure it with my code above!

Robert Wall's picture

Re: Measuring frequency from the EmonLib

Martin Roberts' energy diverter has measured frequency for some time.

Just saying...

Mathieu De Zutter's picture

Re: Measuring frequency from the EmonLib

Yup I know and people were asking to add the code to the library. I just want to help people with this code, you are free to use it so people can make the decision for them selves what code the want to use for measuring frequency.

darko_daca's picture

Re: Measuring frequency from the EmonLib

Hi Mathieu. What changes are required to be done in EmonLib.h ?  Can you share with us EmonLib.cpp  and EmonLib.h ?

Robert Wall's picture

Re: Measuring frequency from the EmonLib

Most of the changes to EmonLib.cpp are in the first post at the top of this thread. You need to add the declaration of "startF" to calcF() in EmonLib.cpp (that was missed - or it was unnecessarily included in the definition of EnergyMonitor - it can be an unsigned integer).

In EmonLib.h you need to add the definition of calcF( ) and frequency (a double) - both are public.

Note: the hard-coded constants "512",  "520 and "528" should really be changed to take account of the possible use of an Arduino Due (for example) where the ADC resolution is other than 10 bits. That's already incorporated elsewhere in EmonLib so easy to implement.

Comment viewing options

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