5

I am trying to create a new component to use with the circuitikz package. I am new to pgf, so I don't master the creation of a new component. I need to build a generic quadrupole (I use it often in my course) so I found a ready-to-use template here.

\documentclass{standalone}
\usepackage{circuitikz}

\makeatletter
% ************************** blackbox *****************************
\ctikzset{quadpoles/blackbox/.is family}
\ctikzset{quadpoles/blackbox/height/.initial=.5}
\ctikzset{quadpoles/blackbox/width/.initial=.5}
\ctikzset{quadpoles/blackbox/sep/.initial=2pt}
\ctikzset{quadpoles/blackbox/lead/.initial=.5}

\pgfdeclareshape{blackbox}{
\anchor{center}{\pgfpointorigin}    % within the node, (0,0) is the center

\anchor{text}   % this is used to center the text in the node
    {\pgfpoint{-.5\wd\pgfnodeparttextbox}{-.5\ht\pgfnodeparttextbox}}

\savedmacro{\resize}{\pgf@circ@res@temp=\ctikzvalof{bipoles/length}% scale
  \pgf@circ@res@temp=0.5\pgf@circ@res@temp
  \pgf@circ@res@right=\ctikzvalof{quadpoles/blackbox/width}\pgf@circ@res@temp
  \pgf@circ@res@step=0.5\wd\pgfnodeparttextbox
  \advance\pgf@circ@res@step by \ctikzvalof{quadpoles/blackbox/sep}%
  \ifdim\pgf@circ@res@right<\pgf@circ@res@step \pgf@circ@res@right=\pgf@circ@res@step\fi
  \pgf@circ@res@left=-\pgf@circ@res@right
  \pgf@circ@res@up=\ctikzvalof{quadpoles/blackbox/height}\pgf@circ@res@temp
  \pgf@circ@res@step=0.5\ht\pgfnodeparttextbox
  \advance\pgf@circ@res@step by \ctikzvalof{quadpoles/blackbox/sep}%
  \ifdim\pgf@circ@res@up<\pgf@circ@res@step \pgf@circ@res@up=\pgf@circ@res@step\fi
  \pgf@circ@res@down=-\pgf@circ@res@up
  \pgfstartlinewidth=\pgflinewidth% don't know why this is needed
}

\savedanchor{\northeast}{\pgfpoint{\pgf@circ@res@right}{\pgf@circ@res@up}}
\savedanchor{\southwest}{\pgfpoint{\pgf@circ@res@left}{\pgf@circ@res@down}}

\anchor{north east}{\northeast}
\anchor{south west}{\southwest}
\anchor{north}{\pgfextracty{\pgf@circ@res@up}{\northeast}\pgfpoint{0cm}{\pgf@circ@res@up}}
\anchor{north west}{\pgfextracty{\pgf@circ@res@up}{\northeast}\pgfextractx{\pgf@circ@res@left}{\southwest}\pgfpoint{\pgf@circ@res@left}{\pgf@circ@res@up}}
\anchor{west}{\pgfextractx{\pgf@circ@res@left}{\sosuthwest}\pgfpoint{\pgf@circ@res@left}{0cm}}
\anchor{south}{\pgfextracty{\pgf@circ@res@down}{\southwest}\pgfpoint{0cm}{\pgf@circ@res@down}}
\anchor{south east}{\pgfextracty{\pgf@circ@res@down}{\southwest}\pgfextractx{\pgf@circ@res@right}{\northeast}\pgfpoint{\pgf@circ@res@right}{\pgf@circ@res@down}}
\anchor{east}{\pgfextractx{\pgf@circ@res@right}{\northeast}\pgfpoint{\pgf@circ@res@right}{0cm}}

\savedanchor{\inone}{%
  \pgf@circ@res@step=-\ctikzvalof{quadpoles/blackbox/lead}\pgf@circ@res@temp
  \advance\pgf@circ@res@step by \pgf@circ@res@left
  \pgfpoint{\pgf@circ@res@step}{0.5\pgf@circ@res@up}
}
\anchor{in1}{\inone}

\savedanchor{\intwo}{%
  \pgf@circ@res@step=-\ctikzvalof{quadpoles/blackbox/lead}\pgf@circ@res@temp
  \advance\pgf@circ@res@step by \pgf@circ@res@left
  \pgfpoint{\pgf@circ@res@step}{0.5\pgf@circ@res@down}
}
\anchor{in2}{\intwo}

\savedanchor{\outone}{%
  \pgf@circ@res@step=\ctikzvalof{quadpoles/blackbox/lead}\pgf@circ@res@temp
  \advance\pgf@circ@res@step by \pgf@circ@res@right
  \pgfpoint{\pgf@circ@res@step}{0.5\pgf@circ@res@up}
}
\anchor{out1}{\outone}

\savedanchor{\outtwo}{%
  \pgf@circ@res@step=\ctikzvalof{quadpoles/blackbox/lead}\pgf@circ@res@temp
  \advance\pgf@circ@res@step by \pgf@circ@res@right
  \pgfpoint{\pgf@circ@res@step}{0.5\pgf@circ@res@down}
}
\anchor{out2}{\outtwo}

\foregroundpath{% border and leads drawn here
  \pgfextractx{\pgf@circ@res@right}{\northeast}
  \pgfextracty{\pgf@circ@res@up}{\northeast}
    \pgfextractx{\pgf@circ@res@left}{\southwest}
    \pgfextracty{\pgf@circ@res@down}{\southwest}

  \pgfsetlinewidth{\pgfkeysvalueof{/tikz/circuitikz/bipoles/thickness}\pgfstartlinewidth}%
  \pgfpathrectanglecorners{\southwest}{\northeast}%
  \pgfusepath{draw}%
  \pgfscope
    \pgfsetlinewidth{\pgfstartlinewidth}%
    \pgfpathmoveto{\inone}%
    \pgfextracty{\pgf@circ@res@step}{\inone}%
    \pgfpathlineto{\pgfpoint{\pgf@circ@res@left}{\pgf@circ@res@step}}%
    \pgfpathmoveto{\intwo}%
    \pgfextracty{\pgf@circ@res@step}{\intwo}%
    \pgfpathlineto{\pgfpoint{\pgf@circ@res@left}{\pgf@circ@res@step}}%
    \pgfpathmoveto{\outone}%
    \pgfextracty{\pgf@circ@res@step}{\outone}%
    \pgfpathlineto{\pgfpoint{\pgf@circ@res@right}{\pgf@circ@res@step}}%
    \pgfpathmoveto{\outtwo}%
    \pgfextracty{\pgf@circ@res@step}{\outtwo}%
    \pgfpathlineto{\pgfpoint{\pgf@circ@res@right}{\pgf@circ@res@step}}%
    \pgfusepath{draw}%
  \endpgfscope
}}
\makeatother

