AC Voltage & Frequency Monitor Project

Hi guys;

I did a project about monitering the AC main and the frequency. I constructed the circuit to take AC voltage measurment convert into a proper DC voltage the analog pin can received and take the frequency into a square wave into a digital pin.

To take AC main, I use a transformer. The transformer I use have : 2 secondary output, one is a CT type <- center tap. I will use the center tap secondary to be use as a power supply to provide a dual-power rail line, and the other secondary, for the AC voltage sample to be measure.

For calibration, use a 5 K multiturn pot for VR1 to get at the output for a 3 V out. Measured the Main with DVM - AC mode to have the main voltage. Take the V main / V out = Main Ratio in your code. Also measure the Aref of the Arduino and place in the code like : Aref / 1023.0 <-- that code line. I will use a precision V reference <-- Kind of voltage regulator to have an exact V ref so I can use in the code.

Right now, it is only a prototype code - without LCD, which I will use later. To test my code, I use the serial monitor to see what values I have.

Here is the code and a picture of my results of the serial monitor.

/*
   Size : 5262 Bytes
   
   AC Frequency and AVC Main monitor
   
   By Serge J Desjardins 
   aka techone / tech37
   
   Toronto, ON Canada
   
   Compile - Tested - Calibrated
*/

//#include <LiquidCrystal.h>

//LiquidCrystal lcd(12,11,10,9,8,7);

byte inpulse=2; // square wave input digital  pin
byte voltpin=1; // Vout input anaalog pin 

const int number_of_samples = 50;
const float main_ratio = 40.63018242;  // <-- The ratio of : AC Main / V out

unsigned long duration_ton;
unsigned long average_ton;
unsigned long sample_the_pulse;
unsigned long duration_toff;
unsigned long average_toff;

unsigned int sample_the_adc;
unsigned long total_adc;
unsigned int average_adc;

float frequency;
float voltage;
float single_step;
float voltage_out;

void setup()
{
  analogReference(DEFAULT);
  pinMode(inpulse, INPUT);
  Serial.begin(9600);
  //lcd.begin(16, 2);
  single_step=4.92/1023.0; // Vref = Aref / 1023.0  
  

}


void loop()
{
  duration_ton = 0;
  sample_the_pulse= 0;
  average_ton = 0;  
  duration_toff=0;
  average_toff=0;
  
  for (int i=0;i<number_of_samples;i++)
  {
    sample_the_pulse = pulseIn(inpulse, HIGH);
    duration_ton = sample_the_pulse+duration_ton;
    sample_the_pulse = pulseIn(inpulse, LOW);
    duration_toff = sample_the_pulse+duration_toff; 
  }
    
  average_ton = (duration_ton*10)/number_of_samples;
  average_toff = (duration_toff*10)/number_of_samples;
  frequency = 1/(float(average_ton+average_toff)/10000000.0);
  
  sample_the_adc=0;
  total_adc=0;
  average_adc=0;
  
  for (int i=0;i<number_of_samples;i++)
  {
    sample_the_adc=analogRead(voltpin);
    total_adc=sample_the_adc+total_adc;
  }
 
  average_adc=((total_adc*10)/number_of_samples)/10;
  voltage_out=float(average_adc)*single_step;
  voltage=(float(average_adc)*single_step)*main_ratio;
    
  
  Serial.print("Ton = "); 
  Serial.print(float(average_ton/10000.0), 3);
  Serial.println(" ms");
  Serial.print("Toff = ");
  Serial.print(float(average_toff/10000.0), 3);
  Serial.println(" ms");
  Serial.print("Average Frequency : ");
  Serial.print(frequency, 3);
  Serial.println(" Hz");
  Serial.print("Average ADC Value : ");
  Serial.println(average_adc, DEC);
  Serial.print("Average V out : ");
  Serial.print(voltage_out, 3);
  Serial.println(" Volt");
  Serial.print("AC Main Voltage : ");
  Serial.print(voltage, 3);
  Serial.println(" Volt"); 
  delay(1000);  
}

Here two pictures of my setup.

Top : The set-up

Bottom : Live set-up.

