Esempio n. 1
0
def place_parts(json_dict, pcb):
    # compute upper left corner of board
    board_ul = Point(*BoardTools.get_board_ul(json_dict['board_edge']))

    # place all components
    for name, module in json_dict['module_dict'].items():
        if module['type'] == 'comp':
            # set rotation
            rot = module['rotation']
            pcb.modules[name].rotation = rot

            # make the buffer vector
            if round(degrees(rot)) in [0, 180]:
                buf_space = Point(module['bufx'], module['bufy'])
            elif round(degrees(rot)) in [90, 270]:
                buf_space = Point(module['bufy'], module['bufx'])
            else:
                raise Exception("Can't determine rotation.")

            # set position
            pcb.modules[name].position =          \
                pcb.modules[name].position        \
                + Point(module['x'], module['y']) \
                + buf_space                       \
                + board_ul                        \
                - pcb.modules[name].boundingBox.ul

        elif module['type'] == 'keepout':
            pass
        else:
            raise Exception('Unimplemented component type: ' +
                            str(module['type']))
Esempio n. 2
0
def draw_board_edge(json_dict, pcb):
    # compute upper left corner of board
    board_ul = Point(*BoardTools.get_board_ul(json_dict['board_edge']))

    # draw edge
    edge = [Point(x, y) + board_ul for x, y in json_dict['board_edge']]
    pcb.add_polyline(edge, layer='Edge.Cuts')
Esempio n. 3
0
 def __init__(self, start, end, layer='F.SilkS', width=0.15, board=None):
     line = pcbnew.DRAWSEGMENT(board and board.native_obj)
     line.SetShape(pcbnew.S_SEGMENT)
     line.SetStart(Point.native_from(start))
     line.SetEnd(Point.native_from(end))
     line.SetLayer(pcbnew_layer.get_board_layer(board, layer))
     line.SetWidth(int(width * units.DEFAULT_UNIT_IUS))
     self._obj = line
Esempio n. 4
0
 def __init__(self, start, end, layer='F.SilkS', width=0.15, board=None):
     line = pcbnew.DRAWSEGMENT(board and board.native_obj)
     line.SetShape(pcbnew.S_SEGMENT)
     line.SetStart(Point.native_from(start))
     line.SetEnd(Point.native_from(end))
     line.SetLayer(pcbnew_layer.get_board_layer(board, layer))
     line.SetWidth(int(width * units.DEFAULT_UNIT_IUS))
     self._obj = line
Esempio n. 5
0
 def __init__(self, width, start, end, layer="F.Cu", board=None):
     self._track = pcbnew.TRACK(board and board.native_obj)
     self._track.SetWidth(int(width * units.DEFAULT_UNIT_IUS))
     if board:
         self._track.SetLayer(board.get_layer(layer))
     else:
         self._track.SetLayer(pcbnew_layer.get_std_layer(layer))
     self._track.SetStart(Point.native_from(start))
     self._track.SetEnd(Point.native_from(end))
Esempio n. 6
0
 def __init__(self, width, start, end, layer='F.Cu', board=None):
     self._track = pcbnew.TRACK(board and board.native_obj)
     self._track.SetWidth(int(width * units.DEFAULT_UNIT_IUS))
     if board:
         self._track.SetLayer(board.get_layer(layer))
     else:
         self._track.SetLayer(pcbnew_layer.get_std_layer(layer))
     self._track.SetStart(Point.native_from(start))
     self._track.SetEnd(Point.native_from(end))
Esempio n. 7
0
 def __init__(self, center, radius, layer='F.SilkS', width=0.15,
              board=None):
     circle = pcbnew.DRAWSEGMENT(board and board.native_obj)
     circle.SetShape(pcbnew.S_CIRCLE)
     circle.SetCenter(Point.native_from(center))
     start_coord = Point.native_from(
         (center[0], center[1] + radius))
     circle.SetArcStart(start_coord)
     circle.SetLayer(pcbnew_layer.get_board_layer(board, layer))
     circle.SetWidth(int(width * units.DEFAULT_UNIT_IUS))
     self._obj = circle
