Monitoring Mains : Microcontrollers

This will be the first part of a larger  project  that will include other friends that have collaborated  with me directly or indirectly this last year. It was in many ways, a funny and interesting project to follow. All schematics, codes and  results are free for use , please just  give  references to authors.



The HP 5370B used during this test as reference

The aim of this test is to prove that it is possible to measure with same results  and accuracy the frequency of the power grid using different methods and hardware.According to online documentation the 50/60 Hz frequency /phase  varies depending on the load on  generators.Several types of algorithms and mechanisms are implemented in the energy industry to ensure a certain degree of frequency stability over time.



The electric frequency in a power system is a measure of the rotation speed of the synchronized generators. Changes in generation/demand will produce chages on the system frequency (speed of generators). System frequency is a continuosly changing variable that is determined and controlled by the second-by-second (real time) balance between system demand and total generation. A change in active power demand at one point of a network is reflected throughout the system by a change in electric frequency. Therefore, system frequency provides a useful index to indicate system generation and load imbalance.Considering a aystem frequency disturbance condition (active power imbalance between generation and demand), the the generation-demand dynamic relationship between the incremental mismatch power and frequency can expressed by an equivalent form of the swing equation.If demand is greater than generator, the frequency falls while generation is greater than demand, thefrequency rises.

 Code provided can be also used  in an 60Hz environment with some minor modifications to the code in case of the ATMega32P . The hardware :

  1. HP 5370B : The reference for this test. It was connected directly to an AC/AC adapter and used as a frequency counter (not as a Time Iterval  counter). The unit uses the old Motorola M68000  for this work (late ’80!) and its internal HP oscillator. (zero cross used here)
  2. The DCD pin of a real (not USB adapter) RS232 connected to another AC/AC adapter with a specific program in C  that create precise timestamps in an assert/clear event  such AC. (no zero cross connected to it )
  3. A PIC 12F683 microchip. With a great team work , Douglas Rice from UK did an incredible job, programming this little 8 pin micro as a sub-millisecond Precise Event Timer. (Connected to a transistor zero-cross circuit )
  4. An ATMega328P microcontroller. The one mounted on the Arduino Uno platform. I’ve used this micro to create an accurate frequency output to compare with the M6800 from the HP 5370B as frequency counter.Also this microcontroller was (connected to another  zero cross circuit.)


Zero Crossing detection is the most common method for measuring the frequency or the period of a periodic signal like in this case the 50 Hz frequency coming from the 220V powergrid. In the past there have been many discussions on the accuracy of the signal detected by a common serial RS232  connected to a wall adapter  compared to a version with a zero cross circuit. When measuring the frequency of a  signal, usually the number of cycles of a reference  signal is measured over one or more time periods of the  signal being measured. Measuring multiple periods  helps to reduce errors caused by phase noise by making  the perturbations in zero crossings small relative to the  total period of the measurement. So normally , Zero crossing is the point of choice for  measuring phase and frequency and avoid noise and disturbances  that, in case of 50 Hz are regular  just due home appliances.
DS3486   Zero Cross Circuit

This was the first good solution that i found on the net , created by John Rowland. ( ) . By using from the beginning  some National’s DS3486 , the results were   excellent. As we’ll see  later , the pulse width of this circuit (at 50Hz) is typically around 600µs (0.6ms) which sounds fast enough. The problem is that at 50Hz each half cycle takes only 10ms (8.33ms at 60Hz), so the pulse width is over 5% of the total period. This is why most dimmers can only claim a range of 10%-90% – the zero crossing pulse lasts too long to allow more range. This is not critical for a slow frequency like the 50/60Hz (and this is why i’ve  then used the transistor near zero, for a more easy approach)but results were just excellent. The problem is that this circuit suffers of some hysteris . Even by modifying  the circuit with trimpots, 100 and 200 ohms respectively and changing the  DS3486 IC with other manufacturers, after a few hours running ,  the output frequency of the zero cross was totally wrong due to individual thresholds and hysteresis behavior as predicted also by  Rowland itself in his paper. So i then swithced to a “near” zero one (the classic design) for a quicker solution . (anyway , this circuit , if working as it should , give best results)


 First Prototype of the DS3486 

