Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
gigoiy committed Mar 2, 2024
0 parents commit 4f0d8e5
Show file tree
Hide file tree
Showing 9 changed files with 206 additions and 0 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# PWM Signal Simulation & Characterization Project
Thank you for checking out this project! Although, this project doesn't haven't any special use other than to showcase my skills, feel free to clone this repo and play around with it for whatever reason you may have!
## Things You Should Know
* algorithm.py uses matplotlib, scipy, and numpy libraries and Python3. Be sure to download those.
* For LaTeX editing, you could use Overleaf, but if you're using VS Code, download the LaTeX language support and LaTeX Workshop extensions and be sure to follow the installation instructions for LaTeX Workshop.
* There is already a pre-compiled PDF of the LaTeX document provided in this repo called finalDocument.pdf as well as the source code for that document called finalDocument.tex.
* Images of the plots are provided and they will also save a new one every time you run the Python code. If you don't want this to happen, be sure to comment out the lines where it saves the plots as PNGs.
94 changes: 94 additions & 0 deletions algorithm.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
#Import libraries for data simulation and signal characterization
import matplotlib.pyplot as plt
import numpy as np
from scipy import signal

T0 = float(5.59e-6) #Calculated fundamental period
omega = float(1124004.527) #Calculated fundamental angular frequency
n = np.arange(1.00, 7.00, 1.00) #List with values of n (each harmonic)
dutycycle = np.arange(0.00, 1.00, 0.01) #List with each percent of duty cycle
spectrum = [] #Frequency spectrum x-axis values
magnitude = [] #Magnitude values post-transform used in plotting y-axis for magnitude plot
phase = [] #Phase values post-transform used in plotting y-axis for phase plot
a0 = [] #Fourier constants throughout the frequency spectrum
aharmonics = [] #List containing one list per harmonic that contains Fourier coefficients throughout the frequency spectrum
jterms = [] #Calculated values from the imaginay term of the transformed equation
realterms = [] #Calculated values from the real term of the transformed equation
totals = [] #Final values calculated from the transformed equation
t = [] #Time base on the x-axis

#Improper definite integral setup
intervalA1 = 0 #Lower limit of the first integral
intervalB1 = float(T0) #Upper limit of the first integral
intervalA2 = intervalB1 #Lower limit of the second integral
intervalB2 = float(T0) #Upper limit of the second integral

for j in range(len(n)): #Increment through each harmonic
a = [] #Initialize a new Fourier coefficient list at the start of each loop
for i in range(len(dutycycle)): #Increment through the frequency spectrum of the signal
intervalB1 = T0*dutycycle[i] #Increment the upper limit of the first integral
intervalB2 = T0*(1.00-dutycycle[i]) #Calculate and increment the upper limit of the second integral
#Calculate the Fourier coefficients throughout the frequency spectrum and append it to the list for the current harmonic
a.append(float((2/T0)*(omega*np.sin(n[j]*omega*intervalB1))-(omega*np.sin(n[j]*omega*intervalA1))-(omega*np.sin(n[j]*omega*intervalB2))+(omega*np.sin(n[j]*omega*intervalA2))))
a[i] = a[i]*(10.00**-9.00) #Convert the exponentials to integers
aharmonics.append(a) #Append the list of Fourier coefficients of the current harmonic to the finalized list

for i in range(len(dutycycle)): #Increment through the frequency spectrum
intervalB1 = T0*dutycycle[i] #Increment the upper limit of the first integral
intervalB2 = T0*(1.00-dutycycle[i]) #Calculate and increment the upper limit of the second integral
a0.append(float((1/T0)*(intervalB1-intervalA1-intervalB2+intervalA2))) #Calculate the Fourier constant throughout the frequency spectrum
t.append(intervalB2) #Creates the time base
spectrum.append(float(1.00/intervalB2)) #Calculates and creates the frequency spectrum values
realterms.append(float((3.00*np.sin(omega*t[i]))/omega)) #Calculates the values of the real terms
jterms.append(float((1.00 + np.cos(omega*t[i]))/omega)) #Calculates the values of the imaginary terms
totals.append((realterms[i]**2.00)+(jterms[i]**2.00)) #Calculates the sum of both terms, getting the final value
phase.append(np.arctan(jterms[i]/realterms[i])) #Calculates the phase angle of the resulting vectors
spectrum[i] = spectrum[i]*(10.00**-6.00) #Convert the exponentials to integers

