# Creating a pulse width modulator in TikZ

Considering the grahpics below:

Is it possible to construct something like this automatically in TikZ? The last hour or so, I have played around with a manual drawing - but it is time consuming and difficult to perfect.

The idea is that "v_AN" is creates columns where the "v_control,A" has a higher value than "v_tri". The same applies to "v_control,B". The last phase is not relevant.
I have tried to explain this by placing red and green lines on the above drawing.

I guess the challenge is to create a table or coordinate values where the control voltage exceeds the triangular voltage, and then use those values to construct the actual pulses. (which all have the exact same height)

The final plot shows the two sets of columns (v_A0 and v_B0) subtracted from one another to create a line voltage. (This is the one i have been drawing manually)

# After applying the answer from moospit:

(Sorry, I had to dumb it down a little in order to fix that odd/even-issue with the intersections of blue and red curves)

\documentclass[tikz, border=6mm]{standalone}

\usetikzlibrary{intersections}

\begin{document}
\newcommand{\step}{.5}
\begin{tikzpicture}[>=latex]
\draw [->] (0,0) -- ++(8,0) node [right] {$t$};
\draw [->] (0,-1.5) -- ++(0,3) node [midway, left] {$0$};
\draw [name path=zigzag]
\foreach \x in {0,\step,...,6} {
(\x,0) -- ++(\step/4,-1.5) -- ++(\step/2,3) -- ++(\step/4,-1.5)
};

%    \foreach \p\l\c in {0/1/red, -0.67*pi/2/blue, 0.67*pi/3/green}

%RED
\draw [red,smooth, domain=0:2*pi+.5, name path global=wave-1] plot ({\x},{sin((\x+0) r)}) node [below right, font=\scriptsize] {$sig_1$};
\draw [red,name intersections={of={wave-1} and zigzag, total=\n}]
\foreach \i [remember=\i as \lasti (initially 2)] in {1,...,\n} {
\ifodd\i {}
\else
(intersection-\lasti) -- (intersection-\i |- intersection-\lasti)
(intersection-\lasti |- 0,-2*1) rectangle (intersection-\i |- 0,-3)
\fi
};
\draw [->] (0,-3) -- ++(8,0) node [right, font=\scriptsize] {$sig_1$};
\draw [->] (0,-3) node [left] {0} -- ++(0,1.2) node [above] {$v_{1 N}$};

%Blue
\draw [blue,smooth, domain=0:2*pi+.5, name path global=wave-2] plot ({\x},{sin((\x+-0.67*pi) r)}) node [right, font=\scriptsize] {$sig_2$};
\draw [blue,name intersections={of={wave-2} and zigzag, total=\n}]
\foreach \i [remember=\i as \lasti (initially 0.01)] in {1,...,\n} {
\ifodd\i {}
\else
(intersection-\lasti) -- (intersection-\i |- intersection-\lasti)
(intersection-\lasti |- 0,-2*2) rectangle (intersection-\i |- 0,-5)
\fi
};
\draw [->] (0,-5) -- ++(8,0) node [right, font=\scriptsize] {$sig_2$};
\draw [->] (0,-5) node [left] {0} -- ++(0,1.2) node [above] {$v_{2 N}$};

%GREEN
\draw [green,smooth, domain=0:2*pi+.5, name path global=wave-3] plot ({\x},{sin((\x+0.67*pi) r)}) node [above right, font=\scriptsize] {$sig_3$};
\draw [green,name intersections={of={wave-3} and zigzag, total=\n}]
\foreach \i [remember=\i as \lasti (initially 0.5)] in {1,...,\n} {
\ifodd\i
(intersection-\lasti) -- (intersection-\i |- intersection-\lasti)
(intersection-\lasti |- 0,-2*3) rectangle (intersection-\i |- 0,-7)
\fi
};
\draw [->] (0,-7) -- ++(8,0) node [right, font=\scriptsize] {$sig_3$};
\draw [->] (0,-7) node [left] {0} -- ++(0,1.2) node [above] {$v_{3 N}$};

\end{tikzpicture}
\end{document}


Now, I "only" need to implement the bottom curve illustrated in the original grahpics. It may take some trial and error :)

Here is some code i used for a graphic similar to yours some time ago. I tried to fit it to your question and it should solve everything but your last plot. This one you could also try to create using intersections of existing paths.

The intersection points can be controlled via the \step-command for the zigzag-step and the phase-shift of the sin-plot using multiples of pi in the example.

If you need to use different intersection-points you can adjust the counters of the initially-option of remember and in the foreach-loop.

Important: To get all intersections points i suggest using the smooth-option or choosing a high samples value of the plot. Using 100 samples showed to be not sufficient in this example.

\documentclass[tikz, border=6mm]{standalone}

\usetikzlibrary{intersections}

\begin{document}
\newcommand{\step}{.5}
\begin{tikzpicture}[>=latex]
\draw [->] (0,0) -- ++(8,0) node [right] {$t$};
\draw [->] (0,-1.5) -- ++(0,3) node [midway, left] {$0$};
\draw [name path=zigzag]
\foreach \x in {0,\step,...,6} {
(\x,0) -- ++(\step/4,-1.5) -- ++(\step/2,3) -- ++(\step/4,-1.5)
};

