# how to generate a smooth sine wave with time varying frequency in matlab

I'm currently designing a knock sensor for my FSAE team's car and I'd like to be able to test various software strategies with a fairly realistic signal (at least more realistic than a couple sine waves added together with some white noise).

From some reading, the frequencies I'll be getting will all be related to a fundamental frequency directly related to engine speed. As engine speed varies continuously, I'd like to be able to take a vector of times and transform it into a vector of frequencies that smoothly and randomly transition within the range 20-170 Hz, ideally with a uniform distribution. I can then create a couple sine waves based on these frequencies and a couple multiples, add them, add some white noise, add a knock at random points, then feed that into my knock detection code.

It's generating a smooth, uniformly distributed frequency vector that is my current issue, but I'm also open to other solutions to the problem.

• Given a rotating engine made out of components with non-zero mass subject to finite forces, are you sure that a uniformly distributed "instantaneous" rpm vector is the proper model? Dec 25, 2015 at 21:12
• Not at all, but I'm sure that it's better than just adding together a few constant frequency signals. I'm completely open to other suggestions. Dec 26, 2015 at 22:38
• I want the frequencies to be distributed to make sure that my code will work correctly at all RPMs. Dec 26, 2015 at 22:48

rpatel: That's an interesting Tex. Instruments Application Note. On pages 8 & 9 they mention the sliding-mode DFT (known as the "sliding DFT") and the Goertzel algorithm. They wrote:

"The disadvantages of these techniques are that the computational overhead is slightly higher and the data memory requirements increase, because a sample-block-length number of samples (N) must be retained for the calculations."

I don't believe that statement is true. The sliding DFT computes updated spectral results upon the arrival of each new input sample, and past input samples need NOT be saved (retained). The Goertzel algorithm computes updated temporary results upon the arrival of each new input sample, and past input samples need NOT be saved (retained). Upon the arrival of the Nth input sample the Goertzel algorithm computes its final spectral result. (I'm merely telling you this for your information.) Maybe the sliding DFT or the Goertzel algorithm would be useful to you. But if the Tex. Instr. Application Note's method does what you want then stick with its method.

To start, try the following code to generate an increasing-freq chirp signal plus its first harmonic, followed by a decreasing-freq chirp signal plus its first harmonic:

Fs = 1000;  % Sample rate in Hz

Dur = 1;    % One second time duration

Time = 0:1/Fs:Dur;

% Generate the fundamental increasing-freq chirp

Fstart = 100;   % Start at 100 Hz

Fstop = 150;    % Final freq of chirp

Sig_1 = chirp(Time,Fstart,Dur,Fstop); % Sweep from 100 –to- 150 Hz

% Generate 1st harmonic of the increasing-freq fundamental chirp

Fstart = 200;    % Start at 200 Hz

Fstop = 300;     % Final freq of chirp

Sig_2 = chirp(Time,Fstart,Dur,Fstop); % Sweep from 200 –to- 300 Hz

Sig = Sig_1 + Sig_2;     % Increasing-freq chirp plus 1st harmonic

Sig = [Sig, fliplr(Sig)]; % Increasing-freq chirp followed by decreasing-freq chirp


Now if you need a fundamental sine wave signal that randomly changes in frequency (plus its harmonics) then that's a whole different ballgame. To satisfy that need I'd have to think about ways of using 'continuous multitone FSK (freq shift keying) signal generation' techniques. Let's keep in touch on this.

• Originally I was wanting a signal with random changes in frequency but I think that a sweep up then a sweep down is sufficient. Thanks for the pointers! Dec 28, 2015 at 22:58

The wording of your question (your terminology) makes it difficult to understand exactly what you desire. Is your question, "Using Matlab, how do I generate a time-domain sequence representing a sinusoidal wave whose instantaneous frequency increases as a linear function of time so that its spectrum contains a broad band of spectral energy?" If so, then try the following example Matlab code:

Fs = 1000;       % Signal sample rate in Hz

Dur = 1;         % Signal's 1-second time duration

Time = 0:1/Fs:Dur;

Fstart = 100;    % Start freq is 100 Hz

Fstop = 400;     % Final freq is 400 Hz

Sig = chirp(Time,Fstart,Dur,Fstop);   % Generate a "chirp" sequence


rpatel, generate the above 'Sig' signal, compute its DFT samples, and plot the DFT's spectral magnitude values. Maybe that's what you want.

• Sorry about the terminology, I'm a freshman so I've not taken any ECE courses at all yet. I'd like (I think) a time domain sequence representing the sum of several sinusoidal waves. The first sinusoidal wave will have a instantaneous frequency which varies randomly with time, such that the distribution of instantaneous frequencies is uniformly distributed (over time, not spectral energy) within a certain range. Several other waves will be created with their instantaneous frequency equal to a multiple of the first wave's instantaneous frequency at each time, then summed. Dec 25, 2015 at 20:49
• rpatel: Humm, ... Can you tell us what is the purpose of such a signal? For what will you be using this signal? Why must it have the characteristics you describe? Perhaps there is a less complicated signal that will serve your purpose. Dec 26, 2015 at 10:36
• I'm developing a system to detect knock in an engine. I'm trying to model my algorithm in matlab and would like an appropriate signal to use as a test case. Frequencies detected in an engine will be multiples of a fundamental frequency determined by the engine speed and number of cylinders. The knock that I am trying to detect will be a quick "ping" at 6 kHz. I'll be doing a single point DFT as each sample comes in, as described in ti.com/lit/an/spra039/spra039.pdf Dec 26, 2015 at 18:08