A long time ago I read of a similar experiment where the user recorded the AC frequency over the course of a day to see how it changes; in the past there was always some effort by manipulators of the grid to slow it down or speed it up to keep it accurate to 60Hz so that clocks that depend on that frequency would be correct.

It would be surprising to see it continually at 60.5Hz as it shows in your readout; that's quite a bit of error. But I'm sure that's the grid's fault and not any mistake of yours :wink:

I agree. It is a good idea to monitor during the day, I am planning for it. I will modify the code to send to the serial port, in addition to display the voltage and frequency to a LCD display. I will place a switch call : To data logger - No data logger. I will also build an another project, it will simply take data from serial and store it into a SD card. Just a data logging project. To log any type of data. And at the computer side, a program to analyse the data store inside the SD card. That what I plan to do.

I know, it will be interesting to see that data and to see the power generating to the city of Toronto - Ontario Hydro / Toronto / Hydro is stable or not. It will more interesting to see the voltage and frequency during the summer. Most power failures happen during the summer.

For the project to be complete, I need to build : The AC Monitor, A data linker ( with opto-coupler ) and a Data Logger ( with SD card ). And a program to analyse the data.

Lot of works and lots of fun.

I forgot to mention that the code and the circuit can be use for 220 V / 50 Hz.

Just change this line :

const float main_ratio = 40.63018242;  // <-- The ratio of : AC Main / V out

example : 220 / 3 = 73.33333333 <-- change the const float with this number.

You use the measure value for a better accuracy.

The changing frequency of the mains supply is not "Manipulated" in order to keep clocks accurate.
It's caused by an imbalance between supply and demand and the generating / distribution companies have a minute by minute battle to keep the frequency within it's declared value.

There is no way to store electricity in the grid, supply has to match demand. But adding or removing power from the grid is not instant. Turbines have to speed up or slow down, fuel rods have to be added or removed etc.

A good analogy is riding a bycycle. If you are on perfectly flat track you can keep a perfectly constant speed. If there is a hill up or down then the demand on your legs goes up or down, and so does your speed, unless you are really good at matching your effort with the gradient. As you go up a hill you will slow a little as you pedal harder to bump your speed up. and vice versa.

