Archive-name: paraboard-tqfp-is
Submitted-by:
onei...@gmail.com
Last-modified: 2012-04-10 00:00
Copyright-Notice: both the README and the code are in the public domain
README.paraboard-tqfp-is -*- Text -*-
Synopsis
$ mpost [-soutputformat=\"svg\"]
tqfp-1-so-4.mp
Description
This simplistic code in MetaPost is intended to produce an SVG
or PostScript drawing of a stripboard for surface-mounted
components.
The drawing is comprised of five sections: four sections of
stripes (aligned and suitable for mounting components in SOIC
cases), placed around the single section for a TQFP case.
The design is parameterized, and by default, the code produces a
70 mm by 10 mm stripboard drawing. The stripes have .05 in
pitch, and the TQFP footprint has 0.8 mm pitch, and 8 pads on
each of the sides, which are connected to the nearest SOIC
sections' stripes.
Parameters
The eponymous section of the code defines the following,
user-changeable parameters.
board.outrr.sz (70 mm, 100 mm), offset.board (5 mm) — board
“outer” size and the outer to inner offset, respectively;
tqfp.innrr.sz (7 mm, 7 mm), offset.tqfp (4 mm) — TQFP section
“inner” size (the distances between the corresponding pads
at the opposite sides) and offset;
tqfp.len (2 mm), tqfp.stpp (.8 mm) — TQFP section pads length
and pitch;
tqfp.pins (8, 8) — the number of pads along the horizontal and
vertical side of the TQFP case;
offset.so (1 mm) — SOIC section offset;
so.stpp (.05 in), so.break (2 mm) — the pitch of and the gap
between the consequent rows of SOIC stripes;
so[0].parts (4), so[1].parts (2), …, so[3].parts (2) — the
number of the rows of stripes in the SOIC sections;
pen_scale — the pad width to pad pitch ratio;
outputformat — this is a MetaPost's own parameter; when set to
‘svg’, the output is produced in the SVG format instead of
PostScript; the example code to add is:
outputformat := "svg";
(alternatively, this parameter may be passed via an mpost(1)
command line argument.)
Note that it's possible to set the “inner” sizes instead of the
outer ones, and all the four “corner” offsets instead of having
all of the latter equal, though it requires some tweaks to the
code.
Bugs
It still could be made both more simple and more generic.
A possible extension is to allow for both through-hole and mixed
(through-hole and SMT) stripboard designs.
The (0 = 1) conditions within the code correspond to the
disabled “debug features” of the code. It should be possible to
enable those via a parameter, too.
README.paraboard-tqfp-is ends here
%%%
tqfp-1-so-4.mp -*- MetaPost -*-
%% A simple PCB stripboard for SMT (TQFP + 4 SO rectangles.)
%%% Ivan Shmakov, 2012
%% This code is in the public domain.
%%% Code:
%% Parameters
pair
board.outrr.sz;
pair
tqfp.innrr.sz;
pair tqfp.pins;
pair conn.off;
board.outrr.sz = (7 cm, 10 cm);
tqfp.innrr.sz = (7 mm, 7 mm);
offset.board = 5 mm;
offset.so = 1 mm;
offset.tqfp = 4 mm;
so.break = 2 mm;
so[0].parts = 4;
so[1].parts = 2;
so[2].parts = 4;
so[3].parts = 2;
so.stpp = .05 in;
tqfp.len = 2 mm;
tqfp.pins = (8, 8);
tqfp.stpp = 0.8 mm;
conn.off = (1, 1);
pen_scale = .43;
%% Utilities
def linear (suffix z, d) (expr from, to, stride) =
save i;
for i = from step stride until to :
save a;
z[i] = d * a;
endfor;
relax
enddef;
def linear_eq (suffix z) (expr o, stap, from, to, stride) =
save i;
for i = from step stride until to :
z[i] = stap * ((i - from) / stride) + o;
endfor;
relax
enddef;
%% Object classes
def rectangle_ccw (suffix $) (expr angle) =
z$c[0] = $o;
z$c[1] = $o + (xpart $sz, 0) rotated (angle);
z$c[2] = $o + $sz rotated (angle);
z$c[3] = $o + (0, ypart $sz) rotated (angle);
relax
enddef;
def rectangle_path (suffix $) =
%% .
z$c[0] -- z$c[1] -- z$c[2] -- z$c[3] -- cycle;
relax
enddef;
def rectangle_pair (suffix $) =
save j;
for j = 0 upto 3 :
z$innrr.c[j]
= z$outrr.c[j] + $offset[j];
endfor;
relax
enddef;
def so_seat (suffix $) =
%% NB: subclass of rectangle
%% NB: z$c[] have to be known by this time
%% FIXME: allow $stpp to be derived from $pins?
$pins
= 1 + floor (length (z$c[1] - z$c[0]) / $stpp);
($len + $break) * ($parts - 1) + $len
= length (z$c[3] - z$c[0]);
$ustep * (-1 + $pins)
= (z$c[1] - z$c[0]);
$vstep
= unitvector (z$c[3] - z$c[0]) * ($len + $break);
save i;
z$p[0]
= z$c[0];
for i = 0 step 2 * $pins until 2 * $pins * ($parts - 1) :
save dummya, dummyb;
pair dummya, dummyb;
linear_eq (z$p, dummya, $ustep, i, i + 2 * $pins - 2, 2);
linear_eq (z$p, dummyb, $ustep, i + 1, i + 2 * $pins - 1, 2);
$len * unitvector ($vstep)
= z$p[i + 1] - z$p[i];
endfor;
linear_eq (z$p, z$c[0], $vstep,
0,
2 * $pins * ($parts - 1),
2 * $pins);
save dummy;
pair dummy;
linear_eq (z$p, dummy, $vstep,
1,
2 * $pins * ($parts - 1) + 1,
2 * $pins);
if (0 = 1) :
for i = 0 step 2 * $pins until 2 * $pins * ($parts - 1) :
show i, z$p[i + 1], z$p[i];
endfor;
fi;
relax
enddef;
def tqfp_seat (suffix $) =
%% NB: subclass of rectangle
$ustep
= $stpp * unitvector (z$c[1] - z$c[0]);
$vstep
= $stpp * unitvector (z$c[3] - z$c[0]);
save pad, pbd, pn;
pad = 2 * xpart $pins;
pbd = 2 * ypart $pins;
pn = 2 * (pad + pbd);
save a, b, c, d, e, f, g, h;
pair a, b, c, d, e, f, g, h;
% show 0, pad, pbd + pad, pn - pbd, pn;
linear_eq (z$p, a, $ustep, 0, pad - 2, 2);
linear_eq (z$p, e, $ustep, 1, pad - 1, 2);
linear_eq (z$p, b, $vstep, pad + 0, pbd + pad - 2, 2);
linear_eq (z$p, f, $vstep, pad + 1, pbd + pad - 1, 2);
linear_eq (z$p, c, - $ustep, pbd + pad + 0, pn - pbd - 2, 2);
linear_eq (z$p, g, - $ustep, pbd + pad + 1, pn - pbd - 1, 2);
linear_eq (z$p, d, - $vstep, pn - pbd + 0, pn - 2, 2);
linear_eq (z$p, h, - $vstep, pn - pbd + 1, pn - 1, 2);
%% case size
z$p[pn - pbd - 2] - z$p[0]
= z$c[3] - z$c[0];
z$p[pn - 2] - z$p[pad]
= z$c[0] - z$c[1];
%% pads are of the length $len
z$p[1] - z$p[0]
= - $len * unitvector ($vstep);
z$p[pad + 1] - z$p[pad]
= $len * unitvector ($ustep);
z$p[pbd + pad + 1] - z$p[pbd + pad]
= $len * unitvector ($vstep);
z$p[pn - pbd + 1] - z$p[pn - pbd]
= - $len * unitvector ($ustep);
%% the center of the seat (case)
a + c
= z$c[0] + z$c[2];
b + d
= z$c[1] + z$c[3];
% e + f + g + h
% = z$c[0] + z$c[1] + z$c[2] + z$c[3];
% show a, b, c, d, e, f, g, h;
% show z$p[0], z$p[1], z$p[2], z$p[3];
% show z$p[pad], z$p[pad + 1], z$p[pad + 2], z$p[pad + 3];
relax
enddef;
%% The board
beginfig (-1);
pair board.innrr.o,
board.innrr.sz;
pair board.offset[];
pair board.outrr.o; % ,
board.outrr.sz
pair so[].innrr.o, so[].
innrr.sz;
pair so[].innrr.ustep, so[].innrr.vstep;
pair so[].offset[];
pair so[].outrr.o, so[].
outrr.sz;
pair tqfp.innrr.o; % ,
tqfp.innrr.sz
pair tqfp.innrr.ustep, tqfp.innrr.vstep;
pair tqfp.innrr.pins;
pair tqfp.offset[];
pair tqfp.outrr.o,
tqfp.outrr.sz;
%% the board's origin
z.board.outrr.c[1]
= (0, 0);
%% FIXME: huh?
so[0].
outrr.sz = so[2].
outrr.sz;
so[1].
outrr.sz = so[3].
outrr.sz;
rectangle_ccw (board.outrr, -90);
rectangle_ccw (board.innrr, -90);
rectangle_ccw (tqfp.outrr, -90);
rectangle_ccw (tqfp.innrr, -90);
rectangle_pair (board);
rectangle_pair (tqfp);
for j = 0 step 2 until 3 :
board.offset[j]
= offset.board * (1, 1) rotated (90 * (j - 1));
tqfp.offset[j]
= offset.tqfp * (1, 1) rotated (90 * (j - 1));
endfor;
for i = 0 upto 3 :
rectangle_ccw (so[i].outrr, 90 * (i - 1));
rectangle_ccw (so[i].innrr, 90 * (i - 1));
rectangle_pair (so[i]);
z.so[i].outrr.c[0]
= z.tqfp.outrr.c[i];
if (0 = 1) :
show (so[i].
outrr.sz);
show (z.so[i].outrr.c[2]);
show (z.board.outrr.c[(i + 1) mod 4]);
show ((i + 1) mod 4);
fi;
z.so[i].outrr.c[2]
= z.board.innrr.c[((i + 1) mod 4)];
for j = 0 step 2 until 3 :
so[i].offset[j]
= offset.so * (1, 1) rotated (90 * (2 + i - j));
endfor;
endfor;
if (0 = 1) :
show ("z.board.innrr");
show (
board.innrr.sz);
show (z.board.innrr.c[0]);
show (z.board.innrr.c[1]);
show (z.board.innrr.c[2]);
show (z.board.innrr.c[3]);
show ("z.tqfp.innrr");
show (
tqfp.innrr.sz);
show (z.tqfp.innrr.c[0]);
show (z.tqfp.innrr.c[1]);
show (z.tqfp.innrr.c[2]);
show (z.tqfp.innrr.c[3]);
show ("z.tqfp.outrr");
show (
tqfp.outrr.sz);
show (z.tqfp.outrr.c[0]);
show (z.tqfp.outrr.c[1]);
show (z.tqfp.outrr.c[2]);
show (z.tqfp.outrr.c[3]);
fi;
for i = 0 upto 3 :
if (0 = 1) :
show ("z.so[i].outrr");
show (so[i].
outrr.sz);
show (z.so[i].outrr.c[0]);
show (z.so[i].outrr.c[1]);
show (z.so[i].outrr.c[2]);
show (z.so[i].outrr.c[3]);
show ("z.so[i].intrr");
show (so[i].
innrr.sz);
show (z.so[i].innrr.c[0]);
show (z.so[i].innrr.c[1]);
show (z.so[i].innrr.c[2]);
show (z.so[i].innrr.c[3]);
fi;
so[i].innrr.break = so.break;
so[i].innrr.p.ds = so[i].parts * so[i].innrr.pins;
so[i].innrr.parts = so[i].parts;
so[i].innrr.stpp = so.stpp;
so_seat (so[i].innrr);
endfor;
tqfp.innrr.len = tqfp.len;
tqfp.innrr.p.ds = 2 * (xpart tqfp.pins + ypart tqfp.pins);
tqfp.innrr.pins = tqfp.pins;
tqfp.innrr.stpp = tqfp.stpp;
tqfp_seat (tqfp.innrr);
%% at last, connect TQFP pads to the SO ones
%% FIXME: clean this one up?
pad := 2 * xpart tqfp.pins;
pbd := 2 * ypart tqfp.pins;
pn := 2 * (pad + pbd);
conn.p.ds = pn / 2;
conn.stpp = tqfp.innrr.stpp;
for j = 0 step 2 until pad - 2 :
k := j + pad + pbd;
z.conn.p[j] = z.tqfp.innrr.p[j + 1];
z.conn.p[j + 1] = z.so[0].innrr.p[j + 2 * xpart conn.off];
z.conn.p[k] = z.tqfp.innrr.p[k + 1];
z.conn.p[k + 1] = z.so[2].innrr.p[j + 2 * xpart conn.off];
endfor;
for j = 0 step 2 until pbd - 2 :
k := j + pad + pbd;
z.conn.p[j + pad] = z.tqfp.innrr.p[j + pad + 1];
z.conn.p[j + pad + 1] = z.so[1].innrr.p[j + 2 * ypart conn.off];
z.conn.p[k + pad] = z.tqfp.innrr.p[k + pad + 1];
z.conn.p[k + pad + 1] = z.so[3].innrr.p[j + 2 * ypart conn.off];
endfor;
%% now, draw it all
if (0 = 1) :
%% draw all the rectangles (for debugging purposes)
pickup pencircle scaled (.11 mm);
forsuffixes s
= board.outrr, tqfp.outrr,
so[0].outrr, so[1].outrr, so[2].outrr, so[3].outrr :
draw rectangle_path (s);
endfor;
pickup pencircle scaled (.07 mm);
forsuffixes s
= board.innrr, tqfp.innrr,
so[0].innrr, so[1].innrr, so[2].innrr, so[3].innrr :
draw rectangle_path (s);
endfor;
fi;
forsuffixes $
= tqfp.innrr,
conn,
so[0].innrr, so[1].innrr, so[2].innrr, so[3].innrr :
pickup pencircle scaled (pen_scale * $stpp);
% show $p.ds;
for j = 0 step 2 until 2 * $p.ds - 1 :
draw (z$p[j] -- z$p[j + 1]);
endfor;
endfor;
endfig;
end;
%%% Emacs trailer
%% Local variables:
%% coding: us-ascii
%% indent-tabs-mode: nil
%% ispell-local-dictionary: "american"
%% End:
%%%
tqfp-1-so-4.mp ends here
--
FSF associate member #7257