Introduction: FIR Filtering for More Reliable Frequency Detection
I am a really big fan of akellyirl's instructable about Reliable Frequency Detection Using DSP Techniques but sometimes the technique he used is not good enough if you have noisy measurements.
One easy fix to get a cleaner input for the frequency detector is to apply some kind of filter around the frequency you want to detect.
Unfortunately, creating a digital filter is not easy and there is quite a lot of math involved. So I thought about creating some kind of program to simplify the creation of such filters, to allow anyone to use them in their projects without digging into the details.
In this Instructable, I am going to detect a 50Hz sine wave in a noisy measurement with an Arduino Uno (Arduino is not really necessary).
Step 1: The Problem
Imagine the measured input data looks like the curve above - pretty noisy.
If we construct a simple frequency detector like the one in akellyirl's Instructable, the result is "-inf" or in the case of the code below: "Yeah, too much noise ..."
Note: I used pretty much all of akellyirl's code but added a rawData array at the top containing the noisy measurements.
Below you can find the whole code in a file called "unfiltered.ino".
Attachments
Step 2: The Solution
Since the input data is noisy but we know the frequency we are looking for, we can use a tool I created called easyFIR to create a Bandpass filter and apply it to the input data, which results in a much cleaner input for the frequency detector (image above).
Step 3: EasyFIR
The easyFIR tool is pretty easy to use, just download the GitHub repository and run the easyFIR.py file with one sample of your measurements (in CSV format).
If you open the easyFIR.py file, you will find 5 parameters (see image above) you can and should change depending on the result you would like to achieve. After you tweaked the 5 parameters, and executed the python file, you will see the calculated coefficients in your terminal. These coefficients are crucial for the next step!
More information on the exact usage can be found here: https://github.com/GatCode/easyFIR#run-easyfir
Step 4: Filtering
Now if you've calculated the needed filter coefficients, it is pretty easy to apply the actual filer to the frequency detector.
As you can see in the image above, you only need to add the coefficients, the applyFilter function and then filter the input measurements.
Below you can find the the whole code in a file called "filtered.ino".
Note: big thanks to this Stack Overflow Post for the great filter application algorithm!
Attachments
Step 5: Enjoy
As you can see, now we are able to detect a 50Hz signal even in a noisy environment 🎉
Please feel free to adapt my idea and code to your needs. I would be very grateful to include your improvements!
If you like my work, I would really appreciate if you support my work with star on GitHub!
Thanks for your support! :)