Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Frequency Analysis Fun, Low-end "Noise"

Status
Not open for further replies.
So,

For a hobby project, I'm making a spectrum analyzer using an 8 bit datapath in a MCU.

I wanted to learn more about how the FFT/FHT works, so I am taking a stab at my own attempt at both an FFT and FHT. I have both an 8bit forced datapath FFT and FHT "working" in python, and it's "working!".....well sortof.

Anyways,
here's what I have. The attached image is a pre-generated test sin wave pattern running through my FHT and the magnitude output of the result. There is quite a bit of low end "noise/stuff", and I am trying to come up with a way to get rid of it.


Applying a Hann or Hamming window to the input helps to reduce the spectral leakage of the single tone, but the low end "stuff" remains. I don't want to just ignore/hide it, especially when it's that large in magnitude. I could raise the knee of my high pass filter, but I want to try to keep the low notes present in the result. Similarly, adding a higher noise "floor" will be quite noticeable once this is on a DB-ish scale (graphs are currently on a linear scale)

FHTcapture_zpswynlq3yp.png
HannWindowFHTOut_zpspyx3xhzy.png

Anyways,
Anything come to mind? I'm hoping there may be a particular filter or windowing scheme that could be used. I'm sure the "stuff" could be partly due to a limited 8bit signed "int/char" datapath.


-EF
 
This is sample size dependent. Have you tried Audacity free with audio spectral Analysis in log--log format?
Sample size affects skirt noise.
 
I haven't, but first time using Audacity for this sort of thing. This is pretty sweet!



Here's what I have for the signal:
Fsamp=140
Fsin in signal = 15Hz
Nsamples = 256 = window
(Why such a large period? I thought it made the math easier to mess around with at first. This will be stepped up)

(Rectangular window left, Hann window right)

DB magnitude vs Linear frequency:
Audacity_Spectrum_LinearX_zpspkspigkt.png


DB magnitude vs Log frequency:
Audacity_Spectrum_Logx_zpsoehx3f4n.png


---------
Also, something interesting to note:

I was playing around with settings in my FHT code yesterday to try and find a solution. If I choose to not scale the result, ignoring the 8bit ceiling for each "bin", the following is what I see:
Gotcha_zpsuihgu7si.png


This brings up a question.
Aside from "googling", I'm not very familiar with how industry would handle the "meat" you could say of the algorithm, or the multiply/accumulate. What is common for this? In particular, when adding terms together in each step, or "butterfly", how is the data reduced? It has to be reduced somewhere, otherwise it will "explode" just like shown in the pic directly above.



-EF
 
Well, I think I found a solution. Check it out! :D

Long story short, rather than shrinking everything before the computation, guaranteeing an 8-bit result, I'm keeping the LSB data, adding it through, then reducing before storing the final term

Rough Pseudo-code of the "heart" for each FHT butterfly. Let's pretend in this small block the 8 bit ceiling doesn't apply:
;----------------------------------------------------------------------------------------------
Alpha = X[k+n+shift]*Wa_term[Wpoint] ;//result fits in 16bits, will never go above -16256, 16256
Bravo = X[butterfly-k+n]*Wb_term[Wpoint] ;//''
Charlie = X[k+n] <<7 ;//result fits in 16bits

X[k+n] = (Charlie +Alpha + Bravo) >>8 ;//stored value should fit in 8bits
X[k+n+shift] = (Charlie - Alpha - Bravo)>>8 ;//''
;---------------------------------------------------------------------------------------------

(I'm sure there are faster/cleaner ways to do this then my "nonsense" above. If you know of one, post it here! I'd love to see it! :D )
Anyways, aside from my "nonsense", here's what that small change gives me:

Fsin = 15Hz, Fsamp = 140Hz, N = 256, Window = rectangular
8bitFHT_15freq_zpspii7wyfc.png



Fsin = 62Hz, Fsamp = 140Hz, N = 256, Window = rectangular
8bitFHT_62freq_zpsptfghcop.png

There's still some small "junk" closer to DC, but the peak of the "junk" doesn't look like it moves, and is additive in magnitude if I inject something right at that frequency.

Perfect! Heh, probably not. However, I think it's a place for me to run back and modify my MCU's code. Pity, I know my exec. time is going up, but heck let's see by how much!

Any questions or comments, just let me know!

-EF
 
Last edited:
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top