Electric Circuits in LaTeX

Thursday, 2012 November 15

Part of my work as a graduate student at the Microlab in UP Diliman is to document the circuits that we have designed. So far, I haven't yet found a decent GUI software for creating circuit schematics suitable for research publications. Since I'm already using LaTeX, looking for a package that does circuits would be a good way to go. The most intuitive package I've found is circuitikz.

If you're on a Linux box or Mac OS X with TeX Live, circuitikz should have been included in your TeX installation. To access the manuals, just type the following into your terminal:

$ texdoc circuitikz

Since circuitikz is based on the comprehensive tikz package, it would be worthwhile to learn a little more about it for deeper hacking:

$ texdoc tikz

Below are some fully functional examples that you can copy verbatim and compile to PDF.

Baby Circuit

Basic circuit

\documentclass[preview]{standalone}

\usepackage[siunitx]{circuitikz}

\begin{document}%
\begin{tikzpicture}
  \draw
  (0,0) to[voltage source=\(V\)] ++(0,2)
        -- ++(2,0)
        to[R=\(R\)] ++(0,-2)
        -- (0,0)
        ;
\end{tikzpicture}
\end{document}

RLC Circuit

RLC circuit

\documentclass[preview, american]{standalone}

\usepackage[siunitx]{circuitikz}

\ctikzset{bipoles/capacitor/height/.initial=.4854}
\ctikzset{bipoles/capacitor/width/.initial=.1}

\begin{document}%
\begin{tikzpicture}
  \draw
  (0,0) to[voltage source=\(V\)] ++(0,2)
        -- ++(2,0)
        to[R=\(R\)] ++(0,-2)
        -- (0,0)
  (2,2) -- ++(1,0)
        to[L=\(L\)] ++(0,-2)
        -- (2,0)
  (3,2) -- ++(1,0)
        to[C=\(C\)] ++(0,-2)
        -- (3,0)
        ;
\end{tikzpicture}
\end{document}

Folded Cascode Operational Transconductance Amplifier

Folded cascode circuitikz

\documentclass[preview]{standalone}

\usepackage[siunitx]{circuitikz}

\ctikzset{bipoles/capacitor/height/.initial=.4854}
\ctikzset{bipoles/capacitor/width/.initial=.1}

\begin{document}%
\begin{tikzpicture}
  \draw
  % VDD
  (0,0)node[rground, yscale=-1](vdd_bias){}
  (3,0)node[rground, yscale=-1](vdd_tail){}
  (6,0)node[rground, yscale=-1](vdd_plus){}
  (9,0)node[rground, yscale=-1](vdd_minus){}

  % Biasing
  (vdd_bias)node[pmos, anchor=source, xscale=-1](M1){}
  (M1.base)node[left]{\(M_1\)}
  (M1.gate)node[circ]{} |- (M1.drain)node[circ]{}

  % Tail
  (vdd_tail)node[pmos, anchor=source](M2){}
  (M2.base)node[right]{\(M_2\)}
  (M1.gate) -- (M2.gate)
  (M2.drain)node[circ](vx){}

  % Reference
  (M1.drain) to[I] ++(0,-1.5)node[ground]{}

  % Folded cascode plus
  (vdd_plus)node[pmos, anchor=source, xscale=-1](M3){}
  (M3.drain)node[pmos, anchor=source, xscale=-1](M5){}
  (M5.drain)node[nmos, anchor=drain, xscale=-1](M7){}
  (M7.source) -- ++(0,-0.25)node[nmos, anchor=drain, xscale=-1](M9){}
  (M9.source)node[ground]{}
  (M3.gate)node[ocirc]{}
  (M5.gate)node[ocirc]{}
  (M7.gate)node[ocirc]{}
  (M9.gate)node[ocirc]{}
  (M3.base)node[left]{\(M_3\)}
  (M5.base)node[left]{\(M_5\)}
  (M7.base)node[left]{\(M_7\)}
  (M9.base)node[left]{\(M_9\)}
  (M5.drain) -- ++(-0.65,0)node[ocirc]{} node[below]{\(v_{o+}\)}

  % Folded cascode minus
  (vdd_minus)node[pmos, anchor=source](M4){}
  (M4.drain)node[pmos, anchor=source](M6){}
  (M6.drain)node[nmos, anchor=drain](M8){}
  (M8.source) -- ++(0,-0.25)node[nmos, anchor=drain](M10){}
  (M10.source)node[ground]{}
  (M4.gate)node[ocirc]{}
  (M6.gate)node[ocirc]{}
  (M8.gate)node[ocirc]{}
  (M10.gate)node[ocirc]{}
  (M4.base)node[right]{\(M_4\)}
  (M6.base)node[right]{\(M_6\)}
  (M8.base)node[right]{\(M_8\)}
  (M10.base)node[right]{\(M_{10}\)}
  (M6.drain) -- ++(0.65,0)node[ocirc]{} node[below]{\(v_{o-}\)}

  % Diff pair
  (vx) -- ++(-0.5,0)node[pmos, anchor=source](P+){}
  (vx) -- ++(0.5,0)node[pmos, anchor=source, xscale=-1](P-){}
  (P+.drain) |- (M10.drain)node[circ]{}
  (P-.drain) |- (M7.source)node[circ]{}
  (P+.gate)node[ocirc]{} node[below]{\(v_{i+}\)}
  (P-.gate)node[ocirc]{} node[below]{\(v_{i-}\)}
  ;
\end{tikzpicture}
\end{document}

Fully Differential Operational Amplifier

29 Dec 2012 The author has since updated the package to v0.3.0 and hosted it at mredaelli/circuitikz. The code below has also been updated to use the new package. The only change is the usage of out + instead of out+ (note the space, same goes for the negative output node.) The following words will be retained here for posterity's sake.

The current version of circuitikz at 0.2.4 only has the op amp shape, but not the fully differential operational amplifier. So I did some hacking with the circuitikz package files and added the fd op amp shape. If you're one brave hacker, head on over to my Github repository, kitmonisit/circuitikz-old.

I've had difficulty contacting the author of circuitikz, so I just asked the internets to help me integrate this common electronic circuit component into the next version. Here is the question I posted at TeX Stack Exchange, How do I contribute to CircuiTikZ? Help me out and share the link :)

Fully differential operational amplifier

\documentclass[preview]{standalone}

\usepackage[siunitx]{circuitikz}

\ctikzset{bipoles/capacitor/height/.initial=.4854}
\ctikzset{bipoles/capacitor/width/.initial=.1}

\begin{document}%
\begin{tikzpicture}
  \draw
  (0,0) node[fd op amp] (opamp) {} node[left] {\(A\)}
  % Input
  (opamp.-) node[circ] {} to[C, l_=\(C_s\)] ++(-1.5,0) node[ocirc] {} node[left] {\(v_i^-\)}
  (opamp.+) node[circ] {} to[C, l=\(C_s\)] ++(-1.5,0) node[ocirc] {} node[left] {\(v_i^+\)}
  % Feedback
  (opamp.-) -- ++(0,1)  to[C, l=\(C_f\)] ++(2,0) -| (opamp.out +) {}
  (opamp.+) -- ++(0,-1) to[C, l_=\(C_f\)] ++(2,0) -| (opamp.out -) {}
  % Output
  (opamp.out +) node[circ] {} -- ++(1,0) node[ocirc] {} node[right] {\(v_o^+\)}
  (opamp.out -) node[circ] {} -- ++(1,0) node[ocirc] {} node[right] {\(v_o^-\)}
  ;
\end{tikzpicture}
\end{document}