Project tutorial
Measure Mains Frequency Using Arduino

Measure Mains Frequency Using Arduino © CC BY-NC-SA

Measure and record mains frequency on the SD card along with the timestamp.

  • 0 respects

Components and supplies

Apps and online services

About this project

On 3rd April, Prime Minister of India, Shri. Narendra Modi had appealed to Indians to turn off their lights and light a lamp (Diya) at 9:00 pm on 5th April to mark India's fight against Corona Virus. Just after the announcement, there was big chaos on social media saying that this would result in a complete blackout due to failure of the electric grid.

I, being an electrical engineering student, wanted to see the effect of a sudden reduction of load on the electric grid. One of the parameters which gets affected is Frequency. So, I decided to make a device to measure the frequency of voltage from a power outlet in my house. Please note that for this little experiment precision of the measured value is not important as I just wanted to observe the changes in the frequency.

In this tutorial, I will quickly explain how a grid can fail and then show you how I measured frequency.

Step 1: Why Worry?

An electric grid can fail due to many factors one of which is a sudden reduction of load. I will try to explain it in the simplest way possible such that a person with no electrical background can understand it.

What is Frequency? It is the number of times an AC wave repeats in one second. Frequency in India is 50Hz which means that an AC wave is repeated 50 times in one second.

In any power plant, there is a turbine which is a rotary mechanical device that extracts energy from fluid flow (steam, water, gas, etc) and converts it into useful work (mechanical energy). This turbine is connected (coupled) to a generator. A generator then converts this mechanical energy into electrical energy which we get at our home.

Let us consider a steam power plant for this explanation. Here, high-pressure steam is used to rotate a turbine which in turn rotates the generator and electricity is generated. I won't be discussing how a generator works but just remember that the frequency of the generated voltage is directly related to the speed at which the generator rotates. If speed increases, frequency increases, and vice versa. Assume that the generator is not connected to any load. The generator is brought to speed by increasing the steam input to turbine until the frequency becomes 50Hz. The generator is now ready to deliver power. As soon as the generator is connected to the load (or grid), current starts flowing through its winding and its speed decreases and so the frequency. But as per regulation standards, the frequency should be within a specific band. In India it is +/- 3% i.e. 48.5Hz to 51.5Hz. Now, to compensate for the reduced frequency due to a decrease in speed, the steam input is increased until the frequency becomes 50Hz again. This process goes on. Load increases, speed decreases, frequency decreases, steam input is increased and the generator is brought to speed. All this is done automatically using a device called Governor. It monitors the speed (or frequency) of the generator and adjusts the steam input accordingly. Since most of the part is mechanical it takes few seconds (i.e. high time constant) for changes to take effect.

Now, let us consider that the entire load on the generator is suddenly removed. The generator speeds up above its normal speed since we had earlier increased the steam input to compensate for the increased load. Before the governor can sense and change the steam input, the generator speeds up so fast that the frequency crosses its upper limit. Since this is not permitted as per the regulatory standards, the generator trips (or is disconnected) from the grid due to over-frequency.

In India, we have One Nation - One Grid which means that all the generators in India are connected to one single grid. This helps in sending power to any part of the country. But there is one disadvantage. A massive fault in any one part of the country can spread quickly to other parts which results in the tripping of the entire grid. Thus, an entire country is left with no power!

Step 2: The Plan

The plan is to measure the frequency of voltage at specified intervals.

A center-tapped transformer is used to step down 230V AC to 15V AC.

The RTC Module provides the actual time.

Both the data (Time and Frequency) is then stored in the Micro SD card in two separate files. After the test is over, the data can be imported into an Excel sheet to generate the graph.

An LCD Display will be used to show the frequency.

Beware! You will be dealing with fatal AC Mains voltage. Proceed only if you know what you are doing. Electricity does not give a second chance!

Step 3: Things You Will Need

1x Arduino Nano

1x 16x2 LCD Display

1x DS3231 Real Time Clock Module

1x Micro SD Card Module

1x Center Tapped Transformer (15V-0-15V)

2x 10k Resistor

1x 1k Resistor

1x 39k Resistor

1x 2N2222A NPN Transistor

1x 1N4007 Diode

Step 4: Putting Things Together

The schematic for the build is attached here. I will be building it on a breadboard but you can make it more permanent by using a perfboard or make a custom PCB.

Connections for SD Card Module:

The module uses SPI for communication.

  • MISO to D12
  • MOSI to D11
  • SCK to D13
  • CS/SS to D10 (You can use any pin for Chip Select)

