Finding Harmonic Information: FFT or other method?

Hello,

I am working on a project to determine the distortion in a sine wave signal. To do this I need to find the rms voltage of the fundamental signal(50Hz) as well as that of the harmonics. This would be need to be done up to the 9th harmonic at 450Hz using an Uno.

|500x154

My first thought was to use an FFT to calculate the voltage at each frequency and then sum them together, however I wasn't sure if the Uno was capable due to limited memory which I believe limits it to 128 samples. The number of bins would be half the number of samples and this would span the frequency range of half the sampling rate. So I could use an anti-aliasing filter with a cutoff of 500Hz and a stopband at 1Khz, then sample at 2Khz.

This Would give a frequency interval of 1000/64 ~15Hz.

Could I then sum up the bins containing the 50Hz signal, ie The 3rd and 4th to cover the signal from 30-60Hz?

A second solution I thought of was to sample the entire waveform up to 500Hz and find the rms voltage with and without the fundamental signal, using a notch filter. This could be done digitally or use an analogue filter.

I would welcome some advice.

Thanks

I think FFT is the obvious way to approach the problem. This link has information on a library for performing FFT analysis on Arduino Atmega328 boards (e.g. Uno) including the library itself and example code.

Generally this sort of thing works best if the sampling rate (hence the FFT bins) is some power of 2 multiple of the fundamental frequency of interest (50 Hz in this case). This keeps the harmonic energy confined to specific bins rather than being spread across bins. It also mitigates edge effects due to capturing a non-integral number of cycles of the signal.

In practice this might be achieved by setting up a timer to generate an interrupt at a 3.2 kHz rate (50 Hz * 2^5) for example and do the sampling in the interrupt service routine.

So I could use an anti-aliasing filter with a cutoff of 500Hz and a stopband at 1Khz, then sample at 2Khz.

Which would allow frequencies up to the 20th harmonic.

To work you would need a filter that stopped everything over 550Hz, which as you might know is one hell of a filter.

Grumpy_Mike: Which would allow frequencies up to the 20th harmonic.

To work you would need a filter that stopped everything over 550Hz, which as you might know is one hell of a filter.

That's true, it's why I went for a wider transition band. I thought a cutoff of 500Hz and a stopband of 1kHz was feasible even using an analogue solution.

Grumpy_Mike: Which would allow frequencies up to the 20th harmonic.

To work you would need a filter that stopped everything over 550Hz, which as you might know is one hell of a filter.

It would allow frequencies up to the 20th harmonic but anything above 450Hz would start to be attenuated so I couldn't reliably use this information. It was an example, I appreciate the need for a wider transition band so the filter can be realised, ideally it would be a brick wall response stopping anything >450Hz but it is not feasible.

Seems like there has to be a trade off, between keeping the filtering realistic and also keeping the sampling and therefore the frequency interval low.

MrMark: I think FFT is the obvious way to approach the problem. This link has information on a library for performing FFT analysis on Arduino Atmega328 boards (e.g. Uno) including the library itself and example code.

Generally this sort of thing works best if the sampling rate (hence the FFT bins) is some power of 2 multiple of the fundamental frequency of interest (50 Hz in this case). This keeps the harmonic energy confined to specific bins rather than being spread across bins. It also mitigates edge effects due to capturing a non-integral number of cycles of the signal.

In practice this might be achieved by setting up a timer to generate an interrupt at a 3.2 kHz rate (50 Hz * 2^5) for example and do the sampling in the interrupt service routine.

Thanks, I will start to have a read through the link. I had been looking at the arduinoFFT library up until now after seeing this link.

https://www.norwegiancreations.com/2017/08/what-is-fft-and-how-can-you-implement-it-on-an-arduino/

It would allow frequencies up to the 20th harmonic but anything above 450Hz would start to be attenuated so I couldn't reliably use this information.

No you could not use it. Anything faster than half the sample rate will alias and spread rubbish all over the other bins. There is nothing you can do about it.

The solution is to either have a faster sample rate and more bins, or a serious filter. That is not just an RC filter but something like a 6th or 8th order filter.

Measuring the THD this way with only a 10 bit A/D is the sort of thing you might do as a demonstration only where you are not bothered with the accuracy of the result.

Grumpy_Mike: No you could not use it. Anything faster than half the sample rate will alias and spread rubbish all over the other bins. There is nothing you can do about it.

The solution is to either have a faster sample rate and more bins, or a serious filter. That is not just an RC filter but something like a 6th or 8th order filter.

Measuring the THD this way with only a 10 bit A/D is the sort of thing you might do as a demonstration only where you are not bothered with the accuracy of the result.

But if I am sampling at 2kHz then only anything over 1kHz will alias, with a good filter

Grumpy_Mike: No you could not use it. Anything faster than half the sample rate will alias and spread rubbish all over the other bins. There is nothing you can do about it.

The solution is to either have a faster sample rate and more bins, or a serious filter. That is not just an RC filter but something like a 6th or 8th order filter.

Measuring the THD this way with only a 10 bit A/D is the sort of thing you might do as a demonstration only where you are not bothered with the accuracy of the result.

But if I am sampling at 2kHz only frequencies above 1kHz would alias. I specified the stopband starting at 1kHz so by then any signals will be attenuated enough to not be an issue. I have already worked with Butterworth filters which seem the best solution and an 8th order one should attenuate signals above 1kHz by over 40dB which with a 10 bit ADC seems sufficient.

You are right, this is more for demonstration purposes as I am limited by the Uno ADC and memory.

Thanks

I specified the stopband starting at 1kHz so by then any signals will be attenuated enough to not be an issue.

The break point of a filter is the frequency at which the output has dropped by half, not when it has attained its full maximum attenuation.

Grumpy_Mike: The break point of a filter is the frequency at which the output has dropped by half, not when it has attained its full maximum attenuation.

So I would set fc to 500Hz keeping the 9th harmonic at 450Hz in the passband and unaltered. The transition band would be from 500-1kHz and anything >1kHz would be attenuated enough to not cause issues?

Does this sound ok?