I'm working on an assignment to perform a 200 point DFT at a sampling frequency of 20kHz on a square wave of frequency 500Hz whose amplitude alternates between 0 and 20.
I'm using C++ and I have figured how to code the DFT equation, my problem is I'm having trouble representing the square wave in code using a for loop.
What I'm really still confused about is how many cycles of this square wave will be in my 200 point sample.
Thanks
The period of the square wave is 20000/500=40 points, so you'll have exactly 5 periods of the square wave in your 200-point sample (200/40=5).
One cycle of your square wave will take 1/500 seconds. Each sample will be 1/20000 seconds. A simple division should tell you how many samples each square wave will be.
Another division will tell you how many of those waves will fit in your 200 point window.
If your sampling frequency is 20,000 Hz and you have a square wave of frequency 500 Hz, this basically means that you will have 500 cycles of your wave per second, which means you will have 500 cycles in every 20,000 samples. This means that each wave cycle requires 40 samples (or points), so if you have 200 points that means you should have 5 square wave cycles within your DFT.
You can make sure you do your calculation right by including the units in your calculation. So the period has the dimension time, Hertz has the dimension of 1.0/time and samples is dimensionless.
Programatically, you can do this with boost.units. It will check your units at compile time and give you an error if you make a mistake.
It will also stop your user from entering the wrong units into your code. For example, by entering 20 instead of 20000 for the frequency (thinking you were measuring in kHz)
Your interface will then be something like
using namespace boost::units;
set_period(quantity<si::time> period);
The user will have to enter the time in seconds,
set_period(5*si::seconds)
Related
I'm trying to determine the total length of time that a square wave takes to linearly increase from frequency 1 to frequency 2.
Question 1:
If I start at, for example:
f1=0hz
f2=1000hz
step increase per cycle is 10hz
What is the total time that elapses for this linear increase of frequency to take place?
Question 2:
If I have:
f1=0hz
f2=1000hz
and I want the increase to take place over 5 seconds, for example,
how would I calculate the rate of interval increase per cycle to achieve this.
*(basically the inverse of question 1)
This is for a hobby project to make a faster stepper motor driver profile, for programming an Atmel microcontroller (in C [well, Atmel's Arduino "C"]).
Any thoughts would be helpful. Thank you in advance!
I found this sine wave that slowly ramps up frequency from f1 to f2 for a given time but this answers a slightly different question - and is for a Sine wave.
#T Brunelle,
Q1. Your time for a general frequency would be
t=(1/(delta f))*ln(f2/f1)
where f1 and f2 are start and end frequencies and (delta f) is the change per cycle. Obviously this won't work if f1 is 0, but then a zero-frequency oscillation doesn't make sense either.
This comes from solving (in practice, just multiplying together and using the chain rule):
df/d(phase)=(delta f)
and
d(phase)/dt=f
where "phase" increases by 1 each cycle.
Q2. Just invert the formula in Q1.
This assumes that the change is linear PER CYCLE (rather than PER TIME, as was in your linked page). In your case it is also independent of the waveform shape.
I have a data (file) which contains 2 columns:
Seconds, Volts
0, -0.4238353
2.476346E-08, -0.001119718
4.952693E-08, -0.006520569
(..., thousands of similar entries in file)
4.516856E-05, -0.0002089292
How to calculate the frequency of the highest amplitude wave ? (Each wave is of fixed frequency).
Is there any difference between calculating frequency of seconds and amplitude vs. seconds and volts? Because in Frequency & amplitue there is seconds and amplitude example solved, so it might help in my case.
Your data is in the time domain, the question is about the frequency domain. Your course should have told you how the two are related. In two words: Fourier Transform. In practical programming, we use the FFT: Fast Fourier Tranform. If the input is a fixed frequency sine wave, your FFT output will have one hump. Model that as a parabola and find the peak of the parabola. (Finding the highest amplitude in the FFT is about 10 times less accurate)
The link you give is horrible; I've downvoted the nonsense answer there. In your example, time starts at t=0 and the solution given would do a 1/0.
i have a sinusoidal-like shaped signal,and i would like to compute the frequency.
I tried to implement something but looks very difficult, any idea?
So far i have a vector with timestep and value, how can i get the frequency from this?
thank you
If the input signal is a perfect sinusoid, you can calculate the frequency using the time between positive 0 crossings. Find 2 consecutive instances where the signal goes from negative to positive and measure the time between, then invert this number to convert from period to frequency. Note this is only as accurate as your sample interval and it does not account for any potential aliasing.
You could try auto correlating the signal. An auto correlation can be rapidly calculated by following these steps:
Perform FFT of the audio.
Multiply each complex value with its complex conjugate.
Perform the inverse FFT of the audio.
The left most peak will always be the highest (as the signal always correlates best with itself). The second highest peak, however, can be used to calculate the sinusoid's frequency.
For example if the second peak occurs at an offset (lag) of 50 points and the sample rate is 16kHz and the window is 1 second then the end frequency is 16000 / 50 or 320Hz. You can even use interpolation to get a more accurate estimation of the peak position and thus a more accurate sinusoid frequency. This method is quite intense but is very good for estimating the frequency after significant amounts of noise have been added!
I am trying to create a spectral analyzer plugin using C++; After the FFT, I would like to somehow average each bin using RMS. The reason being is because I want the frequency plot to display at a slower rate for better viewing. How can I achieve this? To be a little more specific, I have a FFT with a sample size of 4096 with a sampling frequency of 44,100 HZ. I'm updating the display every 40 ms. Each FFT frame is displaying to fast for the human eye. How can I smooth this out by some type of averaging?
Thanks,
Isaiah Thompson
Your display updates every 40 ms are of course pointless. You have 44.100 samples per second, 4096 samples per FFT so about 11 FFT's per second. That's one every 90 ms, not 40 ms.
Furthermore, the common way to display this is as a spectrogram. Don't use a 4096 bin FFT, that's overkill anyway. Instead, use a 1024 point FFT. You'll now get 44 FFT's per second. Color-code each bin, and plot each FFT on a vertical line. The horizontal axis is the time axis. You can now show half a minute of FFT's on a single screen, and it will horizontally scroll at 44 pixels/second. This is slow enough for the eye to track.
gyroscopes which measure rate of rotation of angles when integrated produce angles right?
my question is how do i do this? what im doing so far is just adding all the angles ive detected and that seems to be very wrong
AngleIntegrated = GyroDegPersec * (1/GyroBandWidth);
suggestions are very welcome. thanks
You need to integrate with respect to time. So ideally you should sample the gyroscope at regular (fixed) time intervals, T, and then incorporate that sampling interval, T, into your integral calculation.
Note that T needs to be small enough to satisfy the Nyquist criterion.
You can integrate in discrete domain. Suppose the angular rate is da, it's time integral is a.
k is the discrete step number.
a(k) = a(k-1) + T*0.5*(da(k) + da(k-1))
For example, da(k) is current angular rate reading. da(k-1) is previoud angular rate reading. a(k-1) is the previous step's integration value(rotation angle). T is sampling rate. If the sensor outputs in every 1 millisecond, T becomes 0.001.
You can use this formula when k>0. The initial value, a(0), must be given.
Knowing that of course you can't count on having a correct value in the long run (by integration your error window will always increase over time) what I would do is reading the gyroscope, interpolating the current read and previous few ones to get a smooth curve (e.g. a parabola using current read and previous two) and then computing the integral of that parabola from last read time and current time.