Two  zero cross circuits using both DS3486 with trimpots ,ATMega328P (left) and PIC 12F683 Microchip (right) 
 The 2N3904 Classic variant with Optocoupler isolation.

Since last circuit  required further tuning, i’ve switched to a typical  “near” zero circuit using a transistor and an optocoupler that is providing a perfect isolation for the microcontroller area from the 220V. The previous one was connected to an AC/AC wall transformer (9V exit) to fill the DS3486 IC . Instead ,this  can be connected directly to the 220v plug. Here is my design   that i propose below for the ATMega328P microcontroller. Note that using Proteus software to design the circuit i’ve omitted the little capacitors (22pF) for the micro  (2 for the XTAL and another 2 for  VCC and GND at  both side). Please  refer to the pictures below and look online for  a board connection scheme  suitable for a standard ATMega328P connection pinout.



second proto – transistor model .  PIC 12F683  on the left  . On this model, i’ve also used  a “divide by 2” IC  CD 4013  from the full bridge rectifier (100Hz – zero cross)



Using the DCD pin (pin 1) and GND pin  of a common rs232 (USB-serial will not work due to microsecond lag for the conversion from rs232 to USB ) from an AC/AC wall adapter (9vAC) it is indeed possible to measure mains .The server was directly connected to a stratum 1 NTP server with a GPS .Also without a zero cross circuit . (see results below)  The software used is PPSKit from Ulrich Windl , or the original nanokernel used as  implementation of Nanosecond Time and  PPS API for the Linux 2.4 Kernel. The original ( ) PPSKit was intended to be used for the most as a kernel API . It is widely used today in common NTP application where a nanosecond precision is required for kernel discipline timekeeping (stratum 0). Fortunately Ulrich did  an external program in C wich can be used as stand alone software. I’ve modified the original code to adapt it on various  platforms (tested on Debian 3.16.0-4 ,  and various Wheezy for ARM ) and to give a clear  uncommented output , needed for a fast post-processing data  elaboration. You can find my modified version here. Note that you should have the file timepps.h in /sys directory if it doesn’t just  create a static link to it or use the one given, putting it inside /usr/include/timepps.h  (see instruction on the C file)

 Once installed remember to create a /dev/pps0 interface with ldattach. If everything goes fine you will  have similar output :