\begin{document}
\begin{circuitikz}% or tikzpicture
\node[blackbox] (A) at (0,0) {text};
\node[blackbox,anchor=in1] (B) at (A.out1) {more text};
\end{circuitikz}
\end{document}

Unfortunately, I get this error

! Missing number, treated as zero.
<to be read again> 
                   \pgfk@/tikz/circuitikz/bipoles/length 
l.103 \node[blackbox] (A) at (0,0) {text};

I tried to debug in vain... I replaced the \ctikzvalof{bipoles/length} with a manual length (e.g. 1cm) but then it complains about an unknown macro \savedanchor

Rather, I tried to find another example which works. For example the code below compilates fine while it calls the \savedanchor too:

\documentclass[border=1pt]{standalone}
\usepackage{circuitikz}

\makeatletter
% ************************** multipoles *****************************

\ctikzset{multipoles/.is family}
\ctikzset{multipoles/pin spacing/.initial = 5mm} % default value
\ctikzset{multipoles/gate spacing/.initial = 1cm} % default value

\pgfkeys{/tikz/pin spacing/.initial = 0mm}
\pgfkeys{/tikz/pin spacing/.default = 0mm}

\newlength{\IClen}  % scale factor
\newcommand{\pinsize}{\ifdim\IClen<3.5mm \tiny \else \scriptsize \fi}