Esempio n. 8
0
 def __init__(self, center, radius, layer='F.SilkS', width=0.15,
              board=None):
     circle = pcbnew.DRAWSEGMENT(board and board.native_obj)
     circle.SetShape(pcbnew.S_CIRCLE)
     circle.SetCenter(Point.native_from(center))
     start_coord = Point.native_from(
         (center[0], center[1] + radius))
     circle.SetArcStart(start_coord)
     circle.SetLayer(pcbnew_layer.get_board_layer(board, layer))
     circle.SetWidth(int(width * units.DEFAULT_UNIT_IUS))
     self._obj = circle
Esempio n. 9
0
    def get_fixed_pos(self):
        if self.mode.lower() == 'ul':
            ul_relative = Point(0, 0)
        elif self.mode.lower() == 'pin1':
            ul_relative = self.boundingBox.ul - self['1'].pad.center
        elif self.mode.lower() == 'center':
            comp_center = Point.wrap(self.module._obj.GetCenter())
            ul_relative = self.boundingBox.ul - comp_center
        else:
            raise Exception('Unimplemented positioning mode.')

        return self.position + ul_relative
Esempio n. 10
0
    def __init__(self, center, radius, start_angle, stop_angle,
                 layer='F.SilkS', width=0.15, board=None):
        start_coord = radius * cmath.exp(math.radians(start_angle - 90) * 1j)
        start_coord = Point.native_from((start_coord.real, start_coord.imag))

        angle = stop_angle - start_angle
        arc = pcbnew.DRAWSEGMENT(board and board.native_obj)
        arc.SetShape(pcbnew.S_ARC)
        arc.SetCenter(Point.native_from(center))
        arc.SetArcStart(start_coord)
        arc.SetAngle(angle * 10)
        arc.SetLayer(pcbnew_layer.get_board_layer(board, layer))
        arc.SetWidth(int(width * units.DEFAULT_UNIT_IUS))
        self._obj = arc
Esempio n. 11
0
    def add_keepouts(self, min_kw=1e-3, min_kh=1e-3):
        # TODO: handle more general cases

        # determine the board height from the edge
        ylist = [p.y for p in self.edge]
        height = max(ylist) - min(ylist)

        for p0, p1 in zip(self.edge[:-1], self.edge[1:]):
            x0, y0 = p0
            x1, y1 = p1

            if x1 > x0:
                # quadrants I and IV
                kw = x1 - x0
                kh = max(y0, y1)
                kx = x0
                ky = 0
            elif x0 > x1:
                # quadrants II and III
                kw = x0 - x1
                kh = height - min(y0, y1)
                kx = x1
                ky = min(y0, y1)
            else:
                continue

            if kw > min_kw and kh > min_kw:
                kpos = Point(kx, ky)
                self.add(PcbKeepout(width=kw, height=kh, position=kpos))
Esempio n. 12
0
def boundary(edge):
    ul = Point(*BoardTools.get_board_ul(edge))
    edge = [ul + Point(x, y) for x, y in edge]
    # repeat the last point
    edge = edge + [edge[-1]]

    # add points to the edge
    path = ['path', 'pcb', '0']
    for point in edge:
        # convert points from mm to um
        # and negate y coordinate
        x = '%d' % dsnx(point.x)
        y = '%d' % dsny(point.y)
        path = path[:] + [x, y]

    return ['boundary', path]