\foreach \p\l\c in {0/1/red,.5*pi/2/blue,pi/3/green} {
\draw [\c,smooth, domain=0:2*pi+.5, name path global=wave-\l] plot ({\x},{sin((\x+\p) r)}) node [right, font=\scriptsize] {$sig_\l$};
\draw [\c,name intersections={of={wave-\l} and zigzag, total=\n}]
\foreach \i [remember=\i as \lasti (initially 2)] in {3,...,\n} {
\ifodd\i
(intersection-\lasti) -- (intersection-\i |- intersection-\lasti)
(intersection-\lasti |- 0,-2*\l) rectangle (intersection-\i |- 0,-2*\l-1)
\fi
};
\draw [->] (0,-2*\l-1) -- ++(8,0) node [right, font=\scriptsize] {$sig_\l$};
\draw [->] (0,-2*\l-1) node [left] {0} -- ++(0,1) node [above] {$v_{\l N}$};
}
\end{tikzpicture}
\end{document}


Update:

Here an approach to get the whole thing done. I did it using a copies of your sig1 and sig2 (once filled red/blue and once filled white) and overlapping them.

Important: The position of your sin-wave needs manual calculation depending on the values you choose for the first plot (i just did an approximation).

I reused your code supplied and just added my stuff. This version could need some clean up, but it works.

\documentclass[tikz, border=6mm]{standalone}

\usetikzlibrary{calc, intersections}

\begin{document}
\newcommand{\step}{.5}
\begin{tikzpicture}[>=latex]
\draw [->] (0,0) -- ++(8,0) node [right] {$t$};
\draw [->] (0,-1.5) -- ++(0,3) node [midway, left] {$0$};
\draw [name path=zigzag]
\foreach \x in {0,\step,...,6} {
(\x,0) -- ++(\step/4,-1.5) -- ++(\step/2,3) -- ++(\step/4,-1.5)
};

%RED
\draw [red,smooth, domain=0:2*pi+.5, name path global=wave-1] plot ({\x},{sin((\x+0) r)}) node [below right, font=\scriptsize] {$sig_1$};
\fill [red,name intersections={of={wave-1} and zigzag, total=\n}]
\foreach \i [remember=\i as \lasti (initially 2)] in {1,...,\n} {
\ifodd\i {}
\else
(intersection-\lasti |- 0,-2) rectangle (intersection-\i |- 0,-3)
(intersection-\lasti |- 0,-6) rectangle (intersection-\i |- 0,-7)
\fi
};
\draw [->] (0,-3) -- ++(8,0) node [right, font=\scriptsize] {$sig_1$};
\draw [->] (0,-3) node [left] {0} -- ++(0,1.2) node [above] {$v_{1 N}$};

%Blue
\draw [blue, smooth, domain=0:2*pi+.5, name path global=wave-2] plot ({\x},{sin((\x+-0.67*pi) r)}) node [right, font=\scriptsize] {$sig_2$};
\fill [blue,name intersections={of={wave-2} and zigzag, total=\n}]
\foreach \i [remember=\i as \lasti (initially 0.01)] in {1,...,\n} {
\ifodd\i {}
\else
(intersection-\lasti |- 0,-4) rectangle (intersection-\i |- 0,-5)
(intersection-\lasti |- 0,-7) rectangle (intersection-\i |- 0,-8)
\fi
};
\draw [->] (0,-5) -- ++(8,0) node [right, font=\scriptsize] {$sig_2$};
\draw [->] (0,-5) node [left] {0} -- ++(0,1.2) node [above] {$v_{2 N}$};

% Last plot
\fill [white,name intersections={of={wave-1} and zigzag, total=\n}]
\foreach \i [remember=\i as \lasti (initially 2)] in {1,...,\n} {
\ifodd\i {}
\else
($(intersection-\lasti |- 0,-7)$) rectangle ($(intersection-\i |- 0,-8)+(0,-.1)$)
\fi
};

\fill [white,name intersections={of={wave-2} and zigzag, total=\n}]
\foreach \i [remember=\i as \lasti (initially 0.01)] in {1,...,\n} {
\ifodd\i {}
\else
($(intersection-\lasti |- 0,-6)+(0,.1)$) rectangle ($(intersection-\i |- 0,-7)$)
\fi
};

\draw [smooth, domain=0:2*pi+.5] plot ({\x},{-7+sin((\x+.165*pi) r)});

\draw [->] (0,-8.5) -- ++(0,3) node [midway, left] {$0$};
\draw [->] (0,-7) -- ++(8,0) node [right] {$t$};

\end{tikzpicture}
\end{document}


• Wow. Thank you so much! I noticed that the red and green curve has opposite function than the blue one (i.e. blue is ON when the sine wave is above the triangle wave, but the two others are OFF). Anyway, i think I can adjust this on my own. Also i want to try to create the last curve. I will post it here if i succeed :) – fluxmodel Jul 14 '15 at 3:36
• Holy! Your last update is nothing short of perfect! – fluxmodel Jul 14 '15 at 23:01