\newcommand{\Compass}% define anchors for compass points
{\anchor{north east}{\northeast}
\anchor{south west}{\southwest}
\anchor{north}{\pgfextracty{\pgf@circ@res@up}{\northeast}\pgfpoint{0cm}{\pgf@circ@res@up}}
\anchor{north west}{\pgfextracty{\pgf@circ@res@up}{\northeast}\pgfextractx{\pgf@circ@res@left}{\southwest}\pgfpoint{\pgf@circ@res@left}{\pgf@circ@res@up}}
\anchor{west}{\pgfextractx{\pgf@circ@res@left}{\sosuthwest}\pgfpoint{\pgf@circ@res@left}{0cm}}
\anchor{south}{\pgfextracty{\pgf@circ@res@down}{\southwest}\pgfpoint{0cm}{\pgf@circ@res@down}}
\anchor{south east}{\pgfextracty{\pgf@circ@res@down}{\southwest}\pgfextractx{\pgf@circ@res@right}{\northeast}\pgfpoint{\pgf@circ@res@right}{\pgf@circ@res@down}}
\anchor{east}{\pgfextractx{\pgf@circ@res@right}{\northeast}\pgfpoint{\pgf@circ@res@right}{0cm}}}

% ***************************** dip 28 *********************************
\pgfdeclareshape{dip28}{
\anchor{center}{\pgfpointorigin}    % within the node, (0,0) is the center

\anchor{text}   % this is used to center the text in the node
    {\pgfpoint{-.5\wd\pgfnodeparttextbox}{-.5\ht\pgfnodeparttextbox}}

\savedmacro{\resize}{   % called automatically
 \setlength{\IClen}{\pgfkeysvalueof{/tikz/pin spacing}} % from node[]
 \ifdim\IClen=0mm \setlength{\IClen}
  {\pgfkeysvalueof{/tikz/circuitikz/multipoles/pin spacing}} \fi    % from \ctikzset{}
}
\savedanchor\icpina{\pgfpoint{-6.5\IClen}{-2.5\IClen}}  % pin 1
\anchor{p1}{\icpina}
\savedanchor\icpinb{\pgfpoint{-5.5\IClen}{-2.5\IClen}}  % pin 2
\anchor{p2}{\icpinb}
\savedanchor\icpinc{\pgfpoint{-4.5\IClen}{-2.5\IClen}}  % pin 3
\anchor{p3}{\icpinc}
\savedanchor\icpind{\pgfpoint{-3.5\IClen}{-2.5\IClen}}  % pin 4
\anchor{p4}{\icpind}
\savedanchor\icpine{\pgfpoint{-2.5\IClen}{-2.5\IClen}}  % pin 5
\anchor{p5}{\icpine}
\savedanchor\icpinf{\pgfpoint{-1.5\IClen}{-2.5\IClen}}  % pin 6
\anchor{p6}{\icpinf}
\savedanchor\icping{\pgfpoint{-.5\IClen}{-2.5\IClen}}   % pin 7
\anchor{p7}{\icping}
\savedanchor\icpinh{\pgfpoint{.5\IClen}{-2.5\IClen}}    % pin 8
\anchor{p8}{\icpinh}
\savedanchor\icpini{\pgfpoint{1.5\IClen}{-2.5\IClen}}   % pin 9
\anchor{p9}{\icpini}
\savedanchor\icpinj{\pgfpoint{2.5\IClen}{-2.5\IClen}}   % pin 10
\anchor{p10}{\icpinj}
\savedanchor\icpink{\pgfpoint{3.5\IClen}{-2.5\IClen}}   % pin 11
\anchor{p11}{\icpink}
\savedanchor\icpinl{\pgfpoint{4.5\IClen}{-2.5\IClen}}   % pin 12
\anchor{p12}{\icpinl}
\savedanchor\icpinm{\pgfpoint{5.5\IClen}{-2.5\IClen}}   % pin 13
\anchor{p13}{\icpinm}
\savedanchor\icpinn{\pgfpoint{6.5\IClen}{-2.5\IClen}}   % pin 14
\anchor{p14}{\icpinn}
\savedanchor\icpino{\pgfpoint{6.5\IClen}{2.5\IClen}}    % pin 15
\anchor{p15}{\icpino}
\savedanchor\icpinp{\pgfpoint{5.5\IClen}{2.5\IClen}}    % pin 16
\anchor{p16}{\icpinp}
\savedanchor\icpinq{\pgfpoint{4.5\IClen}{2.5\IClen}}    % pin 17
\anchor{p17}{\icpinq}
\savedanchor\icpinr{\pgfpoint{3.5\IClen}{2.5\IClen}}    % pin 18
\anchor{p18}{\icpinr}
\savedanchor\icpins{\pgfpoint{2.5\IClen}{2.5\IClen}}    % pin 19
\anchor{p19}{\icpins}
\savedanchor\icpint{\pgfpoint{1.5\IClen}{2.5\IClen}}    % pin 20
\anchor{p20}{\icpint}
\savedanchor\icpinu{\pgfpoint{.5\IClen}{2.5\IClen}} % pin 21
\anchor{p21}{\icpinu}
\savedanchor\icpinv{\pgfpoint{-.5\IClen}{2.5\IClen}}    % pin 22
\anchor{p22}{\icpinv}
\savedanchor\icpinw{\pgfpoint{-1.5\IClen}{2.5\IClen}}   % pin 23
\anchor{p23}{\icpinw}
\savedanchor\icpinx{\pgfpoint{-2.5\IClen}{2.5\IClen}}   % pin 24
\anchor{p24}{\icpinx}
\savedanchor\icpiny{\pgfpoint{-3.5\IClen}{2.5\IClen}}   % pin 25
\anchor{p25}{\icpiny}
\savedanchor\icpinz{\pgfpoint{-4.5\IClen}{2.5\IClen}}   % pin 26
\anchor{p26}{\icpinz}
\savedanchor\icpinaa{\pgfpoint{-5.5\IClen}{2.5\IClen}}  % pin 27
\anchor{p27}{\icpinaa}
\savedanchor\icpinab{\pgfpoint{-6.5\IClen}{2.5\IClen}}  % pin 28
\anchor{p28}{\icpinab}

\savedanchor{\northeast}{\pgfpoint{7\IClen}{2.5\IClen}}
\savedanchor{\southwest}{\pgfpoint{-7\IClen}{-2.5\IClen}}
\Compass% standard anchors

\foregroundpath{ % border and pin numbers are drawn here
 \pgfsetlinewidth{.1\IClen} % line thickness 
 \pgfpathrectanglecorners{\southwest}{\northeast}
 \pgfusepath{draw}  %draw rectangle
 \pgfsetlinewidth{.06\IClen} % line thickness 
 \pgfpathmoveto{\pgfpoint{-7\IClen}{-.6\IClen}}
 \pgfpatharc{-90}{90}{.6\IClen}
 \pgfusepath{draw}  %draw semicircle
 \pgftext[bottom,at={\pgfpoint{-6.5\IClen}{-2.2\IClen}}]{\pinsize 1}
 \pgftext[bottom,at={\pgfpoint{-5.5\IClen}{-2.2\IClen}}]{\pinsize 2}
 \pgftext[bottom,at={\pgfpoint{-4.5\IClen}{-2.2\IClen}}]{\pinsize 3}
 \pgftext[bottom,at={\pgfpoint{-3.5\IClen}{-2.2\IClen}}]{\pinsize 4}
 \pgftext[bottom,at={\pgfpoint{-2.5\IClen}{-2.2\IClen}}]{\pinsize 5}
 \pgftext[bottom,at={\pgfpoint{-1.5\IClen}{-2.2\IClen}}]{\pinsize 6}
 \pgftext[bottom,at={\pgfpoint{-.5\IClen}{-2.2\IClen}}]{\pinsize 7}
 \pgftext[bottom,at={\pgfpoint{.5\IClen}{-2.2\IClen}}]{\pinsize 8}
 \pgftext[bottom,at={\pgfpoint{1.5\IClen}{-2.2\IClen}}]{\pinsize 9}
 \pgftext[bottom,at={\pgfpoint{2.5\IClen}{-2.2\IClen}}]{\pinsize 10}
 \pgftext[bottom,at={\pgfpoint{3.5\IClen}{-2.2\IClen}}]{\pinsize 11}
 \pgftext[bottom,at={\pgfpoint{4.5\IClen}{-2.2\IClen}}]{\pinsize 12}
 \pgftext[bottom,at={\pgfpoint{5.5\IClen}{-2.2\IClen}}]{\pinsize 13}
 \pgftext[bottom,at={\pgfpoint{6.5\IClen}{-2.2\IClen}}]{\pinsize 14}
 \pgftext[top,at={\pgfpoint{6.5\IClen}{2.2\IClen}}]{\pinsize 15}
 \pgftext[top,at={\pgfpoint{5.5\IClen}{2.2\IClen}}]{\pinsize 16}
 \pgftext[top,at={\pgfpoint{4.5\IClen}{2.2\IClen}}]{\pinsize 17}
 \pgftext[top,at={\pgfpoint{3.5\IClen}{2.2\IClen}}]{\pinsize 18}
 \pgftext[top,at={\pgfpoint{2.5\IClen}{2.2\IClen}}]{\pinsize 19}
 \pgftext[top,at={\pgfpoint{1.5\IClen}{2.2\IClen}}]{\pinsize 20}
 \pgftext[top,at={\pgfpoint{.5\IClen}{2.2\IClen}}]{\pinsize 21}
 \pgftext[top,at={\pgfpoint{-.5\IClen}{2.2\IClen}}]{\pinsize 22}
 \pgftext[top,at={\pgfpoint{-1.5\IClen}{2.2\IClen}}]{\pinsize 23}
 \pgftext[top,at={\pgfpoint{-2.5\IClen}{2.2\IClen}}]{\pinsize 24}
 \pgftext[top,at={\pgfpoint{-3.5\IClen}{2.2\IClen}}]{\pinsize 25}
 \pgftext[top,at={\pgfpoint{-4.5\IClen}{2.2\IClen}}]{\pinsize 26}
 \pgftext[top,at={\pgfpoint{-5.5\IClen}{2.2\IClen}}]{\pinsize 27}
 \pgftext[top,at={\pgfpoint{-6.5\IClen}{2.2\IClen}}]{\pinsize 28}
}}
\makeatother

