Ejemplo n.º 1
0
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])
Ejemplo n.º 2
0
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)
Ejemplo n.º 3
0
# 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)
Ejemplo n.º 4
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)