According to Ulrich work ,the ASSERT event has been defined in terms of the “DCD” modem status register bit of the UART, i.e. `assert” means the bit has been set (the opposite applies to “clear” events). The ECHO feature has been implemented using the “RTS” bit in the modem status register of the UART. An active event will be signalled by clearing the bit, i.e. for an echoed “assert” event the bit will be cleared and for an echoed “clear” event the bit also will be cleared. The bit will be set if all echoed event become inactive, i.e. if echoing both events, the bit will stay cleared after the first event.

In this way you will have important data available :

  1.  1 point  = phase, or time error.
  2.  2 points = change in phase over time, or frequency.
  3.  3 points  = change in frequency over time, or drift. The standard deviation of the frequency prediction errors is called the Allan Deviation This is a measure of frequency stability; the better the predicted frequency matches the actual frequency the lower the errors. A little bit of noise or any drift causes the errors to increase; the ADEV to increase.
  4. With four points you get change in drift over time. The standard deviation of the drift prediction errors is called the Hadamard Deviation.
An implementation on the Raspberry Pi v1


It’s possible to have same results using a Raspberry Pi and old kernel ( 2014-12-24-wheezy-raspbian — 3.6.11+ — ) . For instance , to have an assert/clear status, wich is not present and not yet patched on the recent ARM kernel version ( 3.18.3+ and recent) pps-gpio.h is included in userspace evironment (pre-compiled) and a patch is not yet written (i am working on this , check out  for some news.. )so if you add dtoverlay=pps-gpio,capture_clear= true in the /boot/cmdline.txt will just  not work. For the old version instead you can follow these steps  or just download a custom OS version i’ve done for the old kernel , wich will capture also “clear” status with asserts using dtoverlay=pps-gpio,gpiopin=18 . 


I’ve prepared an image for the Raspberry Pi (First Version) that will be able to capture also “clear” events using GPIO 18 and 3.12.36 kernel . It has already built in the program to capture timestamps. Be sure to have a standard 8 GB SD.


Login informations : root/raspberry or pi/raspberry

Ip address :  (access via SSH port 22). Run the program with :




                             A first portable prototype in a little Hammond case.

This was a joint work with Douglas Rice from United Kingdom. The old PicPet created by LeapSecond based on the 12F675 microchip ( ) was a good starting point , but unfortunately he did not  published the code for the pubblic. Istead of using the basic internal timer (  0x100 (256) events ) , Douglas was able to use the 12F683 CCP to capture TMR1 and output the count when it captures. so range from  0x00000000 to 0xFFFFFFFF or 0 to 4294967295  . The serial output is at 19200 baud . This version it is using an external 10 MHz oscillator (must be a Microchip compatible one)  , but he also has developed another version wich can use just  the internal one.   In this test was connected (see above) to a zero cross circuit and  using a little 10MHz crystal. Good enough to see mains phase /frequenct variations.

You can find schematics and code at Douglas’s Website.

I think the real “bonus” of this project is that you can use it for a wildly types of applications when you need some precise events to log.

Here you can see an output example, where  the 12F683 PicPET is sampling mains precise frequency/timestamps from the zero cross circuit itself :



I’ve designed  this last board  using a double micro :  the ATMega328P , or the one mounted inside the Arduino Uno. It ‘s easier to program thanks to the sketches and few line in C can do a lot . It  doesn’t need necessary the converision in HEX like the microchip family  ,to be programmed.

Here you can find the frequency counter code and here   the one for the LCD. Below is  the schematic connection for the LCD, for the frequency counter part please refer to the zero cross section above. In the meanwhile i’m developing an SMD   circuit  for the one you see in the picture  (2 micro + serial +lcd) .  Probably will be a very little stock  (< 10 pieces) but if you like to try one calibrated , use the contact form.


This is an output example from the rs232 side at 9600 baud :


Final  test was to compare these four systems  after about  3  hours :




A particular of the frequency differences between the two microcontrollers and the HP

As you can see, it’s possible to have same results also with a simple serial line port and an AC/AC wall transformer without a zero cross.Anyway for the long period i suggest to use a specific circuit  for best performances. If you’ll collect all data without intervals ,like for the 12F683 or the serial line,   beware of huge files dimensions with time . you can use something  like this :

while sleep 1; do delta_pps -tb -p/dev/pps0 -FEtdjo -m | head -4 >> filename;done

This will just take N samples each second. This will be enough to have some data  points too since while collecting them, you are not missing cycles.

As you can see from others  and others that conducted related observations and measurements before , the overall frequency stability over one month of data is about 10el-5  . I’ve added three  graph to Sidmonitor ‘s webpage. They represent the frequency  over time  and the frequency histogram updated every 15 minutes / daily from my Mains Monitor Board (ATmega328P). For the ADEV i’ve used SigmaTheta Software  that is running under UNIX/Linux systems too. For instance , i’ve created a script that automate the creation process of a final M-ADEV using various sub-bash-scripts before Sigmatheta Tau and ADEV calculations itself . You can find my script here .. It basecally takes the frequency file coming from the board and  first create a two columns file with time values . Then transforms a time error sequence in a normalized frequency error sequence, then removing the drift and create the ADEV in a *.png file . The image must be converted to *.png first and need a 90° rotation using


To be able to use it, you will need to install also ImageMagick with

apt-get install  ImageMagick

This is a screenshot of the running script :


I’ve added a live page where all plots will be added daily  here  ADEV is updated once a day.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s