Esempio n. 13
0
    def inst_atmega328p(self):
        # Main microcontroller
        atmega328 = ATMEGA328P()
        self.pcb.add(atmega328)

        # Power connections
        atmega328.wire_power(vdd='+5V', gnd='GND')
        self.add_dcap(atmega328.get_pin('VCC'))
        self.add_dcap(atmega328.get_pin('AVCC'))

        # Analog reference
        atmega328.get_pin('AREF').wire('AREF')
        self.add_dcap(atmega328.get_pin('AREF'))

        # Crystal circuit
        atmega328.wire_xtal('XTAL1', 'XTAL2')
        self.pcb.add(Crystal('XTAL1', 'XTAL2'))
        self.pcb.add(Capacitor('XTAL1', 'GND', value=22e-12))
        self.pcb.add(Capacitor('XTAL2', 'GND', value=22e-12))

        # Crystal routing constraints
        self.pcb.add_net_constr('XTAL1', length=4)
        self.pcb.add_net_constr('XTAL2', length=4)

        # Reset circuit
        atmega328.get_pin('~RESET~').wire('RESET')
        self.pcb.add(Resistor('RESET', '+5V', value=10e3))

        # Reset button
        self.pcb.add(SPST('RESET', 'GND'))

        # ICSP connector
        icsp_pos = Point(2505.512, self.top - 1198.031, 'mils')
        self.pcb.add(
            ICSP(
                sck='IO13',
                miso='IO12',
                mosi='IO11',
                reset='RESET',
                vdd='+5V',
                gnd='GND',
                position=icsp_pos,
                mode='PIN1'))

        # Wire Port B
        pb = atmega328.PB
        for idx in range(6):
            pb[idx].wire('IO' + str(idx + 8))

        # Wire Port C
        pc = atmega328.PC
        for idx in range(6):
            pc[idx].wire('AD' + str(idx))

        # Wire Port D
        pd = atmega328.PD
        for idx in range(8):
            pd[idx].wire('IO' + str(idx))
Esempio n. 14
0
def make_nets(pcb, out):
    out = [x for x in out[1:] if x[0] == 'net']
    for entry in out:
        net = entry[1].replace('"', '')
        for routing in entry[2:]:
            if routing[0] == 'wire':
                paths = [x for x in routing[1:] if x[0] == 'path']
                for path in paths:
                    layer = path[1]
                    width = float(path[2]) / 1e4
                    coords = [
                        Point(sesx(x), sesy(y))
                        for x, y in chunks(path[3:], 2)
                    ]
                    pcb.add_track(coords, layer, width, net)
            elif routing[0] == 'via':
                via_name = routing[1]
                size, drill = get_via_params(via_name)
                coord = Point(sesx(routing[2]), sesy(routing[3]))
                pcb.add_via(coord=coord, size=size, drill=drill, net=net)
Esempio n. 15
0
    def __init__(self, coord, layer_pair, size, drill, board=None):
        self._via = pcbnew.VIA(board and board.native_obj)
        self._via.SetViaType(via_type)
        self._via.SetWidth(int(size * units.DEFAULT_UNIT_IUS))
        coord_point = Point.build_from(coord)
        self._via.SetEnd(coord_point.native_obj)
        self._via.SetStart(coord_point.native_obj)
        if board:
            self._via.SetLayerPair(board.get_layer(layer_pair[0]), board.get_layer(layer_pair[1]))
        else:
            self._via.SetLayerPair(layer.get_std_layer(layer_pair[0]), layer.get_std_layer(layer_pair[1]))

        self._via.SetDrill(int(drill * units.DEFAULT_UNIT_IUS))
Esempio n. 16
0
    def compile(self):

        print 'Adding components'
        r1 = Resistor('VDD', 'V1')
        r2 = Resistor('V1', 'V2')
        r3 = Resistor('V2', 'V3')
        r4 = Resistor('V3', 'GND')
        self.pcb.add(r1, r2, r3, r4)

        width = 20.0
        height = 20.0
        print 'Defining the board edge'
        self.pcb.edge = [
            Point(0, 0),
            Point(width, 0),
            Point(width, height),
            Point(0, height),
            Point(0, 0)
        ]

        print 'Compiling PCB'
        self.pcb.compile(json_file=self.json_fname)
Esempio n. 17
0
    def inst_ldo(self):
        # Barrel jack for 7-12V supply
        jack_pos = Point(-75, self.top - 475, 'mils')
        jack = BarrelJack('PWRIN', 'GND', position=jack_pos, mode='UL')
        diode = Diode('PWRIN', 'VIN')
        self.pcb.add(jack, diode)

        # 5.0V LDO
        ldo_5v0 = LDO_5v0(vin='VIN', gnd='GND', vout='VCC')
        self.pcb.add(ldo_5v0)
        self.add_dcap(ldo_5v0.get_pin('IN'))
        self.add_dcap(ldo_5v0.get_pin('IN'), value=47e-6)
        self.add_dcap(ldo_5v0.get_pin('OUT'))
        self.add_dcap(ldo_5v0.get_pin('OUT'), value=47e-6)
