CREATE
WAVEFORMS WITH THE FOURIER SERIES
A SUM OF SINES AND COSINES
I've always been
intrigued with the Fourier Series theory. It says you can generate strange
and wonderful waveforms (square, triangle, etc.) simply by summing sine and
cosine waveforms together! Mathematically, that looks like this
y(t) = a0 + a1·cos(2·π·fo·t)
+ a2·cos(2·π·2·fo·t) + a3·cos(2·π·3·fo·t) + ... +
b1·sin(2·π·fo·t) + b2·sin(2·π·2·fo·t) + b3·sin(2·π·3·fo·t) + ...
where
a0 - the DC offset.
a1 - scales how much of the fundamental frequency fo of a
cosine is added to the waveform.
a2 - scales how much of the 2nd harmonic (2*fo) of the cosine is added
a3 - scales the
3rd harmonic (3*fo).
b1, b2, b3 - scale
the sine wave components added to the waveform.
In a compact form, the
series looks like
y(t) = a0 +
Σ an·cos(2·π·fo·n t)
+ Σ
bn·sin(2·π·fo·n t)
where
Σ simply means sum all the terms for n=1 to
∞.
Let's write a simple VBA
function to help us play with waveforms via the Fourier Series.
You can download the file
Fourier_Series.xlsm. (Also
see
VBA Basics
and other VBA Topics).
In the file, you first enter the fundamental
frequency (fo) and number of Fourier terms (n) you want to use in the waveform creation.
You also need a time increment (dT) so you can create a time variable.
Lastly, the actual Fourier coefficients are placed in a 2D table. The term
a0 represents the DC offset (bn is not used.)
dT |
0.0001 |
Time increment (Sampling period) |
|
|
|
|
|
fo |
100 |
fundamental freq |
|
ntot |
10 |
Use n terms in the waveform calc. |
|
|
|
|
|
Terms |
an |
bn |
|
|
0 |
0.00 |
na |
|
DC Term |
1 |
0.00 |
1.27 |
|
fund freq term |
2 |
0.00 |
0.00 |
|
2nd harmonic |
3 |
0.00 |
0.42 |
|
3rd harmonic |
4 |
0.00 |
0.00 |
|
,,, |
5 |
0.00 |
0.25 |
|
|
6 |
0.00 |
0.00 |
|
|
7 |
0.00 |
0.18 |
|
|
8 |
0.00 |
0.00 |
|
|
9 |
0.00 |
0.14 |
|
|
10 |
0.00 |
0.00 |
|
|
The time column t is generated by adding dT to
the previous sample.
t |
Vo |
0.0000 |
0.00 |
0.0001 |
0.39 |
0.0002 |
0.73 |
0.0003 |
0.98 |
0.0004 |
1.13 |
0.0005 |
1.17 |
The actual waveform Vo gets created by the
function = FourSeries( t,
ntot , Coeff Table, fo
).
Using actual cell references, it looks like = FourSeries(A31,$B$13,$B$16:$C$26,$B$12).
Notice you pass the entire range of cells holding coefficients a0 through b10 to the
function using $B$16:$C$26. However, you
specify how many terms to actually use via the parameter ntot.
THE FOURIER SERIES FUNCTION
Here's the VBA code that creates the waveform
based on the Fourier coefficients. To see the VBA code, hit ALT-F11 and
double click on the Modules > Module1 in the VBA Project window. This opens
the code window for this module.
|
Function
FourSeries(t, ntot, FCoeff, fo)
' Calculate
waveform based on Fourier Coefficients listed in table
' Coefficients table: 1st col is an, 2nd col is bn
'
' t - time
' N - number of Fourier coeff to include.
' FCoeff - 2D cell range of coeff table
' fo - fundamental frequency
Dim y, a0, an, bn As Double
Dim R, C, n As Integer
R = FCoeff.Row
' get start
pos of coeff table
C = FCoeff.Column
a0 = Cells(R, C)
' get DC
offset
' Sum all
sine and cosine terms at time t
y = a0 ' initialize with a0.
For n = 1 To ntot
' Get
Fourier Coeff for frequency n*fo
an = Cells(R + i, C)
bn = Cells(R + i, C + 1)
' Sum the
sine and cosine using Fourier coeff as scale factors
y = y + an*Cos(2*3.1415*(fo*n)*t) + bn*Sin(2*3.1415*(fo*n)*t)
Next n
' assign y
to return variable of function
FourSeries = y
End Function |
First, we'll get the row and column location of the
coefficient table. The range of cells for the table is passed to the
variable FCoeff. VBA has two handy properties ( *.Row and *.Col ) that
returns the Row and Column of a single cell, or the first cell in a range of
cells.
R = FCoeff.Row
' get start
pos of coeff table
C = FCoeff.Column
Now, have the values R = 16 and C = 2. This
allows us to get the a0 coefficient using the Cells( ) property.
a0 = Cells(R, C)
' get DC
offset
We'll initialize the waveform (variable y)
with the DC offset. Finally, we'll create a loop that sums together the sine
and cosine waves at the fundamental frequency fo and higher harmonics fo*n
up to n=ntot. Notice, we get the an, bn coefficients for each value of n
using the Cells( ) property along with R and C.
For n = 1 To ntot
' Get
Fourier Coeff for frequency n*fo
an = Cells(R + n, C)
bn = Cells(R + n, C + 1)
' Sum the
sine and cosine using Fourier coeff as scale factors
y = y + an*Cos(2*3.1415*(fo*n)*t) + bn*Sin(2*3.1415*(fo*n)*t)
Next n
Finally, we'll pass the waveform value y calculated
at time t to the name FourSeries to be returned by the function.
WAVEFORMS
Check out the "Waveform Coeff" sheet for
Square and Sawtooth coefficients.
Okay, let's start creating some waveforms. To
generate a square wave, enter the bn coefficients below.
Terms |
an |
bn |
0 |
0.00 |
na |
1 |
0.00 |
1.27 |
2 |
0.00 |
0.00 |
3 |
0.00 |
0.42 |
4 |
0.00 |
0.00 |
5 |
0.00 |
0.25 |
6 |
0.00 |
0.00 |
7 |
0.00 |
0.18 |
8 |
0.00 |
0.00 |
9 |
0.00 |
0.14 |
10 |
0.00 |
0.00 |
As you enter each coefficient, you can see the
waveform start approaching the shape of a square wave.
To create a sawtooth waveform, simply go
to the bn column and enter 1/n for each of the terms: 1, 1/2, 1/3 and so
on.
Here are some other sine type waveforms to try.
- Sine signal: a1 = 0, b1= 1
- Inverted Sine: a1 = 0, b1= -1
- Cosine: a1 = 1, b1= 0
- Cosine w/ -45 deg shift: a1= 0.707, b1= 0.707
Also try varying some other parameters.
- Change fundamental frequency fo to 200.
- Change sampling period to 0.0002 or 0.00005.
- Change DC Offset (a0) to 5
- Add random values to harmonic terms 0 through 10.
In another topic we'll learn how to perform
Fourier Analysis. This analysis does the opposite of the Fourier Series. It
takes an arbitrary waveform and then extracts the Fourier Coefficients.
Back to Topics
|