From afa7e13b9778dabc4fd8bb4e9e55d8d577d3f6ed Mon Sep 17 00:00:00 2001 From: Quentin Bolsee <quentinbolsee@hotmail.com> Date: Mon, 17 Jan 2022 17:29:52 +0100 Subject: [PATCH] Added serialstep DRV8428P --- serialstep/board/hello.DRV8428-D11C-NEMA17 | 8378 +++++++++++++++++ .../board/hello.DRV8428-D11C-NEMA17.holes.png | Bin 0 -> 17614 bytes .../hello.DRV8428-D11C-NEMA17.interior.png | Bin 0 -> 16144 bytes .../board/hello.DRV8428-D11C-NEMA17.png | Bin 0 -> 84778 bytes .../hello.DRV8428-D11C-NEMA17.traces.png | Bin 0 -> 23877 bytes .../board/hello.DRV8428P-D11C-NEMA17 | 8371 ++++++++++++++++ .../hello.DRV8428P-D11C-NEMA17.holes.png | Bin 0 -> 21455 bytes .../hello.DRV8428P-D11C-NEMA17.interior.png | Bin 0 -> 20296 bytes .../board/hello.DRV8428P-D11C-NEMA17.png | Bin 0 -> 56114 bytes .../hello.DRV8428P-D11C-NEMA17.traces.png | Bin 0 -> 23212 bytes 10 files changed, 16749 insertions(+) create mode 100644 serialstep/board/hello.DRV8428-D11C-NEMA17 create mode 100644 serialstep/board/hello.DRV8428-D11C-NEMA17.holes.png create mode 100644 serialstep/board/hello.DRV8428-D11C-NEMA17.interior.png create mode 100644 serialstep/board/hello.DRV8428-D11C-NEMA17.png create mode 100644 serialstep/board/hello.DRV8428-D11C-NEMA17.traces.png create mode 100644 serialstep/serialstep-DRV8428P/board/hello.DRV8428P-D11C-NEMA17 create mode 100644 serialstep/serialstep-DRV8428P/board/hello.DRV8428P-D11C-NEMA17.holes.png create mode 100644 serialstep/serialstep-DRV8428P/board/hello.DRV8428P-D11C-NEMA17.interior.png create mode 100644 serialstep/serialstep-DRV8428P/board/hello.DRV8428P-D11C-NEMA17.png create mode 100644 serialstep/serialstep-DRV8428P/board/hello.DRV8428P-D11C-NEMA17.traces.png diff --git a/serialstep/board/hello.DRV8428-D11C-NEMA17 b/serialstep/board/hello.DRV8428-D11C-NEMA17 new file mode 100644 index 0000000..e2164e8 --- /dev/null +++ b/serialstep/board/hello.DRV8428-D11C-NEMA17 @@ -0,0 +1,8378 @@ +#!/usr/bin/env python3 +# +# hello.DRV8428-D11C-NEMA17 +# DRV8428 NEMA17 stepper hello-world with D11C interface +# +# usage: +# hello.DRV8428-D11C-NEMA17 | frep.py [dpi [filename]] +# +# Neil Gershenfeld 8/13/21 +# +# This work may be reproduced, modified, distributed, +# performed, and displayed for any purpose, but must +# acknowledge this project. Copyright is retained and +# must be preserved. The work is provided as is; no +# warranty is provided, and users accept all liability. +# + +############################################################ +# uncomment for desired output +############################################################ + +#output = "top, labels, and exterior" +output = "top, labels, holes, and exterior" +#output = "top, bottom, labels, and exterior" +#output = "top, bottom, labels, holes, and exterior" +#output = "top traces" +#output = "top traces and exterior" +#output = "bottom traces reversed" +#output = "bottom traces reversed and exterior" +#output = "holes" +#output = "interior" +#output = "holes and interior" +#output = "exterior" +#output = "solder mask" + +############################################################ +# import +############################################################ + +import math,json,sys + +############################################################ +# define shapes and transformations +############################################################ + +# color(color,part) +# circle(x,y,r) +# cylinder(x,y,z0,z1,r) +# cone(x,y,z0,z1,r) +# sphere(x,y,z,r) +# torus(x,y,z,r0,r1) +# rectangle(x0,x1,y0,y1) +# cube(x0,x1,y0,y1,z0,z1) +# line(x0,y0,x1,y1,z,width) +# right_triangle(x,y,h) +# triangle(x0,y0,x1,y1,x2,y2) (points in clockwise order) +# pyramid(x0,x1,y0,y1,z0,z1) +# function(Z_of_XY) +# functions(upper_Z_of_XY,lower_Z_of_XY) +# add(part1,part2) +# subtract(part1,part2) +# intersect(part1,part2) +# move(part,dx,dy) +# translate(part,dx,dy,dz) +# rotate(part, angle) +# rotate_x(part,angle) +# rotate_y(part,angle) +# rotate_z(part,angle) +# rotate_90(part) +# rotate_180(part) +# rotate_270(part) +# reflect_x(part,x0) +# reflect_y(part,y0) +# reflect_z(part,z0) +# reflect_xy(part) +# reflect_xz(part) +# reflect_yz(part) +# scale_x(part,x0,sx) +# scale_y(part,y0,sy) +# scale_z(part,z0,sz) +# scale_xy(part,x0,y0,sxy) +# scale_xyz(part,x0,y0,z0,sxyz) +# coscale_x_y(part,x0,y0,y1,angle0,angle1,amplitude,offset) +# coscale_x_z(part,x0,z0 z1,angle0,angle1,amplitude,offset) +# coscale_xy_z(part,x0,y0,z0,z1,angle0,angle1,amplitude,offset) +# taper_x_y(part,x0,y0,y1,s0,s1) +# taper_x_z(part,x0,z0,z1,s0,s1) +# taper_xy_z(part,x0,y0,z0,z1,s0,s1) +# shear_x_y(part,y0,y1,dx0,dx1) +# shear_x_z(part,z0,z1,dx0,dx1) + +true = "1" +false = "0" + +def color(color,part): + part = '('+str(color)+'*(('+part+')!=0))' + return part + +Red = (225 << 0) +Green = (225 << 8) +Blue = (225 << 16) +Gray = (128 << 16) + (128 << 8) + (128 << 0) +White = (255 << 16) + (255 << 8) + (255 << 0) +Teal = (255 << 16) + (255 << 8) +Pink = (255 << 16) + (255 << 0) +Yellow = (255 << 8) + (255 << 0) +Brown = (45 << 16) + (82 << 8) + (145 << 0) +Navy = (128 << 16) + (0 << 8) + (0 << 0) +Tan = (60 << 16) + (90 << 8) + (125 << 0) + +def circle(x0,y0,r): + part = "(((X-(x0))*(X-(x0)) + (Y-(y0))*(Y-(y0))) <= (r*r))" + part = part.replace('x0',str(x0)) + part = part.replace('y0',str(y0)) + part = part.replace('r',str(r)) + return part + +def cylinder(x0,y0,z0,z1,r): + part = "(((X-(x0))*(X-(x0)) + (Y-(y0))*(Y-(y0)) <= (r*r)) & (Z >= (z0)) & (Z <= (z1)))" + part = part.replace('x0',str(x0)) + part = part.replace('y0',str(y0)) + part = part.replace('z0',str(z0)) + part = part.replace('z1',str(z1)) + part = part.replace('r',str(r)) + return part + +def cone(x0,y0,z0,z1,r0): + part = cylinder(x0, y0, z0, z1, r0) + part = taper_xy_z(part, x0, y0, z0, z1, 1.0, 0.0) + return part + +def sphere(x0,y0,z0,r): + part = "(((X-(x0))*(X-(x0)) + (Y-(y0))*(Y-(y0)) + (Z-(z0))*(Z-(z0))) <= (r*r))" + part = part.replace('x0',str(x0)) + part = part.replace('y0',str(y0)) + part = part.replace('z0',str(z0)) + part = part.replace('r',str(r)) + return part + +def torus(x0,y0,z0,r0,r1): + part = "(((r0 - sqrt((X-(x0))*(X-(x0)) + (Y-(y0))*(Y-(y0))))*(r0 - sqrt((X-(x0))*(X-(x0)) + (Y-(y0))*(Y-(y0))) + (Z-(z0))*(Z-(z0))) <= (r1*r1))" + part = part.replace('x0',str(x0)) + part = part.replace('y0',str(y0)) + part = part.replace('z0',str(z0)) + part = part.replace('r0',str(r0)) + part = part.replace('r1',str(r1)) + return part + +def rectangle(x0,x1,y0,y1): + part = "((X >= (x0)) & (X <= (x1)) & (Y >= (y0)) & (Y <= (y1)))" + part = part.replace('x0',str(x0)) + part = part.replace('x1',str(x1)) + part = part.replace('y0',str(y0)) + part = part.replace('y1',str(y1)) + return part + +def cube(x0,x1,y0,y1,z0,z1): + part = "((X >= (x0)) & (X <= (x1)) & (Y >= (y0)) & (Y <= (y1)) & (Z >= (z0)) & (Z <= (z1)))" + part = part.replace('x0',str(x0)) + part = part.replace('x1',str(x1)) + part = part.replace('y0',str(y0)) + part = part.replace('y1',str(y1)) + part = part.replace('z0',str(z0)) + part = part.replace('z1',str(z1)) + return part + +def line(x0,y0,x1,y1,z,width): + dx = x1-x0 + dy = y1-y0 + l = math.sqrt(dx*dx+dy*dy) + nx = dx/l + ny = dy/l + rx = -ny + ry = nx + part = "((((X-(x0))*(nx)+(Y-(y0))*(ny)) >= 0) & (((X-(x0))*(nx)+(Y-(y0))*(ny)) <= l) & (((X-(x0))*(rx)+(Y-(y0))*(ry)) >= (-width/2)) & (((X-(x0))*(rx)+(Y-(y0))*(ry)) <= (width/2)) & (Z == z))" + part = part.replace('x0',str(x0)) + part = part.replace('x1',str(x1)) + part = part.replace('y0',str(y0)) + part = part.replace('y1',str(y1)) + part = part.replace('nx',str(nx)) + part = part.replace('ny',str(ny)) + part = part.replace('rx',str(rx)) + part = part.replace('ry',str(ry)) + part = part.replace('l',str(l)) + part = part.replace('z',str(z)) + part = part.replace('width',str(width)) + return part + +def right_triangle(x0,y0,l): + part = "((X > x0) & (X < x0 + l - (Y-y0)) & (Y > y0))" + part = part.replace('x0',str(x0)) + part = part.replace('y0',str(y0)) + part = part.replace('l',str(l)) + return part + +def triangle(x0,y0,x1,y1,x2,y2): # points in clockwise order + part = "(((((y1)-(y0))*(X-(x0))-((x1)-(x0))*(Y-(y0))) >= 0) & ((((y2)-(y1))*(X-(x1))-((x2)-(x1))*(Y-(y1))) >= 0) & ((((y0)-(y2))*(X-(x2))-((x0)-(x2))*(Y-(y2))) >= 0))" + part = part.replace('x0',str(x0)) + part = part.replace('y0',str(y0)) + part = part.replace('x1',str(x1)) + part = part.replace('y1',str(y1)) + part = part.replace('x2',str(x2)) + part = part.replace('y2',str(y2)) + return part + +def pyramid(x0,x1,y0,y1,z0,z1): + part = cube(x0, x1, y0, y1, z0, z1) + part = taper_xy_z(part, (x0+x1)/2., (y0+y1)/2., z0, z1, 1.0, 0.0) + return part + +def function(Z_of_XY): + part = '(Z <= '+Z_of_XY+')' + return part + +def functions(upper_Z_of_XY,lower_Z_of_XY): + part = '(Z <= '+upper_Z_of_XY+') & (Z >= '+lower_Z_of_XY+')' + return part + +def add(part1,part2): + part = "part1 | part2" + part = part.replace('part1',part1) + part = part.replace('part2',part2) + return part + +def subtract(part1,part2): + part = "(part1) & ~(part2)" + part = part.replace('part1',part1) + part = part.replace('part2',part2) + return part + +def intersect(part1,part2): + part = "(part1) & (part2)" + part = part.replace('part1',part1) + part = part.replace('part2',part2) + return part + +def move(part,dx,dy): + part = part.replace('X','(X-('+str(dx)+'))') + part = part.replace('Y','(Y-('+str(dy)+'))') + return part + +def translate(part,dx,dy,dz): + part = part.replace('X','(X-('+str(dx)+'))') + part = part.replace('Y','(Y-('+str(dy)+'))') + part = part.replace('Z','(Z-('+str(dz)+'))') + return part + +def rotate(part,angle): + angle = angle*math.pi/180 + part = part.replace('X','(math.cos(angle)*X+math.sin(angle)*y)') + part = part.replace('Y','(-math.sin(angle)*X+math.cos(angle)*y)') + part = part.replace('y','Y') + part = part.replace('angle',str(angle)) + return part + +def rotate_x(part,angle): + angle = angle*math.pi/180 + part = part.replace('Y','(math.cos(angle)*Y+math.sin(angle)*z)') + part = part.replace('Z','(-math.sin(angle)*Y+math.cos(angle)*z)') + part = part.replace('z','Z') + part = part.replace('angle',str(angle)) + return part + +def rotate_y(part,angle): + angle = angle*math.pi/180 + part = part.replace('X','(math.cos(angle)*X+math.sin(angle)*z)') + part = part.replace('Z','(-math.sin(angle)*X+math.cos(angle)*z)') + part = part.replace('z','Z') + part = part.replace('angle',str(angle)) + return part + +def rotate_z(part,angle): + angle = angle*math.pi/180 + part = part.replace('X','(math.cos(angle)*X+math.sin(angle)*y)') + part = part.replace('Y','(-math.sin(angle)*X+math.cos(angle)*y)') + part = part.replace('y','Y') + part = part.replace('angle',str(angle)) + return part + +def rotate_90(part): + part = reflect_y(part,0) + part = reflect_xy(part) + return part + +def rotate_180(part): + part = rotate_90(part) + part = rotate_90(part) + return part + +def rotate_270(part): + part = rotate_90(part) + part = rotate_90(part) + part = rotate_90(part) + return part + +def reflect_x(part,x0): + part = part.replace('X','(x0-X)') + part = part.replace('x0',str(x0)) + return part + +def reflect_y(part,y0): + part = part.replace('Y','(y0-Y)') + part = part.replace('y0',str(y0)) + return part + +def reflect_z(part,z0): + part = part.replace('Z','(z0-Z)') + part = part.replace('z0',str(z0)) + return part + +def reflect_xy(part): + part = part.replace('X','temp') + part = part.replace('Y','X') + part = part.replace('temp','Y') + return part + +def reflect_xz(part): + part = part.replace('X','temp') + part = part.replace('Z','X') + part = part.replace('temp','Z') + return part + +def reflect_yz(part): + part = part.replace('Y','temp') + part = part.replace('Z','Y') + part = part.replace('temp','Z') + return part + +def scale_x(part,x0,sx): + part = part.replace('X','((x0) + (X-(x0))/(sx))') + part = part.replace('x0',str(x0)) + part = part.replace('sx',str(sx)) + return part + +def scale_y(part,y0,sy): + part = part.replace('Y','((y0) + (Y-(y0))/(sy))') + part = part.replace('y0',str(y0)) + part = part.replace('sy',str(sy)) + return part + +def scale_z(part,z0,sz): + part = part.replace('Z','((z0) + (Z-(z0))/(sz))') + part = part.replace('z0',str(z0)) + part = part.replace('sz',str(sz)) + return part + +def scale_xy(part,x0,y0,sxy): + part = part.replace('X','((x0) + (X-(x0))/(sxy))') + part = part.replace('Y','((y0) + (Y-(y0))/(sxy))') + part = part.replace('x0',str(x0)) + part = part.replace('y0',str(y0)) + part = part.replace('sxy',str(sxy)) + return part + +def scale_xyz(part,x0,y0,z0,sxyz): + part = part.replace('X','((x0) + (X-(x0))/(sxyz))') + part = part.replace('Y','((y0) + (Y-(y0))/(sxyz))') + part = part.replace('Z','((z0) + (Z-(z0))/(sxyz))') + part = part.replace('x0',str(x0)) + part = part.replace('y0',str(y0)) + part = part.replace('z0',str(z0)) + part = part.replace('sxyz',str(sxyz)) + return part + +def coscale_x_y(part,x0,y0,y1,angle0,angle1,amplitude,offset): + phase0 = math.pi*angle0/180. + phase1 = math.pi*angle1/180. + part = part.replace('X','((x0) + (X-(x0))/((offset) + (amplitude)*math.cos((phase0) + ((phase1)-(phase0))*(Y-(y0))/((y1)-(y0)))))') + part = part.replace('x0',str(x0)) + part = part.replace('y0',str(y0)) + part = part.replace('y1',str(y1)) + part = part.replace('phase0',str(phase0)) + part = part.replace('phase1',str(phase1)) + part = part.replace('amplitude',str(amplitude)) + part = part.replace('offset',str(offset)) + return part + +def coscale_x_z(part,x0,z0,z1,angle0,angle1,amplitude,offset): + phase0 = math.pi*angle0/180. + phase1 = math.pi*angle1/180. + part = part.replace('X','((x0) + (X-(x0))/((offset) + (amplitude)*math.cos((phase0) + ((phase1)-(phase0))*(Z-(z0))/((z1)-(z0)))))') + part = part.replace('x0',str(x0)) + part = part.replace('z0',str(z0)) + part = part.replace('z1',str(z1)) + part = part.replace('phase0',str(phase0)) + part = part.replace('phase1',str(phase1)) + part = part.replace('amplitude',str(amplitude)) + part = part.replace('offset',str(offset)) + return part + +def coscale_xy_z(part,x0,y0,z0,z1,angle0,angle1,amplitude,offset): + phase0 = math.pi*angle0/180. + phase1 = math.pi*angle1/180. + part = part.replace('X','((x0) + (X-(x0))/((offset) + (amplitude)*math.cos((phase0) + ((phase1)-(phase0))*(Z-(z0))/((z1)-(z0)))))') + part = part.replace('Y','((y0) + (Y-(y0))/((offset) + (amplitude)*math.cos((phase0) + ((phase1)-(phase0))*(Z-(z0))/((z1)-(z0)))))') + part = part.replace('x0',str(x0)) + part = part.replace('y0',str(y0)) + part = part.replace('z0',str(z0)) + part = part.replace('z1',str(z1)) + part = part.replace('phase0',str(phase0)) + part = part.replace('phase1',str(phase1)) + part = part.replace('amplitude',str(amplitude)) + part = part.replace('offset',str(offset)) + return part + +def taper_x_y(part,x0,y0,y1,s0,s1): + part = part.replace('X','((x0) + (X-(x0))*((y1)-(y0))/((s1)*(Y-(y0)) + (s0)*((y1)-Y)))') + part = part.replace('x0',str(x0)) + part = part.replace('y0',str(y0)) + part = part.replace('y1',str(y1)) + part = part.replace('s0',str(s0)) + part = part.replace('s1',str(s1)) + return part + +def taper_x_z(part,x0,z0,z1,s0,s1): + part = part.replace('X','((x0) + (X-(x0))*((z1)-(z0))/((s1)*(Z-(z0)) + (s0)*((z1)-Z)))') + part = part.replace('x0',str(x0)) + part = part.replace('z0',str(z0)) + part = part.replace('z1',str(z1)) + part = part.replace('s0',str(s0)) + part = part.replace('s1',str(s1)) + return part + +def taper_xy_z(part,x0,y0,z0,z1,s0,s1): + part = part.replace('X','((x0) + (X-(x0))*((z1)-(z0))/((s1)*(Z-(z0)) + (s0)*((z1)-Z)))') + part = part.replace('Y','((y0) + (Y-(y0))*((z1)-(z0))/((s1)*(Z-(z0)) + (s0)*((z1)-Z)))') + part = part.replace('x0',str(x0)) + part = part.replace('y0',str(y0)) + part = part.replace('z0',str(z0)) + part = part.replace('z1',str(z1)) + part = part.replace('s0',str(s0)) + part = part.replace('s1',str(s1)) + return part + +def shear_x_y(part,y0,y1,dx0,dx1): + part = part.replace('X','(X - (dx0) - ((dx1)-(dx0))*(Y-(y0))/((y1)-(y0)))') + part = part.replace('y0',str(y0)) + part = part.replace('y1',str(y1)) + part = part.replace('dx0',str(dx0)) + part = part.replace('dx1',str(dx1)) + return part + +def shear_x_z(part,z0,z1,dx0,dx1): + part = part.replace('X','(X - (dx0) - ((dx1)-(dx0))*(Z-(z0))/((z1)-(z0)))') + part = part.replace('z0',str(z0)) + part = part.replace('z1',str(z1)) + part = part.replace('dx0',str(dx0)) + part = part.replace('dx1',str(dx1)) + return part + +def coshear_x_z(part,z0,z1,angle0,angle1,amplitude,offset): + phase0 = math.pi*angle0/180. + phase1 = math.pi*angle1/180. + part = part.replace('X','(X - (offset) - (amplitude)*math.cos((phase0) + ((phase1)-(phase0))*(Z-(z0))/((z1)-(z0))))') + part = part.replace('z0',str(z0)) + part = part.replace('z1',str(z1)) + part = part.replace('phase0',str(phase0)) + part = part.replace('phase1',str(phase1)) + part = part.replace('amplitude',str(amplitude)) + part = part.replace('offset',str(offset)) + return part + +############################################################ +# text classes and definitions +############################################################ + +class text: + # + # text class + # + def __init__(self,text,x,y,z=0,line='',height='',width='',space='',align='CC',color=White,angle=0): + # + # parameters + # + if (line == ''): + line = 1 + if (height == ''): + height = 6*line + if (width == ''): + width = 4*line + if (space == ''): + space = line/2.0 + self.width = 0 + self.height = 0 + self.text = text + # + # construct shape dictionary + # + shapes = {} + shape = triangle(0,0,width/2.0,height,width,0) + cutout = triangle(0,-2.5*line,width/2.0,height-2.5*line,width,-2.5*line) + cutout = subtract(cutout,rectangle(0,width,height/4-line/2,height/4+line/2)) + shape = subtract(shape,cutout) + shapes['A'] = shape + shape = circle(width/2,width/2,width/2) + shape = subtract(shape,circle(width/2,width/2,width/4)) + shape = add(shape,rectangle(width-line,width,0,height/3)) + shapes['a'] = shape + shape = rectangle(0,width-height/4,0,height) + shape = add(shape,circle(width-height/4,height/4,height/4)) + shape = add(shape,circle(width-height/4,3*height/4,height/4)) + w = height/2-1.5*line + shape = subtract(shape,rectangle(line,line+w/1.5,height/2+line/2,height-line)) + shape = subtract(shape,circle(line+w/1.5,height/2+line/2+w/2,w/2)) + shape = subtract(shape,rectangle(line,line+w/1.5,line,height/2-line/2)) + shape = subtract(shape,circle(line+w/1.5,height/2-line/2-w/2,w/2)) + shapes['B'] = shape + shape = circle(width/2,width/2,width/2) + shape = subtract(shape,circle(width/2,width/2,width/4)) + shape = add(shape,rectangle(0,line,0,height)) + shapes['b'] = shape + shape = circle(width/2,width/2,width/2) + shape = add(shape,circle(width/2,height-width/2,width/2)) + shape = add(shape,rectangle(0,width,line+w/2,height-line-w/2)) + w = width-2*line + shape = subtract(shape,circle(width/2,line+w/2,w/2)) + shape = subtract(shape,circle(width/2,height-line-w/2,w/2)) + shape = subtract(shape,rectangle(line,width,line+w/2,height-line-w/2)) + shapes['C'] = shape + shape = circle(width/2,width/2,width/2) + shape = subtract(shape,circle(width/2,width/2,width/4)) + shape = subtract(shape,rectangle(width/2,width,width/2-line/1.5,width/2+line/1.5)) + shapes['c'] = shape + shape = circle(line,width-line,width-line) + shape = subtract(shape,circle(line,width-line,width-2*line)) + shape = subtract(shape,rectangle(-width,line,0,height)) + shape = scale_y(shape,0,height/(2*(width-line))) + shape = add(shape,rectangle(0,line,0,height)) + shapes['D'] = shape + shape = rectangle(width-line,width,0,height) + shape = add(shape,circle(width/2,width/2,width/2)) + shape = subtract(shape,circle(width/2,width/2,width/2-line)) + shapes['d'] = shape + shape = rectangle(0,line,0,height) + shape = add(shape,rectangle(0,width,height-line,height)) + shape = add(shape,rectangle(0,2*width/3,height/2-line/2,height/2+line/2)) + shape = add(shape,rectangle(0,width,0,line)) + shapes['E'] = shape + shape = circle(width/2,width/2,width/2) + shape = subtract(shape,circle(width/2,width/2,width/2-line)) + shape = subtract(shape,triangle(width,0,width/2,width/2-line/2,width,width/2-line/2)) + shape = add(shape,rectangle(0,width,width/2-line/2,width/2+line/2)) + shapes['e'] = shape + shape = rectangle(0,line,0,height) + shape = add(shape,rectangle(0,width,height-line,height)) + shape = add(shape,rectangle(0,2*width/3,height/2-line/2,height/2+line/2)) + shapes['F'] = shape + shape = circle(width-line/2,height-width/2,width/2) + shape = subtract(shape,circle(width-line/2,height-width/2,width/2-line)) + shape = subtract(shape,rectangle(0,width-line/2,0,height-width/2)) + shape = subtract(shape,rectangle(width-line/2,2*width,0,height)) + shape = add(shape,rectangle(width/2-line/2,width/2+line/2,0,height-width/2)) + shape = add(shape,rectangle(width/5,4*width/5,height/2-line/2,height/2+line/2)) + shapes['f'] = shape + shape = circle(width/2,width/2,width/2) + shape = add(shape,circle(width/2,height-width/2,width/2)) + shape = add(shape,rectangle(0,width,line+w/2,height-line-w/2)) + w = width-2*line + shape = subtract(shape,circle(width/2,line+w/2,w/2)) + shape = subtract(shape,circle(width/2,height-line-w/2,w/2)) + shape = subtract(shape,rectangle(line,width,line+w/2,height-line-w/2)) + shape = add(shape,rectangle(width/2,width,line+w/2,2*line+w/2)) + shapes['G'] = shape + shape = circle(width/2,width/2,width/2) + shape = subtract(shape,circle(width/2,width/2,width/2-line)) + w = height/3-width/2 + shape = add(shape,rectangle(width-line,width,w,width)) + shape = add(shape,subtract(subtract(circle(width/2,w,width/2),circle(width/2,w,width/2-line)),rectangle(0,width,w,height))) + shapes['g'] = shape + shape = rectangle(0,line,0,height) + shape = add(shape,rectangle(width-line,width,0,height)) + shape = add(shape,rectangle(0,width,height/2-line/2,height/2+line/2)) + shapes['H'] = shape + w = width/2 + shape = circle(width/2,w,width/2) + shape = subtract(shape,circle(width/2,w,width/2-line)) + shape = subtract(shape,rectangle(0,width,0,w)) + shape = add(shape,rectangle(0,line,0,height)) + shape = add(shape,rectangle(width-line,width,0,w)) + shapes['h'] = shape + shape = rectangle(width/2-line/2,width/2+line/2,0,height) + shape = add(shape,rectangle(width/5,4*width/5,0,line)) + shape = add(shape,rectangle(width/5,4*width/5,height-line,height)) + shapes['I'] = shape + shape = rectangle(width/2-line/2,width/2+line/2,0,height/2) + shape = add(shape,circle(width/2,3*height/4,.6*line)) + shapes['i'] = shape + shape = circle(width/2,width/2,width/2) + shape = subtract(shape,circle(width/2,width/2,width/2-line)) + shape = subtract(shape,rectangle(0,width,width/2,height)) + shape = add(shape,rectangle(width-line,width,width/2,height)) + shapes['J'] = shape + w = height/3-width/2 + shape = rectangle(width/2-line/2,width/2+line/2,w,height/2) + shape = add(shape,subtract(subtract(subtract(circle(width/4-line/2,w,width/2),circle(width/4-line/2,w,width/2-line)),rectangle(0,width,w,height)),rectangle(-width,width/4-line/2,-height/3,height))) + shape = add(shape,circle(width/2,3*height/4,.6*line)) + shapes['j'] = shape + shape = rectangle(0,width,0,height) + shape = subtract(shape,triangle(line,height,width-1.1*line,height,line,height/2+.5*line)) + shape = subtract(shape,triangle(width,0,line+0.8*line,height/2,width,height)) + shape = subtract(shape,triangle(line,0,line,height/2-.5*line,width-1.1*line,0)) + shapes['K'] = shape + shape = rectangle(0,width,0,height) + shape = subtract(shape,rectangle(line,width,2*height/3,height)) + shape = subtract(shape,triangle(line,2*height/3,width-1.3*line,2*height/3,line,height/3+.5*line)) + shape = subtract(shape,triangle(width,0,line+0.8*line,height/3,width,2*height/3)) + shape = subtract(shape,triangle(line,0,line,height/3-0.5*line,width-1.3*line,0)) + shapes['k'] = shape + shape = rectangle(0,line,0,height) + shape = add(shape,rectangle(0,width,0,line)) + shapes['L'] = shape + shape = rectangle(width/2-line/2,width/2+line/2,0,height) + shapes['l'] = shape + shape = rectangle(0,width,0,height) + shape = subtract(shape,triangle(line,0,line,height-3*line,width/2-line/3,0)) + shape = subtract(shape,triangle(line,height,width-line,height,width/2,1.5*line)) + shape = subtract(shape,triangle(width/2+line/3,0,width-line,height-3*line,width-line,0)) + shapes['M'] = shape + w = width/2 + l = 1.3*line + shape = circle(width/2,w,width/2) + shape = subtract(shape,circle(width/2,w,width/2-l)) + shape = subtract(shape,rectangle(0,width,0,w)) + shape = add(shape,rectangle(width-l,width,0,w)) + shape = add(shape,move(shape,width-l,0)) + shape = add(shape,rectangle(0,l,0,width)) + shape = scale_x(shape,0,width/(2*width-l)) + shapes['m'] = shape + shape = rectangle(0,width,0,height) + shape = subtract(shape,triangle(line,height+1.5*line,width-line,height+1.5*line,width-line,1.5*line)) + shape = subtract(shape,triangle(line,-1.5*line,line,height-1.5*line,width-line,-1.5*line)) + shapes['N'] = shape + w = width/2 + shape = circle(width/2,w,width/2) + shape = subtract(shape,circle(width/2,w,width/2-line)) + shape = subtract(shape,rectangle(0,width,0,w)) + shape = add(shape,rectangle(0,line,0,width)) + shape = add(shape,rectangle(width-line,width,0,w)) + shapes['n'] = shape + shape = circle(width/2,width/2,width/2) + shape = add(shape,circle(width/2,height-width/2,width/2)) + shape = add(shape,rectangle(0,width,line+w/2,height-line-w/2)) + w = width-2*line + shape = subtract(shape,circle(width/2,line+w/2,w/2)) + shape = subtract(shape,circle(width/2,height-line-w/2,w/2)) + shape = subtract(shape,rectangle(line,width-line,line+w/2,height-line-w/2)) + shapes['O'] = shape + shape = circle(width/2,width/2,width/2) + shape = subtract(shape,circle(width/2,width/2,width/2-line)) + shapes['o'] = shape + shape = rectangle(0,line,0,height) + w = 2*height/3 + shape = add(shape,circle(width-w/2,height-w/2,w/2)) + shape = add(shape,rectangle(0,width-w/2,height-w,height)) + shape = subtract(shape,circle(width-w/2,height-w/2,w/2-line)) + shape = subtract(shape,rectangle(line,width-w/2,height-w+line,height-line)) + shapes['P'] = shape + shape = circle(width/2,width/2,width/2) + shape = subtract(shape,circle(width/2,width/2,width/4)) + shape = add(shape,rectangle(0,line,-height/3,width)) + shapes['p'] = shape + shape = subtract(circle(width/2,width/2,width/2),circle(width/2,width/2,width/2-.9*line)) + shape = scale_y(shape,0,height/width) + shape = add(shape,move(rotate(rectangle(-line/2,line/2,-width/4,width/4),30),3*width/4,width/4)) + shapes['Q'] = shape + shape = circle(width/2,width/2,width/2) + shape = subtract(shape,circle(width/2,width/2,width/2-line)) + shape = add(shape,rectangle(width-line,width,-height/3,width)) + shapes['q'] = shape + shape = rectangle(0,line,0,height) + w = 2*height/3 + shape = add(shape,circle(width-w/2,height-w/2,w/2)) + shape = add(shape,rectangle(0,width-w/2,height-w,height)) + shape = subtract(shape,circle(width-w/2,height-w/2,w/2-line)) + shape = subtract(shape,rectangle(line,width-w/2,height-w+line,height-line)) + leg = triangle(line,0,line,height,width,0) + leg = subtract(leg,triangle(line,-2.0*line,line,height-2.0*line,width,-2.0*line)) + leg = subtract(leg,rectangle(0,width,height/3,height)) + shape = add(shape,leg) + shapes['R'] = shape + shape = circle(width,0,width) + shape = subtract(shape,circle(width,0,width-line)) + shape = subtract(shape,rectangle(.8*width,2*width,-height,height)) + shape = subtract(shape,rectangle(0,2*width,-height,0)) + shape = add(shape,rectangle(0,line,0,width)) + shapes['r'] = shape + shape = circle(width/2,width/2,width/2) + shape = subtract(shape,circle(width/2,width/2,width/2-line)) + shape = subtract(shape,rectangle(0,width/2,width/2,width)) + shape = add(shape,move(reflect_y(reflect_x(shape,width),width),0,width-line)) + shape = scale_y(shape,0,height/(2*width-line)) + shapes['S'] = shape + w = width/3 + shape = circle(w,w,w) + shape = subtract(shape,circle(w,w,w-.9*line)) + shape = subtract(shape,rectangle(0,w,w,2*w)) + shape = add(shape,move(reflect_y(reflect_x(shape,2*w),2*w),0,2*w-.9*line)) + shape = scale_y(shape,0,(2*height/3)/(4*w-.9*line)) + shape = move(shape,(width/2)-w,0) + shapes['s'] = shape + shape = rectangle(width/2-line/2,width/2+line/2,0,height) + shape = add(shape,rectangle(0,width,height-line,height)) + shapes['T'] = shape + shape = circle(0,3*width/8,3*width/8) + shape = subtract(shape,circle(0,3*width/8,3*width/8-line)) + shape = subtract(shape,rectangle(-width,width,3*width/8,height)) + shape = subtract(shape,rectangle(0,width,-height,height)) + shape = move(shape,width/2-line/2+3*width/8,0) + shape = add(shape,rectangle(width/2-line/2,width/2+line/2,width/4,3*height/4)) + shape = add(shape,rectangle(width/5,4*width/5,height/2-line/2,height/2+line/2)) + shapes['t'] = shape + shape = circle(width/2,width/2,width/2) + shape = subtract(shape,circle(width/2,width/2,width/2-line)) + shape = subtract(shape,rectangle(0,width,width/2,height)) + shape = add(shape,rectangle(0,line,width/2,height)) + shape = add(shape,rectangle(width-line,width,width/2,height)) + shapes['U'] = shape + shape = circle(width/2,width/2,width/2) + shape = subtract(shape,circle(width/2,width/2,width/2-line)) + shape = subtract(shape,rectangle(0,width,width/2,height)) + shape = add(shape,rectangle(0,line,width/2,2*height/3)) + shape = add(shape,rectangle(width-line,width,0,2*height/3)) + shapes['u'] = shape + shape = triangle(0,height,width,height,width/2,0) + shape = subtract(shape,triangle(0,height+3*line,width,height+3*line,width/2,3*line)) + shapes['V'] = shape + w = 2*height/3.0 + shape = triangle(0,w,width,w,width/2,0) + shape = subtract(shape,triangle(0,w+2*line,width,w+2*line,width/2,2*line)) + shapes['v'] = shape + shape = triangle(0,height,width,height,width/2,0) + shape = add(shape,move(shape,.6*width,0)) + cutout = triangle(0,height+4*line,width,height+4*line,width/2,4*line) + cutout = add(cutout,move(cutout,.6*width,0)) + shape = subtract(shape,cutout) + shape = scale_x(shape,0,1/1.6) + shapes['W'] = shape + shape = scale_y(shapes['W'],0,width/height) + shapes['w'] = shape + shape = rectangle(0,width,0,height) + shape = subtract(shape,triangle(0,0,0,height,width/2-.7*line,height/2)) + shape = subtract(shape,triangle(width,0,width/2+.7*line,height/2,width,height)) + shape = subtract(shape,triangle(1.1*line,height,width-1.1*line,height,width/2,height/2+line)) + shape = subtract(shape,triangle(1.1*line,0,width/2,height/2-line,width-1.1*line,0)) + shapes['X'] = shape + w = 2*height/3.0 + shape = rectangle(0,width,0,w) + shape = subtract(shape,triangle(0,0,0,w,width/2-.75*line,w/2)) + shape = subtract(shape,triangle(width,0,width/2+.75*line,w/2,width,w)) + shape = subtract(shape,triangle(1.25*line,0,width/2,w/2-.75*line,width-1.25*line,0)) + shape = subtract(shape,triangle(1.25*line,w,width-1.25*line,w,width/2,w/2+.75*line)) + shapes['x'] = shape + w = height/2 + shape = rectangle(0,width,w,height) + shape = subtract(shape,triangle(0,w,0,height,width/2-line/2,w)) + shape = subtract(shape,triangle(width/2+line/2,w,width,height,width,w)) + shape = subtract(shape,triangle(1.1*line,height,width-1.1*line,height,width/2,w+1.1*line)) + shape = add(shape,rectangle(width/2-line/2,width/2+line/2,0,w)) + shapes['Y'] = shape + shape = rectangle(0,width,-height/3,width) + shape = subtract(shape,triangle(0,-height/3,0,width,width/2-.9*line,0)) + shape = subtract(shape,triangle(1.1*line,width,width-1.1*line,width,width/2-.2*line,1.6*line)) + shape = subtract(shape,triangle(1.2*line,-height/3,width,width,width,-height/3)) + shapes['y'] = shape + shape = rectangle(0,width,0,height) + shape = subtract(shape,triangle(0,line,0,height-line,width-1.4*line,height-line)) + shape = subtract(shape,triangle(1.4*line,line,width,height-line,width,line)) + shapes['Z'] = shape + w = 2*height/3 + shape = rectangle(0,width,0,w) + shape = subtract(shape,triangle(0,line,0,w-line,width-1.6*line,w-line)) + shape = subtract(shape,triangle(width,line,1.6*line,line,width,w-line)) + shapes['z'] = shape + shape = circle(width/2,width/2,width/2) + shape = subtract(shape,circle(width/2,width/2,width/2-.9*line)) + shape = scale_y(shape,0,height/width) + shapes['0'] = shape + shape = rectangle(width/2-line/2,width/2+line/2,0,height) + w = width/2-line/2 + cutout = circle(0,height,w) + shape = add(shape,rectangle(0,width/2,height-w-line,height)) + shape = subtract(shape,cutout) + shape = move(shape,(width/2+line/2)/4,0) + shapes['1'] = shape + shape = circle(width/2,height-width/2,width/2) + shape = subtract(shape,circle(width/2,height-width/2,width/2-line)) + shape = subtract(shape,rectangle(0,width/2,0,height-width/2)) + shape = add(shape,rectangle(0,width,0,height-width/2)) + shape = subtract(shape,triangle(0,line,0,height-width/2,width-line,height-width/2)) + shape = subtract(shape,triangle(1.5*line,line,width,height-width/2-.5*line,width,line)) + shapes['2'] = shape + shape = circle(width/2,width/2,width/2) + shape = subtract(shape,circle(width/2,width/2,width/2-line)) + shape = scale_y(shape,0,(height/2+line/2)/width) + shape = add(shape,move(shape,0,height/2-line/2)) + shape = subtract(shape,rectangle(0,width/2,height/4,3*height/4)) + shapes['3'] = shape + shape = rectangle(width-line,width,0,height) + shape = add(shape,triangle(0,height/3,width-line,height,width-line,height/3)) + shape = subtract(shape,triangle(1.75*line,height/3+line,width-line,height-1.5*line,width-line,height/3+line)) + shapes['4'] = shape + shape = circle(width/2,width/2,width/2) + shape = subtract(shape,circle(width/2,width/2,width/2-line)) + shape = subtract(shape,rectangle(0,width/2,width/2,width)) + shape = add(shape,rectangle(0,width/2,width-line,width)) + shape = add(shape,rectangle(0,line,width-line,height)) + shape = add(shape,rectangle(0,width,height-line,height)) + shapes['5'] = shape + shape = circle(width/2,height-width/2,width/2) + shape = subtract(shape,circle(width/2,height-width/2,width/2-line)) + shape = subtract(shape,rectangle(0,width,0,height-width/2)) + shape = subtract(shape,triangle(width,height,width,height/2,width/2,height/2)) + shape = add(shape,circle(width/2,width/2,width/2)) + shape = subtract(shape,circle(width/2,width/2,width/2-line)) + shape = add(shape,rectangle(0,line,width/2,height-width/2)) + shapes['6'] = shape + shape = rectangle(0,width,0,height) + shape = subtract(shape,triangle(0,0,0,height-line,width-line,height-line)) + shape = subtract(shape,triangle(line,0,width,height-line,width,0)) + shapes['7'] = shape + shape = circle(width/2,width/2,width/2) + shape = subtract(shape,circle(width/2,width/2,width/2-line)) + shape = scale_y(shape,0,(height/2+line/2)/width) + shape = add(shape,move(shape,0,height/2-line/2)) + shapes['8'] = shape + shape = circle(width/2,width/2,width/2) + shape = subtract(shape,circle(width/2,width/2,width/2-line)) + shape = subtract(shape,rectangle(0,width,width/2,height)) + shape = subtract(shape,triangle(0,0,0,height/2,width/2,height/2)) + shape = add(shape,circle(width/2,height-width/2,width/2)) + shape = subtract(shape,circle(width/2,height-width/2,width/2-line)) + shape = add(shape,rectangle(width-line,width,width/2,height-width/2)) + shapes['9'] = shape + w = width/2 + shape = circle(w,w,w) + shape = subtract(shape,circle(w,w,w-line)) + shape = subtract(shape,rectangle(w,width,0,height)) + shape = scale_y(shape,0,height/width) + shape = move(shape,w/2,0) + shapes['('] = shape + shape = reflect_x(shape,width) + shapes[')'] = shape + shapes[' '] = false + shape = rectangle(width/2-width/3,width/2+width/3,height/2-line/2,height/2+line/2) + shape = add(shape,rectangle(width/2-line/2,width/2+line/2,height/2-width/3,height/2+width/3)) + shapes['+'] = shape + shape = rectangle(width/2-width/3,width/2+width/3,height/2-line/2,height/2+line/2) + shapes['-'] = shape + shape = circle(width/2,line,.75*line) + shapes['.'] = shape + shape = rectangle(0,width,0,height) + d = .8*line + shape = subtract(shape,triangle(d,0,width,height-d,width,0)) + shape = subtract(shape,triangle(0,d,0,height,width-d,height)) + shapes['/'] = shape + # + # to be done + # + shapes['*'] = shape + shapes['~'] = shape + shapes['!'] = shape + shapes['@'] = shape + shapes['#'] = shape + shapes['$'] = shape + shapes['%'] = shape + shapes['^'] = shape + shapes['&'] = shape + shapes['&'] = shape + shapes['_'] = shape + shapes['='] = shape + shapes['['] = shape + shapes['{'] = shape + shapes[']'] = shape + shapes['}'] = shape + shapes[';'] = shape + shapes[':'] = shape + shapes["'"] = shape + shapes['"'] = shape + shapes[','] = shape + shapes['<'] = shape + shapes['>'] = shape + shapes['?'] = shape + # + # add a line to text shape + # + def addline(lineshape): + # + # LR align + # + if (align[0] == 'C'): + lineshape = move(lineshape,-self.width/2.0,0) + elif (align[0] == 'R'): + lineshape = move(lineshape,-self.width,0) + # + # add + # + self.shape = add(self.shape,lineshape) + # + # loop over chars + # + dx = 0 + dy = -height + self.width = -space + self.height = height + lineshape = false + self.shape = false + count = 0 + for chr in text: + if (chr == '\n'): + count += 1 + addline(lineshape) + dx = 0 + dy -= 1.5*self.height/(1+(count-1)*1.5) + self.width = -space + self.height += 1.5*self.height + lineshape = false + else: + lineshape = add(lineshape,move(shapes[chr],dx,dy)) + self.width += space + width + dx += width + space + addline(lineshape) + # + # UD align + # + if (align[1] == 'C'): + self.shape = move(self.shape,0,self.height/2.0) + elif (align[1] == 'B'): + self.shape = move(self.shape,0,self.height) + # + # rotate + # + if (angle == 90): + self.shape = rotate_90(self.shape) + elif (angle == 180): + self.shape = rotate_180(self.shape) + elif ((angle == 270) | (angle == -90)): + self.shape = rotate_270(self.shape) + elif (angle != 0): + self.shape = rotate(self.shape,angle) + # + # translate + # + self.shape = move(self.shape,x,y) + # + # color + # + self.shape = '('+str(color)+'*(('+self.shape+')!=0))' + +############################################################ +# PCB classes and definitions +############################################################ + +class PCB: + def __init__(self,x0,y0,width,height,mask): + self.board = false + self.labels = false + self.interior = rectangle(x0,x0+width,y0,y0+height) + self.exterior = subtract(true,rectangle(x0,x0+width,y0,y0+height)) + self.mask = false + self.holes = false + self.cutout = false + def add(self,part): + self.board = add(self.board,part) + self.mask = add(self.mask,move(part,-mask,mask)) + self.mask = add(self.mask,move(part,-mask,-mask)) + self.mask = add(self.mask,move(part,mask,mask)) + self.mask = add(self.mask,move(part,mask,-mask)) + return self + +class point: + def __init__(self,x,y,z=0): + self.x = x + self.y = y + self.z = z + +class part: + class text: + def __init__(self,x,y,z=0,text='',line=0.006,angle=0): + self.x = x + self.y = y + self.z = z + self.text = text + self.line = line + self.angle = angle + def add(self,pcb,x,y,z=0,angle=0,line=0.007): + self.x = x + self.y = y + self.z = z + self.angle = angle + if (angle == 90): + self.shape = rotate_90(self.shape) + elif (angle == 180): + self.shape = rotate_180(self.shape) + elif ((angle == 270) | (angle == -90)): + self.shape = rotate_270(self.shape) + elif (angle != 0): + self.shape = rotate(self.shape,angle) + self.shape = translate(self.shape,x,y,z) + if hasattr(self,'holes'): + if (angle == 90): + self.holes = rotate_90(self.holes) + elif (angle == 180): + self.holes = rotate_180(self.holes) + elif ((angle == 270) | (angle == -90)): + self.holes = rotate_270(self.holes) + elif (angle != 0): + self.holes = rotate(self.holes,angle) + self.holes = translate(self.holes,x,y,z) + if hasattr(self,'cutout'): + if (angle == 90): + self.cutout = rotate_90(self.cutout) + elif (angle == 180): + self.cutout = rotate_180(self.cutout) + elif ((angle == 270) | (angle == -90)): + self.cutout = rotate_270(self.cutout) + elif (angle != 0): + self.cutout = rotate(self.cutout,angle) + self.cutout = translate(self.cutout,x,y,z) + deg_angle = angle + angle = math.pi*angle/180 + for i in range(len(self.pad)): + xnew = math.cos(angle)*self.pad[i].x - math.sin(angle)*self.pad[i].y + ynew = math.sin(angle)*self.pad[i].x + math.cos(angle)*self.pad[i].y + self.pad[i].x = x + xnew + self.pad[i].y = y + ynew + self.pad[i].z += z + pcb.labels = add(pcb.labels,text(self.value,x,y,z,line=line,color=Green).shape) + for i in range(len(self.labels)): + xnew = math.cos(angle)*self.labels[i].x - math.sin(angle)*self.labels[i].y + ynew = math.sin(angle)*self.labels[i].x + math.cos(angle)*self.labels[i].y + self.labels[i].x = x + xnew + self.labels[i].y = y + ynew + self.labels[i].z += z + if ((-90 < deg_angle) & (deg_angle <= 90)): + pcb.labels = add(pcb.labels,text(self.labels[i].text,self.labels[i].x,self.labels[i].y,self.labels[i].z,self.labels[i].line,color=Red,angle=deg_angle-self.labels[i].angle).shape) + else: + pcb.labels = add(pcb.labels,text(self.labels[i].text,self.labels[i].x,self.labels[i].y,self.labels[i].z,self.labels[i].line,color=Red,angle=(deg_angle-self.labels[i].angle-180)).shape) + pcb = pcb.add(self.shape) + if hasattr(self,'holes'): + pcb.holes = add(pcb.holes,self.holes) + if hasattr(self,'cutout'): + pcb.interior = subtract(pcb.interior,self.cutout) + pcb.exterior = add(pcb.exterior,self.cutout) + return pcb + +def wire(pcb,width,*points): + x0 = points[0].x + y0 = points[0].y + z0 = points[0].z + pcb.board = add(pcb.board,cylinder(x0,y0,z0,z0,width/2)) + for i in range(1,len(points)): + x0 = points[i-1].x + y0 = points[i-1].y + z0 = points[i-1].z + x1 = points[i].x + y1 = points[i].y + z1 = points[i].z + pcb.board = add(pcb.board,line(x0,y0,x1,y1,z1,width)) + pcb.board = add(pcb.board,cylinder(x1,y1,z1,z1,width/2)) + return pcb + +def wirer(pcb,width,*points): + for i in range(1,len(points)): + x0 = points[i-1].x + y0 = points[i-1].y + z0 = points[i-1].z + x1 = points[i].x + y1 = points[i].y + z1 = points[i].z + if (x0 < x1): + pcb.board = add(pcb.board,cube(x0-width/2,x1+width/2,y0-width/2,y0+width/2,z0,z0)) + elif (x1 < x0): + pcb.board = add(pcb.board,cube(x1-width/2,x0+width/2,y0-width/2,y0+width/2,z0,z0)) + if (y0 < y1): + pcb.board = add(pcb.board,cube(x1-width/2,x1+width/2,y0-width/2,y1+width/2,z0,z0)) + elif (y1 < y0): + pcb.board = add(pcb.board,cube(x1-width/2,x1+width/2,y1-width/2,y0+width/2,z0,z0)) + return pcb + +############################################################ +# PCB library +############################################################ + +class via(part): + # + # via + # + def __init__(self,zb,zt,rv,rp,value=''): + self.value = value + self.labels = [] + self.pad = [point(0,0,0)] + self.shape = cylinder(0,0,zb,zt,rp) + self.holes = cylinder(0,0,zb,zt,rv) + self.pad.append(point(0,0,zt)) + self.pad.append(point(0,0,zb)) + +class SJ(part): + # + # solder jumper + # + def __init__(self,value=''): + pad_SJ = cube(-.02,.02,-.03,.03,0,0) + self.value = value + self.labels = [] + self.pad = [point(0,0,0)] + self.shape = translate(pad_SJ,-.029,0,0) + self.pad.append(point(-.029,0,0)) + self.shape = add(self.shape,translate(pad_SJ,.029,0,0)) + self.pad.append(point(.029,0,0)) + +############################################################ +# discretes +############################################################ + + +class ST4EB(part): + # + # Nidec Copal ST4ETB103 trimpot + # + def __init__(self,value=''): + pad1 = cube(-.032,.032,-.039,.039,0,0) + pad2 = cube(-.039,.039,-.039,.039,0,0) + self.value = value + self.labels = [] + self.pad = [point(0,0,0)] + self.shape = translate(pad1,-.046,-.118,0) + self.pad.append(point(-.046,-.118,0)) + self.shape = add(self.shape,translate(pad1,.046,-.118,0)) + self.pad.append(point(.046,-.118,0)) + self.shape = add(self.shape,translate(pad2,0,.118,0)) + self.pad.append(point(0,.118,0)) + +class C_FND(part): + # + # Panasonic FN series, size code D + # 100uF: EEE-FN1E101UL + # + def __init__(self,value=''): + pad = cube(-.032,.032,-.06,.06,0,0) + self.value = value + self.labels = [] + self.pad = [point(0,0,0)] + self.shape = translate(pad,0,.11,0) + self.pad.append(point(0,.11,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'+',angle=90)) + self.shape = add(self.shape,translate(pad,0,-.11,0)) + self.pad.append(point(0,-.11,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'-',angle=90)) + +pad_0402 = cube(-.0175,.0175,-.014,.014,0,0) + +class R_0402(part): + # + # 0402 resistor + # + def __init__(self,value=''): + self.value = value + self.labels = [] + self.pad = [point(0,0,0)] + self.shape = translate(pad_0402,-.0265,0,0) + self.pad.append(point(-.0265,0,0)) + self.shape = add(self.shape,translate(pad_0402,.0265,0,0)) + self.pad.append(point(.0265,0,0)) + +pad_1206 = cube(-.032,.032,-.034,.034,0,0) + +class R_1206(part): + # + # 1206 resistor + # + def __init__(self,value=''): + self.value = value + self.labels = [] + self.pad = [point(0,0,0)] + self.shape = translate(pad_1206,-.06,0,0) + self.pad.append(point(-.06,0,0)) + self.shape = add(self.shape,translate(pad_1206,.06,0,0)) + self.pad.append(point(.06,0,0)) + +class C_1206(part): + # + # 1206 capacitor + # + def __init__(self,value=''): + self.value = value + self.labels = [] + self.pad = [point(0,0,0)] + self.shape = translate(pad_1206,-.06,0,0) + self.pad.append(point(-.06,0,0)) + self.shape = add(self.shape,translate(pad_1206,.06,0,0)) + self.pad.append(point(.06,0,0)) + +pad_1210 = cube(-.032,.032,-.048,.048,0,0) + +class L_1210(part): + # + # 1210 inductor + # + def __init__(self,value=''): + self.value = value + self.labels = [] + self.pad = [point(0,0,0)] + self.shape = translate(pad_1210,-.06,0,0) + self.pad.append(point(-.06,0,0)) + self.shape = add(self.shape,translate(pad_1210,.06,0,0)) + self.pad.append(point(.06,0,0)) + +pad_choke = cube(-.06,.06,-.06,.06,0,0) + +class choke(part): + # + # Panasonic ELLCTV + # + def __init__(self,value=''): + self.value = value + self.labels = [] + self.pad = [point(0,0,0)] + self.shape = translate(pad_choke,-.177,-.177,0) + self.pad.append(point(-.177,-.177,0)) + self.shape = add(self.shape,translate(pad_choke,.177,.177,0)) + self.pad.append(point(.177,.177,0)) + +############################################################ +# connectors +############################################################ + +class header_2H(part): + # + # 2x1x0.1 cable header + # Sullins GEC36SBSN-M89 + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1 + # + self.shape = translate(pad_header,0,.05,0) + self.pad.append(point(0,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad_header,0,-.05,0)) + self.pad.append(point(0,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'2')) + +class header_4H(part): + # + # 4x1x0.1 cable header + # Sullins GEC36SBSN-M89 + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1 + # + self.shape = translate(pad_header,0,.15,0) + self.pad.append(point(0,.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad_header,0,.05,0)) + self.pad.append(point(0,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'2')) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad_header,0,-.05,0)) + self.pad.append(point(0,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'3')) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad_header,0,-0.15,0)) + self.pad.append(point(0,-.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'4')) + +class header_NEO_6M(part): + # + # NEO_6M GPS module + # + def __init__(self,value=''): + pad_header = cylinder(0,0,0,0,.03) + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1 + # + self.shape = translate(pad_header,0,.2,0) + self.pad.append(point(0,.2,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PPS')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad_header,0,.1,0)) + self.pad.append(point(0,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'TXD')) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad_header,0,0,0)) + self.pad.append(point(0,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RXD')) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad_header,0,-.1,0)) + self.pad.append(point(0,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 5 + # + self.shape = add(self.shape,translate(pad_header,0,-.2,0)) + self.pad.append(point(0,-.2,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VCC')) + +class header_MFRC522(part): + # + # MFCR522 RFID module + # + def __init__(self,value=''): + pad_header = cylinder(0,0,0,0,.03) + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1 + # + self.shape = translate(pad_header,0,.35,0) + self.pad.append(point(0,.35,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1SDA')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad_header,0,.25,0)) + self.pad.append(point(0,.25,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SCK')) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad_header,0,.15,0)) + self.pad.append(point(0,.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'COPI')) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad_header,0,0.05,0)) + self.pad.append(point(0,0.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'CIPO')) + # + # pin 5 + # + self.shape = add(self.shape,translate(pad_header,0,-.05,0)) + self.pad.append(point(0,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IRQ')) + # + # pin 6 + # + self.shape = add(self.shape,translate(pad_header,0,-.15,0)) + self.pad.append(point(0,-.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 7 + # + self.shape = add(self.shape,translate(pad_header,0,-.25,0)) + self.pad.append(point(0,-.25,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RST')) + # + # pin 8 + # + self.shape = add(self.shape,translate(pad_header,0,-.35,0)) + self.pad.append(point(0,-.35,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'3.3V')) + +class header_LSM6DS33_2736(part): + # + # LSD6DS33 carrier + # Pololu 2736 + # + def __init__(self,value=''): + pad_header = cylinder(0,0,0,0,.03) + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1 + # + self.shape = translate(pad_header,0,.4,0) + self.pad.append(point(0,.4,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1VDD')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad_header,0,.3,0)) + self.pad.append(point(0,.3,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VIN')) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad_header,0,.2,0)) + self.pad.append(point(0,.2,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad_header,0,0.1,0)) + self.pad.append(point(0,0.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SDA')) + # + # pin 5 + # + self.shape = add(self.shape,translate(pad_header,0,0,0)) + self.pad.append(point(0,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SCL')) + # + # pin 6 + # + self.shape = add(self.shape,translate(pad_header,0,-.1,0)) + self.pad.append(point(0,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SDO')) + # + # pin 7 + # + self.shape = add(self.shape,translate(pad_header,0,-.2,0)) + self.pad.append(point(0,-.2,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'CS')) + # + # pin 8 + # + self.shape = add(self.shape,translate(pad_header,0,-.3,0)) + self.pad.append(point(0,-.3,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'INT2')) + # + # pin 9 + # + self.shape = add(self.shape,translate(pad_header,0,-.4,0)) + self.pad.append(point(0,-.4,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'INT1')) + +class header_VL53L1X_3415(part): + # + # VL53L1X carrier + # Pololu 3415 + # + def __init__(self,value=''): + pad_header = cylinder(0,0,0,0,.03) + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1 + # + self.shape = translate(pad_header,0,.3,0) + self.pad.append(point(0,.3,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1VDD')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad_header,0,.2,0)) + self.pad.append(point(0,.2,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VIN')) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad_header,0,.1,0)) + self.pad.append(point(0,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad_header,0,0,0)) + self.pad.append(point(0,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SDA')) + # + # pin 5 + # + self.shape = add(self.shape,translate(pad_header,0,-.1,0)) + self.pad.append(point(0,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SCL')) + # + # pin 6 + # + self.shape = add(self.shape,translate(pad_header,0,-.2,0)) + self.pad.append(point(0,-.2,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'XSHUT')) + # + # pin 7 + # + self.shape = add(self.shape,translate(pad_header,0,-.3,0)) + self.pad.append(point(0,-.3,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GPIO1')) + +class ESP_WROOM_02D(part): + # + # ESP-WROOM-02D + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + pad = cube(-1/25.4,1/25.4,-.45/25.4,.45/25.4,0,0) + width = 17.5/25.4 + pitch = 1.5/25.4 + # + # pin 1 + # + self.shape = translate(pad,-width/2,4*pitch,0) + self.shape = add(self.shape,cylinder(-width/2-.75/25.4,4*pitch,0,0,.45/25.4)) + self.pad.append(point(-width/2,4*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'3V3')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad,-width/2,3*pitch,0)) + self.pad.append(point(-width/2,3*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'EN')) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad,-width/2,2*pitch,0)) + self.pad.append(point(-width/2,2*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO14')) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad,-width/2,1*pitch,0)) + self.pad.append(point(-width/2,1*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO12')) + # + # pin 5 + # + self.shape = add(self.shape,translate(pad,-width/2,0*pitch,0)) + self.pad.append(point(-width/2,0*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO13')) + # + # pin 6 + # + self.shape = add(self.shape,translate(pad,-width/2,-1*pitch,0)) + self.pad.append(point(-width/2,-1*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO15')) + # + # pin 7 + # + self.shape = add(self.shape,translate(pad,-width/2,-2*pitch,0)) + self.pad.append(point(-width/2,-2*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO2')) + # + # pin 8 + # + self.shape = add(self.shape,translate(pad,-width/2,-3*pitch,0)) + self.pad.append(point(-width/2,-3*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO0')) + # + # pin 9 + # + self.shape = add(self.shape,translate(pad,-width/2,-4*pitch,0)) + self.pad.append(point(-width/2,-4*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 10 + # + self.shape = add(self.shape,translate(pad,width/2,-4*pitch,0)) + self.pad.append(point(width/2,-4*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO4')) + # + # pin 11 + # + self.shape = add(self.shape,translate(pad,width/2,-3*pitch,0)) + self.pad.append(point(width/2,-3*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RXD')) + # + # pin 12 + # + self.shape = add(self.shape,translate(pad,width/2,-2*pitch,0)) + self.pad.append(point(width/2,-2*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'TXD')) + # + # pin 13 + # + self.shape = add(self.shape,translate(pad,width/2,-1*pitch,0)) + self.pad.append(point(width/2,-1*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 14 + # + self.shape = add(self.shape,translate(pad,width/2,0*pitch,0)) + self.pad.append(point(width/2,0*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO5')) + # + # pin 15 + # + self.shape = add(self.shape,translate(pad,width/2,1*pitch,0)) + self.pad.append(point(width/2,1*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RST')) + # + # pin 16 + # + self.shape = add(self.shape,translate(pad,width/2,2*pitch,0)) + self.pad.append(point(width/2,2*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'TOUT')) + # + # pin 17 + # + self.shape = add(self.shape,translate(pad,width/2,3*pitch,0)) + self.pad.append(point(width/2,3*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO16')) + # + # pin 18 + # + self.shape = add(self.shape,translate(pad,width/2,4*pitch,0)) + self.pad.append(point(width/2,4*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 19 + # + padg = cube(-2/25.4,2/25.4,-2/25.4,2/25.4,0,0) + self.shape = add(self.shape,translate(padg,(1.5/2+7.1+2-17.5/2)/25.4,(4*1.5+7.1-20+4.29+2)/25.4,0)) + self.pad.append(point((1.5/2+7.1+2-17.5/2)/25.4,(4*1.5+7.1-20+4.29+2)/25.4,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + +class ESP_01(part): + # + # ESP-01 4x2 vertical + # Sullins NPTC042KFMS-RC + # + def __init__(self,value=''): + pad_header = cube(-.075/2,.075/2,-.04/2,.04/2,0,0) + d = .305/2-.07/2 + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1 + # + self.shape = translate(pad_header,d,.15,0) + self.shape = add(self.shape,cylinder(d+.061/2,.15,0,0,.039/2)) + self.pad.append(point(d,.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad_header,-d,.15,0)) + self.pad.append(point(-d,.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'Tx')) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad_header,d,.05,0)) + self.pad.append(point(d,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO2')) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad_header,-d,.05,0)) + self.pad.append(point(-d,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'EN')) + # + # pin 5 + # + self.shape = add(self.shape,translate(pad_header,d,-.05,0)) + self.pad.append(point(d,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO0')) + # + # pin 6 + # + self.shape = add(self.shape,translate(pad_header,-d,-.05,0)) + self.pad.append(point(-d,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RST')) + # + # pin 7 + # + self.shape = add(self.shape,translate(pad_header,d,-.15,0)) + self.pad.append(point(d,-.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'Rx')) + # + # pin 8 + # + self.shape = add(self.shape,translate(pad_header,-d,-.15,0)) + self.pad.append(point(-d,-.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VCC')) + +class header_serial_reverse_5V(part): + # + # serial cable header, reverse for female connector, 5V output + # GCT BG300-06-A-L-A + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1 + # + self.shape = translate(pad_header,0,-.25,0) + self.shape = add(self.shape,cylinder(-.05,-.25,0,0,.025)) + self.pad.append(point(0,-.25,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad_header,0,-.15,0)) + self.pad.append(point(0,-.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'CTS')) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad_header,0,-.05,0)) + self.pad.append(point(0,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'5V')) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad_header,0,0.05,0)) + self.pad.append(point(0,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'Tx')) + # + # pin 5 + # + self.shape = add(self.shape,translate(pad_header,0,.15,0)) + self.pad.append(point(0,.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'Rx')) + # + # pin 6 + # + self.shape = add(self.shape,translate(pad_header,0,.25,0)) + self.pad.append(point(0,.25,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RTS')) + +class header_serial_reverse_3V3(part): + # + # serial cable header, reverse for female connector, 3.3V output + # GCT BG300-06-A-L-A + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1 + # + self.shape = translate(pad_header,0,-.25,0) + self.shape = add(self.shape,cylinder(-.05,-.25,0,0,.025)) + self.pad.append(point(0,-.25,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad_header,0,-.15,0)) + self.pad.append(point(0,-.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'CTS')) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad_header,0,-.05,0)) + self.pad.append(point(0,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'3.3V')) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad_header,0,0.05,0)) + self.pad.append(point(0,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'Tx')) + # + # pin 5 + # + self.shape = add(self.shape,translate(pad_header,0,.15,0)) + self.pad.append(point(0,.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'Rx')) + # + # pin 6 + # + self.shape = add(self.shape,translate(pad_header,0,.25,0)) + self.pad.append(point(0,.25,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RTS')) + +class TFT8x1v(part): + # + # TFT 8x1 vertical + # 2x Sullins S5635-ND + # + def __init__(self,value=''): + pad_header = cube(-.079/2,.079/2,-.039/2,.039/2,0,0) + d = .209/2-.079/2 + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1 + # + self.shape = translate(pad_header,-d,-.35,0) + self.pad.append(point(-d,-.35,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1LED')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad_header,d,-.25,0)) + self.pad.append(point(d,-.25,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SCK')) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad_header,-d,-.15,0)) + self.pad.append(point(-d,-.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'MOSI')) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad_header,d,-.05,0)) + self.pad.append(point(d,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'DC')) + # + # pin 5 + # + self.shape = add(self.shape,translate(pad_header,-d,.05,0)) + self.pad.append(point(-d,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RST')) + # + # pin 6 + # + self.shape = add(self.shape,translate(pad_header,d,.15,0)) + self.pad.append(point(d,.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'CS')) + # + # pin 7 + # + self.shape = add(self.shape,translate(pad_header,-d,.25,0)) + self.pad.append(point(-d,.25,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 8 + # + self.shape = add(self.shape,translate(pad_header,d,.35,0)) + self.pad.append(point(d,.35,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VCC')) + +class header_SWD_4_05(part): + # + # 4-pin header + # Sullins GRPB022VWQS-RC 2x2x0.05" + # + def __init__(self,value=''): + pad_header = cube(-.043,.043,-.015,.015,0,0) + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1 + # + self.shape = translate(pad_header,-.072,.025,0) + self.shape = add(self.shape,cylinder(-.116,.025,0,0,.015)) + self.pad.append(point(-.072,.025,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'CLK')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad_header,.072,.025,0)) + self.pad.append(point(.072,.025,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'DIO')) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad_header,-.072,-.025,0)) + self.pad.append(point(-.072,-.025,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RST')) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad_header,.072,-.025,0)) + self.pad.append(point(.072,-.025,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + +class header_SWD_4_1(part): + # + # 4-pin header + # FCI 95278-101a04lf Bergstik 2x2x0.1" + # + pad_header = cube(-.05,.05,-.025,.025,0,0) + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1 + # + self.shape = translate(pad_header,-.107,.05,0) + #self.shape = add(self.shape,cylinder(-.157,.05,0,0,.025)) + self.pad.append(point(-.107,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'CLK')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad_header,.107,.05,0)) + self.pad.append(point(.107,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'DIO')) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad_header,-.107,-.05,0)) + self.pad.append(point(-.107,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RST')) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad_header,.107,-.05,0)) + self.pad.append(point(.107,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + +class header_UPDI(part): + # + # UPDI header + # Sullins GEC36SBSN-M89 + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: UPDI + # + self.shape = translate(pad_header,0,-.05,0) + self.shape = add(self.shape,cylinder(.05,-.05,0,0,.025)) + self.pad.append(point(0,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'UPDI')) + # + # pin 2: GND + # + self.shape = add(self.shape,translate(pad_header,0,.05,0)) + self.pad.append(point(0,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + +class header_UPDI_reverse(part): + # + # UPDI header, reverse for female connector + # GCT BG300-03-A-L-A + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: UPDI + # + self.shape = translate(pad_header,0,.05,0) + self.shape = add(self.shape,cylinder(.05,.05,0,0,.025)) + self.pad.append(point(0,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'UPDI')) + # + # pin 2: GND + # + self.shape = add(self.shape,translate(pad_header,0,-.05,0)) + self.pad.append(point(0,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + +class USB_A_plug(part): + # + # USB type A PCB plug + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: 5V + # + self.shape = translate(cube(-.05,.242,-.02,.02,0,0),0,.138,0) + self.pad.append(point(0,.138,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'5V')) + # + # pin 2: D- + # + self.shape = add(self.shape,translate(cube(-0.05,.202,-.02,.02,0,0),0,.039,0)) + self.pad.append(point(0,.039,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'D-')) + # + # pin 3: D+ + # + self.shape = add(self.shape,translate(cube(-.05,.202,-.02,.02,0,0),0,-.039,0)) + self.pad.append(point(0,-.039,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'D+')) + # + # pin 4: GND + # + self.shape = add(self.shape,translate(cube(-.05,.242,-.02,.02,0,0),0,-.138,0)) + self.pad.append(point(0,-.138,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # plug cutout + # + self.cutout = cube(-.05,1,.24,10,zb,zt) + self.cutout = add(self.cutout,cube(-.05,10,-10,-.24,zb,zt)) + +class header_SWD(part): + # + # Serial Wire Debug programming header + # Amphenol 20021121-00010T1LF 2x5x0.05 + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + d = 0.077 + w = 0.015 + h = .047 + pad = cube(-h,h,-w,w,0,0) + # + # pin 1: VCC + # + self.shape = translate(pad,d,-.1,0) + self.shape = add(self.shape,cylinder(d+h,-.1,0,0,w)) + self.pad.append(point(d,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VCC')) + # + # pin 2: DIO + # + self.shape = add(self.shape,translate(pad,-d,-.1,0)) + self.pad.append(point(-d,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'DIO')) + # + # pin 3: GND + # + self.shape = add(self.shape,translate(pad,d,-.05,0)) + self.pad.append(point(d,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 4: CLK + # + self.shape = add(self.shape,translate(pad,-d,-.05,0)) + self.pad.append(point(-d,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'CLK')) + # + # pin 5: GND + # + self.shape = add(self.shape,translate(pad,d,0,0)) + self.pad.append(point(d,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 6: SWO + # + self.shape = add(self.shape,translate(pad,-d,0,0)) + self.pad.append(point(-d,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SWO')) + # + # pin 7: KEY + # + self.shape = add(self.shape,translate(pad,d,.05,0)) + self.pad.append(point(d,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'KEY')) + # + # pin 8: NC + # + self.shape = add(self.shape,translate(pad,-d,.05,0)) + self.pad.append(point(-d,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'NC')) + # + # pin 9: GND + # + self.shape = add(self.shape,translate(pad,d,.1,0)) + self.pad.append(point(d,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 10: nRESET + # + self.shape = add(self.shape,translate(pad,-d,.1,0)) + self.pad.append(point(-d,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RST')) + +class ESC(part): + # + # ESC 3x1 + # Sullins S1013E-36-ND + # + def __init__(self,value=''): + pad_header = cube(-.1,.1,-.05/2,.05/2,0,0) + d = .075 + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: PWM + # + self.shape = translate(pad_header,-d,-.1,0) + self.pad.append(point(-d,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PWM')) + # + # pin 2: 5V + # + self.shape = add(self.shape,translate(pad_header,d,0,0)) + self.pad.append(point(d,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'5V')) + # + # pin 3: GND + # + self.shape = add(self.shape,translate(pad_header,-d,.1,0)) + self.pad.append(point(-d,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + +class I2C4x1h(part): + # + # I2C 4x1 horizontal female + # GCT BG300-03-A-L-A + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: SCL + # + self.shape = translate(pad_header,0,-.15,0) + #self.shape = cylinder(.05,.15,0,0,.025) + self.pad.append(point(0,-.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SCL')) + # + # pin 2: SDA + # + self.shape = add(self.shape,translate(pad_header,0,-.05,0)) + self.pad.append(point(0,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SDA')) + # + # pin 3: VCC + # + self.shape = add(self.shape,translate(pad_header,0,.05,0)) + self.pad.append(point(0,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VCC')) + # + # pin 4: GND + # + self.shape = add(self.shape,translate(pad_header,0,.15,0)) + self.pad.append(point(0,.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + +class I2C4x1v(part): + # + # I2C 4x1 vertical + # Sullins S5635-ND + # + def __init__(self,value=''): + pad_header = cube(-.079/2,.079/2,-.039/2,.039/2,0,0) + d = .209/2-.079/2 + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: VCC + # + self.shape = translate(pad_header,-d,-.15,0) + self.pad.append(point(-d,-.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1VCC')) + # + # pin 2: GND + # + self.shape = add(self.shape,translate(pad_header,d,-.05,0)) + self.pad.append(point(d,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 3: SCL + # + self.shape = add(self.shape,translate(pad_header,-d,.05,0)) + self.pad.append(point(-d,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SCL')) + # + # pin 4: SDA + # + self.shape = add(self.shape,translate(pad_header,d,.15,0)) + self.pad.append(point(d,.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SDA')) + +class I2C4x1i(part): + # + # I2C 4x1 inline + # + def __init__(self,value=''): + pad_header = cube(-.079/2,.079/2,-.039/2,.039/2,0,0) + d = 0 + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: VCC + # + self.shape = translate(pad_header,-d,-.15,0) + self.pad.append(point(-d,-.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1VCC')) + # + # pin 2: GND + # + self.shape = add(self.shape,translate(pad_header,d,-.05,0)) + self.pad.append(point(d,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 3: SCL + # + self.shape = add(self.shape,translate(pad_header,-d,.05,0)) + self.pad.append(point(-d,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SCL')) + # + # pin 4: SDA + # + self.shape = add(self.shape,translate(pad_header,d,.15,0)) + self.pad.append(point(d,.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SDA')) + +class RCWL0516(part): + # + # RCWL-0516 Doppler radar + # + def __init__(self,value=''): + pad_header = cube(-.065,.065,-.025,.025,0,0) + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: 3.3V + # + self.shape = translate(pad_header,.107,-.2,0) + self.shape = add(self.shape,cylinder(.172,-.2,0,0,.025)) + self.pad.append(point(.107,-.2,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'3.3V')) + # + # pin 2: GND + # + self.shape = add(self.shape,translate(pad_header,-.107,-.1,0)) + self.pad.append(point(-.107,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 3: OUT + # + self.shape = add(self.shape,translate(pad_header,.107,0,0)) + self.pad.append(point(.107,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'OUT')) + # + # pin 4: VIN + # + self.shape = add(self.shape,translate(pad_header,-.107,.1,0)) + self.pad.append(point(-.107,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VIN')) + # + # pin 5: CDS + # + self.shape = add(self.shape,translate(pad_header,.107,.2,0)) + self.pad.append(point(.107,.2,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'CDS')) + +class microSD(part): + # + # microSD + # Amphenol 114-00841-68 + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1 + # + self.shape = translate(cube(-.0138,.0138,-.034,.034,0,0),-.177+7*.0433,-.304,0) + self.pad.append(point(-.177+7*.0433,-.304,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1NC',angle=90)) + # + # pin 2 + # + self.shape = add(self.shape,translate(cube(-.0138,.0138,-.034,.034,0,0),-.177+6*.0433,-.304,0)) + self.pad.append(point(-.177+6*.0433,-.304,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SS',angle=90)) + # + # pin 3 + # + self.shape = add(self.shape,translate(cube(-.0138,.0138,-.034,.034,0,0),-.177+5*.0433,-.304,0)) + self.pad.append(point(-.177+5*.0433,-.304,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'MOSI',angle=90)) + # + # pin 4 + # + self.shape = add(self.shape,translate(cube(-.0138,.0138,-.034,.034,0,0),-.177+4*.0433,-.304,0)) + self.pad.append(point(-.177+4*.0433,-.304,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VCC',angle=90)) + # + # pin 5 + # + self.shape = add(self.shape,translate(cube(-.0138,.0138,-.034,.034,0,0),-.177+3*.0433,-.304,0)) + self.pad.append(point(-.177+3*.0433,-.304,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SCK',angle=90)) + # + # pin 6 + # + self.shape = add(self.shape,translate(cube(-.0138,.0138,-.034,.034,0,0),-.177+2*.0433,-.304,0)) + self.pad.append(point(-.177+2*.0433,-.304,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND',angle=90)) + # + # pin 7 + # + self.shape = add(self.shape,translate(cube(-.0138,.0138,-.034,.034,0,0),-.177+1*.0433,-.304,0)) + self.pad.append(point(-.177+1*.0433,-.304,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'MISO',angle=90)) + # + # pin 8 + # + self.shape = add(self.shape,translate(cube(-.0138,.0138,-.034,.034,0,0),-.177+0*.0433,-.304,0)) + self.pad.append(point(-.177+0*.0433,-.304,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'NC',angle=90)) + # + # feet + # + self.shape = add(self.shape,translate(cube(-.021,.021,-.029,.029,0,0),-.228,-.299,0)) # leave extra space for 1/64 milling + self.shape = add(self.shape,translate(cube(-.029,.029,-.029,.029,0,0),.222,-.299,0)) + self.shape = add(self.shape,translate(cube(-.015,.015,-.029,.025,0,0),-.232,0,0)) # leave extra space for 1/64 milling + self.shape = add(self.shape,translate(cube(-.015,.015,-.029,.029,0,0),-.232+.47,.025,0)) + self.shape = add(self.shape,translate(cube(-.028,.028,-.019,.019,0,0),-.221,.059,0)) + self.shape = add(self.shape,translate(cube(-.019,.019,-.030,.030,0,0),.222,.121,0)) + +pad_USB_trace = cube(-.0075,.0075,-.04,.04,0,0) +pad_USB_feet = cube(-.049,.049,-.043,.043,0,0) + +class USB_mini_B(part): + # + # USB mini B + # Hirose UX60-MB-5ST + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1 + # + self.shape = translate(pad_USB_trace,.063,.36,0) + self.pad.append(point(.063,.36,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'G')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad_USB_trace,.0315,.36,0)) + self.pad.append(point(.0315,.36,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'')) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad_USB_trace,0,.36,0)) + self.pad.append(point(0,.36,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'+')) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad_USB_trace,-.0315,.36,0)) + self.pad.append(point(-.0315,.36,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'-')) + # + # pin 5 + # + self.shape = add(self.shape,translate(pad_USB_trace,-.063,.36,0)) + self.pad.append(point(-.063,.36,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'V')) + # + # feet + # + self.shape = add(self.shape,translate(pad_USB_feet,.165,.33,0)) + self.shape = add(self.shape,translate(pad_USB_feet,-.165,.33,0)) + self.shape = add(self.shape,translate(pad_USB_feet,.165,.12,0)) + self.shape = add(self.shape,translate(pad_USB_feet,-.165,.12,0)) + +pad_header = cube(-.05,.05,-.025,.025,0,0) + +class header_4(part): + # + # 4-pin header + # fci 95278-101a04lf bergstik 2x2x0.1" + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1 + # + self.shape = translate(pad_header,-.107,.05,0) + self.shape = add(self.shape,cylinder(-.157,.05,0,0,.025)) + self.pad.append(point(-.107,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad_header,.107,.05,0)) + self.pad.append(point(.107,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'2')) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad_header,-.107,-.05,0)) + self.pad.append(point(-.107,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'3')) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad_header,.107,-.05,0)) + self.pad.append(point(.107,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'4')) + +class header_signal(part): + # + # signal header + # FCI 95278-101A04LF Bergstik 2x2x0.1" + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: Gnd + # + self.shape = translate(pad_header,.107,-.05,0) + self.shape = add(self.shape,cylinder(.157,-.05,0,0,.025)) + self.pad.append(point(.107,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad_header,-.107,-.05,0)) + self.pad.append(point(-.107,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'')) + # + # pin 3: signal + # + self.shape = add(self.shape,translate(pad_header,.107,.05,0)) + self.pad.append(point(.107,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'signal')) + # + # pin 4: + # + self.shape = add(self.shape,translate(pad_header,-.107,.05,0)) + self.pad.append(point(-.107,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'')) + + +class header_power(part): + # + # power header + # FCI 95278-101A04LF Bergstik 2x2x0.1" + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: Gnd + # + self.shape = translate(pad_header,.107,-.05,0) + self.shape = add(self.shape,cylinder(.157,-.05,0,0,.025)) + self.pad.append(point(.107,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad_header,-.107,-.05,0)) + self.pad.append(point(-.107,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'')) + # + # pin 3: V + # + self.shape = add(self.shape,translate(pad_header,.107,.05,0)) + self.pad.append(point(.107,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'V')) + # + # pin 4: + # + self.shape = add(self.shape,translate(pad_header,-.107,.05,0)) + self.pad.append(point(-.107,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'')) + +class header_i0(part): + # + # i0 header + # FCI 95278-101A04LF Bergstik 2x2x0.1" + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: Gnd + # + self.shape = translate(pad_header,.107,-.05,0) + self.shape = add(self.shape,cylinder(.157,-.05,0,0,.025)) + self.pad.append(point(.107,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 2: data + # + self.shape = add(self.shape,translate(pad_header,-.107,-.05,0)) + self.pad.append(point(-.107,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'data')) + # + # pin 3: V + # + self.shape = add(self.shape,translate(pad_header,.107,.05,0)) + self.pad.append(point(.107,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'V')) + # + # pin 4: + # + self.shape = add(self.shape,translate(pad_header,-.107,.05,0)) + self.pad.append(point(-.107,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'')) + +class header_serial(part): + # + # serial comm header + # FCI 95278-101A04LF Bergstik 2x2x0.1" + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: Gnd + # + self.shape = translate(pad_header,.107,-.05,0) + self.shape = add(self.shape,cylinder(.157,-.05,0,0,.025)) + self.pad.append(point(.107,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 2:DTR + # + self.shape = add(self.shape,translate(pad_header,-.107,-.05,0)) + self.pad.append(point(-.107,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'DTR')) + # + # pin 3: Tx + # + self.shape = add(self.shape,translate(pad_header,.107,.05,0)) + self.pad.append(point(.107,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'Tx')) + # + # pin 4: Rx + # + self.shape = add(self.shape,translate(pad_header,-.107,.05,0)) + self.pad.append(point(-.107,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'Rx')) + +class header_bus(part): + # + # bus header + # FCI 95278-101A04LF Bergstik 2x2x0.1" + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: Gnd + # + self.shape = translate(pad_header,.107,-.05,0) + self.shape = add(self.shape,cylinder(.157,-.05,0,0,.025)) + self.pad.append(point(.107,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 2: Tx + # + self.shape = add(self.shape,translate(pad_header,-.107,-.05,0)) + self.pad.append(point(-.107,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'Tx')) + # + # pin 3: V + # + self.shape = add(self.shape,translate(pad_header,.107,.05,0)) + self.pad.append(point(.107,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'V')) + # + # pin 4: Rx + # + self.shape = add(self.shape,translate(pad_header,-.107,.05,0)) + self.pad.append(point(-.107,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'Rx')) + +class header_I2C(part): + # + # I2C header + # FCI 95278-101A04LF Bergstik 2x2x0.1" + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: SCL + # + self.shape = translate(pad_header,.107,-.05,0) + self.shape = add(self.shape,cylinder(.157,-.05,0,0,.025)) + self.pad.append(point(.107,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SCL')) + # + # pin 2: G + # + self.shape = add(self.shape,translate(pad_header,-.107,-.05,0)) + self.pad.append(point(-.107,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'G')) + # + # pin 3: SDA + # + self.shape = add(self.shape,translate(pad_header,.107,.05,0)) + self.pad.append(point(.107,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SDA')) + # + # pin 4: V + # + self.shape = add(self.shape,translate(pad_header,-.107,.05,0)) + self.pad.append(point(-.107,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'V')) + +class header_APA(part): + # + # APA header + # FCI 95278-101A04LF Bergstik 2x2x0.1" + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: Gnd + # + self.shape = translate(pad_header,.107,-.05,0) + self.shape = add(self.shape,cylinder(.157,-.05,0,0,.025)) + self.pad.append(point(.107,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 2: in + # + self.shape = add(self.shape,translate(pad_header,-.107,-.05,0)) + self.pad.append(point(-.107,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'in')) + # + # pin 3: V + # + self.shape = add(self.shape,translate(pad_header,.107,.05,0)) + self.pad.append(point(.107,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'V')) + # + # pin 4: out + # + self.shape = add(self.shape,translate(pad_header,-.107,.05,0)) + self.pad.append(point(-.107,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'out')) + +class header_6(part): + # + # 6-pin header + # FCI 95278-101A06LF Bergstik 2x3x0.1" + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1 + # + self.shape = translate(pad_header,.107,-.1,0) + self.shape = add(self.shape,cylinder(.157,-.1,0,0,.025)) + self.pad.append(point(.107,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad_header,-.107,-.1,0)) + self.pad.append(point(-.107,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'')) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad_header,.107,0,0)) + self.pad.append(point(.107,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'')) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad_header,-.107,0,0)) + self.pad.append(point(-.107,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'')) + # + # pin 5 + # + self.shape = add(self.shape,translate(pad_header,.107,.1,0)) + self.pad.append(point(.107,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'')) + # + # pin 6 + # + self.shape = add(self.shape,translate(pad_header,-.107,.1,0)) + self.pad.append(point(-.107,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'')) + +class header_ATP(part): + # + # Asynchronous Token Protocol header + # FCI 95278-101A06LF Bergstik 2x3x0.1" + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1 + # + self.shape = translate(pad_header,.107,-.1,0) + self.shape = add(self.shape,cylinder(.157,-.1,0,0,.025)) + self.pad.append(point(.107,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'BI')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad_header,-.107,-.1,0)) + self.pad.append(point(-.107,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'TI')) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad_header,.107,0,0)) + self.pad.append(point(.107,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'G')) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad_header,-.107,0,0)) + self.pad.append(point(-.107,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'V')) + # + # pin 5 + # + self.shape = add(self.shape,translate(pad_header,.107,.1,0)) + self.pad.append(point(.107,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'TO')) + # + # pin 6 + # + self.shape = add(self.shape,translate(pad_header,-.107,.1,0)) + self.pad.append(point(-.107,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'BO')) + +class header_PDI(part): + # + # in-circuit PDI programming header + # FCI 95278-101A06LF Bergstik 2x3x0.1" + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: Data + # + self.shape = translate(pad_header,.107,-.1,0) + self.shape = add(self.shape,cylinder(.157,-.1,0,0,.025)) + self.pad.append(point(.107,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'DAT')) + # + # pin 2: VCC + # + self.shape = add(self.shape,translate(pad_header,-.107,-.1,0)) + self.pad.append(point(-.107,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VCC')) + # + # pin 3: NC + # + self.shape = add(self.shape,translate(pad_header,.107,0,0)) + self.pad.append(point(.107,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'NC')) + # + # pin 4: NC + # + self.shape = add(self.shape,translate(pad_header,-.107,0,0)) + self.pad.append(point(-.107,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'NC')) + # + # pin 5: Clock + # + self.shape = add(self.shape,translate(pad_header,.107,.1,0)) + self.pad.append(point(.107,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'CLK')) + # + # pin 6: GND + # + self.shape = add(self.shape,translate(pad_header,-.107,.1,0)) + self.pad.append(point(-.107,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + +class header_ISP(part): + # + # in-circuit ISP programming header + # FCI 95278-101A06LF Bergstik 2x3x0.1" + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: MISO + # + self.shape = translate(pad_header,.107,-.1,0) + self.shape = add(self.shape,cylinder(.157,-.1,0,0,.025)) + self.pad.append(point(.107,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'MISO')) + # + # pin 2: V + # + self.shape = add(self.shape,translate(pad_header,-.107,-.1,0)) + self.pad.append(point(-.107,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'V')) + # + # pin 3: SCK + # + self.shape = add(self.shape,translate(pad_header,.107,0,0)) + self.pad.append(point(.107,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SCK')) + # + # pin 4: MOSI + # + self.shape = add(self.shape,translate(pad_header,-.107,0,0)) + self.pad.append(point(-.107,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'MOSI')) + # + # pin 5: RST + # + self.shape = add(self.shape,translate(pad_header,.107,.1,0)) + self.pad.append(point(.107,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RST')) + # + # pin 6: GND + # + self.shape = add(self.shape,translate(pad_header,-.107,.1,0)) + self.pad.append(point(-.107,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + +class header_nRF24L01(part): + # + # nRF24L01 module header + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: + # + self.shape = translate(pad_header,.107,-.15,0) + self.shape = add(self.shape,cylinder(.157,-.15,0,0,.025)) + self.pad.append(point(.107,-.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 2: + # + self.shape = add(self.shape,translate(pad_header,-.107,-.15,0)) + self.pad.append(point(-.107,-.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VCC')) + # + # pin 3: + # + self.shape = add(self.shape,translate(pad_header,.107,-.05,0)) + self.pad.append(point(.107,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'CE')) + # + # pin 4: + # + self.shape = add(self.shape,translate(pad_header,-.107,-.05,0)) + self.pad.append(point(-.107,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'CS')) + # + # pin 5: + # + self.shape = add(self.shape,translate(pad_header,.107,.05,0)) + self.pad.append(point(.107,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SCK')) + # + # pin 6: + # + self.shape = add(self.shape,translate(pad_header,-.107,.05,0)) + self.pad.append(point(-.107,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'MOSI')) + # + # pin 7: + # + self.shape = add(self.shape,translate(pad_header,.107,.15,0)) + self.pad.append(point(.107,.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'MISO')) + # + # pin 8: + # + self.shape = add(self.shape,translate(pad_header,-.107,.15,0)) + self.pad.append(point(-.107,.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IRQ')) + +class header_servo(part): + # + # servo motor header + # FCI 95278-101A06LF Bergstik 2x3x0.1" + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: ground + # + self.shape = translate(pad_header,.107,-.1,0) + self.shape = add(self.shape,cylinder(.157,-.1,0,0,.025)) + self.pad.append(point(.107,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'G/blk')) + # + # pin 2: ground + # + self.shape = add(self.shape,translate(pad_header,-.107,-.1,0)) + self.pad.append(point(-.107,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'G/blk')) + # + # pin 3: power + # + self.shape = add(self.shape,translate(pad_header,.107,0,0)) + self.pad.append(point(.107,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'V/red')) + # + # pin 4: power + # + self.shape = add(self.shape,translate(pad_header,-.107,0,0)) + self.pad.append(point(-.107,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'V/red')) + # + # pin 5: signal 0 + # + self.shape = add(self.shape,translate(pad_header,.107,.1,0)) + self.pad.append(point(.107,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'S0/wht')) + # + # pin 6: signal 1 + # + self.shape = add(self.shape,translate(pad_header,-.107,.1,0)) + self.pad.append(point(-.107,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'S1/wht')) + +class header_unipolar_stepper(part): + # + # unipolar stepper header + # FCI 95278-101A06LF Bergstik 2x3x0.1" + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1 + # + self.shape = translate(pad_header,.107,-.1,0) + self.shape = add(self.shape,cylinder(.157,-.1,0,0,.025)) + self.pad.append(point(.107,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'red')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad_header,-.107,-.1,0)) + self.pad.append(point(-.107,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'green')) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad_header,.107,0,0)) + self.pad.append(point(.107,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'black')) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad_header,-.107,0,0)) + self.pad.append(point(-.107,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'brown')) + # + # pin 5 + # + self.shape = add(self.shape,translate(pad_header,.107,.1,0)) + self.pad.append(point(.107,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'orange')) + # + # pin 6 + # + self.shape = add(self.shape,translate(pad_header,-.107,.1,0)) + self.pad.append(point(-.107,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'yellow')) + +class header_LCD(part): + # + # LCD interface header + # FCI 95278-101A10LF Bergstik 2x3x0.1" + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: + # + self.shape = translate(pad_header,.107,-.2,0) + self.shape = add(self.shape,cylinder(.157,-.2,0,0,.025)) + self.pad.append(point(.107,-.2,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'DB7\n14')) + # + # pin 2: + # + self.shape = add(self.shape,translate(pad_header,-.107,-.2,0)) + self.pad.append(point(-.107,-.2,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'DB6\n13')) + # + # pin 3: + # + self.shape = add(self.shape,translate(pad_header,.107,-.1,0)) + self.pad.append(point(.107,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'DB5\n12')) + # + # pin 4: + # + self.shape = add(self.shape,translate(pad_header,-.107,-.1,0)) + self.pad.append(point(-.107,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'DB4\n11')) + # + # pin 5: + # + self.shape = add(self.shape,translate(pad_header,.107,0,0)) + self.pad.append(point(.107,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'E\n6')) + # + # pin 6: + # + self.shape = add(self.shape,translate(pad_header,-.107,0,0)) + self.pad.append(point(-.107,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'R/W\n5')) + # + # pin 7: + # + self.shape = add(self.shape,translate(pad_header,.107,.1,0)) + self.pad.append(point(.107,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RS\n4')) + # + # pin 8: + # + self.shape = add(self.shape,translate(pad_header,-.107,.1,0)) + self.pad.append(point(-.107,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'Vee\n3')) + # + # pin 9: + # + self.shape = add(self.shape,translate(pad_header,.107,.2,0)) + self.pad.append(point(.107,.2,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'Vcc\n2')) + # + # pin 10: + # + self.shape = add(self.shape,translate(pad_header,-.107,.2,0)) + self.pad.append(point(-.107,.2,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND\n1')) + +class header_serial_reverse(part): + # + # serial cable header, reverse for female connector + # GCT BG300-06-A-L-A + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: GND + # + self.shape = translate(pad_header,0,-.25,0) + self.shape = add(self.shape,cylinder(-.05,-.25,0,0,.025)) + self.pad.append(point(0,-.25,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 2: CTS (brown) + # + self.shape = add(self.shape,translate(pad_header,0,-.15,0)) + self.pad.append(point(0,-.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'CTS')) + # + # pin 3: VCC (red) + # + self.shape = add(self.shape,translate(pad_header,0,-.05,0)) + self.pad.append(point(0,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VCC')) + # + # pin 4: Tx (orange) + # + self.shape = add(self.shape,translate(pad_header,0,0.05,0)) + self.pad.append(point(0,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'Tx')) + # + # pin 5: Rx (yellow) + # + self.shape = add(self.shape,translate(pad_header,0,.15,0)) + self.pad.append(point(0,.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'Rx')) + # + # pin 6: RTS (green) + # + self.shape = add(self.shape,translate(pad_header,0,.25,0)) + self.pad.append(point(0,.25,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RTS')) + +class header_FTDI(part): + # + # FTDI cable header + # Sullins GEC36SBSN-M89 + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: GND + # + self.shape = translate(pad_header,0,.25,0) + self.shape = add(self.shape,cylinder(-.05,.25,0,0,.025)) + self.pad.append(point(0,.25,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 2: CTS (brown) + # + self.shape = add(self.shape,translate(pad_header,0,.15,0)) + self.pad.append(point(0,.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'CTS')) + # + # pin 3: VCC (red) + # + self.shape = add(self.shape,translate(pad_header,0,.05,0)) + self.pad.append(point(0,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VCC')) + # + # pin 4: Tx (orange) + # + self.shape = add(self.shape,translate(pad_header,0,-0.05,0)) + self.pad.append(point(0,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'Tx')) + # + # pin 5: Rx (yellow) + # + self.shape = add(self.shape,translate(pad_header,0,-.15,0)) + self.pad.append(point(0,-.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'Rx')) + # + # pin 6: RTS (green) + # + self.shape = add(self.shape,translate(pad_header,0,-.25,0)) + self.pad.append(point(0,-.25,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RTS')) + +class HCSR04(part): + # + # HC-SR04 sonar header + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: GND + # + self.shape = translate(pad_header,0,.15,0) + self.shape = add(self.shape,cylinder(-.05,.15,0,0,.025)) + self.pad.append(point(0,.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 2: echo + # + self.shape = add(self.shape,translate(pad_header,0,.05,0)) + self.pad.append(point(0,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'echo')) + # + # pin 3: trig + # + self.shape = add(self.shape,translate(pad_header,0,-.05,0)) + self.pad.append(point(0,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'trig')) + # + # pin 4: Vcc + # + self.shape = add(self.shape,translate(pad_header,0,-0.15,0)) + self.pad.append(point(0,-.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'Vcc')) + +class HCSR501(part): + # + # HC-SR501 motion detector header + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: Vcc + # + self.shape = translate(pad_header,0,.1,0) + self.shape = add(self.shape,cylinder(-.05,.1,0,0,.025)) + self.pad.append(point(0,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'Vcc')) + # + # pin 2: out + # + self.shape = add(self.shape,translate(pad_header,0,0,0)) + self.pad.append(point(0,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'out')) + # + # pin 3: GND + # + self.shape = add(self.shape,translate(pad_header,0,-.1,0)) + self.pad.append(point(0,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + +pad_RN4871_left = cube(-0.5/25.4,1/25.4,-0.7/2/25.4,0.7/2/25.4,0,0) +pad_RN4871_right = cube(-1/25.4,0.5/25.4,-0.7/2/25.4,0.7/2/25.4,0,0) +pad_RN4871_bot = cube(-0.7/2/25.4,0.7/2/25.4,-0.5/25.4,1/25.4,0,0) + +class RN4871(part): + # + # RN4871 + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + width = 9/25.4 + height = 7.5/25.4 + bottom = 1.9/25.4 + left = 1.5/25.4 + pitch = 1.2/25.4 + size = .004 + # + # pin 1: + # + self.shape = translate(pad_RN4871_left,-width/2.0,-height+bottom+4*pitch,0) + self.pad.append(point(-width/2.0,-height+bottom+4*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'BT_RF',line=size)) + # + # pin 2: + # + self.shape = add(self.shape,translate(pad_RN4871_left,-width/2.0,-height+bottom+3*pitch,0)) + self.pad.append(point(-width/2.0,-height+bottom+3*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND',line=size)) + # + # pin 3: + # + self.shape = add(self.shape,translate(pad_RN4871_left,-width/2.0,-height+bottom+2*pitch,0)) + self.pad.append(point(-width/2.0,-height+bottom+2*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'P1_2',line=size)) + # + # pin 4: + # + self.shape = add(self.shape,translate(pad_RN4871_left,-width/2.0,-height+bottom+1*pitch,0)) + self.pad.append(point(-width/2.0,-height+bottom+1*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'P1_3',line=size)) + # + # pin 5: + # + self.shape = add(self.shape,translate(pad_RN4871_left,-width/2.0,-height+bottom+0*pitch,0)) + self.pad.append(point(-width/2.0,-height+bottom+0*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'P1_7',line=size)) + # + # pin 6: + # + self.shape = add(self.shape,translate(pad_RN4871_bot,-width/2.0+left+0*pitch,-height,0)) + self.pad.append(point(-width/2.0+left+0*pitch,-height,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'P1_6',line=size,angle=90)) + # + # pin 7: + # + self.shape = add(self.shape,translate(pad_RN4871_bot,-width/2.0+left+1*pitch,-height,0)) + self.pad.append(point(-width/2.0+left+1*pitch,-height,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RX',line=size,angle=90)) + # + # pin 8: + # + self.shape = add(self.shape,translate(pad_RN4871_bot,-width/2.0+left+2*pitch,-height,0)) + self.pad.append(point(-width/2.0+left+2*pitch,-height,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'TX',line=size,angle=90)) + # + # pin 9: + # + self.shape = add(self.shape,translate(pad_RN4871_bot,-width/2.0+left+3*pitch,-height,0)) + self.pad.append(point(-width/2.0+left+3*pitch,-height,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'P3_6',line=size,angle=90)) + # + # pin 10: + # + self.shape = add(self.shape,translate(pad_RN4871_bot,-width/2.0+left+4*pitch,-height,0)) + self.pad.append(point(-width/2.0+left+4*pitch,-height,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RST_N',line=size,angle=90)) + # + # pin 11: + # + self.shape = add(self.shape,translate(pad_RN4871_bot,-width/2.0+left+5*pitch,-height,0)) + self.pad.append(point(-width/2.0+left+5*pitch,-height,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'P0_0',line=size,angle=90)) + # + # pin 12: + # + self.shape = add(self.shape,translate(pad_RN4871_right,width/2.0,-height+bottom+0*pitch,0)) + self.pad.append(point(width/2.0,-height+bottom+0*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'P0_2',line=size)) + # + # pin 13: + # + self.shape = add(self.shape,translate(pad_RN4871_right,width/2.0,-height+bottom+1*pitch,0)) + self.pad.append(point(width/2.0,-height+bottom+1*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND',line=size)) + # + # pin 14: + # + self.shape = add(self.shape,translate(pad_RN4871_right,width/2.0,-height+bottom+2*pitch,0)) + self.pad.append(point(width/2.0,-height+bottom+2*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VBAT',line=size)) + # + # pin 15: + # + self.shape = add(self.shape,translate(pad_RN4871_right,width/2.0,-height+bottom+3*pitch,0)) + self.pad.append(point(width/2.0,-height+bottom+3*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'P2_7',line=size)) + # + # pin 16: + # + self.shape = add(self.shape,translate(pad_RN4871_right,width/2.0,-height+bottom+4*pitch,0)) + self.pad.append(point(width/2.0,-height+bottom+4*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'P2_0',line=size)) + +pad_HM11 = cube(-.047,.047,-.0177,.0177,0,0) + +class HM11(part): + # + # HM-11 + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + height = 18.5/25.4 + width = 13.5/25.4 + pitch = 1.5/25.4 + bottom = 1/25.4 + offset = 0 + size = .004 + # + # pin 1: + # + self.shape = translate(pad_HM11,-width/2.0+offset,-height/2.0+bottom+7*pitch,0) + self.pad.append(point(-width/2.0+offset,-height/2.0+bottom+7*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RTS',line=size)) + # + # pin 2: + # + self.shape = add(self.shape,translate(pad_HM11,-width/2.0+offset,-height/2.0+bottom+6*pitch,0)) + self.pad.append(point(-width/2.0+offset,-height/2.0+bottom+6*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'TX',line=size)) + # + # pin 3: + # + self.shape = add(self.shape,translate(pad_HM11,-width/2.0+offset,-height/2.0+bottom+5*pitch,0)) + self.pad.append(point(-width/2.0+offset,-height/2.0+bottom+5*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'CTS',line=size)) + # + # pin 4: + # + self.shape = add(self.shape,translate(pad_HM11,-width/2.0+offset,-height/2.0+bottom+4*pitch,0)) + self.pad.append(point(-width/2.0+offset,-height/2.0+bottom+4*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RX',line=size)) + # + # pin 5: + # + self.shape = add(self.shape,translate(pad_HM11,-width/2.0+offset,-height/2.0+bottom+3*pitch,0)) + self.pad.append(point(-width/2.0+offset,-height/2.0+bottom+3*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'NC',line=size)) + # + # pin 6: + # + self.shape = add(self.shape,translate(pad_HM11,-width/2.0+offset,-height/2.0+bottom+2*pitch,0)) + self.pad.append(point(-width/2.0+offset,-height/2.0+bottom+2*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'NC',line=size)) + # + # pin 7: + # + self.shape = add(self.shape,translate(pad_HM11,-width/2.0+offset,-height/2.0+bottom+1*pitch,0)) + self.pad.append(point(-width/2.0+offset,-height/2.0+bottom+1*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'NC',line=size)) + # + # pin 8: + # + self.shape = add(self.shape,translate(pad_HM11,-width/2.0+offset,-height/2.0+bottom+0*pitch,0)) + self.pad.append(point(-width/2.0+offset,-height/2.0+bottom+0*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'NC',line=size)) + # + # pin 9: + # + self.shape = add(self.shape,translate(pad_HM11,width/2.0-offset,-height/2.0+bottom+0*pitch,0)) + self.pad.append(point(width/2.0-offset,-height/2.0+bottom+0*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VCC',line=size)) + # + # pin 10: + # + self.shape = add(self.shape,translate(pad_HM11,width/2.0-offset,-height/2.0+bottom+1*pitch,0)) + self.pad.append(point(width/2.0-offset,-height/2.0+bottom+1*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'NC',line=size)) + # + # pin 11: + # + self.shape = add(self.shape,translate(pad_HM11,width/2.0-offset,-height/2.0+bottom+2*pitch,0)) + self.pad.append(point(width/2.0-offset,-height/2.0+bottom+2*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RST',line=size)) + # + # pin 12: + # + self.shape = add(self.shape,translate(pad_HM11,width/2.0-offset,-height/2.0+bottom+3*pitch,0)) + self.pad.append(point(width/2.0-offset,-height/2.0+bottom+3*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND',line=size)) + # + # pin 13: + # + self.shape = add(self.shape,translate(pad_HM11,width/2.0-offset,-height/2.0+bottom+4*pitch,0)) + self.pad.append(point(width/2.0-offset,-height/2.0+bottom+4*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO3',line=size)) + # + # pin 14: + # + self.shape = add(self.shape,translate(pad_HM11,width/2.0-offset,-height/2.0+bottom+5*pitch,0)) + self.pad.append(point(width/2.0-offset,-height/2.0+bottom+5*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO2',line=size)) + # + # pin 15: + # + self.shape = add(self.shape,translate(pad_HM11,width/2.0-offset,-height/2.0+bottom+6*pitch,0)) + self.pad.append(point(width/2.0-offset,-height/2.0+bottom+6*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO1',line=size)) + # + # pin 16: + # + self.shape = add(self.shape,translate(pad_HM11,width/2.0-offset,-height/2.0+bottom+7*pitch,0)) + self.pad.append(point(width/2.0-offset,-height/2.0+bottom+7*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO0',line=size)) + +class ESP32_WROOM(part): + # + # ESP32-WROOM + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + pad = cube(-1/25.4,1/25.4,-.4/25.4,.4/25.4,0,0) + padb = cube(-.4/25.4,.4/25.4,-1/25.4,1/25.4,0,0) + width = 17/25.4 + height = 25.5/25.4 + pitch = 1.27/25.4 + # + # pin 1 + # + self.shape = translate(pad,-width/2,6*pitch,0) + self.pad.append(point(-width/2,6*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad,-width/2,5*pitch,0)) + self.pad.append(point(-width/2,5*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'3V3')) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad,-width/2,4*pitch,0)) + self.pad.append(point(-width/2,4*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'EN')) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad,-width/2,3*pitch,0)) + self.pad.append(point(-width/2,3*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VP')) + # + # pin 5 + # + self.shape = add(self.shape,translate(pad,-width/2,2*pitch,0)) + self.pad.append(point(-width/2,2*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VN')) + # + # pin 6 + # + self.shape = add(self.shape,translate(pad,-width/2,1*pitch,0)) + self.pad.append(point(-width/2,1*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO34')) + # + # pin 7 + # + self.shape = add(self.shape,translate(pad,-width/2,0*pitch,0)) + self.pad.append(point(-width/2,0*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO35')) + # + # pin 8 + # + self.shape = add(self.shape,translate(pad,-width/2,-1*pitch,0)) + self.pad.append(point(-width/2,-1*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO32')) + # + # pin 9 + # + self.shape = add(self.shape,translate(pad,-width/2,-2*pitch,0)) + self.pad.append(point(-width/2,-2*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO33')) + # + # pin 10 + # + self.shape = add(self.shape,translate(pad,-width/2,-3*pitch,0)) + self.pad.append(point(-width/2,-3*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO25')) + # + # pin 11 + # + self.shape = add(self.shape,translate(pad,-width/2,-4*pitch,0)) + self.pad.append(point(-width/2,-4*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO26')) + # + # pin 12 + # + self.shape = add(self.shape,translate(pad,-width/2,-5*pitch,0)) + self.pad.append(point(-width/2,-5*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO27')) + # + # pin 13 + # + self.shape = add(self.shape,translate(pad,-width/2,-6*pitch,0)) + self.pad.append(point(-width/2,-6*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO14')) + # + # pin 14 + # + self.shape = add(self.shape,translate(pad,-width/2,-7*pitch,0)) + self.pad.append(point(-width/2,-7*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO12')) + # + # pin 15 + # + self.shape = add(self.shape,translate(padb,-4.5*pitch,-7*pitch-1/25.4,0)) + self.pad.append(point(-4.5*pitch,-7*pitch-1/25.4,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND',angle=90)) + # + # pin 16 + # + self.shape = add(self.shape,translate(padb,-3.5*pitch,-7*pitch-1/25.4,0)) + self.pad.append(point(-3.5*pitch,-7*pitch-1/25.4,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO13',angle=90)) + # + # pin 17 + # + self.shape = add(self.shape,translate(padb,-2.5*pitch,-7*pitch-1/25.4,0)) + self.pad.append(point(-2.5*pitch,-7*pitch-1/25.4,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SHD',angle=90)) + # + # pin 18 + # + self.shape = add(self.shape,translate(padb,-1.5*pitch,-7*pitch-1/25.4,0)) + self.pad.append(point(-1.5*pitch,-7*pitch-1/25.4,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SWP',angle=90)) + # + # pin 19 + # + self.shape = add(self.shape,translate(padb,-0.5*pitch,-7*pitch-1/25.4,0)) + self.pad.append(point(-0.5*pitch,-7*pitch-1/25.4,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SCS',angle=90)) + # + # pin 20 + # + self.shape = add(self.shape,translate(padb,0.5*pitch,-7*pitch-1/25.4,0)) + self.pad.append(point(0.5*pitch,-7*pitch-1/25.4,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SCK',angle=90)) + # + # pin 21 + # + self.shape = add(self.shape,translate(padb,1.5*pitch,-7*pitch-1/25.4,0)) + self.pad.append(point(1.5*pitch,-7*pitch-1/25.4,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SDO',angle=90)) + # + # pin 22 + # + self.shape = add(self.shape,translate(padb,2.5*pitch,-7*pitch-1/25.4,0)) + self.pad.append(point(2.5*pitch,-7*pitch-1/25.4,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SDI',angle=90)) + # + # pin 23 + # + self.shape = add(self.shape,translate(padb,3.5*pitch,-7*pitch-1/25.4,0)) + self.pad.append(point(3.5*pitch,-7*pitch-1/25.4,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO15',angle=90)) + # + # pin 24 + # + self.shape = add(self.shape,translate(padb,4.5*pitch,-7*pitch-1/25.4,0)) + self.pad.append(point(4.5*pitch,-7*pitch-1/25.4,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO2',angle=90)) + # + # pin 25 + # + self.shape = add(self.shape,translate(pad,width/2,-7*pitch,0)) + self.pad.append(point(width/2,-7*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO0')) + # + # pin 26 + # + self.shape = add(self.shape,translate(pad,width/2,-6*pitch,0)) + self.pad.append(point(width/2,-6*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO4')) + # + # pin 27 + # + self.shape = add(self.shape,translate(pad,width/2,-5*pitch,0)) + self.pad.append(point(width/2,-5*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO16')) + # + # pin 28 + # + self.shape = add(self.shape,translate(pad,width/2,-4*pitch,0)) + self.pad.append(point(width/2,-4*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO17')) + # + # pin 29 + # + self.shape = add(self.shape,translate(pad,width/2,-3*pitch,0)) + self.pad.append(point(width/2,-3*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO5')) + # + # pin 30 + # + self.shape = add(self.shape,translate(pad,width/2,-2*pitch,0)) + self.pad.append(point(width/2,-2*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO18')) + # + # pin 31 + # + self.shape = add(self.shape,translate(pad,width/2,-1*pitch,0)) + self.pad.append(point(width/2,-1*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO19')) + # + # pin 32 + # + self.shape = add(self.shape,translate(pad,width/2,0*pitch,0)) + self.pad.append(point(width/2,0*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'NC')) + # + # pin 33 + # + self.shape = add(self.shape,translate(pad,width/2,1*pitch,0)) + self.pad.append(point(width/2,1*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO21')) + # + # pin 34 + # + self.shape = add(self.shape,translate(pad,width/2,2*pitch,0)) + self.pad.append(point(width/2,2*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RX0')) + # + # pin 35 + # + self.shape = add(self.shape,translate(pad,width/2,3*pitch,0)) + self.pad.append(point(width/2,3*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'TX0')) + # + # pin 36 + # + self.shape = add(self.shape,translate(pad,width/2,4*pitch,0)) + self.pad.append(point(width/2,4*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO22')) + # + # pin 37 + # + self.shape = add(self.shape,translate(pad,width/2,5*pitch,0)) + self.pad.append(point(width/2,5*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO23')) + # + # pin 38 + # + self.shape = add(self.shape,translate(pad,width/2,6*pitch,0)) + self.pad.append(point(width/2,6*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + +class ESP32_CAM(part): + # + # ESP32-CAM + # Sullins S5635-ND + # + def __init__(self,value=''): + pad_header = cube(-.079/2,.079/2,-.039/2,.039/2,0,0) + d = .209/2-.079/2 + w = 0.9 + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1 + # + self.shape = translate(pad_header,+d-w/2,.35,0) + self.pad.append(point(+d-w/2,.35,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'+5V')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad_header,-d-w/2,.25,0)) + self.pad.append(point(-d-w/2,.25,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad_header,+d-w/2,.15,0)) + self.pad.append(point(+d-w/2,.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO12')) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad_header,-d-w/2,.05,0)) + self.pad.append(point(-d-w/2,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO13')) + # + # pin 5 + # + self.shape = add(self.shape,translate(pad_header,+d-w/2,-.05,0)) + self.pad.append(point(+d-w/2,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO15')) + # + # pin 6 + # + self.shape = add(self.shape,translate(pad_header,-d-w/2,-.15,0)) + self.pad.append(point(-d-w/2,-.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO14')) + # + # pin 7 + # + self.shape = add(self.shape,translate(pad_header,+d-w/2,-.25,0)) + self.pad.append(point(+d-w/2,-.25,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO2')) + # + # pin 8 + # + self.shape = add(self.shape,translate(pad_header,-d-w/2,-.35,0)) + self.pad.append(point(-d-w/2,-.35,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO4')) + # + # pin 9 + # + self.shape = add(self.shape,translate(pad_header,-d+w/2,-.35,0)) + self.pad.append(point(-d+w/2,-.35,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 10 + # + self.shape = add(self.shape,translate(pad_header,+d+w/2,-.25,0)) + self.pad.append(point(+d+w/2,-.25,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'U0T')) + # + # pin 11 + # + self.shape = add(self.shape,translate(pad_header,-d+w/2,-.15,0)) + self.pad.append(point(-d+w/2,-.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'U0R')) + # + # pin 12 + # + self.shape = add(self.shape,translate(pad_header,+d+w/2,-.05,0)) + self.pad.append(point(+d+w/2,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VCC')) + # + # pin 13 + # + self.shape = add(self.shape,translate(pad_header,-d+w/2,.05,0)) + self.pad.append(point(-d+w/2,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 14 + # + self.shape = add(self.shape,translate(pad_header,+d+w/2,.15,0)) + self.pad.append(point(+d+w/2,.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO0')) + # + # pin 15 + # + self.shape = add(self.shape,translate(pad_header,-d+w/2,.25,0)) + self.pad.append(point(-d+w/2,.25,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO16')) + # + # pin 16 + # + self.shape = add(self.shape,translate(pad_header,+d+w/2,.35,0)) + self.pad.append(point(+d+w/2,.35,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'3V3')) + + +class ESP8266_12E(part): + # + # ESP8266 12E + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + height = 24/25.4 + width = 16/25.4 + pitch = 2/25.4 + bottom = 1.8/25.4 + left = 3/25.4 + offset = .4/25.4 - .01 + size = .004 + pad_ESP8266 = cube(-.0493,.0493,-.0197,.0197,0,0) + pad_ESP8266_bot = cube(-.0197,.0197,-.0415,.0415,0,0) + # + # pin 1: + # + self.shape = translate(pad_ESP8266,-width/2.0+offset,-height/2.0+bottom+7*pitch,0) + self.pad.append(point(-width/2.0+offset,-height/2.0+bottom+7*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RST',line=size)) + # + # pin 2: + # + self.shape = add(self.shape,translate(pad_ESP8266,-width/2.0+offset,-height/2.0+bottom+6*pitch,0)) + self.pad.append(point(-width/2.0+offset,-height/2.0+bottom+6*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'ADC',line=size)) + # + # pin 3: + # + self.shape = add(self.shape,translate(pad_ESP8266,-width/2.0+offset,-height/2.0+bottom+5*pitch,0)) + self.pad.append(point(-width/2.0+offset,-height/2.0+bottom+5*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'EN',line=size)) + # + # pin 4: + # + self.shape = add(self.shape,translate(pad_ESP8266,-width/2.0+offset,-height/2.0+bottom+4*pitch,0)) + self.pad.append(point(-width/2.0+offset,-height/2.0+bottom+4*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GPIO16',line=size)) + # + # pin 5: + # + self.shape = add(self.shape,translate(pad_ESP8266,-width/2.0+offset,-height/2.0+bottom+3*pitch,0)) + self.pad.append(point(-width/2.0+offset,-height/2.0+bottom+3*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GPIO14',line=size)) + # + # pin 6: + # + self.shape = add(self.shape,translate(pad_ESP8266,-width/2.0+offset,-height/2.0+bottom+2*pitch,0)) + self.pad.append(point(-width/2.0+offset,-height/2.0+bottom+2*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GPIO12',line=size)) + # + # pin 7: + # + self.shape = add(self.shape,translate(pad_ESP8266,-width/2.0+offset,-height/2.0+bottom+1*pitch,0)) + self.pad.append(point(-width/2.0+offset,-height/2.0+bottom+1*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GPIO13',line=size)) + # + # pin 8: + # + self.shape = add(self.shape,translate(pad_ESP8266,-width/2.0+offset,-height/2.0+bottom+0*pitch,0)) + self.pad.append(point(-width/2.0+offset,-height/2.0+bottom+0*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VDD',line=size)) + # + # pin 9: + # + self.shape = add(self.shape,translate(pad_ESP8266_bot,-width/2.0+left+0*pitch,-height/2.0+offset,0)) + self.pad.append(point(-width/2.0+left+0*pitch,-height/2.0+offset,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'CS',line=size,angle=90)) + # + # pin 10: + # + self.shape = add(self.shape,translate(pad_ESP8266_bot,-width/2.0+left+1*pitch,-height/2.0+offset,0)) + self.pad.append(point(-width/2.0+left+1*pitch,-height/2.0+offset,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'MISO',line=size,angle=90)) + # + # pin 11: + # + self.shape = add(self.shape,translate(pad_ESP8266_bot,-width/2.0+left+2*pitch,-height/2.0+offset,0)) + self.pad.append(point(-width/2.0+left+2*pitch,-height/2.0+offset,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GPIO9',line=size,angle=90)) + # + # pin 12: + # + self.shape = add(self.shape,translate(pad_ESP8266_bot,-width/2.0+left+3*pitch,-height/2.0+offset,0)) + self.pad.append(point(-width/2.0+left+3*pitch,-height/2.0+offset,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GPIO10',line=size,angle=90)) + # + # pin 13: + # + self.shape = add(self.shape,translate(pad_ESP8266_bot,-width/2.0+left+4*pitch,-height/2.0+offset,0)) + self.pad.append(point(-width/2.0+left+4*pitch,-height/2.0+offset,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'MOSI',line=size,angle=90)) + # + # pin 14: + # + self.shape = add(self.shape,translate(pad_ESP8266_bot,-width/2.0+left+5*pitch,-height/2.0+offset,0)) + self.pad.append(point(-width/2.0+left+5*pitch,-height/2.0+offset,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SCLK',line=size,angle=90)) + # + # pin 15: + # + self.shape = add(self.shape,translate(pad_ESP8266,width/2.0-offset,-height/2.0+bottom+0*pitch,0)) + self.pad.append(point(width/2.0-offset,-height/2.0+bottom+0*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND',line=size)) + # + # pin 16: + # + self.shape = add(self.shape,translate(pad_ESP8266,width/2.0-offset,-height/2.0+bottom+1*pitch,0)) + self.pad.append(point(width/2.0-offset,-height/2.0+bottom+1*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GPIO15',line=size)) + # + # pin 17: + # + self.shape = add(self.shape,translate(pad_ESP8266,width/2.0-offset,-height/2.0+bottom+2*pitch,0)) + self.pad.append(point(width/2.0-offset,-height/2.0+bottom+2*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GPIO2',line=size)) + # + # pin 18: + # + self.shape = add(self.shape,translate(pad_ESP8266,width/2.0-offset,-height/2.0+bottom+3*pitch,0)) + self.pad.append(point(width/2.0-offset,-height/2.0+bottom+3*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GPIO0',line=size)) + # + # pin 19: + # + self.shape = add(self.shape,translate(pad_ESP8266,width/2.0-offset,-height/2.0+bottom+4*pitch,0)) + self.pad.append(point(width/2.0-offset,-height/2.0+bottom+4*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GPIO4',line=size)) + # + # pin 20: + # + self.shape = add(self.shape,translate(pad_ESP8266,width/2.0-offset,-height/2.0+bottom+5*pitch,0)) + self.pad.append(point(width/2.0-offset,-height/2.0+bottom+5*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GPIO5',line=size)) + # + # pin 21: + # + self.shape = add(self.shape,translate(pad_ESP8266,width/2.0-offset,-height/2.0+bottom+6*pitch,0)) + self.pad.append(point(width/2.0-offset,-height/2.0+bottom+6*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RXD',line=size)) + # + # pin 22: + # + self.shape = add(self.shape,translate(pad_ESP8266,width/2.0-offset,-height/2.0+bottom+7*pitch,0)) + self.pad.append(point(width/2.0-offset,-height/2.0+bottom+7*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'TXD',line=size)) + +pad_MTA = cube(-.021,.021,-.041,.041,0,0) +pad_MTA_solder = cube(-.071,.071,-.041,.041,0,0) + +class MTA_2(part): + # + # AMP 1445121-2 + # MTA .050 SMT 2-pin vertical + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1 + # + self.shape = translate(pad_MTA,-.025,-.1,0) + self.pad.append(point(-.025,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad_MTA,.025,.1,0)) + self.pad.append(point(.025,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'2')) + # + # solder pads + # + self.shape = add(self.shape,translate(pad_MTA_solder,-.187,0,0)) + self.shape = add(self.shape,translate(pad_MTA_solder,.187,0,0)) + +class MTA_power(part): + # + # AMP 1445121-2 + # MTA .050 SMT 2-pin vertical + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: Gnd + # + self.shape = translate(pad_MTA,-.025,-.1,0) + self.pad.append(point(-.025,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1\nGND')) + # + # pin 2: Vcc + # + self.shape = add(self.shape,translate(pad_MTA,.025,.1,0)) + self.pad.append(point(.025,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'Vcc')) + # + # solder pads + # + self.shape = add(self.shape,translate(pad_MTA_solder,-.187,0,0)) + self.shape = add(self.shape,translate(pad_MTA_solder,.187,0,0)) + +class MTA_3(part): + # + # AMP 1445121-3 + # MTA .050 SMT 3-pin vertical + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: GND + # + self.shape = translate(pad_MTA,.05,.1,0) + self.pad.append(point(.05,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1')) + # + # pin 2: power + # + self.shape = add(self.shape,translate(pad_MTA,-.05,.1,0)) + self.pad.append(point(-.05,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'2')) + # + # pin 3: data + # + self.shape = add(self.shape,translate(pad_MTA,0,-.1,0)) + self.pad.append(point(0,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'3')) + # + # solder pads + # + self.shape = add(self.shape,translate(pad_MTA_solder,-.212,0,0)) + self.shape = add(self.shape,translate(pad_MTA_solder,.212,0,0)) + +class MTA_i0(part): + # + # AMP 1445121-3 + # MTA .050 SMT 3-pin vertical + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: GND + # + self.shape = translate(pad_MTA,.05,.1,0) + self.pad.append(point(.05,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1\nGND')) + # + # pin 2: power + # + self.shape = add(self.shape,translate(pad_MTA,-.05,.1,0)) + self.pad.append(point(-.05,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'V')) + # + # pin 3: data + # + self.shape = add(self.shape,translate(pad_MTA,0,-.1,0)) + self.pad.append(point(0,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'data')) + # + # solder pads + # + self.shape = add(self.shape,translate(pad_MTA_solder,-.212,0,0)) + self.shape = add(self.shape,translate(pad_MTA_solder,.212,0,0)) + +class MTA_4(part): + # + # AMP 1445121-4 + # MTA .050 SMT 4-pin vertical + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1 + # + self.shape = translate(pad_MTA,-.075,-.1,0) + self.pad.append(point(-.075,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad_MTA,.025,-.1,0)) + self.pad.append(point(.025,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'2')) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad_MTA,.075,.1,0)) + self.pad.append(point(.075,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'3')) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad_MTA,-.025,.1,0)) + self.pad.append(point(-.025,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'4')) + # + # solder pads + # + self.shape = add(self.shape,translate(pad_MTA_solder,-.237,0,0)) + self.shape = add(self.shape,translate(pad_MTA_solder,.237,0,0)) + +class MTA_serial(part): + # + # AMP 1445121-4 + # MTA .050 SMT 4-pin vertical + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: Gnd + # + self.shape = translate(pad_MTA,-.075,-.1,0) + self.pad.append(point(-.075,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1')) + # + # pin 2: Tx + # + self.shape = add(self.shape,translate(pad_MTA,.025,-.1,0)) + self.pad.append(point(.025,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'Tx')) + # + # pin 3: Rx + # + self.shape = add(self.shape,translate(pad_MTA,.075,.1,0)) + self.pad.append(point(.075,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'Rx')) + # + # pin 4: DTR + # + self.shape = add(self.shape,translate(pad_MTA,-.025,.1,0)) + self.pad.append(point(-.025,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'DTR')) + # + # solder pads + # + self.shape = add(self.shape,translate(pad_MTA_solder,-.237,0,0)) + self.shape = add(self.shape,translate(pad_MTA_solder,.237,0,0)) + +class MTA_PS2(part): + # + # AMP 1445121-4 + # MTA .050 SMT 4-pin vertical + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: GND + # + self.shape = translate(pad_MTA,-.075,-.1,0) + self.pad.append(point(-.075,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1\nGND')) + # + # pin 2: data + # + self.shape = add(self.shape,translate(pad_MTA,.025,-.1,0)) + self.pad.append(point(.025,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'data')) + # + # pin 3: clock + # + self.shape = add(self.shape,translate(pad_MTA,.075,.1,0)) + self.pad.append(point(.075,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'clock')) + # + # pin 4: 5V + # + self.shape = add(self.shape,translate(pad_MTA,-.025,.1,0)) + self.pad.append(point(-.025,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'5V')) + # + # solder pads + # + self.shape = add(self.shape,translate(pad_MTA_solder,-.237,0,0)) + self.shape = add(self.shape,translate(pad_MTA_solder,.237,0,0)) + +class MTA_5(part): + # + # AMP 1445121-5 + # MTA .050 SMT 5-pin vertical + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1 + # + self.shape = translate(pad_MTA,-.1,-.1,0) + self.pad.append(point(-.1,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad_MTA,0,-.1,0)) + self.pad.append(point(0,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'2')) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad_MTA,.1,-.1,0)) + self.pad.append(point(.1,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'3')) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad_MTA,.05,.1,0)) + self.pad.append(point(.05,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'4')) + # + # pin 5 + # + self.shape = add(self.shape,translate(pad_MTA,-.05,.1,0)) + self.pad.append(point(-.05,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'5')) + # + # solder pads + # + self.shape = add(self.shape,translate(pad_MTA_solder,-.262,0,0)) + self.shape = add(self.shape,translate(pad_MTA_solder,.262,0,0)) + +class MTA_ICP(part): + # + # AMP 1445121-5 + # MTA .050 SMT 5-pin vertical + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: MISO + # + self.shape = translate(pad_MTA,-.1,-.1,0) + self.pad.append(point(-.1,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'MISO')) + # + # pin 2: GND + # + self.shape = add(self.shape,translate(pad_MTA,0,-.1,0)) + self.pad.append(point(0,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 3: MOSI + # + self.shape = add(self.shape,translate(pad_MTA,.1,-.1,0)) + self.pad.append(point(.1,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'MOSI')) + # + # pin 4: -RESET + # + self.shape = add(self.shape,translate(pad_MTA,.05,.1,0)) + self.pad.append(point(.05,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'-RESET')) + # + # pin 5: SCK + # + self.shape = add(self.shape,translate(pad_MTA,-.05,.1,0)) + self.pad.append(point(-.05,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SCK')) + # + # solder pads + # + self.shape = add(self.shape,translate(pad_MTA_solder,-.262,0,0)) + self.shape = add(self.shape,translate(pad_MTA_solder,.262,0,0)) + +pad_screw_terminal = cylinder(0,0,0,0,.047) +hole_screw_terminal = circle(0,0,.025) + +class screw_terminal_2(part): + # + # On Shore ED555/2DS + # two position screw terminal + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1 + # + self.shape = translate(pad_screw_terminal,-.069,0,0) + self.pad.append(point(-.069,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad_screw_terminal,.069,0,0)) + self.pad.append(point(.069,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'2')) + # + # holes + # + self.shape = add(self.shape,translate(hole_screw_terminal,-.069,0,0)) + self.shape = add(self.shape,translate(hole_screw_terminal,.069,0,0)) + +class screw_terminal_power(part): + # + # On Shore ED555/2DS + # power screw terminal + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1 + # + self.shape = translate(pad_screw_terminal,-.069,0,0) + self.pad.append(point(-.069,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'G')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad_screw_terminal,.069,0,0)) + self.pad.append(point(.069,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'V')) + # + # holes + # + self.shape = add(self.shape,translate(hole_screw_terminal,-.069,0,0)) + self.shape = add(self.shape,translate(hole_screw_terminal,.069,0,0)) + +class screw_terminal_i0(part): + # + # On Shore ED555/3DS + # i0 screw terminal + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: Gnd + # + self.shape = translate(pad_screw_terminal,-.138,0,0) + self.pad.append(point(-.138,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'Gnd\n1')) + # + # pin 2: data + # + self.shape = add(self.shape,pad_screw_terminal) + self.pad.append(point(0,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'data')) + # + # pin 3: V + # + self.shape = add(self.shape,translate(pad_screw_terminal,.138,0,0)) + self.pad.append(point(.138,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'V')) + # + # holes + # + self.shape = add(self.shape,translate(hole_screw_terminal,-.138,0,0)) + self.shape = add(self.shape,hole_screw_terminal) + self.shape = add(self.shape,translate(hole_screw_terminal,.138,0,0)) + +class power_65mm(part): + # + # CUI PJ1-023-SMT + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: power + # + self.shape = cube(.433,.512,-.047,.047,0,0) + self.pad.append(point(.467,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'P')) + # + # pin 2: ground + # + self.shape = add(self.shape,cube(.285,.423,-.189,-.098,0,0)) + self.pad.append(point(.354,-.144,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'G')) + # + # pin 3: contact + # + self.shape = add(self.shape,cube(.325,.463,.098,.189,0,0)) + self.pad.append(point(.394,.144,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'C')) + # + # solder pads + # + self.shape = add(self.shape,cube(.108,.246,-.169,-.110,0,0)) + self.shape = add(self.shape,cube(.069,.207,.110,.169,0,0)) + +pad_stereo_2_5mm = cube(-.03,.03,-.05,.05,0,0) + +class stereo_2_5mm(part): + # + # CUI SJ1-2533-SMT + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: base + # + self.shape = translate(pad_stereo_2_5mm,-.130,-.16,0) + self.pad.append(point(-.130,-.149,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'base')) + # + # pin 2: tip + # + self.shape = add(self.shape,translate(pad_stereo_2_5mm,.197,.15,0)) + self.pad.append(point(.197,.141,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'tip')) + # + # pin 3: middle + # + self.shape = add(self.shape,translate(pad_stereo_2_5mm,-.012,-.16,0)) + self.pad.append(point(-.012,-.149,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'middle')) + +pad_Molex = cube(-.0155,.0155,-.0265,.0265,0,0) +pad_Molex_solder = cube(-.055,.055,-.065,.065,0,0) + +class Molex_serial(part): + # + # Molex 53261-0471 + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: Rx + # + self.shape = translate(pad_Molex,-.075,.064,0) + self.pad.append(point(-.075,.064,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'Rx')) + # + # pin 2: Tx + # + self.shape = add(self.shape,translate(pad_Molex,-.025,.064,0)) + self.pad.append(point(-.025,.064,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'Tx')) + # + # pin 3: DTR + # + self.shape = add(self.shape,translate(pad_Molex,.025,.064,0)) + self.pad.append(point(.025,.064,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'DTR')) + # + # pin 4: GND + # + self.shape = add(self.shape,translate(pad_Molex,.075,.064,0)) + self.pad.append(point(.075,.064,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # solder pads + # + self.shape = add(self.shape,translate(pad_Molex_solder,-.16,-.065,0)) + self.shape = add(self.shape,translate(pad_Molex_solder,.16,-.065,0)) + +############################################################ +# switches +############################################################ + +class slide_switch(part): + # + # slide switch + # C&K AYZ0102AGRLC + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + pad = cube(-.039/2,.039/2,-.047/2,.047/2,0,0) + # + # pad 1 + # + self.shape = translate(pad,-.098,.1,0) + self.pad.append(point(-.098,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'')) + # + # pad 2 + # + self.shape = add(self.shape,translate(pad,0,.1,0)) + self.pad.append(point(0,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'')) + # + # pad 3 + # + self.shape = add(self.shape,translate(pad,.098,.1,0)) + self.pad.append(point(.098,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'')) + # + # holes + # + self.holes = cylinder(-.118/2,0,zb,zt,.034/2) + self.holes = add(self.holes,cylinder(.118/2,0,zb,zt,.034/2)) + +class button_6mm(part): + # + # Omron 6mm pushbutton + # B3SN-3112P + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + pad_button_6mm = cube(-.04,.04,-.03,.03,0,0) + # + # left 1 + # + self.shape = translate(pad_button_6mm,-.125,.08,0) + self.pad.append(point(-.125,.08,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'L1')) + # + # right 1 + # + self.shape = add(self.shape,translate(pad_button_6mm,-.125,-.08,0)) + self.pad.append(point(-.125,-.08,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'R1')) + # + # right 2 + # + self.shape = add(self.shape,translate(pad_button_6mm,.125,-.08,0)) + self.pad.append(point(.125,-.08,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'R2')) + # + # left 2 + # + self.shape = add(self.shape,translate(pad_button_6mm,.125,.08,0)) + self.pad.append(point(.125,.08,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'L2')) + +############################################################ +# crystals and resonators +############################################################ + +pad_XTAL_EFOBM = cube(-.016,.016,-.085,.085,0,0) + +class XTAL_EFOBM(part): + # + # Panasonic EFOBM series + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # left + # + self.shape = translate(pad_XTAL_EFOBM,-.053,0,0) + self.pad.append(point(-.053,0,0)) + # + # ground + # + self.shape = add(self.shape,translate(pad_XTAL_EFOBM,0,0,0)) + self.pad.append(point(0,0,0)) + # + # right + # + self.shape = add(self.shape,translate(pad_XTAL_EFOBM,.053,0,0)) + self.pad.append(point(.053,0,0)) + +pad_XTAL_NX5032GA = cube(-.039,.039,-.047,.047,0,0) +.079 + +class XTAL_NX5032GA(part): + # + # NDK NX5032GA + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # left + # + self.shape = translate(pad_XTAL_NX5032GA,-.079,0,0) + self.pad.append(point(-.079,0,0)) + # + # right + # + self.shape = add(self.shape,translate(pad_XTAL_NX5032GA,.079,0,0)) + self.pad.append(point(.079,0,0)) + +pad_XTAL_CSM_7 = cube(-.108,.108,-.039,.039,0,0) + +class XTAL_CSM_7(part): + # + # ECS CSM-7 series + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # left + # + self.shape = translate(pad_XTAL_CSM_7,-.187,0,0) + self.pad.append(point(-.187,0,0)) + # + # right + # + self.shape = add(self.shape,translate(pad_XTAL_CSM_7,.187,0,0)) + self.pad.append(point(.187,0,0)) + +############################################################ +# diodes, transistors, regulators, sensors +############################################################ + +class DRV8428_HTSSOP(part): + # + # TI DRV8428PWPR stepper driver + # HTSSOP package + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + d = 0.12 + w = 0.029 + h = 0.0053 + p = 0.02559 + pad = cube(-w,w,-h,h,0,0) + s = 0.003 + # + # pin 1 + # + self.shape = translate(pad,-d,3.5*p,0) + self.shape = add(self.shape,cylinder(-d-w,3.5*p,0,0,h)) + self.pad.append(point(-d,3.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'.VM',line=s)) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad,-d,2.5*p,0)) + self.pad.append(point(-d,2.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PGND',line=s)) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad,-d,1.5*p,0)) + self.pad.append(point(-d,1.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'AOUT1',line=s)) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad,-d,.5*p,0)) + self.pad.append(point(-d,.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'AOUT2',line=s)) + # + # pin 5 + # + self.shape = add(self.shape,translate(pad,-d,-.5*p,0)) + self.pad.append(point(-d,-.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'BOUT2',line=s)) + # + # pin 6 + # + self.shape = add(self.shape,translate(pad,-d,-1.5*p,0)) + self.pad.append(point(-d,-1.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'BOUT1',line=s)) + # + # pin 7 + # + self.shape = add(self.shape,translate(pad,-d,-2.5*p,0)) + self.pad.append(point(-d,-2.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND',line=s)) + # + # pin 8 + # + self.shape = add(self.shape,translate(pad,-d,-3.5*p,0)) + self.pad.append(point(-d,-3.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'DVDD',line=s)) + # + # pin 9 + # + self.shape = add(self.shape,translate(pad,d,-3.5*p,0)) + self.pad.append(point(d,-3.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VREF',line=s)) + # + # pin 10 + # + self.shape = add(self.shape,translate(pad,d,-2.5*p,0)) + self.pad.append(point(d,-2.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'M0',line=s)) + # + # pin 11 + # + self.shape = add(self.shape,translate(pad,d,-1.5*p,0)) + self.pad.append(point(d,-1.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'DECAY',line=s)) + # + # pin 12 + # + self.shape = add(self.shape,translate(pad,d,-.5*p,0)) + self.pad.append(point(d,-.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'M1',line=s)) + # + # pin 13 + # + self.shape = add(self.shape,translate(pad,d,.5*p,0)) + self.pad.append(point(d,.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'STEP',line=s)) + # + # pin 14 + # + self.shape = add(self.shape,translate(pad,d,1.5*p,0)) + self.pad.append(point(d,1.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'DIR',line=s)) + # + # pin 15 + # + self.shape = add(self.shape,translate(pad,d,2.5*p,0)) + self.pad.append(point(d,2.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'EN',line=s)) + # + # pin 16 + # + self.shape = add(self.shape,translate(pad,d,3.5*p,0)) + self.pad.append(point(d,3.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SLEEP',line=s)) + # + # pin 17 + # + self.shape = add(self.shape,translate(cube(-.06,.06,-.09,.09,0,0),0,0,0)) + self.pad.append(point(0,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND',line=s)) + +class LED_3014_1100(part): + # + # Luminus MP-3014-1100-50-80 + # + def __init__(self,value=''): + anode = cube(-.011,.011,-.027,.027,0,0) + cathode = cube(-.036,.036,-.027,.027,0,0) + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # anode + # + self.shape = translate(anode,-.047,0,0) + self.pad.append(point(-.047,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A')) + # + # cathode + # + self.shape = add(self.shape,translate(cathode,.022,0,0)) + self.pad.append(point(.022,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'C')) + +class CMM4030D261I2STR(part): + # + # CUI CMM-4030D-261-I2S-TR I2S microphone + # + def __init__(self,value=''): + pad = cube(-.018,.018,-.011,.011,0,0) + self.value = value + self.x = 0 + self.y = 0 + self.z = 0 + self.pad = [point(0,0,0)] + self.labels = [] + s = 0.004 + # + # pin 1 + # + self.shape = translate(pad,.037,-.059,0) + self.pad.append(point(.037,-.059,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND.',line=s)) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad,.037,-.019,0)) + self.pad.append(point(.037,-.019,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'N/C',line=s)) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad,.037,.019,0)) + self.pad.append(point(.037,.019,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'WS',line=s)) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad,.037,.059,0)) + self.pad.append(point(.037,.059,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'EN',line=s)) + # + # pin 5 + # + self.shape = add(self.shape,translate(pad,-.037,.059,0)) + self.pad.append(point(-.037,.059,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'L/R',line=s)) + # + # pin 6 + # + self.shape = add(self.shape,translate(pad,-.037,.019,0)) + self.pad.append(point(-.037,.019,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SCK',line=s)) + # + # pin 7 + # + self.shape = add(self.shape,translate(pad,-.037,-.019,0)) + self.pad.append(point(-.037,-.019,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SD',line=s)) + # + # pin 8 + # + self.shape = add(self.shape,translate(pad,-.037,-.059,0)) + self.pad.append(point(-.037,-.059,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VDD',line=s)) + +class SPG08P4HM4H(part): + # + # Knowles SPG08P4HM4H-1 PDM microphone + # + def __init__(self,value=''): + pad = cube(-.011,.011,-.011,.011,0,0) + self.value = value + self.x = 0 + self.y = 0 + self.z = 0 + self.pad = [point(0,0,0)] + self.labels = [] + s = 0.004 + # + # pin 1 + # + self.shape = translate(pad,.023,-.037,0) + self.pad.append(point(.023,-.037,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'V.',line=s)) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad,.023,0,0)) + self.pad.append(point(.023,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'G',line=s)) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad,.023,.037,0)) + self.pad.append(point(.023,.037,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'DAT',line=s)) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad,-.023,.037,0)) + self.pad.append(point(-.023,.037,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'CK',line=s)) + # + # pin 5 + # + self.shape = add(self.shape,translate(pad,-.023,0,0)) + self.pad.append(point(-.023,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'G',line=s)) + # + # pin 6 + # + self.shape = add(self.shape,translate(pad,-.023,-.037,0)) + self.pad.append(point(-.023,-.037,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SEL',line=s)) + +class VEML6040(part): + # + # Vishay VEML6040 color sensor + # + def __init__(self,value=''): + pad12 = cube(-.016,.019,-.006,.006,0,0) + pad3 = cube(-.023,.016,-.006,.006,0,0) + pad4 = cube(-.019,.016,-.006,.006,0,0) + self.value = value + self.x = 0 + self.y = 0 + self.z = 0 + self.pad = [point(0,0,0)] + self.labels = [] + s = 0.004 + # + # pin 1 + # + self.shape = translate(pad12,-.039,.014,0) + self.pad.append(point(-.039,.014,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1GND',line=s)) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad12,-.039,-.014,0)) + self.pad.append(point(-.039,-.014,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SDA',line=s)) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad3,.039,-.014,0)) + self.pad.append(point(.039,-.014,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SCL',line=s)) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad4,.039,.014,0)) + self.pad.append(point(.039,.014,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VDD',line=s)) + +class D_1206(part): + # + # 1206 diode + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # anode + # + self.shape = translate(pad_1206,-.06,0,0) + self.pad.append(point(-.055,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A')) + # + # cathode + # + self.shape = add(self.shape,translate(pad_1206,.06,0,0)) + self.pad.append(point(.055,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'C')) + +class LED_1206(part): + # + # 1206 LED + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # anode + # + self.shape = translate(pad_1206,-.06,0,0) + self.pad.append(point(-.055,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A')) + # + # cathode + # + self.shape = add(self.shape,translate(pad_1206,.06,0,0)) + self.pad.append(point(.055,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'C')) + +pad_RGB = cube(-.02,.02,-.029,.029,0,0) + +class LED_RGB(part): + # + # CREE CLV1A-FKB + # + def __init__(self,value=''): + self.value = value + self.x = 0 + self.y = 0 + self.z = 0 + self.pad = [point(0,0,0)] + self.labels = [] + dx = .029 + dy = .059 + # + # pin 1: red + # + self.shape = translate(pad_RGB,-dx,-dy,0) + self.shape = add(self.shape,cylinder(-dx,-dy-.029,0,0,.02)) + self.pad.append(point(-dx,-dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'R')) + # + # pin 2: anode + # + self.shape = add(self.shape,translate(pad_RGB,dx,-dy,0)) + self.pad.append(point(dx,-dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A')) + # + # pin 3: blue + # + self.shape = add(self.shape,translate(pad_RGB,dx,dy,0)) + self.pad.append(point(dx,dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'B')) + # + # pin 4: green + # + self.shape = add(self.shape,translate(pad_RGB,-dx,dy,0)) + self.pad.append(point(-dx,dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'G')) + +class phototransistor_1206(part): + # + # 1206 phototransistor + # OPTEK 520,521 + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # collector + # + self.shape = translate(pad_1206,-.06,0,0) + self.pad.append(point(-.055,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'C')) + # + # emitter + # + self.shape = add(self.shape,translate(pad_1206,.06,0,0)) + self.pad.append(point(.055,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'E')) + +pad_PLCC2 = cube(-.029,.029,-.059,.059,0,0) + +class phototransistor_PLCC2(part): + # + # PLCC2 phototransistor + # Optek OP580 + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # collector + # + self.shape = translate(pad_PLCC2,-.065,0,0) + self.pad.append(point(-.065,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'C')) + # + # emitter + # + self.shape = add(self.shape,translate(pad_PLCC2,.065,0,0)) + self.pad.append(point(.065,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'E')) + +pad_SOD_123 = cube(-.02,.02,-.024,.024,0,0) + +class D_SOD_123(part): + # + # SOD-123 diode + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # anode + # + self.shape = translate(pad_SOD_123,-.07,0,0) + self.pad.append(point(-.07,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A')) + # + # cathode + # + self.shape = add(self.shape,translate(pad_SOD_123,.07,0,0)) + self.pad.append(point(.07,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'C')) + +pad_SOT23 = cube(-.02,.02,-.012,.012,0,0) + +class NMOSFET_SOT23(part): + # + # Fairchild NDS355AN + # + def __init__(self,value=''): + self.value = value + self.x = 0 + self.y = 0 + self.z = 0 + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: gate + # + self.shape = translate(pad_SOT23,.045,-.0375,0) + self.pad.append(point(.045,-.0375,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'G')) + # + # pin 2: source + # + self.shape = add(self.shape,translate(pad_SOT23,.045,.0375,0)) + self.pad.append(point(.045,.0375,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'S')) + # + # pin 3: drain + # + self.shape = add(self.shape,translate(pad_SOT23,-.045,0,0)) + self.pad.append(point(-.045,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'D')) + +class PMOSFET_SOT23(part): + # + # Fairchild NDS356AP + # + def __init__(self,value=''): + self.value = value + self.x = 0 + self.y = 0 + self.z = 0 + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: gate + # + self.shape = translate(pad_SOT23,.045,-.0375,0) + self.pad.append(point(.045,-.0375,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'G')) + # + # pin 2: source + # + self.shape = add(self.shape,translate(pad_SOT23,.045,.0375,0)) + self.pad.append(point(.045,.0375,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'S')) + # + # pin 3: drain + # + self.shape = add(self.shape,translate(pad_SOT23,-.045,0,0)) + self.pad.append(point(-.045,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'D')) + +class NMOSFET_TO252AA(part): + # + # Fairchild RFD16N05LSM + # + def __init__(self,value=''): + self.value = value + self.x = 0 + self.y = 0 + self.z = 0 + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: gate + # + self.shape = translate(cube(-.031,.031,-.059,.059,0,0),-.090,0,0) + self.pad.append(point(-.090,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'G 1')) + # + # pin 2: source + # + self.shape = add(self.shape,translate(cube(-.031,.031,-.059,.059,0,0),.090,0,0)) + self.pad.append(point(.090,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'S')) + # + # pin 3: drain + # + self.shape = add(self.shape,translate(cube(-.132,.132,-.132,.132,0,0),0,.261,0)) + self.pad.append(point(0,.261,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'D')) + +class Hall_SOT23(part): + # + # Allegro A1324 + # + def __init__(self,value=''): + self.value = value + self.x = 0 + self.y = 0 + self.z = 0 + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: output + # + self.shape = translate(pad_SOT23,-.045,.0375,0) + self.pad.append(point(-.045,.0375,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'Vcc')) + # + # pin 2: input + # + self.shape = add(self.shape,translate(pad_SOT23,-.045,-.0375,0)) + self.pad.append(point(-.045,-.0375,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'out')) + # + # pin 3: ground + # + self.shape = add(self.shape,translate(pad_SOT23,.045,0,0)) + self.pad.append(point(.045,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'gnd')) + +class regulator_SOT23(part): + # + # TI LM3480IM3 + # + def __init__(self,value=''): + self.value = value + self.x = 0 + self.y = 0 + self.z = 0 + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: output + # + self.shape = translate(pad_SOT23,-.045,.0375,0) + self.pad.append(point(-.045,.0375,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'out')) + # + # pin 2: input + # + self.shape = add(self.shape,translate(pad_SOT23,-.045,-.0375,0)) + self.pad.append(point(-.045,-.0375,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'in')) + # + # pin 3: ground + # + self.shape = add(self.shape,translate(pad_SOT23,.045,0,0)) + self.pad.append(point(.045,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'gnd')) + +class regulator_SOT223(part): + # + # Zetex ZLDO1117 + # + def __init__(self,value=''): + self.value = value + self.x = 0 + self.y = 0 + self.z = 0 + self.pad = [point(0,0,0)] + self.labels = [] + pad_SOT223 = cube(-.02,.02,-.03,.03,0,0) + pad_SOT223_ground = cube(-.065,.065,-.03,.03,0,0) + # + # pin 1: GND + # + self.shape = translate(pad_SOT223,-.09,-.12,0) + self.pad.append(point(-.09,-.12,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1G')) + # + # pin 2: output + # + self.shape = add(self.shape,translate(pad_SOT223,0,-.12,0)) + self.pad.append(point(0,-.12,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'O')) + # + # pin 3: input + # + self.shape = add(self.shape,translate(pad_SOT223,.09,-.12,0)) + self.pad.append(point(.09,-.12,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'I')) + # + # pin 4: output + # + self.shape = add(self.shape,translate(pad_SOT223_ground,0,.12,0)) + self.pad.append(point(0,.12,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'out')) + +class A4953_SOICN(part): + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: GND + # + self.shape = translate(pad_SOIC,-.11,.075,0) + self.shape = add(self.shape,cylinder(-.153,.075,0,0,.015)) + self.pad.append(point(-.11,.075,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 2: IN2 + # + self.shape = add(self.shape,translate(pad_SOIC,-.11,.025,0)) + self.pad.append(point(-.11,.025,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IN2')) + # + # pin 3: IN1 + # + self.shape = add(self.shape,translate(pad_SOIC,-.11,-.025,0)) + self.pad.append(point(-.11,-.025,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IN1')) + # + # pin 4: VREF + # + self.shape = add(self.shape,translate(pad_SOIC,-.11,-.075,0)) + self.pad.append(point(-.11,-.075,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VREF')) + # + # pin 5: VBB + # + self.shape = add(self.shape,translate(pad_SOIC,.11,-.075,0)) + self.pad.append(point(.11,-.075,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VBB')) + # + # pin 6: OUT1 + # + self.shape = add(self.shape,translate(pad_SOIC,.11,-.025,0)) + self.pad.append(point(.11,-.025,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'OUT1')) + # + # pin 7: LSS + # + self.shape = add(self.shape,translate(pad_SOIC,.11,.025,0)) + self.pad.append(point(.11,.025,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'LSS')) + # + # pin 8: OUT2 + # + self.shape = add(self.shape,translate(pad_SOIC,.11,.075,0)) + self.pad.append(point(.11,.075,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'OUT2')) + # + # thermal pad + # + self.shape = add(self.shape,rectangle(-.04,.04,-.075,.075)) + +pad_SM8 = cube(-.035,.035,-.016,.016,0,0) + +class H_bridge_SM8(part): + # + # Zetex ZXMHC3A01T8 + # + def __init__(self,value=''): + self.value = value + self.x = 0 + self.y = 0 + self.z = 0 + self.pad = [point(0,0,0)] + self.labels = [] + d = .13 + # + # pin 1: G3 (right N gate) + # + self.shape = translate(pad_SM8,-d,.09,0) + self.shape = add(self.shape,cylinder(-d-.035,.09,0,0,.016)) + self.pad.append(point(-d,.09,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GRN')) + # + # pin 2: S2 S3 (N source) + # + self.shape = add(self.shape,translate(pad_SM8,-d,.03,0)) + self.pad.append(point(-d,.03,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SN')) + # + # pin 3: G2 (left N gate) + # + self.shape = add(self.shape,translate(pad_SM8,-d,-.03,0)) + self.pad.append(point(-d,-.03,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GLN')) + # + # pin 4: G1 (left P gate) + # + self.shape = add(self.shape,translate(pad_SM8,-d,-.09,0)) + self.pad.append(point(-d,-.09,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GLP')) + # + # pin 5: D1 D2 (left drain) + # + self.shape = add(self.shape,translate(pad_SM8,d,-.09,0)) + self.pad.append(point(d,-.09,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'DL')) + # + # pin 6: S1 S4 (P source) + # + self.shape = add(self.shape,translate(pad_SM8,d,-.03,0)) + self.pad.append(point(d,-.03,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SP')) + # + # pin 7: D3 D4 (right drain) + # + self.shape = add(self.shape,translate(pad_SM8,d,.03,0)) + self.pad.append(point(d,.03,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'DR')) + # + # pin 8: G4 (right N gate) + # + self.shape = add(self.shape,translate(pad_SM8,d,.09,0)) + self.pad.append(point(d,.09,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GRP')) + +pad_mic = cylinder(0,0,0,0,.02) + +class mic_SPU0414HR5H(part): + # + # Knowles SPU0414HR5H-SB + # + def __init__(self,value=''): + s = 0.004 + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: Vdd + # + self.shape = translate(pad_mic,.033,.048,0) + self.pad.append(point(.033,.048,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'V1',line=s)) + # + # pin 2: GND + # + self.shape = add(self.shape,translate(pad_mic,.033,-.048,0)) + self.pad.append(point(.033,-.048,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND',line=s)) + # + # pin 3: gain + # + self.shape = add(self.shape,translate(pad_mic,-.033,-.048,0)) + self.pad.append(point(-.033,-.048,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'gain',line=s)) + # + # pin 4: out + # + self.shape = add(self.shape,translate(pad_mic,-.033,.048,0)) + self.pad.append(point(-.033,.048,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'out',line=s)) + +class mic_SPM1437(part): + # + # Knowles SPM1437HM4H-B + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1 + # + self.shape = translate(pad_mic,-.046,.065,0) + #self.shape = add(self.shape,cylinder(-.183,.075,0,0,.015)) + self.pad.append(point(-.046,.065,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad_mic,-.046,0,0)) + self.pad.append(point(-.046,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SEL')) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad_mic,-.046,-.065,0)) + self.pad.append(point(-.046,-.065,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad_mic,.046,-.065,0)) + self.pad.append(point(.046,-.065,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'CLK')) + # + # pin 5 + # + self.shape = add(self.shape,translate(pad_mic,.046,0,0)) + self.pad.append(point(.046,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'DAT')) + # + # pin 6 + # + self.shape = add(self.shape,translate(pad_mic,.046,.065,0)) + self.shape = add(self.shape,translate(pad_mic,.038,.057,0)) + self.pad.append(point(.046,.065,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'V')) + +pad_accel = cube(-.03,.03,-.0125,.0125,0,0) +pad_accel90 = cube(-.0125,.0125,-.03,.03,0,0) + +class accel_MXD6235M(part): + # + # MEMSIC MXD6235M + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1 + # + self.shape = translate(pad_accel,-.1,.05,0) + self.shape = add(self.shape,cylinder(-.13,.05,0,0,.0125)) + self.pad.append(point(-.1,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad_accel,-.1,0,0)) + self.pad.append(point(-.1,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'TP')) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad_accel,-.1,-.05,0)) + self.pad.append(point(-.1,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'G')) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad_accel90,0,-.1,0)) + self.pad.append(point(0,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'NC')) + # + # pin 5 + # + self.shape = add(self.shape,translate(pad_accel,.1,-.05,0)) + self.pad.append(point(.1,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'NC')) + # + # pin 6 + # + self.shape = add(self.shape,translate(pad_accel,.1,0,0)) + self.pad.append(point(.1,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'Y')) + # + # pin 7 + # + self.shape = add(self.shape,translate(pad_accel,.1,.05,0)) + self.pad.append(point(.1,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'X')) + # + # pin 8 + # + self.shape = add(self.shape,translate(pad_accel90,0,.1,0)) + self.pad.append(point(0,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'V')) + # + # ground plane + # + self.shape = add(self.shape,cube(-.05,.05,-.05,.05,0,0)) + +pad_cc_14_1 = cube(-.014,.014,-.0075,.0075,0,0) +pad_cc_14_1_90 = cube(-.0075,.0075,-.014,.014,0,0) + +class ADXL343(part): + # + # ADI ADXL343 accelerometer + # + def __init__(self,value=''): + d = 0.8/25.4 + w = 1.01/25.4 + s = 0.004 + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1 + # + self.shape = translate(pad_cc_14_1,-w,2.5*d,0) + self.pad.append(point(-w,2.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,"VD1",line=s)) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad_cc_14_1,-w,1.5*d,0)) + self.pad.append(point(-w,1.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND',line=s)) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad_cc_14_1,-w,.5*d,0)) + self.pad.append(point(-w,.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RSV',line=s)) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad_cc_14_1,-w,-.5*d,0)) + self.pad.append(point(-w,-.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND',line=s)) + # + # pin 5 + # + self.shape = add(self.shape,translate(pad_cc_14_1,-w,-1.5*d,0)) + self.pad.append(point(-w,-1.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND',line=s)) + # + # pin 6 + # + self.shape = add(self.shape,translate(pad_cc_14_1,-w,-2.5*d,0)) + self.pad.append(point(-w,-2.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VS',line=s)) + # + # pin 7 + # + self.shape = add(self.shape,translate(pad_cc_14_1_90,0,-2.5*d,0)) + self.pad.append(point(0,-2.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'-CS',angle=90,line=s)) + # + # pin 8 + # + self.shape = add(self.shape,translate(pad_cc_14_1,w,-2.5*d,0)) + self.pad.append(point(w,-2.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'INT1',line=s)) + # + # pin 9 + # + self.shape = add(self.shape,translate(pad_cc_14_1,w,-1.5*d,0)) + self.pad.append(point(w,-1.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'INT2',line=s)) + # + # pin 10 + # + self.shape = add(self.shape,translate(pad_cc_14_1,w,-.5*d,0)) + self.pad.append(point(w,-.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'NC',line=s)) + # + # pin 11 + # + self.shape = add(self.shape,translate(pad_cc_14_1,w,.5*d,0)) + self.pad.append(point(w,.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RSV',line=s)) + # + # pin 12 + # + self.shape = add(self.shape,translate(pad_cc_14_1,w,1.5*d,0)) + self.pad.append(point(w,1.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'ALT',line=s)) + # + # pin 13 + # + self.shape = add(self.shape,translate(pad_cc_14_1,w,2.5*d,0)) + self.pad.append(point(w,2.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SDA',line=s)) + # + # pin 14 + # + self.shape = add(self.shape,translate(pad_cc_14_1_90,0,2.5*d,0)) + self.pad.append(point(0,2.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SCL',angle=90,line=s)) + +class VL53L1X(part): + # + # ST VL53L1X time of flight sensor + # + def __init__(self,value=''): + pad = cube(-.0075,.0075,-.0075,.0075,0,0) + d = 0.8/25.4 + w = 0.8/25.4 + s = 0.004 + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1 + # + self.shape = translate(pad,-w,-2*d,0) + self.pad.append(point(-w,-2*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,"1V",line=s)) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad,-w,-1*d,0)) + self.pad.append(point(-w,-1*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'G',line=s)) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad,-w,0*d,0)) + self.pad.append(point(-w,0*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'G',line=s)) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad,-w,1*d,0)) + self.pad.append(point(-w,1*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'G',line=s)) + # + # pin 5 + # + self.shape = add(self.shape,translate(pad,-w,2*d,0)) + self.pad.append(point(-w,2*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'XS',line=s)) + # + # pin 6 + # + self.shape = add(self.shape,translate(pad,0,2*d,0)) + self.pad.append(point(0,2*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'G',line=s)) + # + # pin 7 + # + self.shape = add(self.shape,translate(pad,w,2*d,0)) + self.pad.append(point(w,2*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO',line=s)) + # + # pin 8 + # + self.shape = add(self.shape,translate(pad,w,1*d,0)) + self.pad.append(point(w,1*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'NC',line=s)) + # + # pin 9 + # + self.shape = add(self.shape,translate(pad,w,0*d,0)) + self.pad.append(point(w,0*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SDA',line=s)) + # + # pin 10 + # + self.shape = add(self.shape,translate(pad,w,-1*d,0)) + self.pad.append(point(w,-1*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SCL',line=s)) + # + # pin 11 + # + self.shape = add(self.shape,translate(pad,w,-2*d,0)) + self.pad.append(point(w,-2*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'V',line=s)) + # + # pin 12 + # + self.shape = add(self.shape,translate(pad,0,-2*d,0)) + self.pad.append(point(0,-2*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'G',line=s)) + +############################################################ +# ICs +############################################################ + +class AVRDB28(part): + # + # AVR*DB28 + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + d = 9.01/2/25.4 # spacing + w = 0.4/2/25.4 # width + h = 1.4/2/25.4 # height + p = 0.8/25.4 # pitch + l = 0.004 # text + pad = cube(-h,h,-w,w,0,0) + padv = cube(-w,w,-h,h,0,0) + # + # pin 1 + # + self.shape = translate(pad,-d,3.5*p,0) + self.shape = add(self.shape,cylinder(-d-h,3.5*p,0,0,w)) + self.pad.append(point(-d,3.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'.PA3',line=l)) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad,-d,2.5*p,0)) + self.pad.append(point(-d,2.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA4',line=l)) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad,-d,1.5*p,0)) + self.pad.append(point(-d,1.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA5',line=l)) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad,-d,.5*p,0)) + self.pad.append(point(-d,.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA6',line=l)) + # + # pin 5 + # + self.shape = add(self.shape,translate(pad,-d,-.5*p,0)) + self.pad.append(point(-d,-.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA7',line=l)) + # + # pin 6 + # + self.shape = add(self.shape,translate(pad,-d,-1.5*p,0)) + self.pad.append(point(-d,-1.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC0',line=l)) + # + # pin 7 + # + self.shape = add(self.shape,translate(pad,-d,-2.5*p,0)) + self.pad.append(point(-d,-2.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC1',line=l)) + # + # pin 8 + # + self.shape = add(self.shape,translate(pad,-d,-3.5*p,0)) + self.pad.append(point(-d,-3.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC2',line=l)) + # + # pin 9 + # + self.shape = add(self.shape,translate(padv,-3.5*p,-d,0)) + self.pad.append(point(-3.5*p,-d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC3',line=l,angle=-90)) + # + # pin 10 + # + self.shape = add(self.shape,translate(padv,-2.5*p,-d,0)) + self.pad.append(point(-2.5*p,-d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VIO2',line=l,angle=-90)) + # + # pin 11 + # + self.shape = add(self.shape,translate(padv,-1.5*p,-d,0)) + self.pad.append(point(-1.5*p,-d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD1',line=l,angle=-90)) + # + # pin 12 + # + self.shape = add(self.shape,translate(padv,-.5*p,-d,0)) + self.pad.append(point(-.5*p,-d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD2',line=l,angle=-90)) + # + # pin 13 + # + self.shape = add(self.shape,translate(padv,.5*p,-d,0)) + self.pad.append(point(.5*p,-d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD3',line=l,angle=-90)) + # + # pin 14 + # + self.shape = add(self.shape,translate(padv,1.5*p,-d,0)) + self.pad.append(point(1.5*p,-d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD4',line=l,angle=-90)) + # + # pin 15 + # + self.shape = add(self.shape,translate(padv,2.5*p,-d,0)) + self.pad.append(point(2.5*p,-d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD5',line=l,angle=-90)) + # + # pin 16 + # + self.shape = add(self.shape,translate(padv,3.5*p,-d,0)) + self.pad.append(point(3.5*p,-d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD6',line=l,angle=-90)) + # + # pin 17 + # + self.shape = add(self.shape,translate(pad,d,-3.5*p,0)) + self.pad.append(point(d,-3.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD7',line=l)) + # + # pin 18 + # + self.shape = add(self.shape,translate(pad,d,-2.5*p,0)) + self.pad.append(point(d,-2.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'AVDD',line=l)) + # + # pin 19 + # + self.shape = add(self.shape,translate(pad,d,-1.5*p,0)) + self.pad.append(point(d,-1.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND',line=l)) + # + # pin 20 + # + self.shape = add(self.shape,translate(pad,d,-.5*p,0)) + self.pad.append(point(d,-.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PF0',line=l)) + # + # pin 21 + # + self.shape = add(self.shape,translate(pad,d,.5*p,0)) + self.pad.append(point(d,.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PF1',line=l)) + # + # pin 22 + # + self.shape = add(self.shape,translate(pad,d,1.5*p,0)) + self.pad.append(point(d,1.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PF2',line=l)) + # + # pin 23 + # + self.shape = add(self.shape,translate(pad,d,2.5*p,0)) + self.pad.append(point(d,2.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PF3',line=l)) + # + # pin 24 + # + self.shape = add(self.shape,translate(pad,d,3.5*p,0)) + self.pad.append(point(d,3.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PF4',line=l)) + # + # pin 25 + # + self.shape = add(self.shape,translate(padv,3.5*p,d,0)) + self.pad.append(point(3.5*p,d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PF5',line=l,angle=-90)) + # + # pin 26 + # + self.shape = add(self.shape,translate(padv,2.5*p,d,0)) + self.pad.append(point(2.5*p,d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PF6',line=l,angle=-90)) + # + # pin 27 + # + self.shape = add(self.shape,translate(padv,1.5*p,d,0)) + self.pad.append(point(1.5*p,d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'UPDI',line=l,angle=-90)) + # + # pin 28 + # + self.shape = add(self.shape,translate(padv,.5*p,d,0)) + self.pad.append(point(.5*p,d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VDD',line=l,angle=-90)) + # + # pin 29 + # + self.shape = add(self.shape,translate(padv,-.5*p,d,0)) + self.pad.append(point(-.5*p,d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND',line=l,angle=-90)) + # + # pin 30 + # + self.shape = add(self.shape,translate(padv,-1.5*p,d,0)) + self.pad.append(point(-1.5*p,d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA0',line=l,angle=-90)) + # + # pin 31 + # + self.shape = add(self.shape,translate(padv,-2.5*p,d,0)) + self.pad.append(point(-2.5*p,d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA1',line=l,angle=-90)) + # + # pin 32 + # + self.shape = add(self.shape,translate(padv,-3.5*p,d,0)) + self.pad.append(point(-3.5*p,d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA2',line=l,angle=-90)) + +class ATtiny3216(part): + # + # SOIC-20 + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + d = 9.82/2/25.4 + w = .63/2/25.4 + h = 1.9/2/25.4 + pad = cube(-h,h,-w,w,0,0) + # + # pin 1 + # + self.shape = translate(pad,-d,.225,0) + self.shape = add(self.shape,cylinder(-d-h,.225,0,0,w)) + self.pad.append(point(-d,.225,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1VCC')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad,-d,.175,0)) + self.pad.append(point(-d,.175,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA4')) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad,-d,.125,0)) + self.pad.append(point(-d,.125,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA5')) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad,-d,.075,0)) + self.pad.append(point(-d,.075,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA6')) + # + # pin 5 + # + self.shape = add(self.shape,translate(pad,-d,.025,0)) + self.pad.append(point(-d,.025,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA7')) + # + # pin 6 + # + self.shape = add(self.shape,translate(pad,-d,-.025,0)) + self.pad.append(point(-d,-.025,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PB5')) + # + # pin 7 + # + self.shape = add(self.shape,translate(pad,-d,-.075,0)) + self.pad.append(point(-d,-.075,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PB4')) + # + # pin 8 + # + self.shape = add(self.shape,translate(pad,-d,-.125,0)) + self.pad.append(point(-d,-.125,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RB3')) + # + # pin 9 + # + self.shape = add(self.shape,translate(pad,-d,-.175,0)) + self.pad.append(point(-d,-.175,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'TB2')) + # + # pin 10 + # + self.shape = add(self.shape,translate(pad,-d,-.225,0)) + self.pad.append(point(-d,-.225,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PB1')) + # + # pin 11 + # + self.shape = add(self.shape,translate(pad,d,-.225,0)) + self.pad.append(point(d,-.225,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PB0')) + # + # pin 12 + # + self.shape = add(self.shape,translate(pad,d,-.175,0)) + self.pad.append(point(d,-.175,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC0')) + # + # pin 13 + # + self.shape = add(self.shape,translate(pad,d,-.125,0)) + self.pad.append(point(d,-.125,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC1')) + # + # pin 14 + # + self.shape = add(self.shape,translate(pad,d,-.075,0)) + self.pad.append(point(d,-.075,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC2')) + # + # pin 15 + # + self.shape = add(self.shape,translate(pad,d,-.025,0)) + self.pad.append(point(d,-.025,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC3')) + # + # pin 16 + # + self.shape = add(self.shape,translate(pad,d,.025,0)) + self.pad.append(point(d,.025,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'UPDI')) + # + # pin 17 + # + self.shape = add(self.shape,translate(pad,d,.075,0)) + self.pad.append(point(d,.075,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA1')) + # + # pin 18 + # + self.shape = add(self.shape,translate(pad,d,.125,0)) + self.pad.append(point(d,.125,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA2')) + # + # pin 19 + # + self.shape = add(self.shape,translate(pad,d,.175,0)) + self.pad.append(point(d,.175,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA3')) + # + # pin 20 + # + self.shape = add(self.shape,translate(pad,d,.225,0)) + self.pad.append(point(d,.225,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + +class SAMD21E(part): + # + # TQFP + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + d = 9.01/2/25.4 # spacing + w = 0.4/2/25.4 # width + h = 1.4/2/25.4 # height + p = 0.8/25.4 # pitch + l = 0.004 # text + pad = cube(-h,h,-w,w,0,0) + padv = cube(-w,w,-h,h,0,0) + # + # pin 1 + # + self.shape = translate(pad,-d,3.5*p,0) + self.shape = add(self.shape,cylinder(-d-h,3.5*p,0,0,w)) + self.pad.append(point(-d,3.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1A0',line=l)) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad,-d,2.5*p,0)) + self.pad.append(point(-d,2.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A01',line=l)) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad,-d,1.5*p,0)) + self.pad.append(point(-d,1.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A02',line=l)) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad,-d,.5*p,0)) + self.pad.append(point(-d,.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A03',line=l)) + # + # pin 5 + # + self.shape = add(self.shape,translate(pad,-d,-.5*p,0)) + self.pad.append(point(-d,-.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A04',line=l)) + # + # pin 6 + # + self.shape = add(self.shape,translate(pad,-d,-1.5*p,0)) + self.pad.append(point(-d,-1.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A05',line=l)) + # + # pin 7 + # + self.shape = add(self.shape,translate(pad,-d,-2.5*p,0)) + self.pad.append(point(-d,-2.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A06',line=l)) + # + # pin 8 + # + self.shape = add(self.shape,translate(pad,-d,-3.5*p,0)) + self.pad.append(point(-d,-3.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A07',line=l)) + # + # pin 9 + # + self.shape = add(self.shape,translate(padv,-3.5*p,-d,0)) + self.pad.append(point(-3.5*p,-d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VAN',line=l,angle=-90)) + # + # pin 10 + # + self.shape = add(self.shape,translate(padv,-2.5*p,-d,0)) + self.pad.append(point(-2.5*p,-d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND',line=l,angle=-90)) + # + # pin 11 + # + self.shape = add(self.shape,translate(padv,-1.5*p,-d,0)) + self.pad.append(point(-1.5*p,-d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A08',line=l,angle=-90)) + # + # pin 12 + # + self.shape = add(self.shape,translate(padv,-.5*p,-d,0)) + self.pad.append(point(-.5*p,-d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A09',line=l,angle=-90)) + # + # pin 13 + # + self.shape = add(self.shape,translate(padv,.5*p,-d,0)) + self.pad.append(point(.5*p,-d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A10',line=l,angle=-90)) + # + # pin 14 + # + self.shape = add(self.shape,translate(padv,1.5*p,-d,0)) + self.pad.append(point(1.5*p,-d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A11',line=l,angle=-90)) + # + # pin 15 + # + self.shape = add(self.shape,translate(padv,2.5*p,-d,0)) + self.pad.append(point(2.5*p,-d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A14',line=l,angle=-90)) + # + # pin 16 + # + self.shape = add(self.shape,translate(padv,3.5*p,-d,0)) + self.pad.append(point(3.5*p,-d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A15',line=l,angle=-90)) + # + # pin 17 + # + self.shape = add(self.shape,translate(pad,d,-3.5*p,0)) + self.pad.append(point(d,-3.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A16',line=l)) + # + # pin 18 + # + self.shape = add(self.shape,translate(pad,d,-2.5*p,0)) + self.pad.append(point(d,-2.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A17',line=l)) + # + # pin 19 + # + self.shape = add(self.shape,translate(pad,d,-1.5*p,0)) + self.pad.append(point(d,-1.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A18',line=l)) + # + # pin 20 + # + self.shape = add(self.shape,translate(pad,d,-.5*p,0)) + self.pad.append(point(d,-.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A19',line=l)) + # + # pin 21 + # + self.shape = add(self.shape,translate(pad,d,.5*p,0)) + self.pad.append(point(d,.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A22',line=l)) + # + # pin 22 + # + self.shape = add(self.shape,translate(pad,d,1.5*p,0)) + self.pad.append(point(d,1.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A23',line=l)) + # + # pin 23 + # + self.shape = add(self.shape,translate(pad,d,2.5*p,0)) + self.pad.append(point(d,2.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'24-',line=l)) + # + # pin 24 + # + self.shape = add(self.shape,translate(pad,d,3.5*p,0)) + self.pad.append(point(d,3.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'25+',line=l)) + # + # pin 25 + # + self.shape = add(self.shape,translate(padv,3.5*p,d,0)) + self.pad.append(point(3.5*p,d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A27',line=l,angle=-90)) + # + # pin 26 + # + self.shape = add(self.shape,translate(padv,2.5*p,d,0)) + self.pad.append(point(2.5*p,d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RST',line=l,angle=-90)) + # + # pin 27 + # + self.shape = add(self.shape,translate(padv,1.5*p,d,0)) + self.pad.append(point(1.5*p,d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A28',line=l,angle=-90)) + # + # pin 28 + # + self.shape = add(self.shape,translate(padv,.5*p,d,0)) + self.pad.append(point(.5*p,d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND',line=l,angle=-90)) + # + # pin 29 + # + self.shape = add(self.shape,translate(padv,-.5*p,d,0)) + self.pad.append(point(-.5*p,d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VCR',line=l,angle=-90)) + # + # pin 30 + # + self.shape = add(self.shape,translate(padv,-1.5*p,d,0)) + self.pad.append(point(-1.5*p,d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VIN',line=l,angle=-90)) + # + # pin 31 + # + self.shape = add(self.shape,translate(padv,-2.5*p,d,0)) + self.pad.append(point(-2.5*p,d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'CLK',line=l,angle=-90)) + # + # pin 32 + # + self.shape = add(self.shape,translate(padv,-3.5*p,d,0)) + self.pad.append(point(-3.5*p,d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'DIO',line=l,angle=-90)) + +class SAMD11D(part): + # + # SOIC-20 + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + d = 9.82/2/25.4 + w = .63/2/25.4 + h = 1.9/2/25.4 + pad = cube(-h,h,-w,w,0,0) + # + # pin 1 + # + self.shape = translate(pad,-d,.225,0) + self.shape = add(self.shape,cylinder(-d-h,.225,0,0,w)) + self.pad.append(point(-d,.225,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1A05')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad,-d,.175,0)) + self.pad.append(point(-d,.175,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A06')) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad,-d,.125,0)) + self.pad.append(point(-d,.125,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A07')) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad,-d,.075,0)) + self.pad.append(point(-d,.075,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A08')) + # + # pin 5 + # + self.shape = add(self.shape,translate(pad,-d,.025,0)) + self.pad.append(point(-d,.025,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A09')) + # + # pin 6 + # + self.shape = add(self.shape,translate(pad,-d,-.025,0)) + self.pad.append(point(-d,-.025,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A14')) + # + # pin 7 + # + self.shape = add(self.shape,translate(pad,-d,-.075,0)) + self.pad.append(point(-d,-.075,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A15')) + # + # pin 8 + # + self.shape = add(self.shape,translate(pad,-d,-.125,0)) + self.pad.append(point(-d,-.125,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A16')) + # + # pin 9 + # + self.shape = add(self.shape,translate(pad,-d,-.175,0)) + self.pad.append(point(-d,-.175,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A22')) + # + # pin 10 + # + self.shape = add(self.shape,translate(pad,-d,-.225,0)) + self.pad.append(point(-d,-.225,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A23')) + # + # pin 11 + # + self.shape = add(self.shape,translate(pad,d,-.225,0)) + self.pad.append(point(d,-.225,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RST')) + # + # pin 12 + # + self.shape = add(self.shape,translate(pad,d,-.175,0)) + self.pad.append(point(d,-.175,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'CLK')) + # + # pin 13 + # + self.shape = add(self.shape,translate(pad,d,-.125,0)) + self.pad.append(point(d,-.125,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'DIO')) + # + # pin 14 + # + self.shape = add(self.shape,translate(pad,d,-.075,0)) + self.pad.append(point(d,-.075,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'24-')) + # + # pin 15 + # + self.shape = add(self.shape,translate(pad,d,-.025,0)) + self.pad.append(point(d,-.025,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'25+')) + # + # pin 16 + # + self.shape = add(self.shape,translate(pad,d,.025,0)) + self.pad.append(point(d,.025,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 17 + # + self.shape = add(self.shape,translate(pad,d,.075,0)) + self.pad.append(point(d,.075,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VCC')) + # + # pin 18 + # + self.shape = add(self.shape,translate(pad,d,.125,0)) + self.pad.append(point(d,.125,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A02')) + # + # pin 19 + # + self.shape = add(self.shape,translate(pad,d,.175,0)) + self.pad.append(point(d,.175,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A03')) + # + # pin 20 + # + self.shape = add(self.shape,translate(pad,d,.225,0)) + self.pad.append(point(d,.225,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A04')) + +class ATtiny1614(part): + # + # SOIC + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + d = 0.11 + w = 0.015 + h = .03 + pad = cube(-h,h,-w,w,0,0) + # + # pin 1 + # + self.shape = translate(pad,-d,.15,0) + self.shape = add(self.shape,cylinder(-d-h,.15,0,0,w)) + self.pad.append(point(-d,.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'.VCC')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad,-d,.1,0)) + self.pad.append(point(-d,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA4')) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad,-d,.050,0)) + self.pad.append(point(-d,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA5')) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad,-d,0,0)) + self.pad.append(point(-d,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA6')) + # + # pin 5 + # + self.shape = add(self.shape,translate(pad,-d,-.05,0)) + self.pad.append(point(-d,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA7')) + # + # pin 6 + # + self.shape = add(self.shape,translate(pad,-d,-.1,0)) + self.pad.append(point(-d,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RB3')) + # + # pin 7 + # + self.shape = add(self.shape,translate(pad,-d,-.15,0)) + self.pad.append(point(-d,-.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'TB2')) + # + # pin 8 + # + self.shape = add(self.shape,translate(pad,d,-.15,0)) + self.pad.append(point(d,-.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PB1')) + # + # pin 9 + # + self.shape = add(self.shape,translate(pad,d,-.1,0)) + self.pad.append(point(d,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PB0')) + # + # pin 10 + # + self.shape = add(self.shape,translate(pad,d,-.05,0)) + self.pad.append(point(d,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'UPDI')) + # + # pin 11 + # + self.shape = add(self.shape,translate(pad,d,0,0)) + self.pad.append(point(d,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA1')) + # + # pin 12 + # + self.shape = add(self.shape,translate(pad,d,.050,0)) + self.pad.append(point(d,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA2')) + # + # pin 13 + # + self.shape = add(self.shape,translate(pad,d,.1,0)) + self.pad.append(point(d,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA3')) + # + # pin 14 + self.shape = add(self.shape,translate(pad,d,.15,0)) + self.pad.append(point(d,.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + +class FT230XS(part): + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + d = 0.11 + w = 0.0053 + h = .03 + p = .65/25.4 + l = 0.004 + pad = cube(-h,h,-w,w,0,0) + # + # pin 1 + # + self.shape = translate(pad,-d,3.5*p,0) + self.shape = add(self.shape,cylinder(-d-h,3.5*p,0,0,w)) + self.pad.append(point(-d,3.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1TXD',line=l)) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad,-d,2.5*p,0)) + self.pad.append(point(-d,2.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RTS',line=l)) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad,-d,1.5*p,0)) + self.pad.append(point(-d,1.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VIO',line=l)) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad,-d,.5*p,0)) + self.pad.append(point(-d,.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RXD',line=l)) + # + # pin 5 + # + self.shape = add(self.shape,translate(pad,-d,-.5*p,0)) + self.pad.append(point(-d,-.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND',line=l)) + # + # pin 6 + # + self.shape = add(self.shape,translate(pad,-d,-1.5*p,0)) + self.pad.append(point(-d,-1.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'CTS',line=l)) + # + # pin 7 + # + self.shape = add(self.shape,translate(pad,-d,-2.5*p,0)) + self.pad.append(point(-d,-2.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'CB2',line=l)) + # + # pin 8 + # + self.shape = add(self.shape,translate(pad,-d,-3.5*p,0)) + self.pad.append(point(-d,-3.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'USP',line=l)) + # + # pin 9 + # + self.shape = add(self.shape,translate(pad,d,-3.5*p,0)) + self.pad.append(point(d,-3.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'USM',line=l)) + # + # pin 10 + # + self.shape = add(self.shape,translate(pad,d,-2.5*p,0)) + self.pad.append(point(d,-2.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'3V3',line=l)) + # + # pin 11 + # + self.shape = add(self.shape,translate(pad,d,-1.5*p,0)) + self.pad.append(point(d,-1.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RST',line=l)) + # + # pin 12 + # + self.shape = add(self.shape,translate(pad,d,-.5*p,0)) + self.pad.append(point(d,-.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VCC',line=l)) + # + # pin 13 + # + self.shape = add(self.shape,translate(pad,d,.5*p,0)) + self.pad.append(point(d,.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND',line=l)) + # + # pin 14 + self.shape = add(self.shape,translate(pad,d,1.5*p,0)) + self.pad.append(point(d,1.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'CB1',line=l)) + # + # pin 15 + # + self.shape = add(self.shape,translate(pad,d,2.5*p,0)) + self.pad.append(point(d,2.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'CB0',line=l)) + # + # pin 16 + self.shape = add(self.shape,translate(pad,d,3.5*p,0)) + self.pad.append(point(d,3.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'CB3',line=l)) + + +class ATtiny412(part): + # + # SOIC150 + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + d = 0.11 + w = 0.015 + h = .03 + pad = cube(-h,h,-w,w,0,0) + # + # pin 1: VCC + # + self.shape = translate(pad,-d,.075,0) + self.shape = add(self.shape,cylinder(-d-h,.075,0,0,w)) + self.pad.append(point(-d,.075,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VCC')) + # + # pin 2: PA6 + # + self.shape = add(self.shape,translate(pad,-d,.025,0)) + self.pad.append(point(-d,.025,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA6')) + # + # pin 3: PA7 + # + self.shape = add(self.shape,translate(pad,-d,-.025,0)) + self.pad.append(point(-d,-.025,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA7')) + # + # pin 4: PA1 + # + self.shape = add(self.shape,translate(pad,-d,-.075,0)) + self.pad.append(point(-d,-.075,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA1')) + # + # pin 5: PA2 + # + self.shape = add(self.shape,translate(pad,d,-.075,0)) + self.pad.append(point(d,-.075,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA2')) + # + # pin 6: UPDI + # + self.shape = add(self.shape,translate(pad,d,-.025,0)) + self.pad.append(point(d,-.025,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'UPDI')) + # + # pin 7: PA3 + # + self.shape = add(self.shape,translate(pad,d,.025,0)) + self.pad.append(point(d,.025,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA3')) + # + # pin 8: GND + # + self.shape = add(self.shape,translate(pad,d,.075,0)) + self.pad.append(point(d,.075,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + +class SAMD11C(part): + # + # SOIC + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + d = 0.11 + w = 0.015 + h = .03 + pad = cube(-h,h,-w,w,0,0) + # + # pin 1: PA05 + # + self.shape = translate(pad,-d,.15,0) + self.shape = add(self.shape,cylinder(-d-h,.15,0,0,w)) + self.pad.append(point(-d,.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1A05')) + # + # pin 2: PA08 + # + self.shape = add(self.shape,translate(pad,-d,.1,0)) + self.pad.append(point(-d,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A08')) + # + # pin 3: PA09 + # + self.shape = add(self.shape,translate(pad,-d,.050,0)) + self.pad.append(point(-d,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A09')) + # + # pin 4: PA14 + # + self.shape = add(self.shape,translate(pad,-d,0,0)) + self.pad.append(point(-d,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A14')) + # + # pin 5: PA15 + # + self.shape = add(self.shape,translate(pad,-d,-.05,0)) + self.pad.append(point(-d,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A15')) + # + # pin 6: nRESET + # + self.shape = add(self.shape,translate(pad,-d,-.1,0)) + self.pad.append(point(-d,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RST')) + # + # pin 7: CLK + # + self.shape = add(self.shape,translate(pad,-d,-.15,0)) + self.pad.append(point(-d,-.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'CLK')) + # + # pin 8: DIO + # + self.shape = add(self.shape,translate(pad,d,-.15,0)) + self.pad.append(point(d,-.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'DIO')) + # + # pin 9: PA24/D- + # + self.shape = add(self.shape,translate(pad,d,-.1,0)) + self.pad.append(point(d,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'24-')) + # + # pin 10: PA25/D+ + # + self.shape = add(self.shape,translate(pad,d,-.05,0)) + self.pad.append(point(d,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'25+')) + # + # pin 11: GND + # + self.shape = add(self.shape,translate(pad,d,0,0)) + self.pad.append(point(d,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 12: VDD + # + self.shape = add(self.shape,translate(pad,d,.050,0)) + self.pad.append(point(d,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VDD')) + # + # pin 13: PA02 + # + self.shape = add(self.shape,translate(pad,d,.1,0)) + self.pad.append(point(d,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A02')) + # + # pin 14: PA04 + # + self.shape = add(self.shape,translate(pad,d,.15,0)) + self.pad.append(point(d,.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A04')) + +pad_SOT23_5 = cube(-.01,.01,-.02,.02,0,0) + +class op_amp_SOT23_5(part): + def __init__(self,value=''): + self.value = value + self.x = 0 + self.y = 0 + self.z = 0 + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: output + # + self.shape = translate(pad_SOT23_5,-.0375,-.045,0) + self.pad.append(point(-.0375,-.045,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'O')) + # + # pin 2: V- + # + self.shape = add(self.shape,translate(pad_SOT23_5,0,-.045,0)) + self.pad.append(point(0,-.045,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'V-')) + # + # pin 3: I+ + # + self.shape = add(self.shape,translate(pad_SOT23_5,.0375,-.045,0)) + self.pad.append(point(.0375,-.045,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'I+')) + # + # pin 4: I- + # + self.shape = add(self.shape,translate(pad_SOT23_5,.0375,.045,0)) + self.pad.append(point(.0375,.045,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'I-')) + # + # pin 5: V+ + # + self.shape = add(self.shape,translate(pad_SOT23_5,-.0375,.045,0)) + self.pad.append(point(-.0375,.045,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'V+')) + +pad_SOICN = cube(-.035,.035,-.015,.015,0,0) + +class op_amp_SOICN(part): + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: A out + # + self.shape = translate(pad_SOICN,-.12,.075,0) + self.pad.append(point(-.12,.075,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1 Ao')) + # + # pin 2: A- + # + self.shape = add(self.shape,translate(pad_SOICN,-.12,.025,0)) + self.pad.append(point(-.12,.025,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A-')) + # + # pin 3: A+ + # + self.shape = add(self.shape,translate(pad_SOICN,-.12,-.025,0)) + self.pad.append(point(-.12,-.025,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A+')) + # + # pin 4: V- + # + self.shape = add(self.shape,translate(pad_SOICN,-.12,-.075,0)) + self.pad.append(point(-.12,-.075,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'V-')) + # + # pin 5: B+ + # + self.shape = add(self.shape,translate(pad_SOICN,.12,-.075,0)) + self.pad.append(point(.12,-.075,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'B+')) + # + # pin 6: B- + # + self.shape = add(self.shape,translate(pad_SOICN,.12,-.025,0)) + self.pad.append(point(.12,-.025,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'B-')) + # + # pin 7: B out + # + self.shape = add(self.shape,translate(pad_SOICN,.12,.025,0)) + self.pad.append(point(.12,.025,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'Bo')) + # + # pin 8: V+ + # + self.shape = add(self.shape,translate(pad_SOICN,.12,.075,0)) + self.pad.append(point(.12,.075,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'V+')) + +TSSOP_pad_width = 0.040 +TSSOP_pad_height = 0.011 +TSSOP_pad_dy = 0.026 +TSSOP_pad_dx = 0.120 +pad_TSSOP = cube(-TSSOP_pad_width/2.0,TSSOP_pad_width/2.0,-TSSOP_pad_height/2.0,TSSOP_pad_height/2.0,0,0) + +class TRC102(part): + # + # RFM TRC102 ISM transceiver + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: SDI + # + self.shape = translate(pad_TSSOP,-TSSOP_pad_dx,3.5*TSSOP_pad_dy,0) + self.pad.append(point(-TSSOP_pad_dx,3.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1 SDI')) + # + # pin 2: SCK + # + self.shape = add(self.shape,translate(pad_TSSOP,-TSSOP_pad_dx,2.5*TSSOP_pad_dy,0)) + self.pad.append(point(-TSSOP_pad_dx,2.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SCK')) + # + # pin 3: nCS + # + self.shape = add(self.shape,translate(pad_TSSOP,-TSSOP_pad_dx,1.5*TSSOP_pad_dy,0)) + self.pad.append(point(-TSSOP_pad_dx,1.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'nCS')) + # + # pin 4: SDO + # + self.shape = add(self.shape,translate(pad_TSSOP,-TSSOP_pad_dx,0.5*TSSOP_pad_dy,0)) + self.pad.append(point(-TSSOP_pad_dx,0.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SDO')) + # + # pin 5: IRQ + # + self.shape = add(self.shape,translate(pad_TSSOP,-TSSOP_pad_dx,-0.5*TSSOP_pad_dy,0)) + self.pad.append(point(-TSSOP_pad_dx,-0.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IRQ')) + # + # pin 6: DATA/nFSEL + # + self.shape = add(self.shape,translate(pad_TSSOP,-TSSOP_pad_dx,-1.5*TSSOP_pad_dy,0)) + self.pad.append(point(-TSSOP_pad_dx,-1.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'DATA')) + # + # pin 7: CR + # + self.shape = add(self.shape,translate(pad_TSSOP,-TSSOP_pad_dx,-2.5*TSSOP_pad_dy,0)) + self.pad.append(point(-TSSOP_pad_dx,-2.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'CR')) + # + # pin 8: CLKOUT + # + self.shape = add(self.shape,translate(pad_TSSOP,-TSSOP_pad_dx,-3.5*TSSOP_pad_dy,0)) + self.pad.append(point(-TSSOP_pad_dx,-3.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'CLKOUT')) + # + # pin 9: Xtal/Ref + # + self.shape = add(self.shape,translate(pad_TSSOP,TSSOP_pad_dx,-3.5*TSSOP_pad_dy,0)) + self.pad.append(point(TSSOP_pad_dx,-3.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'Xtal')) + # + # pin 10: RESET + # + self.shape = add(self.shape,translate(pad_TSSOP,TSSOP_pad_dx,-2.5*TSSOP_pad_dy,0)) + self.pad.append(point(TSSOP_pad_dx,-2.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RESET')) + # + # pin 11: GND + # + self.shape = add(self.shape,translate(pad_TSSOP,TSSOP_pad_dx,-1.5*TSSOP_pad_dy,0)) + self.pad.append(point(TSSOP_pad_dx,-1.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 12: RF_P + # + self.shape = add(self.shape,translate(pad_TSSOP,TSSOP_pad_dx,-0.5*TSSOP_pad_dy,0)) + self.pad.append(point(TSSOP_pad_dx,-0.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RF_P')) + # + # pin 13: RF_N + # + self.shape = add(self.shape,translate(pad_TSSOP,TSSOP_pad_dx,0.5*TSSOP_pad_dy,0)) + self.pad.append(point(TSSOP_pad_dx,0.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RF_N')) + # + # pin 14: VDD + # + self.shape = add(self.shape,translate(pad_TSSOP,TSSOP_pad_dx,1.5*TSSOP_pad_dy,0)) + self.pad.append(point(TSSOP_pad_dx,1.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VDD')) + # + # pin 15: RSSIA + # + self.shape = add(self.shape,translate(pad_TSSOP,TSSOP_pad_dx,2.5*TSSOP_pad_dy,0)) + self.pad.append(point(TSSOP_pad_dx,2.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RSSIA')) + # + # pin 16: nINT/DDET + # + self.shape = add(self.shape,translate(pad_TSSOP,TSSOP_pad_dx,3.5*TSSOP_pad_dy,0)) + self.pad.append(point(TSSOP_pad_dx,3.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'nINT')) + +pad_SOIC = cube(-.041,.041,-.015,.015,0,0) + +class ATtiny45_SOIC(part): + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: PB5/dW/ADC0/-RESET/PCINT5 + # + self.shape = translate(pad_SOIC,-.14,.075,0) + self.shape = add(self.shape,cylinder(-.183,.075,0,0,.015)) + self.pad.append(point(-.14,.075,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RST')) + # + # pin 2: PB3/ADC3/-OC1B/CLKI/XTAL1/PCINT3 + # + self.shape = add(self.shape,translate(pad_SOIC,-.14,.025,0)) + self.pad.append(point(-.14,.025,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PB3')) + # + # pin 3: PB4/ADC2/OC1B/CLKO/XTAL2/PCINT4 + # + self.shape = add(self.shape,translate(pad_SOIC,-.14,-.025,0)) + self.pad.append(point(-.14,-.025,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PB4')) + # + # pin 4: GND + # + self.shape = add(self.shape,translate(pad_SOIC,-.14,-.075,0)) + self.pad.append(point(-.14,-.075,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 5: PB0/MOSI/DI/SDA/AIN0/OC0A/-OC1A/AREF/PCINT0 + # + self.shape = add(self.shape,translate(pad_SOIC,.14,-.075,0)) + self.pad.append(point(.14,-.075,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PB0')) + # + # pin 6: PB1/MISO/DO/AIN1/OC0B/OC1A/PCINT1 + # + self.shape = add(self.shape,translate(pad_SOIC,.14,-.025,0)) + self.pad.append(point(.14,-.025,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PB1')) + # + # pin 7: PB2/SCK/USCK/SCL/ADC1/T0/INT0/PCINT2 + # + self.shape = add(self.shape,translate(pad_SOIC,.14,.025,0)) + self.pad.append(point(.14,.025,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PB2')) + # + # pin 8: VCC + # + self.shape = add(self.shape,translate(pad_SOIC,.14,.075,0)) + self.pad.append(point(.14,.075,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VCC')) + +class ATtiny44_SOICN(part): + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: VCC + # + self.shape = translate(pad_SOICN,-.12,.15,0) + self.shape = add(self.shape,cylinder(-.155,.15,0,0,.015)) + self.pad.append(point(-.12,.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VCC')) + # + # pin 2: PB0/XTAL1/PCINT8 + # + self.shape = add(self.shape,translate(pad_SOICN,-.12,.1,0)) + self.pad.append(point(-.12,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PB0')) + # + # pin 3: PB1/XTAL2/PCINT9 + # + self.shape = add(self.shape,translate(pad_SOICN,-.12,.050,0)) + self.pad.append(point(-.12,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PB1')) + # + # pin 4: PB3/dW/-RESET/PCINT11 + # + self.shape = add(self.shape,translate(pad_SOICN,-.12,0,0)) + self.pad.append(point(-.12,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PB3')) + # + # pin 5: PB2/CKOUT/OC0A/INT0/PCINT10 + # + self.shape = add(self.shape,translate(pad_SOICN,-.12,-.05,0)) + self.pad.append(point(-.12,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PB2')) + # + # pin 6: PA7/ADC7/OC0B/ICP/PCINT7 + # + self.shape = add(self.shape,translate(pad_SOICN,-.12,-.1,0)) + self.pad.append(point(-.12,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA7')) + # + # pin 7: PA6/ADC6/MOSI/SDA/OC1A/PCINT6 + # + self.shape = add(self.shape,translate(pad_SOICN,-.12,-.15,0)) + self.pad.append(point(-.12,-.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA6')) + # + # pin 8: PA5/ADC5/DO/MISO/OC1B/PCINT5 + # + self.shape = add(self.shape,translate(pad_SOICN,.12,-.15,0)) + self.pad.append(point(.12,-.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA5')) + # + # pin 9: PA4/ADC4/USCK/SCL/T1/PCINT4 + # + self.shape = add(self.shape,translate(pad_SOICN,.12,-.1,0)) + self.pad.append(point(.12,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA4')) + # + # pin 10: PA3/ADC3/T0/PCINT3 + # + self.shape = add(self.shape,translate(pad_SOICN,.12,-.05,0)) + self.pad.append(point(.12,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA3')) + # + # pin 11: PA2/ADC2/AIN1/PCINT2 + # + self.shape = add(self.shape,translate(pad_SOICN,.12,0,0)) + self.pad.append(point(.12,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA2')) + # + # pin 12: PA1/ADC1/AIN0/PCINT1 + # + self.shape = add(self.shape,translate(pad_SOICN,.12,.050,0)) + self.pad.append(point(.12,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA1')) + # + # pin 13: PA0/ADC0/AREF/PCINT0 + # + self.shape = add(self.shape,translate(pad_SOICN,.12,.1,0)) + self.pad.append(point(.12,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA0')) + # + # pin 14: GND + # + self.shape = add(self.shape,translate(pad_SOICN,.12,.15,0)) + self.pad.append(point(.12,.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + +pad_TQFP_h = cube(-.025,.025,-.007,.007,0,0) +pad_TQFP_v = cube(-.007,.007,-.025,.025,0,0) + +class ATxmegaE5_TQFP(part): + def __init__(self,value=''): + c = .18 + d = 0.8/25.4 + s = 0.004 + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: GND + # + self.shape = translate(pad_TQFP_h,-c,3.5*d,0) + self.pad.append(point(-c,3.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1 GND',line=s)) + # + # pin 2: PA4 + # + self.shape = add(self.shape,translate(pad_TQFP_h,-c,2.5*d,0)) + self.pad.append(point(-c,2.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA4',line=s)) + # + # pin 3: PA3 + # + self.shape = add(self.shape,translate(pad_TQFP_h,-c,1.5*d,0)) + self.pad.append(point(-c,1.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA3',line=s)) + # + # pin 4: PA2 + # + self.shape = add(self.shape,translate(pad_TQFP_h,-c,.5*d,0)) + self.pad.append(point(-c,.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA2',line=s)) + # + # pin 5: PA1 + # + self.shape = add(self.shape,translate(pad_TQFP_h,-c,-.5*d,0)) + self.pad.append(point(-c,-.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA1',line=s)) + # + # pin 6: PA0 + # + self.shape = add(self.shape,translate(pad_TQFP_h,-c,-1.5*d,0)) + self.pad.append(point(-c,-1.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA0',line=s)) + # + # pin 7: PDI/DATA + # + self.shape = add(self.shape,translate(pad_TQFP_h,-c,-2.5*d,0)) + self.pad.append(point(-c,-2.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PDI/DATA',line=s)) + # + # pin 8: RST/CLOCK + # + self.shape = add(self.shape,translate(pad_TQFP_h,-c,-3.5*d,0)) + self.pad.append(point(-c,-3.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RST/CLOCK',line=s)) + # + # pin 9: PC7 + # + self.shape = add(self.shape,translate(pad_TQFP_v,-3.5*d,-c,0)) + self.pad.append(point(-3.5*d,-c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC7',angle=90,line=s)) + # + # pin 10: PC6 + # + self.shape = add(self.shape,translate(pad_TQFP_v,-2.5*d,-c,0)) + self.pad.append(point(-2.5*d,-c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC6',angle=90,line=s)) + # + # pin 11: PC5 + # + self.shape = add(self.shape,translate(pad_TQFP_v,-1.5*d,-c,0)) + self.pad.append(point(-1.5*d,-c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC5',angle=90,line=s)) + # + # pin 12: PC4 + # + self.shape = add(self.shape,translate(pad_TQFP_v,-.5*d,-c,0)) + self.pad.append(point(-.5*d,-c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC4',angle=90,line=s)) + # + # pin 13: PC3 + # + self.shape = add(self.shape,translate(pad_TQFP_v,.5*d,-c,0)) + self.pad.append(point(.5*d,-c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC3',angle=90,line=s)) + # + # pin 14: PC2 + # + self.shape = add(self.shape,translate(pad_TQFP_v,1.5*d,-c,0)) + self.pad.append(point(1.5*d,-c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC2',angle=90,line=s)) + # + # pin 15: PC1 + # + self.shape = add(self.shape,translate(pad_TQFP_v,2.5*d,-c,0)) + self.pad.append(point(2.5*d,-c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC1',angle=90,line=s)) + # + # pin 16: PC0 + # + self.shape = add(self.shape,translate(pad_TQFP_v,3.5*d,-c,0)) + self.pad.append(point(3.5*d,-c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC0',angle=90,line=s)) + # + # pin 17: VCC + # + self.shape = add(self.shape,translate(pad_TQFP_h,c,-3.5*d,0)) + self.pad.append(point(c,-3.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VCC',line=s)) + # + # pin 18: GND + # + self.shape = add(self.shape,translate(pad_TQFP_h,c,-2.5*d,0)) + self.pad.append(point(c,-2.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND',line=s)) + # + # pin 19: PR1 + # + self.shape = add(self.shape,translate(pad_TQFP_h,c,-1.5*d,0)) + self.pad.append(point(c,-1.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PR1',line=s)) + # + # pin 20: PR0 + # + self.shape = add(self.shape,translate(pad_TQFP_h,c,-.5*d,0)) + self.pad.append(point(c,-.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PR0',line=s)) + # + # pin 21: PD7 + # + self.shape = add(self.shape,translate(pad_TQFP_h,c,.5*d,0)) + self.pad.append(point(c,.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD7',line=s)) + # + # pin 22: PD6 + # + self.shape = add(self.shape,translate(pad_TQFP_h,c,1.5*d,0)) + self.pad.append(point(c,1.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD6',line=s)) + # + # pin 23: PD5 + # + self.shape = add(self.shape,translate(pad_TQFP_h,c,2.5*d,0)) + self.pad.append(point(c,2.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD5',line=s)) + # + # pin 24: PD4 + # + self.shape = add(self.shape,translate(pad_TQFP_h,c,3.5*d,0)) + self.pad.append(point(c,3.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD4',line=s)) + # + # pin 25: PD3 + # + self.shape = add(self.shape,translate(pad_TQFP_v,3.5*d,c,0)) + self.pad.append(point(3.5*d,c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD3',angle=90,line=s)) + # + # pin 26: PD2 + # + self.shape = add(self.shape,translate(pad_TQFP_v,2.5*d,c,0)) + self.pad.append(point(2.5*d,c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD2',angle=90,line=s)) + # + # pin 27: PD1 + # + self.shape = add(self.shape,translate(pad_TQFP_v,1.5*d,c,0)) + self.pad.append(point(1.5*d,c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD1',angle=90,line=s)) + # + # pin 28: PD0 + # + self.shape = add(self.shape,translate(pad_TQFP_v,.5*d,c,0)) + self.pad.append(point(.5*d,c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD0',angle=90,line=s)) + # + # pin 29: PA7 + # + self.shape = add(self.shape,translate(pad_TQFP_v,-.5*d,c,0)) + self.pad.append(point(-.5*d,c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA7',angle=90,line=s)) + # + # pin 30: PA6 + # + self.shape = add(self.shape,translate(pad_TQFP_v,-1.5*d,c,0)) + self.pad.append(point(-1.5*d,c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA6',angle=90,line=s)) + # + # pin 31: PA5 + # + self.shape = add(self.shape,translate(pad_TQFP_v,-2.5*d,c,0)) + self.pad.append(point(-2.5*d,c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA5',angle=90,line=s)) + # + # pin 32: AVCC + # + self.shape = add(self.shape,translate(pad_TQFP_v,-3.5*d,c,0)) + self.pad.append(point(-3.5*d,c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'AVCC',angle=90,line=s)) + +class ATmega88_TQFP(part): + def __init__(self,value=''): + c = .18 + d = .031 + s = 0.004 + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: PD3/PCINT19/OC2B/INT1 + # + self.shape = translate(pad_TQFP_h,-c,3.5*d,0) + self.pad.append(point(-c,3.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1 PD3',line=s)) + # + # pin 2: PD4/PCINT20/XCK/T0 + # + self.shape = add(self.shape,translate(pad_TQFP_h,-c,2.5*d,0)) + self.pad.append(point(-c,2.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD4',line=s)) + # + # pin 3: GND + # + self.shape = add(self.shape,translate(pad_TQFP_h,-c,1.5*d,0)) + self.pad.append(point(-c,1.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND',line=s)) + # + # pin 4: VCC + # + self.shape = add(self.shape,translate(pad_TQFP_h,-c,.5*d,0)) + self.pad.append(point(-c,.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VCC',line=s)) + # + # pin 5: GND + # + self.shape = add(self.shape,translate(pad_TQFP_h,-c,-.5*d,0)) + self.pad.append(point(-c,-.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND',line=s)) + # + # pin 6: VCC + # + self.shape = add(self.shape,translate(pad_TQFP_h,-c,-1.5*d,0)) + self.pad.append(point(-c,-1.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VCC',line=s)) + # + # pin 7: PB6/PCINT6/XTAL1/TOSC1 + # + self.shape = add(self.shape,translate(pad_TQFP_h,-c,-2.5*d,0)) + self.pad.append(point(-c,-2.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PB6',line=s)) + # + # pin 8: PB7/PCINT7/XTAL2/TOSC2 + # + self.shape = add(self.shape,translate(pad_TQFP_h,-c,-3.5*d,0)) + self.pad.append(point(-c,-3.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PB7',line=s)) + # + # pin 9: PD5/PCINT21/OC0B/T1 + # + self.shape = add(self.shape,translate(pad_TQFP_v,-3.5*d,-c,0)) + self.pad.append(point(-3.5*d,-c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD5',angle=90,line=s)) + # + # pin 10: PD6/PCINT22/OC0A/AIN0 + # + self.shape = add(self.shape,translate(pad_TQFP_v,-2.5*d,-c,0)) + self.pad.append(point(-2.5*d,-c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD6',angle=90,line=s)) + # + # pin 11: PD7/PCINT23/AIN1 + # + self.shape = add(self.shape,translate(pad_TQFP_v,-1.5*d,-c,0)) + self.pad.append(point(-1.5*d,-c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD7',angle=90,line=s)) + # + # pin 12: PB0/PCINT0/CLKO/ICP1 + # + self.shape = add(self.shape,translate(pad_TQFP_v,-.5*d,-c,0)) + self.pad.append(point(-.5*d,-c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PB0',angle=90,line=s)) + # + # pin 13: PB1/PCINT1/OC1A + # + self.shape = add(self.shape,translate(pad_TQFP_v,.5*d,-c,0)) + self.pad.append(point(.5*d,-c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PB1',angle=90,line=s)) + # + # pin 14: PB2/PCINT2/-SS/OC1B + # + self.shape = add(self.shape,translate(pad_TQFP_v,1.5*d,-c,0)) + self.pad.append(point(1.5*d,-c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PB2',angle=90,line=s)) + # + # pin 15: PB3/PCINT3/OC2A/MOSI + # + self.shape = add(self.shape,translate(pad_TQFP_v,2.5*d,-c,0)) + self.pad.append(point(2.5*d,-c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PB3',angle=90,line=s)) + # + # pin 16: PB4/PCINT4/MISO + # + self.shape = add(self.shape,translate(pad_TQFP_v,3.5*d,-c,0)) + self.pad.append(point(3.5*d,-c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PB4',angle=90,line=s)) + # + # pin 17: PB5/SCK/PCINT5 + # + self.shape = add(self.shape,translate(pad_TQFP_h,c,-3.5*d,0)) + self.pad.append(point(c,-3.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PB5',line=s)) + # + # pin 18: AVCC + # + self.shape = add(self.shape,translate(pad_TQFP_h,c,-2.5*d,0)) + self.pad.append(point(c,-2.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'AVCC',line=s)) + # + # pin 19: ADC6 + # + self.shape = add(self.shape,translate(pad_TQFP_h,c,-1.5*d,0)) + self.pad.append(point(c,-1.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'ADC6',line=s)) + # + # pin 20: AREF + # + self.shape = add(self.shape,translate(pad_TQFP_h,c,-.5*d,0)) + self.pad.append(point(c,-.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'AREF',line=s)) + # + # pin 21: GND + # + self.shape = add(self.shape,translate(pad_TQFP_h,c,.5*d,0)) + self.pad.append(point(c,.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND',line=s)) + # + # pin 22: ADC7 + # + self.shape = add(self.shape,translate(pad_TQFP_h,c,1.5*d,0)) + self.pad.append(point(c,1.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'ADC7',line=s)) + # + # pin 23: PC0/ADC0/PCINT8 + # + self.shape = add(self.shape,translate(pad_TQFP_h,c,2.5*d,0)) + self.pad.append(point(c,2.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC0',line=s)) + # + # pin 24: PC1/ADC1/PCINT9 + # + self.shape = add(self.shape,translate(pad_TQFP_h,c,3.5*d,0)) + self.pad.append(point(c,3.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC1',line=s)) + # + # pin 25: PC2/ADC2/PCINT10 + # + self.shape = add(self.shape,translate(pad_TQFP_v,3.5*d,c,0)) + self.pad.append(point(3.5*d,c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC2',angle=90,line=s)) + # + # pin 26: PC3/ADC3/PCINT11 + # + self.shape = add(self.shape,translate(pad_TQFP_v,2.5*d,c,0)) + self.pad.append(point(2.5*d,c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC3',angle=90,line=s)) + # + # pin 27: PC4/ADC4/SDA/PCINT12 + # + self.shape = add(self.shape,translate(pad_TQFP_v,1.5*d,c,0)) + self.pad.append(point(1.5*d,c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC4',angle=90,line=s)) + # + # pin 28: PC5/ADC5/SCL/PCINT13 + # + self.shape = add(self.shape,translate(pad_TQFP_v,.5*d,c,0)) + self.pad.append(point(.5*d,c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC5',angle=90,line=s)) + # + # pin 29: PC6/-RESET/PCINT14 + # + self.shape = add(self.shape,translate(pad_TQFP_v,-.5*d,c,0)) + self.pad.append(point(-.5*d,c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC6',angle=90,line=s)) + # + # pin 30: PD0/RXD/PCINT16 + # + self.shape = add(self.shape,translate(pad_TQFP_v,-1.5*d,c,0)) + self.pad.append(point(-1.5*d,c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD0',angle=90,line=s)) + # + # pin 31: PD1/TXD/PCINT17 + # + self.shape = add(self.shape,translate(pad_TQFP_v,-2.5*d,c,0)) + self.pad.append(point(-2.5*d,c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD1',angle=90,line=s)) + # + # pin 32: PD2/INT0/PCINT18 + # + self.shape = add(self.shape,translate(pad_TQFP_v,-3.5*d,c,0)) + self.pad.append(point(-3.5*d,c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD2',angle=90,line=s)) + +class ATmega644_TQFP(part): + def __init__(self,value=''): + c = .235 + d = .031 + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: PB5/PCINT13/MOSI + # + self.shape = translate(pad_TQFP_h,-c,5*d,0) + self.pad.append(point(-c,5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'*MOSI (1)')) + # + # pin 2: PB6/PCINT14/MISO + # + self.shape = add(self.shape,translate(pad_TQFP_h,-c,4*d,0)) + self.pad.append(point(-c,4*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'MISO')) + # + # pin 3: PB7/PCINT15/SCK + # + self.shape = add(self.shape,translate(pad_TQFP_h,-c,3*d,0)) + self.pad.append(point(-c,3*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SCK')) + # + # pin 4: -RESET + # + self.shape = add(self.shape,translate(pad_TQFP_h,-c,2*d,0)) + self.pad.append(point(-c,2*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'-RESET')) + # + # pin 5: VCC + # + self.shape = add(self.shape,translate(pad_TQFP_h,-c,d,0)) + self.pad.append(point(-c,d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VCC')) + # + # pin 6: GND + # + self.shape = add(self.shape,translate(pad_TQFP_h,-c,0,0)) + self.pad.append(point(-c,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 7: XTAL2 + # + self.shape = add(self.shape,translate(pad_TQFP_h,-c,-d,0)) + self.pad.append(point(-c,-d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'XTAL2')) + # + # pin 8: XTAL1 + # + self.shape = add(self.shape,translate(pad_TQFP_h,-c,-2*d,0)) + self.pad.append(point(-c,-2*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'XTAL1')) + # + # pin 9: PD0/PCINT24/RXD0 + # + self.shape = add(self.shape,translate(pad_TQFP_h,-c,-3*d,0)) + self.pad.append(point(-c,-3*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RXD0')) + # + # pin 10: PD1/PCINT25/TXD0 + # + self.shape = add(self.shape,translate(pad_TQFP_h,-c,-4*d,0)) + self.pad.append(point(-c,-4*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'TXD0')) + # + # pin 11: PD2/PCINT26/INT0 + # + self.shape = add(self.shape,translate(pad_TQFP_h,-c,-5*d,0)) + self.pad.append(point(-c,-5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD2')) + # + # pin 12: PD3/PCINT27/INT1 + # + self.shape = add(self.shape,translate(pad_TQFP_v,-5*d,-c,0)) + self.pad.append(point(-5*d,-c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD3')) + # + # pin 13: PD4/PCINT28/OC1B + # + self.shape = add(self.shape,translate(pad_TQFP_v,-4*d,-c,0)) + self.pad.append(point(-4*d,-c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD4')) + # + # pin 14: PD5/PCINT28/OC1A + # + self.shape = add(self.shape,translate(pad_TQFP_v,-3*d,-c,0)) + self.pad.append(point(-3*d,-c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD5')) + # + # pin 15: PD6/PCINT30/OC2B/ICP + # + self.shape = add(self.shape,translate(pad_TQFP_v,-2*d,-c,0)) + self.pad.append(point(-2*d,-c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD6')) + # + # pin 16: PD7/PCINT31/OC2A + # + self.shape = add(self.shape,translate(pad_TQFP_v,-d,-c,0)) + self.pad.append(point(-d,-c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD7')) + # + # pin 17: VCC + # + self.shape = add(self.shape,translate(pad_TQFP_v,0,-c,0)) + self.pad.append(point(0,-c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VCC')) + # + # pin 18: GND + # + self.shape = add(self.shape,translate(pad_TQFP_v,d,-c,0)) + self.pad.append(point(d,-c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 19: PC0/PCINT16/SCL + # + self.shape = add(self.shape,translate(pad_TQFP_v,2*d,-c,0)) + self.pad.append(point(2*d,-c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC0')) + # + # pin 20: PC1/PCINT17/SDA + # + self.shape = add(self.shape,translate(pad_TQFP_v,3*d,-c,0)) + self.pad.append(point(3*d,-c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC1')) + # + # pin 21: PC2/PCINT18/TCK + # + self.shape = add(self.shape,translate(pad_TQFP_v,4*d,-c,0)) + self.pad.append(point(4*d,-c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC2')) + # + # pin 22: PC3/PCINT19/TMS + # + self.shape = add(self.shape,translate(pad_TQFP_v,5*d,-c,0)) + self.pad.append(point(5*d,-c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC3')) + # + # pin 23: PC4/TDO/PCINT20 + # + self.shape = add(self.shape,translate(pad_TQFP_h,c,-5*d,0)) + self.pad.append(point(c,-5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC4')) + # + # pin 24: PC5/TDI/PCINT21 + # + self.shape = add(self.shape,translate(pad_TQFP_h,c,-4*d,0)) + self.pad.append(point(c,-4*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC5')) + # + # pin 25: PC6/TOSC1/PCINT22 + # + self.shape = add(self.shape,translate(pad_TQFP_h,c,-3*d,0)) + self.pad.append(point(c,-3*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC6')) + # + # pin 26: PC7/TOSC2/PCINT23 + # + self.shape = add(self.shape,translate(pad_TQFP_h,c,-2*d,0)) + self.pad.append(point(c,-2*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC7')) + # + # pin 27: AVCC + # + self.shape = add(self.shape,translate(pad_TQFP_h,c,-d,0)) + self.pad.append(point(c,-d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'AVCC')) + # + # pin 28: GND + # + self.shape = add(self.shape,translate(pad_TQFP_h,c,0,0)) + self.pad.append(point(c,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 29: AREF + # + self.shape = add(self.shape,translate(pad_TQFP_h,c,d,0)) + self.pad.append(point(c,d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'AREF')) + # + # pin 30: PA7/ADC7/PCINT7 + # + self.shape = add(self.shape,translate(pad_TQFP_h,c,2*d,0)) + self.pad.append(point(c,2*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA7')) + # + # pin 31: PA6/ADC6/PCINT6 + # + self.shape = add(self.shape,translate(pad_TQFP_h,c,3*d,0)) + self.pad.append(point(c,3*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA6')) + # + # pin 32: PA5/ADC5/PCINT5 + # + self.shape = add(self.shape,translate(pad_TQFP_h,c,4*d,0)) + self.pad.append(point(c,4*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA5')) + # + # pin 33: PA4/ADC4/PCINT4 + # + self.shape = add(self.shape,translate(pad_TQFP_h,c,5*d,0)) + self.pad.append(point(c,5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA4')) + # + # pin 34: PA3/ADC3/PCINT3 + # + self.shape = add(self.shape,translate(pad_TQFP_v,5*d,c,0)) + self.pad.append(point(5*d,c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA3')) + # + # pin 35: PA2/ADC2/PCINT2 + # + self.shape = add(self.shape,translate(pad_TQFP_v,4*d,c,0)) + self.pad.append(point(4*d,c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA2')) + # + # pin 36: PA1/ADC1/PCINT1 + # + self.shape = add(self.shape,translate(pad_TQFP_v,3*d,c,0)) + self.pad.append(point(3*d,c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA1')) + # + # pin 37: PA0/ADC0/PCINT0 + # + self.shape = add(self.shape,translate(pad_TQFP_v,2*d,c,0)) + self.pad.append(point(2*d,c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA0')) + # + # pin 38: VCC + # + self.shape = add(self.shape,translate(pad_TQFP_v,d,c,0)) + self.pad.append(point(d,c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VCC')) + # + # pin 39: GND + # + self.shape = add(self.shape,translate(pad_TQFP_v,0,c,0)) + self.pad.append(point(0,c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 40: PB0/XCK0/T0/PCINT8 + # + self.shape = add(self.shape,translate(pad_TQFP_v,-d,c,0)) + self.pad.append(point(-d,c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PB0')) + # + # pin 41: PB1/T1/CLKO/PCINT9 + # + self.shape = add(self.shape,translate(pad_TQFP_v,-2*d,c,0)) + self.pad.append(point(-2*d,c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PB1')) + # + # pin 42: PB2/AIN0/INT2/PCINT10 + # + self.shape = add(self.shape,translate(pad_TQFP_v,-3*d,c,0)) + self.pad.append(point(-3*d,c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PB2')) + # + # pin 43: PB3/AIN1/OC0A/PCINT11 + # + self.shape = add(self.shape,translate(pad_TQFP_v,-4*d,c,0)) + self.pad.append(point(-4*d,c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PB2')) + # + # pin 44: PB4/-SS/OC0B/PCINT12 + # + self.shape = add(self.shape,translate(pad_TQFP_v,-5*d,c,0)) + self.pad.append(point(-5*d,c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PB4')) + +TSSOP_pad_width = 0.040 +TSSOP_pad_height = 0.011 +TSSOP_pad_dy = 0.026 +TSSOP_pad_dx = 0.120 +pad_TSSOP = cube(-TSSOP_pad_width/2.0,TSSOP_pad_width/2.0,-TSSOP_pad_height/2.0,TSSOP_pad_height/2.0,0,0) + +class TRC102(part): + # + # RFM TRC102 ISM transceiver + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: SDI + # + self.shape = translate(pad_TSSOP,-TSSOP_pad_dx,3.5*TSSOP_pad_dy,0) + self.pad.append(point(-TSSOP_pad_dx,3.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1 SDI')) + # + # pin 2: SCK + # + self.shape = add(self.shape,translate(pad_TSSOP,-TSSOP_pad_dx,2.5*TSSOP_pad_dy,0)) + self.pad.append(point(-TSSOP_pad_dx,2.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SCK')) + # + # pin 3: nCS + # + self.shape = add(self.shape,translate(pad_TSSOP,-TSSOP_pad_dx,1.5*TSSOP_pad_dy,0)) + self.pad.append(point(-TSSOP_pad_dx,1.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'nCS')) + # + # pin 4: SDO + # + self.shape = add(self.shape,translate(pad_TSSOP,-TSSOP_pad_dx,0.5*TSSOP_pad_dy,0)) + self.pad.append(point(-TSSOP_pad_dx,0.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SDO')) + # + # pin 5: IRQ + # + self.shape = add(self.shape,translate(pad_TSSOP,-TSSOP_pad_dx,-0.5*TSSOP_pad_dy,0)) + self.pad.append(point(-TSSOP_pad_dx,-0.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IRQ')) + # + # pin 6: DATA/nFSEL + # + self.shape = add(self.shape,translate(pad_TSSOP,-TSSOP_pad_dx,-1.5*TSSOP_pad_dy,0)) + self.pad.append(point(-TSSOP_pad_dx,-1.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'DATA')) + # + # pin 7: CR + # + self.shape = add(self.shape,translate(pad_TSSOP,-TSSOP_pad_dx,-2.5*TSSOP_pad_dy,0)) + self.pad.append(point(-TSSOP_pad_dx,-2.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'CR')) + # + # pin 8: CLKOUT + # + self.shape = add(self.shape,translate(pad_TSSOP,-TSSOP_pad_dx,-3.5*TSSOP_pad_dy,0)) + self.pad.append(point(-TSSOP_pad_dx,-3.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'CLKOUT')) + # + # pin 9: Xtal/Ref + # + self.shape = add(self.shape,translate(pad_TSSOP,TSSOP_pad_dx,-3.5*TSSOP_pad_dy,0)) + self.pad.append(point(TSSOP_pad_dx,-3.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'Xtal')) + # + # pin 10: RESET + # + self.shape = add(self.shape,translate(pad_TSSOP,TSSOP_pad_dx,-2.5*TSSOP_pad_dy,0)) + self.pad.append(point(TSSOP_pad_dx,-2.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RESET')) + # + # pin 11: GND + # + self.shape = add(self.shape,translate(pad_TSSOP,TSSOP_pad_dx,-1.5*TSSOP_pad_dy,0)) + self.pad.append(point(TSSOP_pad_dx,-1.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 12: RF_P + # + self.shape = add(self.shape,translate(pad_TSSOP,TSSOP_pad_dx,-0.5*TSSOP_pad_dy,0)) + self.pad.append(point(TSSOP_pad_dx,-0.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RF_P')) + # + # pin 13: RF_N + # + self.shape = add(self.shape,translate(pad_TSSOP,TSSOP_pad_dx,0.5*TSSOP_pad_dy,0)) + self.pad.append(point(TSSOP_pad_dx,0.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RF_N')) + # + # pin 14: VDD + # + self.shape = add(self.shape,translate(pad_TSSOP,TSSOP_pad_dx,1.5*TSSOP_pad_dy,0)) + self.pad.append(point(TSSOP_pad_dx,1.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VDD')) + # + # pin 15: RSSIA + # + self.shape = add(self.shape,translate(pad_TSSOP,TSSOP_pad_dx,2.5*TSSOP_pad_dy,0)) + self.pad.append(point(TSSOP_pad_dx,2.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RSSIA')) + # + # pin 16: nINT/DDET + # + self.shape = add(self.shape,translate(pad_TSSOP,TSSOP_pad_dx,3.5*TSSOP_pad_dy,0)) + self.pad.append(point(TSSOP_pad_dx,3.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'nINT')) + +class CBA(part): + # + # CBA logo + # + def __init__(self,r=.02): + self.value = '' + self.pad = [point(0,0,0)] + self.labels = [] + d = 3*r + self.shape = cylinder(0,0,0,0,r) + self.shape = add(self.shape,translate(cylinder(0,0,0,0,r),-d,d,0)) + self.shape = add(self.shape,translate(cube(-r,r,-r,r,0,0),-d,0,0)) + self.shape = add(self.shape,translate(cube(-r,r,-r,r,0,0),-d,-d,0)) + self.shape = add(self.shape,translate(cube(-r,r,-r,r,0,0),0,-d,0)) + self.shape = add(self.shape,translate(cube(-r,r,-r,r,0,0),d,-d,0)) + self.shape = add(self.shape,translate(cube(-r,r,-r,r,0,0),d,0,0)) + self.shape = add(self.shape,translate(cube(-r,r,-r,r,0,0),d,d,0)) + self.shape = add(self.shape,translate(cube(-r,r,-r,r,0,0),0,d,0)) + +class fab(part): + def __init__(self,r=.05): + self.value = '' + self.pad = [point(0,0,0)] + self.labels = [] + d = 1.8*r + l = 3.5*r + h = r/2. + self.shape = rectangle(-d,d,-d,d) + self.shape = subtract(self.shape,circle(0,0,r)) + self.shape = subtract(self.shape,rectangle(-l,0,-h,h)) + self.shape = add(self.shape,rectangle(d,l,-h,h)) + self.shape = add(self.shape,circle(l,0,r)) + self.shape = add(self.shape,circle(-l,0,r)) + +############################################################ +# define board +############################################################ + +width = 1.99 # board width +height = 1.99-.34 # board height +x = 1 # x origin +y = 1 # y origin +zt = 0 # top z +zb = -0.06 # bottom z +w = .0106 # wire width +w1 = .015 # thicker wire width +w2 = .03 # thickest wire width +mask = .002 # solder mask size + +pcb = PCB(x,y,width,height,mask) + +IC1 = DRV8428_HTSSOP('IC1\nDRV8428') +pcb = IC1.add(pcb,x+.56,y+height/2+.25) + +pcb = wire(pcb,w, + IC1.pad[2], + point(IC1.x,IC1.pad[2].y)) + +pcb = wire(pcb,w, + IC1.pad[2], + point(IC1.pad[2].x-.075,IC1.pad[2].y)) + +pcb = wire(pcb,w, + IC1.pad[7], + point(IC1.x,IC1.pad[7].y)) + +pcb = wire(pcb,w, + IC1.pad[7], + point(IC1.pad[7].x-.075,IC1.pad[7].y)) + +pcb = wire(pcb,w, + IC1.pad[9], + point(IC1.pad[9].x+.075,IC1.pad[9].y)) + +pcb = wire(pcb,w, + IC1.pad[11], + point(IC1.x,IC1.pad[11].y)) + +pcb = wire(pcb,w, + IC1.pad[11], + point(IC1.pad[11].x+.075,IC1.pad[11].y)) + +J2 = header_4H('J2\nstepper') +pcb = J2.add(pcb,x+.23,y+height/2,angle=180) + +pcb = wire(pcb,w, + IC1.pad[3], + point(J2.x-.132,IC1.pad[3].y), + point(J2.x-.132,J2.pad[1].y), + J2.pad[1]) + +pcb = wire(pcb,w, + IC1.pad[4], + point(J2.x-.106,IC1.pad[4].y), + point(J2.x-.106,J2.pad[2].y), + J2.pad[2]) + +pcb = wire(pcb,w, + IC1.pad[5], + point(J2.x-.08,IC1.pad[5].y), + point(J2.x-.08,J2.pad[3].y), + J2.pad[3]) + +pcb = wire(pcb,w, + IC1.pad[6], + point(J2.x,IC1.pad[6].y), + J2.pad[4]) + +R1 = ST4EB('R1\n10k') +pcb = R1.add(pcb,IC1.x-.05,IC1.y-.35) + +pcb = wire(pcb,w, + IC1.pad[9], + point(IC1.pad[9].x,IC1.pad[9].y-.06), + point(R1.pad[3].x,IC1.pad[9].y-.06), + R1.pad[3]) + +C1 = C_1206('C1\n1uF') +pcb = C1.add(pcb,J2.x,J2.pad[1].y-.16,angle=90) + +pcb = wire(pcb,w1, + C1.pad[1], + point(C1.x,y+.37)) + +pcb = wire(pcb,w, + C1.pad[2], + point(C1.x+.1,C1.pad[2].y), + point(C1.x+.1,IC1.pad[8].y), + IC1.pad[8]) + +R2 = R_1206('R2\n10k') +pcb = R2.add(pcb,R1.pad[1].x-.02,R1.y-.24,angle=0) + +pcb = wire(pcb,w, + R2.pad[1], + point(R2.pad[1].x,C1.pad[2].y), + C1.pad[2]) + +pcb = wire(pcb,w1, + R2.pad[2], + point(R1.pad[1].x,R2.y), + R1.pad[1]) + +C2 = C_FND('C2\n100uF') +pcb = C2.add(pcb,IC1.x+.08,IC1.y+.27,angle=90) + +pcb = wire(pcb,w2, + C2.pad[2], + point(C2.pad[2].x,C2.y-.08)) + +J4 = header_2H('J4\npower') +pcb = J4.add(pcb,x+.23,IC1.pad[1].y+.05,angle=180) + +pcb = wire(pcb,w, + IC1.pad[1], + point(J4.x,IC1.pad[1].y)) + +pcb = wire(pcb,w, + IC1.pad[1], + point(IC1.pad[1].x+.025,IC1.pad[1].y), + point(IC1.pad[1].x+.025,IC1.pad[1].y+w), + point(J4.x,IC1.pad[1].y+w)) + +pcb = wire(pcb,w2, + point(C2.pad[1].x-.02,C2.y), + point(J4.x+.10,J4.pad[1].y+.01), + point(J4.x,J4.pad[1].y+.01), + J4.pad[1]) + +C3 = C_1206('C3\n.01uF') +pcb = C3.add(pcb,C2.x+.31,C2.y) + +pcb = wire(pcb,w2, + C2.pad[2], + C3.pad[1]) + +pcb = wire(pcb,w2, + C3.pad[2], + point(C3.pad[2].x,C3.y+.08), + point(C2.pad[1].x,C3.y+.08), + C2.pad[1]) + +IC2 = SAMD11C('IC2\nD11C') +pcb = IC2.add(pcb,x+width-.62,y+height/2,angle=-90) + +J1 = header_SWD_4_1('J1 SWD') +pcb = J1.add(pcb,IC2.pad[7].x-.14,IC2.y,angle=-90) + +pcb = wire(pcb,w1, + J1.pad[1], + point(J1.pad[1].x,IC2.pad[7].y), + IC2.pad[7]) + +pcb = wire(pcb,w1, + J1.pad[2], + point(J1.pad[2].x,IC2.pad[8].y), + IC2.pad[8]) + +pcb = wire(pcb,w, + J1.pad[3], + point(J1.pad[3].x,IC2.pad[6].y+.1), + point(IC2.pad[6].x,IC2.pad[6].y+.1), + IC2.pad[6]) + +pcb = wire(pcb,w1, + J1.pad[4], + point(J1.pad[4].x,IC2.pad[12].y-.08), + point(IC2.pad[11].x,IC2.pad[11].y-.08), + IC2.pad[11]) + +pcb = wire(pcb,w1, + J1.pad[4], + point(J1.pad[4].x,IC2.pad[12].y-.08), + point(R1.pad[2].x,IC2.pad[12].y-.08), + R1.pad[2]) + +pcb = wire(pcb,w, + IC2.pad[1], + point(IC2.pad[1].x,IC2.pad[1].y+.21+.03), + point(J1.pad[3].x-.190,IC2.pad[5].y+.21+.03), + point(J1.pad[3].x-.200,IC1.pad[16].y), + IC1.pad[16]) + +pcb = wire(pcb,w, + point(J1.pad[3].x-.154,IC1.pad[16].y), + point(J1.pad[3].x-.174,IC1.pad[15].y), + IC1.pad[15]) + +pcb = wire(pcb,w, + IC2.pad[2], + point(IC2.pad[2].x,IC2.pad[2].y+.184+.03), + point(J1.pad[3].x-.128,IC2.pad[5].y+.184+.03), + point(J1.pad[3].x-.148,IC1.pad[14].y), + IC1.pad[14]) + +pcb = wire(pcb,w, + IC2.pad[3], + point(IC2.pad[3].x,IC2.pad[5].y+.158+.03), + point(J1.pad[3].x-.102,IC2.pad[5].y+.158+.03), + point(J1.pad[3].x-.122,IC1.pad[13].y), + IC1.pad[13]) + +pcb = wire(pcb,w, + IC2.pad[4], + point(IC2.pad[4].x,IC2.pad[5].y+.132+.03), + point(J1.pad[3].x-.076,IC2.pad[5].y+.132+.03), + point(J1.pad[3].x-.096,IC1.pad[12].y), + IC1.pad[12]) + +pcb = wire(pcb,w, + IC2.pad[5], + point(IC2.pad[5].x,IC2.pad[5].y+.106+.03), + point(J1.pad[3].x-.05,IC2.pad[5].y+.106+.03), + point(J1.pad[3].x-.09,IC1.pad[10].y), + IC1.pad[10]) + +J3 = USB_A_plug('J3\nUSB') +pcb = J3.add(pcb,x+width-.29,IC2.y+.025,angle=0) + +pcb = wire(pcb,w1, + J3.pad[2], + point(J3.pad[2].x-.11,J3.pad[2].y), + point(J3.pad[2].x-.11,IC2.y+.015), + point(IC2.pad[9].x,IC2.y+.015), + IC2.pad[9]) + +pcb = wire(pcb,w1, + point(J3.pad[3].x,IC2.y-.015), + point(IC2.pad[10].x,IC2.y-.015), + IC2.pad[10]) + +pcb = wire(pcb,w1, + J3.pad[4], + point(J3.pad[4].x-.11,J3.pad[4].y), + point(J3.pad[4].x-.11,IC2.y-.045), + point(IC2.pad[11].x,IC2.y-.045), + IC2.pad[11]) + +pcb = wire(pcb,w2, + J3.pad[4], + point(J3.pad[4].x-.11,J3.pad[4].y), + point(J3.pad[4].x-.11,y+.37), + point(x+.03,y+.37), + point(x+.03,J4.pad[2].y), + J4.pad[2]) + +IC3 = regulator_SOT23('IC3\n3.3V') +pcb = IC3.add(pcb,IC2.pad[8].x-.1,IC2.pad[9].y-.21,angle=0) + +pcb = wire(pcb,w1, + J4.pad[1], + point(x+.07,J4.pad[1].y), + point(x+.07,C1.y), + point(C1.x+.08,C1.y), + point(C1.x+.08,IC3.pad[2].y-.05), + point(IC3.pad[2].x,IC3.pad[2].y-.05), + IC3.pad[2]) + +pcb = wire(pcb,w1, + IC3.pad[3], + point(IC3.pad[3].x,y+.37)) + +C4 = C_1206('C4\n1uF') +pcb = C4.add(pcb,IC3.x-.22,IC3.y) + +pcb = wire(pcb,w1, + C4.pad[1], + point(C4.pad[1].x,C4.y+.1), + point(IC3.pad[1].x,C4.y+.1), + IC3.pad[1]) + +pcb = wire(pcb,w1, + C4.pad[2], + IC3.pad[3]) + +pcb = wire(pcb,w1, + IC3.pad[1], + point(IC3.pad[1].x,C4.y+.1), + point(IC2.pad[12].x,C4.y+.1), + IC2.pad[12]) + +R3 = R_1206('R3\n0') +pcb = R3.add(pcb,C3.x+.22,C3.y) + +pcb = wire(pcb,w2, + C3.pad[2], + R3.pad[1]) + +pcb = wire(pcb,w2, + R3.pad[2], + point(R3.pad[2].x+.07,R3.pad[2].y), + point(R3.pad[2].x+.12,J4.pad[2].y), + point(J3.pad[4].x-.11,J4.pad[2].y), + point(J3.pad[4].x-.11,J3.pad[1].y), + J3.pad[1]) + +pcb = wire(pcb,w2, + IC1.pad[17], + point(IC1.x,R3.y-.13), + point(IC1.x+.04,R3.y-.08), + point(R3.x,R3.y-.08)) + +pcb = wire(pcb,w2, + J4.pad[2], + point(J4.x+.11,J4.pad[2].y), + point(J4.x+.17,J4.pad[2].y+.06), + point(J4.x+.17,C2.y+.07), + point(J4.x+.23,C2.y+.13), + point(R3.x,C2.y+.13)) + +pcb = wire(pcb,w1, + point(R3.x,R3.y-.08), + point(R3.x,C2.y+.13)) + +R4 = R_1206('R4\n1k') +pcb = R4.add(pcb,IC2.pad[11].x+.01,IC3.y+.03,angle=0) + +pcb = wire(pcb,w1, + R4.pad[2], + point(IC2.pad[13].x,R4.y), + IC2.pad[13]) + +LED = LED_1206('LED') +pcb = LED.add(pcb,R4.x,R4.y-.09,angle=180) + +pcb = wire(pcb,w1, + LED.pad[1], + point(IC2.pad[14].x,LED.y), + IC2.pad[14]) + +pcb = wire(pcb,w1, + LED.pad[2], + point(R4.pad[1].x,LED.y), + R4.pad[1]) + +pcb.holes = add(pcb.holes,cylinder(x+(width-.34)/2,y+height/2,zb,zt,.125)) +pcb.holes = add(pcb.holes,cylinder(x+.21,y+height-.21,zb,zt,.065)) +pcb.holes = add(pcb.holes,cylinder(x+.21,y+.21,zb,zt,.065)) +pcb.holes = add(pcb.holes,cylinder(x+width-(.21+.34),y+height-.21,zb,zt,.065)) +pcb.holes = add(pcb.holes,cylinder(x+width-(.21+.34),y+.21,zb,zt,.065)) + +l = 0.13 +pcb.exterior = add(pcb.exterior,triangle(x,y+height-l,x,y+height,x+l,y+height)) +pcb.exterior = add(pcb.exterior,triangle(x,y,x,y+l,x+l,y)) +pcb.exterior = add(pcb.exterior,triangle(x+width-.34,y+height,x+width-.34,y+height-l,x+width-l-.34,y+height)) +pcb.exterior = add(pcb.exterior,triangle(x+width-.34-l,y,x+width-.34,y+l,x+width-.34,y)) +pcb.interior = subtract(pcb.interior,triangle(x,y+height-l,x,y+height,x+l,y+height)) +pcb.interior = subtract(pcb.interior,triangle(x,y,x,y+l,x+l,y)) +pcb.interior = subtract(pcb.interior,triangle(x+width-.34,y+height,x+width-.34,y+height-l,x+width-l-.34,y+height)) +pcb.interior = subtract(pcb.interior,triangle(x+width-.34-l,y,x+width-.34,y+l,x+width-.34,y)) + +#pcb.exterior = add(pcb.exterior,text("8/20/21",x+(width-.34)/2+.1,y+0.2,0,line=0.01,color=White).shape) +#pcb.exterior = add(pcb.exterior,text("hello.DRV8428-D11C-NEMA17",x+(width-.34)/2,y+0.075,0,line=0.01,color=White).shape) +#c = CBA(r=0.0125) +#pcb.exterior = add(pcb.exterior,move(c.shape,x+(width-.34)/2-.175,y+.2)) + +############################################################ +# select output +############################################################ + +outputs = {} +if (output == "top, labels, and exterior"): + outputs["function"] = add(add(color(Tan,pcb.board),pcb.labels), + color(White,pcb.exterior)) + outputs["layers"] = [zt] +elif (output == "top, labels, holes, and exterior"): + outputs["function"] = add(add(color(Tan,pcb.board),pcb.labels), + add(color(White,pcb.exterior),color(Blue,pcb.holes))) + outputs["layers"] = [zt] +elif (output == "top, bottom, labels, and exterior"): + outputs["function"] = add(add(color(Tan,pcb.board),pcb.labels), + color(White,pcb.exterior)) + outputs["layers"] = [zb,zt] +elif (output == "top, bottom, labels, holes, and exterior"): + outputs["function"] = add(add(color(Tan,pcb.board),pcb.labels), + add(color(White,pcb.exterior),color(Blue,pcb.holes))) + outputs["layers"] = [zb,zt] +elif (output == "top traces"): + outputs["function"] = color(White,pcb.board) + outputs["layers"] = [zt] +elif (output == "top traces and exterior"): + outputs["function"] = color(White,add(pcb.board,pcb.exterior)) + outputs["layers"] = [zt] +elif (output == "bottom traces reversed"): + outputs["function"] = color(White, + reflect_x(pcb.board,2*x+width)) + outputs["layers"] = [zb] +elif (output == "bottom traces reversed and exterior"): + outputs["function"] = color(White, + reflect_x(add(pcb.board,pcb.exterior),2*x+width)) + outputs["layers"] = [zb] +elif (output == "interior"): + outputs["function"] = color(White,pcb.interior) + outputs["layers"] = [zt] +elif (output == "exterior"): + outputs["function"] = color(White,pcb.exterior) + outputs["layers"] = [zt] +elif (output == "holes"): + outputs["function"] = color(White, + subtract(add(pcb.exterior,pcb.interior),pcb.holes)) + outputs["layers"] = [zb] +elif (output == "holes and interior"): + outputs["function"] = color(White, + subtract(pcb.interior,pcb.holes)) + outputs["layers"] = [zb] +elif (output == "solder mask"): + outputs["function"] = color(White,pcb.mask) + outputs["layers"] = [zt] +else: + print("oops -- don't recognize output") + +############################################################ +# set limits and parameters +############################################################ + +border = 0.05 +outputs["xmin"] = x-border # min x to render +outputs["xmax"] = x+width+border # max x to render +outputs["ymin"] = y-border # min y to render +outputs["ymax"] = y+height+border # max y to render +outputs["mm_per_unit"] = 25.4 # use inch units +outputs["type"] = "RGB" # use RGB color + +############################################################ +# send output +############################################################ + +json.dump(outputs,sys.stdout) + diff --git a/serialstep/board/hello.DRV8428-D11C-NEMA17.holes.png b/serialstep/board/hello.DRV8428-D11C-NEMA17.holes.png new file mode 100644 index 0000000000000000000000000000000000000000..cf6d3674e63875f56e78e033a2bf1007f138de37 GIT binary patch literal 17614 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 L{an^LB{Ts5jYymu literal 0 HcmV?d00001 diff --git a/serialstep/board/hello.DRV8428-D11C-NEMA17.interior.png b/serialstep/board/hello.DRV8428-D11C-NEMA17.interior.png new file mode 100644 index 0000000000000000000000000000000000000000..615ca64cd4bbb7ae0abab441e7d59aea3d0db85c GIT binary patch literal 16144 zcmeAS@N?(olHy`uVBq!ia0y~y;Lu`VV7tb_#K6Gt@lmiK0|NtRfk$L91H;TyAk6r9 z;u0kW2D?L^E{-7;bKcyJ_EU}&ado`&>ZkwAe+;41H5T;jHTrC)<n~~Fbx`$5eSL;e zKuQQWye|97pAfTt{rd3#EDQ_`32NJCujOng{~z<0Sz^jJkWqi8*fKW6KVi3f7|qDQ zz);Z>%GhB3iCO-q7f5zqVl=}8*SZJH_t_a37!G{a;bAzz|L6R4kkWvS#tb=rbr0s| zgW`8VYA(Z#nSTzP?p_a)d>~=Q-jI8e{|6t)7`~KBh8vUrY_N_8@eW*k!_Oc+Nq*b2 zZ_Eq~49_<>F}!iByD@z=KLZ29oReaV8$^F52EVgqU|=Y)>t;D%_oQ8R=NFLup>Kp3 zW>1jc_V^e`<MmB`3~wCjZgjr}S<-XBjd6p`&qU>SRtyXb27KPE2W~xSkKOSCq%q@- zC<FIo`E3uTfixy>iegyfRTnW|8?5n68RG_(pNWO<%t0FMxY-U=J!zl1^A1R(&Kn7a z?uqi#o~D5`7H>>rSmRO`F*%!;fq~)7iDir%czz~2zB2)7)IZI3K<Y{R)g2c=8sEH; zX5gM6KkbnjNMrVfB8D@5brJ2Wc^DWN)*QLUXkhv?QShB10|Ubbxo-9Yd!Dq5?l=O{ zxay4@!{kZw%bv4=HEynBIO9<_WA<xq1_p*V2iTYlWPc_mz0(6}<oD({5c8xxa_0_^ z#=JL*48jxTmp!=#ijV3|T?}WO>Spw7gEgKpV=`d<nP~J*n}LC$p_L_}=F?%Hm@p8> zyiBO!;7R_=1;L<*t4r5ql$iO)fc?4%0|UbYe>35R#FPBO1@0ipeMy##5|jTJSc!ur ztG@|1FrMUhF17|qzDsmvl<56qpcgI-(pk4nq+#I+{^lZmkYwGdMN9^KKNDT_R6%Y{ zext?EJVCzgu^Y&(HivgH88H1!)LEwtlKh;b!!UiaJli8ZkYtFCF2nUn@@@~6K)fw) zbQ#1a$+tZa1My@IzG5m6{rRwJodQT>VU9k-^a=8M&;Eg|lsU`9TwwR}p_iUKNYe6+ z0fYKvdA-NaK$3G#N--Cx{d_33P8KBjGslQw`9yiW2j@VNF-MJ<3;2FM%+ZqpNp5{( z%%DC&-tXx)kYvvRFXjT1pAT);Nr5CSa!eW8C&~Lgng^CVmc(2j^YbB(o+L<e#v3yR z_KEU*&)dL~XR4SBSbjc?SSJpW{E=h9VEOZ*!#gn$Pe;d+LHFlF4LvX~=8YwT;?IWy zd7>b>o;6ksqCXct_X3%6=JYn^2@~X#-ho2-z#APKhVzr<z4X95sW&zZ{*&a5@`OOz zyw=z<oSz^swGLG99;nK(W8j}G&-6|JB)3Y(o}quD{Jf`3AT!sT{m1-);paomJWv)q zz_-SM!Cuwg=G;|~<c)S+jtA~f+Szx4@(082jU0@3{Oc-Oyg})6gZgfP19P9W%NHku zvUXXTEYptmKOc<Ofl?iVnNq|4N%D0EVnOCS=v~V3p!(C{y)mG~!%&y5&-A11Pl5P$ zP|4I_AKA;WPs#qzTy0Rq9th8IXP7@p{@<a$AY&g?i>Wl&pX9$^XbIx(XqV-D!2I)} zcODyv`+c(-;~&4eA9J!n)*SG^IfbEaqP*QhKak`HiPJ&{q<=nC76+NzkbYx2L)?>g z{ySiu^U_n9CdmJLt_4yVu+fxp_GI~cJ3&Pq!xkOC1LvN!PZysKl50r5F&9*v<$*X1 z?3?Tut8dxbSNsK8XfcbI>&As^KM(E(2cD%);DNkvXZho5Kx)sW^fPVSlv(%T8Yr|1 z>{g3x=$HN694-gSd8=<MYw*pPF2CnJNNLPzC)PI!>;F7R1vwyrrA#ZKQu---KBzcj zc)THuG5fZveZ^Ujl@h&Yxgu_e{XA$5D!>lR&<Q`V>e_k!xB`$lZfX0OrfsRH`%nh5 z(!fqzY{R^%pPR#_K~_fI*wk=TXSV#F>ma3PjxJ(dlXCXYgQcM0NN_9DO_1b%#-0x< z&lo;$%45uq(6z6a3$k*?++Oa813^Cz?go`$2c&dj54^c{l0Pm5WKLMpd!}XEJnBA( zfvnshw_4m_z38Xra0!r=p*Qz6c>2zl-?Ja2bj?{Nwlf*;{yccf3aXIU%M22%grBqL zg9<c;-y7N(i)WhJSLA}MywU5+GvmaRp9if$iRr*Ro#X>L&rb8lMS#pHOOt0_W)NBT zVH-GJr}9YL_xX8nHK_5yke`!!;K8z!{P%)EDu2v9$|G@8=I23guw?zF*^Gy0DcDyy zgY0;qea$$*XYq6P_39wCHRs#dcrsr6d2kn;D61nbHC*hOEx%_5NV34bTFPLG<LBn> zpzOuK@XR!$4kXUN@J!Vn!Z7>^GL(U#<0L38FfcgyKvg7t0)-3%gTQ1^VZ^}DFyjwI z$B`$X*k)i*P#ZO3G%QBb1;c0_0Tm3R<;7^($uL@vfU?49ojTe$U|?VvZ5)g?4n`XX zpaPL$v~e)#8VB1~*B^Ku7aza=A16493>t6e9$9&R|7dS-G_el4#5y__F*+_Y+P46e z)1!Th(Z0oK-vX2qMhB!v2OdG`V6?e5+FTnQcm(AHhSA2sh-w`CkNXRrqis0$wruw= zb%s5k-;Yksj!sjLPT4asjE*>tF697KiKEL}7)DzKKi2Q9_RfpqX424lW}oqnJ!D6N zXHvSiRsUAE2kY~~-&?7UmKO}8<;7@u0SbZ9@`7P>Z6hclj4odoUA{27d;ydb2B<Sp zyZbl$p69>6zb^-Gg<_a-czeF{{a+1tE5KU}7%pFyYq-cWSDwcg<j5ZrjHL_~Ec|>p zu>`cf{J?IR3k`<8#<OeKL0pD^3v3w<Oa1){9x(VY;TuCw&a6KPGeB|&q@Nol6kLAN ze%J%F!oA_Kh0Li2NgvDQ5UmZlnfwPt(yAbq&b}<y5a}~ho+lDyso4`9HlLJJe+neF zg19-y9C>D({$hN(9JITIA!6P)2A}k6*TE~xH*mgXoN@8X&x0R8mLw#ei$Abr*?InU zK_1ZVjzu#28Y*>7_d~5r&EP+9B@F7%?u&8_H+84V^Q4085PNWjRVQKPp8|=qAg<53 zM(&8in>L?;SUIEb8-q^rR*01bnr|5+PHy^na07U=fYQ0h14+})^0!X}?S(p^BD1OC zYmVV{sFjJC{0An5)j@pOd|9p`G<TvrPa((-wkJ8PIyv2c3M8I_xID)Waz)%OGd>5g za>v|n3_AJKp;mIdWxR2)?B~G(&`8V!w{yV<)V7`GZx;lG!2w^HWev4Cw(p@<p3dMu z5LQ+Lu~Pi9T*KX*x$-=<AUpIP@UZ4&y#7-l0hXO}hLP*W<eT3ozjpx1PPi=Bko)%E zFYwZRzeTnT)|2JyHh}_?fy2@qv?ru)BY4HXhlL5_jAs5He4xz%4EmSl82HwM7kDTv zv1Rz9U~iM)2{P{kQ@Uz{`KQClVW7BS@GlHt`eASUk$E38$c6*$Ti6@yp^*{4$d=)c zZ{3fEr(h}TIsFWBljQBvTEXT_I4pQz|BQbB53(E}{=E!-hW8&J&YZW*mSK;7T}9JU zaGHDQ!}5Xi)8XPZpxr|aXDtO7YuX}zD&21c>ANxE8^Z_BIPm_01Ish`8Ro0o?>Vsv zWaEvlVu1s}Puj0Xf;ZO8F5qCQn6^_AVqrsTCO?Bd)WUzB)eIHAe*`wPfQ+2><PGx& zqn`^CMM0+M96QMVK>N&v8IbVQaj0hap#%w;2j;h!4_rUVZ+IHCE+!%CoHYaI&xPr( zAZ<RU64@6d&6{@u67y<{Y#CbiK=w<#WmHhJpL608$a6EAjQJe=>MW*T1qG*p1-ndx z@r<?NAHjjrz?jL;p#BjYC=I@u{0z@0%IhV~1R2kBbSK+`kWYt8*MPROG&ovZVVHAv z&fZ3dBky=rGwf)9B(ofsYK9$ce+rnrLEC8_h@CTHm_AYdT_Sk<Q_LAhwg+Bm@6JM! z*#o9q%m<D_oS9H~i}}FUC+)K%!LD9jRL8iZ^-qDlHfW300~J1fhH}Gt_D9wrE`#D* z#s_YYNZ6q8mhnN{r^609uAmJvEymmj-acvH7|{y~+W032m<*UUR|G(k%Lk^nj0plz zeH?EY6J$OeUZCR*(zo1VIRlStoy7F1ps@Ym$*0M%*l@b~1BiX^FUT>lJ%N-^!k6V3 zj;YxD91sEpVa17?EC~^x4$G_w0vTg(F@vG!OwYU?NWjS4Vm|Nz>OZ4f%m;ovX+IgU z4pgc<o8!)~Ou_!l@h*@l+nyRQ8E}8DN`kmE$F-VaMh7H3eH^M8W_15CF!Tm(bi2`F z%yFRPN&C*oy&zLQ$v7~irIhI(0>^rTY9>F!<WG?JbIjyt_&iBoEKw3vu67r`W0*1P z&jvni&|bQTHfQz&Z_a#V{Rz%}2BvQr6Br@EVj%FAF@g8f;U=9-(3Ya0b5abaC&*t* z2?d#Qx$pu*MCZ(X7LdHKY=JF<&au~^;)Ee@nJvQ__qvEVPeCOZ&$*vW37(%0|5^ju zMU@c2C(f|i=)O55_6`JWVQ*-y1eYEMc(<@OY(2>@z3~bo14DzOMKFVof8CAltDwYl z=UgLG0(;uuWsuaeqxBoZ22My;*wOKgVFUlq#NcV*ovnt?IU3fU;Qzhp6Uda)7A_2L zj@>y936$bYeg<i1pa^I3GgMEK{{Y^fWYN8u`M|a(?0tvhK}q}p3m+eY^=9TDy^y%$ ze9M?n3<(s0%W@18<bU+qgS>h`+)|&R-~|7lv+<y!>p?0XH^ZL<`49e(xU+GsW_ZvG oi941pAPt~|IEsl3fd=Eh?DPF<&t<Rm2X8s_boFyt=akR{08N<tIRF3v literal 0 HcmV?d00001 diff --git a/serialstep/board/hello.DRV8428-D11C-NEMA17.png b/serialstep/board/hello.DRV8428-D11C-NEMA17.png new file mode 100644 index 0000000000000000000000000000000000000000..bf68cd92c2cb19c62b5c346f26a51ca9eda37af0 GIT binary patch literal 84778 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%0A>U>%;1M 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 literal 0 HcmV?d00001 diff --git a/serialstep/board/hello.DRV8428-D11C-NEMA17.traces.png b/serialstep/board/hello.DRV8428-D11C-NEMA17.traces.png new file mode 100644 index 0000000000000000000000000000000000000000..505d3283c21e9e5547b59789b4347c63a6c296e1 GIT binary patch literal 23877 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 Cls-NH literal 0 HcmV?d00001 diff --git a/serialstep/serialstep-DRV8428P/board/hello.DRV8428P-D11C-NEMA17 b/serialstep/serialstep-DRV8428P/board/hello.DRV8428P-D11C-NEMA17 new file mode 100644 index 0000000..57c445d --- /dev/null +++ b/serialstep/serialstep-DRV8428P/board/hello.DRV8428P-D11C-NEMA17 @@ -0,0 +1,8371 @@ +#!/usr/bin/env python3 +# +# hello.DRV8428P-D11C-NEMA17 +# DRV8428P NEMA17 stepper hello-world with D11C interface +# +# usage: +# hello.DRV8428P-D11C-NEMA17 | frep.py [dpi [filename]] +# +# Neil Gershenfeld 8/13/21 +# Quentin Bolsee 1/17/22 +# +# This work may be reproduced, modified, distributed, +# performed, and displayed for any purpose, but must +# acknowledge this project. Copyright is retained and +# must be preserved. The work is provided as is; no +# warranty is provided, and users accept all liability. +# + +############################################################ +# uncomment for desired output +############################################################ + +#output = "top, labels, and exterior" +output = "top, labels, holes, and exterior" +#output = "top, bottom, labels, and exterior" +#output = "top, bottom, labels, holes, and exterior" +#output = "top traces" +#output = "top traces and exterior" +#output = "bottom traces reversed" +#output = "bottom traces reversed and exterior" +# output = "holes" +#output = "interior" +#output = "holes and interior" +#output = "exterior" +#output = "solder mask" + +############################################################ +# import +############################################################ + +import math,json,sys + +############################################################ +# define shapes and transformations +############################################################ + +# color(color,part) +# circle(x,y,r) +# cylinder(x,y,z0,z1,r) +# cone(x,y,z0,z1,r) +# sphere(x,y,z,r) +# torus(x,y,z,r0,r1) +# rectangle(x0,x1,y0,y1) +# cube(x0,x1,y0,y1,z0,z1) +# line(x0,y0,x1,y1,z,width) +# right_triangle(x,y,h) +# triangle(x0,y0,x1,y1,x2,y2) (points in clockwise order) +# pyramid(x0,x1,y0,y1,z0,z1) +# function(Z_of_XY) +# functions(upper_Z_of_XY,lower_Z_of_XY) +# add(part1,part2) +# subtract(part1,part2) +# intersect(part1,part2) +# move(part,dx,dy) +# translate(part,dx,dy,dz) +# rotate(part, angle) +# rotate_x(part,angle) +# rotate_y(part,angle) +# rotate_z(part,angle) +# rotate_90(part) +# rotate_180(part) +# rotate_270(part) +# reflect_x(part,x0) +# reflect_y(part,y0) +# reflect_z(part,z0) +# reflect_xy(part) +# reflect_xz(part) +# reflect_yz(part) +# scale_x(part,x0,sx) +# scale_y(part,y0,sy) +# scale_z(part,z0,sz) +# scale_xy(part,x0,y0,sxy) +# scale_xyz(part,x0,y0,z0,sxyz) +# coscale_x_y(part,x0,y0,y1,angle0,angle1,amplitude,offset) +# coscale_x_z(part,x0,z0 z1,angle0,angle1,amplitude,offset) +# coscale_xy_z(part,x0,y0,z0,z1,angle0,angle1,amplitude,offset) +# taper_x_y(part,x0,y0,y1,s0,s1) +# taper_x_z(part,x0,z0,z1,s0,s1) +# taper_xy_z(part,x0,y0,z0,z1,s0,s1) +# shear_x_y(part,y0,y1,dx0,dx1) +# shear_x_z(part,z0,z1,dx0,dx1) + +true = "1" +false = "0" + +def color(color,part): + part = '('+str(color)+'*(('+part+')!=0))' + return part + +Red = (225 << 0) +Green = (225 << 8) +Blue = (225 << 16) +Gray = (128 << 16) + (128 << 8) + (128 << 0) +White = (255 << 16) + (255 << 8) + (255 << 0) +Teal = (255 << 16) + (255 << 8) +Pink = (255 << 16) + (255 << 0) +Yellow = (255 << 8) + (255 << 0) +Brown = (45 << 16) + (82 << 8) + (145 << 0) +Navy = (128 << 16) + (0 << 8) + (0 << 0) +Tan = (60 << 16) + (90 << 8) + (125 << 0) + +def circle(x0,y0,r): + part = "(((X-(x0))*(X-(x0)) + (Y-(y0))*(Y-(y0))) <= (r*r))" + part = part.replace('x0',str(x0)) + part = part.replace('y0',str(y0)) + part = part.replace('r',str(r)) + return part + +def cylinder(x0,y0,z0,z1,r): + part = "(((X-(x0))*(X-(x0)) + (Y-(y0))*(Y-(y0)) <= (r*r)) & (Z >= (z0)) & (Z <= (z1)))" + part = part.replace('x0',str(x0)) + part = part.replace('y0',str(y0)) + part = part.replace('z0',str(z0)) + part = part.replace('z1',str(z1)) + part = part.replace('r',str(r)) + return part + +def cone(x0,y0,z0,z1,r0): + part = cylinder(x0, y0, z0, z1, r0) + part = taper_xy_z(part, x0, y0, z0, z1, 1.0, 0.0) + return part + +def sphere(x0,y0,z0,r): + part = "(((X-(x0))*(X-(x0)) + (Y-(y0))*(Y-(y0)) + (Z-(z0))*(Z-(z0))) <= (r*r))" + part = part.replace('x0',str(x0)) + part = part.replace('y0',str(y0)) + part = part.replace('z0',str(z0)) + part = part.replace('r',str(r)) + return part + +def torus(x0,y0,z0,r0,r1): + part = "(((r0 - sqrt((X-(x0))*(X-(x0)) + (Y-(y0))*(Y-(y0))))*(r0 - sqrt((X-(x0))*(X-(x0)) + (Y-(y0))*(Y-(y0))) + (Z-(z0))*(Z-(z0))) <= (r1*r1))" + part = part.replace('x0',str(x0)) + part = part.replace('y0',str(y0)) + part = part.replace('z0',str(z0)) + part = part.replace('r0',str(r0)) + part = part.replace('r1',str(r1)) + return part + +def rectangle(x0,x1,y0,y1): + part = "((X >= (x0)) & (X <= (x1)) & (Y >= (y0)) & (Y <= (y1)))" + part = part.replace('x0',str(x0)) + part = part.replace('x1',str(x1)) + part = part.replace('y0',str(y0)) + part = part.replace('y1',str(y1)) + return part + +def cube(x0,x1,y0,y1,z0,z1): + part = "((X >= (x0)) & (X <= (x1)) & (Y >= (y0)) & (Y <= (y1)) & (Z >= (z0)) & (Z <= (z1)))" + part = part.replace('x0',str(x0)) + part = part.replace('x1',str(x1)) + part = part.replace('y0',str(y0)) + part = part.replace('y1',str(y1)) + part = part.replace('z0',str(z0)) + part = part.replace('z1',str(z1)) + return part + +def line(x0,y0,x1,y1,z,width): + dx = x1-x0 + dy = y1-y0 + l = math.sqrt(dx*dx+dy*dy) + nx = dx/l + ny = dy/l + rx = -ny + ry = nx + part = "((((X-(x0))*(nx)+(Y-(y0))*(ny)) >= 0) & (((X-(x0))*(nx)+(Y-(y0))*(ny)) <= l) & (((X-(x0))*(rx)+(Y-(y0))*(ry)) >= (-width/2)) & (((X-(x0))*(rx)+(Y-(y0))*(ry)) <= (width/2)) & (Z == z))" + part = part.replace('x0',str(x0)) + part = part.replace('x1',str(x1)) + part = part.replace('y0',str(y0)) + part = part.replace('y1',str(y1)) + part = part.replace('nx',str(nx)) + part = part.replace('ny',str(ny)) + part = part.replace('rx',str(rx)) + part = part.replace('ry',str(ry)) + part = part.replace('l',str(l)) + part = part.replace('z',str(z)) + part = part.replace('width',str(width)) + return part + +def right_triangle(x0,y0,l): + part = "((X > x0) & (X < x0 + l - (Y-y0)) & (Y > y0))" + part = part.replace('x0',str(x0)) + part = part.replace('y0',str(y0)) + part = part.replace('l',str(l)) + return part + +def triangle(x0,y0,x1,y1,x2,y2): # points in clockwise order + part = "(((((y1)-(y0))*(X-(x0))-((x1)-(x0))*(Y-(y0))) >= 0) & ((((y2)-(y1))*(X-(x1))-((x2)-(x1))*(Y-(y1))) >= 0) & ((((y0)-(y2))*(X-(x2))-((x0)-(x2))*(Y-(y2))) >= 0))" + part = part.replace('x0',str(x0)) + part = part.replace('y0',str(y0)) + part = part.replace('x1',str(x1)) + part = part.replace('y1',str(y1)) + part = part.replace('x2',str(x2)) + part = part.replace('y2',str(y2)) + return part + +def pyramid(x0,x1,y0,y1,z0,z1): + part = cube(x0, x1, y0, y1, z0, z1) + part = taper_xy_z(part, (x0+x1)/2., (y0+y1)/2., z0, z1, 1.0, 0.0) + return part + +def function(Z_of_XY): + part = '(Z <= '+Z_of_XY+')' + return part + +def functions(upper_Z_of_XY,lower_Z_of_XY): + part = '(Z <= '+upper_Z_of_XY+') & (Z >= '+lower_Z_of_XY+')' + return part + +def add(part1,part2): + part = "part1 | part2" + part = part.replace('part1',part1) + part = part.replace('part2',part2) + return part + +def subtract(part1,part2): + part = "(part1) & ~(part2)" + part = part.replace('part1',part1) + part = part.replace('part2',part2) + return part + +def intersect(part1,part2): + part = "(part1) & (part2)" + part = part.replace('part1',part1) + part = part.replace('part2',part2) + return part + +def move(part,dx,dy): + part = part.replace('X','(X-('+str(dx)+'))') + part = part.replace('Y','(Y-('+str(dy)+'))') + return part + +def translate(part,dx,dy,dz): + part = part.replace('X','(X-('+str(dx)+'))') + part = part.replace('Y','(Y-('+str(dy)+'))') + part = part.replace('Z','(Z-('+str(dz)+'))') + return part + +def rotate(part,angle): + angle = angle*math.pi/180 + part = part.replace('X','(math.cos(angle)*X+math.sin(angle)*y)') + part = part.replace('Y','(-math.sin(angle)*X+math.cos(angle)*y)') + part = part.replace('y','Y') + part = part.replace('angle',str(angle)) + return part + +def rotate_x(part,angle): + angle = angle*math.pi/180 + part = part.replace('Y','(math.cos(angle)*Y+math.sin(angle)*z)') + part = part.replace('Z','(-math.sin(angle)*Y+math.cos(angle)*z)') + part = part.replace('z','Z') + part = part.replace('angle',str(angle)) + return part + +def rotate_y(part,angle): + angle = angle*math.pi/180 + part = part.replace('X','(math.cos(angle)*X+math.sin(angle)*z)') + part = part.replace('Z','(-math.sin(angle)*X+math.cos(angle)*z)') + part = part.replace('z','Z') + part = part.replace('angle',str(angle)) + return part + +def rotate_z(part,angle): + angle = angle*math.pi/180 + part = part.replace('X','(math.cos(angle)*X+math.sin(angle)*y)') + part = part.replace('Y','(-math.sin(angle)*X+math.cos(angle)*y)') + part = part.replace('y','Y') + part = part.replace('angle',str(angle)) + return part + +def rotate_90(part): + part = reflect_y(part,0) + part = reflect_xy(part) + return part + +def rotate_180(part): + part = rotate_90(part) + part = rotate_90(part) + return part + +def rotate_270(part): + part = rotate_90(part) + part = rotate_90(part) + part = rotate_90(part) + return part + +def reflect_x(part,x0): + part = part.replace('X','(x0-X)') + part = part.replace('x0',str(x0)) + return part + +def reflect_y(part,y0): + part = part.replace('Y','(y0-Y)') + part = part.replace('y0',str(y0)) + return part + +def reflect_z(part,z0): + part = part.replace('Z','(z0-Z)') + part = part.replace('z0',str(z0)) + return part + +def reflect_xy(part): + part = part.replace('X','temp') + part = part.replace('Y','X') + part = part.replace('temp','Y') + return part + +def reflect_xz(part): + part = part.replace('X','temp') + part = part.replace('Z','X') + part = part.replace('temp','Z') + return part + +def reflect_yz(part): + part = part.replace('Y','temp') + part = part.replace('Z','Y') + part = part.replace('temp','Z') + return part + +def scale_x(part,x0,sx): + part = part.replace('X','((x0) + (X-(x0))/(sx))') + part = part.replace('x0',str(x0)) + part = part.replace('sx',str(sx)) + return part + +def scale_y(part,y0,sy): + part = part.replace('Y','((y0) + (Y-(y0))/(sy))') + part = part.replace('y0',str(y0)) + part = part.replace('sy',str(sy)) + return part + +def scale_z(part,z0,sz): + part = part.replace('Z','((z0) + (Z-(z0))/(sz))') + part = part.replace('z0',str(z0)) + part = part.replace('sz',str(sz)) + return part + +def scale_xy(part,x0,y0,sxy): + part = part.replace('X','((x0) + (X-(x0))/(sxy))') + part = part.replace('Y','((y0) + (Y-(y0))/(sxy))') + part = part.replace('x0',str(x0)) + part = part.replace('y0',str(y0)) + part = part.replace('sxy',str(sxy)) + return part + +def scale_xyz(part,x0,y0,z0,sxyz): + part = part.replace('X','((x0) + (X-(x0))/(sxyz))') + part = part.replace('Y','((y0) + (Y-(y0))/(sxyz))') + part = part.replace('Z','((z0) + (Z-(z0))/(sxyz))') + part = part.replace('x0',str(x0)) + part = part.replace('y0',str(y0)) + part = part.replace('z0',str(z0)) + part = part.replace('sxyz',str(sxyz)) + return part + +def coscale_x_y(part,x0,y0,y1,angle0,angle1,amplitude,offset): + phase0 = math.pi*angle0/180. + phase1 = math.pi*angle1/180. + part = part.replace('X','((x0) + (X-(x0))/((offset) + (amplitude)*math.cos((phase0) + ((phase1)-(phase0))*(Y-(y0))/((y1)-(y0)))))') + part = part.replace('x0',str(x0)) + part = part.replace('y0',str(y0)) + part = part.replace('y1',str(y1)) + part = part.replace('phase0',str(phase0)) + part = part.replace('phase1',str(phase1)) + part = part.replace('amplitude',str(amplitude)) + part = part.replace('offset',str(offset)) + return part + +def coscale_x_z(part,x0,z0,z1,angle0,angle1,amplitude,offset): + phase0 = math.pi*angle0/180. + phase1 = math.pi*angle1/180. + part = part.replace('X','((x0) + (X-(x0))/((offset) + (amplitude)*math.cos((phase0) + ((phase1)-(phase0))*(Z-(z0))/((z1)-(z0)))))') + part = part.replace('x0',str(x0)) + part = part.replace('z0',str(z0)) + part = part.replace('z1',str(z1)) + part = part.replace('phase0',str(phase0)) + part = part.replace('phase1',str(phase1)) + part = part.replace('amplitude',str(amplitude)) + part = part.replace('offset',str(offset)) + return part + +def coscale_xy_z(part,x0,y0,z0,z1,angle0,angle1,amplitude,offset): + phase0 = math.pi*angle0/180. + phase1 = math.pi*angle1/180. + part = part.replace('X','((x0) + (X-(x0))/((offset) + (amplitude)*math.cos((phase0) + ((phase1)-(phase0))*(Z-(z0))/((z1)-(z0)))))') + part = part.replace('Y','((y0) + (Y-(y0))/((offset) + (amplitude)*math.cos((phase0) + ((phase1)-(phase0))*(Z-(z0))/((z1)-(z0)))))') + part = part.replace('x0',str(x0)) + part = part.replace('y0',str(y0)) + part = part.replace('z0',str(z0)) + part = part.replace('z1',str(z1)) + part = part.replace('phase0',str(phase0)) + part = part.replace('phase1',str(phase1)) + part = part.replace('amplitude',str(amplitude)) + part = part.replace('offset',str(offset)) + return part + +def taper_x_y(part,x0,y0,y1,s0,s1): + part = part.replace('X','((x0) + (X-(x0))*((y1)-(y0))/((s1)*(Y-(y0)) + (s0)*((y1)-Y)))') + part = part.replace('x0',str(x0)) + part = part.replace('y0',str(y0)) + part = part.replace('y1',str(y1)) + part = part.replace('s0',str(s0)) + part = part.replace('s1',str(s1)) + return part + +def taper_x_z(part,x0,z0,z1,s0,s1): + part = part.replace('X','((x0) + (X-(x0))*((z1)-(z0))/((s1)*(Z-(z0)) + (s0)*((z1)-Z)))') + part = part.replace('x0',str(x0)) + part = part.replace('z0',str(z0)) + part = part.replace('z1',str(z1)) + part = part.replace('s0',str(s0)) + part = part.replace('s1',str(s1)) + return part + +def taper_xy_z(part,x0,y0,z0,z1,s0,s1): + part = part.replace('X','((x0) + (X-(x0))*((z1)-(z0))/((s1)*(Z-(z0)) + (s0)*((z1)-Z)))') + part = part.replace('Y','((y0) + (Y-(y0))*((z1)-(z0))/((s1)*(Z-(z0)) + (s0)*((z1)-Z)))') + part = part.replace('x0',str(x0)) + part = part.replace('y0',str(y0)) + part = part.replace('z0',str(z0)) + part = part.replace('z1',str(z1)) + part = part.replace('s0',str(s0)) + part = part.replace('s1',str(s1)) + return part + +def shear_x_y(part,y0,y1,dx0,dx1): + part = part.replace('X','(X - (dx0) - ((dx1)-(dx0))*(Y-(y0))/((y1)-(y0)))') + part = part.replace('y0',str(y0)) + part = part.replace('y1',str(y1)) + part = part.replace('dx0',str(dx0)) + part = part.replace('dx1',str(dx1)) + return part + +def shear_x_z(part,z0,z1,dx0,dx1): + part = part.replace('X','(X - (dx0) - ((dx1)-(dx0))*(Z-(z0))/((z1)-(z0)))') + part = part.replace('z0',str(z0)) + part = part.replace('z1',str(z1)) + part = part.replace('dx0',str(dx0)) + part = part.replace('dx1',str(dx1)) + return part + +def coshear_x_z(part,z0,z1,angle0,angle1,amplitude,offset): + phase0 = math.pi*angle0/180. + phase1 = math.pi*angle1/180. + part = part.replace('X','(X - (offset) - (amplitude)*math.cos((phase0) + ((phase1)-(phase0))*(Z-(z0))/((z1)-(z0))))') + part = part.replace('z0',str(z0)) + part = part.replace('z1',str(z1)) + part = part.replace('phase0',str(phase0)) + part = part.replace('phase1',str(phase1)) + part = part.replace('amplitude',str(amplitude)) + part = part.replace('offset',str(offset)) + return part + +############################################################ +# text classes and definitions +############################################################ + +class text: + # + # text class + # + def __init__(self,text,x,y,z=0,line='',height='',width='',space='',align='CC',color=White,angle=0): + # + # parameters + # + if (line == ''): + line = 1 + if (height == ''): + height = 6*line + if (width == ''): + width = 4*line + if (space == ''): + space = line/2.0 + self.width = 0 + self.height = 0 + self.text = text + # + # construct shape dictionary + # + shapes = {} + shape = triangle(0,0,width/2.0,height,width,0) + cutout = triangle(0,-2.5*line,width/2.0,height-2.5*line,width,-2.5*line) + cutout = subtract(cutout,rectangle(0,width,height/4-line/2,height/4+line/2)) + shape = subtract(shape,cutout) + shapes['A'] = shape + shape = circle(width/2,width/2,width/2) + shape = subtract(shape,circle(width/2,width/2,width/4)) + shape = add(shape,rectangle(width-line,width,0,height/3)) + shapes['a'] = shape + shape = rectangle(0,width-height/4,0,height) + shape = add(shape,circle(width-height/4,height/4,height/4)) + shape = add(shape,circle(width-height/4,3*height/4,height/4)) + w = height/2-1.5*line + shape = subtract(shape,rectangle(line,line+w/1.5,height/2+line/2,height-line)) + shape = subtract(shape,circle(line+w/1.5,height/2+line/2+w/2,w/2)) + shape = subtract(shape,rectangle(line,line+w/1.5,line,height/2-line/2)) + shape = subtract(shape,circle(line+w/1.5,height/2-line/2-w/2,w/2)) + shapes['B'] = shape + shape = circle(width/2,width/2,width/2) + shape = subtract(shape,circle(width/2,width/2,width/4)) + shape = add(shape,rectangle(0,line,0,height)) + shapes['b'] = shape + shape = circle(width/2,width/2,width/2) + shape = add(shape,circle(width/2,height-width/2,width/2)) + shape = add(shape,rectangle(0,width,line+w/2,height-line-w/2)) + w = width-2*line + shape = subtract(shape,circle(width/2,line+w/2,w/2)) + shape = subtract(shape,circle(width/2,height-line-w/2,w/2)) + shape = subtract(shape,rectangle(line,width,line+w/2,height-line-w/2)) + shapes['C'] = shape + shape = circle(width/2,width/2,width/2) + shape = subtract(shape,circle(width/2,width/2,width/4)) + shape = subtract(shape,rectangle(width/2,width,width/2-line/1.5,width/2+line/1.5)) + shapes['c'] = shape + shape = circle(line,width-line,width-line) + shape = subtract(shape,circle(line,width-line,width-2*line)) + shape = subtract(shape,rectangle(-width,line,0,height)) + shape = scale_y(shape,0,height/(2*(width-line))) + shape = add(shape,rectangle(0,line,0,height)) + shapes['D'] = shape + shape = rectangle(width-line,width,0,height) + shape = add(shape,circle(width/2,width/2,width/2)) + shape = subtract(shape,circle(width/2,width/2,width/2-line)) + shapes['d'] = shape + shape = rectangle(0,line,0,height) + shape = add(shape,rectangle(0,width,height-line,height)) + shape = add(shape,rectangle(0,2*width/3,height/2-line/2,height/2+line/2)) + shape = add(shape,rectangle(0,width,0,line)) + shapes['E'] = shape + shape = circle(width/2,width/2,width/2) + shape = subtract(shape,circle(width/2,width/2,width/2-line)) + shape = subtract(shape,triangle(width,0,width/2,width/2-line/2,width,width/2-line/2)) + shape = add(shape,rectangle(0,width,width/2-line/2,width/2+line/2)) + shapes['e'] = shape + shape = rectangle(0,line,0,height) + shape = add(shape,rectangle(0,width,height-line,height)) + shape = add(shape,rectangle(0,2*width/3,height/2-line/2,height/2+line/2)) + shapes['F'] = shape + shape = circle(width-line/2,height-width/2,width/2) + shape = subtract(shape,circle(width-line/2,height-width/2,width/2-line)) + shape = subtract(shape,rectangle(0,width-line/2,0,height-width/2)) + shape = subtract(shape,rectangle(width-line/2,2*width,0,height)) + shape = add(shape,rectangle(width/2-line/2,width/2+line/2,0,height-width/2)) + shape = add(shape,rectangle(width/5,4*width/5,height/2-line/2,height/2+line/2)) + shapes['f'] = shape + shape = circle(width/2,width/2,width/2) + shape = add(shape,circle(width/2,height-width/2,width/2)) + shape = add(shape,rectangle(0,width,line+w/2,height-line-w/2)) + w = width-2*line + shape = subtract(shape,circle(width/2,line+w/2,w/2)) + shape = subtract(shape,circle(width/2,height-line-w/2,w/2)) + shape = subtract(shape,rectangle(line,width,line+w/2,height-line-w/2)) + shape = add(shape,rectangle(width/2,width,line+w/2,2*line+w/2)) + shapes['G'] = shape + shape = circle(width/2,width/2,width/2) + shape = subtract(shape,circle(width/2,width/2,width/2-line)) + w = height/3-width/2 + shape = add(shape,rectangle(width-line,width,w,width)) + shape = add(shape,subtract(subtract(circle(width/2,w,width/2),circle(width/2,w,width/2-line)),rectangle(0,width,w,height))) + shapes['g'] = shape + shape = rectangle(0,line,0,height) + shape = add(shape,rectangle(width-line,width,0,height)) + shape = add(shape,rectangle(0,width,height/2-line/2,height/2+line/2)) + shapes['H'] = shape + w = width/2 + shape = circle(width/2,w,width/2) + shape = subtract(shape,circle(width/2,w,width/2-line)) + shape = subtract(shape,rectangle(0,width,0,w)) + shape = add(shape,rectangle(0,line,0,height)) + shape = add(shape,rectangle(width-line,width,0,w)) + shapes['h'] = shape + shape = rectangle(width/2-line/2,width/2+line/2,0,height) + shape = add(shape,rectangle(width/5,4*width/5,0,line)) + shape = add(shape,rectangle(width/5,4*width/5,height-line,height)) + shapes['I'] = shape + shape = rectangle(width/2-line/2,width/2+line/2,0,height/2) + shape = add(shape,circle(width/2,3*height/4,.6*line)) + shapes['i'] = shape + shape = circle(width/2,width/2,width/2) + shape = subtract(shape,circle(width/2,width/2,width/2-line)) + shape = subtract(shape,rectangle(0,width,width/2,height)) + shape = add(shape,rectangle(width-line,width,width/2,height)) + shapes['J'] = shape + w = height/3-width/2 + shape = rectangle(width/2-line/2,width/2+line/2,w,height/2) + shape = add(shape,subtract(subtract(subtract(circle(width/4-line/2,w,width/2),circle(width/4-line/2,w,width/2-line)),rectangle(0,width,w,height)),rectangle(-width,width/4-line/2,-height/3,height))) + shape = add(shape,circle(width/2,3*height/4,.6*line)) + shapes['j'] = shape + shape = rectangle(0,width,0,height) + shape = subtract(shape,triangle(line,height,width-1.1*line,height,line,height/2+.5*line)) + shape = subtract(shape,triangle(width,0,line+0.8*line,height/2,width,height)) + shape = subtract(shape,triangle(line,0,line,height/2-.5*line,width-1.1*line,0)) + shapes['K'] = shape + shape = rectangle(0,width,0,height) + shape = subtract(shape,rectangle(line,width,2*height/3,height)) + shape = subtract(shape,triangle(line,2*height/3,width-1.3*line,2*height/3,line,height/3+.5*line)) + shape = subtract(shape,triangle(width,0,line+0.8*line,height/3,width,2*height/3)) + shape = subtract(shape,triangle(line,0,line,height/3-0.5*line,width-1.3*line,0)) + shapes['k'] = shape + shape = rectangle(0,line,0,height) + shape = add(shape,rectangle(0,width,0,line)) + shapes['L'] = shape + shape = rectangle(width/2-line/2,width/2+line/2,0,height) + shapes['l'] = shape + shape = rectangle(0,width,0,height) + shape = subtract(shape,triangle(line,0,line,height-3*line,width/2-line/3,0)) + shape = subtract(shape,triangle(line,height,width-line,height,width/2,1.5*line)) + shape = subtract(shape,triangle(width/2+line/3,0,width-line,height-3*line,width-line,0)) + shapes['M'] = shape + w = width/2 + l = 1.3*line + shape = circle(width/2,w,width/2) + shape = subtract(shape,circle(width/2,w,width/2-l)) + shape = subtract(shape,rectangle(0,width,0,w)) + shape = add(shape,rectangle(width-l,width,0,w)) + shape = add(shape,move(shape,width-l,0)) + shape = add(shape,rectangle(0,l,0,width)) + shape = scale_x(shape,0,width/(2*width-l)) + shapes['m'] = shape + shape = rectangle(0,width,0,height) + shape = subtract(shape,triangle(line,height+1.5*line,width-line,height+1.5*line,width-line,1.5*line)) + shape = subtract(shape,triangle(line,-1.5*line,line,height-1.5*line,width-line,-1.5*line)) + shapes['N'] = shape + w = width/2 + shape = circle(width/2,w,width/2) + shape = subtract(shape,circle(width/2,w,width/2-line)) + shape = subtract(shape,rectangle(0,width,0,w)) + shape = add(shape,rectangle(0,line,0,width)) + shape = add(shape,rectangle(width-line,width,0,w)) + shapes['n'] = shape + shape = circle(width/2,width/2,width/2) + shape = add(shape,circle(width/2,height-width/2,width/2)) + shape = add(shape,rectangle(0,width,line+w/2,height-line-w/2)) + w = width-2*line + shape = subtract(shape,circle(width/2,line+w/2,w/2)) + shape = subtract(shape,circle(width/2,height-line-w/2,w/2)) + shape = subtract(shape,rectangle(line,width-line,line+w/2,height-line-w/2)) + shapes['O'] = shape + shape = circle(width/2,width/2,width/2) + shape = subtract(shape,circle(width/2,width/2,width/2-line)) + shapes['o'] = shape + shape = rectangle(0,line,0,height) + w = 2*height/3 + shape = add(shape,circle(width-w/2,height-w/2,w/2)) + shape = add(shape,rectangle(0,width-w/2,height-w,height)) + shape = subtract(shape,circle(width-w/2,height-w/2,w/2-line)) + shape = subtract(shape,rectangle(line,width-w/2,height-w+line,height-line)) + shapes['P'] = shape + shape = circle(width/2,width/2,width/2) + shape = subtract(shape,circle(width/2,width/2,width/4)) + shape = add(shape,rectangle(0,line,-height/3,width)) + shapes['p'] = shape + shape = subtract(circle(width/2,width/2,width/2),circle(width/2,width/2,width/2-.9*line)) + shape = scale_y(shape,0,height/width) + shape = add(shape,move(rotate(rectangle(-line/2,line/2,-width/4,width/4),30),3*width/4,width/4)) + shapes['Q'] = shape + shape = circle(width/2,width/2,width/2) + shape = subtract(shape,circle(width/2,width/2,width/2-line)) + shape = add(shape,rectangle(width-line,width,-height/3,width)) + shapes['q'] = shape + shape = rectangle(0,line,0,height) + w = 2*height/3 + shape = add(shape,circle(width-w/2,height-w/2,w/2)) + shape = add(shape,rectangle(0,width-w/2,height-w,height)) + shape = subtract(shape,circle(width-w/2,height-w/2,w/2-line)) + shape = subtract(shape,rectangle(line,width-w/2,height-w+line,height-line)) + leg = triangle(line,0,line,height,width,0) + leg = subtract(leg,triangle(line,-2.0*line,line,height-2.0*line,width,-2.0*line)) + leg = subtract(leg,rectangle(0,width,height/3,height)) + shape = add(shape,leg) + shapes['R'] = shape + shape = circle(width,0,width) + shape = subtract(shape,circle(width,0,width-line)) + shape = subtract(shape,rectangle(.8*width,2*width,-height,height)) + shape = subtract(shape,rectangle(0,2*width,-height,0)) + shape = add(shape,rectangle(0,line,0,width)) + shapes['r'] = shape + shape = circle(width/2,width/2,width/2) + shape = subtract(shape,circle(width/2,width/2,width/2-line)) + shape = subtract(shape,rectangle(0,width/2,width/2,width)) + shape = add(shape,move(reflect_y(reflect_x(shape,width),width),0,width-line)) + shape = scale_y(shape,0,height/(2*width-line)) + shapes['S'] = shape + w = width/3 + shape = circle(w,w,w) + shape = subtract(shape,circle(w,w,w-.9*line)) + shape = subtract(shape,rectangle(0,w,w,2*w)) + shape = add(shape,move(reflect_y(reflect_x(shape,2*w),2*w),0,2*w-.9*line)) + shape = scale_y(shape,0,(2*height/3)/(4*w-.9*line)) + shape = move(shape,(width/2)-w,0) + shapes['s'] = shape + shape = rectangle(width/2-line/2,width/2+line/2,0,height) + shape = add(shape,rectangle(0,width,height-line,height)) + shapes['T'] = shape + shape = circle(0,3*width/8,3*width/8) + shape = subtract(shape,circle(0,3*width/8,3*width/8-line)) + shape = subtract(shape,rectangle(-width,width,3*width/8,height)) + shape = subtract(shape,rectangle(0,width,-height,height)) + shape = move(shape,width/2-line/2+3*width/8,0) + shape = add(shape,rectangle(width/2-line/2,width/2+line/2,width/4,3*height/4)) + shape = add(shape,rectangle(width/5,4*width/5,height/2-line/2,height/2+line/2)) + shapes['t'] = shape + shape = circle(width/2,width/2,width/2) + shape = subtract(shape,circle(width/2,width/2,width/2-line)) + shape = subtract(shape,rectangle(0,width,width/2,height)) + shape = add(shape,rectangle(0,line,width/2,height)) + shape = add(shape,rectangle(width-line,width,width/2,height)) + shapes['U'] = shape + shape = circle(width/2,width/2,width/2) + shape = subtract(shape,circle(width/2,width/2,width/2-line)) + shape = subtract(shape,rectangle(0,width,width/2,height)) + shape = add(shape,rectangle(0,line,width/2,2*height/3)) + shape = add(shape,rectangle(width-line,width,0,2*height/3)) + shapes['u'] = shape + shape = triangle(0,height,width,height,width/2,0) + shape = subtract(shape,triangle(0,height+3*line,width,height+3*line,width/2,3*line)) + shapes['V'] = shape + w = 2*height/3.0 + shape = triangle(0,w,width,w,width/2,0) + shape = subtract(shape,triangle(0,w+2*line,width,w+2*line,width/2,2*line)) + shapes['v'] = shape + shape = triangle(0,height,width,height,width/2,0) + shape = add(shape,move(shape,.6*width,0)) + cutout = triangle(0,height+4*line,width,height+4*line,width/2,4*line) + cutout = add(cutout,move(cutout,.6*width,0)) + shape = subtract(shape,cutout) + shape = scale_x(shape,0,1/1.6) + shapes['W'] = shape + shape = scale_y(shapes['W'],0,width/height) + shapes['w'] = shape + shape = rectangle(0,width,0,height) + shape = subtract(shape,triangle(0,0,0,height,width/2-.7*line,height/2)) + shape = subtract(shape,triangle(width,0,width/2+.7*line,height/2,width,height)) + shape = subtract(shape,triangle(1.1*line,height,width-1.1*line,height,width/2,height/2+line)) + shape = subtract(shape,triangle(1.1*line,0,width/2,height/2-line,width-1.1*line,0)) + shapes['X'] = shape + w = 2*height/3.0 + shape = rectangle(0,width,0,w) + shape = subtract(shape,triangle(0,0,0,w,width/2-.75*line,w/2)) + shape = subtract(shape,triangle(width,0,width/2+.75*line,w/2,width,w)) + shape = subtract(shape,triangle(1.25*line,0,width/2,w/2-.75*line,width-1.25*line,0)) + shape = subtract(shape,triangle(1.25*line,w,width-1.25*line,w,width/2,w/2+.75*line)) + shapes['x'] = shape + w = height/2 + shape = rectangle(0,width,w,height) + shape = subtract(shape,triangle(0,w,0,height,width/2-line/2,w)) + shape = subtract(shape,triangle(width/2+line/2,w,width,height,width,w)) + shape = subtract(shape,triangle(1.1*line,height,width-1.1*line,height,width/2,w+1.1*line)) + shape = add(shape,rectangle(width/2-line/2,width/2+line/2,0,w)) + shapes['Y'] = shape + shape = rectangle(0,width,-height/3,width) + shape = subtract(shape,triangle(0,-height/3,0,width,width/2-.9*line,0)) + shape = subtract(shape,triangle(1.1*line,width,width-1.1*line,width,width/2-.2*line,1.6*line)) + shape = subtract(shape,triangle(1.2*line,-height/3,width,width,width,-height/3)) + shapes['y'] = shape + shape = rectangle(0,width,0,height) + shape = subtract(shape,triangle(0,line,0,height-line,width-1.4*line,height-line)) + shape = subtract(shape,triangle(1.4*line,line,width,height-line,width,line)) + shapes['Z'] = shape + w = 2*height/3 + shape = rectangle(0,width,0,w) + shape = subtract(shape,triangle(0,line,0,w-line,width-1.6*line,w-line)) + shape = subtract(shape,triangle(width,line,1.6*line,line,width,w-line)) + shapes['z'] = shape + shape = circle(width/2,width/2,width/2) + shape = subtract(shape,circle(width/2,width/2,width/2-.9*line)) + shape = scale_y(shape,0,height/width) + shapes['0'] = shape + shape = rectangle(width/2-line/2,width/2+line/2,0,height) + w = width/2-line/2 + cutout = circle(0,height,w) + shape = add(shape,rectangle(0,width/2,height-w-line,height)) + shape = subtract(shape,cutout) + shape = move(shape,(width/2+line/2)/4,0) + shapes['1'] = shape + shape = circle(width/2,height-width/2,width/2) + shape = subtract(shape,circle(width/2,height-width/2,width/2-line)) + shape = subtract(shape,rectangle(0,width/2,0,height-width/2)) + shape = add(shape,rectangle(0,width,0,height-width/2)) + shape = subtract(shape,triangle(0,line,0,height-width/2,width-line,height-width/2)) + shape = subtract(shape,triangle(1.5*line,line,width,height-width/2-.5*line,width,line)) + shapes['2'] = shape + shape = circle(width/2,width/2,width/2) + shape = subtract(shape,circle(width/2,width/2,width/2-line)) + shape = scale_y(shape,0,(height/2+line/2)/width) + shape = add(shape,move(shape,0,height/2-line/2)) + shape = subtract(shape,rectangle(0,width/2,height/4,3*height/4)) + shapes['3'] = shape + shape = rectangle(width-line,width,0,height) + shape = add(shape,triangle(0,height/3,width-line,height,width-line,height/3)) + shape = subtract(shape,triangle(1.75*line,height/3+line,width-line,height-1.5*line,width-line,height/3+line)) + shapes['4'] = shape + shape = circle(width/2,width/2,width/2) + shape = subtract(shape,circle(width/2,width/2,width/2-line)) + shape = subtract(shape,rectangle(0,width/2,width/2,width)) + shape = add(shape,rectangle(0,width/2,width-line,width)) + shape = add(shape,rectangle(0,line,width-line,height)) + shape = add(shape,rectangle(0,width,height-line,height)) + shapes['5'] = shape + shape = circle(width/2,height-width/2,width/2) + shape = subtract(shape,circle(width/2,height-width/2,width/2-line)) + shape = subtract(shape,rectangle(0,width,0,height-width/2)) + shape = subtract(shape,triangle(width,height,width,height/2,width/2,height/2)) + shape = add(shape,circle(width/2,width/2,width/2)) + shape = subtract(shape,circle(width/2,width/2,width/2-line)) + shape = add(shape,rectangle(0,line,width/2,height-width/2)) + shapes['6'] = shape + shape = rectangle(0,width,0,height) + shape = subtract(shape,triangle(0,0,0,height-line,width-line,height-line)) + shape = subtract(shape,triangle(line,0,width,height-line,width,0)) + shapes['7'] = shape + shape = circle(width/2,width/2,width/2) + shape = subtract(shape,circle(width/2,width/2,width/2-line)) + shape = scale_y(shape,0,(height/2+line/2)/width) + shape = add(shape,move(shape,0,height/2-line/2)) + shapes['8'] = shape + shape = circle(width/2,width/2,width/2) + shape = subtract(shape,circle(width/2,width/2,width/2-line)) + shape = subtract(shape,rectangle(0,width,width/2,height)) + shape = subtract(shape,triangle(0,0,0,height/2,width/2,height/2)) + shape = add(shape,circle(width/2,height-width/2,width/2)) + shape = subtract(shape,circle(width/2,height-width/2,width/2-line)) + shape = add(shape,rectangle(width-line,width,width/2,height-width/2)) + shapes['9'] = shape + w = width/2 + shape = circle(w,w,w) + shape = subtract(shape,circle(w,w,w-line)) + shape = subtract(shape,rectangle(w,width,0,height)) + shape = scale_y(shape,0,height/width) + shape = move(shape,w/2,0) + shapes['('] = shape + shape = reflect_x(shape,width) + shapes[')'] = shape + shapes[' '] = false + shape = rectangle(width/2-width/3,width/2+width/3,height/2-line/2,height/2+line/2) + shape = add(shape,rectangle(width/2-line/2,width/2+line/2,height/2-width/3,height/2+width/3)) + shapes['+'] = shape + shape = rectangle(width/2-width/3,width/2+width/3,height/2-line/2,height/2+line/2) + shapes['-'] = shape + shape = circle(width/2,line,.75*line) + shapes['.'] = shape + shape = rectangle(0,width,0,height) + d = .8*line + shape = subtract(shape,triangle(d,0,width,height-d,width,0)) + shape = subtract(shape,triangle(0,d,0,height,width-d,height)) + shapes['/'] = shape + # + # to be done + # + shapes['*'] = shape + shapes['~'] = shape + shapes['!'] = shape + shapes['@'] = shape + shapes['#'] = shape + shapes['$'] = shape + shapes['%'] = shape + shapes['^'] = shape + shapes['&'] = shape + shapes['&'] = shape + shapes['_'] = shape + shapes['='] = shape + shapes['['] = shape + shapes['{'] = shape + shapes[']'] = shape + shapes['}'] = shape + shapes[';'] = shape + shapes[':'] = shape + shapes["'"] = shape + shapes['"'] = shape + shapes[','] = shape + shapes['<'] = shape + shapes['>'] = shape + shapes['?'] = shape + # + # add a line to text shape + # + def addline(lineshape): + # + # LR align + # + if (align[0] == 'C'): + lineshape = move(lineshape,-self.width/2.0,0) + elif (align[0] == 'R'): + lineshape = move(lineshape,-self.width,0) + # + # add + # + self.shape = add(self.shape,lineshape) + # + # loop over chars + # + dx = 0 + dy = -height + self.width = -space + self.height = height + lineshape = false + self.shape = false + count = 0 + for chr in text: + if (chr == '\n'): + count += 1 + addline(lineshape) + dx = 0 + dy -= 1.5*self.height/(1+(count-1)*1.5) + self.width = -space + self.height += 1.5*self.height + lineshape = false + else: + lineshape = add(lineshape,move(shapes[chr],dx,dy)) + self.width += space + width + dx += width + space + addline(lineshape) + # + # UD align + # + if (align[1] == 'C'): + self.shape = move(self.shape,0,self.height/2.0) + elif (align[1] == 'B'): + self.shape = move(self.shape,0,self.height) + # + # rotate + # + if (angle == 90): + self.shape = rotate_90(self.shape) + elif (angle == 180): + self.shape = rotate_180(self.shape) + elif ((angle == 270) | (angle == -90)): + self.shape = rotate_270(self.shape) + elif (angle != 0): + self.shape = rotate(self.shape,angle) + # + # translate + # + self.shape = move(self.shape,x,y) + # + # color + # + self.shape = '('+str(color)+'*(('+self.shape+')!=0))' + +############################################################ +# PCB classes and definitions +############################################################ + +class PCB: + def __init__(self,x0,y0,width,height,mask): + self.board = false + self.labels = false + self.interior = rectangle(x0,x0+width,y0,y0+height) + self.exterior = subtract(true,rectangle(x0,x0+width,y0,y0+height)) + self.mask = false + self.holes = false + self.cutout = false + def add(self,part): + self.board = add(self.board,part) + self.mask = add(self.mask,move(part,-mask,mask)) + self.mask = add(self.mask,move(part,-mask,-mask)) + self.mask = add(self.mask,move(part,mask,mask)) + self.mask = add(self.mask,move(part,mask,-mask)) + return self + +class point: + def __init__(self,x,y,z=0): + self.x = x + self.y = y + self.z = z + +class part: + class text: + def __init__(self,x,y,z=0,text='',line=0.006,angle=0): + self.x = x + self.y = y + self.z = z + self.text = text + self.line = line + self.angle = angle + def add(self,pcb,x,y,z=0,angle=0,line=0.007): + self.x = x + self.y = y + self.z = z + self.angle = angle + if (angle == 90): + self.shape = rotate_90(self.shape) + elif (angle == 180): + self.shape = rotate_180(self.shape) + elif ((angle == 270) | (angle == -90)): + self.shape = rotate_270(self.shape) + elif (angle != 0): + self.shape = rotate(self.shape,angle) + self.shape = translate(self.shape,x,y,z) + if hasattr(self,'holes'): + if (angle == 90): + self.holes = rotate_90(self.holes) + elif (angle == 180): + self.holes = rotate_180(self.holes) + elif ((angle == 270) | (angle == -90)): + self.holes = rotate_270(self.holes) + elif (angle != 0): + self.holes = rotate(self.holes,angle) + self.holes = translate(self.holes,x,y,z) + if hasattr(self,'cutout'): + if (angle == 90): + self.cutout = rotate_90(self.cutout) + elif (angle == 180): + self.cutout = rotate_180(self.cutout) + elif ((angle == 270) | (angle == -90)): + self.cutout = rotate_270(self.cutout) + elif (angle != 0): + self.cutout = rotate(self.cutout,angle) + self.cutout = translate(self.cutout,x,y,z) + deg_angle = angle + angle = math.pi*angle/180 + for i in range(len(self.pad)): + xnew = math.cos(angle)*self.pad[i].x - math.sin(angle)*self.pad[i].y + ynew = math.sin(angle)*self.pad[i].x + math.cos(angle)*self.pad[i].y + self.pad[i].x = x + xnew + self.pad[i].y = y + ynew + self.pad[i].z += z + pcb.labels = add(pcb.labels,text(self.value,x,y,z,line=line,color=Green).shape) + for i in range(len(self.labels)): + xnew = math.cos(angle)*self.labels[i].x - math.sin(angle)*self.labels[i].y + ynew = math.sin(angle)*self.labels[i].x + math.cos(angle)*self.labels[i].y + self.labels[i].x = x + xnew + self.labels[i].y = y + ynew + self.labels[i].z += z + if ((-90 < deg_angle) & (deg_angle <= 90)): + pcb.labels = add(pcb.labels,text(self.labels[i].text,self.labels[i].x,self.labels[i].y,self.labels[i].z,self.labels[i].line,color=Red,angle=deg_angle-self.labels[i].angle).shape) + else: + pcb.labels = add(pcb.labels,text(self.labels[i].text,self.labels[i].x,self.labels[i].y,self.labels[i].z,self.labels[i].line,color=Red,angle=(deg_angle-self.labels[i].angle-180)).shape) + pcb = pcb.add(self.shape) + if hasattr(self,'holes'): + pcb.holes = add(pcb.holes,self.holes) + if hasattr(self,'cutout'): + pcb.interior = subtract(pcb.interior,self.cutout) + pcb.exterior = add(pcb.exterior,self.cutout) + return pcb + +def wire(pcb,width,*points): + x0 = points[0].x + y0 = points[0].y + z0 = points[0].z + pcb.board = add(pcb.board,cylinder(x0,y0,z0,z0,width/2)) + for i in range(1,len(points)): + x0 = points[i-1].x + y0 = points[i-1].y + z0 = points[i-1].z + x1 = points[i].x + y1 = points[i].y + z1 = points[i].z + pcb.board = add(pcb.board,line(x0,y0,x1,y1,z1,width)) + pcb.board = add(pcb.board,cylinder(x1,y1,z1,z1,width/2)) + return pcb + +def wirer(pcb,width,*points): + for i in range(1,len(points)): + x0 = points[i-1].x + y0 = points[i-1].y + z0 = points[i-1].z + x1 = points[i].x + y1 = points[i].y + z1 = points[i].z + if (x0 < x1): + pcb.board = add(pcb.board,cube(x0-width/2,x1+width/2,y0-width/2,y0+width/2,z0,z0)) + elif (x1 < x0): + pcb.board = add(pcb.board,cube(x1-width/2,x0+width/2,y0-width/2,y0+width/2,z0,z0)) + if (y0 < y1): + pcb.board = add(pcb.board,cube(x1-width/2,x1+width/2,y0-width/2,y1+width/2,z0,z0)) + elif (y1 < y0): + pcb.board = add(pcb.board,cube(x1-width/2,x1+width/2,y1-width/2,y0+width/2,z0,z0)) + return pcb + +############################################################ +# PCB library +############################################################ + +class via(part): + # + # via + # + def __init__(self,zb,zt,rv,rp,value=''): + self.value = value + self.labels = [] + self.pad = [point(0,0,0)] + self.shape = cylinder(0,0,zb,zt,rp) + self.holes = cylinder(0,0,zb,zt,rv) + self.pad.append(point(0,0,zt)) + self.pad.append(point(0,0,zb)) + +class SJ(part): + # + # solder jumper + # + def __init__(self,value=''): + pad_SJ = cube(-.02,.02,-.03,.03,0,0) + self.value = value + self.labels = [] + self.pad = [point(0,0,0)] + self.shape = translate(pad_SJ,-.029,0,0) + self.pad.append(point(-.029,0,0)) + self.shape = add(self.shape,translate(pad_SJ,.029,0,0)) + self.pad.append(point(.029,0,0)) + +############################################################ +# discretes +############################################################ + + +class ST4EB(part): + # + # Nidec Copal ST4ETB103 trimpot + # + def __init__(self,value=''): + pad1 = cube(-.032,.032,-.039,.039,0,0) + pad2 = cube(-.039,.039,-.039,.039,0,0) + self.value = value + self.labels = [] + self.pad = [point(0,0,0)] + self.shape = translate(pad1,-.046,-.118,0) + self.pad.append(point(-.046,-.118,0)) + self.shape = add(self.shape,translate(pad1,.046,-.118,0)) + self.pad.append(point(.046,-.118,0)) + self.shape = add(self.shape,translate(pad2,0,.118,0)) + self.pad.append(point(0,.118,0)) + +class C_FND(part): + # + # Panasonic FN series, size code D + # 100uF: EEE-FN1E101UL + # + def __init__(self,value=''): + pad = cube(-.032,.032,-.06,.06,0,0) + self.value = value + self.labels = [] + self.pad = [point(0,0,0)] + self.shape = translate(pad,0,.11,0) + self.pad.append(point(0,.11,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'+',angle=90)) + self.shape = add(self.shape,translate(pad,0,-.11,0)) + self.pad.append(point(0,-.11,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'-',angle=90)) + +pad_0402 = cube(-.0175,.0175,-.014,.014,0,0) + +class R_0402(part): + # + # 0402 resistor + # + def __init__(self,value=''): + self.value = value + self.labels = [] + self.pad = [point(0,0,0)] + self.shape = translate(pad_0402,-.0265,0,0) + self.pad.append(point(-.0265,0,0)) + self.shape = add(self.shape,translate(pad_0402,.0265,0,0)) + self.pad.append(point(.0265,0,0)) + +pad_1206 = cube(-.032,.032,-.034,.034,0,0) + +class R_1206(part): + # + # 1206 resistor + # + def __init__(self,value=''): + self.value = value + self.labels = [] + self.pad = [point(0,0,0)] + self.shape = translate(pad_1206,-.06,0,0) + self.pad.append(point(-.06,0,0)) + self.shape = add(self.shape,translate(pad_1206,.06,0,0)) + self.pad.append(point(.06,0,0)) + +class C_1206(part): + # + # 1206 capacitor + # + def __init__(self,value=''): + self.value = value + self.labels = [] + self.pad = [point(0,0,0)] + self.shape = translate(pad_1206,-.06,0,0) + self.pad.append(point(-.06,0,0)) + self.shape = add(self.shape,translate(pad_1206,.06,0,0)) + self.pad.append(point(.06,0,0)) + +pad_1210 = cube(-.032,.032,-.048,.048,0,0) + +class L_1210(part): + # + # 1210 inductor + # + def __init__(self,value=''): + self.value = value + self.labels = [] + self.pad = [point(0,0,0)] + self.shape = translate(pad_1210,-.06,0,0) + self.pad.append(point(-.06,0,0)) + self.shape = add(self.shape,translate(pad_1210,.06,0,0)) + self.pad.append(point(.06,0,0)) + +pad_choke = cube(-.06,.06,-.06,.06,0,0) + +class choke(part): + # + # Panasonic ELLCTV + # + def __init__(self,value=''): + self.value = value + self.labels = [] + self.pad = [point(0,0,0)] + self.shape = translate(pad_choke,-.177,-.177,0) + self.pad.append(point(-.177,-.177,0)) + self.shape = add(self.shape,translate(pad_choke,.177,.177,0)) + self.pad.append(point(.177,.177,0)) + +############################################################ +# connectors +############################################################ + +class header_2H(part): + # + # 2x1x0.1 cable header + # Sullins GEC36SBSN-M89 + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1 + # + self.shape = translate(pad_header,0,.05,0) + self.pad.append(point(0,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad_header,0,-.05,0)) + self.pad.append(point(0,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'2')) + +class header_4H(part): + # + # 4x1x0.1 cable header + # Sullins GEC36SBSN-M89 + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1 + # + self.shape = translate(pad_header,0,.15,0) + self.pad.append(point(0,.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad_header,0,.05,0)) + self.pad.append(point(0,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'2')) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad_header,0,-.05,0)) + self.pad.append(point(0,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'3')) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad_header,0,-0.15,0)) + self.pad.append(point(0,-.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'4')) + +class header_NEO_6M(part): + # + # NEO_6M GPS module + # + def __init__(self,value=''): + pad_header = cylinder(0,0,0,0,.03) + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1 + # + self.shape = translate(pad_header,0,.2,0) + self.pad.append(point(0,.2,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PPS')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad_header,0,.1,0)) + self.pad.append(point(0,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'TXD')) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad_header,0,0,0)) + self.pad.append(point(0,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RXD')) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad_header,0,-.1,0)) + self.pad.append(point(0,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 5 + # + self.shape = add(self.shape,translate(pad_header,0,-.2,0)) + self.pad.append(point(0,-.2,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VCC')) + +class header_MFRC522(part): + # + # MFCR522 RFID module + # + def __init__(self,value=''): + pad_header = cylinder(0,0,0,0,.03) + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1 + # + self.shape = translate(pad_header,0,.35,0) + self.pad.append(point(0,.35,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1SDA')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad_header,0,.25,0)) + self.pad.append(point(0,.25,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SCK')) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad_header,0,.15,0)) + self.pad.append(point(0,.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'COPI')) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad_header,0,0.05,0)) + self.pad.append(point(0,0.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'CIPO')) + # + # pin 5 + # + self.shape = add(self.shape,translate(pad_header,0,-.05,0)) + self.pad.append(point(0,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IRQ')) + # + # pin 6 + # + self.shape = add(self.shape,translate(pad_header,0,-.15,0)) + self.pad.append(point(0,-.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 7 + # + self.shape = add(self.shape,translate(pad_header,0,-.25,0)) + self.pad.append(point(0,-.25,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RST')) + # + # pin 8 + # + self.shape = add(self.shape,translate(pad_header,0,-.35,0)) + self.pad.append(point(0,-.35,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'3.3V')) + +class header_LSM6DS33_2736(part): + # + # LSD6DS33 carrier + # Pololu 2736 + # + def __init__(self,value=''): + pad_header = cylinder(0,0,0,0,.03) + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1 + # + self.shape = translate(pad_header,0,.4,0) + self.pad.append(point(0,.4,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1VDD')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad_header,0,.3,0)) + self.pad.append(point(0,.3,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VIN')) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad_header,0,.2,0)) + self.pad.append(point(0,.2,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad_header,0,0.1,0)) + self.pad.append(point(0,0.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SDA')) + # + # pin 5 + # + self.shape = add(self.shape,translate(pad_header,0,0,0)) + self.pad.append(point(0,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SCL')) + # + # pin 6 + # + self.shape = add(self.shape,translate(pad_header,0,-.1,0)) + self.pad.append(point(0,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SDO')) + # + # pin 7 + # + self.shape = add(self.shape,translate(pad_header,0,-.2,0)) + self.pad.append(point(0,-.2,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'CS')) + # + # pin 8 + # + self.shape = add(self.shape,translate(pad_header,0,-.3,0)) + self.pad.append(point(0,-.3,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'INT2')) + # + # pin 9 + # + self.shape = add(self.shape,translate(pad_header,0,-.4,0)) + self.pad.append(point(0,-.4,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'INT1')) + +class header_VL53L1X_3415(part): + # + # VL53L1X carrier + # Pololu 3415 + # + def __init__(self,value=''): + pad_header = cylinder(0,0,0,0,.03) + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1 + # + self.shape = translate(pad_header,0,.3,0) + self.pad.append(point(0,.3,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1VDD')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad_header,0,.2,0)) + self.pad.append(point(0,.2,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VIN')) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad_header,0,.1,0)) + self.pad.append(point(0,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad_header,0,0,0)) + self.pad.append(point(0,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SDA')) + # + # pin 5 + # + self.shape = add(self.shape,translate(pad_header,0,-.1,0)) + self.pad.append(point(0,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SCL')) + # + # pin 6 + # + self.shape = add(self.shape,translate(pad_header,0,-.2,0)) + self.pad.append(point(0,-.2,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'XSHUT')) + # + # pin 7 + # + self.shape = add(self.shape,translate(pad_header,0,-.3,0)) + self.pad.append(point(0,-.3,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GPIO1')) + +class ESP_WROOM_02D(part): + # + # ESP-WROOM-02D + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + pad = cube(-1/25.4,1/25.4,-.45/25.4,.45/25.4,0,0) + width = 17.5/25.4 + pitch = 1.5/25.4 + # + # pin 1 + # + self.shape = translate(pad,-width/2,4*pitch,0) + self.shape = add(self.shape,cylinder(-width/2-.75/25.4,4*pitch,0,0,.45/25.4)) + self.pad.append(point(-width/2,4*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'3V3')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad,-width/2,3*pitch,0)) + self.pad.append(point(-width/2,3*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'EN')) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad,-width/2,2*pitch,0)) + self.pad.append(point(-width/2,2*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO14')) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad,-width/2,1*pitch,0)) + self.pad.append(point(-width/2,1*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO12')) + # + # pin 5 + # + self.shape = add(self.shape,translate(pad,-width/2,0*pitch,0)) + self.pad.append(point(-width/2,0*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO13')) + # + # pin 6 + # + self.shape = add(self.shape,translate(pad,-width/2,-1*pitch,0)) + self.pad.append(point(-width/2,-1*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO15')) + # + # pin 7 + # + self.shape = add(self.shape,translate(pad,-width/2,-2*pitch,0)) + self.pad.append(point(-width/2,-2*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO2')) + # + # pin 8 + # + self.shape = add(self.shape,translate(pad,-width/2,-3*pitch,0)) + self.pad.append(point(-width/2,-3*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO0')) + # + # pin 9 + # + self.shape = add(self.shape,translate(pad,-width/2,-4*pitch,0)) + self.pad.append(point(-width/2,-4*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 10 + # + self.shape = add(self.shape,translate(pad,width/2,-4*pitch,0)) + self.pad.append(point(width/2,-4*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO4')) + # + # pin 11 + # + self.shape = add(self.shape,translate(pad,width/2,-3*pitch,0)) + self.pad.append(point(width/2,-3*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RXD')) + # + # pin 12 + # + self.shape = add(self.shape,translate(pad,width/2,-2*pitch,0)) + self.pad.append(point(width/2,-2*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'TXD')) + # + # pin 13 + # + self.shape = add(self.shape,translate(pad,width/2,-1*pitch,0)) + self.pad.append(point(width/2,-1*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 14 + # + self.shape = add(self.shape,translate(pad,width/2,0*pitch,0)) + self.pad.append(point(width/2,0*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO5')) + # + # pin 15 + # + self.shape = add(self.shape,translate(pad,width/2,1*pitch,0)) + self.pad.append(point(width/2,1*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RST')) + # + # pin 16 + # + self.shape = add(self.shape,translate(pad,width/2,2*pitch,0)) + self.pad.append(point(width/2,2*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'TOUT')) + # + # pin 17 + # + self.shape = add(self.shape,translate(pad,width/2,3*pitch,0)) + self.pad.append(point(width/2,3*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO16')) + # + # pin 18 + # + self.shape = add(self.shape,translate(pad,width/2,4*pitch,0)) + self.pad.append(point(width/2,4*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 19 + # + padg = cube(-2/25.4,2/25.4,-2/25.4,2/25.4,0,0) + self.shape = add(self.shape,translate(padg,(1.5/2+7.1+2-17.5/2)/25.4,(4*1.5+7.1-20+4.29+2)/25.4,0)) + self.pad.append(point((1.5/2+7.1+2-17.5/2)/25.4,(4*1.5+7.1-20+4.29+2)/25.4,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + +class ESP_01(part): + # + # ESP-01 4x2 vertical + # Sullins NPTC042KFMS-RC + # + def __init__(self,value=''): + pad_header = cube(-.075/2,.075/2,-.04/2,.04/2,0,0) + d = .305/2-.07/2 + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1 + # + self.shape = translate(pad_header,d,.15,0) + self.shape = add(self.shape,cylinder(d+.061/2,.15,0,0,.039/2)) + self.pad.append(point(d,.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad_header,-d,.15,0)) + self.pad.append(point(-d,.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'Tx')) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad_header,d,.05,0)) + self.pad.append(point(d,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO2')) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad_header,-d,.05,0)) + self.pad.append(point(-d,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'EN')) + # + # pin 5 + # + self.shape = add(self.shape,translate(pad_header,d,-.05,0)) + self.pad.append(point(d,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO0')) + # + # pin 6 + # + self.shape = add(self.shape,translate(pad_header,-d,-.05,0)) + self.pad.append(point(-d,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RST')) + # + # pin 7 + # + self.shape = add(self.shape,translate(pad_header,d,-.15,0)) + self.pad.append(point(d,-.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'Rx')) + # + # pin 8 + # + self.shape = add(self.shape,translate(pad_header,-d,-.15,0)) + self.pad.append(point(-d,-.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VCC')) + +class header_serial_reverse_5V(part): + # + # serial cable header, reverse for female connector, 5V output + # GCT BG300-06-A-L-A + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1 + # + self.shape = translate(pad_header,0,-.25,0) + self.shape = add(self.shape,cylinder(-.05,-.25,0,0,.025)) + self.pad.append(point(0,-.25,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad_header,0,-.15,0)) + self.pad.append(point(0,-.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'CTS')) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad_header,0,-.05,0)) + self.pad.append(point(0,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'5V')) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad_header,0,0.05,0)) + self.pad.append(point(0,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'Tx')) + # + # pin 5 + # + self.shape = add(self.shape,translate(pad_header,0,.15,0)) + self.pad.append(point(0,.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'Rx')) + # + # pin 6 + # + self.shape = add(self.shape,translate(pad_header,0,.25,0)) + self.pad.append(point(0,.25,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RTS')) + +class header_serial_reverse_3V3(part): + # + # serial cable header, reverse for female connector, 3.3V output + # GCT BG300-06-A-L-A + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1 + # + self.shape = translate(pad_header,0,-.25,0) + self.shape = add(self.shape,cylinder(-.05,-.25,0,0,.025)) + self.pad.append(point(0,-.25,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad_header,0,-.15,0)) + self.pad.append(point(0,-.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'CTS')) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad_header,0,-.05,0)) + self.pad.append(point(0,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'3.3V')) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad_header,0,0.05,0)) + self.pad.append(point(0,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'Tx')) + # + # pin 5 + # + self.shape = add(self.shape,translate(pad_header,0,.15,0)) + self.pad.append(point(0,.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'Rx')) + # + # pin 6 + # + self.shape = add(self.shape,translate(pad_header,0,.25,0)) + self.pad.append(point(0,.25,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RTS')) + +class TFT8x1v(part): + # + # TFT 8x1 vertical + # 2x Sullins S5635-ND + # + def __init__(self,value=''): + pad_header = cube(-.079/2,.079/2,-.039/2,.039/2,0,0) + d = .209/2-.079/2 + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1 + # + self.shape = translate(pad_header,-d,-.35,0) + self.pad.append(point(-d,-.35,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1LED')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad_header,d,-.25,0)) + self.pad.append(point(d,-.25,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SCK')) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad_header,-d,-.15,0)) + self.pad.append(point(-d,-.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'MOSI')) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad_header,d,-.05,0)) + self.pad.append(point(d,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'DC')) + # + # pin 5 + # + self.shape = add(self.shape,translate(pad_header,-d,.05,0)) + self.pad.append(point(-d,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RST')) + # + # pin 6 + # + self.shape = add(self.shape,translate(pad_header,d,.15,0)) + self.pad.append(point(d,.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'CS')) + # + # pin 7 + # + self.shape = add(self.shape,translate(pad_header,-d,.25,0)) + self.pad.append(point(-d,.25,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 8 + # + self.shape = add(self.shape,translate(pad_header,d,.35,0)) + self.pad.append(point(d,.35,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VCC')) + +class header_SWD_4_05(part): + # + # 4-pin header + # Sullins GRPB022VWQS-RC 2x2x0.05" + # + def __init__(self,value=''): + pad_header = cube(-.043,.043,-.015,.015,0,0) + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1 + # + self.shape = translate(pad_header,-.072,.025,0) + self.shape = add(self.shape,cylinder(-.116,.025,0,0,.015)) + self.pad.append(point(-.072,.025,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'CLK')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad_header,.072,.025,0)) + self.pad.append(point(.072,.025,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'DIO')) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad_header,-.072,-.025,0)) + self.pad.append(point(-.072,-.025,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RST')) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad_header,.072,-.025,0)) + self.pad.append(point(.072,-.025,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + +class header_SWD_4_1(part): + # + # 4-pin header + # FCI 95278-101a04lf Bergstik 2x2x0.1" + # + pad_header = cube(-.05,.05,-.025,.025,0,0) + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1 + # + self.shape = translate(pad_header,-.107,.05,0) + #self.shape = add(self.shape,cylinder(-.157,.05,0,0,.025)) + self.pad.append(point(-.107,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'CLK')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad_header,.107,.05,0)) + self.pad.append(point(.107,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'DIO')) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad_header,-.107,-.05,0)) + self.pad.append(point(-.107,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RST')) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad_header,.107,-.05,0)) + self.pad.append(point(.107,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + +class header_UPDI(part): + # + # UPDI header + # Sullins GEC36SBSN-M89 + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: UPDI + # + self.shape = translate(pad_header,0,-.05,0) + self.shape = add(self.shape,cylinder(.05,-.05,0,0,.025)) + self.pad.append(point(0,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'UPDI')) + # + # pin 2: GND + # + self.shape = add(self.shape,translate(pad_header,0,.05,0)) + self.pad.append(point(0,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + +class header_UPDI_reverse(part): + # + # UPDI header, reverse for female connector + # GCT BG300-03-A-L-A + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: UPDI + # + self.shape = translate(pad_header,0,.05,0) + self.shape = add(self.shape,cylinder(.05,.05,0,0,.025)) + self.pad.append(point(0,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'UPDI')) + # + # pin 2: GND + # + self.shape = add(self.shape,translate(pad_header,0,-.05,0)) + self.pad.append(point(0,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + +class USB_A_plug(part): + # + # USB type A PCB plug + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: 5V + # + self.shape = translate(cube(-.05,.242,-.02,.02,0,0),0,.138,0) + self.pad.append(point(0,.138,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'5V')) + # + # pin 2: D- + # + self.shape = add(self.shape,translate(cube(-0.05,.202,-.02,.02,0,0),0,.039,0)) + self.pad.append(point(0,.039,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'D-')) + # + # pin 3: D+ + # + self.shape = add(self.shape,translate(cube(-.05,.202,-.02,.02,0,0),0,-.039,0)) + self.pad.append(point(0,-.039,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'D+')) + # + # pin 4: GND + # + self.shape = add(self.shape,translate(cube(-.05,.242,-.02,.02,0,0),0,-.138,0)) + self.pad.append(point(0,-.138,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # plug cutout + # + self.cutout = cube(-.05,1,.24,10,zb,zt) + self.cutout = add(self.cutout,cube(-.05,10,-10,-.24,zb,zt)) + +class header_SWD(part): + # + # Serial Wire Debug programming header + # Amphenol 20021121-00010T1LF 2x5x0.05 + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + d = 0.077 + w = 0.015 + h = .047 + pad = cube(-h,h,-w,w,0,0) + # + # pin 1: VCC + # + self.shape = translate(pad,d,-.1,0) + self.shape = add(self.shape,cylinder(d+h,-.1,0,0,w)) + self.pad.append(point(d,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VCC')) + # + # pin 2: DIO + # + self.shape = add(self.shape,translate(pad,-d,-.1,0)) + self.pad.append(point(-d,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'DIO')) + # + # pin 3: GND + # + self.shape = add(self.shape,translate(pad,d,-.05,0)) + self.pad.append(point(d,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 4: CLK + # + self.shape = add(self.shape,translate(pad,-d,-.05,0)) + self.pad.append(point(-d,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'CLK')) + # + # pin 5: GND + # + self.shape = add(self.shape,translate(pad,d,0,0)) + self.pad.append(point(d,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 6: SWO + # + self.shape = add(self.shape,translate(pad,-d,0,0)) + self.pad.append(point(-d,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SWO')) + # + # pin 7: KEY + # + self.shape = add(self.shape,translate(pad,d,.05,0)) + self.pad.append(point(d,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'KEY')) + # + # pin 8: NC + # + self.shape = add(self.shape,translate(pad,-d,.05,0)) + self.pad.append(point(-d,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'NC')) + # + # pin 9: GND + # + self.shape = add(self.shape,translate(pad,d,.1,0)) + self.pad.append(point(d,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 10: nRESET + # + self.shape = add(self.shape,translate(pad,-d,.1,0)) + self.pad.append(point(-d,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RST')) + +class ESC(part): + # + # ESC 3x1 + # Sullins S1013E-36-ND + # + def __init__(self,value=''): + pad_header = cube(-.1,.1,-.05/2,.05/2,0,0) + d = .075 + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: PWM + # + self.shape = translate(pad_header,-d,-.1,0) + self.pad.append(point(-d,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PWM')) + # + # pin 2: 5V + # + self.shape = add(self.shape,translate(pad_header,d,0,0)) + self.pad.append(point(d,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'5V')) + # + # pin 3: GND + # + self.shape = add(self.shape,translate(pad_header,-d,.1,0)) + self.pad.append(point(-d,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + +class I2C4x1h(part): + # + # I2C 4x1 horizontal female + # GCT BG300-03-A-L-A + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: SCL + # + self.shape = translate(pad_header,0,-.15,0) + #self.shape = cylinder(.05,.15,0,0,.025) + self.pad.append(point(0,-.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SCL')) + # + # pin 2: SDA + # + self.shape = add(self.shape,translate(pad_header,0,-.05,0)) + self.pad.append(point(0,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SDA')) + # + # pin 3: VCC + # + self.shape = add(self.shape,translate(pad_header,0,.05,0)) + self.pad.append(point(0,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VCC')) + # + # pin 4: GND + # + self.shape = add(self.shape,translate(pad_header,0,.15,0)) + self.pad.append(point(0,.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + +class I2C4x1v(part): + # + # I2C 4x1 vertical + # Sullins S5635-ND + # + def __init__(self,value=''): + pad_header = cube(-.079/2,.079/2,-.039/2,.039/2,0,0) + d = .209/2-.079/2 + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: VCC + # + self.shape = translate(pad_header,-d,-.15,0) + self.pad.append(point(-d,-.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1VCC')) + # + # pin 2: GND + # + self.shape = add(self.shape,translate(pad_header,d,-.05,0)) + self.pad.append(point(d,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 3: SCL + # + self.shape = add(self.shape,translate(pad_header,-d,.05,0)) + self.pad.append(point(-d,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SCL')) + # + # pin 4: SDA + # + self.shape = add(self.shape,translate(pad_header,d,.15,0)) + self.pad.append(point(d,.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SDA')) + +class I2C4x1i(part): + # + # I2C 4x1 inline + # + def __init__(self,value=''): + pad_header = cube(-.079/2,.079/2,-.039/2,.039/2,0,0) + d = 0 + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: VCC + # + self.shape = translate(pad_header,-d,-.15,0) + self.pad.append(point(-d,-.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1VCC')) + # + # pin 2: GND + # + self.shape = add(self.shape,translate(pad_header,d,-.05,0)) + self.pad.append(point(d,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 3: SCL + # + self.shape = add(self.shape,translate(pad_header,-d,.05,0)) + self.pad.append(point(-d,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SCL')) + # + # pin 4: SDA + # + self.shape = add(self.shape,translate(pad_header,d,.15,0)) + self.pad.append(point(d,.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SDA')) + +class RCWL0516(part): + # + # RCWL-0516 Doppler radar + # + def __init__(self,value=''): + pad_header = cube(-.065,.065,-.025,.025,0,0) + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: 3.3V + # + self.shape = translate(pad_header,.107,-.2,0) + self.shape = add(self.shape,cylinder(.172,-.2,0,0,.025)) + self.pad.append(point(.107,-.2,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'3.3V')) + # + # pin 2: GND + # + self.shape = add(self.shape,translate(pad_header,-.107,-.1,0)) + self.pad.append(point(-.107,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 3: OUT + # + self.shape = add(self.shape,translate(pad_header,.107,0,0)) + self.pad.append(point(.107,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'OUT')) + # + # pin 4: VIN + # + self.shape = add(self.shape,translate(pad_header,-.107,.1,0)) + self.pad.append(point(-.107,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VIN')) + # + # pin 5: CDS + # + self.shape = add(self.shape,translate(pad_header,.107,.2,0)) + self.pad.append(point(.107,.2,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'CDS')) + +class microSD(part): + # + # microSD + # Amphenol 114-00841-68 + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1 + # + self.shape = translate(cube(-.0138,.0138,-.034,.034,0,0),-.177+7*.0433,-.304,0) + self.pad.append(point(-.177+7*.0433,-.304,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1NC',angle=90)) + # + # pin 2 + # + self.shape = add(self.shape,translate(cube(-.0138,.0138,-.034,.034,0,0),-.177+6*.0433,-.304,0)) + self.pad.append(point(-.177+6*.0433,-.304,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SS',angle=90)) + # + # pin 3 + # + self.shape = add(self.shape,translate(cube(-.0138,.0138,-.034,.034,0,0),-.177+5*.0433,-.304,0)) + self.pad.append(point(-.177+5*.0433,-.304,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'MOSI',angle=90)) + # + # pin 4 + # + self.shape = add(self.shape,translate(cube(-.0138,.0138,-.034,.034,0,0),-.177+4*.0433,-.304,0)) + self.pad.append(point(-.177+4*.0433,-.304,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VCC',angle=90)) + # + # pin 5 + # + self.shape = add(self.shape,translate(cube(-.0138,.0138,-.034,.034,0,0),-.177+3*.0433,-.304,0)) + self.pad.append(point(-.177+3*.0433,-.304,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SCK',angle=90)) + # + # pin 6 + # + self.shape = add(self.shape,translate(cube(-.0138,.0138,-.034,.034,0,0),-.177+2*.0433,-.304,0)) + self.pad.append(point(-.177+2*.0433,-.304,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND',angle=90)) + # + # pin 7 + # + self.shape = add(self.shape,translate(cube(-.0138,.0138,-.034,.034,0,0),-.177+1*.0433,-.304,0)) + self.pad.append(point(-.177+1*.0433,-.304,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'MISO',angle=90)) + # + # pin 8 + # + self.shape = add(self.shape,translate(cube(-.0138,.0138,-.034,.034,0,0),-.177+0*.0433,-.304,0)) + self.pad.append(point(-.177+0*.0433,-.304,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'NC',angle=90)) + # + # feet + # + self.shape = add(self.shape,translate(cube(-.021,.021,-.029,.029,0,0),-.228,-.299,0)) # leave extra space for 1/64 milling + self.shape = add(self.shape,translate(cube(-.029,.029,-.029,.029,0,0),.222,-.299,0)) + self.shape = add(self.shape,translate(cube(-.015,.015,-.029,.025,0,0),-.232,0,0)) # leave extra space for 1/64 milling + self.shape = add(self.shape,translate(cube(-.015,.015,-.029,.029,0,0),-.232+.47,.025,0)) + self.shape = add(self.shape,translate(cube(-.028,.028,-.019,.019,0,0),-.221,.059,0)) + self.shape = add(self.shape,translate(cube(-.019,.019,-.030,.030,0,0),.222,.121,0)) + +pad_USB_trace = cube(-.0075,.0075,-.04,.04,0,0) +pad_USB_feet = cube(-.049,.049,-.043,.043,0,0) + +class USB_mini_B(part): + # + # USB mini B + # Hirose UX60-MB-5ST + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1 + # + self.shape = translate(pad_USB_trace,.063,.36,0) + self.pad.append(point(.063,.36,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'G')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad_USB_trace,.0315,.36,0)) + self.pad.append(point(.0315,.36,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'')) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad_USB_trace,0,.36,0)) + self.pad.append(point(0,.36,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'+')) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad_USB_trace,-.0315,.36,0)) + self.pad.append(point(-.0315,.36,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'-')) + # + # pin 5 + # + self.shape = add(self.shape,translate(pad_USB_trace,-.063,.36,0)) + self.pad.append(point(-.063,.36,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'V')) + # + # feet + # + self.shape = add(self.shape,translate(pad_USB_feet,.165,.33,0)) + self.shape = add(self.shape,translate(pad_USB_feet,-.165,.33,0)) + self.shape = add(self.shape,translate(pad_USB_feet,.165,.12,0)) + self.shape = add(self.shape,translate(pad_USB_feet,-.165,.12,0)) + +pad_header = cube(-.05,.05,-.025,.025,0,0) + +class header_4(part): + # + # 4-pin header + # fci 95278-101a04lf bergstik 2x2x0.1" + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1 + # + self.shape = translate(pad_header,-.107,.05,0) + self.shape = add(self.shape,cylinder(-.157,.05,0,0,.025)) + self.pad.append(point(-.107,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad_header,.107,.05,0)) + self.pad.append(point(.107,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'2')) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad_header,-.107,-.05,0)) + self.pad.append(point(-.107,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'3')) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad_header,.107,-.05,0)) + self.pad.append(point(.107,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'4')) + +class header_signal(part): + # + # signal header + # FCI 95278-101A04LF Bergstik 2x2x0.1" + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: Gnd + # + self.shape = translate(pad_header,.107,-.05,0) + self.shape = add(self.shape,cylinder(.157,-.05,0,0,.025)) + self.pad.append(point(.107,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad_header,-.107,-.05,0)) + self.pad.append(point(-.107,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'')) + # + # pin 3: signal + # + self.shape = add(self.shape,translate(pad_header,.107,.05,0)) + self.pad.append(point(.107,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'signal')) + # + # pin 4: + # + self.shape = add(self.shape,translate(pad_header,-.107,.05,0)) + self.pad.append(point(-.107,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'')) + + +class header_power(part): + # + # power header + # FCI 95278-101A04LF Bergstik 2x2x0.1" + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: Gnd + # + self.shape = translate(pad_header,.107,-.05,0) + self.shape = add(self.shape,cylinder(.157,-.05,0,0,.025)) + self.pad.append(point(.107,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad_header,-.107,-.05,0)) + self.pad.append(point(-.107,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'')) + # + # pin 3: V + # + self.shape = add(self.shape,translate(pad_header,.107,.05,0)) + self.pad.append(point(.107,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'V')) + # + # pin 4: + # + self.shape = add(self.shape,translate(pad_header,-.107,.05,0)) + self.pad.append(point(-.107,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'')) + +class header_i0(part): + # + # i0 header + # FCI 95278-101A04LF Bergstik 2x2x0.1" + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: Gnd + # + self.shape = translate(pad_header,.107,-.05,0) + self.shape = add(self.shape,cylinder(.157,-.05,0,0,.025)) + self.pad.append(point(.107,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 2: data + # + self.shape = add(self.shape,translate(pad_header,-.107,-.05,0)) + self.pad.append(point(-.107,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'data')) + # + # pin 3: V + # + self.shape = add(self.shape,translate(pad_header,.107,.05,0)) + self.pad.append(point(.107,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'V')) + # + # pin 4: + # + self.shape = add(self.shape,translate(pad_header,-.107,.05,0)) + self.pad.append(point(-.107,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'')) + +class header_serial(part): + # + # serial comm header + # FCI 95278-101A04LF Bergstik 2x2x0.1" + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: Gnd + # + self.shape = translate(pad_header,.107,-.05,0) + self.shape = add(self.shape,cylinder(.157,-.05,0,0,.025)) + self.pad.append(point(.107,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 2:DTR + # + self.shape = add(self.shape,translate(pad_header,-.107,-.05,0)) + self.pad.append(point(-.107,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'DTR')) + # + # pin 3: Tx + # + self.shape = add(self.shape,translate(pad_header,.107,.05,0)) + self.pad.append(point(.107,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'Tx')) + # + # pin 4: Rx + # + self.shape = add(self.shape,translate(pad_header,-.107,.05,0)) + self.pad.append(point(-.107,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'Rx')) + +class header_bus(part): + # + # bus header + # FCI 95278-101A04LF Bergstik 2x2x0.1" + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: Gnd + # + self.shape = translate(pad_header,.107,-.05,0) + self.shape = add(self.shape,cylinder(.157,-.05,0,0,.025)) + self.pad.append(point(.107,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 2: Tx + # + self.shape = add(self.shape,translate(pad_header,-.107,-.05,0)) + self.pad.append(point(-.107,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'Tx')) + # + # pin 3: V + # + self.shape = add(self.shape,translate(pad_header,.107,.05,0)) + self.pad.append(point(.107,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'V')) + # + # pin 4: Rx + # + self.shape = add(self.shape,translate(pad_header,-.107,.05,0)) + self.pad.append(point(-.107,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'Rx')) + +class header_I2C(part): + # + # I2C header + # FCI 95278-101A04LF Bergstik 2x2x0.1" + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: SCL + # + self.shape = translate(pad_header,.107,-.05,0) + self.shape = add(self.shape,cylinder(.157,-.05,0,0,.025)) + self.pad.append(point(.107,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SCL')) + # + # pin 2: G + # + self.shape = add(self.shape,translate(pad_header,-.107,-.05,0)) + self.pad.append(point(-.107,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'G')) + # + # pin 3: SDA + # + self.shape = add(self.shape,translate(pad_header,.107,.05,0)) + self.pad.append(point(.107,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SDA')) + # + # pin 4: V + # + self.shape = add(self.shape,translate(pad_header,-.107,.05,0)) + self.pad.append(point(-.107,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'V')) + +class header_APA(part): + # + # APA header + # FCI 95278-101A04LF Bergstik 2x2x0.1" + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: Gnd + # + self.shape = translate(pad_header,.107,-.05,0) + self.shape = add(self.shape,cylinder(.157,-.05,0,0,.025)) + self.pad.append(point(.107,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 2: in + # + self.shape = add(self.shape,translate(pad_header,-.107,-.05,0)) + self.pad.append(point(-.107,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'in')) + # + # pin 3: V + # + self.shape = add(self.shape,translate(pad_header,.107,.05,0)) + self.pad.append(point(.107,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'V')) + # + # pin 4: out + # + self.shape = add(self.shape,translate(pad_header,-.107,.05,0)) + self.pad.append(point(-.107,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'out')) + +class header_6(part): + # + # 6-pin header + # FCI 95278-101A06LF Bergstik 2x3x0.1" + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1 + # + self.shape = translate(pad_header,.107,-.1,0) + self.shape = add(self.shape,cylinder(.157,-.1,0,0,.025)) + self.pad.append(point(.107,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad_header,-.107,-.1,0)) + self.pad.append(point(-.107,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'')) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad_header,.107,0,0)) + self.pad.append(point(.107,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'')) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad_header,-.107,0,0)) + self.pad.append(point(-.107,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'')) + # + # pin 5 + # + self.shape = add(self.shape,translate(pad_header,.107,.1,0)) + self.pad.append(point(.107,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'')) + # + # pin 6 + # + self.shape = add(self.shape,translate(pad_header,-.107,.1,0)) + self.pad.append(point(-.107,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'')) + +class header_ATP(part): + # + # Asynchronous Token Protocol header + # FCI 95278-101A06LF Bergstik 2x3x0.1" + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1 + # + self.shape = translate(pad_header,.107,-.1,0) + self.shape = add(self.shape,cylinder(.157,-.1,0,0,.025)) + self.pad.append(point(.107,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'BI')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad_header,-.107,-.1,0)) + self.pad.append(point(-.107,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'TI')) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad_header,.107,0,0)) + self.pad.append(point(.107,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'G')) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad_header,-.107,0,0)) + self.pad.append(point(-.107,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'V')) + # + # pin 5 + # + self.shape = add(self.shape,translate(pad_header,.107,.1,0)) + self.pad.append(point(.107,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'TO')) + # + # pin 6 + # + self.shape = add(self.shape,translate(pad_header,-.107,.1,0)) + self.pad.append(point(-.107,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'BO')) + +class header_PDI(part): + # + # in-circuit PDI programming header + # FCI 95278-101A06LF Bergstik 2x3x0.1" + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: Data + # + self.shape = translate(pad_header,.107,-.1,0) + self.shape = add(self.shape,cylinder(.157,-.1,0,0,.025)) + self.pad.append(point(.107,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'DAT')) + # + # pin 2: VCC + # + self.shape = add(self.shape,translate(pad_header,-.107,-.1,0)) + self.pad.append(point(-.107,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VCC')) + # + # pin 3: NC + # + self.shape = add(self.shape,translate(pad_header,.107,0,0)) + self.pad.append(point(.107,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'NC')) + # + # pin 4: NC + # + self.shape = add(self.shape,translate(pad_header,-.107,0,0)) + self.pad.append(point(-.107,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'NC')) + # + # pin 5: Clock + # + self.shape = add(self.shape,translate(pad_header,.107,.1,0)) + self.pad.append(point(.107,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'CLK')) + # + # pin 6: GND + # + self.shape = add(self.shape,translate(pad_header,-.107,.1,0)) + self.pad.append(point(-.107,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + +class header_ISP(part): + # + # in-circuit ISP programming header + # FCI 95278-101A06LF Bergstik 2x3x0.1" + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: MISO + # + self.shape = translate(pad_header,.107,-.1,0) + self.shape = add(self.shape,cylinder(.157,-.1,0,0,.025)) + self.pad.append(point(.107,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'MISO')) + # + # pin 2: V + # + self.shape = add(self.shape,translate(pad_header,-.107,-.1,0)) + self.pad.append(point(-.107,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'V')) + # + # pin 3: SCK + # + self.shape = add(self.shape,translate(pad_header,.107,0,0)) + self.pad.append(point(.107,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SCK')) + # + # pin 4: MOSI + # + self.shape = add(self.shape,translate(pad_header,-.107,0,0)) + self.pad.append(point(-.107,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'MOSI')) + # + # pin 5: RST + # + self.shape = add(self.shape,translate(pad_header,.107,.1,0)) + self.pad.append(point(.107,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RST')) + # + # pin 6: GND + # + self.shape = add(self.shape,translate(pad_header,-.107,.1,0)) + self.pad.append(point(-.107,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + +class header_nRF24L01(part): + # + # nRF24L01 module header + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: + # + self.shape = translate(pad_header,.107,-.15,0) + self.shape = add(self.shape,cylinder(.157,-.15,0,0,.025)) + self.pad.append(point(.107,-.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 2: + # + self.shape = add(self.shape,translate(pad_header,-.107,-.15,0)) + self.pad.append(point(-.107,-.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VCC')) + # + # pin 3: + # + self.shape = add(self.shape,translate(pad_header,.107,-.05,0)) + self.pad.append(point(.107,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'CE')) + # + # pin 4: + # + self.shape = add(self.shape,translate(pad_header,-.107,-.05,0)) + self.pad.append(point(-.107,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'CS')) + # + # pin 5: + # + self.shape = add(self.shape,translate(pad_header,.107,.05,0)) + self.pad.append(point(.107,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SCK')) + # + # pin 6: + # + self.shape = add(self.shape,translate(pad_header,-.107,.05,0)) + self.pad.append(point(-.107,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'MOSI')) + # + # pin 7: + # + self.shape = add(self.shape,translate(pad_header,.107,.15,0)) + self.pad.append(point(.107,.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'MISO')) + # + # pin 8: + # + self.shape = add(self.shape,translate(pad_header,-.107,.15,0)) + self.pad.append(point(-.107,.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IRQ')) + +class header_servo(part): + # + # servo motor header + # FCI 95278-101A06LF Bergstik 2x3x0.1" + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: ground + # + self.shape = translate(pad_header,.107,-.1,0) + self.shape = add(self.shape,cylinder(.157,-.1,0,0,.025)) + self.pad.append(point(.107,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'G/blk')) + # + # pin 2: ground + # + self.shape = add(self.shape,translate(pad_header,-.107,-.1,0)) + self.pad.append(point(-.107,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'G/blk')) + # + # pin 3: power + # + self.shape = add(self.shape,translate(pad_header,.107,0,0)) + self.pad.append(point(.107,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'V/red')) + # + # pin 4: power + # + self.shape = add(self.shape,translate(pad_header,-.107,0,0)) + self.pad.append(point(-.107,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'V/red')) + # + # pin 5: signal 0 + # + self.shape = add(self.shape,translate(pad_header,.107,.1,0)) + self.pad.append(point(.107,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'S0/wht')) + # + # pin 6: signal 1 + # + self.shape = add(self.shape,translate(pad_header,-.107,.1,0)) + self.pad.append(point(-.107,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'S1/wht')) + +class header_unipolar_stepper(part): + # + # unipolar stepper header + # FCI 95278-101A06LF Bergstik 2x3x0.1" + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1 + # + self.shape = translate(pad_header,.107,-.1,0) + self.shape = add(self.shape,cylinder(.157,-.1,0,0,.025)) + self.pad.append(point(.107,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'red')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad_header,-.107,-.1,0)) + self.pad.append(point(-.107,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'green')) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad_header,.107,0,0)) + self.pad.append(point(.107,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'black')) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad_header,-.107,0,0)) + self.pad.append(point(-.107,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'brown')) + # + # pin 5 + # + self.shape = add(self.shape,translate(pad_header,.107,.1,0)) + self.pad.append(point(.107,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'orange')) + # + # pin 6 + # + self.shape = add(self.shape,translate(pad_header,-.107,.1,0)) + self.pad.append(point(-.107,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'yellow')) + +class header_LCD(part): + # + # LCD interface header + # FCI 95278-101A10LF Bergstik 2x3x0.1" + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: + # + self.shape = translate(pad_header,.107,-.2,0) + self.shape = add(self.shape,cylinder(.157,-.2,0,0,.025)) + self.pad.append(point(.107,-.2,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'DB7\n14')) + # + # pin 2: + # + self.shape = add(self.shape,translate(pad_header,-.107,-.2,0)) + self.pad.append(point(-.107,-.2,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'DB6\n13')) + # + # pin 3: + # + self.shape = add(self.shape,translate(pad_header,.107,-.1,0)) + self.pad.append(point(.107,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'DB5\n12')) + # + # pin 4: + # + self.shape = add(self.shape,translate(pad_header,-.107,-.1,0)) + self.pad.append(point(-.107,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'DB4\n11')) + # + # pin 5: + # + self.shape = add(self.shape,translate(pad_header,.107,0,0)) + self.pad.append(point(.107,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'E\n6')) + # + # pin 6: + # + self.shape = add(self.shape,translate(pad_header,-.107,0,0)) + self.pad.append(point(-.107,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'R/W\n5')) + # + # pin 7: + # + self.shape = add(self.shape,translate(pad_header,.107,.1,0)) + self.pad.append(point(.107,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RS\n4')) + # + # pin 8: + # + self.shape = add(self.shape,translate(pad_header,-.107,.1,0)) + self.pad.append(point(-.107,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'Vee\n3')) + # + # pin 9: + # + self.shape = add(self.shape,translate(pad_header,.107,.2,0)) + self.pad.append(point(.107,.2,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'Vcc\n2')) + # + # pin 10: + # + self.shape = add(self.shape,translate(pad_header,-.107,.2,0)) + self.pad.append(point(-.107,.2,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND\n1')) + +class header_serial_reverse(part): + # + # serial cable header, reverse for female connector + # GCT BG300-06-A-L-A + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: GND + # + self.shape = translate(pad_header,0,-.25,0) + self.shape = add(self.shape,cylinder(-.05,-.25,0,0,.025)) + self.pad.append(point(0,-.25,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 2: CTS (brown) + # + self.shape = add(self.shape,translate(pad_header,0,-.15,0)) + self.pad.append(point(0,-.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'CTS')) + # + # pin 3: VCC (red) + # + self.shape = add(self.shape,translate(pad_header,0,-.05,0)) + self.pad.append(point(0,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VCC')) + # + # pin 4: Tx (orange) + # + self.shape = add(self.shape,translate(pad_header,0,0.05,0)) + self.pad.append(point(0,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'Tx')) + # + # pin 5: Rx (yellow) + # + self.shape = add(self.shape,translate(pad_header,0,.15,0)) + self.pad.append(point(0,.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'Rx')) + # + # pin 6: RTS (green) + # + self.shape = add(self.shape,translate(pad_header,0,.25,0)) + self.pad.append(point(0,.25,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RTS')) + +class header_FTDI(part): + # + # FTDI cable header + # Sullins GEC36SBSN-M89 + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: GND + # + self.shape = translate(pad_header,0,.25,0) + self.shape = add(self.shape,cylinder(-.05,.25,0,0,.025)) + self.pad.append(point(0,.25,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 2: CTS (brown) + # + self.shape = add(self.shape,translate(pad_header,0,.15,0)) + self.pad.append(point(0,.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'CTS')) + # + # pin 3: VCC (red) + # + self.shape = add(self.shape,translate(pad_header,0,.05,0)) + self.pad.append(point(0,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VCC')) + # + # pin 4: Tx (orange) + # + self.shape = add(self.shape,translate(pad_header,0,-0.05,0)) + self.pad.append(point(0,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'Tx')) + # + # pin 5: Rx (yellow) + # + self.shape = add(self.shape,translate(pad_header,0,-.15,0)) + self.pad.append(point(0,-.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'Rx')) + # + # pin 6: RTS (green) + # + self.shape = add(self.shape,translate(pad_header,0,-.25,0)) + self.pad.append(point(0,-.25,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RTS')) + +class HCSR04(part): + # + # HC-SR04 sonar header + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: GND + # + self.shape = translate(pad_header,0,.15,0) + self.shape = add(self.shape,cylinder(-.05,.15,0,0,.025)) + self.pad.append(point(0,.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 2: echo + # + self.shape = add(self.shape,translate(pad_header,0,.05,0)) + self.pad.append(point(0,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'echo')) + # + # pin 3: trig + # + self.shape = add(self.shape,translate(pad_header,0,-.05,0)) + self.pad.append(point(0,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'trig')) + # + # pin 4: Vcc + # + self.shape = add(self.shape,translate(pad_header,0,-0.15,0)) + self.pad.append(point(0,-.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'Vcc')) + +class HCSR501(part): + # + # HC-SR501 motion detector header + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: Vcc + # + self.shape = translate(pad_header,0,.1,0) + self.shape = add(self.shape,cylinder(-.05,.1,0,0,.025)) + self.pad.append(point(0,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'Vcc')) + # + # pin 2: out + # + self.shape = add(self.shape,translate(pad_header,0,0,0)) + self.pad.append(point(0,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'out')) + # + # pin 3: GND + # + self.shape = add(self.shape,translate(pad_header,0,-.1,0)) + self.pad.append(point(0,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + +pad_RN4871_left = cube(-0.5/25.4,1/25.4,-0.7/2/25.4,0.7/2/25.4,0,0) +pad_RN4871_right = cube(-1/25.4,0.5/25.4,-0.7/2/25.4,0.7/2/25.4,0,0) +pad_RN4871_bot = cube(-0.7/2/25.4,0.7/2/25.4,-0.5/25.4,1/25.4,0,0) + +class RN4871(part): + # + # RN4871 + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + width = 9/25.4 + height = 7.5/25.4 + bottom = 1.9/25.4 + left = 1.5/25.4 + pitch = 1.2/25.4 + size = .004 + # + # pin 1: + # + self.shape = translate(pad_RN4871_left,-width/2.0,-height+bottom+4*pitch,0) + self.pad.append(point(-width/2.0,-height+bottom+4*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'BT_RF',line=size)) + # + # pin 2: + # + self.shape = add(self.shape,translate(pad_RN4871_left,-width/2.0,-height+bottom+3*pitch,0)) + self.pad.append(point(-width/2.0,-height+bottom+3*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND',line=size)) + # + # pin 3: + # + self.shape = add(self.shape,translate(pad_RN4871_left,-width/2.0,-height+bottom+2*pitch,0)) + self.pad.append(point(-width/2.0,-height+bottom+2*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'P1_2',line=size)) + # + # pin 4: + # + self.shape = add(self.shape,translate(pad_RN4871_left,-width/2.0,-height+bottom+1*pitch,0)) + self.pad.append(point(-width/2.0,-height+bottom+1*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'P1_3',line=size)) + # + # pin 5: + # + self.shape = add(self.shape,translate(pad_RN4871_left,-width/2.0,-height+bottom+0*pitch,0)) + self.pad.append(point(-width/2.0,-height+bottom+0*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'P1_7',line=size)) + # + # pin 6: + # + self.shape = add(self.shape,translate(pad_RN4871_bot,-width/2.0+left+0*pitch,-height,0)) + self.pad.append(point(-width/2.0+left+0*pitch,-height,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'P1_6',line=size,angle=90)) + # + # pin 7: + # + self.shape = add(self.shape,translate(pad_RN4871_bot,-width/2.0+left+1*pitch,-height,0)) + self.pad.append(point(-width/2.0+left+1*pitch,-height,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RX',line=size,angle=90)) + # + # pin 8: + # + self.shape = add(self.shape,translate(pad_RN4871_bot,-width/2.0+left+2*pitch,-height,0)) + self.pad.append(point(-width/2.0+left+2*pitch,-height,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'TX',line=size,angle=90)) + # + # pin 9: + # + self.shape = add(self.shape,translate(pad_RN4871_bot,-width/2.0+left+3*pitch,-height,0)) + self.pad.append(point(-width/2.0+left+3*pitch,-height,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'P3_6',line=size,angle=90)) + # + # pin 10: + # + self.shape = add(self.shape,translate(pad_RN4871_bot,-width/2.0+left+4*pitch,-height,0)) + self.pad.append(point(-width/2.0+left+4*pitch,-height,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RST_N',line=size,angle=90)) + # + # pin 11: + # + self.shape = add(self.shape,translate(pad_RN4871_bot,-width/2.0+left+5*pitch,-height,0)) + self.pad.append(point(-width/2.0+left+5*pitch,-height,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'P0_0',line=size,angle=90)) + # + # pin 12: + # + self.shape = add(self.shape,translate(pad_RN4871_right,width/2.0,-height+bottom+0*pitch,0)) + self.pad.append(point(width/2.0,-height+bottom+0*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'P0_2',line=size)) + # + # pin 13: + # + self.shape = add(self.shape,translate(pad_RN4871_right,width/2.0,-height+bottom+1*pitch,0)) + self.pad.append(point(width/2.0,-height+bottom+1*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND',line=size)) + # + # pin 14: + # + self.shape = add(self.shape,translate(pad_RN4871_right,width/2.0,-height+bottom+2*pitch,0)) + self.pad.append(point(width/2.0,-height+bottom+2*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VBAT',line=size)) + # + # pin 15: + # + self.shape = add(self.shape,translate(pad_RN4871_right,width/2.0,-height+bottom+3*pitch,0)) + self.pad.append(point(width/2.0,-height+bottom+3*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'P2_7',line=size)) + # + # pin 16: + # + self.shape = add(self.shape,translate(pad_RN4871_right,width/2.0,-height+bottom+4*pitch,0)) + self.pad.append(point(width/2.0,-height+bottom+4*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'P2_0',line=size)) + +pad_HM11 = cube(-.047,.047,-.0177,.0177,0,0) + +class HM11(part): + # + # HM-11 + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + height = 18.5/25.4 + width = 13.5/25.4 + pitch = 1.5/25.4 + bottom = 1/25.4 + offset = 0 + size = .004 + # + # pin 1: + # + self.shape = translate(pad_HM11,-width/2.0+offset,-height/2.0+bottom+7*pitch,0) + self.pad.append(point(-width/2.0+offset,-height/2.0+bottom+7*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RTS',line=size)) + # + # pin 2: + # + self.shape = add(self.shape,translate(pad_HM11,-width/2.0+offset,-height/2.0+bottom+6*pitch,0)) + self.pad.append(point(-width/2.0+offset,-height/2.0+bottom+6*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'TX',line=size)) + # + # pin 3: + # + self.shape = add(self.shape,translate(pad_HM11,-width/2.0+offset,-height/2.0+bottom+5*pitch,0)) + self.pad.append(point(-width/2.0+offset,-height/2.0+bottom+5*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'CTS',line=size)) + # + # pin 4: + # + self.shape = add(self.shape,translate(pad_HM11,-width/2.0+offset,-height/2.0+bottom+4*pitch,0)) + self.pad.append(point(-width/2.0+offset,-height/2.0+bottom+4*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RX',line=size)) + # + # pin 5: + # + self.shape = add(self.shape,translate(pad_HM11,-width/2.0+offset,-height/2.0+bottom+3*pitch,0)) + self.pad.append(point(-width/2.0+offset,-height/2.0+bottom+3*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'NC',line=size)) + # + # pin 6: + # + self.shape = add(self.shape,translate(pad_HM11,-width/2.0+offset,-height/2.0+bottom+2*pitch,0)) + self.pad.append(point(-width/2.0+offset,-height/2.0+bottom+2*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'NC',line=size)) + # + # pin 7: + # + self.shape = add(self.shape,translate(pad_HM11,-width/2.0+offset,-height/2.0+bottom+1*pitch,0)) + self.pad.append(point(-width/2.0+offset,-height/2.0+bottom+1*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'NC',line=size)) + # + # pin 8: + # + self.shape = add(self.shape,translate(pad_HM11,-width/2.0+offset,-height/2.0+bottom+0*pitch,0)) + self.pad.append(point(-width/2.0+offset,-height/2.0+bottom+0*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'NC',line=size)) + # + # pin 9: + # + self.shape = add(self.shape,translate(pad_HM11,width/2.0-offset,-height/2.0+bottom+0*pitch,0)) + self.pad.append(point(width/2.0-offset,-height/2.0+bottom+0*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VCC',line=size)) + # + # pin 10: + # + self.shape = add(self.shape,translate(pad_HM11,width/2.0-offset,-height/2.0+bottom+1*pitch,0)) + self.pad.append(point(width/2.0-offset,-height/2.0+bottom+1*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'NC',line=size)) + # + # pin 11: + # + self.shape = add(self.shape,translate(pad_HM11,width/2.0-offset,-height/2.0+bottom+2*pitch,0)) + self.pad.append(point(width/2.0-offset,-height/2.0+bottom+2*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RST',line=size)) + # + # pin 12: + # + self.shape = add(self.shape,translate(pad_HM11,width/2.0-offset,-height/2.0+bottom+3*pitch,0)) + self.pad.append(point(width/2.0-offset,-height/2.0+bottom+3*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND',line=size)) + # + # pin 13: + # + self.shape = add(self.shape,translate(pad_HM11,width/2.0-offset,-height/2.0+bottom+4*pitch,0)) + self.pad.append(point(width/2.0-offset,-height/2.0+bottom+4*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO3',line=size)) + # + # pin 14: + # + self.shape = add(self.shape,translate(pad_HM11,width/2.0-offset,-height/2.0+bottom+5*pitch,0)) + self.pad.append(point(width/2.0-offset,-height/2.0+bottom+5*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO2',line=size)) + # + # pin 15: + # + self.shape = add(self.shape,translate(pad_HM11,width/2.0-offset,-height/2.0+bottom+6*pitch,0)) + self.pad.append(point(width/2.0-offset,-height/2.0+bottom+6*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO1',line=size)) + # + # pin 16: + # + self.shape = add(self.shape,translate(pad_HM11,width/2.0-offset,-height/2.0+bottom+7*pitch,0)) + self.pad.append(point(width/2.0-offset,-height/2.0+bottom+7*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO0',line=size)) + +class ESP32_WROOM(part): + # + # ESP32-WROOM + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + pad = cube(-1/25.4,1/25.4,-.4/25.4,.4/25.4,0,0) + padb = cube(-.4/25.4,.4/25.4,-1/25.4,1/25.4,0,0) + width = 17/25.4 + height = 25.5/25.4 + pitch = 1.27/25.4 + # + # pin 1 + # + self.shape = translate(pad,-width/2,6*pitch,0) + self.pad.append(point(-width/2,6*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad,-width/2,5*pitch,0)) + self.pad.append(point(-width/2,5*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'3V3')) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad,-width/2,4*pitch,0)) + self.pad.append(point(-width/2,4*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'EN')) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad,-width/2,3*pitch,0)) + self.pad.append(point(-width/2,3*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VP')) + # + # pin 5 + # + self.shape = add(self.shape,translate(pad,-width/2,2*pitch,0)) + self.pad.append(point(-width/2,2*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VN')) + # + # pin 6 + # + self.shape = add(self.shape,translate(pad,-width/2,1*pitch,0)) + self.pad.append(point(-width/2,1*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO34')) + # + # pin 7 + # + self.shape = add(self.shape,translate(pad,-width/2,0*pitch,0)) + self.pad.append(point(-width/2,0*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO35')) + # + # pin 8 + # + self.shape = add(self.shape,translate(pad,-width/2,-1*pitch,0)) + self.pad.append(point(-width/2,-1*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO32')) + # + # pin 9 + # + self.shape = add(self.shape,translate(pad,-width/2,-2*pitch,0)) + self.pad.append(point(-width/2,-2*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO33')) + # + # pin 10 + # + self.shape = add(self.shape,translate(pad,-width/2,-3*pitch,0)) + self.pad.append(point(-width/2,-3*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO25')) + # + # pin 11 + # + self.shape = add(self.shape,translate(pad,-width/2,-4*pitch,0)) + self.pad.append(point(-width/2,-4*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO26')) + # + # pin 12 + # + self.shape = add(self.shape,translate(pad,-width/2,-5*pitch,0)) + self.pad.append(point(-width/2,-5*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO27')) + # + # pin 13 + # + self.shape = add(self.shape,translate(pad,-width/2,-6*pitch,0)) + self.pad.append(point(-width/2,-6*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO14')) + # + # pin 14 + # + self.shape = add(self.shape,translate(pad,-width/2,-7*pitch,0)) + self.pad.append(point(-width/2,-7*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO12')) + # + # pin 15 + # + self.shape = add(self.shape,translate(padb,-4.5*pitch,-7*pitch-1/25.4,0)) + self.pad.append(point(-4.5*pitch,-7*pitch-1/25.4,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND',angle=90)) + # + # pin 16 + # + self.shape = add(self.shape,translate(padb,-3.5*pitch,-7*pitch-1/25.4,0)) + self.pad.append(point(-3.5*pitch,-7*pitch-1/25.4,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO13',angle=90)) + # + # pin 17 + # + self.shape = add(self.shape,translate(padb,-2.5*pitch,-7*pitch-1/25.4,0)) + self.pad.append(point(-2.5*pitch,-7*pitch-1/25.4,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SHD',angle=90)) + # + # pin 18 + # + self.shape = add(self.shape,translate(padb,-1.5*pitch,-7*pitch-1/25.4,0)) + self.pad.append(point(-1.5*pitch,-7*pitch-1/25.4,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SWP',angle=90)) + # + # pin 19 + # + self.shape = add(self.shape,translate(padb,-0.5*pitch,-7*pitch-1/25.4,0)) + self.pad.append(point(-0.5*pitch,-7*pitch-1/25.4,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SCS',angle=90)) + # + # pin 20 + # + self.shape = add(self.shape,translate(padb,0.5*pitch,-7*pitch-1/25.4,0)) + self.pad.append(point(0.5*pitch,-7*pitch-1/25.4,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SCK',angle=90)) + # + # pin 21 + # + self.shape = add(self.shape,translate(padb,1.5*pitch,-7*pitch-1/25.4,0)) + self.pad.append(point(1.5*pitch,-7*pitch-1/25.4,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SDO',angle=90)) + # + # pin 22 + # + self.shape = add(self.shape,translate(padb,2.5*pitch,-7*pitch-1/25.4,0)) + self.pad.append(point(2.5*pitch,-7*pitch-1/25.4,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SDI',angle=90)) + # + # pin 23 + # + self.shape = add(self.shape,translate(padb,3.5*pitch,-7*pitch-1/25.4,0)) + self.pad.append(point(3.5*pitch,-7*pitch-1/25.4,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO15',angle=90)) + # + # pin 24 + # + self.shape = add(self.shape,translate(padb,4.5*pitch,-7*pitch-1/25.4,0)) + self.pad.append(point(4.5*pitch,-7*pitch-1/25.4,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO2',angle=90)) + # + # pin 25 + # + self.shape = add(self.shape,translate(pad,width/2,-7*pitch,0)) + self.pad.append(point(width/2,-7*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO0')) + # + # pin 26 + # + self.shape = add(self.shape,translate(pad,width/2,-6*pitch,0)) + self.pad.append(point(width/2,-6*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO4')) + # + # pin 27 + # + self.shape = add(self.shape,translate(pad,width/2,-5*pitch,0)) + self.pad.append(point(width/2,-5*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO16')) + # + # pin 28 + # + self.shape = add(self.shape,translate(pad,width/2,-4*pitch,0)) + self.pad.append(point(width/2,-4*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO17')) + # + # pin 29 + # + self.shape = add(self.shape,translate(pad,width/2,-3*pitch,0)) + self.pad.append(point(width/2,-3*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO5')) + # + # pin 30 + # + self.shape = add(self.shape,translate(pad,width/2,-2*pitch,0)) + self.pad.append(point(width/2,-2*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO18')) + # + # pin 31 + # + self.shape = add(self.shape,translate(pad,width/2,-1*pitch,0)) + self.pad.append(point(width/2,-1*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO19')) + # + # pin 32 + # + self.shape = add(self.shape,translate(pad,width/2,0*pitch,0)) + self.pad.append(point(width/2,0*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'NC')) + # + # pin 33 + # + self.shape = add(self.shape,translate(pad,width/2,1*pitch,0)) + self.pad.append(point(width/2,1*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO21')) + # + # pin 34 + # + self.shape = add(self.shape,translate(pad,width/2,2*pitch,0)) + self.pad.append(point(width/2,2*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RX0')) + # + # pin 35 + # + self.shape = add(self.shape,translate(pad,width/2,3*pitch,0)) + self.pad.append(point(width/2,3*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'TX0')) + # + # pin 36 + # + self.shape = add(self.shape,translate(pad,width/2,4*pitch,0)) + self.pad.append(point(width/2,4*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO22')) + # + # pin 37 + # + self.shape = add(self.shape,translate(pad,width/2,5*pitch,0)) + self.pad.append(point(width/2,5*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO23')) + # + # pin 38 + # + self.shape = add(self.shape,translate(pad,width/2,6*pitch,0)) + self.pad.append(point(width/2,6*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + +class ESP32_CAM(part): + # + # ESP32-CAM + # Sullins S5635-ND + # + def __init__(self,value=''): + pad_header = cube(-.079/2,.079/2,-.039/2,.039/2,0,0) + d = .209/2-.079/2 + w = 0.9 + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1 + # + self.shape = translate(pad_header,+d-w/2,.35,0) + self.pad.append(point(+d-w/2,.35,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'+5V')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad_header,-d-w/2,.25,0)) + self.pad.append(point(-d-w/2,.25,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad_header,+d-w/2,.15,0)) + self.pad.append(point(+d-w/2,.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO12')) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad_header,-d-w/2,.05,0)) + self.pad.append(point(-d-w/2,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO13')) + # + # pin 5 + # + self.shape = add(self.shape,translate(pad_header,+d-w/2,-.05,0)) + self.pad.append(point(+d-w/2,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO15')) + # + # pin 6 + # + self.shape = add(self.shape,translate(pad_header,-d-w/2,-.15,0)) + self.pad.append(point(-d-w/2,-.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO14')) + # + # pin 7 + # + self.shape = add(self.shape,translate(pad_header,+d-w/2,-.25,0)) + self.pad.append(point(+d-w/2,-.25,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO2')) + # + # pin 8 + # + self.shape = add(self.shape,translate(pad_header,-d-w/2,-.35,0)) + self.pad.append(point(-d-w/2,-.35,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO4')) + # + # pin 9 + # + self.shape = add(self.shape,translate(pad_header,-d+w/2,-.35,0)) + self.pad.append(point(-d+w/2,-.35,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 10 + # + self.shape = add(self.shape,translate(pad_header,+d+w/2,-.25,0)) + self.pad.append(point(+d+w/2,-.25,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'U0T')) + # + # pin 11 + # + self.shape = add(self.shape,translate(pad_header,-d+w/2,-.15,0)) + self.pad.append(point(-d+w/2,-.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'U0R')) + # + # pin 12 + # + self.shape = add(self.shape,translate(pad_header,+d+w/2,-.05,0)) + self.pad.append(point(+d+w/2,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VCC')) + # + # pin 13 + # + self.shape = add(self.shape,translate(pad_header,-d+w/2,.05,0)) + self.pad.append(point(-d+w/2,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 14 + # + self.shape = add(self.shape,translate(pad_header,+d+w/2,.15,0)) + self.pad.append(point(+d+w/2,.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO0')) + # + # pin 15 + # + self.shape = add(self.shape,translate(pad_header,-d+w/2,.25,0)) + self.pad.append(point(-d+w/2,.25,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO16')) + # + # pin 16 + # + self.shape = add(self.shape,translate(pad_header,+d+w/2,.35,0)) + self.pad.append(point(+d+w/2,.35,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'3V3')) + + +class ESP8266_12E(part): + # + # ESP8266 12E + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + height = 24/25.4 + width = 16/25.4 + pitch = 2/25.4 + bottom = 1.8/25.4 + left = 3/25.4 + offset = .4/25.4 - .01 + size = .004 + pad_ESP8266 = cube(-.0493,.0493,-.0197,.0197,0,0) + pad_ESP8266_bot = cube(-.0197,.0197,-.0415,.0415,0,0) + # + # pin 1: + # + self.shape = translate(pad_ESP8266,-width/2.0+offset,-height/2.0+bottom+7*pitch,0) + self.pad.append(point(-width/2.0+offset,-height/2.0+bottom+7*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RST',line=size)) + # + # pin 2: + # + self.shape = add(self.shape,translate(pad_ESP8266,-width/2.0+offset,-height/2.0+bottom+6*pitch,0)) + self.pad.append(point(-width/2.0+offset,-height/2.0+bottom+6*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'ADC',line=size)) + # + # pin 3: + # + self.shape = add(self.shape,translate(pad_ESP8266,-width/2.0+offset,-height/2.0+bottom+5*pitch,0)) + self.pad.append(point(-width/2.0+offset,-height/2.0+bottom+5*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'EN',line=size)) + # + # pin 4: + # + self.shape = add(self.shape,translate(pad_ESP8266,-width/2.0+offset,-height/2.0+bottom+4*pitch,0)) + self.pad.append(point(-width/2.0+offset,-height/2.0+bottom+4*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GPIO16',line=size)) + # + # pin 5: + # + self.shape = add(self.shape,translate(pad_ESP8266,-width/2.0+offset,-height/2.0+bottom+3*pitch,0)) + self.pad.append(point(-width/2.0+offset,-height/2.0+bottom+3*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GPIO14',line=size)) + # + # pin 6: + # + self.shape = add(self.shape,translate(pad_ESP8266,-width/2.0+offset,-height/2.0+bottom+2*pitch,0)) + self.pad.append(point(-width/2.0+offset,-height/2.0+bottom+2*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GPIO12',line=size)) + # + # pin 7: + # + self.shape = add(self.shape,translate(pad_ESP8266,-width/2.0+offset,-height/2.0+bottom+1*pitch,0)) + self.pad.append(point(-width/2.0+offset,-height/2.0+bottom+1*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GPIO13',line=size)) + # + # pin 8: + # + self.shape = add(self.shape,translate(pad_ESP8266,-width/2.0+offset,-height/2.0+bottom+0*pitch,0)) + self.pad.append(point(-width/2.0+offset,-height/2.0+bottom+0*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VDD',line=size)) + # + # pin 9: + # + self.shape = add(self.shape,translate(pad_ESP8266_bot,-width/2.0+left+0*pitch,-height/2.0+offset,0)) + self.pad.append(point(-width/2.0+left+0*pitch,-height/2.0+offset,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'CS',line=size,angle=90)) + # + # pin 10: + # + self.shape = add(self.shape,translate(pad_ESP8266_bot,-width/2.0+left+1*pitch,-height/2.0+offset,0)) + self.pad.append(point(-width/2.0+left+1*pitch,-height/2.0+offset,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'MISO',line=size,angle=90)) + # + # pin 11: + # + self.shape = add(self.shape,translate(pad_ESP8266_bot,-width/2.0+left+2*pitch,-height/2.0+offset,0)) + self.pad.append(point(-width/2.0+left+2*pitch,-height/2.0+offset,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GPIO9',line=size,angle=90)) + # + # pin 12: + # + self.shape = add(self.shape,translate(pad_ESP8266_bot,-width/2.0+left+3*pitch,-height/2.0+offset,0)) + self.pad.append(point(-width/2.0+left+3*pitch,-height/2.0+offset,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GPIO10',line=size,angle=90)) + # + # pin 13: + # + self.shape = add(self.shape,translate(pad_ESP8266_bot,-width/2.0+left+4*pitch,-height/2.0+offset,0)) + self.pad.append(point(-width/2.0+left+4*pitch,-height/2.0+offset,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'MOSI',line=size,angle=90)) + # + # pin 14: + # + self.shape = add(self.shape,translate(pad_ESP8266_bot,-width/2.0+left+5*pitch,-height/2.0+offset,0)) + self.pad.append(point(-width/2.0+left+5*pitch,-height/2.0+offset,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SCLK',line=size,angle=90)) + # + # pin 15: + # + self.shape = add(self.shape,translate(pad_ESP8266,width/2.0-offset,-height/2.0+bottom+0*pitch,0)) + self.pad.append(point(width/2.0-offset,-height/2.0+bottom+0*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND',line=size)) + # + # pin 16: + # + self.shape = add(self.shape,translate(pad_ESP8266,width/2.0-offset,-height/2.0+bottom+1*pitch,0)) + self.pad.append(point(width/2.0-offset,-height/2.0+bottom+1*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GPIO15',line=size)) + # + # pin 17: + # + self.shape = add(self.shape,translate(pad_ESP8266,width/2.0-offset,-height/2.0+bottom+2*pitch,0)) + self.pad.append(point(width/2.0-offset,-height/2.0+bottom+2*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GPIO2',line=size)) + # + # pin 18: + # + self.shape = add(self.shape,translate(pad_ESP8266,width/2.0-offset,-height/2.0+bottom+3*pitch,0)) + self.pad.append(point(width/2.0-offset,-height/2.0+bottom+3*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GPIO0',line=size)) + # + # pin 19: + # + self.shape = add(self.shape,translate(pad_ESP8266,width/2.0-offset,-height/2.0+bottom+4*pitch,0)) + self.pad.append(point(width/2.0-offset,-height/2.0+bottom+4*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GPIO4',line=size)) + # + # pin 20: + # + self.shape = add(self.shape,translate(pad_ESP8266,width/2.0-offset,-height/2.0+bottom+5*pitch,0)) + self.pad.append(point(width/2.0-offset,-height/2.0+bottom+5*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GPIO5',line=size)) + # + # pin 21: + # + self.shape = add(self.shape,translate(pad_ESP8266,width/2.0-offset,-height/2.0+bottom+6*pitch,0)) + self.pad.append(point(width/2.0-offset,-height/2.0+bottom+6*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RXD',line=size)) + # + # pin 22: + # + self.shape = add(self.shape,translate(pad_ESP8266,width/2.0-offset,-height/2.0+bottom+7*pitch,0)) + self.pad.append(point(width/2.0-offset,-height/2.0+bottom+7*pitch,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'TXD',line=size)) + +pad_MTA = cube(-.021,.021,-.041,.041,0,0) +pad_MTA_solder = cube(-.071,.071,-.041,.041,0,0) + +class MTA_2(part): + # + # AMP 1445121-2 + # MTA .050 SMT 2-pin vertical + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1 + # + self.shape = translate(pad_MTA,-.025,-.1,0) + self.pad.append(point(-.025,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad_MTA,.025,.1,0)) + self.pad.append(point(.025,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'2')) + # + # solder pads + # + self.shape = add(self.shape,translate(pad_MTA_solder,-.187,0,0)) + self.shape = add(self.shape,translate(pad_MTA_solder,.187,0,0)) + +class MTA_power(part): + # + # AMP 1445121-2 + # MTA .050 SMT 2-pin vertical + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: Gnd + # + self.shape = translate(pad_MTA,-.025,-.1,0) + self.pad.append(point(-.025,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1\nGND')) + # + # pin 2: Vcc + # + self.shape = add(self.shape,translate(pad_MTA,.025,.1,0)) + self.pad.append(point(.025,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'Vcc')) + # + # solder pads + # + self.shape = add(self.shape,translate(pad_MTA_solder,-.187,0,0)) + self.shape = add(self.shape,translate(pad_MTA_solder,.187,0,0)) + +class MTA_3(part): + # + # AMP 1445121-3 + # MTA .050 SMT 3-pin vertical + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: GND + # + self.shape = translate(pad_MTA,.05,.1,0) + self.pad.append(point(.05,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1')) + # + # pin 2: power + # + self.shape = add(self.shape,translate(pad_MTA,-.05,.1,0)) + self.pad.append(point(-.05,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'2')) + # + # pin 3: data + # + self.shape = add(self.shape,translate(pad_MTA,0,-.1,0)) + self.pad.append(point(0,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'3')) + # + # solder pads + # + self.shape = add(self.shape,translate(pad_MTA_solder,-.212,0,0)) + self.shape = add(self.shape,translate(pad_MTA_solder,.212,0,0)) + +class MTA_i0(part): + # + # AMP 1445121-3 + # MTA .050 SMT 3-pin vertical + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: GND + # + self.shape = translate(pad_MTA,.05,.1,0) + self.pad.append(point(.05,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1\nGND')) + # + # pin 2: power + # + self.shape = add(self.shape,translate(pad_MTA,-.05,.1,0)) + self.pad.append(point(-.05,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'V')) + # + # pin 3: data + # + self.shape = add(self.shape,translate(pad_MTA,0,-.1,0)) + self.pad.append(point(0,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'data')) + # + # solder pads + # + self.shape = add(self.shape,translate(pad_MTA_solder,-.212,0,0)) + self.shape = add(self.shape,translate(pad_MTA_solder,.212,0,0)) + +class MTA_4(part): + # + # AMP 1445121-4 + # MTA .050 SMT 4-pin vertical + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1 + # + self.shape = translate(pad_MTA,-.075,-.1,0) + self.pad.append(point(-.075,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad_MTA,.025,-.1,0)) + self.pad.append(point(.025,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'2')) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad_MTA,.075,.1,0)) + self.pad.append(point(.075,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'3')) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad_MTA,-.025,.1,0)) + self.pad.append(point(-.025,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'4')) + # + # solder pads + # + self.shape = add(self.shape,translate(pad_MTA_solder,-.237,0,0)) + self.shape = add(self.shape,translate(pad_MTA_solder,.237,0,0)) + +class MTA_serial(part): + # + # AMP 1445121-4 + # MTA .050 SMT 4-pin vertical + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: Gnd + # + self.shape = translate(pad_MTA,-.075,-.1,0) + self.pad.append(point(-.075,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1')) + # + # pin 2: Tx + # + self.shape = add(self.shape,translate(pad_MTA,.025,-.1,0)) + self.pad.append(point(.025,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'Tx')) + # + # pin 3: Rx + # + self.shape = add(self.shape,translate(pad_MTA,.075,.1,0)) + self.pad.append(point(.075,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'Rx')) + # + # pin 4: DTR + # + self.shape = add(self.shape,translate(pad_MTA,-.025,.1,0)) + self.pad.append(point(-.025,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'DTR')) + # + # solder pads + # + self.shape = add(self.shape,translate(pad_MTA_solder,-.237,0,0)) + self.shape = add(self.shape,translate(pad_MTA_solder,.237,0,0)) + +class MTA_PS2(part): + # + # AMP 1445121-4 + # MTA .050 SMT 4-pin vertical + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: GND + # + self.shape = translate(pad_MTA,-.075,-.1,0) + self.pad.append(point(-.075,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1\nGND')) + # + # pin 2: data + # + self.shape = add(self.shape,translate(pad_MTA,.025,-.1,0)) + self.pad.append(point(.025,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'data')) + # + # pin 3: clock + # + self.shape = add(self.shape,translate(pad_MTA,.075,.1,0)) + self.pad.append(point(.075,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'clock')) + # + # pin 4: 5V + # + self.shape = add(self.shape,translate(pad_MTA,-.025,.1,0)) + self.pad.append(point(-.025,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'5V')) + # + # solder pads + # + self.shape = add(self.shape,translate(pad_MTA_solder,-.237,0,0)) + self.shape = add(self.shape,translate(pad_MTA_solder,.237,0,0)) + +class MTA_5(part): + # + # AMP 1445121-5 + # MTA .050 SMT 5-pin vertical + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1 + # + self.shape = translate(pad_MTA,-.1,-.1,0) + self.pad.append(point(-.1,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad_MTA,0,-.1,0)) + self.pad.append(point(0,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'2')) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad_MTA,.1,-.1,0)) + self.pad.append(point(.1,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'3')) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad_MTA,.05,.1,0)) + self.pad.append(point(.05,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'4')) + # + # pin 5 + # + self.shape = add(self.shape,translate(pad_MTA,-.05,.1,0)) + self.pad.append(point(-.05,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'5')) + # + # solder pads + # + self.shape = add(self.shape,translate(pad_MTA_solder,-.262,0,0)) + self.shape = add(self.shape,translate(pad_MTA_solder,.262,0,0)) + +class MTA_ICP(part): + # + # AMP 1445121-5 + # MTA .050 SMT 5-pin vertical + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: MISO + # + self.shape = translate(pad_MTA,-.1,-.1,0) + self.pad.append(point(-.1,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'MISO')) + # + # pin 2: GND + # + self.shape = add(self.shape,translate(pad_MTA,0,-.1,0)) + self.pad.append(point(0,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 3: MOSI + # + self.shape = add(self.shape,translate(pad_MTA,.1,-.1,0)) + self.pad.append(point(.1,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'MOSI')) + # + # pin 4: -RESET + # + self.shape = add(self.shape,translate(pad_MTA,.05,.1,0)) + self.pad.append(point(.05,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'-RESET')) + # + # pin 5: SCK + # + self.shape = add(self.shape,translate(pad_MTA,-.05,.1,0)) + self.pad.append(point(-.05,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SCK')) + # + # solder pads + # + self.shape = add(self.shape,translate(pad_MTA_solder,-.262,0,0)) + self.shape = add(self.shape,translate(pad_MTA_solder,.262,0,0)) + +pad_screw_terminal = cylinder(0,0,0,0,.047) +hole_screw_terminal = circle(0,0,.025) + +class screw_terminal_2(part): + # + # On Shore ED555/2DS + # two position screw terminal + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1 + # + self.shape = translate(pad_screw_terminal,-.069,0,0) + self.pad.append(point(-.069,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad_screw_terminal,.069,0,0)) + self.pad.append(point(.069,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'2')) + # + # holes + # + self.shape = add(self.shape,translate(hole_screw_terminal,-.069,0,0)) + self.shape = add(self.shape,translate(hole_screw_terminal,.069,0,0)) + +class screw_terminal_power(part): + # + # On Shore ED555/2DS + # power screw terminal + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1 + # + self.shape = translate(pad_screw_terminal,-.069,0,0) + self.pad.append(point(-.069,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'G')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad_screw_terminal,.069,0,0)) + self.pad.append(point(.069,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'V')) + # + # holes + # + self.shape = add(self.shape,translate(hole_screw_terminal,-.069,0,0)) + self.shape = add(self.shape,translate(hole_screw_terminal,.069,0,0)) + +class screw_terminal_i0(part): + # + # On Shore ED555/3DS + # i0 screw terminal + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: Gnd + # + self.shape = translate(pad_screw_terminal,-.138,0,0) + self.pad.append(point(-.138,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'Gnd\n1')) + # + # pin 2: data + # + self.shape = add(self.shape,pad_screw_terminal) + self.pad.append(point(0,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'data')) + # + # pin 3: V + # + self.shape = add(self.shape,translate(pad_screw_terminal,.138,0,0)) + self.pad.append(point(.138,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'V')) + # + # holes + # + self.shape = add(self.shape,translate(hole_screw_terminal,-.138,0,0)) + self.shape = add(self.shape,hole_screw_terminal) + self.shape = add(self.shape,translate(hole_screw_terminal,.138,0,0)) + +class power_65mm(part): + # + # CUI PJ1-023-SMT + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: power + # + self.shape = cube(.433,.512,-.047,.047,0,0) + self.pad.append(point(.467,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'P')) + # + # pin 2: ground + # + self.shape = add(self.shape,cube(.285,.423,-.189,-.098,0,0)) + self.pad.append(point(.354,-.144,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'G')) + # + # pin 3: contact + # + self.shape = add(self.shape,cube(.325,.463,.098,.189,0,0)) + self.pad.append(point(.394,.144,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'C')) + # + # solder pads + # + self.shape = add(self.shape,cube(.108,.246,-.169,-.110,0,0)) + self.shape = add(self.shape,cube(.069,.207,.110,.169,0,0)) + +pad_stereo_2_5mm = cube(-.03,.03,-.05,.05,0,0) + +class stereo_2_5mm(part): + # + # CUI SJ1-2533-SMT + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: base + # + self.shape = translate(pad_stereo_2_5mm,-.130,-.16,0) + self.pad.append(point(-.130,-.149,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'base')) + # + # pin 2: tip + # + self.shape = add(self.shape,translate(pad_stereo_2_5mm,.197,.15,0)) + self.pad.append(point(.197,.141,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'tip')) + # + # pin 3: middle + # + self.shape = add(self.shape,translate(pad_stereo_2_5mm,-.012,-.16,0)) + self.pad.append(point(-.012,-.149,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'middle')) + +pad_Molex = cube(-.0155,.0155,-.0265,.0265,0,0) +pad_Molex_solder = cube(-.055,.055,-.065,.065,0,0) + +class Molex_serial(part): + # + # Molex 53261-0471 + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: Rx + # + self.shape = translate(pad_Molex,-.075,.064,0) + self.pad.append(point(-.075,.064,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'Rx')) + # + # pin 2: Tx + # + self.shape = add(self.shape,translate(pad_Molex,-.025,.064,0)) + self.pad.append(point(-.025,.064,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'Tx')) + # + # pin 3: DTR + # + self.shape = add(self.shape,translate(pad_Molex,.025,.064,0)) + self.pad.append(point(.025,.064,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'DTR')) + # + # pin 4: GND + # + self.shape = add(self.shape,translate(pad_Molex,.075,.064,0)) + self.pad.append(point(.075,.064,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # solder pads + # + self.shape = add(self.shape,translate(pad_Molex_solder,-.16,-.065,0)) + self.shape = add(self.shape,translate(pad_Molex_solder,.16,-.065,0)) + +############################################################ +# switches +############################################################ + +class slide_switch(part): + # + # slide switch + # C&K AYZ0102AGRLC + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + pad = cube(-.039/2,.039/2,-.047/2,.047/2,0,0) + # + # pad 1 + # + self.shape = translate(pad,-.098,.1,0) + self.pad.append(point(-.098,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'')) + # + # pad 2 + # + self.shape = add(self.shape,translate(pad,0,.1,0)) + self.pad.append(point(0,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'')) + # + # pad 3 + # + self.shape = add(self.shape,translate(pad,.098,.1,0)) + self.pad.append(point(.098,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'')) + # + # holes + # + self.holes = cylinder(-.118/2,0,zb,zt,.034/2) + self.holes = add(self.holes,cylinder(.118/2,0,zb,zt,.034/2)) + +class button_6mm(part): + # + # Omron 6mm pushbutton + # B3SN-3112P + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + pad_button_6mm = cube(-.04,.04,-.03,.03,0,0) + # + # left 1 + # + self.shape = translate(pad_button_6mm,-.125,.08,0) + self.pad.append(point(-.125,.08,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'L1')) + # + # right 1 + # + self.shape = add(self.shape,translate(pad_button_6mm,-.125,-.08,0)) + self.pad.append(point(-.125,-.08,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'R1')) + # + # right 2 + # + self.shape = add(self.shape,translate(pad_button_6mm,.125,-.08,0)) + self.pad.append(point(.125,-.08,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'R2')) + # + # left 2 + # + self.shape = add(self.shape,translate(pad_button_6mm,.125,.08,0)) + self.pad.append(point(.125,.08,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'L2')) + +############################################################ +# crystals and resonators +############################################################ + +pad_XTAL_EFOBM = cube(-.016,.016,-.085,.085,0,0) + +class XTAL_EFOBM(part): + # + # Panasonic EFOBM series + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # left + # + self.shape = translate(pad_XTAL_EFOBM,-.053,0,0) + self.pad.append(point(-.053,0,0)) + # + # ground + # + self.shape = add(self.shape,translate(pad_XTAL_EFOBM,0,0,0)) + self.pad.append(point(0,0,0)) + # + # right + # + self.shape = add(self.shape,translate(pad_XTAL_EFOBM,.053,0,0)) + self.pad.append(point(.053,0,0)) + +pad_XTAL_NX5032GA = cube(-.039,.039,-.047,.047,0,0) +.079 + +class XTAL_NX5032GA(part): + # + # NDK NX5032GA + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # left + # + self.shape = translate(pad_XTAL_NX5032GA,-.079,0,0) + self.pad.append(point(-.079,0,0)) + # + # right + # + self.shape = add(self.shape,translate(pad_XTAL_NX5032GA,.079,0,0)) + self.pad.append(point(.079,0,0)) + +pad_XTAL_CSM_7 = cube(-.108,.108,-.039,.039,0,0) + +class XTAL_CSM_7(part): + # + # ECS CSM-7 series + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # left + # + self.shape = translate(pad_XTAL_CSM_7,-.187,0,0) + self.pad.append(point(-.187,0,0)) + # + # right + # + self.shape = add(self.shape,translate(pad_XTAL_CSM_7,.187,0,0)) + self.pad.append(point(.187,0,0)) + +############################################################ +# diodes, transistors, regulators, sensors +############################################################ + +class DRV8428P_HTSSOP(part): + # + # TI DRV8428PPWPR stepper driver + # HTSSOP package + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + d = 0.12 + w = 0.029 + h = 0.0053 + p = 0.02559 + pad = cube(-w,w,-h,h,0,0) + s = 0.003 + # + # pin 1 + # + self.shape = translate(pad,-d,3.5*p,0) + self.shape = add(self.shape,cylinder(-d-w,3.5*p,0,0,h)) + self.pad.append(point(-d,3.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'.VM',line=s)) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad,-d,2.5*p,0)) + self.pad.append(point(-d,2.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PGND',line=s)) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad,-d,1.5*p,0)) + self.pad.append(point(-d,1.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'AOUT1',line=s)) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad,-d,.5*p,0)) + self.pad.append(point(-d,.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'AOUT2',line=s)) + # + # pin 5 + # + self.shape = add(self.shape,translate(pad,-d,-.5*p,0)) + self.pad.append(point(-d,-.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'BOUT2',line=s)) + # + # pin 6 + # + self.shape = add(self.shape,translate(pad,-d,-1.5*p,0)) + self.pad.append(point(-d,-1.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'BOUT1',line=s)) + # + # pin 7 + # + self.shape = add(self.shape,translate(pad,-d,-2.5*p,0)) + self.pad.append(point(-d,-2.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND',line=s)) + # + # pin 8 + # + self.shape = add(self.shape,translate(pad,-d,-3.5*p,0)) + self.pad.append(point(-d,-3.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'DVDD',line=s)) + # + # pin 9 + # + self.shape = add(self.shape,translate(pad,d,-3.5*p,0)) + self.pad.append(point(d,-3.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VREFB',line=s)) + # + # pin 10 + # + self.shape = add(self.shape,translate(pad,d,-2.5*p,0)) + self.pad.append(point(d,-2.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VREFA',line=s)) + # + # pin 11 + # + self.shape = add(self.shape,translate(pad,d,-1.5*p,0)) + self.pad.append(point(d,-1.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'DECAY',line=s)) + # + # pin 12 + # + self.shape = add(self.shape,translate(pad,d,-.5*p,0)) + self.pad.append(point(d,-.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'BIN2',line=s)) + # + # pin 13 + # + self.shape = add(self.shape,translate(pad,d,.5*p,0)) + self.pad.append(point(d,.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'BIN1',line=s)) + # + # pin 14 + # + self.shape = add(self.shape,translate(pad,d,1.5*p,0)) + self.pad.append(point(d,1.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'AIN2',line=s)) + # + # pin 15 + # + self.shape = add(self.shape,translate(pad,d,2.5*p,0)) + self.pad.append(point(d,2.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'AIN1',line=s)) + # + # pin 16 + # + self.shape = add(self.shape,translate(pad,d,3.5*p,0)) + self.pad.append(point(d,3.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SLEEP',line=s)) + # + # pin 17 + # + self.shape = add(self.shape,translate(cube(-.06,.06,-.09,.09,0,0),0,0,0)) + self.pad.append(point(0,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND',line=s)) + +class LED_3014_1100(part): + # + # Luminus MP-3014-1100-50-80 + # + def __init__(self,value=''): + anode = cube(-.011,.011,-.027,.027,0,0) + cathode = cube(-.036,.036,-.027,.027,0,0) + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # anode + # + self.shape = translate(anode,-.047,0,0) + self.pad.append(point(-.047,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A')) + # + # cathode + # + self.shape = add(self.shape,translate(cathode,.022,0,0)) + self.pad.append(point(.022,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'C')) + +class CMM4030D261I2STR(part): + # + # CUI CMM-4030D-261-I2S-TR I2S microphone + # + def __init__(self,value=''): + pad = cube(-.018,.018,-.011,.011,0,0) + self.value = value + self.x = 0 + self.y = 0 + self.z = 0 + self.pad = [point(0,0,0)] + self.labels = [] + s = 0.004 + # + # pin 1 + # + self.shape = translate(pad,.037,-.059,0) + self.pad.append(point(.037,-.059,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND.',line=s)) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad,.037,-.019,0)) + self.pad.append(point(.037,-.019,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'N/C',line=s)) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad,.037,.019,0)) + self.pad.append(point(.037,.019,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'WS',line=s)) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad,.037,.059,0)) + self.pad.append(point(.037,.059,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'EN',line=s)) + # + # pin 5 + # + self.shape = add(self.shape,translate(pad,-.037,.059,0)) + self.pad.append(point(-.037,.059,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'L/R',line=s)) + # + # pin 6 + # + self.shape = add(self.shape,translate(pad,-.037,.019,0)) + self.pad.append(point(-.037,.019,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SCK',line=s)) + # + # pin 7 + # + self.shape = add(self.shape,translate(pad,-.037,-.019,0)) + self.pad.append(point(-.037,-.019,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SD',line=s)) + # + # pin 8 + # + self.shape = add(self.shape,translate(pad,-.037,-.059,0)) + self.pad.append(point(-.037,-.059,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VDD',line=s)) + +class SPG08P4HM4H(part): + # + # Knowles SPG08P4HM4H-1 PDM microphone + # + def __init__(self,value=''): + pad = cube(-.011,.011,-.011,.011,0,0) + self.value = value + self.x = 0 + self.y = 0 + self.z = 0 + self.pad = [point(0,0,0)] + self.labels = [] + s = 0.004 + # + # pin 1 + # + self.shape = translate(pad,.023,-.037,0) + self.pad.append(point(.023,-.037,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'V.',line=s)) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad,.023,0,0)) + self.pad.append(point(.023,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'G',line=s)) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad,.023,.037,0)) + self.pad.append(point(.023,.037,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'DAT',line=s)) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad,-.023,.037,0)) + self.pad.append(point(-.023,.037,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'CK',line=s)) + # + # pin 5 + # + self.shape = add(self.shape,translate(pad,-.023,0,0)) + self.pad.append(point(-.023,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'G',line=s)) + # + # pin 6 + # + self.shape = add(self.shape,translate(pad,-.023,-.037,0)) + self.pad.append(point(-.023,-.037,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SEL',line=s)) + +class VEML6040(part): + # + # Vishay VEML6040 color sensor + # + def __init__(self,value=''): + pad12 = cube(-.016,.019,-.006,.006,0,0) + pad3 = cube(-.023,.016,-.006,.006,0,0) + pad4 = cube(-.019,.016,-.006,.006,0,0) + self.value = value + self.x = 0 + self.y = 0 + self.z = 0 + self.pad = [point(0,0,0)] + self.labels = [] + s = 0.004 + # + # pin 1 + # + self.shape = translate(pad12,-.039,.014,0) + self.pad.append(point(-.039,.014,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1GND',line=s)) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad12,-.039,-.014,0)) + self.pad.append(point(-.039,-.014,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SDA',line=s)) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad3,.039,-.014,0)) + self.pad.append(point(.039,-.014,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SCL',line=s)) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad4,.039,.014,0)) + self.pad.append(point(.039,.014,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VDD',line=s)) + +class D_1206(part): + # + # 1206 diode + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # anode + # + self.shape = translate(pad_1206,-.06,0,0) + self.pad.append(point(-.055,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A')) + # + # cathode + # + self.shape = add(self.shape,translate(pad_1206,.06,0,0)) + self.pad.append(point(.055,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'C')) + +class LED_1206(part): + # + # 1206 LED + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # anode + # + self.shape = translate(pad_1206,-.06,0,0) + self.pad.append(point(-.055,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A')) + # + # cathode + # + self.shape = add(self.shape,translate(pad_1206,.06,0,0)) + self.pad.append(point(.055,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'C')) + +pad_RGB = cube(-.02,.02,-.029,.029,0,0) + +class LED_RGB(part): + # + # CREE CLV1A-FKB + # + def __init__(self,value=''): + self.value = value + self.x = 0 + self.y = 0 + self.z = 0 + self.pad = [point(0,0,0)] + self.labels = [] + dx = .029 + dy = .059 + # + # pin 1: red + # + self.shape = translate(pad_RGB,-dx,-dy,0) + self.shape = add(self.shape,cylinder(-dx,-dy-.029,0,0,.02)) + self.pad.append(point(-dx,-dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'R')) + # + # pin 2: anode + # + self.shape = add(self.shape,translate(pad_RGB,dx,-dy,0)) + self.pad.append(point(dx,-dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A')) + # + # pin 3: blue + # + self.shape = add(self.shape,translate(pad_RGB,dx,dy,0)) + self.pad.append(point(dx,dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'B')) + # + # pin 4: green + # + self.shape = add(self.shape,translate(pad_RGB,-dx,dy,0)) + self.pad.append(point(-dx,dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'G')) + +class phototransistor_1206(part): + # + # 1206 phototransistor + # OPTEK 520,521 + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # collector + # + self.shape = translate(pad_1206,-.06,0,0) + self.pad.append(point(-.055,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'C')) + # + # emitter + # + self.shape = add(self.shape,translate(pad_1206,.06,0,0)) + self.pad.append(point(.055,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'E')) + +pad_PLCC2 = cube(-.029,.029,-.059,.059,0,0) + +class phototransistor_PLCC2(part): + # + # PLCC2 phototransistor + # Optek OP580 + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # collector + # + self.shape = translate(pad_PLCC2,-.065,0,0) + self.pad.append(point(-.065,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'C')) + # + # emitter + # + self.shape = add(self.shape,translate(pad_PLCC2,.065,0,0)) + self.pad.append(point(.065,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'E')) + +pad_SOD_123 = cube(-.02,.02,-.024,.024,0,0) + +class D_SOD_123(part): + # + # SOD-123 diode + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # anode + # + self.shape = translate(pad_SOD_123,-.07,0,0) + self.pad.append(point(-.07,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A')) + # + # cathode + # + self.shape = add(self.shape,translate(pad_SOD_123,.07,0,0)) + self.pad.append(point(.07,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'C')) + +pad_SOT23 = cube(-.02,.02,-.012,.012,0,0) + +class NMOSFET_SOT23(part): + # + # Fairchild NDS355AN + # + def __init__(self,value=''): + self.value = value + self.x = 0 + self.y = 0 + self.z = 0 + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: gate + # + self.shape = translate(pad_SOT23,.045,-.0375,0) + self.pad.append(point(.045,-.0375,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'G')) + # + # pin 2: source + # + self.shape = add(self.shape,translate(pad_SOT23,.045,.0375,0)) + self.pad.append(point(.045,.0375,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'S')) + # + # pin 3: drain + # + self.shape = add(self.shape,translate(pad_SOT23,-.045,0,0)) + self.pad.append(point(-.045,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'D')) + +class PMOSFET_SOT23(part): + # + # Fairchild NDS356AP + # + def __init__(self,value=''): + self.value = value + self.x = 0 + self.y = 0 + self.z = 0 + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: gate + # + self.shape = translate(pad_SOT23,.045,-.0375,0) + self.pad.append(point(.045,-.0375,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'G')) + # + # pin 2: source + # + self.shape = add(self.shape,translate(pad_SOT23,.045,.0375,0)) + self.pad.append(point(.045,.0375,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'S')) + # + # pin 3: drain + # + self.shape = add(self.shape,translate(pad_SOT23,-.045,0,0)) + self.pad.append(point(-.045,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'D')) + +class NMOSFET_TO252AA(part): + # + # Fairchild RFD16N05LSM + # + def __init__(self,value=''): + self.value = value + self.x = 0 + self.y = 0 + self.z = 0 + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: gate + # + self.shape = translate(cube(-.031,.031,-.059,.059,0,0),-.090,0,0) + self.pad.append(point(-.090,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'G 1')) + # + # pin 2: source + # + self.shape = add(self.shape,translate(cube(-.031,.031,-.059,.059,0,0),.090,0,0)) + self.pad.append(point(.090,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'S')) + # + # pin 3: drain + # + self.shape = add(self.shape,translate(cube(-.132,.132,-.132,.132,0,0),0,.261,0)) + self.pad.append(point(0,.261,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'D')) + +class Hall_SOT23(part): + # + # Allegro A1324 + # + def __init__(self,value=''): + self.value = value + self.x = 0 + self.y = 0 + self.z = 0 + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: output + # + self.shape = translate(pad_SOT23,-.045,.0375,0) + self.pad.append(point(-.045,.0375,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'Vcc')) + # + # pin 2: input + # + self.shape = add(self.shape,translate(pad_SOT23,-.045,-.0375,0)) + self.pad.append(point(-.045,-.0375,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'out')) + # + # pin 3: ground + # + self.shape = add(self.shape,translate(pad_SOT23,.045,0,0)) + self.pad.append(point(.045,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'gnd')) + +class regulator_SOT23(part): + # + # TI LM3480IM3 + # + def __init__(self,value=''): + self.value = value + self.x = 0 + self.y = 0 + self.z = 0 + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: output + # + self.shape = translate(pad_SOT23,-.045,.0375,0) + self.pad.append(point(-.045,.0375,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'out')) + # + # pin 2: input + # + self.shape = add(self.shape,translate(pad_SOT23,-.045,-.0375,0)) + self.pad.append(point(-.045,-.0375,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'in')) + # + # pin 3: ground + # + self.shape = add(self.shape,translate(pad_SOT23,.045,0,0)) + self.pad.append(point(.045,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'gnd')) + +class regulator_SOT223(part): + # + # Zetex ZLDO1117 + # + def __init__(self,value=''): + self.value = value + self.x = 0 + self.y = 0 + self.z = 0 + self.pad = [point(0,0,0)] + self.labels = [] + pad_SOT223 = cube(-.02,.02,-.03,.03,0,0) + pad_SOT223_ground = cube(-.065,.065,-.03,.03,0,0) + # + # pin 1: GND + # + self.shape = translate(pad_SOT223,-.09,-.12,0) + self.pad.append(point(-.09,-.12,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1G')) + # + # pin 2: output + # + self.shape = add(self.shape,translate(pad_SOT223,0,-.12,0)) + self.pad.append(point(0,-.12,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'O')) + # + # pin 3: input + # + self.shape = add(self.shape,translate(pad_SOT223,.09,-.12,0)) + self.pad.append(point(.09,-.12,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'I')) + # + # pin 4: output + # + self.shape = add(self.shape,translate(pad_SOT223_ground,0,.12,0)) + self.pad.append(point(0,.12,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'out')) + +class A4953_SOICN(part): + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: GND + # + self.shape = translate(pad_SOIC,-.11,.075,0) + self.shape = add(self.shape,cylinder(-.153,.075,0,0,.015)) + self.pad.append(point(-.11,.075,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 2: IN2 + # + self.shape = add(self.shape,translate(pad_SOIC,-.11,.025,0)) + self.pad.append(point(-.11,.025,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IN2')) + # + # pin 3: IN1 + # + self.shape = add(self.shape,translate(pad_SOIC,-.11,-.025,0)) + self.pad.append(point(-.11,-.025,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IN1')) + # + # pin 4: VREF + # + self.shape = add(self.shape,translate(pad_SOIC,-.11,-.075,0)) + self.pad.append(point(-.11,-.075,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VREF')) + # + # pin 5: VBB + # + self.shape = add(self.shape,translate(pad_SOIC,.11,-.075,0)) + self.pad.append(point(.11,-.075,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VBB')) + # + # pin 6: OUT1 + # + self.shape = add(self.shape,translate(pad_SOIC,.11,-.025,0)) + self.pad.append(point(.11,-.025,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'OUT1')) + # + # pin 7: LSS + # + self.shape = add(self.shape,translate(pad_SOIC,.11,.025,0)) + self.pad.append(point(.11,.025,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'LSS')) + # + # pin 8: OUT2 + # + self.shape = add(self.shape,translate(pad_SOIC,.11,.075,0)) + self.pad.append(point(.11,.075,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'OUT2')) + # + # thermal pad + # + self.shape = add(self.shape,rectangle(-.04,.04,-.075,.075)) + +pad_SM8 = cube(-.035,.035,-.016,.016,0,0) + +class H_bridge_SM8(part): + # + # Zetex ZXMHC3A01T8 + # + def __init__(self,value=''): + self.value = value + self.x = 0 + self.y = 0 + self.z = 0 + self.pad = [point(0,0,0)] + self.labels = [] + d = .13 + # + # pin 1: G3 (right N gate) + # + self.shape = translate(pad_SM8,-d,.09,0) + self.shape = add(self.shape,cylinder(-d-.035,.09,0,0,.016)) + self.pad.append(point(-d,.09,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GRN')) + # + # pin 2: S2 S3 (N source) + # + self.shape = add(self.shape,translate(pad_SM8,-d,.03,0)) + self.pad.append(point(-d,.03,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SN')) + # + # pin 3: G2 (left N gate) + # + self.shape = add(self.shape,translate(pad_SM8,-d,-.03,0)) + self.pad.append(point(-d,-.03,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GLN')) + # + # pin 4: G1 (left P gate) + # + self.shape = add(self.shape,translate(pad_SM8,-d,-.09,0)) + self.pad.append(point(-d,-.09,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GLP')) + # + # pin 5: D1 D2 (left drain) + # + self.shape = add(self.shape,translate(pad_SM8,d,-.09,0)) + self.pad.append(point(d,-.09,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'DL')) + # + # pin 6: S1 S4 (P source) + # + self.shape = add(self.shape,translate(pad_SM8,d,-.03,0)) + self.pad.append(point(d,-.03,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SP')) + # + # pin 7: D3 D4 (right drain) + # + self.shape = add(self.shape,translate(pad_SM8,d,.03,0)) + self.pad.append(point(d,.03,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'DR')) + # + # pin 8: G4 (right N gate) + # + self.shape = add(self.shape,translate(pad_SM8,d,.09,0)) + self.pad.append(point(d,.09,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GRP')) + +pad_mic = cylinder(0,0,0,0,.02) + +class mic_SPU0414HR5H(part): + # + # Knowles SPU0414HR5H-SB + # + def __init__(self,value=''): + s = 0.004 + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: Vdd + # + self.shape = translate(pad_mic,.033,.048,0) + self.pad.append(point(.033,.048,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'V1',line=s)) + # + # pin 2: GND + # + self.shape = add(self.shape,translate(pad_mic,.033,-.048,0)) + self.pad.append(point(.033,-.048,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND',line=s)) + # + # pin 3: gain + # + self.shape = add(self.shape,translate(pad_mic,-.033,-.048,0)) + self.pad.append(point(-.033,-.048,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'gain',line=s)) + # + # pin 4: out + # + self.shape = add(self.shape,translate(pad_mic,-.033,.048,0)) + self.pad.append(point(-.033,.048,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'out',line=s)) + +class mic_SPM1437(part): + # + # Knowles SPM1437HM4H-B + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1 + # + self.shape = translate(pad_mic,-.046,.065,0) + #self.shape = add(self.shape,cylinder(-.183,.075,0,0,.015)) + self.pad.append(point(-.046,.065,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad_mic,-.046,0,0)) + self.pad.append(point(-.046,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SEL')) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad_mic,-.046,-.065,0)) + self.pad.append(point(-.046,-.065,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad_mic,.046,-.065,0)) + self.pad.append(point(.046,-.065,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'CLK')) + # + # pin 5 + # + self.shape = add(self.shape,translate(pad_mic,.046,0,0)) + self.pad.append(point(.046,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'DAT')) + # + # pin 6 + # + self.shape = add(self.shape,translate(pad_mic,.046,.065,0)) + self.shape = add(self.shape,translate(pad_mic,.038,.057,0)) + self.pad.append(point(.046,.065,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'V')) + +pad_accel = cube(-.03,.03,-.0125,.0125,0,0) +pad_accel90 = cube(-.0125,.0125,-.03,.03,0,0) + +class accel_MXD6235M(part): + # + # MEMSIC MXD6235M + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1 + # + self.shape = translate(pad_accel,-.1,.05,0) + self.shape = add(self.shape,cylinder(-.13,.05,0,0,.0125)) + self.pad.append(point(-.1,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad_accel,-.1,0,0)) + self.pad.append(point(-.1,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'TP')) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad_accel,-.1,-.05,0)) + self.pad.append(point(-.1,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'G')) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad_accel90,0,-.1,0)) + self.pad.append(point(0,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'NC')) + # + # pin 5 + # + self.shape = add(self.shape,translate(pad_accel,.1,-.05,0)) + self.pad.append(point(.1,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'NC')) + # + # pin 6 + # + self.shape = add(self.shape,translate(pad_accel,.1,0,0)) + self.pad.append(point(.1,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'Y')) + # + # pin 7 + # + self.shape = add(self.shape,translate(pad_accel,.1,.05,0)) + self.pad.append(point(.1,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'X')) + # + # pin 8 + # + self.shape = add(self.shape,translate(pad_accel90,0,.1,0)) + self.pad.append(point(0,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'V')) + # + # ground plane + # + self.shape = add(self.shape,cube(-.05,.05,-.05,.05,0,0)) + +pad_cc_14_1 = cube(-.014,.014,-.0075,.0075,0,0) +pad_cc_14_1_90 = cube(-.0075,.0075,-.014,.014,0,0) + +class ADXL343(part): + # + # ADI ADXL343 accelerometer + # + def __init__(self,value=''): + d = 0.8/25.4 + w = 1.01/25.4 + s = 0.004 + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1 + # + self.shape = translate(pad_cc_14_1,-w,2.5*d,0) + self.pad.append(point(-w,2.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,"VD1",line=s)) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad_cc_14_1,-w,1.5*d,0)) + self.pad.append(point(-w,1.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND',line=s)) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad_cc_14_1,-w,.5*d,0)) + self.pad.append(point(-w,.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RSV',line=s)) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad_cc_14_1,-w,-.5*d,0)) + self.pad.append(point(-w,-.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND',line=s)) + # + # pin 5 + # + self.shape = add(self.shape,translate(pad_cc_14_1,-w,-1.5*d,0)) + self.pad.append(point(-w,-1.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND',line=s)) + # + # pin 6 + # + self.shape = add(self.shape,translate(pad_cc_14_1,-w,-2.5*d,0)) + self.pad.append(point(-w,-2.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VS',line=s)) + # + # pin 7 + # + self.shape = add(self.shape,translate(pad_cc_14_1_90,0,-2.5*d,0)) + self.pad.append(point(0,-2.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'-CS',angle=90,line=s)) + # + # pin 8 + # + self.shape = add(self.shape,translate(pad_cc_14_1,w,-2.5*d,0)) + self.pad.append(point(w,-2.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'INT1',line=s)) + # + # pin 9 + # + self.shape = add(self.shape,translate(pad_cc_14_1,w,-1.5*d,0)) + self.pad.append(point(w,-1.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'INT2',line=s)) + # + # pin 10 + # + self.shape = add(self.shape,translate(pad_cc_14_1,w,-.5*d,0)) + self.pad.append(point(w,-.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'NC',line=s)) + # + # pin 11 + # + self.shape = add(self.shape,translate(pad_cc_14_1,w,.5*d,0)) + self.pad.append(point(w,.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RSV',line=s)) + # + # pin 12 + # + self.shape = add(self.shape,translate(pad_cc_14_1,w,1.5*d,0)) + self.pad.append(point(w,1.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'ALT',line=s)) + # + # pin 13 + # + self.shape = add(self.shape,translate(pad_cc_14_1,w,2.5*d,0)) + self.pad.append(point(w,2.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SDA',line=s)) + # + # pin 14 + # + self.shape = add(self.shape,translate(pad_cc_14_1_90,0,2.5*d,0)) + self.pad.append(point(0,2.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SCL',angle=90,line=s)) + +class VL53L1X(part): + # + # ST VL53L1X time of flight sensor + # + def __init__(self,value=''): + pad = cube(-.0075,.0075,-.0075,.0075,0,0) + d = 0.8/25.4 + w = 0.8/25.4 + s = 0.004 + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1 + # + self.shape = translate(pad,-w,-2*d,0) + self.pad.append(point(-w,-2*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,"1V",line=s)) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad,-w,-1*d,0)) + self.pad.append(point(-w,-1*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'G',line=s)) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad,-w,0*d,0)) + self.pad.append(point(-w,0*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'G',line=s)) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad,-w,1*d,0)) + self.pad.append(point(-w,1*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'G',line=s)) + # + # pin 5 + # + self.shape = add(self.shape,translate(pad,-w,2*d,0)) + self.pad.append(point(-w,2*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'XS',line=s)) + # + # pin 6 + # + self.shape = add(self.shape,translate(pad,0,2*d,0)) + self.pad.append(point(0,2*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'G',line=s)) + # + # pin 7 + # + self.shape = add(self.shape,translate(pad,w,2*d,0)) + self.pad.append(point(w,2*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IO',line=s)) + # + # pin 8 + # + self.shape = add(self.shape,translate(pad,w,1*d,0)) + self.pad.append(point(w,1*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'NC',line=s)) + # + # pin 9 + # + self.shape = add(self.shape,translate(pad,w,0*d,0)) + self.pad.append(point(w,0*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SDA',line=s)) + # + # pin 10 + # + self.shape = add(self.shape,translate(pad,w,-1*d,0)) + self.pad.append(point(w,-1*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SCL',line=s)) + # + # pin 11 + # + self.shape = add(self.shape,translate(pad,w,-2*d,0)) + self.pad.append(point(w,-2*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'V',line=s)) + # + # pin 12 + # + self.shape = add(self.shape,translate(pad,0,-2*d,0)) + self.pad.append(point(0,-2*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'G',line=s)) + +############################################################ +# ICs +############################################################ + +class AVRDB28(part): + # + # AVR*DB28 + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + d = 9.01/2/25.4 # spacing + w = 0.4/2/25.4 # width + h = 1.4/2/25.4 # height + p = 0.8/25.4 # pitch + l = 0.004 # text + pad = cube(-h,h,-w,w,0,0) + padv = cube(-w,w,-h,h,0,0) + # + # pin 1 + # + self.shape = translate(pad,-d,3.5*p,0) + self.shape = add(self.shape,cylinder(-d-h,3.5*p,0,0,w)) + self.pad.append(point(-d,3.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'.PA3',line=l)) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad,-d,2.5*p,0)) + self.pad.append(point(-d,2.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA4',line=l)) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad,-d,1.5*p,0)) + self.pad.append(point(-d,1.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA5',line=l)) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad,-d,.5*p,0)) + self.pad.append(point(-d,.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA6',line=l)) + # + # pin 5 + # + self.shape = add(self.shape,translate(pad,-d,-.5*p,0)) + self.pad.append(point(-d,-.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA7',line=l)) + # + # pin 6 + # + self.shape = add(self.shape,translate(pad,-d,-1.5*p,0)) + self.pad.append(point(-d,-1.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC0',line=l)) + # + # pin 7 + # + self.shape = add(self.shape,translate(pad,-d,-2.5*p,0)) + self.pad.append(point(-d,-2.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC1',line=l)) + # + # pin 8 + # + self.shape = add(self.shape,translate(pad,-d,-3.5*p,0)) + self.pad.append(point(-d,-3.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC2',line=l)) + # + # pin 9 + # + self.shape = add(self.shape,translate(padv,-3.5*p,-d,0)) + self.pad.append(point(-3.5*p,-d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC3',line=l,angle=-90)) + # + # pin 10 + # + self.shape = add(self.shape,translate(padv,-2.5*p,-d,0)) + self.pad.append(point(-2.5*p,-d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VIO2',line=l,angle=-90)) + # + # pin 11 + # + self.shape = add(self.shape,translate(padv,-1.5*p,-d,0)) + self.pad.append(point(-1.5*p,-d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD1',line=l,angle=-90)) + # + # pin 12 + # + self.shape = add(self.shape,translate(padv,-.5*p,-d,0)) + self.pad.append(point(-.5*p,-d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD2',line=l,angle=-90)) + # + # pin 13 + # + self.shape = add(self.shape,translate(padv,.5*p,-d,0)) + self.pad.append(point(.5*p,-d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD3',line=l,angle=-90)) + # + # pin 14 + # + self.shape = add(self.shape,translate(padv,1.5*p,-d,0)) + self.pad.append(point(1.5*p,-d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD4',line=l,angle=-90)) + # + # pin 15 + # + self.shape = add(self.shape,translate(padv,2.5*p,-d,0)) + self.pad.append(point(2.5*p,-d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD5',line=l,angle=-90)) + # + # pin 16 + # + self.shape = add(self.shape,translate(padv,3.5*p,-d,0)) + self.pad.append(point(3.5*p,-d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD6',line=l,angle=-90)) + # + # pin 17 + # + self.shape = add(self.shape,translate(pad,d,-3.5*p,0)) + self.pad.append(point(d,-3.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD7',line=l)) + # + # pin 18 + # + self.shape = add(self.shape,translate(pad,d,-2.5*p,0)) + self.pad.append(point(d,-2.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'AVDD',line=l)) + # + # pin 19 + # + self.shape = add(self.shape,translate(pad,d,-1.5*p,0)) + self.pad.append(point(d,-1.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND',line=l)) + # + # pin 20 + # + self.shape = add(self.shape,translate(pad,d,-.5*p,0)) + self.pad.append(point(d,-.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PF0',line=l)) + # + # pin 21 + # + self.shape = add(self.shape,translate(pad,d,.5*p,0)) + self.pad.append(point(d,.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PF1',line=l)) + # + # pin 22 + # + self.shape = add(self.shape,translate(pad,d,1.5*p,0)) + self.pad.append(point(d,1.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PF2',line=l)) + # + # pin 23 + # + self.shape = add(self.shape,translate(pad,d,2.5*p,0)) + self.pad.append(point(d,2.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PF3',line=l)) + # + # pin 24 + # + self.shape = add(self.shape,translate(pad,d,3.5*p,0)) + self.pad.append(point(d,3.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PF4',line=l)) + # + # pin 25 + # + self.shape = add(self.shape,translate(padv,3.5*p,d,0)) + self.pad.append(point(3.5*p,d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PF5',line=l,angle=-90)) + # + # pin 26 + # + self.shape = add(self.shape,translate(padv,2.5*p,d,0)) + self.pad.append(point(2.5*p,d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PF6',line=l,angle=-90)) + # + # pin 27 + # + self.shape = add(self.shape,translate(padv,1.5*p,d,0)) + self.pad.append(point(1.5*p,d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'UPDI',line=l,angle=-90)) + # + # pin 28 + # + self.shape = add(self.shape,translate(padv,.5*p,d,0)) + self.pad.append(point(.5*p,d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VDD',line=l,angle=-90)) + # + # pin 29 + # + self.shape = add(self.shape,translate(padv,-.5*p,d,0)) + self.pad.append(point(-.5*p,d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND',line=l,angle=-90)) + # + # pin 30 + # + self.shape = add(self.shape,translate(padv,-1.5*p,d,0)) + self.pad.append(point(-1.5*p,d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA0',line=l,angle=-90)) + # + # pin 31 + # + self.shape = add(self.shape,translate(padv,-2.5*p,d,0)) + self.pad.append(point(-2.5*p,d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA1',line=l,angle=-90)) + # + # pin 32 + # + self.shape = add(self.shape,translate(padv,-3.5*p,d,0)) + self.pad.append(point(-3.5*p,d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA2',line=l,angle=-90)) + +class ATtiny3216(part): + # + # SOIC-20 + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + d = 9.82/2/25.4 + w = .63/2/25.4 + h = 1.9/2/25.4 + pad = cube(-h,h,-w,w,0,0) + # + # pin 1 + # + self.shape = translate(pad,-d,.225,0) + self.shape = add(self.shape,cylinder(-d-h,.225,0,0,w)) + self.pad.append(point(-d,.225,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1VCC')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad,-d,.175,0)) + self.pad.append(point(-d,.175,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA4')) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad,-d,.125,0)) + self.pad.append(point(-d,.125,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA5')) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad,-d,.075,0)) + self.pad.append(point(-d,.075,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA6')) + # + # pin 5 + # + self.shape = add(self.shape,translate(pad,-d,.025,0)) + self.pad.append(point(-d,.025,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA7')) + # + # pin 6 + # + self.shape = add(self.shape,translate(pad,-d,-.025,0)) + self.pad.append(point(-d,-.025,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PB5')) + # + # pin 7 + # + self.shape = add(self.shape,translate(pad,-d,-.075,0)) + self.pad.append(point(-d,-.075,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PB4')) + # + # pin 8 + # + self.shape = add(self.shape,translate(pad,-d,-.125,0)) + self.pad.append(point(-d,-.125,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RB3')) + # + # pin 9 + # + self.shape = add(self.shape,translate(pad,-d,-.175,0)) + self.pad.append(point(-d,-.175,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'TB2')) + # + # pin 10 + # + self.shape = add(self.shape,translate(pad,-d,-.225,0)) + self.pad.append(point(-d,-.225,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PB1')) + # + # pin 11 + # + self.shape = add(self.shape,translate(pad,d,-.225,0)) + self.pad.append(point(d,-.225,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PB0')) + # + # pin 12 + # + self.shape = add(self.shape,translate(pad,d,-.175,0)) + self.pad.append(point(d,-.175,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC0')) + # + # pin 13 + # + self.shape = add(self.shape,translate(pad,d,-.125,0)) + self.pad.append(point(d,-.125,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC1')) + # + # pin 14 + # + self.shape = add(self.shape,translate(pad,d,-.075,0)) + self.pad.append(point(d,-.075,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC2')) + # + # pin 15 + # + self.shape = add(self.shape,translate(pad,d,-.025,0)) + self.pad.append(point(d,-.025,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC3')) + # + # pin 16 + # + self.shape = add(self.shape,translate(pad,d,.025,0)) + self.pad.append(point(d,.025,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'UPDI')) + # + # pin 17 + # + self.shape = add(self.shape,translate(pad,d,.075,0)) + self.pad.append(point(d,.075,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA1')) + # + # pin 18 + # + self.shape = add(self.shape,translate(pad,d,.125,0)) + self.pad.append(point(d,.125,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA2')) + # + # pin 19 + # + self.shape = add(self.shape,translate(pad,d,.175,0)) + self.pad.append(point(d,.175,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA3')) + # + # pin 20 + # + self.shape = add(self.shape,translate(pad,d,.225,0)) + self.pad.append(point(d,.225,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + +class SAMD21E(part): + # + # TQFP + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + d = 9.01/2/25.4 # spacing + w = 0.4/2/25.4 # width + h = 1.4/2/25.4 # height + p = 0.8/25.4 # pitch + l = 0.004 # text + pad = cube(-h,h,-w,w,0,0) + padv = cube(-w,w,-h,h,0,0) + # + # pin 1 + # + self.shape = translate(pad,-d,3.5*p,0) + self.shape = add(self.shape,cylinder(-d-h,3.5*p,0,0,w)) + self.pad.append(point(-d,3.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1A0',line=l)) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad,-d,2.5*p,0)) + self.pad.append(point(-d,2.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A01',line=l)) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad,-d,1.5*p,0)) + self.pad.append(point(-d,1.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A02',line=l)) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad,-d,.5*p,0)) + self.pad.append(point(-d,.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A03',line=l)) + # + # pin 5 + # + self.shape = add(self.shape,translate(pad,-d,-.5*p,0)) + self.pad.append(point(-d,-.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A04',line=l)) + # + # pin 6 + # + self.shape = add(self.shape,translate(pad,-d,-1.5*p,0)) + self.pad.append(point(-d,-1.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A05',line=l)) + # + # pin 7 + # + self.shape = add(self.shape,translate(pad,-d,-2.5*p,0)) + self.pad.append(point(-d,-2.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A06',line=l)) + # + # pin 8 + # + self.shape = add(self.shape,translate(pad,-d,-3.5*p,0)) + self.pad.append(point(-d,-3.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A07',line=l)) + # + # pin 9 + # + self.shape = add(self.shape,translate(padv,-3.5*p,-d,0)) + self.pad.append(point(-3.5*p,-d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VAN',line=l,angle=-90)) + # + # pin 10 + # + self.shape = add(self.shape,translate(padv,-2.5*p,-d,0)) + self.pad.append(point(-2.5*p,-d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND',line=l,angle=-90)) + # + # pin 11 + # + self.shape = add(self.shape,translate(padv,-1.5*p,-d,0)) + self.pad.append(point(-1.5*p,-d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A08',line=l,angle=-90)) + # + # pin 12 + # + self.shape = add(self.shape,translate(padv,-.5*p,-d,0)) + self.pad.append(point(-.5*p,-d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A09',line=l,angle=-90)) + # + # pin 13 + # + self.shape = add(self.shape,translate(padv,.5*p,-d,0)) + self.pad.append(point(.5*p,-d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A10',line=l,angle=-90)) + # + # pin 14 + # + self.shape = add(self.shape,translate(padv,1.5*p,-d,0)) + self.pad.append(point(1.5*p,-d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A11',line=l,angle=-90)) + # + # pin 15 + # + self.shape = add(self.shape,translate(padv,2.5*p,-d,0)) + self.pad.append(point(2.5*p,-d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A14',line=l,angle=-90)) + # + # pin 16 + # + self.shape = add(self.shape,translate(padv,3.5*p,-d,0)) + self.pad.append(point(3.5*p,-d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A15',line=l,angle=-90)) + # + # pin 17 + # + self.shape = add(self.shape,translate(pad,d,-3.5*p,0)) + self.pad.append(point(d,-3.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A16',line=l)) + # + # pin 18 + # + self.shape = add(self.shape,translate(pad,d,-2.5*p,0)) + self.pad.append(point(d,-2.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A17',line=l)) + # + # pin 19 + # + self.shape = add(self.shape,translate(pad,d,-1.5*p,0)) + self.pad.append(point(d,-1.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A18',line=l)) + # + # pin 20 + # + self.shape = add(self.shape,translate(pad,d,-.5*p,0)) + self.pad.append(point(d,-.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A19',line=l)) + # + # pin 21 + # + self.shape = add(self.shape,translate(pad,d,.5*p,0)) + self.pad.append(point(d,.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A22',line=l)) + # + # pin 22 + # + self.shape = add(self.shape,translate(pad,d,1.5*p,0)) + self.pad.append(point(d,1.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A23',line=l)) + # + # pin 23 + # + self.shape = add(self.shape,translate(pad,d,2.5*p,0)) + self.pad.append(point(d,2.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'24-',line=l)) + # + # pin 24 + # + self.shape = add(self.shape,translate(pad,d,3.5*p,0)) + self.pad.append(point(d,3.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'25+',line=l)) + # + # pin 25 + # + self.shape = add(self.shape,translate(padv,3.5*p,d,0)) + self.pad.append(point(3.5*p,d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A27',line=l,angle=-90)) + # + # pin 26 + # + self.shape = add(self.shape,translate(padv,2.5*p,d,0)) + self.pad.append(point(2.5*p,d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RST',line=l,angle=-90)) + # + # pin 27 + # + self.shape = add(self.shape,translate(padv,1.5*p,d,0)) + self.pad.append(point(1.5*p,d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A28',line=l,angle=-90)) + # + # pin 28 + # + self.shape = add(self.shape,translate(padv,.5*p,d,0)) + self.pad.append(point(.5*p,d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND',line=l,angle=-90)) + # + # pin 29 + # + self.shape = add(self.shape,translate(padv,-.5*p,d,0)) + self.pad.append(point(-.5*p,d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VCR',line=l,angle=-90)) + # + # pin 30 + # + self.shape = add(self.shape,translate(padv,-1.5*p,d,0)) + self.pad.append(point(-1.5*p,d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VIN',line=l,angle=-90)) + # + # pin 31 + # + self.shape = add(self.shape,translate(padv,-2.5*p,d,0)) + self.pad.append(point(-2.5*p,d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'CLK',line=l,angle=-90)) + # + # pin 32 + # + self.shape = add(self.shape,translate(padv,-3.5*p,d,0)) + self.pad.append(point(-3.5*p,d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'DIO',line=l,angle=-90)) + +class SAMD11D(part): + # + # SOIC-20 + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + d = 9.82/2/25.4 + w = .63/2/25.4 + h = 1.9/2/25.4 + pad = cube(-h,h,-w,w,0,0) + # + # pin 1 + # + self.shape = translate(pad,-d,.225,0) + self.shape = add(self.shape,cylinder(-d-h,.225,0,0,w)) + self.pad.append(point(-d,.225,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1A05')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad,-d,.175,0)) + self.pad.append(point(-d,.175,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A06')) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad,-d,.125,0)) + self.pad.append(point(-d,.125,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A07')) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad,-d,.075,0)) + self.pad.append(point(-d,.075,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A08')) + # + # pin 5 + # + self.shape = add(self.shape,translate(pad,-d,.025,0)) + self.pad.append(point(-d,.025,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A09')) + # + # pin 6 + # + self.shape = add(self.shape,translate(pad,-d,-.025,0)) + self.pad.append(point(-d,-.025,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A14')) + # + # pin 7 + # + self.shape = add(self.shape,translate(pad,-d,-.075,0)) + self.pad.append(point(-d,-.075,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A15')) + # + # pin 8 + # + self.shape = add(self.shape,translate(pad,-d,-.125,0)) + self.pad.append(point(-d,-.125,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A16')) + # + # pin 9 + # + self.shape = add(self.shape,translate(pad,-d,-.175,0)) + self.pad.append(point(-d,-.175,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A22')) + # + # pin 10 + # + self.shape = add(self.shape,translate(pad,-d,-.225,0)) + self.pad.append(point(-d,-.225,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A23')) + # + # pin 11 + # + self.shape = add(self.shape,translate(pad,d,-.225,0)) + self.pad.append(point(d,-.225,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RST')) + # + # pin 12 + # + self.shape = add(self.shape,translate(pad,d,-.175,0)) + self.pad.append(point(d,-.175,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'CLK')) + # + # pin 13 + # + self.shape = add(self.shape,translate(pad,d,-.125,0)) + self.pad.append(point(d,-.125,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'DIO')) + # + # pin 14 + # + self.shape = add(self.shape,translate(pad,d,-.075,0)) + self.pad.append(point(d,-.075,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'24-')) + # + # pin 15 + # + self.shape = add(self.shape,translate(pad,d,-.025,0)) + self.pad.append(point(d,-.025,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'25+')) + # + # pin 16 + # + self.shape = add(self.shape,translate(pad,d,.025,0)) + self.pad.append(point(d,.025,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 17 + # + self.shape = add(self.shape,translate(pad,d,.075,0)) + self.pad.append(point(d,.075,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VCC')) + # + # pin 18 + # + self.shape = add(self.shape,translate(pad,d,.125,0)) + self.pad.append(point(d,.125,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A02')) + # + # pin 19 + # + self.shape = add(self.shape,translate(pad,d,.175,0)) + self.pad.append(point(d,.175,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A03')) + # + # pin 20 + # + self.shape = add(self.shape,translate(pad,d,.225,0)) + self.pad.append(point(d,.225,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A04')) + +class ATtiny1614(part): + # + # SOIC + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + d = 0.11 + w = 0.015 + h = .03 + pad = cube(-h,h,-w,w,0,0) + # + # pin 1 + # + self.shape = translate(pad,-d,.15,0) + self.shape = add(self.shape,cylinder(-d-h,.15,0,0,w)) + self.pad.append(point(-d,.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'.VCC')) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad,-d,.1,0)) + self.pad.append(point(-d,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA4')) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad,-d,.050,0)) + self.pad.append(point(-d,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA5')) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad,-d,0,0)) + self.pad.append(point(-d,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA6')) + # + # pin 5 + # + self.shape = add(self.shape,translate(pad,-d,-.05,0)) + self.pad.append(point(-d,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA7')) + # + # pin 6 + # + self.shape = add(self.shape,translate(pad,-d,-.1,0)) + self.pad.append(point(-d,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RB3')) + # + # pin 7 + # + self.shape = add(self.shape,translate(pad,-d,-.15,0)) + self.pad.append(point(-d,-.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'TB2')) + # + # pin 8 + # + self.shape = add(self.shape,translate(pad,d,-.15,0)) + self.pad.append(point(d,-.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PB1')) + # + # pin 9 + # + self.shape = add(self.shape,translate(pad,d,-.1,0)) + self.pad.append(point(d,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PB0')) + # + # pin 10 + # + self.shape = add(self.shape,translate(pad,d,-.05,0)) + self.pad.append(point(d,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'UPDI')) + # + # pin 11 + # + self.shape = add(self.shape,translate(pad,d,0,0)) + self.pad.append(point(d,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA1')) + # + # pin 12 + # + self.shape = add(self.shape,translate(pad,d,.050,0)) + self.pad.append(point(d,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA2')) + # + # pin 13 + # + self.shape = add(self.shape,translate(pad,d,.1,0)) + self.pad.append(point(d,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA3')) + # + # pin 14 + self.shape = add(self.shape,translate(pad,d,.15,0)) + self.pad.append(point(d,.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + +class FT230XS(part): + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + d = 0.11 + w = 0.0053 + h = .03 + p = .65/25.4 + l = 0.004 + pad = cube(-h,h,-w,w,0,0) + # + # pin 1 + # + self.shape = translate(pad,-d,3.5*p,0) + self.shape = add(self.shape,cylinder(-d-h,3.5*p,0,0,w)) + self.pad.append(point(-d,3.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1TXD',line=l)) + # + # pin 2 + # + self.shape = add(self.shape,translate(pad,-d,2.5*p,0)) + self.pad.append(point(-d,2.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RTS',line=l)) + # + # pin 3 + # + self.shape = add(self.shape,translate(pad,-d,1.5*p,0)) + self.pad.append(point(-d,1.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VIO',line=l)) + # + # pin 4 + # + self.shape = add(self.shape,translate(pad,-d,.5*p,0)) + self.pad.append(point(-d,.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RXD',line=l)) + # + # pin 5 + # + self.shape = add(self.shape,translate(pad,-d,-.5*p,0)) + self.pad.append(point(-d,-.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND',line=l)) + # + # pin 6 + # + self.shape = add(self.shape,translate(pad,-d,-1.5*p,0)) + self.pad.append(point(-d,-1.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'CTS',line=l)) + # + # pin 7 + # + self.shape = add(self.shape,translate(pad,-d,-2.5*p,0)) + self.pad.append(point(-d,-2.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'CB2',line=l)) + # + # pin 8 + # + self.shape = add(self.shape,translate(pad,-d,-3.5*p,0)) + self.pad.append(point(-d,-3.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'USP',line=l)) + # + # pin 9 + # + self.shape = add(self.shape,translate(pad,d,-3.5*p,0)) + self.pad.append(point(d,-3.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'USM',line=l)) + # + # pin 10 + # + self.shape = add(self.shape,translate(pad,d,-2.5*p,0)) + self.pad.append(point(d,-2.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'3V3',line=l)) + # + # pin 11 + # + self.shape = add(self.shape,translate(pad,d,-1.5*p,0)) + self.pad.append(point(d,-1.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RST',line=l)) + # + # pin 12 + # + self.shape = add(self.shape,translate(pad,d,-.5*p,0)) + self.pad.append(point(d,-.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VCC',line=l)) + # + # pin 13 + # + self.shape = add(self.shape,translate(pad,d,.5*p,0)) + self.pad.append(point(d,.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND',line=l)) + # + # pin 14 + self.shape = add(self.shape,translate(pad,d,1.5*p,0)) + self.pad.append(point(d,1.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'CB1',line=l)) + # + # pin 15 + # + self.shape = add(self.shape,translate(pad,d,2.5*p,0)) + self.pad.append(point(d,2.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'CB0',line=l)) + # + # pin 16 + self.shape = add(self.shape,translate(pad,d,3.5*p,0)) + self.pad.append(point(d,3.5*p,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'CB3',line=l)) + + +class ATtiny412(part): + # + # SOIC150 + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + d = 0.11 + w = 0.015 + h = .03 + pad = cube(-h,h,-w,w,0,0) + # + # pin 1: VCC + # + self.shape = translate(pad,-d,.075,0) + self.shape = add(self.shape,cylinder(-d-h,.075,0,0,w)) + self.pad.append(point(-d,.075,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VCC')) + # + # pin 2: PA6 + # + self.shape = add(self.shape,translate(pad,-d,.025,0)) + self.pad.append(point(-d,.025,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA6')) + # + # pin 3: PA7 + # + self.shape = add(self.shape,translate(pad,-d,-.025,0)) + self.pad.append(point(-d,-.025,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA7')) + # + # pin 4: PA1 + # + self.shape = add(self.shape,translate(pad,-d,-.075,0)) + self.pad.append(point(-d,-.075,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA1')) + # + # pin 5: PA2 + # + self.shape = add(self.shape,translate(pad,d,-.075,0)) + self.pad.append(point(d,-.075,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA2')) + # + # pin 6: UPDI + # + self.shape = add(self.shape,translate(pad,d,-.025,0)) + self.pad.append(point(d,-.025,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'UPDI')) + # + # pin 7: PA3 + # + self.shape = add(self.shape,translate(pad,d,.025,0)) + self.pad.append(point(d,.025,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA3')) + # + # pin 8: GND + # + self.shape = add(self.shape,translate(pad,d,.075,0)) + self.pad.append(point(d,.075,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + +class SAMD11C(part): + # + # SOIC + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + d = 0.11 + w = 0.015 + h = .03 + pad = cube(-h,h,-w,w,0,0) + # + # pin 1: PA05 + # + self.shape = translate(pad,-d,.15,0) + self.shape = add(self.shape,cylinder(-d-h,.15,0,0,w)) + self.pad.append(point(-d,.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1A05')) + # + # pin 2: PA08 + # + self.shape = add(self.shape,translate(pad,-d,.1,0)) + self.pad.append(point(-d,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A08')) + # + # pin 3: PA09 + # + self.shape = add(self.shape,translate(pad,-d,.050,0)) + self.pad.append(point(-d,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A09')) + # + # pin 4: PA14 + # + self.shape = add(self.shape,translate(pad,-d,0,0)) + self.pad.append(point(-d,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A14')) + # + # pin 5: PA15 + # + self.shape = add(self.shape,translate(pad,-d,-.05,0)) + self.pad.append(point(-d,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A15')) + # + # pin 6: nRESET + # + self.shape = add(self.shape,translate(pad,-d,-.1,0)) + self.pad.append(point(-d,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RST')) + # + # pin 7: CLK + # + self.shape = add(self.shape,translate(pad,-d,-.15,0)) + self.pad.append(point(-d,-.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'CLK')) + # + # pin 8: DIO + # + self.shape = add(self.shape,translate(pad,d,-.15,0)) + self.pad.append(point(d,-.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'DIO')) + # + # pin 9: PA24/D- + # + self.shape = add(self.shape,translate(pad,d,-.1,0)) + self.pad.append(point(d,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'24-')) + # + # pin 10: PA25/D+ + # + self.shape = add(self.shape,translate(pad,d,-.05,0)) + self.pad.append(point(d,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'25+')) + # + # pin 11: GND + # + self.shape = add(self.shape,translate(pad,d,0,0)) + self.pad.append(point(d,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 12: VDD + # + self.shape = add(self.shape,translate(pad,d,.050,0)) + self.pad.append(point(d,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VDD')) + # + # pin 13: PA02 + # + self.shape = add(self.shape,translate(pad,d,.1,0)) + self.pad.append(point(d,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A02')) + # + # pin 14: PA04 + # + self.shape = add(self.shape,translate(pad,d,.15,0)) + self.pad.append(point(d,.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A04')) + +pad_SOT23_5 = cube(-.01,.01,-.02,.02,0,0) + +class op_amp_SOT23_5(part): + def __init__(self,value=''): + self.value = value + self.x = 0 + self.y = 0 + self.z = 0 + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: output + # + self.shape = translate(pad_SOT23_5,-.0375,-.045,0) + self.pad.append(point(-.0375,-.045,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'O')) + # + # pin 2: V- + # + self.shape = add(self.shape,translate(pad_SOT23_5,0,-.045,0)) + self.pad.append(point(0,-.045,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'V-')) + # + # pin 3: I+ + # + self.shape = add(self.shape,translate(pad_SOT23_5,.0375,-.045,0)) + self.pad.append(point(.0375,-.045,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'I+')) + # + # pin 4: I- + # + self.shape = add(self.shape,translate(pad_SOT23_5,.0375,.045,0)) + self.pad.append(point(.0375,.045,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'I-')) + # + # pin 5: V+ + # + self.shape = add(self.shape,translate(pad_SOT23_5,-.0375,.045,0)) + self.pad.append(point(-.0375,.045,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'V+')) + +pad_SOICN = cube(-.035,.035,-.015,.015,0,0) + +class op_amp_SOICN(part): + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: A out + # + self.shape = translate(pad_SOICN,-.12,.075,0) + self.pad.append(point(-.12,.075,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1 Ao')) + # + # pin 2: A- + # + self.shape = add(self.shape,translate(pad_SOICN,-.12,.025,0)) + self.pad.append(point(-.12,.025,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A-')) + # + # pin 3: A+ + # + self.shape = add(self.shape,translate(pad_SOICN,-.12,-.025,0)) + self.pad.append(point(-.12,-.025,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'A+')) + # + # pin 4: V- + # + self.shape = add(self.shape,translate(pad_SOICN,-.12,-.075,0)) + self.pad.append(point(-.12,-.075,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'V-')) + # + # pin 5: B+ + # + self.shape = add(self.shape,translate(pad_SOICN,.12,-.075,0)) + self.pad.append(point(.12,-.075,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'B+')) + # + # pin 6: B- + # + self.shape = add(self.shape,translate(pad_SOICN,.12,-.025,0)) + self.pad.append(point(.12,-.025,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'B-')) + # + # pin 7: B out + # + self.shape = add(self.shape,translate(pad_SOICN,.12,.025,0)) + self.pad.append(point(.12,.025,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'Bo')) + # + # pin 8: V+ + # + self.shape = add(self.shape,translate(pad_SOICN,.12,.075,0)) + self.pad.append(point(.12,.075,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'V+')) + +TSSOP_pad_width = 0.040 +TSSOP_pad_height = 0.011 +TSSOP_pad_dy = 0.026 +TSSOP_pad_dx = 0.120 +pad_TSSOP = cube(-TSSOP_pad_width/2.0,TSSOP_pad_width/2.0,-TSSOP_pad_height/2.0,TSSOP_pad_height/2.0,0,0) + +class TRC102(part): + # + # RFM TRC102 ISM transceiver + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: SDI + # + self.shape = translate(pad_TSSOP,-TSSOP_pad_dx,3.5*TSSOP_pad_dy,0) + self.pad.append(point(-TSSOP_pad_dx,3.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1 SDI')) + # + # pin 2: SCK + # + self.shape = add(self.shape,translate(pad_TSSOP,-TSSOP_pad_dx,2.5*TSSOP_pad_dy,0)) + self.pad.append(point(-TSSOP_pad_dx,2.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SCK')) + # + # pin 3: nCS + # + self.shape = add(self.shape,translate(pad_TSSOP,-TSSOP_pad_dx,1.5*TSSOP_pad_dy,0)) + self.pad.append(point(-TSSOP_pad_dx,1.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'nCS')) + # + # pin 4: SDO + # + self.shape = add(self.shape,translate(pad_TSSOP,-TSSOP_pad_dx,0.5*TSSOP_pad_dy,0)) + self.pad.append(point(-TSSOP_pad_dx,0.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SDO')) + # + # pin 5: IRQ + # + self.shape = add(self.shape,translate(pad_TSSOP,-TSSOP_pad_dx,-0.5*TSSOP_pad_dy,0)) + self.pad.append(point(-TSSOP_pad_dx,-0.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IRQ')) + # + # pin 6: DATA/nFSEL + # + self.shape = add(self.shape,translate(pad_TSSOP,-TSSOP_pad_dx,-1.5*TSSOP_pad_dy,0)) + self.pad.append(point(-TSSOP_pad_dx,-1.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'DATA')) + # + # pin 7: CR + # + self.shape = add(self.shape,translate(pad_TSSOP,-TSSOP_pad_dx,-2.5*TSSOP_pad_dy,0)) + self.pad.append(point(-TSSOP_pad_dx,-2.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'CR')) + # + # pin 8: CLKOUT + # + self.shape = add(self.shape,translate(pad_TSSOP,-TSSOP_pad_dx,-3.5*TSSOP_pad_dy,0)) + self.pad.append(point(-TSSOP_pad_dx,-3.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'CLKOUT')) + # + # pin 9: Xtal/Ref + # + self.shape = add(self.shape,translate(pad_TSSOP,TSSOP_pad_dx,-3.5*TSSOP_pad_dy,0)) + self.pad.append(point(TSSOP_pad_dx,-3.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'Xtal')) + # + # pin 10: RESET + # + self.shape = add(self.shape,translate(pad_TSSOP,TSSOP_pad_dx,-2.5*TSSOP_pad_dy,0)) + self.pad.append(point(TSSOP_pad_dx,-2.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RESET')) + # + # pin 11: GND + # + self.shape = add(self.shape,translate(pad_TSSOP,TSSOP_pad_dx,-1.5*TSSOP_pad_dy,0)) + self.pad.append(point(TSSOP_pad_dx,-1.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 12: RF_P + # + self.shape = add(self.shape,translate(pad_TSSOP,TSSOP_pad_dx,-0.5*TSSOP_pad_dy,0)) + self.pad.append(point(TSSOP_pad_dx,-0.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RF_P')) + # + # pin 13: RF_N + # + self.shape = add(self.shape,translate(pad_TSSOP,TSSOP_pad_dx,0.5*TSSOP_pad_dy,0)) + self.pad.append(point(TSSOP_pad_dx,0.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RF_N')) + # + # pin 14: VDD + # + self.shape = add(self.shape,translate(pad_TSSOP,TSSOP_pad_dx,1.5*TSSOP_pad_dy,0)) + self.pad.append(point(TSSOP_pad_dx,1.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VDD')) + # + # pin 15: RSSIA + # + self.shape = add(self.shape,translate(pad_TSSOP,TSSOP_pad_dx,2.5*TSSOP_pad_dy,0)) + self.pad.append(point(TSSOP_pad_dx,2.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RSSIA')) + # + # pin 16: nINT/DDET + # + self.shape = add(self.shape,translate(pad_TSSOP,TSSOP_pad_dx,3.5*TSSOP_pad_dy,0)) + self.pad.append(point(TSSOP_pad_dx,3.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'nINT')) + +pad_SOIC = cube(-.041,.041,-.015,.015,0,0) + +class ATtiny45_SOIC(part): + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: PB5/dW/ADC0/-RESET/PCINT5 + # + self.shape = translate(pad_SOIC,-.14,.075,0) + self.shape = add(self.shape,cylinder(-.183,.075,0,0,.015)) + self.pad.append(point(-.14,.075,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RST')) + # + # pin 2: PB3/ADC3/-OC1B/CLKI/XTAL1/PCINT3 + # + self.shape = add(self.shape,translate(pad_SOIC,-.14,.025,0)) + self.pad.append(point(-.14,.025,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PB3')) + # + # pin 3: PB4/ADC2/OC1B/CLKO/XTAL2/PCINT4 + # + self.shape = add(self.shape,translate(pad_SOIC,-.14,-.025,0)) + self.pad.append(point(-.14,-.025,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PB4')) + # + # pin 4: GND + # + self.shape = add(self.shape,translate(pad_SOIC,-.14,-.075,0)) + self.pad.append(point(-.14,-.075,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 5: PB0/MOSI/DI/SDA/AIN0/OC0A/-OC1A/AREF/PCINT0 + # + self.shape = add(self.shape,translate(pad_SOIC,.14,-.075,0)) + self.pad.append(point(.14,-.075,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PB0')) + # + # pin 6: PB1/MISO/DO/AIN1/OC0B/OC1A/PCINT1 + # + self.shape = add(self.shape,translate(pad_SOIC,.14,-.025,0)) + self.pad.append(point(.14,-.025,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PB1')) + # + # pin 7: PB2/SCK/USCK/SCL/ADC1/T0/INT0/PCINT2 + # + self.shape = add(self.shape,translate(pad_SOIC,.14,.025,0)) + self.pad.append(point(.14,.025,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PB2')) + # + # pin 8: VCC + # + self.shape = add(self.shape,translate(pad_SOIC,.14,.075,0)) + self.pad.append(point(.14,.075,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VCC')) + +class ATtiny44_SOICN(part): + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: VCC + # + self.shape = translate(pad_SOICN,-.12,.15,0) + self.shape = add(self.shape,cylinder(-.155,.15,0,0,.015)) + self.pad.append(point(-.12,.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VCC')) + # + # pin 2: PB0/XTAL1/PCINT8 + # + self.shape = add(self.shape,translate(pad_SOICN,-.12,.1,0)) + self.pad.append(point(-.12,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PB0')) + # + # pin 3: PB1/XTAL2/PCINT9 + # + self.shape = add(self.shape,translate(pad_SOICN,-.12,.050,0)) + self.pad.append(point(-.12,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PB1')) + # + # pin 4: PB3/dW/-RESET/PCINT11 + # + self.shape = add(self.shape,translate(pad_SOICN,-.12,0,0)) + self.pad.append(point(-.12,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PB3')) + # + # pin 5: PB2/CKOUT/OC0A/INT0/PCINT10 + # + self.shape = add(self.shape,translate(pad_SOICN,-.12,-.05,0)) + self.pad.append(point(-.12,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PB2')) + # + # pin 6: PA7/ADC7/OC0B/ICP/PCINT7 + # + self.shape = add(self.shape,translate(pad_SOICN,-.12,-.1,0)) + self.pad.append(point(-.12,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA7')) + # + # pin 7: PA6/ADC6/MOSI/SDA/OC1A/PCINT6 + # + self.shape = add(self.shape,translate(pad_SOICN,-.12,-.15,0)) + self.pad.append(point(-.12,-.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA6')) + # + # pin 8: PA5/ADC5/DO/MISO/OC1B/PCINT5 + # + self.shape = add(self.shape,translate(pad_SOICN,.12,-.15,0)) + self.pad.append(point(.12,-.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA5')) + # + # pin 9: PA4/ADC4/USCK/SCL/T1/PCINT4 + # + self.shape = add(self.shape,translate(pad_SOICN,.12,-.1,0)) + self.pad.append(point(.12,-.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA4')) + # + # pin 10: PA3/ADC3/T0/PCINT3 + # + self.shape = add(self.shape,translate(pad_SOICN,.12,-.05,0)) + self.pad.append(point(.12,-.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA3')) + # + # pin 11: PA2/ADC2/AIN1/PCINT2 + # + self.shape = add(self.shape,translate(pad_SOICN,.12,0,0)) + self.pad.append(point(.12,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA2')) + # + # pin 12: PA1/ADC1/AIN0/PCINT1 + # + self.shape = add(self.shape,translate(pad_SOICN,.12,.050,0)) + self.pad.append(point(.12,.05,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA1')) + # + # pin 13: PA0/ADC0/AREF/PCINT0 + # + self.shape = add(self.shape,translate(pad_SOICN,.12,.1,0)) + self.pad.append(point(.12,.1,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA0')) + # + # pin 14: GND + # + self.shape = add(self.shape,translate(pad_SOICN,.12,.15,0)) + self.pad.append(point(.12,.15,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + +pad_TQFP_h = cube(-.025,.025,-.007,.007,0,0) +pad_TQFP_v = cube(-.007,.007,-.025,.025,0,0) + +class ATxmegaE5_TQFP(part): + def __init__(self,value=''): + c = .18 + d = 0.8/25.4 + s = 0.004 + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: GND + # + self.shape = translate(pad_TQFP_h,-c,3.5*d,0) + self.pad.append(point(-c,3.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1 GND',line=s)) + # + # pin 2: PA4 + # + self.shape = add(self.shape,translate(pad_TQFP_h,-c,2.5*d,0)) + self.pad.append(point(-c,2.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA4',line=s)) + # + # pin 3: PA3 + # + self.shape = add(self.shape,translate(pad_TQFP_h,-c,1.5*d,0)) + self.pad.append(point(-c,1.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA3',line=s)) + # + # pin 4: PA2 + # + self.shape = add(self.shape,translate(pad_TQFP_h,-c,.5*d,0)) + self.pad.append(point(-c,.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA2',line=s)) + # + # pin 5: PA1 + # + self.shape = add(self.shape,translate(pad_TQFP_h,-c,-.5*d,0)) + self.pad.append(point(-c,-.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA1',line=s)) + # + # pin 6: PA0 + # + self.shape = add(self.shape,translate(pad_TQFP_h,-c,-1.5*d,0)) + self.pad.append(point(-c,-1.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA0',line=s)) + # + # pin 7: PDI/DATA + # + self.shape = add(self.shape,translate(pad_TQFP_h,-c,-2.5*d,0)) + self.pad.append(point(-c,-2.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PDI/DATA',line=s)) + # + # pin 8: RST/CLOCK + # + self.shape = add(self.shape,translate(pad_TQFP_h,-c,-3.5*d,0)) + self.pad.append(point(-c,-3.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RST/CLOCK',line=s)) + # + # pin 9: PC7 + # + self.shape = add(self.shape,translate(pad_TQFP_v,-3.5*d,-c,0)) + self.pad.append(point(-3.5*d,-c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC7',angle=90,line=s)) + # + # pin 10: PC6 + # + self.shape = add(self.shape,translate(pad_TQFP_v,-2.5*d,-c,0)) + self.pad.append(point(-2.5*d,-c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC6',angle=90,line=s)) + # + # pin 11: PC5 + # + self.shape = add(self.shape,translate(pad_TQFP_v,-1.5*d,-c,0)) + self.pad.append(point(-1.5*d,-c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC5',angle=90,line=s)) + # + # pin 12: PC4 + # + self.shape = add(self.shape,translate(pad_TQFP_v,-.5*d,-c,0)) + self.pad.append(point(-.5*d,-c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC4',angle=90,line=s)) + # + # pin 13: PC3 + # + self.shape = add(self.shape,translate(pad_TQFP_v,.5*d,-c,0)) + self.pad.append(point(.5*d,-c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC3',angle=90,line=s)) + # + # pin 14: PC2 + # + self.shape = add(self.shape,translate(pad_TQFP_v,1.5*d,-c,0)) + self.pad.append(point(1.5*d,-c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC2',angle=90,line=s)) + # + # pin 15: PC1 + # + self.shape = add(self.shape,translate(pad_TQFP_v,2.5*d,-c,0)) + self.pad.append(point(2.5*d,-c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC1',angle=90,line=s)) + # + # pin 16: PC0 + # + self.shape = add(self.shape,translate(pad_TQFP_v,3.5*d,-c,0)) + self.pad.append(point(3.5*d,-c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC0',angle=90,line=s)) + # + # pin 17: VCC + # + self.shape = add(self.shape,translate(pad_TQFP_h,c,-3.5*d,0)) + self.pad.append(point(c,-3.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VCC',line=s)) + # + # pin 18: GND + # + self.shape = add(self.shape,translate(pad_TQFP_h,c,-2.5*d,0)) + self.pad.append(point(c,-2.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND',line=s)) + # + # pin 19: PR1 + # + self.shape = add(self.shape,translate(pad_TQFP_h,c,-1.5*d,0)) + self.pad.append(point(c,-1.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PR1',line=s)) + # + # pin 20: PR0 + # + self.shape = add(self.shape,translate(pad_TQFP_h,c,-.5*d,0)) + self.pad.append(point(c,-.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PR0',line=s)) + # + # pin 21: PD7 + # + self.shape = add(self.shape,translate(pad_TQFP_h,c,.5*d,0)) + self.pad.append(point(c,.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD7',line=s)) + # + # pin 22: PD6 + # + self.shape = add(self.shape,translate(pad_TQFP_h,c,1.5*d,0)) + self.pad.append(point(c,1.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD6',line=s)) + # + # pin 23: PD5 + # + self.shape = add(self.shape,translate(pad_TQFP_h,c,2.5*d,0)) + self.pad.append(point(c,2.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD5',line=s)) + # + # pin 24: PD4 + # + self.shape = add(self.shape,translate(pad_TQFP_h,c,3.5*d,0)) + self.pad.append(point(c,3.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD4',line=s)) + # + # pin 25: PD3 + # + self.shape = add(self.shape,translate(pad_TQFP_v,3.5*d,c,0)) + self.pad.append(point(3.5*d,c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD3',angle=90,line=s)) + # + # pin 26: PD2 + # + self.shape = add(self.shape,translate(pad_TQFP_v,2.5*d,c,0)) + self.pad.append(point(2.5*d,c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD2',angle=90,line=s)) + # + # pin 27: PD1 + # + self.shape = add(self.shape,translate(pad_TQFP_v,1.5*d,c,0)) + self.pad.append(point(1.5*d,c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD1',angle=90,line=s)) + # + # pin 28: PD0 + # + self.shape = add(self.shape,translate(pad_TQFP_v,.5*d,c,0)) + self.pad.append(point(.5*d,c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD0',angle=90,line=s)) + # + # pin 29: PA7 + # + self.shape = add(self.shape,translate(pad_TQFP_v,-.5*d,c,0)) + self.pad.append(point(-.5*d,c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA7',angle=90,line=s)) + # + # pin 30: PA6 + # + self.shape = add(self.shape,translate(pad_TQFP_v,-1.5*d,c,0)) + self.pad.append(point(-1.5*d,c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA6',angle=90,line=s)) + # + # pin 31: PA5 + # + self.shape = add(self.shape,translate(pad_TQFP_v,-2.5*d,c,0)) + self.pad.append(point(-2.5*d,c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA5',angle=90,line=s)) + # + # pin 32: AVCC + # + self.shape = add(self.shape,translate(pad_TQFP_v,-3.5*d,c,0)) + self.pad.append(point(-3.5*d,c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'AVCC',angle=90,line=s)) + +class ATmega88_TQFP(part): + def __init__(self,value=''): + c = .18 + d = .031 + s = 0.004 + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: PD3/PCINT19/OC2B/INT1 + # + self.shape = translate(pad_TQFP_h,-c,3.5*d,0) + self.pad.append(point(-c,3.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1 PD3',line=s)) + # + # pin 2: PD4/PCINT20/XCK/T0 + # + self.shape = add(self.shape,translate(pad_TQFP_h,-c,2.5*d,0)) + self.pad.append(point(-c,2.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD4',line=s)) + # + # pin 3: GND + # + self.shape = add(self.shape,translate(pad_TQFP_h,-c,1.5*d,0)) + self.pad.append(point(-c,1.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND',line=s)) + # + # pin 4: VCC + # + self.shape = add(self.shape,translate(pad_TQFP_h,-c,.5*d,0)) + self.pad.append(point(-c,.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VCC',line=s)) + # + # pin 5: GND + # + self.shape = add(self.shape,translate(pad_TQFP_h,-c,-.5*d,0)) + self.pad.append(point(-c,-.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND',line=s)) + # + # pin 6: VCC + # + self.shape = add(self.shape,translate(pad_TQFP_h,-c,-1.5*d,0)) + self.pad.append(point(-c,-1.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VCC',line=s)) + # + # pin 7: PB6/PCINT6/XTAL1/TOSC1 + # + self.shape = add(self.shape,translate(pad_TQFP_h,-c,-2.5*d,0)) + self.pad.append(point(-c,-2.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PB6',line=s)) + # + # pin 8: PB7/PCINT7/XTAL2/TOSC2 + # + self.shape = add(self.shape,translate(pad_TQFP_h,-c,-3.5*d,0)) + self.pad.append(point(-c,-3.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PB7',line=s)) + # + # pin 9: PD5/PCINT21/OC0B/T1 + # + self.shape = add(self.shape,translate(pad_TQFP_v,-3.5*d,-c,0)) + self.pad.append(point(-3.5*d,-c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD5',angle=90,line=s)) + # + # pin 10: PD6/PCINT22/OC0A/AIN0 + # + self.shape = add(self.shape,translate(pad_TQFP_v,-2.5*d,-c,0)) + self.pad.append(point(-2.5*d,-c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD6',angle=90,line=s)) + # + # pin 11: PD7/PCINT23/AIN1 + # + self.shape = add(self.shape,translate(pad_TQFP_v,-1.5*d,-c,0)) + self.pad.append(point(-1.5*d,-c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD7',angle=90,line=s)) + # + # pin 12: PB0/PCINT0/CLKO/ICP1 + # + self.shape = add(self.shape,translate(pad_TQFP_v,-.5*d,-c,0)) + self.pad.append(point(-.5*d,-c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PB0',angle=90,line=s)) + # + # pin 13: PB1/PCINT1/OC1A + # + self.shape = add(self.shape,translate(pad_TQFP_v,.5*d,-c,0)) + self.pad.append(point(.5*d,-c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PB1',angle=90,line=s)) + # + # pin 14: PB2/PCINT2/-SS/OC1B + # + self.shape = add(self.shape,translate(pad_TQFP_v,1.5*d,-c,0)) + self.pad.append(point(1.5*d,-c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PB2',angle=90,line=s)) + # + # pin 15: PB3/PCINT3/OC2A/MOSI + # + self.shape = add(self.shape,translate(pad_TQFP_v,2.5*d,-c,0)) + self.pad.append(point(2.5*d,-c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PB3',angle=90,line=s)) + # + # pin 16: PB4/PCINT4/MISO + # + self.shape = add(self.shape,translate(pad_TQFP_v,3.5*d,-c,0)) + self.pad.append(point(3.5*d,-c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PB4',angle=90,line=s)) + # + # pin 17: PB5/SCK/PCINT5 + # + self.shape = add(self.shape,translate(pad_TQFP_h,c,-3.5*d,0)) + self.pad.append(point(c,-3.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PB5',line=s)) + # + # pin 18: AVCC + # + self.shape = add(self.shape,translate(pad_TQFP_h,c,-2.5*d,0)) + self.pad.append(point(c,-2.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'AVCC',line=s)) + # + # pin 19: ADC6 + # + self.shape = add(self.shape,translate(pad_TQFP_h,c,-1.5*d,0)) + self.pad.append(point(c,-1.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'ADC6',line=s)) + # + # pin 20: AREF + # + self.shape = add(self.shape,translate(pad_TQFP_h,c,-.5*d,0)) + self.pad.append(point(c,-.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'AREF',line=s)) + # + # pin 21: GND + # + self.shape = add(self.shape,translate(pad_TQFP_h,c,.5*d,0)) + self.pad.append(point(c,.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND',line=s)) + # + # pin 22: ADC7 + # + self.shape = add(self.shape,translate(pad_TQFP_h,c,1.5*d,0)) + self.pad.append(point(c,1.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'ADC7',line=s)) + # + # pin 23: PC0/ADC0/PCINT8 + # + self.shape = add(self.shape,translate(pad_TQFP_h,c,2.5*d,0)) + self.pad.append(point(c,2.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC0',line=s)) + # + # pin 24: PC1/ADC1/PCINT9 + # + self.shape = add(self.shape,translate(pad_TQFP_h,c,3.5*d,0)) + self.pad.append(point(c,3.5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC1',line=s)) + # + # pin 25: PC2/ADC2/PCINT10 + # + self.shape = add(self.shape,translate(pad_TQFP_v,3.5*d,c,0)) + self.pad.append(point(3.5*d,c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC2',angle=90,line=s)) + # + # pin 26: PC3/ADC3/PCINT11 + # + self.shape = add(self.shape,translate(pad_TQFP_v,2.5*d,c,0)) + self.pad.append(point(2.5*d,c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC3',angle=90,line=s)) + # + # pin 27: PC4/ADC4/SDA/PCINT12 + # + self.shape = add(self.shape,translate(pad_TQFP_v,1.5*d,c,0)) + self.pad.append(point(1.5*d,c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC4',angle=90,line=s)) + # + # pin 28: PC5/ADC5/SCL/PCINT13 + # + self.shape = add(self.shape,translate(pad_TQFP_v,.5*d,c,0)) + self.pad.append(point(.5*d,c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC5',angle=90,line=s)) + # + # pin 29: PC6/-RESET/PCINT14 + # + self.shape = add(self.shape,translate(pad_TQFP_v,-.5*d,c,0)) + self.pad.append(point(-.5*d,c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC6',angle=90,line=s)) + # + # pin 30: PD0/RXD/PCINT16 + # + self.shape = add(self.shape,translate(pad_TQFP_v,-1.5*d,c,0)) + self.pad.append(point(-1.5*d,c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD0',angle=90,line=s)) + # + # pin 31: PD1/TXD/PCINT17 + # + self.shape = add(self.shape,translate(pad_TQFP_v,-2.5*d,c,0)) + self.pad.append(point(-2.5*d,c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD1',angle=90,line=s)) + # + # pin 32: PD2/INT0/PCINT18 + # + self.shape = add(self.shape,translate(pad_TQFP_v,-3.5*d,c,0)) + self.pad.append(point(-3.5*d,c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD2',angle=90,line=s)) + +class ATmega644_TQFP(part): + def __init__(self,value=''): + c = .235 + d = .031 + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: PB5/PCINT13/MOSI + # + self.shape = translate(pad_TQFP_h,-c,5*d,0) + self.pad.append(point(-c,5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'*MOSI (1)')) + # + # pin 2: PB6/PCINT14/MISO + # + self.shape = add(self.shape,translate(pad_TQFP_h,-c,4*d,0)) + self.pad.append(point(-c,4*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'MISO')) + # + # pin 3: PB7/PCINT15/SCK + # + self.shape = add(self.shape,translate(pad_TQFP_h,-c,3*d,0)) + self.pad.append(point(-c,3*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SCK')) + # + # pin 4: -RESET + # + self.shape = add(self.shape,translate(pad_TQFP_h,-c,2*d,0)) + self.pad.append(point(-c,2*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'-RESET')) + # + # pin 5: VCC + # + self.shape = add(self.shape,translate(pad_TQFP_h,-c,d,0)) + self.pad.append(point(-c,d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VCC')) + # + # pin 6: GND + # + self.shape = add(self.shape,translate(pad_TQFP_h,-c,0,0)) + self.pad.append(point(-c,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 7: XTAL2 + # + self.shape = add(self.shape,translate(pad_TQFP_h,-c,-d,0)) + self.pad.append(point(-c,-d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'XTAL2')) + # + # pin 8: XTAL1 + # + self.shape = add(self.shape,translate(pad_TQFP_h,-c,-2*d,0)) + self.pad.append(point(-c,-2*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'XTAL1')) + # + # pin 9: PD0/PCINT24/RXD0 + # + self.shape = add(self.shape,translate(pad_TQFP_h,-c,-3*d,0)) + self.pad.append(point(-c,-3*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RXD0')) + # + # pin 10: PD1/PCINT25/TXD0 + # + self.shape = add(self.shape,translate(pad_TQFP_h,-c,-4*d,0)) + self.pad.append(point(-c,-4*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'TXD0')) + # + # pin 11: PD2/PCINT26/INT0 + # + self.shape = add(self.shape,translate(pad_TQFP_h,-c,-5*d,0)) + self.pad.append(point(-c,-5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD2')) + # + # pin 12: PD3/PCINT27/INT1 + # + self.shape = add(self.shape,translate(pad_TQFP_v,-5*d,-c,0)) + self.pad.append(point(-5*d,-c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD3')) + # + # pin 13: PD4/PCINT28/OC1B + # + self.shape = add(self.shape,translate(pad_TQFP_v,-4*d,-c,0)) + self.pad.append(point(-4*d,-c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD4')) + # + # pin 14: PD5/PCINT28/OC1A + # + self.shape = add(self.shape,translate(pad_TQFP_v,-3*d,-c,0)) + self.pad.append(point(-3*d,-c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD5')) + # + # pin 15: PD6/PCINT30/OC2B/ICP + # + self.shape = add(self.shape,translate(pad_TQFP_v,-2*d,-c,0)) + self.pad.append(point(-2*d,-c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD6')) + # + # pin 16: PD7/PCINT31/OC2A + # + self.shape = add(self.shape,translate(pad_TQFP_v,-d,-c,0)) + self.pad.append(point(-d,-c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PD7')) + # + # pin 17: VCC + # + self.shape = add(self.shape,translate(pad_TQFP_v,0,-c,0)) + self.pad.append(point(0,-c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VCC')) + # + # pin 18: GND + # + self.shape = add(self.shape,translate(pad_TQFP_v,d,-c,0)) + self.pad.append(point(d,-c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 19: PC0/PCINT16/SCL + # + self.shape = add(self.shape,translate(pad_TQFP_v,2*d,-c,0)) + self.pad.append(point(2*d,-c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC0')) + # + # pin 20: PC1/PCINT17/SDA + # + self.shape = add(self.shape,translate(pad_TQFP_v,3*d,-c,0)) + self.pad.append(point(3*d,-c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC1')) + # + # pin 21: PC2/PCINT18/TCK + # + self.shape = add(self.shape,translate(pad_TQFP_v,4*d,-c,0)) + self.pad.append(point(4*d,-c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC2')) + # + # pin 22: PC3/PCINT19/TMS + # + self.shape = add(self.shape,translate(pad_TQFP_v,5*d,-c,0)) + self.pad.append(point(5*d,-c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC3')) + # + # pin 23: PC4/TDO/PCINT20 + # + self.shape = add(self.shape,translate(pad_TQFP_h,c,-5*d,0)) + self.pad.append(point(c,-5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC4')) + # + # pin 24: PC5/TDI/PCINT21 + # + self.shape = add(self.shape,translate(pad_TQFP_h,c,-4*d,0)) + self.pad.append(point(c,-4*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC5')) + # + # pin 25: PC6/TOSC1/PCINT22 + # + self.shape = add(self.shape,translate(pad_TQFP_h,c,-3*d,0)) + self.pad.append(point(c,-3*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC6')) + # + # pin 26: PC7/TOSC2/PCINT23 + # + self.shape = add(self.shape,translate(pad_TQFP_h,c,-2*d,0)) + self.pad.append(point(c,-2*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PC7')) + # + # pin 27: AVCC + # + self.shape = add(self.shape,translate(pad_TQFP_h,c,-d,0)) + self.pad.append(point(c,-d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'AVCC')) + # + # pin 28: GND + # + self.shape = add(self.shape,translate(pad_TQFP_h,c,0,0)) + self.pad.append(point(c,0,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 29: AREF + # + self.shape = add(self.shape,translate(pad_TQFP_h,c,d,0)) + self.pad.append(point(c,d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'AREF')) + # + # pin 30: PA7/ADC7/PCINT7 + # + self.shape = add(self.shape,translate(pad_TQFP_h,c,2*d,0)) + self.pad.append(point(c,2*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA7')) + # + # pin 31: PA6/ADC6/PCINT6 + # + self.shape = add(self.shape,translate(pad_TQFP_h,c,3*d,0)) + self.pad.append(point(c,3*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA6')) + # + # pin 32: PA5/ADC5/PCINT5 + # + self.shape = add(self.shape,translate(pad_TQFP_h,c,4*d,0)) + self.pad.append(point(c,4*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA5')) + # + # pin 33: PA4/ADC4/PCINT4 + # + self.shape = add(self.shape,translate(pad_TQFP_h,c,5*d,0)) + self.pad.append(point(c,5*d,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA4')) + # + # pin 34: PA3/ADC3/PCINT3 + # + self.shape = add(self.shape,translate(pad_TQFP_v,5*d,c,0)) + self.pad.append(point(5*d,c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA3')) + # + # pin 35: PA2/ADC2/PCINT2 + # + self.shape = add(self.shape,translate(pad_TQFP_v,4*d,c,0)) + self.pad.append(point(4*d,c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA2')) + # + # pin 36: PA1/ADC1/PCINT1 + # + self.shape = add(self.shape,translate(pad_TQFP_v,3*d,c,0)) + self.pad.append(point(3*d,c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA1')) + # + # pin 37: PA0/ADC0/PCINT0 + # + self.shape = add(self.shape,translate(pad_TQFP_v,2*d,c,0)) + self.pad.append(point(2*d,c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PA0')) + # + # pin 38: VCC + # + self.shape = add(self.shape,translate(pad_TQFP_v,d,c,0)) + self.pad.append(point(d,c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VCC')) + # + # pin 39: GND + # + self.shape = add(self.shape,translate(pad_TQFP_v,0,c,0)) + self.pad.append(point(0,c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 40: PB0/XCK0/T0/PCINT8 + # + self.shape = add(self.shape,translate(pad_TQFP_v,-d,c,0)) + self.pad.append(point(-d,c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PB0')) + # + # pin 41: PB1/T1/CLKO/PCINT9 + # + self.shape = add(self.shape,translate(pad_TQFP_v,-2*d,c,0)) + self.pad.append(point(-2*d,c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PB1')) + # + # pin 42: PB2/AIN0/INT2/PCINT10 + # + self.shape = add(self.shape,translate(pad_TQFP_v,-3*d,c,0)) + self.pad.append(point(-3*d,c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PB2')) + # + # pin 43: PB3/AIN1/OC0A/PCINT11 + # + self.shape = add(self.shape,translate(pad_TQFP_v,-4*d,c,0)) + self.pad.append(point(-4*d,c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PB2')) + # + # pin 44: PB4/-SS/OC0B/PCINT12 + # + self.shape = add(self.shape,translate(pad_TQFP_v,-5*d,c,0)) + self.pad.append(point(-5*d,c,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'PB4')) + +TSSOP_pad_width = 0.040 +TSSOP_pad_height = 0.011 +TSSOP_pad_dy = 0.026 +TSSOP_pad_dx = 0.120 +pad_TSSOP = cube(-TSSOP_pad_width/2.0,TSSOP_pad_width/2.0,-TSSOP_pad_height/2.0,TSSOP_pad_height/2.0,0,0) + +class TRC102(part): + # + # RFM TRC102 ISM transceiver + # + def __init__(self,value=''): + self.value = value + self.pad = [point(0,0,0)] + self.labels = [] + # + # pin 1: SDI + # + self.shape = translate(pad_TSSOP,-TSSOP_pad_dx,3.5*TSSOP_pad_dy,0) + self.pad.append(point(-TSSOP_pad_dx,3.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'1 SDI')) + # + # pin 2: SCK + # + self.shape = add(self.shape,translate(pad_TSSOP,-TSSOP_pad_dx,2.5*TSSOP_pad_dy,0)) + self.pad.append(point(-TSSOP_pad_dx,2.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SCK')) + # + # pin 3: nCS + # + self.shape = add(self.shape,translate(pad_TSSOP,-TSSOP_pad_dx,1.5*TSSOP_pad_dy,0)) + self.pad.append(point(-TSSOP_pad_dx,1.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'nCS')) + # + # pin 4: SDO + # + self.shape = add(self.shape,translate(pad_TSSOP,-TSSOP_pad_dx,0.5*TSSOP_pad_dy,0)) + self.pad.append(point(-TSSOP_pad_dx,0.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'SDO')) + # + # pin 5: IRQ + # + self.shape = add(self.shape,translate(pad_TSSOP,-TSSOP_pad_dx,-0.5*TSSOP_pad_dy,0)) + self.pad.append(point(-TSSOP_pad_dx,-0.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'IRQ')) + # + # pin 6: DATA/nFSEL + # + self.shape = add(self.shape,translate(pad_TSSOP,-TSSOP_pad_dx,-1.5*TSSOP_pad_dy,0)) + self.pad.append(point(-TSSOP_pad_dx,-1.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'DATA')) + # + # pin 7: CR + # + self.shape = add(self.shape,translate(pad_TSSOP,-TSSOP_pad_dx,-2.5*TSSOP_pad_dy,0)) + self.pad.append(point(-TSSOP_pad_dx,-2.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'CR')) + # + # pin 8: CLKOUT + # + self.shape = add(self.shape,translate(pad_TSSOP,-TSSOP_pad_dx,-3.5*TSSOP_pad_dy,0)) + self.pad.append(point(-TSSOP_pad_dx,-3.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'CLKOUT')) + # + # pin 9: Xtal/Ref + # + self.shape = add(self.shape,translate(pad_TSSOP,TSSOP_pad_dx,-3.5*TSSOP_pad_dy,0)) + self.pad.append(point(TSSOP_pad_dx,-3.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'Xtal')) + # + # pin 10: RESET + # + self.shape = add(self.shape,translate(pad_TSSOP,TSSOP_pad_dx,-2.5*TSSOP_pad_dy,0)) + self.pad.append(point(TSSOP_pad_dx,-2.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RESET')) + # + # pin 11: GND + # + self.shape = add(self.shape,translate(pad_TSSOP,TSSOP_pad_dx,-1.5*TSSOP_pad_dy,0)) + self.pad.append(point(TSSOP_pad_dx,-1.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'GND')) + # + # pin 12: RF_P + # + self.shape = add(self.shape,translate(pad_TSSOP,TSSOP_pad_dx,-0.5*TSSOP_pad_dy,0)) + self.pad.append(point(TSSOP_pad_dx,-0.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RF_P')) + # + # pin 13: RF_N + # + self.shape = add(self.shape,translate(pad_TSSOP,TSSOP_pad_dx,0.5*TSSOP_pad_dy,0)) + self.pad.append(point(TSSOP_pad_dx,0.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RF_N')) + # + # pin 14: VDD + # + self.shape = add(self.shape,translate(pad_TSSOP,TSSOP_pad_dx,1.5*TSSOP_pad_dy,0)) + self.pad.append(point(TSSOP_pad_dx,1.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'VDD')) + # + # pin 15: RSSIA + # + self.shape = add(self.shape,translate(pad_TSSOP,TSSOP_pad_dx,2.5*TSSOP_pad_dy,0)) + self.pad.append(point(TSSOP_pad_dx,2.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'RSSIA')) + # + # pin 16: nINT/DDET + # + self.shape = add(self.shape,translate(pad_TSSOP,TSSOP_pad_dx,3.5*TSSOP_pad_dy,0)) + self.pad.append(point(TSSOP_pad_dx,3.5*TSSOP_pad_dy,0)) + self.labels.append(self.text(self.pad[-1].x,self.pad[-1].y,self.pad[-1].z,'nINT')) + +class CBA(part): + # + # CBA logo + # + def __init__(self,r=.02): + self.value = '' + self.pad = [point(0,0,0)] + self.labels = [] + d = 3*r + self.shape = cylinder(0,0,0,0,r) + self.shape = add(self.shape,translate(cylinder(0,0,0,0,r),-d,d,0)) + self.shape = add(self.shape,translate(cube(-r,r,-r,r,0,0),-d,0,0)) + self.shape = add(self.shape,translate(cube(-r,r,-r,r,0,0),-d,-d,0)) + self.shape = add(self.shape,translate(cube(-r,r,-r,r,0,0),0,-d,0)) + self.shape = add(self.shape,translate(cube(-r,r,-r,r,0,0),d,-d,0)) + self.shape = add(self.shape,translate(cube(-r,r,-r,r,0,0),d,0,0)) + self.shape = add(self.shape,translate(cube(-r,r,-r,r,0,0),d,d,0)) + self.shape = add(self.shape,translate(cube(-r,r,-r,r,0,0),0,d,0)) + +class fab(part): + def __init__(self,r=.05): + self.value = '' + self.pad = [point(0,0,0)] + self.labels = [] + d = 1.8*r + l = 3.5*r + h = r/2. + self.shape = rectangle(-d,d,-d,d) + self.shape = subtract(self.shape,circle(0,0,r)) + self.shape = subtract(self.shape,rectangle(-l,0,-h,h)) + self.shape = add(self.shape,rectangle(d,l,-h,h)) + self.shape = add(self.shape,circle(l,0,r)) + self.shape = add(self.shape,circle(-l,0,r)) + +############################################################ +# define board +############################################################ + +width = 1.99 # board width +height = 1.99-.34 # board height +x = 1 # x origin +y = 1 # y origin +zt = 0 # top z +zb = -0.06 # bottom z +w = .0106 # wire width +w1 = .015 # thicker wire width +w2 = .03 # thickest wire width +mask = .002 # solder mask size + +pcb = PCB(x,y,width,height,mask) + +IC1 = DRV8428P_HTSSOP('IC1\nDRV8428P') +pcb = IC1.add(pcb,x+.56,y+height/2+.25) + +pcb = wire(pcb,w, + IC1.pad[2], + point(IC1.x,IC1.pad[2].y)) + +pcb = wire(pcb,w, + IC1.pad[2], + point(IC1.pad[2].x-.075,IC1.pad[2].y)) + +pcb = wire(pcb,w, + IC1.pad[7], + point(IC1.x,IC1.pad[7].y)) + +pcb = wire(pcb,w, + IC1.pad[7], + point(IC1.pad[7].x-.075,IC1.pad[7].y)) + +pcb = wire(pcb,w, + IC1.pad[9], + point(IC1.pad[9].x+.075,IC1.pad[9].y)) + +pcb = wire(pcb,w, + IC1.pad[10], + point(IC1.pad[10].x+.075,IC1.pad[10].y)) + +pcb = wire(pcb,w, + point(IC1.pad[9].x+.075,IC1.pad[9].y), + point(IC1.pad[10].x+.075,IC1.pad[10].y)) + +pcb = wire(pcb,w, + IC1.pad[11], + point(IC1.x,IC1.pad[11].y)) + +pcb = wire(pcb,w, + IC1.pad[11], + point(IC1.pad[11].x+.075,IC1.pad[11].y)) + +J2 = header_4H('J2\nstepper') +pcb = J2.add(pcb,x+.23,y+height/2,angle=180) + +pcb = wire(pcb,w, + IC1.pad[3], + point(J2.x-.132,IC1.pad[3].y), + point(J2.x-.132,J2.pad[1].y), + J2.pad[1]) + +pcb = wire(pcb,w, + IC1.pad[4], + point(J2.x-.106,IC1.pad[4].y), + point(J2.x-.106,J2.pad[2].y), + J2.pad[2]) + +pcb = wire(pcb,w, + IC1.pad[5], + point(J2.x-.08,IC1.pad[5].y), + point(J2.x-.08,J2.pad[3].y), + J2.pad[3]) + +pcb = wire(pcb,w, + IC1.pad[6], + point(J2.x,IC1.pad[6].y), + J2.pad[4]) + +R1 = ST4EB('R1\n10k') +pcb = R1.add(pcb,IC1.x-.05,IC1.y-.35) + +pcb = wire(pcb,w, + IC1.pad[9], + point(IC1.pad[9].x,IC1.pad[9].y-.06), + point(R1.pad[3].x,IC1.pad[9].y-.06), + R1.pad[3]) + +C1 = C_1206('C1\n1uF') +pcb = C1.add(pcb,J2.x,J2.pad[1].y-.16,angle=90) + +pcb = wire(pcb,w1, + C1.pad[1], + point(C1.x,y+.37)) + +pcb = wire(pcb,w, + C1.pad[2], + point(C1.x+.1,C1.pad[2].y), + point(C1.x+.1,IC1.pad[8].y), + IC1.pad[8]) + +R2 = R_1206('R2\n10k') +pcb = R2.add(pcb,R1.pad[1].x-.02,R1.y-.24,angle=0) + +pcb = wire(pcb,w, + R2.pad[1], + point(R2.pad[1].x,C1.pad[2].y), + C1.pad[2]) + +pcb = wire(pcb,w1, + R2.pad[2], + point(R1.pad[1].x,R2.y), + R1.pad[1]) + +C2 = C_FND('C2\n100uF') +pcb = C2.add(pcb,IC1.x+.08,IC1.y+.27,angle=90) + +pcb = wire(pcb,w2, + C2.pad[2], + point(C2.pad[2].x,C2.y-.08)) + +J4 = header_2H('J4\npower') +pcb = J4.add(pcb,x+.23,IC1.pad[1].y+.05,angle=180) + +pcb = wire(pcb,w, + IC1.pad[1], + point(J4.x,IC1.pad[1].y)) + +pcb = wire(pcb,w, + IC1.pad[1], + point(IC1.pad[1].x+.025,IC1.pad[1].y), + point(IC1.pad[1].x+.025,IC1.pad[1].y+w), + point(J4.x,IC1.pad[1].y+w)) + +pcb = wire(pcb,w2, + point(C2.pad[1].x-.02,C2.y), + point(J4.x+.10,J4.pad[1].y+.01), + point(J4.x,J4.pad[1].y+.01), + J4.pad[1]) + +C3 = C_1206('C3\n.01uF') +pcb = C3.add(pcb,C2.x+.31,C2.y) + +pcb = wire(pcb,w2, + C2.pad[2], + C3.pad[1]) + +pcb = wire(pcb,w2, + C3.pad[2], + point(C3.pad[2].x,C3.y+.08), + point(C2.pad[1].x,C3.y+.08), + C2.pad[1]) + +IC2 = SAMD11C('IC2\nD11C') +pcb = IC2.add(pcb,x+width-.62,y+height/2,angle=-90) + +J1 = header_SWD_4_1('J1 SWD') +pcb = J1.add(pcb,IC2.pad[7].x-.14,IC2.y,angle=-90) + +pcb = wire(pcb,w1, + J1.pad[1], + point(J1.pad[1].x,IC2.pad[7].y), + IC2.pad[7]) + +pcb = wire(pcb,w1, + J1.pad[2], + point(J1.pad[2].x,IC2.pad[8].y), + IC2.pad[8]) + +pcb = wire(pcb,w, + J1.pad[3], + point(J1.pad[3].x,IC2.pad[6].y+.08), + point(IC2.pad[6].x,IC2.pad[6].y+.08), + IC2.pad[6]) + +pcb = wire(pcb,w1, + J1.pad[4], + point(J1.pad[4].x,IC2.pad[12].y-.08), + point(IC2.pad[11].x,IC2.pad[11].y-.08), + IC2.pad[11]) + +pcb = wire(pcb,w1, + J1.pad[4], + point(J1.pad[4].x,IC2.pad[12].y-.08), + point(R1.pad[2].x,IC2.pad[12].y-.08), + R1.pad[2]) + +pcb = wire(pcb,w, + IC2.pad[1], + point(IC2.pad[1].x,IC1.pad[16].y), + IC1.pad[16]) + +pcb = wire(pcb,w, + IC2.pad[2], + point(IC2.pad[2].x,IC1.pad[15].y), + IC1.pad[15]) + +pcb = wire(pcb,w, + IC2.pad[3], + point(IC2.pad[3].x,IC1.pad[14].y), + IC1.pad[14]) + +pcb = wire(pcb,w, + IC2.pad[4], + point(IC2.pad[4].x,IC1.pad[13].y), + IC1.pad[13]) + +pcb = wire(pcb,w, + IC2.pad[5], + point(IC2.pad[5].x,IC1.pad[12].y), + IC1.pad[12]) + +J3 = USB_A_plug('J3\nUSB') +pcb = J3.add(pcb,x+width-.29,IC2.y+.025,angle=0) + +pcb = wire(pcb,w1, + J3.pad[2], + point(J3.pad[2].x-.11,J3.pad[2].y), + point(J3.pad[2].x-.11,IC2.y+.015), + point(IC2.pad[9].x,IC2.y+.015), + IC2.pad[9]) + +pcb = wire(pcb,w1, + point(J3.pad[3].x,IC2.y-.015), + point(IC2.pad[10].x,IC2.y-.015), + IC2.pad[10]) + +pcb = wire(pcb,w1, + J3.pad[4], + point(J3.pad[4].x-.11,J3.pad[4].y), + point(J3.pad[4].x-.11,IC2.y-.045), + point(IC2.pad[11].x,IC2.y-.045), + IC2.pad[11]) + +pcb = wire(pcb,w2, + J3.pad[4], + point(J3.pad[4].x-.11,J3.pad[4].y), + point(J3.pad[4].x-.11,y+.37), + point(x+.03,y+.37), + point(x+.03,J4.pad[2].y), + J4.pad[2]) + +IC3 = regulator_SOT23('IC3\n3.3V') +pcb = IC3.add(pcb,IC2.pad[8].x-.1,IC2.pad[9].y-.21,angle=0) + +pcb = wire(pcb,w1, + J4.pad[1], + point(x+.07,J4.pad[1].y), + point(x+.07,C1.y), + point(C1.x+.08,C1.y), + point(C1.x+.08,IC3.pad[2].y-.05), + point(IC3.pad[2].x,IC3.pad[2].y-.05), + IC3.pad[2]) + +pcb = wire(pcb,w1, + IC3.pad[3], + point(IC3.pad[3].x,y+.37)) + +C4 = C_1206('C4\n1uF') +pcb = C4.add(pcb,IC3.x-.22,IC3.y) + +pcb = wire(pcb,w1, + C4.pad[1], + point(C4.pad[1].x,C4.y+.1), + point(IC3.pad[1].x,C4.y+.1), + IC3.pad[1]) + +pcb = wire(pcb,w1, + C4.pad[2], + IC3.pad[3]) + +pcb = wire(pcb,w1, + IC3.pad[1], + point(IC3.pad[1].x,C4.y+.1), + point(IC2.pad[12].x,C4.y+.1), + IC2.pad[12]) + +R3 = R_1206('R3\n0') +pcb = R3.add(pcb,C3.x+.22,C3.y) + +pcb = wire(pcb,w2, + C3.pad[2], + R3.pad[1]) + +pcb = wire(pcb,w2, + R3.pad[2], + point(R3.pad[2].x+.07,R3.pad[2].y), + point(R3.pad[2].x+.12,J4.pad[2].y), + point(J3.pad[4].x-.11,J4.pad[2].y), + point(J3.pad[4].x-.11,J3.pad[1].y), + J3.pad[1]) + +pcb = wire(pcb,w2, + IC1.pad[17], + point(IC1.x,R3.y-.13), + point(IC1.x+.04,R3.y-.08), + point(R3.x,R3.y-.08)) + +pcb = wire(pcb,w2, + J4.pad[2], + point(J4.x+.11,J4.pad[2].y), + point(J4.x+.17,J4.pad[2].y+.06), + point(J4.x+.17,C2.y+.07), + point(J4.x+.23,C2.y+.13), + point(R3.x,C2.y+.13)) + +pcb = wire(pcb,w1, + point(R3.x,R3.y-.08), + point(R3.x,C2.y+.13)) + +R4 = R_1206('R4\n1k') +pcb = R4.add(pcb,IC2.pad[11].x+.01,IC3.y+.03,angle=0) + +pcb = wire(pcb,w1, + R4.pad[2], + point(IC2.pad[13].x,R4.y), + IC2.pad[13]) + +LED = LED_1206('LED') +pcb = LED.add(pcb,R4.x,R4.y-.09,angle=180) + +pcb = wire(pcb,w1, + LED.pad[1], + point(IC2.pad[14].x,LED.y), + IC2.pad[14]) + +pcb = wire(pcb,w1, + LED.pad[2], + point(R4.pad[1].x,LED.y), + R4.pad[1]) + +pcb.holes = add(pcb.holes,cylinder(x+(width-.34)/2,y+height/2,zb,zt,.125)) +pcb.holes = add(pcb.holes,cylinder(x+.21,y+height-.21,zb,zt,.065)) +pcb.holes = add(pcb.holes,cylinder(x+.21,y+.21,zb,zt,.065)) +pcb.holes = add(pcb.holes,cylinder(x+width-(.21+.34),y+height-.21,zb,zt,.065)) +pcb.holes = add(pcb.holes,cylinder(x+width-(.21+.34),y+.21,zb,zt,.065)) + +l = 0.13 +pcb.exterior = add(pcb.exterior,triangle(x,y+height-l,x,y+height,x+l,y+height)) +pcb.exterior = add(pcb.exterior,triangle(x,y,x,y+l,x+l,y)) +pcb.exterior = add(pcb.exterior,triangle(x+width-.34,y+height,x+width-.34,y+height-l,x+width-l-.34,y+height)) +pcb.exterior = add(pcb.exterior,triangle(x+width-.34-l,y,x+width-.34,y+l,x+width-.34,y)) +pcb.interior = subtract(pcb.interior,triangle(x,y+height-l,x,y+height,x+l,y+height)) +pcb.interior = subtract(pcb.interior,triangle(x,y,x,y+l,x+l,y)) +pcb.interior = subtract(pcb.interior,triangle(x+width-.34,y+height,x+width-.34,y+height-l,x+width-l-.34,y+height)) +pcb.interior = subtract(pcb.interior,triangle(x+width-.34-l,y,x+width-.34,y+l,x+width-.34,y)) + +#pcb.exterior = add(pcb.exterior,text("8/20/21",x+(width-.34)/2+.1,y+0.2,0,line=0.01,color=White).shape) +#pcb.exterior = add(pcb.exterior,text("hello.DRV8428P-D11C-NEMA17",x+(width-.34)/2,y+0.075,0,line=0.01,color=White).shape) +#c = CBA(r=0.0125) +#pcb.exterior = add(pcb.exterior,move(c.shape,x+(width-.34)/2-.175,y+.2)) + +############################################################ +# select output +############################################################ + +outputs = {} +if (output == "top, labels, and exterior"): + outputs["function"] = add(add(color(Tan,pcb.board),pcb.labels), + color(White,pcb.exterior)) + outputs["layers"] = [zt] +elif (output == "top, labels, holes, and exterior"): + outputs["function"] = add(add(color(Tan,pcb.board),pcb.labels), + add(color(White,pcb.exterior),color(Blue,pcb.holes))) + outputs["layers"] = [zt] +elif (output == "top, bottom, labels, and exterior"): + outputs["function"] = add(add(color(Tan,pcb.board),pcb.labels), + color(White,pcb.exterior)) + outputs["layers"] = [zb,zt] +elif (output == "top, bottom, labels, holes, and exterior"): + outputs["function"] = add(add(color(Tan,pcb.board),pcb.labels), + add(color(White,pcb.exterior),color(Blue,pcb.holes))) + outputs["layers"] = [zb,zt] +elif (output == "top traces"): + outputs["function"] = color(White,pcb.board) + outputs["layers"] = [zt] +elif (output == "top traces and exterior"): + outputs["function"] = color(White,add(pcb.board,pcb.exterior)) + outputs["layers"] = [zt] +elif (output == "bottom traces reversed"): + outputs["function"] = color(White, + reflect_x(pcb.board,2*x+width)) + outputs["layers"] = [zb] +elif (output == "bottom traces reversed and exterior"): + outputs["function"] = color(White, + reflect_x(add(pcb.board,pcb.exterior),2*x+width)) + outputs["layers"] = [zb] +elif (output == "interior"): + outputs["function"] = color(White,pcb.interior) + outputs["layers"] = [zt] +elif (output == "exterior"): + outputs["function"] = color(White,pcb.exterior) + outputs["layers"] = [zt] +elif (output == "holes"): + outputs["function"] = color(White, + subtract(add(pcb.exterior,pcb.interior),pcb.holes)) + outputs["layers"] = [zb] +elif (output == "holes and interior"): + outputs["function"] = color(White, + subtract(pcb.interior,pcb.holes)) + outputs["layers"] = [zb] +elif (output == "solder mask"): + outputs["function"] = color(White,pcb.mask) + outputs["layers"] = [zt] +else: + print("oops -- don't recognize output") + +############################################################ +# set limits and parameters +############################################################ + +border = 0.05 +outputs["xmin"] = x-border # min x to render +outputs["xmax"] = x+width+border # max x to render +outputs["ymin"] = y-border # min y to render +outputs["ymax"] = y+height+border # max y to render +outputs["mm_per_unit"] = 25.4 # use inch units +outputs["type"] = "RGB" # use RGB color + +############################################################ +# send output +############################################################ + +json.dump(outputs,sys.stdout) diff --git a/serialstep/serialstep-DRV8428P/board/hello.DRV8428P-D11C-NEMA17.holes.png b/serialstep/serialstep-DRV8428P/board/hello.DRV8428P-D11C-NEMA17.holes.png new file mode 100644 index 0000000000000000000000000000000000000000..e14ffbb3b6535677ad7f97e16cecca0dbea76366 GIT binary patch literal 21455 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 R-B<x~qNl5$%Q~loCICC0+qnP$ literal 0 HcmV?d00001 diff --git a/serialstep/serialstep-DRV8428P/board/hello.DRV8428P-D11C-NEMA17.interior.png b/serialstep/serialstep-DRV8428P/board/hello.DRV8428P-D11C-NEMA17.interior.png new file mode 100644 index 0000000000000000000000000000000000000000..34acd3b421bc48e61cefc9f943f06bc0e6c0d7d6 GIT binary patch literal 20296 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 literal 0 HcmV?d00001 diff --git a/serialstep/serialstep-DRV8428P/board/hello.DRV8428P-D11C-NEMA17.png b/serialstep/serialstep-DRV8428P/board/hello.DRV8428P-D11C-NEMA17.png new file mode 100644 index 0000000000000000000000000000000000000000..0b0723c90a086ea02e143137f5cd0323ce197a06 GIT binary patch literal 56114 zcmeAS@N?(olHy`uVBq!ia0y~y;Lv1XV7tn}#=yWJtjznGfq{Xuz$3Dlfnnw;5N3Ql zafuQGg93x6i(^Q|oHuuUi=-{Lu?1{!Uj3reY|+$=N2Pljl_VBAu01Tg_K5VwCEFL8 z7i{#J=J8DapI(7q%i`N&Q_naVO+0Y)_?gScj~{nuVt@dRH}-4GAxs8_8O;-5;sLFr zOi-|lz;HO~{93kQj^Fa&*Rh}wV0h5o-`{_2Hv>b-p}8UwhhCNl1%Sn0O!=kDP@uR3 z%wZ5wU%|kzL}keV2A&*7kWf;<c~*uN5suT!av(0lqrmH|4LdnC!5oHAPA!H5ds;*| zPBMsrL=?<Q;}~X4p1`!Q;s`TH;DE)IYQ_XRC$5&n4WN9&U?8_Oo?%8eG+ADlvVe)< zjI&3h08aqex?{`uco>QWf)->izkKq52*`*8p;reP4D1wHK^%q!(oI|p24;$^yHXV( z2C9EeWRRFXf$8qY4tB7TE1ir9K2Bgs28Zb^q6`T(PFy8N8-zi!4d<`)GA8Iaag`i| z`e=viUkQd|ic1`d*`|Y3Fz5t&vo#okvNDLP$f3pHP~*g9lIp+-;vW!ub&5e?_5>#1 zIezNQo**HHvcPz@h8-<n=Q1=Du!u4!s423pGA>{NNh`2_O=IYA_h`(rc?9-k!<{R0 z85P8!K2k7oWM$}Z_Gr}N5dceTc*;sKBnbp9(CDuK>1S9V_BDgy#e8U(8Spr=GQ5~Q zf$69O2RNT!X!>Qs@WtDs@eR!UYgbk>F7S8aN=dx{4iX3bD{B}R*h9nQzy=mkh6Vag zTq(&5AkzI;)-x`UcjA&Mvzp8E0c_`sSypBYUmQKaE@GI`w1A0Wi~5oSifkodX_rOo zco}jzH8*s-+kgcGrv5Tx*rE(gMn3KVj10E~f)b3G&B4-c3-0kUeC5>KFbk^QK&mvK zVTHFxV<^uhunLK(QWgwX;0E{yFfzOn2uhgPC<&G}4&Y~R_|zh@<7J7J<OHy*3`9!{ z88p11PJAHj$jYGM?$NlK=Kxs8jG0!J3{w=B9FT_w3qxJ7K6}F-Xf!e834|~->}e7C z(cTD7y9_nU>-ZRca%esf<OdtD!9iA*;gdiRn8Og^7{JKTCmb|m4x=boWX<w*d<@4q zG<{A%6H<cw*HVTX{vL@=Z2n*s1wB#L3~yjw+R(g!i6KXQiGd`u8d&;-`(0UvZGu5F zj=U@}3IIoC1JjlJj0v{Tl+n-(O1!d)t(+1PU>`eFzWT_p!N(&pLGB~i2!_&?r<o7b zLL-(z5|kZtow%Bf7$C-#U3tm)z)G?8AT&ENd~w_>$FNTr>L(4C07iy?DoYFmm}SA{ zz3BgC%kanBBT<0O0xWPrzqE$ohp&g?j>|7o62MuSfpNui<_2hDbTDn=VmRaHp=iJi ziKh<tTKR^VoSH08prI%*+sd9{vk=tA42J;521!m$mgECq7cx8!_|BeS=EUU)b77C? zU-^cau-s>&wu0e+PKyYWfdM!K8a_tyGbFG%amjv$=JpxgrHl-2>Ps$YHVc5AJY%vc z6N8%?G$me;bYx|4Q(baFkr@)J2dWqul!by`oOoGc^Z=}Z;a}oihK7qUD@%L=7#k*X zXqFsefcSUEQ7a~f#R5SYXP^<?V7f+~!GH-COA0Ka3>|(R3l*8c1q4Ha_G@ki7qul9 z8lY*N!960KK|xEg^%Rd3*v1B#HI@tl6JcQ((8R^yqP!$vVk0C>Cd~fI&Y&b1wBkXD zm81e#2gA{bb_NA5n3aqiS_}e>6Pyy+z$FZWgYGp|h8J@uI4Qys#+HOyriOX2a+=32 zfUzNtQ&Z%@AxJ1}N!!cRAjheh0*fXG|25GJ7o=epG;(S&To6`l^@(`^3HP|j;|vSL zow(R5Aq6{wK;u^)hAM?61r6PnU?&Q6Zslc&f+ejP9SfKkbU8KOJYnJkOS`1bWo`&- z5izrx>!)`IEaXse&6*(tR>mX*HE}UqQCqU1k=qn3Z6Nhpp5cnhk_}C;a8%yR$K;?3 zOYIz53<0eZ4l#+RfR!hRU2|p7@b!4e1}!!j(o$+!8YZ=ftSk5ksXWrs*0MAN!3uyM zpg<975!qL85F-8K>@H4*ot&C~-j-PHya0)dn#8{>4Rc^xc6bLcHpH}uOybrC+j&6f zwI;(8gHjJzWx{Z6^E##jfx+#Nx`5#Z$PVRYyqY^2Am+VEp3B;>cNw=PEWIBnycW%H zBY77zF)&neXfbTK8luQ5?gh4@Vb7ZV3>%J$D6+!5rE%PfhasC+KByoN68jqGXYnv( z^T<Q<*aALBR)%RjvOxuk5cw6SfAKJU=aCGunCqw405+AOH)1*CgK3J+kZO`)i|Pu7 z1Ez;tMPeYuKf|wtyKD{X+c@Fwbf{l*pW(wz1853iU|5h3iwFh>(Lu)KUt7+g@pkWn zZSvfC(jX6e1(`E5WIX)x@#DvfRq90+bN$wqGg<`}6>UB8gqwkZp&@SNY)9{A9e2hF zjT4w!t|KJEuAE(<4wty{ndP;Zus+zxVDsiU-c2&B4s1?b0$xWvuZ63Dn_5qn<+1IR zPO;=_;As(AP_68<A<yt5DE1TdON~2HCOp+(FcJuA$m_K^`RmjYu<cu~oK;xlIBhY* z2?r0xUB;JHUTaU*16h(6Xx@B+EwYbEq51!odyEe@&s2}n{P`YKZ9mv`^R?UN|KFJz zlnd2aUo?3hE5Gy*q-VwK+U0p}J}@_%q)ys;25e1&-K(_ISI%~%f}QYT2Ybdbmu%U$ zphRLI{&hj=7GVZ~$rG4N5}7vkegippMzhrgvs>H@9mgNbEzp|W_V~^*P-afBd6jm2 z<?M^w!7e^9S7d>d@LHQK$_xw)2O_Rif4b1e;K1{42}9@%g(vEgeBN>M=109}Vqj?b z^y}N|uX+bsuAKc8Y`)kZ=0cJ5MWKD1;xWo|7#J9ib7(v0zDj$#V)n)P5c40)Ezl5N zyJ?Gljp_oB0?BY^-d9$snehw@;@>S{I68ylin1hM*9r!PfVSOQ4xF#jzOI;ku^*y& zuE+uo;kCQAm=_BNFfcR}^=wx(FP*b%i#fvuc}3O}=ML=WeS2<>hz}zJLx=O<WxQ|s z7{0iAFm5t>knjE5Se%iSfnmkr8`4Dq+cUj?Gc)`Z2x`dT`SSaLg#o*35Cg-C(-Ja$ z0qb8jKV|^8mNpq2c;Ef_;0+OXuz_=z>G!cST$ne3NhU4fzWVW2Lrx6_1_$e7k2g&H z<uhMKoMC~kA}a%jlOv?O=<xGk<eO;qZuaBD7Azp44%gUa`F;Eh7y2eJy-8D$Z+`4j z!vxB+M;6HmH$P@!*rK?EVYkGA<Buu?r-O@_jVlfxc~rp&YHTq$EC(5~!2Z}vP`Ghu z9!R@%)X*~T$f6IN3=FkZwZE@ci7!ZgrEh4N$KVj_#I>Q5(K=ur*qDziW-~Hu=$pV~ zAUHYompUlm8LlkPV*@wQR!gqvKUlaV9^#TE_l($%3o@*5_F!bNQUI%DU^wI8!5B7C zNv`{`XFSLe3T@Z7$FD7Cv|4h`NbI;UgNDBcBZCyQ55kb9w1lC1N&E39J1&8(Kk`tI ztDyJSsTnfi3=4D=Ss5}M92glG9tnW@EGOJO7#Xxc(aE4-cYhl@LxQ{_>yFbY**Sgs zU%}z4^KKEt8PB^s3>wcDe&u60paXUR-$ND#h6bZMo{V{u#O5_W_K^j-U!c8#Nhi>M zX7ghnhAE(KP%Fp?P(JztYD2KXd9N3K<#U*S=Twf~d(EZCuUQ{#P+}Fib54w*;i8LF zzq8J(wBkT>W`<A2>Z}YJ3PFw`AQv+*FsyL(U}P`?JC}ihVTT`x2ljVDjNDfSh69C8 zTpxN*UYjFR-Um^1Y;hhN!xPmd3=EPS8X$)-Fz5&eF*G!Td;#KL6AWT#V21OAgBt8B z_T9Q8Q@>3R6g~-Zuhfc*|1dVxw1_Yyu!E8?sDyh9;wi&;wICidjQ1DBQ-$%8K|EF% z?=gti2u>6X3=VQmTnq*6FrFQV*9_yufq1PjUY!#c!v{D|(us?qz9N4wvxyosg#?^) zel5%J;&k$B*#(M>t(GoU=NJr>AImT>Fi6avz{Id5g8Mqx_unp7#~2JYpEkWc161f8 zds4{H;G=)((blBDb`$#y89vN@4eDX^oSZAdFe7ToqwNic$|m;dGklo4TMJYkRowAp zY{+ztIuJJFzTTyetPJmpW7!!P8VWfy84Q+swB|v*nIPiC#o*)akXQpUbwl54YX$~} z9!C$xhLtW_dE6RrgkMT9Gu+;Bj+p`69c1uP4hoEhMzI8_DHkjdFvEGtV;+V#kE=k9 ztc{$S3<i5VT617Fq&RVXXg_|<+99~_e+M}B6xd5A@3j2K-~b9o9&e~=pspDMk0*== z>bCK?!+8Fn)be~aV<{wQ{0-J;W%wi%#NeShGpASiRICWt;12h{EDQ~xn3HIO#mD^? z5rzdyFvp}haTQFBzJB)TM>)rq-5Oxi1m;_vijm1@P_S2IWmo~uaSRL$4jzmQU67Q? z0O|@b<`rpgwzN1m1zZ{*sJIgR?12R{Ln?<RgM%U{M}d-Py--lY?j@~_wP5Eo?6~5} z*ih6W($G0GClKPI$HC!@;GD~F!UO8L2WE<_5h|i~YR9Mk0qdL5jZ_4jfH^2(<^-lS zO13s)$0zTBD4T9|Izq;uVZomEYt{@56FD^=7&9C=1FLoz1bVDB4`c-$NiL89HD*5r z<x4g{=3ux2%IzS>27`R}N-(Iwm*-k?@gI=Tsep1uh6Gtf)*EM9wAGIDGB7YK(D^!j zhKxDG0zE_%h)a?6hU+d1vE!gxd;wqSj0hQhh6Q$ttT)aw*s&c4^#>N{eVrj8qt38^ z7piSWR|6BcJeNr_xNm+Ol&Tl-mP#@(tP>7uIPA0I*OMI}7i?K-cUk>7D?^622jeD# z4ez@jgWP_By>!+-3poadYETpB*vA<`Rrz~`XJjybd3$f^CO7eWzy3CU-0~)T+A{fH zri)G(PA%K#`25P*Ukf%fG5k_k!Vo#LU~B3k)(cCwPCs^j{pp)ax7XDt*sT3M_1b%W z+oFAr46o91U(R7@sH?ccoRWUvep?y)i%a*Up8RgSe|979*5C)zPW+v<uQ$@-{(|IJ z=D8W=;DLmImd5(nTha@xcXoZ&b!HQjXgDABE!*<9@?R<ApF2O7fBSRK^qlz)N7?0i zZ+RKMxO*^m88WVLwq`C-FL$ha{Vi(0y}`U`f4w^GJoX>+*~Y?G)GBOOyze0IE6dW1 zbOz8+M!=L#hsayv2~ySb*m*B(zV<it_4oE!UM>9F3P9?h%>gH_fH|CwlD9+`c&m1Q z@V=e*^WK3SN?)@3!~Z?0sFyey6p)xZ;owiUnJeE<Ss2UMu+MhOJ;oV_lY=InIO)Q@ zz&l#(^0$9^eAV~=|2_7e>2cQ0^=p6rt**WFG<}((%l2ots=pNPQ(N$$rn%|L*-u89 zj10e?`*8*IayrS~5>!}IecvqRx9^eYt*5tkSGwPqf3SJd-&?c3pZjQ)?bMU-_UE?m z8~M+fuQ-rk!~d3p;fTT#hR~TBZ_>YVEXekD{T_4l?_M1}hUl+%*5}?`mT0oMV4q`w z--5qa&N4Jaw1_OQn%wqwi}-<%qVnH*$`0AlzZDxbZsfoIx$XNqE(gU|X}2@=85HJ$ za=_<Ld-j(4Y+*Qb`tH>I^*7VronGl}vSCTd{xlArr+<7j|Ni*$UEVzIdst$8gEh~o z>xLN&3`s@mtQlTbf6Q{34YtNiXP7RuK>U~TisL`onggVF`QBz=*vP5rAnv2}Z;34^ zd3t!xeWCr9k>SYmLjDWAr&*GpMc<s6!ua9jt<z1X*#%nvaWRwynHx`FU~p4f!f<zH z;ic3`tPbvJyI7cuFRXX8J!h`rbC-u9fyIgI!dgkSShYxolC&qM^$eCTtvfqmj^Nf^ z^Q`YLP%1TMXgC3GMf>gY*~IYTg2(izhACgN3(odC-7ekdsQfC8fkBW{(?Mdsx`v>7 zoLU4!NzU7)SD*Hr++$<E^<Hb)zuA{w|F7G6uRC{}pRn9xxyLfU|Ngpm{bO&H&ZZyl z-~T^ZbnfabJ^zw@PcPj5d935gSq4zoyJ5m2pFKVs7&t(M&an%hzeud`xXZ(^pxlW| zATD26Us#8MNicvRZE1Y6O7{BaOXa?9IP#N?cjatGhA$o-jBQ1^i-L=o(vnyg&-xj* zCE7Jdd;9Ib(dvw?9rG2p6`o_1xo~)vk^u+EdvP3^2R`_8Fg%#;$Hc{Oc8_|kOmSwZ zc<Yoo`4>#p)fpVP|7Y%HW?%@I+Q7tcW@##@ux!W&^+;#5H!vA&I<8+oZAY)2v4&_s z!9GR?hBu&Q%K;e{k%pTu&d-QFYpr2%pMilP4Ae7EsA1wdux8q?t@A^_F};eaE^iik zU)}$imw`cHsmc-th667^+FstDad4Wu{*-&5YV2KA2FUh;t9uI$-eP57WL=<c`O9?1 z*}cV&{~r4v{|l5FW)-QkGB6xdS-`-M94(yyDlD}@J;E=~UmR*`V7eg9y$qCQG*$bn z85kC9`98&*XTug<M%D#eF8#d~WWVfxQ%&8yAK&-?`xpOQnt{Qg?A;Ou28Z~*n%fZ$ zj4v);tMip-eSOzDK95zv?)SuOcLoNA2++7+!{eg6cO4uUUmU%3D7Cjv_qv&F7Sp$4 zP$;CRgN%@U|FZ1izkBEHc8eMa1TaKt++4r5^1aOZ&$>l!1z+;GyyxUIFfc@dN&yB2 zwvRKeiGD1uKU{G7ThX5F3z*L=4&A@)+g^S9{nzw=nwf9jS$^)1&v#}f`%6VL4*q0g zV3^Qrt;xVJ!T%&{%|nI-t<(PAy7j$o|0nh1zYqIdyZ7_}NKL^EP|yBv@C|mi%e&&U z|Nb)&2Kn)Tyv;jChK4=Y?#b1j{-&^D`t#-2b{`1T{k`?h`@LWPvOl{cb77*p-I6Wu zHu6VX-VgHncy2qS1<k<F_RNoqf#J#b8J|R+ihgU1+w$gm(cbU(zPHc(<MCSl?}j5k z#jc(H9K0iem4U%U2^0>N)!m;h#h)+~W!+pad$X->YUG{YbMkk3H+}9EdCw=nz#!0i z+?IhM;M#Mgzk8#nX+L8Q-16?a-tE{bo|d|)k+QXK4qwk*YJL0nFRQj<POS<S76yhV zpn**XTUD+fVyq3*qP{u)vUe-w<lU2c=UKAXOUuvSX52dcdGZ1#28NVJg`kuKN&@ha z0&czjItB)YzK=WD84{wN_x|T&U^sI&S)PI6fkioVAcKKn6?F79;v`r`0#b!G@Un<9 zFeHFlDIhZ$7#4JaiamyaTb74kZ_i^+E6w}!n}K2L9vl0m;4oumU^r9=N}>!54YD@h z7#SG0fpP;xGt7<~C+~_dFeJc+z!(@7a6zqOzT?Ztz;LY^oDr7JHU4Y8;mw^Yb_NEi z%E~&g_4)gw-m@_<l$@Un>al?gZO{T`PX-1CqYpRO85kl!Ig){aVL~S;H12>>CP)<n zL&(PqAY-B|x8GxAU`X)LKkxtY>)Y_xcNrKO^ma}Lb-_Uj16o1J%;o#%bLZ<sD)xVu z{{JuH!QN~8%GZ8B|JHWtm-}7s!ykQSP~LI1e_!a`?)!_r7k^*px%9>Dh}GX_biUj< zn~8xT<~b<Mtoc0eo&G%Czk8lkPp_*_@Ug%A*VX$kS5M;0nE2mPHy%Fyx$>(X1A{|3 z$o)I=Un|AFbKSf4_NE0KIyZMoXs%%>%;lBi05z;dK)yJT>n`@RNaw}dyKP5Z9!yi_ zp72YoBlZ1Hy%i2=??73;UMPq`!G=|SS=gqIdqyb}9{<%<V~T(J!r1$p?l0XF$1Ru` z7#2i>nlcQ10s#$<PopF%{55UUZi&750v;=P^UUh>i7IRJx%rZk?j_5g{=9a2=hshv zuEg$VW?)#mV=@y%;@6;@rnIX4-G}bwKK=J>QN9zC=F_*v-e0tTX`MK1(bPBdFcZUp z{C7(j96Y+Lee}H?9)32f6)v1DzqXu#EojmCGdI_t-Ndmfo>{7*_IK((4hDv~ptN!* zFhR@vH(P+wf(ubATX#i@F*H_u@t@FN$YTEG%M8}fx(o~gK@18KtaCSQ$$wtA>=R?F zuIrEETi!+=*~$Iq-5G{88<*byGjUt(?f)M8ztw&C-k5ynW^>z_-3$yf<{r0Y5OB+H zoilG=?_}rvx8AS5_i@G_W}LoXJ~k)%^Y88Vs?WZ!e!^04`ufpRr|<ti^+S${GvL~+ z;y2fJ&b#z!$7u^CoBmn`hK4#&2q<c(P5u1o&yw26_i=^$N*>l_{ubkFuzgoMJ8D1E z<A`0wP1f2z3zsk0X(_?LU@RQOu%Noj{Aot?zYSk_kC=9sdau9v+xO8{?p868#`Dwm zN$yPx+!V5(?aF4e289(244^?)CWhF}9dUizQYY(n|F3Rh+A8)_M~z85T1=UB!Gio_ zf;kWJxEL5N+ynLK8lpvVPF>vAvZ=K2gJEv8%Z~52_Hs{F-Nv~gtkdqry;#kf-*e{W z{;m1vak@OQu_tcc{9Rmr3=9supeUMN74Om?<ML{6Zl=ojrfYlef7EqZ&~~T$)i2YA zM3;Hz85s_6w1_ag=yUy2v_<#fo4?1_?-pfXsDA(H;X8%k7n&;)=CLsx$N?$wYI)@2 ze{_wm(iU9?h66okt}`&qI0<$jx9iNJEx7^N`;Ufy+IiCboyUh6cbNWmtUZ2pyIta3 z<>#j+*5&5bTNUkJ8P9C>`PaA8F`NtxQU&U)47&uD8i;(<;|jbb#=ww}_AHNq;f#|9 zW5csWB1zz`$T6Y9dF%`f7c1{DGx)kjy7Wiv=(@B`T=4b|>H51rZ$@w3o3Q-)|I}Y^ z!foU`7g)j80$f}BOZ+bjLx7Wie{Dr&ozXK!hJ*@Gco^>$X`JSwBjB2OdrIB*{3B*; z3=A5ImumPJ7`_PvF)ZlRaGl=K{XFoN+0q$rxfvLGj^ANnV0dL&TT@fB<zA-@Wd1i{ zsYdq;!R`=<vfFFFTiaK!+0m<fd(YQfd*AO(ovr)-w)dWLR=MvE9BY4X-Mi@fOUK`) zO}jtttp2(G@AcK!_vghF*YvetzdYyE4R(pM3a0}ZQXcqmF@#(VKKOiI$I%5ExwC`L zd;<-ZX<m}yXJFU{a@;Hp)@dEwFCeyhJAdCdG5XPWhK9mFYyMR89IRnwU^oRzja?we zaR)(^S@%|N*Soj*!TYlN4%xp<8Q26e_pviDWOHgV1jI~P<h6zM%k<~V4RU7(?fJG; zIa*x!t}7$MjvH0sEaia;Gj}sEIAl6;F^Gt!3fe{qYI*IBbIFchcVp9s{pu<KucJ@w zd&?6u<=yp$svc#H1<Ngcw)~W5V9*f^VpuRkqjk!>F8^$o%<J75Z>_g3J@k8)>#n8O z-{`(uAFHrs0!QKA_@Big=l@CtoWHeOc}F*sY_}Od3qwP7iwJ{;k{6@uEvBj|WqUiW z?ORijzj0lOLqg_n)qD2ei(fas&YNp)dT#l&zfs)3Ow+cCI0yth;QB1dz@Xvm!PxL- zk<Jo#Z3|bh#i!Zg_dkqzEq#9e{nvkw-T$6rf82cS_dQ}i*19shyj4Br#r3F*>kSv1 zKJJ)5|6k1S-xuE+FPZnu^y0G?28IIAw0fkg=BzIv8Bxj*zuVmmYPi3vWBTqL@x>2y zj_W>be4k}=N;PPI*yOt2n>&k{99?HiGcg=6b>d=35ndW0l*?!f(P<T&bud43clP^7 z8=j{#=)Sl<BXD&g%VFc=pk_;p2*U}bQ%+S|9tA=Cd?#R$fW24Y|G&rN7v%ridizT@ z!$X(Z>P!p=!kxGnWW<&_AWRl}5>s<~*V;SW_1W9aPc<nQ#GbBOJ5}R1r{z{DcLSTx zvJ4EMF}?<8aKLCl0>+zRrx;5VyGq0FmX1@G%g(I0YSHxYtI7LLvvd}QhVv~V3^#PW z0+%dzx+E2N>#I`K?@f+<hyF~=m8t!|cYnSk)2k?}=T*CzosQTkJ+eC-xb~P}K;V|0 z$_xxK9GVOpyr(32Y+?PP@wQ5EZSBp4sV5$sFw^mI(Aj=&r_l4H*L7>Bp7_mI{ddKm zYM+BL91Ng|V1|Uv8r&~0cDV=MGF^H<S9)!&<paaq=sUN5{W86+{qtA#?VFo*xf?f} ze>~NG>HXDLURN)TPj-uDW@qABbK!D~#w8me1_nL3sP_yE8(lOTzJ!>7;%u47`rMN* zHhFyA_u;eH``Ax^ukR^8`JMe#=FRn6m&7NVO@DCkyy$vH28IO|imVJ_-J2%J<qFz* z?FQ*v9#}27^68?`Dc|FMM{ze?XrFiP=&aw1;*-sqI8s3M>Fk|%PJf=fQ;LCMVZ|M0 zhSgt!Y9fW!8VE0q4eq+Wje&t-bBD=x76t}IRt7Ow%`%s0m;OuZG>>LSGcYt<Iy0Gp zAwj;sy1~yiYR{a5XIk4e<{!;Ct^u)|k%1xWBdD=+<J?>kh8-)XJDr~7;W`79SKrPG zTC<Infni4MlAme}44;L97#^(BXzlgrei3-<i&D^SCI*HrN$*$~7;bZDGJNoza`cNw z>jI73D#4Yxj0_A>uQT~XbN_KN8~}}H{&1d><mS)1Kozc)fq`KoNMFB3_sfZ57Z-1N z>AD1D-3w3u&nq*E0~r{eDJ@}e@Y3{ST)ceI`AKktcj(`mBf`*7X|v@XV}j1}x%P|K zYP5DEyXwoUuW!S5{8V6Ixbn=8%R%h<78$3A&r+|tgKRptbjU6B)mPf8%fR69zG_yo z>+JbV3<m7wK@5DB@;~O<?)Q!h>=LyVt(fMLdAZvo*Sq$j-T9vL=|T(%yQe=_FSci3 z*j4oF$B!Qwdxb6M_$}9Zzu185zg77r-eY1bCkVZj5?q<9sekLaIKu*!<kTXAV{G3f zeoC2~C=y|i+%fr(mzwB@<;BO|KDj0KxYI<lyKHX9m2Fc*-);ttL@Dn+bNOl>gTzd0 zO`U)p?eEVyZu88UsFrkbo#@0{(~1_=<}os48Rx07KhArwV&Xb?=tRsRSvA3eyOqb! zfB(bxxy$5dSIOFrE9<6+zAWZuxG<~G#9gwU*}b<&R|-70_3v^OdsXTuhU;_1>&jj~ z|6aFkOYAeD%uAv#qXbvRYHDA4F2=Bc{g^+)mS<5c2Qom@um{;QlrK3|Ey;FWQnqxB z$NXpp28mWn$qCJtwhYRGK|c<)%6+p;uao`U8M37lY&iqNh1DL#48KzH*q%J7VmYAE zB4StA$ey7bv{CKSR;8fbL2*mY>oGX=_bg|4(fC@BK^au>tn}c1IZ>@~;;pHllxoWu z84^OCWil{)xDBfPlPtyWm7RQhdA<hgtPJiwfw!hwEvl_!WT^V~=}*cYUIvDO3D%l_ zd>Q3mS!}<@xJz*92JyGQ1eV6GR0hQbgIoGJwkHYu_#H}|xExHMU$b^FUnG*c$oI#h zE!qqW2hN<i3vJ*1{=4V%X8HPmU-u*xXUA=RzW1f~l%$>pri-q>dBE!mz-gt+I=$+w z{X15X7g1AMzhrdp4!kwBYEf+)BSV7OvqA=jGd>=S8n5QOG(94|ltDPR(A;ZxkpGtR z1`G}+$D*Gk*|9SmSkofXkaTWl+-LUkKn_i>hpJH<4dJR>j)A5Gk8@};xXv-&`;4E7 zOVL&Hfot@g-b?Ek7#QxP<*_py=xGsYcmp<pv30^Ck!ThX3CAtx4MANGhGL;0hD}!K zRlFZvBR%@JZIE6XyHfksa|s59AJZ%47#KDS1~F{1Os_g?{%(<g-xMbAEv<Jo-g?De zv^&ngaG?BIH3P$$C!k4~WDAfYCa#ArnrmF5ZuDMSc18SUF%N?QQ*to_L&M`co{Sc6 z=Dak$&!N#Gyfi^PGtt}&)Nv{30aekP1wi=<><rCi92y2)9`jQf8U!Wg2REOWWMD8B z2x2G$1!d^FMFL(^l)RR>-qpzUlAdUHnt?&tz>XbKquh8p=cQ@5E~`l0o4W?8E}GX| zqptK`TDC>-<z^lRhMaUi4u%6ST0|Poo|_q0Jhj0|BalmdqFCwTEt<J5zjT-xdJaj< z6{~s2z#uVm0@H?*mY1{31Or}pO=<E3+sDPgU<~R*^!Nqa)iW^kyaM_AvE}=}N9UK< zg*z<N7UWW$c!*Q;Xh!g@u5UBh7&^}Um=m{W-(Mqf28IL+CoTv1X>y+(#21OYS|nPq zXp8n+m)}0j3@)iTe*Jp$y+1QCFt{l$Vc4==B%naNb=e}(my1Mm7j4!5>IzntAmisU z-+ucuP6qJmlNp|d+h^qbTRXX-so1nF<9Y9SQSYjMKEMAkfhQm@^v`?#?*I9Fcb{Ba zxh0!<op7qidZkJwNl&YnDN@tqPWIY%-t|1Le9}e7HC@O(`u_Eb&1D7;mp3$NJ=nG6 zgw6{4JqOBSwsSLNTy4L_%#fFtCEDu7#5L#e&411>#J%Rsd@T-2KMh-3L>j7CL^NC+ z8nv^&?kf8W?$mAo4L5YVtZZAx#ASK>;q)-|qT@3js2;z$E*qqa;Y6w`D}&$b9O0cz zTu(B7?keL2XPFICComP*tX2tdI4!)>+2`G)#ZO<~GUWkjao}{~I<S#NL}S6z&O3@~ z<(Agh4M5@yOF1+djtd4XU|?ijx9V#4ZK!fj`D}g$hN7)joz_Q==y}h1c?+~?m!Uy- z%@PKg!&+Q9CCfZx7+I%f{Jd4B3${F9)>M%Nfk)Nb?y2?JuFd(pzB75f@%rtvtma>; z4U9cKc}J~UY2>1(*|)cX9dtl$%@PKO%Te==yft2VI&{Z0(C|IOjqV9d8_r$vVhiYK zU<$wX>g(Gmu)PWXPFxO^+4Ay?vTOYw@ENW=9hANcG>*l<us}tTHR0zfj<CRl^z>N= zL<165PFtUU-5Bh<>faI73<n(NT`Jk}KsS=H@m18kJ+eto)0al=I~IE$tVHIZ7uSLO zVr`W@sZ#_?5|&O=&u^b`;i*>)RQjkFSAlx*YRx4*k2f$gvc6kz_4S>v5HCzzvxH$v zvM6g<M(Lxn9?sZn7Pm`53ji1xss)1@cHh+YP*`w)D}DA3(SU^BY3qxxn}BU}7Y=H$ z){@l_2uNt1rk>Y6<4h`&tSN`)f!L{BVjLP9oK6dGclLQ!WV$XBtT9V4sKL70>$Vdc z6W1Dr1qWicRIS~;3><JPUM9a~WZ<o6;k_p|t-UpB?iSf(qv>1Em8}Iw&Vj%dk%s%{ zMC>dsM|f(^&A$}p(6}{f-?iB5V1utbE97T*v+k+qZAG=B$kk7?@0Nn5bQm1C*DPT; zur6xembb>8r$cvc1KX9+I#q<>MsEXC`K4E1-$4?_0#zq2hBu3@a^6-{D+H@z=u=$6 z;84iKb;o!0^*yh_%S;-sacD9Ggsh&t)!FAkQR+I-=pq9{l*$qY2SX;V3vAaxbCnDX zYkx&lGce4#Kl2c$=F9_6Z^eKHXc-u`oblpf$WemMk2-+nnZkqv8n(S-z7AQ9w^lfa zAz|t?wY1_Hd!D|Ec?|a3oW==E4Bea>4$&|H(4y~d4kUrj2}}$(!TnPP28J7;4yz6m z*9E!jmS6+Ym6tFa&|zfF=zk5Gd}U}b77AiWm;{|SWB_F#12531GiVlhQi}+K1Zbca zq}3r4l#3d^&Cy(-09w1jz`#%-7Z$|uKo&a9$nZ^R3B!T?aH}UzU}DgO%`-E6Q(wZ+ z0JElDAc$dyB}`x6r;Xnj7*;&?dDt=qrhDB1FD?dixZS)?Tny&Qu)qSX3NwcXoi9jE z5hj-l;wiv*+$|yudVVnfgmGvx#LR#>LRT<|VTT6H5mBEveq(qL0?O}ar^s9F+wT5f z^_QI0_l;%WwRXF#ERO#*&)f-SkQk??gJ-btt-r~}!gp4y&D`Jr=KubCuh*ZR?e||Y zvwX$cg`48pzV-H&uXr<O@44C+F>=>>jF;X|j{R&GGXZM<fm#kt2hCu{)|H=B|4G&7 zG}W#9BdT`te9=4a<CVg&xz+DVOBlB9UHa9rb*=FIYM&eZy)S<|{?%E#zdXXxB5^_i zxP)amU|YMwmO()`zEyGQrpfm$b9;TCt(QF>v3Jge0~ep~+ZM~%>IgScbqT}T2%(T0 z$)A4f2)|l8e|Nzl6=*0lR0{_+Onbs2`fUz_{#TCHsJGYiqAe2P$-{|j!}jH^Pp{kj zN<4FY%J&~Fs&9ECtt|IH4dmbHHUGB^W2-03nk7>%9lyog;QfkSc-Q*vEdoVqhuYPi z?fzX9X02hdQ=a>Kf7Z`C*I7jRcmhITs{{@-PZe3PW#?4kqOh<C>68;Qf85J1vMFCw zw_cPzYwqt!pMTEki+{M#2<lpfU2B#ws6Ms3^-yza?HXsV(`x(nFZ-I<s9XB{mhGav zlOOeYHSS#aJpKIE_5)5$s-Q&7aA01G$bu<%8l1NOnY7?goVGyE*Q=M7RGmwf^7<C~ z=}z=78>hDC`tw;K%YGZ~R@`BZIXJ8H1GC!s$M1x{l-t+)o#v8&7!}td((u$s?f&9| z>gB~piy=|b(Ay%?@MzIDhAiQL2TW@~1EUNK3~wAg7&Wxyq~ojQ-#^NG4r;eEFfee} ztg&Tyuw>t|Df|A{Nk-q=*`+-fD)q*}gK^!1>L@$Mf3^Eg%(-!o<$|E{?cn3jUp<-D zxVl>U#&?t8ycZRDw}a*0z6;eahb*!*<<N|olinr%ZGLC+|LN0MS*NwJRB4O9$$H(z z@b_2ral7#St)e_p63h(sGiF_=m)U)5$-mI^U@Ld9DYkM8`K-_=cWt&k#O56qY@zk0 zV2Y`>=M<F%4$4Y@cLq8AH@)Ne&WknwWQ!dr1VH7mo{Pmo!D8WOmW+*CC*SMecKp?J zKJ_UPiVLUgEN&O>`0~$?@1nKY7TzZ_tG67U_g5zJ{o3uiHQ+LJi<`$oB^D8>&DXtH zcP?z0b+B>cuWI{G4-?n*2rwVe<^8+n%gXASr2BJBOTVr9US1`i5_L(Bf#HB)TwMJX zIVOgHo1n%>)ibq=-{+*{*D~!t^5a{CFH=Ksm&u<QpwannpZ`4FY`=@SVfN-phgg3! zzH{<3dnl`Uc3pu$GJDp%*LRdH7cBCqxBH}6bsX#>hI6O9xGr?5PJUMHvtfG1=Z;VX zuera!Z@HgrxnPmR&9>d$%)ej$zr9(Gf#E>p&&SpbJM^_R9k{Rg>^Z+CVMFzQ)2TM) z3pDE-C%*5Qzk2a}>t9oXs$TEuYcz8HeNHEf9~5Q`32hUYu543P_^@Jk*`a+Q7Kxb| z3!ZdwZ9OkrCh+pFvizk3W)qgnhrH-6c~`9+CI_zYK&y(pRvHH0&)44mU)%S>{hxOj zPkfpZRQ2v{_r0<uM%T6lulm3D7Fex@s|TakDqF_5&HwN0`!4nP=B-v)mtV!3w*I%e ze)06D!xxoe%a!b5j%k{}#9*QkwAbC1L*qcD%Ueh==zyjNt-EJlKVWyy>UMp&G-Sza ztP>Z5<eyZ_=$hAi>mmd5*ZA!}6A*9t_P|x%T3PvB=GX4%XTRUL_%$N~gUrL9r=Q<) zW?+y4O&#=BdHw(E{bBhn=0@&{+4`GS`ThSF6P)f1noeYB*en>d!?Ip>--USL<8i0U zR1105eB>~*+4k_<uJ4CqAk`MA`em>-X5{*6^KSpb4NcX;pul`k;l#yoVZ%<(D+?e0 ztyN1>{BIXgynoH!<9+McLGl-x__u-?AkH1cPN@P8MTn0W7#;|K<}N|<3<nfJ6Cq$` zgEMS_I0HlbkBDl90xf^INd=&#Pa6(Jr|sOBb2;R1-Q0znf>Y<QeS6x+{qBwK)4S5{ zclKM>?(PSLCAfMm6Wz+rFqPN0>Kv;~k-FD*i$##6(6A5eyg!=iCpMJJ7pS}6<InzG zbRJxegeR!7GVp!<^R)P_qR7XUn`N1g@BaPo<(_xb=T`l-xezX8aZlekMBi=Of6p+R zhjP#MeY1HteNOeG_wn+(pUT}n|8nov@A>yH%s6(6iGktz=TE;De-mI}=-N1miJ`sX z->08OjIA;oH~E~A(O-D~UEE)W+pb0ZObiU)fA8gDC;-)=Z_d>(I^8+(t?t_ccU@cS z`d$e$FzgW9pUlXx&H=QVPx$4J{qyWL>1V`Vfov8!(8{UFutA&if0^rBMuyEwS2^_< z85rJv+AYTL;EmliIR=9_PrtgqRb<dUdgisz+v5k!HpG0{mb@Y4=D(x_aD(cB9%%L1 z;u{-#g>socCp{>wmj}njZO{Pw?p?oEDFjwC2rv2u7G!9+4O$s@Na^kW@EeAkVi(!& z=st00d-{I&FW@M@Ak<&YkWj9_-u@D}2G}@T<BnVBw`pJ4d)UR=zJc?~hIvy(7%YyQ ze%*iD{+FVAPtN<R$LIZp82=^Gld-`$R&~XPwVVHLT5!+X>*d<($AZ)EpKmNX{_EAY ztM3=buit(5?c>a}J?^_dbxB{j`v2DFY4`4PFaE05_q0YfqWXW{OJN2E3-$l%Yz*(5 zK<gN#XRWYNvbhlDz?dbmoBy7b{O{DZcQ=pQeFs-J2Tb~_85)|;`X+HfmjZ@^x<)G& zNDE2)@_wuOmgjHi_mKL6@}1v({C4X0y#RY+0cbRLgVRaR|7*3idt}9Z8WMMYck8TP z{pFPAJ8%!{!5h%@GsIgKEmK7p8nS=y+xYLg(&8VvSvE_5pSpMpviE3*i6SdQ!``QC zs=J<oW_>|R7!^R%_%|-!nkutx9RnyyGcfROn#9C#K+da$M=tlx)>Takphd+D4D6dH zF)=t~E>-{E3R(-rz_5cuTa)2{Q@-ZX<*iS5x4qhTRz^O1`TqQKcXkvXJJ_?AiS>T) zO;J%6`LNl$-v9c3HsIz;Bky<hAcunUO~c$C-xRxVvr}5O>F_GZ9=t9Hl6sH@N+s-; z+A>?r6nB+`wq1U)-p*ia(}8PKxr)NoC0?m7&s%v_WX+-v?aJ%_->LrJ6AxNLz`*c~ zLzCeEQ~un3Z#6dgRB!*5bGo|ot&g2%6NxewHK>reZSA12V8hJ|e`BmP3`+HP$Af&^ zU@RQ8pyRpz{A_;42Lki0Zl709O-lG3`0f3@fAw{_&$s+u`MqjIjNi<45;wko{(9U; zm+h?Yzvt^3K9nw7yLGkZ9h*4@-#4Fne6RA(WXo%JwmUy<zxDE6cihkYmwy}TNg6XS z+_~8O|2Y$b$y4XIj0JT}Tnx`ewz3zfdponL%2{9he|*J?3+J!dZNJ9O&|v-Xw>Lw> zHV(}Vo$?<VtvhF4XISd;{QiwX1_p)s_mi0zwm5q<Uj386&#*sY<%6I_-x$)sMfw5H zpS5ZX4$`22Te!lu!71s1{2kw(ob9*n2h25n3kp?+E8s@>1D>R$|2GV8Jjs5`cwyFw zJCLkoq^-%oP*837dDk|Wkd-1ULxe(=eB<Y?Gqu&<W?#M^Fmp~7*d*OgJJ=a!2rA#c zTkHIL`Zq!5+rdv8ixz!jaC3PEZZ|Z526z~D%v#TVs_uTS$a3+Oc?t<D-Y={LYfo2N zazGJM#UIGJZ**!;&y@euf~sCkt@YOYE3?8nG=Gg>eEpi_r^lYm(Vi3dKYijqThplg zM-kuaPVQ8XuezNt{Fk?P{r{~j3=BWkLt>7hffeL;r*fgfjHVB3KYv^q{4RIFnF-79 zmHF8UPYt+sWv^|@iyO)J=Y3CqcU=hNj)rNVCN;y3MRPcvCwB$hzf)@=3hpQ~Bv>l4 zGMq3ln`mizaObldmro@-?3?r8py2mezrow0b|{0gF=uqRON2FNWy#*4uMc^O)_*pA zxMXRn_ZLv2Vkl4xgD-pFgRM+tV2}Y75+KVN7%W;qD@nlYf{uPr-E*Mfz3}mUa%P|f z;S3BKr@SBx257ytZPO;O(F`e|RTdF1beDeFvf#~xy1&~ylaq68eYe=Bt$4f8tmr)d zIgRi8PVN<7{_4q{c+2nqXKe!8q6^B@Z&I?9iZgd4@aJdN$OIpcc=-F=)0?f;U<C_o z6j>Q=IG%fwc9!$PoqfKS^bEeAXutE|V2ow|G>a>8-w)g}yW0;^dO)<|4)gLa;JS;! zTy($Pzson}v?qW5b@ANtbNil8EVKU_XTN;PzqlLU7r*rvPK}GJpTTqYv~q)ih{=Yk zL+f_gTl>WRcmDnB`;+_3Pvvg^-Sqc&*^0Ase($$mwsI2#!-lJ;U-yF=7Y`1#h*<C* zWO>k&lyd(<UD>9TPxUL_Oq$BQFYViQvk3{Jt+zWtt)d6hcI|H$j$mL|VA5ax0JLhh zVRQGyTn2`WnfFgKGJpnq7!-ne_Pl#<-MzxLLHl&9Z=&yRkXINAik!Gi{G+5Ze3xYV zf7*Xl?tthNJ}nN7H)>{b_oMg!|Ci0cU~%a4^z(AR8FIea|Nm^iwVk1W^Z)z*fA`;V zzH#QU9799B>-(?4y^b+QuWzx930TA%*15%BLBS0&{s68RjE)@on=Z2VIulpx8eT~b z^$<{t0c3wcpxk!`25y(<$vxAo=D*l07ND_4+G0i(PfNm~he?l0d1Syj6ugjS$Icgf z_r*9Y+}c_HI5TR=-)646X5QPuLmwBcKuJ>a;_bf1+NHlEg7$^%SG^5s0!bvPvNGHV zTvFD|VEB1f<;0!!EAHIcHzT8d6=XakW99^=>7T&uhX(Fn(*mC@-TwF5>i-ojhoZe+ zra!+Cy#7wW+=W$l|1CRa6_%GJ^Q3cTa`5ru(@(zaU)pQ^@?Xz|z5c(xd;GsAp*8vP zxtN*%u6OP%oA!m1fnn#o{Wa@sSr{1dJUkc~)JoI^+tohZw~}A3_N!e@`S-l4r^jBs z5!9F=HJ{<|e5K7kemmFpy?VZ?=-t^lR{gc_#6jWH0Ga@vkeKsmqrA?H+xFL=#n=ij z_<FSIx?#Z{m;Fm`rOc}ak6|rX18!=Cf1PrynIl+uzVq?tuL9gt-bq{Ag_~`^zxA!b zyN>E}w&1|JGjXa2LxR&el}9l%w+c_pe)aU4p=DLw#1`Rex2pc?uZ;ioy15!`yM;BV zU=$I1IYYp)CkI>`JFEsZBKgFWZ-bo2P*950yaY9Z7!HWOOo^&yfSwC*<PfB}QQ!_L z5LUnv#e-8IQ~b1`X=FhtC>1E*Gdg9nHY0t-x!Y$xZY(Q0W^uhd@4rv?#J9@7l4q{{ z{w?Hh-Cj^z^v+_C-3P8ldNMMYRd_!Zo|b%k*(;gc3?1Fx^`#Sc>M#FytIGTJq~%k8 zAFu_NA~C&FMHm(|Z2$6a{p?~jf#0QlX6DCkJ<bkY@~7b7m5ru<i}uX=-dGLlR59#O z0u_H-Oj-;=wttDYKd-C1|H(x`=i@$2eBCDUQZuaMP6hsr2|f2%^4P02wJgr(YE8e+ z;P|cqa#KN?6PLjQNY_B>!^-c!c5eP#{;Rm?N8z6R_EyJ#ef{_I>#p13+vnf;sH1sV zUwm(o|9X2J)%l8-DjX7W{$DD4_G;q#-+OCc)y>|u{Wq*Sy}$Tw@?XQgue=Nnw)*Ss zv-lYq7-p$1VX$T5a#-i_`rj<O<#NvjT2J-Lp3j~CyYtKMUoY~Q87{#3`3XnbZ!tGa z<IrFz7d&}HO-9#k+woI&{}>qx{OZoLFfbfmvxI>``>0%RU3|p9?4SSc|GRbL*yU4I z`I<}r_sB$7&kLS^-uBj=OL>{@^MBuaZu^~Q($?#-@8>A_?w1RBXxsmIH@JPI;pD+s zH!+X>*^yJpyI=Wj5SyXVJLS^(wY??klc)R0*e{*(FaODn?;+)%>OCu-1b)+bta~-= zVfM%P;)g8@i@4YAj;MSyckj7cmot0V7#7IN{bpcbs0UTGHxz=Lg<I}lUUu@O#EtFW z`Y-?gI_;DCOmFRv;s2xUmP_C7znaA&()KD>_V~2y<p)Z|v$fC7sqV>n{_1+<W$=Ks z184|sgX0o5b<S`ff#V1Eon>rY7v<Qh>*f3HI+u1%VAh%JTN;u%H!t`t>HYqV?|mi6 z4Gatn7R;cuAhNgqZ}Qobb5wd8Yh9VS_$`Hx1#8R5SYF)k9`D|>KWxK-km~A|$h2EM zjrD&YuNM6ibL<SbVG3>tG)zrezOCri*>}}xlS)?1jb-BEcVD|=!_z?i^yse-7CtS! zE*E`vstwyYTeoe;znp$@1zgQ#Or5~Q5OengOJT}8?R8Jx?VtE9tC#%|zUl8$FS}Vu z`o+1=<HY@$|9gGeznr)BILyAEpt0D3u!)h&;`Nr_Tky~2$E42l@87@X?@i3OZ*4jG zpehqb{N*1zzn*(s5L|2DcXqG-*7J#HCN&(pwJW)3-RzaG-xsbaVNiQsd&}^TfH7!p zo`K<<hX-R=MdjbXYK{Yp`_At9ceDEMrJpzEYR_Hu{fhqg>jiVC1pWGX>-Fl-zb+>3 zzvun^X#9R_nXLa8>;K<ablm=lpV)rg+=|An{Z%t&=bYme^J&%jRuB@e$|RM2|N9*) z|I9D9s(;>>|9_A9ZuXzs@%7XGewX`O+Q0Wp-~Q6mf3-fp&8=AR|J&DaFa5dAf7c7& z{o8N%D?YjH-R<^R`O8cU2jpP|t%WYA8jyYBBk}FD&dm1MtBGF6ZL=O`887n=x3kDv z+Ok;g^9Gd#fwwMYul%re`rSKM*HwbDZNps9eh)_H&yy`zU*>-sU#zqKz`<=jsi(Wx z(*qvKME$kV;nk86ofDb(QT5KHzu+qAf(FPgLDgr{*SBq4dGE-i@0x$V-w5WOyt3Nn zQ{vmja^DKRB+Gw$wfoES+>^ieT`t|V^``3A`%~Y}{XI(o+`B(;6I6iR=%0D5cFV4= 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 literal 0 HcmV?d00001 diff --git a/serialstep/serialstep-DRV8428P/board/hello.DRV8428P-D11C-NEMA17.traces.png b/serialstep/serialstep-DRV8428P/board/hello.DRV8428P-D11C-NEMA17.traces.png new file mode 100644 index 0000000000000000000000000000000000000000..c663ae1f619bab07e75a27afd73a710455b50e5f GIT binary patch literal 23212 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 N44$rjF6*2UngEp_*&+Y{ literal 0 HcmV?d00001 -- GitLab