Esempio n. 18
0
    def __init__(self, coord, layer_pair, diameter, drill, board=None):
        self._obj = pcbnew.VIA(board and board.native_obj)
        self.diameter = diameter
        coord_point = Point.build_from(coord)
        self._obj.SetEnd(coord_point.native_obj)
        self._obj.SetStart(coord_point.native_obj)
        if board:
            self._obj.SetLayerPair(board.get_layer(layer_pair[0]),
                                   board.get_layer(layer_pair[1]))
        else:
            self._obj.SetLayerPair(layer.get_std_layer(layer_pair[0]),
                                   layer.get_std_layer(layer_pair[1]))

        self.drill = drill
Esempio n. 19
0
    def __init__(self, coord, layer_pair, size, drill, board=None):
        self._via = pcbnew.VIA(board and board.native_obj)
        self._via.SetWidth(int(size * units.DEFAULT_UNIT_IUS))
        coord_point = Point.build_from(coord)
        self._via.SetEnd(coord_point.native_obj)
        self._via.SetStart(coord_point.native_obj)
        if board:
            self._via.SetLayerPair(board.get_layer(layer_pair[0]),
                                   board.get_layer(layer_pair[1]))
        else:
            self._via.SetLayerPair(layer.get_std_layer(layer_pair[0]),
                                   layer.get_std_layer(layer_pair[1]))

        self._via.SetDrill(int(drill * units.DEFAULT_UNIT_IUS))
Esempio n. 20
0
    def inst_usb(self):
        # USB B connector
        usb_pos = Point(-250, self.top - 1725, 'mils')
        usb = UsbConnB(vdd='XUSB',
                       dm='D-',
                       dp='D+',
                       gnd='GND',
                       shield='GND',
                       position=usb_pos,
                       rotation=pi,
                       mode='UL')
        self.pcb.add(usb)

        # Polyfuse to protect computer from shorts on the Freeduino board
        self.pcb.add(PTC('XUSB', 'USBVCC'))

        # USB bypass cap
        self.pcb.add(Capacitor('USBVCC', 'GND'))

        # Power header
        self.pcb.add(Header('USBVCC', '+5V', 'VCC', type='male'))
Esempio n. 21
0
 def center(self):
     return Point.wrap(self._obj.GetCenter())
Esempio n. 22
0
 def center(self):
     """Via center"""
     return Point.wrap(self._obj.GetCenter())
Esempio n. 23
0
def main():
    # load command-line arguments
    parser = argparse.ArgumentParser()
    parser.add_argument('--json')
    parser.add_argument('--pcb')
    parser.add_argument('--fill_top', default='GND')
    parser.add_argument('--fill_bot', default='GND')
    parser.add_argument('--bufx', type=float, default=0.5)
    parser.add_argument('--bufy', type=float, default=0.5)
    args = parser.parse_args()

    # read board placement from SMT-PCB
    with open(args.json, 'r') as f:
        json_dict = json.load(f)

    # get the board edge
    board_edge = json_dict['board_edge']
    board_ul = Point(*BoardTools.get_board_ul(board_edge))

    # compute board center
    cx, cy = BoardTools.get_board_center(board_edge)

    edge = []
    for idx, (x, y) in enumerate(board_edge):
        if x < cx:
            px = x - args.bufx
        else:
            px = x + args.bufx
        if y < cy:
            py = y - args.bufy
        else:
            py = y + args.bufy

        board_edge[idx] = (px, py)

    # write board edge back
    with open(args.json, 'w') as f:
        json.dump(json_dict, f, indent=2, sort_keys=True)

    # create the new board edge
    edge = [Point(x, y) + board_ul for x, y in board_edge]

    # create zone outline for copper pours
    minx = min([p.x for p in edge])
    maxx = max([p.x for p in edge])
    miny = min([p.y for p in edge])
    maxy = max([p.y for p in edge])
    ul = Point(minx, miny)
    ur = Point(maxx, miny)
    lr = Point(maxx, maxy)
    ll = Point(minx, maxy)
    outline = [ul, ur, lr, ll]

    # write changes to board
    pcb = Board.load(args.pcb)

    # write edge
    pcb.clearLayer('Edge.Cuts')
    pcb.add_polyline(edge, layer='Edge.Cuts')

    # write zones
    #clearance = max(args.bufx, args.bufy)
    #pcb.add_zone(outline, args.fill_top, 'F.Cu', clearance)
    #pcb.add_zone(outline, args.fill_bot, 'B.Cu', clearance)

    pcb.save()