In the UK we have "TV Pickup" when soap operas finish we all go and put the kettle on (1.75 Million kettles in under 5 minutes that's 3 Gigawatts extra). Its such a big surge, and the frequency drops so fast we have to get more in from France!

our "National Balancing Engineer" braces himself, and the grid, for the end of Eastenders (TV soap opera) and sweats a bit when it's late and France lets us down. Watch him go quiet when the end theme tune (Drums. Dum Dum Dum diddiddy) starts.

Great project BTW.

And... What a good day to be posting about it. Heinrich Rudolf Hertz's 155th Birthday.

Bookworm:
The changing frequency of the mains supply is not "Manipulated" in order to keep clocks accurate.

http://www.msnbc.msn.com/id/43532031/ns/technology_and_science-innovation/t/power-grid-experiment-could-confuse-electric-clocks/

What a good day to be posting about it. Heinrich Rudolf Hertz's 155th Birthday.

Hum...I did know about that little detail. :~

Its such a big surge, and the frequency drops so fast we have to get more in from France!

That is interresting !!!. In Canada, the extra need power came from the US. I did not know UK depand on France or Europe for the extra power. In 1759 , In Canada, French and English where fighting each others... just pointing this out.
http://www.ask.com/wiki/Battle_of_the_Plains_of_Abraham ... :smiley:

Thank for the comment and the U-tube link.

Right now, it still a work in progress. My project will work in the UK. You just need the proper transformer secondary Voltage output. Beside, you can change the value of the AC voltage input of the circuit by increasing or decreasing R5, R6, R4 and VR1 for a proper Vout at IC2A out pin.

@Chagrin

I just hope this "experiment" will not affect the Canadian electrical system. Maybe an "out of phase" problem may occur.

If one were to construct your instrument for use in the UK the accuracy of your measurements could be checked against that of the grid.

http://www.nationalgrid.com/uk/Electricity/Data/Realtime/Frequency/Freq60.htm

I don't know if there is something similar in Canada or USA.

BTW The UK has electrical connections to France, Northern Ireland, the Isle of Man & The Netherlands.

Interesting...Thank.

The Canadian grid system is not all connected together. The Electrical Utility is control by the provinces, not federal. The city I live - Toronto, it is control by Toronto Hydro - in Ontario, it is control by Hydro One, and I pay the City of Toronto for my electrical bills - BTW, one is coming at the end of this month. In Quebec, it is control by Hydro Quebec, in New-runswick, it is control by NB Power. Same for the rest of Canada.

About a monitor web site like in your example ? That, I don't know...I have to Google it.

Bookworm:
The changing frequency of the mains supply is not "Manipulated" in order to keep clocks accurate.
It's caused by an imbalance between supply and demand and the generating / distribution companies have a minute by minute battle to keep the frequency within it's declared value.

There is no way to store electricity in the grid, supply has to match demand. But adding or removing power from the grid is not instant. Turbines have to speed up or slow down, fuel rods have to be added or removed etc.

A good analogy is riding a bycycle. If you are on perfectly flat track you can keep a perfectly constant speed. If there is a hill up or down then the demand on your legs goes up or down, and so does your speed, unless you are really good at matching your effort with the gradient. As you go up a hill you will slow a little as you pedal harder to bump your speed up. and vice versa.

In the UK we have "TV Pickup" when soap operas finish we all go and put the kettle on (1.75 Million kettles in under 5 minutes that's 3 Gigawatts extra). Its such a big surge, and the frequency drops so fast we have to get more in from France!
- YouTube
our "National Balancing Engineer" braces himself, and the grid, for the end of Eastenders (TV soap opera) and sweats a bit when it's late and France lets us down. Watch him go quiet when the end theme tune (Drums. Dum Dum Dum diddiddy) starts.

Great project BTW.

And... What a good day to be posting about it. Heinrich Rudolf Hertz's 155th Birthday.

I agree with your analysis of need for proper power balancing and methods used. However in addition to that the grid management does also make slowly 'correcting' frequency changes as and if required to keep clocks, which are driven by the synchronous frequency of the power grid, accurate over longer time frames. It's a fact, at least here in the U.S.

Lefty

Update :

I re-do the code to show the data on a LCD display 16 X 8. Hum.. I may need a larger one... got to check the prices for those...

Here the up-date code :

/*
   Size : 6810 Bytes
   
   Version 2.0
   
   AC Frequency and AVC Main monitor
   
   By Serge J Desjardins 
   aka techone / tech37
   
   Toronto, ON Canada
   
   Compile - Tested - Calibrated
*/

#include <LiquidCrystal.h>

LiquidCrystal lcd(12,11,10,9,8,7);

byte sw_mode=3;
byte inpulse=2;
byte voltpin=1;

boolean what_mode;

const int number_of_samples = 50;
const float main_ratio = 40.63018242;

unsigned long duration_ton;
unsigned long average_ton;
unsigned long sample_the_pulse;
unsigned long duration_toff;
unsigned long average_toff;
unsigned long total_adc;

unsigned int sample_the_adc;
unsigned int average_adc;

float frequency;
float voltage;
float single_step;
float voltage_out;
float duty_cycle;

void setup()
{
  analogReference(DEFAULT);
  pinMode(inpulse, INPUT);
  pinMode(sw_mode, INPUT);
  Serial.begin(9600);
  lcd.begin(16, 2);
  lcd.clear();
  lcd.print("Main:");
  lcd.setCursor(12,0);
  lcd.print("VAC");
  lcd.setCursor(0,1);
  lcd.print("F:");
  lcd.setCursor(7,1);
  lcd.print(" Hz D:");
  lcd.setCursor(15,1);
  lcd.print("%");
  single_step=4.92/1023.0;
  delay(5000);
  what_mode = digitalRead(sw_mode);
  delay(100);
  if ( what_mode == 0 )
  {
    Serial.print(" S ");
    Serial.print(main_ratio, 8);
    Serial.print(' ');
    Serial.print(single_step, 8);
    Serial.print(" E ");    
  }   
}


void loop()
{
  pulse_sampling();
     
  average_ton = ((duration_ton*10)/number_of_samples)/10;
  average_toff = ((duration_toff*10)/number_of_samples)/10;
  frequency = 1/(float(average_ton+average_toff)/1000000.0);
  duty_cycle = (float(average_ton)/float(average_ton+average_toff))*100.0;
  
  voltage_sampling();
  
  average_adc=((total_adc*10)/number_of_samples)/10;
  voltage_out=float(average_adc)*single_step;
  voltage=(float(average_adc)*single_step)*main_ratio;
  
  what_mode = digitalRead(sw_mode);
  delay(100);
  if ( what_mode == 0 ) 
  {
    send_data();
    display_the_data();
  }
  else
  {  
    display_the_data();
  }  
}

void pulse_sampling()
{
  duration_ton = 0;
  sample_the_pulse= 0;
  duration_toff=0;
    
  for (int i=0;i<number_of_samples;i++)
  {
    sample_the_pulse = pulseIn(inpulse, HIGH);
    duration_ton = sample_the_pulse+duration_ton;
    sample_the_pulse = pulseIn(inpulse, LOW);
    duration_toff = sample_the_pulse+duration_toff; 
  }
} 

void voltage_sampling()
{
  sample_the_adc=0;
  total_adc=0;
    
  for (int i=0;i<number_of_samples;i++)
  {
    sample_the_adc=analogRead(voltpin);
    total_adc=sample_the_adc+total_adc;
  }
}

void display_the_data()
{
  lcd.setCursor(5,0);
  lcd.print(voltage, 3); 
  lcd.setCursor(2,1);
  lcd.print(frequency, 3);
  lcd.setCursor(13,1);
  lcd.print(duty_cycle, 0);
} 

void send_data()
{
  Serial.print(" S ");  
  Serial.print(average_ton, DEC);
  Serial.print(' ');
  Serial.print(average_toff, DEC);
  Serial.print(' ');
  Serial.print(average_adc, DEC);
  Serial.print(" E ");  
}

Here a picture of the LCD dispay. The voltage and frequency was taken around 12:20 AM EST.

I can expend my project to also monitor the power usage of the place I live. I will need to build a "AC current sensor" <-- picture is included for this concept, build a circuit to "translate" the sensor signal into a 0 > 5 DC Volt for the analog pin and code properly to calculate for the current and wattage.

Any further progress on this project? I'm thinking about logging our mains voltage and frequency (240V, 50Hz), and this looks like a good starting point.

P.

I know that this thread is really old, so no one may be watching it anymore, but I thought I'd ask anyhow in case someone was ^o^

Out of random curiosity -

Is the transformer for this 9v with the center tap at 4.5v? Or is it 18v with the CT at 9v? Or is it 36v with the CT at 18v? It looks like the main voltage gets applied to CN4, and is AC, while the CT voltage would be applied to CN3, and be DC, correct?

Also, are my assumptions here correct about the connectors on the schematic?
CN1 = voltage measurement to arduino board
CN2 = frequency measurement to arduino board
CN3 = 9V in (top pin is +9v, center is ground, bottom is -9v)
CN4 = AC in (9v?)

Thanks much!

That's funny , I was going to ask the same thing but when I read your post you answered all my questions.

Lol...don't take my assumptions as final on it; I'm not anywhere remotely an EE, and only a beginner when it comes to circuit design, so I may be totally off-base :wink:

Hopefully someone "in the know" can validate/contradict my interpretations of the schematic, and also be able to confirm the AC voltages that the system is expecting to have as inputs :slight_smile:

OH - and, for someone who does know circuit design, I'm hoping to implement something like this on an Arduino Due most likely (through an UDOO.) However, the Due only supports 3.3v GPIO. What all would I need to do to make it properly output for 3V3 GPIO rather than 5V? (short of using some sort of level converter, unless that would be required...)

I have a BSEET (Bachelor's of Science of Electronic Engineering Technology, or Electronic Engineering Technician degree)
but sometimes I'm too lazy to read the fine print....
There is also a CN5 (+5v for frequency measurement).
Here's his two inputs:

byte inpulse=2; // square wave input digital  pin
byte voltpin=1; // Vout input anaalog pin

I think a V/F converter with step-down resistors would be simpler but I guess this works.