\begin{document}
\begin{circuitikz}
\draw (2,3.5) node[dip28] (Q) {MCP23017};
 \draw
(Q.p1) -- +(0,-.5)
(Q.p2) -- +(0,-.5)
(Q.p3) -- +(0,-.5)
(Q.p4) -- +(0,-.5)
(Q.p5) -- +(0,-.5)
(Q.p6) -- +(0,-.5)
(Q.p7) -- +(0,-.5)
(Q.p8) -- +(0,-.5)
(Q.p9) -- +(0,-.5)
(Q.p10) -- +(0,-.5)
(Q.p11) -- +(0,-.5)
(Q.p12) -- +(0,-.5)
(Q.p13) -- +(0,-.5)
(Q.p14) -- +(0,-.5)
(Q.p15) -- +(0,.5)
(Q.p16) -- +(0,.5)
(Q.p17) -- +(0,.5)
(Q.p18) -- +(0,.5)
(Q.p19) -- +(0,.5)
(Q.p20) -- +(0,.5)
(Q.p21) -- +(0,.5)
(Q.p22) -- +(0,.5)
(Q.p23) -- +(0,.5)
(Q.p24) -- +(0,.5)
(Q.p25) -- +(0,.5)
(Q.p26) -- +(0,.5)
(Q.p27) -- +(0,.5)
(Q.p28) -- +(0,.5);
\end{circuitikz}
\end{document}