Make sure that the SD card is first formatted as FAT.

Connections for RTC Module:

This module uses I2C for communication.

  • SDA to A4
  • SCL to A5

Connections for LCD Display

  • RST to D9
  • EN to D8
  • D4 to D7
  • D5 to D6
  • D6 to D5
  • D7 to D4
  • R/W to GND

Step 5: Time for Coding

The code has been attached here. Download and open it using Arduino IDE. Before uploading, make sure you install DS3231 Library. I found some useful information on this website.

Setting up RTC:

  • Insert a 2032-type coin cell battery.
  • Open the DS3231_Serial_Easy from the examples as shown.
  • Uncomment the 3 lines and enter the time and date as shown in the picture.
  • Upload the sketch to Arduino and open up the serial monitor. Set the baud rate to 115200. You should be able to see the time which keeps on refreshing every 1 sec.
  • Now, unplug the Arduino and plug it in again after a few seconds. Look at the serial monitor. It should show real-time.

Done! RTC has been set up. This step has to be done only once to set the date and time.

Step 6: Processing the Data

Once the test is finished, remove the micro SD card from the module and connect it to your computer using a card reader. There will be two text files named as FREQ.txt and TIME.txt.

Copy the content from these files and paste it in an excel sheet in two separate columns (Time and Freq).

Click on Insert>Chart. Excel should automatically check the data on the sheet and plot the graph.

Increase the resolution of the vertical axis so that the fluctuations are clearly visible. In Google Sheets, Customise>Vertical axis> Min. = 49.5 and Max. = 50.5

Step 7: Results

We can clearly see a slight increase in frequency as loads are cut off around 9:00 pm (21:00) and a decrease in frequency around 9:10 pm (21:10) as loads are turned back on. No harm to the grid as the frequency is well within the tolerance band (+/- 3%) i.e. 48.5Hz to 51.5Hz.

A tweet from Minister of State in Government of India, Mr. R K Singh confirms that the results which I got were pretty accurate.

Thank you for sticking to the end. Hope you all love this project and learned something new today. Let me know if you make one for yourself. Subscribe to my YouTube channel for more such projects.


#include <LiquidCrystal.h>
#include <SPI.h>
#include <SD.h>
#include <DS3231.h>
#define RS 9 
#define E 8 
#define D4 7 
#define D5 6  
#define D6 5 
#define D7 4         
#define MainPeriod 100

const int chipSelect = 10; 
long previousMillis = 0; 
volatile unsigned long duration=0; 
volatile unsigned int pulsecount=0;
volatile unsigned long previousMicros=0;
LiquidCrystal lcd(RS, E, D4, D5, D6, D7);
DS3231  rtc(SDA, SCL);
File freqFile;
File timeFile; 
void setup(){
  lcd.begin(16, 2);  // intialise the LCD 
  attachInterrupt(digitalPinToInterrupt(2), myinthandler, RISING);
    Serial.println("Card failed, or not present");
    while (1);
  Serial.println("card initialized.");
void loop(){
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= MainPeriod){
    previousMillis = currentMillis;   
    // need to bufferize to avoid glitches
    unsigned long _duration = duration;
    unsigned long _pulsecount = pulsecount;
    duration = 0; 
    pulsecount = 0;
    float Freq = 1e6 / float(_duration);    
    Freq *= _pulsecount; 
    lcd.print(" Hz");
    freqFile ="freq.txt", FILE_WRITE);
    if (freqFile){
      Serial.println("Cannot open file freq.txt");
    timeFile ="time.txt", FILE_WRITE);
    if (timeFile) {
      Serial.println("Cannot open file time.txt");

void myinthandler(){
  unsigned long currentMicros = micros();
  duration += currentMicros - previousMicros;
  previousMicros = currentMicros;




Similar projects you might like

Arduino Frequency Counter with 16×2 LCD Display

Project in progress by jasir

  • 20 respects

Shooting Laser to Measure Distance

by remnis

  • 19 respects

Pressure Airflow Measure Device with Analog Sensor

Project tutorial by Team ItMightBeWorse

  • 14 respects

SHT21/HTU 21 Measure Temperature and Himidity

Project tutorial by SurtrTech

  • 1 comment
  • 2 respects

Height Measure using VL53L0X

Project tutorial by HomeMadeGarbage

  • 30 respects

Measure LUX with Arduino Using BH1750

Project tutorial by afsh_ad

  • 4 respects
Add projectSign up / Login