Esempio n. 24
0
 def end(self):
     return Point.wrap(self._obj.GetEnd())
Esempio n. 25
0
 def start(self, value):
     self._obj.SetStart(Point.native_from(value))
Esempio n. 26
0
    def inst_headers(self):
        # Digital 10-pin header
        header_pos = Point(1640, self.top - 2000, 'mils')
        header_rot = 3.0 * pi / 2.0
        self.pcb.add(
            Header(
                'IO8',
                'IO9',
                'IO10',
                'IO11',
                'IO12',
                'IO13',
                'GND',
                'AREF',
                'AD4',
                'AD5',
                type='female',
                position=header_pos,
                rotation=header_rot,
                mode='PIN1'))

        # Digital 8-pin header
        header_pos = Point(2500, self.top - 2000, 'mils')
        header_rot = 3.0 * pi / 2.0
        self.pcb.add(
            Header(
                'IO0',
                'IO1',
                'IO2',
                'IO3',
                'IO4',
                'IO5',
                'IO6',
                'IO7',
                type='female',
                position=header_pos,
                rotation=header_rot,
                mode='PIN1'))

        # Analog 6-pin header
        header_pos = Point(2000, self.top - 100, 'mils')
        header_rot = pi / 2.0
        self.pcb.add(
            Header(
                'AD0',
                'AD1',
                'AD2',
                'AD3',
                'AD4',
                'AD5',
                type='female',
                position=header_pos,
                rotation=header_rot,
                mode='PIN1'))

        # Power header
        header_pos = Point(1100, self.top - 100, 'mils')
        header_rot = pi / 2.0
        self.pcb.add(
            Header(
                None,
                '+5V',
                'RESET',
                '+3V3',
                '+5V',
                'GND',
                'GND',
                'VIN',
                type='female',
                position=header_pos,
                rotation=header_rot,
                mode='PIN1'))
Esempio n. 27
0
 def position(self):
     return Point.wrap(self._obj.GetPosition())
Esempio n. 28
0
 def end(self, value):
     self._obj.SetArcEnd(Point.native_from(value))
Esempio n. 29
0
 def center(self, value):
     self._obj.SetCenter(Point.native_from(value))
Esempio n. 30
0
 def position(self, value):
     self._obj.SetPosition(Point.native_from(value))
Esempio n. 31
0
 def position(self, value):
     self._obj.SetPosition(Point.native_from(value))
Esempio n. 32
0
 def position(self):
     return Point.wrap(self._obj.GetPosition())
Esempio n. 33
0
 def __init__(self, width, start, end, layer='F.Cu', board=None):
     self._obj = pcbnew.TRACK(board and board.native_obj)
     self._obj.SetWidth(int(width * units.DEFAULT_UNIT_IUS))
     self.layer = layer
     self._obj.SetStart(Point.native_from(start))
     self._obj.SetEnd(Point.native_from(end))
Esempio n. 34
0
 def start(self):
     return Point.wrap(self._obj.GetStart())
Esempio n. 35
0
 def define_edge(self):
     # create list of points representing the board edge
     points = [(0, 0), (0, 2100), (2540, 2100), (2600, 2040), (2600, 1590),
               (2700, 1490), (2700, 200), (2600, 100), (2600, 0), (0, 0)]
     points = [Point(x, self.top - y, 'mils') for x, y in points]
     self.pcb.edge = points
Esempio n. 36
0
 def inst_mounting_holes(self):
     coords = [(600, 2000), (550, 100), (2600, 1400), (2600, 300)]
     for coord in coords:
         hole_pos = Point(coord[0], self.top - coord[1], 'mils')
         hole = MountingHole(position=hole_pos, mode='CENTER')
         self.pcb.add(hole)