thank you for your help!

2
  • 1
    Welcome to TeX.SE. Can't you use dipchip or qfpchip instead of creating a new component?
    – nidhin
    Nov 1, 2019 at 14:01
  • @nidhin: I did not know those two modular components existed. Yes, this will do the trick so thank you much! However, I wait for other answers because I'd like to know what is going wrong with that ``blackbox```component...
    – Vincent
    Nov 1, 2019 at 14:41

2 Answers 2

6

The error is due to the fact the the key circuititz/bipoles/length is not a normal "value" key, is just a .code to set the internal variable pgf@circ@Rlen.

So you have to substitute the line:

\pgf@circ@res@temp=\ctikzvalof{bipoles/length}

with

 \pgf@circ@res@temp=\pgf@circ@Rlen

and the error is gone.

2
  • Brilliant! not sure I got the origin of the problem but it does work like a charm!
    – Vincent
    Nov 1, 2019 at 19:03
  • 1
    They changed the definition of bipoles/length. BTW, I (finally) changed my tutorials to match the new definition (see elfsoft2000.com/projects/index.htm). Nov 1, 2019 at 22:52
4

You can use dipchip or qfpchip for drawing quadrupole.

enter image description here

\documentclass[margin=3mm]{standalone}
\usepackage{circuitikz}