magnitude = np.sqrt(totals) #Calculate magnitudes of the vectors
for i in range(len(magnitude)): #Increment through the frequency spectrum
magnitude[i] = magnitude[i]*(10.00**6.00) #Convert the exponentials to integers

#Create a plot showing the harmonics of the signal
fig, harmonics = plt.subplots()

harmonics.bar(x=spectrum, height=magnitude, color='maroon', width=0.1)
plt.xlabel('Frequency (MHz)')
plt.ylabel('Magnitude (udB)')
plt.title('Harmonics of a 179 kHz PWM Square Wave')
plt.grid()
plt.savefig('harmonics.png')

#Create a plot showing the phase of the signal
fig, phasedata = plt.subplots()

phasedata.plot(spectrum, phase, color='green')
phasedata.set(xlabel='Frequency (MHz)', ylabel='Phase (Radians)', title='Phase of a 179 kHz PWM Square Wave on the Frequency Spectrum')
plt.grid()
plt.savefig('phase.png')

#Create a plot showing the Fourier coefficients throughout the frequency spectrum
fig, coefficients = plt.subplots()

coefficients.plot(spectrum, a0, color='purple', label='A0')
coefficients.plot(spectrum, aharmonics[0], color='blue', label='Fundamental')
coefficients.plot(spectrum, aharmonics[1], color='yellow', label='First Harmonic')
coefficients.plot(spectrum, aharmonics[2], color='red', label='Second Harmonic')
coefficients.plot(spectrum, aharmonics[3], color='orange', label='Third Harmonic')
coefficients.plot(spectrum, aharmonics[4], color='brown', label='Fourth Harmonic')
coefficients.plot(spectrum, aharmonics[5], color='gray', label='Fifth Harmonic')
coefficients.set(xlabel='Frequency (MHz)', ylabel='Amplitude (GV)', title='Fourier Coefficients Throughout the Frequency Spectrum')
coefficients.legend()
plt.grid()
plt.savefig('coefficients.png')

#Create a plot of the initial PWM square wave that we are characterizing
fig, squarewave = plt.subplots()
t = np.linspace(0, 3*T0, 10000, endpoint=False)
frequency = 179000
squarewave.plot(t*1e6, signal.square(2*np.pi*t*frequency, duty=.25))
squarewave.set(xlabel='Time (us)', ylabel='Amplitude (V)', title='PWM Square Wave at 179 kHz and 25% Duty Cycle')
plt.grid()
plt.savefig('squarewave.png')

plt.show()
Binary file added coefficients.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added finalDocument.pdf
Binary file not shown.
Binary file added finalDocument.synctex.gz
Binary file not shown.
105 changes: 105 additions & 0 deletions finalDocument.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{amsmath, amssymb, amsthm}
\usepackage{graphicx}
\usepackage{witharrows}

\title{PWM Simulation and Characterization}
\author{Kadyn Belesca}
\date{1/28/2024}

\begin{document}

\maketitle

\newpage

\section{PWM Defined as a Function of Duty Cycle}

We can define a PWM signal with amplitudes of -1 to 1 as a function of duty cycle like so:

\begin{equation}
x(t) =
\begin{cases}
1 & 0 \leq t \leq \alpha{T_{0}} \\
-1 & \alpha{T_{0}} \leq t \leq T_{0}(1 - \alpha) \\
\end{cases}
\end{equation}

Where:

\vspace{5mm}

$T_{0} =$ Fundamental Period

$\alpha =$ Duty Cycle

\subsection{PWM Example}
Figure 1 is an example of a PWM square wave signal at 179 kHz, which is my student ID number rounded up to 3 significant digits,
at 25 percent duty cycle. For the following calculations, we will use this example at different duty cycles.
\begin{figure}[h]
\includegraphics[scale=.70]{squarewave.png}
\caption{PWM Example}
\end{figure}

\newpage

\subsection{Derivation of Frequency Spectra}

We can derive the math defintion using a Fourier Transform to get the signal in the frequency spectra.
Since this is a PWM square wave, we will need to setup an improper integral defining the amplitudes at
their specified time intervals.

