6

I'm looking to put together a simple mains frequency monitor based on the Arduino platform. The mains here are 250 V @ 50 Hz, but obviously these fluctuate slightly, which is the whole point of the exercise. (I am not interested in capturing voltage fluctuations, only frequency fluctuations).

I have never used any Arduino products before, but I am familiar with PIC-based MCUs. I understand Arduino should be somewhat simpler. Also, I am not an electronics engineer.

Presumably, the Arduino will sample the mains frequency for a second or two, and then report the result somehow. I guess the easiest way is for a computer connected to the Arduino by USB to receive the result and act accordingly. Otherwise, other options include adding an Ethernet module to the Arduino and having it HTTP POST the result to a web server.

(I assume doing this naive method is preferable to recording a time series and then performing a Fourier transform?)

Size isn't a huge concern, but a compact device is preferable over a larger one as I'll be 3D-printing a custom enclosure for it. Therefore I would like to use the Arduino Nano if it's suitable.

Here is what I have so far:

  1. The 250V mains will be half-rectified with an IN4004 (?) transistor (together with a 1K resistor and 0.22 uF cap), and that will go into a 4N35 optocoupler.
  2. A digital (?) GPIO pin from the Arduino goes into the base of the 4N35 and emitter goes to GND.
  3. The Arduino samples for a short time the number of pulses on that pin, does a simple calculation, and reports the result.

Here are my uncertainties so far:

  1. Based on my research, I believe the Arduino can reliably be powered by USB. If this is correct, this would be ideal as it would avoid me having to build a low voltage DC power supply for it.
  2. How stable is the clock on the Arduino? How many decimal places on the frequency can I realistically achieve?
  3. I presume I'll need to debounce the result from the optocoupler? Will there be some noise as the transistor transitions between states? Are there built-in debouncing functions or will I need to write my own? How is this likely to affect available clock cycles and therefore the accuracy of the measurement?
  4. I've seen PIC projects where it interacts with the computer by emulating a keyboard. While simple, this wouldn't be ideal as the computer it's connected to must also remain usable. The software processing the result should run in the background while a user can continue using the computer. How simple is it to write some software (in C#) that will recognise the Arduino connected via USB, and communicate with that device in particular?

I also welcome any other comments and suggestions. Thank you.

Edit: Following these helpful comments and suggestions, I've made some revisions and asked a follow-up question.

6
  • The stability of the mains will exceed the accuracy of the Arduino clock by several orders of magnitude. Arduino usually uses a ceramic resonator and you would be lucky if this is accurate to 1%. If you wanted to monitor the short term mains frequency deviations you first need to use a stable reference (atomic clock or GPS).
    – Milliways
    May 17, 2017 at 9:37
  • 1
    @Milliways: [citation needed] ;-) The inaccuracy of the Arduino clock is not an issue if you calibrate it away. And the mains may not be as stable as you seem to believe. Here is a mains stability measurement showing an Allan deviation higher than 1e-4 for 40 s ≤ τ ≤ 1 h. In the same τ range, an Arduino with a ceramic resonator has been measured to be better than 1e-6, whereas a quartz-based one is better than 1e-8, more than four orders of magnitude better than mains. May 18, 2017 at 9:31
  • @EdgarBonet I do not deny there are short term variations in mains frequency. Most networks (at least in advanced countries) adjust mains frequency so the total number of cycles is constant over longer periods (typically 24 hours). My experience as a telecommunications engineer has confirmed this (at least in Australia). Ceramic resonators can be stable (if not accurate) PROVIDED the temperature is kept constant. Your second reference (one measurement) claiming MOST use a crystal is just plain wrong. I am sure there are more Unos than all others combined.
    – Milliways
    May 18, 2017 at 9:57
  • @Milliways: The second reference is old: nowadays most Arduinos use ceramic resonators, as I stated in my answer. But that does not invalidate the measurements which, by the way, were not done with a controlled temperature. May 18, 2017 at 11:22
  • 1
    Either way, I want the highest resolution and best tolerance possible. Given mains in Australia is required to be 50Hz +/- 0.5Hz, I probably want 4 decimal places if possible. I'm trying to find a way to determine which Arduino boards use crystals for the MCU clock and which use ceramic resonators. From what I can see, they all have a crystal, but presumably that's for the USB interface? How can I get a list of Arduinos that use crystals? Otherwise I'll just scrap the Arduino idea and do it all myself with a PIC.
    – Ozzah
    May 18, 2017 at 22:57