\begin{document}
\begin{circuitikz}
\draw (0,0) node[dipchip,num pins=4,external pins width=0.0,no topmark,](C1){IC1};
\draw (0,-2) node[qfpchip,num pins=4,external pins width=0.0,no topmark,](C2){IC1};

\draw (C1.pin 1) to[short] ++(-1,0) |- (C2.pin 1);
\draw (C1.pin 4) to[short] ++(1,0) |- (C2.pin 3);

\end{circuitikz}
\end{document}

EDIT

Aliases can be given to anchors, say input 1 instead of pin 1. See answer to: Renaming anchors in predefined shapes. You can hide the default pin numbers and give desired name to those pins. See MWE:

\documentclass[margin=3mm]{standalone}
\usepackage{circuitikz}
\makeatletter
\newcommand*\pgfdeclareanchoralias[3]{%
    \expandafter\def\csname pgf@anchor@#1@#3\expandafter\endcsname
            \expandafter{\csname pgf@anchor@#1@#2\endcsname}}
\makeatother            

\pgfdeclareanchoralias{dipchip}{pin 1}{input 1}
\pgfdeclareanchoralias{dipchip}{pin 2}{input 2}
\pgfdeclareanchoralias{dipchip}{pin 4}{output 1}
\pgfdeclareanchoralias{dipchip}{pin 3}{output 2}

\begin{document}
\begin{circuitikz}
\draw (0,0) node[dipchip,num pins=4,external pins width=0.0,no topmark,hide numbers](C1){IC1};
\draw (0,-2) node[qfpchip,num pins=4,external pins width=0.0,no topmark,](C2){IC1};

\node [right, font=\tiny] at (C1.bpin 1) {IN1};
\node [right, font=\tiny] at (C1.bpin 2) {IN2};
\node [left, font=\tiny] at (C1.bpin 4) {OUT1};
\node [left, font=\tiny] at (C1.bpin 3) {OUT2};

\draw (C1.input 1) to[short] ++(-1,0) |- (C2.pin 1);
\draw (C1.output 2) to[short] ++(1,0) |- (C2.pin 3);

\end{circuitikz}
\end{document}

enter image description here

3
  • this works too. Thank you. About this, is there a way to rename or alias the C1.pin 1 to C1.input 1 for example?
    – Vincent
    Nov 1, 2019 at 19:06
  • @Vincent Yes. That is possible. See the Edit.
    – nidhin
    Nov 3, 2019 at 3:28
  • Thank you! I also love this short expression which I've been looking for for a while++(-1,0) |- (C2.pin 1); I have never seen a mix between relative ++ and intersection |-. Have you a source, reference?
    – Vincent
    Nov 6, 2019 at 7:10

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .