def smp_connector(em, x, y, z, zmax, coax_port_length=0.2e-3, pin_diameter=0.85e-3): copper_shield = Metal(em, 'smp_shield') copper = Metal(em, 'smp_pin') lcp = Dielectric(em, 'lcp', eps_r=3.2) # shield outside = np.array([[-2.5, 1.0], [-2.5, 2.5], [2.5, 2.5], [2.5, -2.5], [-2.5, -2.5], [-2.5, -1.0]]) * 1e-3 angle = np.arcsin(1.0 / 2.25) inside = arc(0, 0, 4.5e-3 / 2.0, -np.pi + angle, np.pi - angle) Polygon(copper_shield, priority=9, pcb_layer=None, points=[x, y] + np.concatenate((inside, outside)), elevation=[z, z + 0.9e-3], normal_direction='z') outside = np.array([[0, 2.5], [2.5, 2.5], [2.5, -2.5], [0, -2.5]]) * 1e-3 inside = arc(0, 0, 1.95e-3 / 2.0, -np.pi * 0.5, np.pi * 0.5) for m in ['', 'x']: Polygon(copper_shield, 9, pcb_layer=None, points=[x, y] + np.concatenate((inside, outside)), elevation=[z + 0.9e-3, zmax], normal_direction='z', mirror=m) # pin start = np.array([x, y, zmax - coax_port_length]) stop = np.array([x, y, z + 0.9e-3]) Cylinder(copper, 9, start, stop, 0.5 * pin_diameter) # smaller part of pin Cylinder(copper, 9, start, [x, y, z], 0.5 * 0.8e-3) # insulator Cylinder(lcp, 1, [x, y, z], [x, y, z + 0.9e-3], 2.25e-3) if coax_port_length != 0: # port (coax) start = [ x + 0.5 * coax_port_length, y + 0.5 * coax_port_length, zmax - coax_port_length ] stop = [x - 0.5 * coax_port_length, y - 0.5 * coax_port_length, zmax] Port(em, start, stop, direction='z', z=50) em.mesh.AddLine('z', start[2])
def idbpf( em, # openems instance sub, # substrate, define with Dielectric() z=[], # z position, z[0] = sub bottom, z[1] = sub top, z[2] = foil top lidz=0, # upper substrate thickness rl=[], # length of resonator fingers rw=[], # width of resonator fingers space=[], # space between resonator fingers endmetal=True, # add metal to filter ends portlength=0.2 * mm, # length of the openems port feedwidth=0.85 * mm, # width of the trace leaving the filter and port end_gap=0.3 * mm, # space between the end of a resonator and ground via_radius=0.15 * mm, # radius of the via drills via_padradius=0.3 * mm, # radius of the via pads pcb_layer='F.Cu', # Kicad layer mask=None, # mask, define with Dielectric() mask_thickness=0, # set to non-zero to enable solder mask over filter ): edge_space = 0.5 * mm pec = Metal(em, 'pec_filter') ring_ix = 0.5 * (np.max(rl) + end_gap) ring_ox = ring_ix + 2.0 * via_padradius via_z = [[z[0], z[1] + lidz], [z[1], z[2]]] # fingers y = -0.5 * space[-1:][0] mirror = False mirrorstring = ['', 'x'] for i in range(len(space))[::-1]: # reverse order x1 = 0.5 * (ring_ox + ring_ix) x2 = ring_ix - rl[i] y += space[i] start = [x1, y, z[1]] y += rw[i] stop = [x2, y, z[2]] box = Box(pec, 9, start, stop, padname='poly', pcb_layer=pcb_layer) box.mirror(mirrorstring[mirror]) mirror = not mirror box2 = box.duplicate() box2.mirror('xy') if i == 0: continue v = Via(pec, priority=2, x=ring_ix + via_padradius, y=y - 0.5 * rw[i], z=via_z, drillradius=via_radius, padradius=via_padradius, padname='2') if not mirror: v.mirror('x') v.duplicate().mirror('xy') mirror = not mirror # ports y1 = y + feedwidth - rw[0] # outer edge of feed y2 = y - rw[0] # inner edge px = ring_ox start = [px, y2, z[1]] stop = [px - portlength, y1, z[2]] p = Port(em, start, stop, direction='x', z=50) p.mirror(mirrorstring[mirror]) p2 = p.duplicate().mirror('xy') # feed lines start = [-ring_ix + rl[0], y1, z[1]] stop = [px - portlength, y2, z[2]] box = Box(pec, 9, start, stop, padname='1', pcb_layer=pcb_layer) box.mirror(mirrorstring[mirror]) box2 = box.duplicate() box2.mirror('xy') box2.padname = '3' # substrate start = np.array([ring_ox, y1 + edge_space, z[0]]) stop = mirror(start, 'xy') stop[2] = z[1] + lidz sub = Box(sub, 1, start, stop) # mask if mask_thickness > 0.0: start = np.array([ring_ox, y2, z[1]]) stop = mirror(start, 'xy') stop[2] += mask_thickness Box(mask, 1, start, stop) # grounded end metal if endmetal: for m in ['', 'xy']: Box(pec, 9, start=[ring_ix, -y2 + space[0], z[1]], stop=[ring_ix + 2.0 * via_padradius, y1 + edge_space, z[2]], padname='2', pcb_layer=pcb_layer, mirror=m)
# substrate start = np.array([-0.5 * box_length, 0.5 * box_width, substrate_bottom]) stop = np.array([0.0, -0.5 * box_width, substrate_top]) Box(sub, 1, start, stop) # line port_length = 0.065 * mm start = np.array( [-0.5 * box_length + port_length, 0.5 * ms_width, substrate_top]) stop = np.array([0, -0.5 * ms_width, foil_top]) Box(copper_ms, 1, start, stop, padname=None) # port (ms) stop[0] = -0.5 * box_length Port(em, start, stop, direction='x', z=50) # pad ypad = 0.3e-3 xpad = -0.62e-3 xpad2 = -0.8e-3 xpad1 = -0.1e-3 points = np.array([[0, 0], [xpad1, ypad], [xpad, ypad], [xpad2, 0], [xpad, -ypad], [xpad1, -ypad]]) Polygon(copper, points, [substrate_top, foil_top], is_custom_pad=True, pad_name='1', x=0.5 * xpad, y=0)
def generate( em, sub, mask, min_width, # minimum copper width, typically design rule minimum cutout_width, # width of ground plane cutouts inductors, capacitors, z, # bottom of [air below, bottom metal, substrate, top metal, air above, lid] port_length, ms_width, box_width, half_fan_angle=0.25*np.pi): em.mesh.AddLine('z', z[0]) # air above, below em.mesh.AddLine('z', z[5]) em.mesh.AddLine('z', 0.5*(z[2]+z[3])) em.mesh.AddLine('z', 0.25*(3*z[2]+z[3])) em.mesh.AddLine('z', 0.25*(z[2]+3*z[3])) em.mesh.AddLine('y', -0.5*min_width) em.mesh.AddLine('y', 0.5*min_width) box_length = 2.0*(np.sum(inductors) + capacitors[0] + 0.5e-3) x0 = -0.5*box_length x1 = x0 + port_length x2 = x1 + ms_width yb = 0.5*cutout_width yo = -0.1e-3 # overlap pec = Metal(em, 'pec') # substrate start = np.array([ 0.5*box_length, 0.5*box_width, z[2]]) stop = np.array([-0.5*box_length, -0.5*box_width, z[3]]) Box(sub, 1, start, stop) # solder mask if mask != None: start[2] = z[3] + 25e-6 Box(mask, 1, start, stop) # top copper polygon points = np.zeros((6+10*len(inductors),2)) points[0] = [x1, 0.5*ms_width] x = -np.sum(inductors) points[1] = [x - 0.5*ms_width, 0.5*ms_width] points[2:10] = arc(x, 0, capacitors[0], 0.5*np.pi+half_fan_angle, 0.5*np.pi-half_fan_angle, npoints = 8) points[10] = [x + 0.5*min_width, 0.5*min_width] i = 11 x += inductors[0] for j in range(1, len(inductors)): points[i+0] = [x-0.5*min_width, 0.5*min_width] points[i+1:i+9] = arc(x, 0, capacitors[j], 0.5*np.pi+half_fan_angle, 0.5*np.pi-half_fan_angle, npoints = 8) points[i+9] = [x+0.5*min_width, 0.5*min_width] i += 10 x += inductors[j] # center cap points[i+0] = [-0.5*min_width, 0.5*min_width] points[i+1:i+5] = arc(0, 0, capacitors[-1], 0.5*np.pi+half_fan_angle, 0.5*np.pi + 0.001, npoints = 4) print(points) points = np.concatenate((points, points[::-1]*[-1,1])) points = np.concatenate((points, points[::-1]*[1,-1])) Polygon(pec, points, z[3:5], priority=9, pcb_layer = 'F.Cu') # ground plane gpec = Metal(em, 'ground_plane') points = np.zeros((2+6*len(inductors),2)) points[0] = [x0, 0.5*box_width] points[1] = [x0, yo] i = 2 x = -np.sum(inductors) for l in inductors: hmw = 0.5*min_width xl = x + hmw points[i+0] = [xl,yo] points[i+1] = [xl,hmw] xl = x + yb points[i+2] = [xl,yb] xl = x + l - yb points[i+3] = [xl,yb] xl = x + l - hmw points[i+4] = [xl,hmw] points[i+5] = [xl,yo] i += 6 x += l print("ground plane",points) for ym in [1,-1]: Polygon(gpec, points = [1,ym] * np.concatenate((points, points[::-1]*[-1,1])), priority = 9, elevation = z[1:3], pcb_layer = 'B.Cu', is_custom_pad = True, x=0, y=ym*(yb+0.1e-3), pad_name='3', ) for (xm,padname) in [(-1,2),(1,1)]: # main line ports start = [x0*xm, -0.5*ms_width, z[3]] stop = [x1*xm, 0.5*ms_width, z[4]] Port(em, start, stop, direction='x', z=50) # pads start[0] = x2*xm l1 = Box(pec, 9, start, stop, padname=padname)