5 Answers 5

3

I understand Arduino should be somewhat simpler [than PIC].

The whole Arduino platform (boards, core library and IDE) makes it super easy to get started and do simple things. However, if you want to “push the limits” and use the full potential of the MCU, you may have to dig into low-level programming, and this has a steep learning curve.

The 250V mains will be half-rectified with an IN4004 (?) transistor (together with a 1K resistor and 0.22uF cap), and that will go into a 4N35 optocoupler.

1 kΩ seems way too low to me: your resistor will dissipate on average 31 W, and it will burn unless it is a heavy-duty power resistor. You should choose a resistor that limits the current to a value low enough to avoid overheating, but still high enough to reliably turn on the optocoupler. If these two constraints end up being incompatible, you will need a step-down transformer in addition to (not instead of) the optocoupler.

A digital (?) GPIO pin from the Arudino goes into the base of the 4N35 and emitter goes to GND.

The base of the optocoupler is typically left floating. You connect the Arduino input to the collector, using either the internal or an external pullup resistor, and you ground the emitter.

  1. I believe the Arduino can reliably be powered by USB.

Yes, powering through USB is fine. The Arduino itself draws very little power. Only when it is powering something else you may worry about power limits. Here it would seem your Arduino will only be sourcing a very small amount of current into the output transistor of your optocoupler, so you will be fine.

  1. How stable is the clock on the Arduino?

Terrible. Most Arduinos are clocked off a ceramic resonator. These are typically specified with 0.5% frequency tolerance, but their frequency is constantly fluctuating, and is also strongly dependent on ambient temperature. This makes those Arduinos grossly unsuited for any job requiring precise timings. I would recommend you get an Arduino sporting a real quartz crystal, like the Leonardo or the Micro. A quartz crystal can be quite inaccurate, but at least its frequency is stable. It's orders of magnitude more stable than a ceramic resonator. C.f. for example this article about the Arduino clock frequency accuracy.

  1. I presume I'll need to debounce the result from the optocoupler?

