Fourier Synthesis of Triangle and Square Waves Passed Through Various Filters
Physics 238

Basic Waveforms

First, we will define three simple waves,  each of amplitude Vin, and frequency f. 
Use Fourier modes up to 'nmax'.  We trade off computational efficiency for accuracy here.  A value of '99' is reasonably quick but still gives good results.

Clear["Global`*"]; nmax = 1000;  DateString[]

Define several different wave forms.  The input is given by a simple Fourier Series.  The output is given by taking each term in the sum and passing it through a filter with gain a[f] and phase shift ϕ[f] (defined later).

Sinusoid

sinusoid[Vin_, f_, t_] := Vin * Sin[2 π f t]
sineout[Vin_, f_, t_] := Vin  *a[f] *Sin[2 π f t  + ϕ[f]]

Triangle

At[n_]  := (8/(π^2))(1/(n^2)) (* Don't need to alternate signs if we use Cosine[] *)

triangle[Vin_, f_, t_] := Vin * Sum[At[n] * Cos[n * 2 π f t], {n, 1, nmax, 2}];

triangleout[Vin_, f_, t_] := Vin * Sum[At[n]  *a[n*f] *Cos[n * 2 π f  t  + ϕ[n*f]], {n, 1, nmax, 2}];

Square

Asq[n_] := (4/π)(1/n)

square[Vin_,f_,t_]:=Vin Sum[Asq[n] * Sin[n 2 π f t],{n,1,nmax,2}]
squareout[Vin_, f_, t_] := Vin Sum[Asq[n]  a[n f] Sin[n 2π f t + ϕ[n f]], {n, 1, nmax, 2}]

Sawtooth

Asaw[n_] := ((-1)/(n π))

saw[Vin_,f_,t_]:=Vin Sum[Asaw[n] * Sin[n 2 π f t],{n,1,nmax,1}]
sawout[Vin_, f_, t_] := Vin Sum[Asaw[n] a[n f]*Sin[n  2π f t + ϕ[n f]], {n, 1, nmax, 1}]

Component Values

It's easiest to scale everything by the breakpoint frequency, fb.  For our typical experiment with R = 3.3 kΩ, C=22 nF, fb = 2192 Hz.

ωb = 1 / (3300 * 22.*10^(-9)); 
fb = ωb/(2 π)

Utility Functions

We will also use a simple helper function for the period T.

T[f_] := 1/f

This is a utility function to compare two wave forms.

compare[vin_, vout_, f_] := Plot[{vin[10, f, t], vout[10, f, t]}, {t, 0, 2 T[f]}, PlotLegends -> {"vin","vout"},  PlotRange->All, PlotLabel->StringForm["f = `` fb", f/fb], ImageSize -> 300, Frame -> False, AxesLabel -> {"t (s)", "V (Volts)"}, LabelStyle-> Larger]

Show a column of 3 graphs, tightly spaced.  Tweak/experiment with the ImageSize, Spacings, and AspectRatio to get it all to work.

showGraphs[list_] := GraphicsColumn[list,
Alignment -> {Center, Center}, Frame -> All, Spacings -> 0, ImageSize -> 400, AspectRatio -> 3/GoldenRatio]

showImg[file_] := Show[Import[file], ImageSize -> 300]

Low-pass Filter

a[f_] := 1/Sqrt[1 + (f/fb )^2]
ϕ[f_] := ArcTan[-f/fb]

Sinusoid

showGraphs[Table[compare[sinusoid, sineout, f], {f, {fb/10, fb, 10 fb}}]]

Triangle

showGraphs[Table[compare[triangle, triangleout, f], {f, {fb/10, fb, 10 fb}}]]

SetDirectory[NotebookDirectory[]];

showGraphs[{
Import["Triangle-LP-Low-f.png"], Import["Triangle-LP-Med-f.png"], Import["Triangle-LP-High-f.png"]}]

Square

showGraphs[Table[compare[square, squareout, f], {f, {fb/10, fb, 10 fb}}]]

SetDirectory[NotebookDirectory[]];
showGraphs[{
Import["Square-LP-Low-f.png"], Import["Square-LP-Med-f.png"], Import["Square-LP-High-f.png"]}]

Sawtooth

showGraphs[Table[compare[saw, sawout, f], {f, {fb/10, fb, 10 fb}}]]

High-pass Filter

a[f_] := (f/fb) /Sqrt[1 + (f/fb) ^2]
ϕ[f_] := ArcTan[f, fb]

Sinusoid

showGraphs[Table[compare[sinusoid, sineout, f], {f, {fb/10, fb, 10 fb}}]]

Triangle

showGraphs[Table[compare[triangle, triangleout, f], {f, {fb/10, fb, 10 fb}}]]

Square

showGraphs[Table[compare[square, squareout, f], {f, {fb/10, fb, 10 fb}}]]

Sawtooth

showGraphs[Table[compare[saw, sawout, f], {f, {fb/10, fb, 10 fb}}]]