\begin{gather*}
\int_a^b \! x(t)e^{-j\omega{t}} \, \mathrm{d}t = \int_{a_1}^{b_1} \! 1e^{-j\omega{t}} \, \mathrm{d}t + \int_{a_2}^{b_2} \! -1e^{-j\omega{t}} \, \mathrm{d}t \\
= \int_{a_1}^{b_1} \! e^{-j\omega{t}} \, \mathrm{d}t - \int_{a_2}^{b_2} \! e^{-j\omega{t}} \, \mathrm{d}t \\
\text{We can pull out $\frac{1}{\omega{j}}$ from the resulting Riemann sums.} \\
= \frac{1}{\omega{j}}[[-e^{-\omega{jb_{1}}}+e^{-\omega{ja_{1}}}]+[e^{-\omega{jb_{2}}}+e^{-\omega{ja_{2}}}]] \\
\text{Then we can combine both Riemann sums into one whole} \\
\text{Riemann sum and use Euler's formula on the terms.} \\
= \frac{1}{\omega{j}}(-\cos{\omega{b_1}}-j\sin{\omega{b_1}}+\cos{\omega{a_1}}+j\sin{\omega{a_1}}+\cos{\omega{b_2}}+j\sin{\omega{b_2}}+\cos{\omega{a_2}}+j\sin{\omega{a_2}}) \\
\text{Since $b_1=a_2$ and $a_1=0$, we can cancel out some terms.} \\
= \frac{1}{\omega{j}}(1+\cos{\omega{b_2}}+j\sin{\omega{b_2}}) \\
\text{Using the following (adjusted) Euler's identity we can derive the complete Fourier transform.} \\
\sin{\omega} = \frac{1}{2j}(\cos{\omega}+j\sin{\omega}-\cos{\omega}+j\sin{\omega}) \\
\text{We can balance out the above equation with our equation we got in the previous integration.} \\
\sin{\omega{b_2}} = \frac{1}{2j}(\cos{\omega{b_2}}+j\sin{\omega{b_2}}-\cos{\omega{b_2}}+j\sin{\omega{b_2}}) \\
\text{First is to balance the $\frac{1}{2j}$ coefficient with the our coefficient} \\
\frac{2\sin{\omega{b_2}}}{\omega} = \frac{1}{\omega{j}}(\cos{\omega{b_2}}+j\sin{\omega{b_2}}-\cos{\omega{b_2}}+j\sin{\omega{b_2}}) \\
\text{Next, we expand the term on the right and add $\frac{1}{\omega{j}}$} \\
\frac{2\sin{\omega{b_2}}}{\omega}+\frac{1}{\omega{j}} = \frac{1}{\omega{j}} + \frac{\cos{\omega{b_2}}}{\omega{j}}+\frac{j\sin{\omega{b_2}}}{\omega{j}}-\frac{\cos{\omega{b_2}}}{\omega{j}}-\frac{j\sin{\omega{b_2}}}{\omega{j}} \\
\text{We can then add $\frac{\cos{\omega{b_2}}}{\omega{j}}+\frac{j\sin{\omega{b_2}}}{\omega{j}}$ to both sides,} \\
\text{cancel out some $j$'s, and combine like-terms to get the resulting Fourier transform:} \\
X(t) = \frac{3\sin{\omega{b_2}}}{\omega}-j\frac{1+\cos{\omega{b_2}}}{\omega} \\
\end{gather*}

\subsection{Further Calculations and Explainations}

From our equation $X(t) = \frac{3\sin{\omega{b_2}}}{\omega}-j\frac{1+\cos{\omega{b_2}}}{\omega}$, we can understand a few things.
First, since $b_2 = T_0(1-\alpha)$, we can directly get the frequency value for each point by using the equation $\frac{1}{T}$, which is the equation
for converting time to frequency. Since $b_2$ is a point in time from $0$ to $T_0$, we can replace $T$ with $b_2$ to get the resulting equation $\frac{1}{b_2}$ to get our x-values in the frequency domain.

\vspace{5mm}

For magnitude: $||\vec{X}(t)|| = \sqrt{{(\frac{3\sin{\omega{b_2}}}{\omega})}^2+{(\frac{1+\cos{\omega{b_2}}}{\omega})}^2}$

\vspace{5mm}

For phase: $\theta = \tan^{-1}{\frac{\frac{1+\cos{\omega{b_2}}}{\omega}}{\frac{3\sin{\omega{b_2}}}{\omega}}}$

\begin{figure}[h]
\includegraphics[scale=.70]{harmonics.png}
\caption{Harmonics of the PWM Square Wave}
\end{figure}

\begin{figure}[h]
\includegraphics[scale=.70]{phase.png}
\caption{Phase of the PWM Square Wave}
\end{figure}

\begin{figure}[h]
\includegraphics[scale=.70]{coefficients.png}
\caption{Coefficients Throughout the Frequency Spectrum}
\end{figure}

\end{document}
Binary file added harmonics.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added phase.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added squarewave.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 4f0d8e5

Please sign in to comment.