If the capacitor after your half-wave rectifier is well dimensioned, your signal should be clean and not need debouncing. The Arduino digital inputs all have Schmitt triggers which clean up the input noise as long as it is not excessive. If you really need debouncing (check with a scope if you can), well... there are no provisions for doing so in the Arduino core library, but there is a Debounce tutorial among the examples shipped with the Arduino IDE, and there are a few third party debounce libraries floating around the Web.

  1. How simple is it to write some software (in C#) that will recognise the Arduino connected via USB, and communicate with that device in particular?

As stated in other answers, your Arduino will be seen by your computer as a virtual serial port. I don't know C#, but any decent programming language should allow you to easily read data from a serial port.

Measuring method:

You will time one or several periods of the input signal. There are several ways of doing so. In roughly increasing order of complexity and accuracy:

  1. You continuously monitor the digital input, in a loop, and whenever you see a transition from LOW to HIGH you record the current time using micros().

  2. You use an interrupt pin as the input and you have the interrupt handler record the time with micros().

  3. You use the input capture facility of your 16-bit timer running at the full CPU speed.

The methods using micros() have a resolution of 4 µs. Both will give you some software-induced jitter because they depend on the timing of your program execution. The advice given by GuitarPicker: “Keep your code predictable, using as few conditional branches as possible that might alter how long your code takes to run each cycle” is relevant only to the first method. The interrupt method is immune to your main loop timing, but it is still affected by the CPU processing other interrupts.

The input capture method will give you single-cycle resolution and accuracy, with zero software-induced jitter. That would be my first choice, but it requires digging into the MCU datasheet and doing some low-level programming.


Addendum: Here are some tentative answers to a comment posted by Ozzah to his own question:

I probably want 4 decimal places if possible.

If you want 10−4 absolute accuracy, you may need to calibrate your clock, even if it is a crystal. If you only require 10−4 stability (variations of the frequency), then even a ceramic resonator may be (barely) up to the task, if you don't mind recalibrating it every few weeks, and assuming your indoor temperature doesn't vary by more than ≈ 10°C.

I want the highest resolution and best tolerance possible.

Then a quartz crystal is definitely a plus. It's roughly 100 times more stable than the ceramic resonator.

But if you really want the “best”, you may as well follow Milliways' advice and get a GPS reference. Some options, in increasing order of price and accuracy:

  1. A simple GPS module for the Arduino. Make sure you get one with a 1PPS output (a “one pulse per second” reference signal). You may want an external antenna for better reception.
  2. A GPSDO (GPS disciplined oscillator). This is typically a lab-grade frequency standard consisting of an OCXO (oven-controlled crystal oscillator) disciplined by a feedback loop into tracking GPS time. It gives the same long-term stability as the simple GPS module but has far better short-term stability.
  3. A rubidium-based GPSDO. This is similar to the above but has also a rubidium atomic frequency reference. Still better short-term stability. Now we are talking about stabilities in the 10−11 to 10−12 range. Provably overkill for your use case.

From the software point of view, I would recommend you start with the interrupt method, just to get a prototype working easily, and then go to the input capture method, as it will give you the best accuracy. It should be possible to be cycle-accurate with the interrupt method, but that would require some non-trivial tweaks.

Note also that the Arduinos based on the ATmega32U4 (Leonardo and Micro at least) have two 16-bit timers with input capture capability. You can then time both the mains signal and a 1PPS reference in parallel. If your Arduino has only one 16-bit timer (like the Nano), you would have to time one of the signals with the interrupt method.

I'm trying to find a way to determine which Arduino boards use crystals for the MCU clock and which use ceramic resonators. From what I can see, they all have a crystal, but presumably that's for the USB interface?

Yes, the USB/serial interface is clocked off a crystal more often than the main MCU. The Arduinos that do not have a separate USB/serial bridge (like those based on the ATmega32U4) seem to have the main MCU clocked off a crystal.

How can I get a list of Arduinos that use crystals?

It's often stated in the product page. E.g., the page of the Arduino Micro states (emphasis mine): “It has 20 digital input/output pins (of which 7 can be used as PWM outputs and 12 as analog inputs), a 16 MHz crystal oscillator, a micro USB connection, an ICSP header, and a reset button.”

Arguably, the info is not very prominent, and a compiled list would be useful. I think this could be a very good question to ask in this site.

2
  • Thanks so much for your insightful answer. I had later revised it to 6K resistor and then finally decided it would be best just to transform down to a lower voltage, probably 5V. I will look into the models with quartz crystals. Is it simple to replace the ceramic resonator with a quartz? Is it just a matter of swapping out some components?
    – Ozzah
    May 18, 2017 at 2:00
  • @Ozzah: Replacing the ceramic resonator with a quartz doesn't look like an easy task. It's a tiny SMD component, you will need to find a quartz small enough to fit in there, and most quartz crystals require a pair of capacitors that you would also have to fit, together with the crystal, into the footprint of the resonator. May 18, 2017 at 9:01
2

It sounds like you're well on your way to creating a solid project. I will attempt to answer some questions and offer some suggestions on approaching this.

Rather than counting the number of AC pulses per time period, you might get better results seeing how many Arduino clock ticks you get between a sampling of say, 50 (debounced) pulses. This will give you bigger numbers to work with. Doing the opposite (seeing how many pulses per time period) will not give the same precision. If you only got 49 pulses in a second, did you just barely miss the 50th, or was it a whole 2% off? Since the Arduino clock can count much faster, it would be better to count those ticks instead.

  1. Arduinos can be reliably powered by USB, as long as you don't draw too much current. Your application sounds like it shouldn't draw much at all.
  2. The clock on the Arduino isn't going to compare with using a separate real-time clock circuit, but it should be good enough to measure trends and differences. Keep your code predictable, using as few conditional branches as possible that might alter how long your code takes to run each cycle.
  3. Debouncing is probably a very good idea in this situation. There are several debouncing libraries available for the Arduino, or you can roll your own. Once again, the library should written as to not introduce inconsistent delays into the code. For this reason, it might be better to write your own specifically suited for this application. You might need to borrow an oscilloscope and see how long the pulses are from your optocoupler circuit. The closer you can get them to being a 0V/5V square wave, the better.
  4. Arduinos come in many flavors. Some can emulate keyboards, but most act natively as serial ports. If you can read data from a serial port, then you can read the output from the Arduino. This should be trivial in C#, or just use a terminal emulator or the Arduino IDE's serial console to view the results. Once again, if you are outputting data while still measuring, then you should use use fixed width output so that the program takes the same amount of time to run each cycle. It would be far more accurate instead to take your measurements silently, and output the results afterward later so that you don't have to account for serial port buffer delays. Take another "flush" delay before starting measurement cycle again.
2

I would use a step-down transformer with that 1N4004 rectifier diode to limit the peak rectified voltages to less than the Arduino's safe input voltage. I would also be inclined to add a zener diode to ground at the Arduino's input to "clamp" or limit that input voltage to whatever your Arduino's safe upper limit is.

At some point you might also find it beneficial to double the 50hz using a full-wave rectifier to give you more pulses to count for finer resolution.

A low current fuse in there somewhere wouldn't be a bad idea either.

1
  • 2
    So I'm not an electronic engineer, but I don't understand why I need to bring the voltage down to the Arduino's range? Isn't that the whole point of the optocoupler? The input end runs at 250V and the output end runs at whatever voltage the Arduino is running at?
    – Ozzah
    May 17, 2017 at 3:30
2

It's a safety issue at the very least. A catastrophic failure of the opto & everything is gone. At least with a "wall bug" style transformer, you've given yourself & your device a large safety margin.

I assume your opto will be triggered at line voltage & frequency to subsequently switch a 3.3 or 5v bus to an Arduino input pin at the 50hz line rate.

The opto you've chosen turns ON at ~1 volt & it needs a current limit of ~10ma thru it. You'll need to calculate a dropping resistor value to bring the rectified peak voltage down so that the opto isn't overloaded in either category. You'll need to also compensate for the eventual surge/peak voltages well above the typical line voltages.

There could conceivably be enough constant "noise" riding in on the line that prevents the opto from regularly seeing the "zero crossing" moment that your pulse counter relies on.

Transforming that line voltage to a much lower level decreases ambient line noise by the same transformer ratio, increases safety & makes it easier for the opto to detect the zero crossing in the presence of line noise etc. bc

2
  • Thanks. I think I'll drop down to ~5V with a transformer as you suggest.
    – Ozzah
    May 17, 2017 at 6:23
  • It wouldn't hurt to do both the transformer and the opto. I've seen wall transformers fail with higher voltages than their usual output. I'm thinking back to a cheap powered USB hub I encountered that kept zapping flash drives (back when they were new and expensive). May 22, 2017 at 12:40
0

Based on my research, I believe the Arduino can reliably be powered by USB.

it can also be powered by the mains directly. ST wrote such an application note for its STM8 but the basic principle is the same. The beauty of this approach is that your zero cross detection can be done without the use of an optocoupler, directly through a gpio pin.

How stable is the clock on the Arduino? How many decimal places on the frequency can I realistically achieve?

depending on your board. crystals are usually specified to 20ppm but typically within 10ppm at room temperature. resonators, which some arduino uses, are 0.1 - 1%.

if you are n't too picky, even the internal oscillators will do -> you can average the measurement over a long period of time to minimize jitter.

I presume I'll need to debounce the result from the optocoupler?

generally no.

when you measure frequencies, you typically count the input signal. for low frequencies like the mains, you do the other way around: count the internal clock and use the input signal to gate its counting.

This allows frequency calculation down to quite a few decimal points: you should average approximately 8M counts per half cycle.

that's a lot of effective digits.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.