Beispiel #1
0
    def _renderBoards(self, outputDirectory):
        """
        Convert all boards to images and gerber exports. Enrich self.boards
        with paths of generated files
        """
        pcbdraw = shutil.which("pcbdraw")
        if not pcbdraw:
            raise RuntimeError("PcbDraw needs to be installed in order to render boards")

        dirPrefix = "boards"
        boardDir = os.path.join(outputDirectory, dirPrefix)
        Path(boardDir).mkdir(parents=True, exist_ok=True)
        for boardDesc in self.boards:
            boardName = os.path.basename(boardDesc["source"]).replace(".kicad_pcb", "")
            boardDesc["front"] = os.path.join(dirPrefix, boardName + "-front.png")
            boardDesc["back"] = os.path.join(dirPrefix, boardName + "-back.png")
            boardDesc["gerbers"] = os.path.join(dirPrefix, boardName + "-gerbers.zip")
            boardDesc["file"] = os.path.join(dirPrefix, boardName + ".kicad_pcb")

            subprocess.check_call([pcbdraw, "--vcuts", "--silent", boardDesc["source"],
                os.path.join(outputDirectory, boardDesc["front"])])
            subprocess.check_call([pcbdraw, "--vcuts", "--silent", "--back", boardDesc["source"],
                os.path.join(outputDirectory, boardDesc["back"])])

            tmp = tempfile.mkdtemp()
            export.gerberImpl(boardDesc["source"], tmp)
            gerbers = [os.path.join(tmp, x) for x in os.listdir(tmp)]
            subprocess.check_call(["zip", "-j",
                os.path.join(outputDirectory, boardDesc["gerbers"])] + gerbers)
            shutil.rmtree(tmp)

            shutil.copy(boardDesc["source"], os.path.join(outputDirectory, boardDesc["file"]))
Beispiel #2
0
def exportJlcpcb(board, outputdir, assembly, schematic, ignore, field,
                 corrections, correctionpatterns, missingerror, nametemplate,
                 drc):
    """
    Prepare fabrication files for JLCPCB including their assembly service
    """
    loadedBoard = pcbnew.LoadBoard(board)

    if drc:
        ensurePassingDrc(loadedBoard)

    refsToIgnore = parseReferences(ignore)
    removeComponents(loadedBoard, refsToIgnore)
    Path(outputdir).mkdir(parents=True, exist_ok=True)

    gerberdir = os.path.join(outputdir, "gerber")
    shutil.rmtree(gerberdir, ignore_errors=True)
    gerberImpl(board, gerberdir)
    archiveName = nametemplate.format("gerbers")
    shutil.make_archive(os.path.join(outputdir, archiveName), "zip", outputdir,
                        "gerber")

    if not assembly:
        return
    if schematic is None:
        raise RuntimeError(
            "When outputing assembly data, schematic is required")
    correctionFields = [x.strip() for x in corrections.split(",")]
    components = extractComponents(schematic)
    ordercodeFields = [x.strip() for x in field.split(",")]
    bom = collectBom(components, ordercodeFields, refsToIgnore)

    posData = collectPosData(loadedBoard,
                             correctionFields,
                             bom=components,
                             posFilter=noFilter,
                             correctionFile=correctionpatterns)
    boardReferences = set([x[0] for x in posData])
    bom = {
        key: [v for v in val if v in boardReferences]
        for key, val in bom.items()
    }
    bom = {key: val for key, val in bom.items() if len(val) > 0}

    missingFields = False
    for type, references in bom.items():
        _, _, lcsc = type
        if not lcsc:
            missingFields = True
            for r in references:
                print(f"WARNING: Component {r} is missing ordercode")
    if missingFields and missingerror:
        sys.exit("There are components with missing ordercode, aborting")

    posDataToFile(posData,
                  os.path.join(outputdir,
                               nametemplate.format("pos") + ".csv"))
    bomToCsv(bom, os.path.join(outputdir, nametemplate.format("bom") + ".csv"))
Beispiel #3
0
def exportPcbway(board, outputdir, assembly, schematic, ignore, manufacturer,
                 partnumber, description, notes, soldertype, footprint,
                 corrections, missingerror, nboards):
    """
    Prepare fabrication files for PCBWay including their assembly service
    """
    loadedBoard = pcbnew.LoadBoard(board)
    refsToIgnore = parseReferences(ignore)
    removeComponents(loadedBoard, refsToIgnore)
    Path(outputdir).mkdir(parents=True, exist_ok=True)

    gerberdir = os.path.join(outputdir, "gerber")
    shutil.rmtree(gerberdir, ignore_errors=True)
    gerberImpl(board, gerberdir, settings=exportSettingsPcbway)
    shutil.make_archive(os.path.join(outputdir, "gerbers"), "zip", outputdir,
                        "gerber")

    if not assembly:
        return
    if schematic is None:
        raise RuntimeError(
            "When outputing assembly data, schematic is required")
    components = extractComponents(schematic)
    correctionFields = [x.strip() for x in corrections.split(",")]
    manufacturerFields = [x.strip() for x in manufacturer.split(",")]
    partNumberFields = [x.strip() for x in partnumber.split(",")]
    descriptionFields = [x.strip() for x in description.split(",")]
    notesFields = [x.strip() for x in notes.split(",")]
    typeFields = [x.strip() for x in soldertype.split(",")]
    footprintFields = [x.strip() for x in footprint.split(",")]
    addVirtualToRefsToIgnore(refsToIgnore, loadedBoard)
    bom = collectBom(components, manufacturerFields, partNumberFields,
                     descriptionFields, notesFields, typeFields,
                     footprintFields, refsToIgnore)

    missingFields = False
    for type, references in bom.items():
        _, _, manu, partno, _, _ = type
        if not manu or not partno:
            missingFields = True
            for r in references:
                print(
                    f"WARNING: Component {r} is missing manufacturer and/or part number"
                )
    if missingFields and missingerror:
        sys.exit("There are components with missing ordercode, aborting")

    posData = collectPosData(loadedBoard, correctionFields, bom=components)
    posDataToFile(posData, os.path.join(outputdir, "pos.csv"))
    types = collectSolderTypes(loadedBoard)
    bomToCsv(bom, os.path.join(outputdir, "bom.csv"), nboards, types)
Beispiel #4
0
def create(inputboard, outputdir, jigsize, jigthickness, pcbthickness,
           registerborder, tolerance, ignore, cutout):
    board = pcbnew.LoadBoard(inputboard)
    refs = parseReferences(ignore)
    removeComponents(board, refs)

    Path(outputdir).mkdir(parents=True, exist_ok=True)

    jigsize = (fromMm(jigsize[0]), fromMm(jigsize[1]))
    addJigFrame(board, jigsize)
    cutoutComponents(board, getComponents(board, parseReferences(cutout)))

    stencilFile = os.path.join(outputdir, "stencil.kicad_pcb")
    board.Save(stencilFile)

    plotPlan = [
        # name, id, comment
        ("PasteBottom", pcbnew.B_Paste, "Paste Bottom"),
        ("PasteTop", pcbnew.F_Paste, "Paste top"),
    ]
    # get a copy of exportSettingsJlcpcb dictionary and
    # exclude the Edge.Cuts layer for creation of stencil gerber files
    exportSettings = exportSettingsJlcpcb.copy()
    exportSettings["ExcludeEdgeLayer"] = True
    gerberDir = os.path.join(outputdir, "gerber")
    gerberImpl(stencilFile, gerberDir, plotPlan, False, exportSettings)
    gerbers = [os.path.join(gerberDir, x) for x in os.listdir(gerberDir)]
    subprocess.check_call(
        ["zip", "-j", os.path.join(outputdir, "gerbers.zip")] + gerbers)

    jigthickness = fromMm(jigthickness)
    pcbthickness = fromMm(pcbthickness)
    outerBorder, innerBorder = fromMm(registerborder[0]), fromMm(
        registerborder[1])
    tolerance = fromMm(tolerance)
    topRegister = makeTopRegister(board, jigsize, jigthickness, pcbthickness,
                                  outerBorder, innerBorder, tolerance)
    bottomRegister = makeBottomRegister(board, jigsize, jigthickness,
                                        pcbthickness, outerBorder, innerBorder,
                                        tolerance)

    topRegisterFile = os.path.join(outputdir, "topRegister.scad")
    solid.scad_render_to_file(topRegister, topRegisterFile)
    renderScad(topRegisterFile, os.path.join(outputdir, "topRegister.stl"))

    bottomRegisterFile = os.path.join(outputdir, "bottomRegister.scad")
    solid.scad_render_to_file(bottomRegister, bottomRegisterFile)
    renderScad(bottomRegisterFile, os.path.join(outputdir,
                                                "bottomRegister.stl"))
Beispiel #5
0
def create(inputboard, outputdir, jigsize, jigthickness, pcbthickness,
           registerborder, tolerance, ignore, cutout):
    """
    Create stencil and register elements for manual paste dispensing jig.
    See more details at: https://github.com/yaqwsx/KiKit/blob/master/doc/stencil.md
    """
    board = pcbnew.LoadBoard(inputboard)
    refs = parseReferences(ignore)
    removeComponents(board, refs)

    Path(outputdir).mkdir(parents=True, exist_ok=True)

    jigsize = (fromMm(jigsize[0]), fromMm(jigsize[1]))
    addJigFrame(board, jigsize)
    cutoutComponents(board, getComponents(board, parseReferences(cutout)))

    stencilFile = os.path.join(outputdir, "stencil.kicad_pcb")
    board.Save(stencilFile)

    plotPlan = [
        # name, id, comment
        ("PasteBottom", pcbnew.B_Paste, "Paste Bottom"),
        ("PasteTop", pcbnew.F_Paste, "Paste top"),
    ]
    gerberDir = os.path.join(outputdir, "gerber")
    gerberImpl(stencilFile, gerberDir, plotPlan, False)
    gerbers = [os.path.join(gerberDir, x) for x in os.listdir(gerberDir)]
    subprocess.check_call(
        ["zip", "-j", os.path.join(outputdir, "gerbers.zip")] + gerbers)

    jigthickness = fromMm(jigthickness)
    pcbthickness = fromMm(pcbthickness)
    outerBorder, innerBorder = fromMm(registerborder[0]), fromMm(
        registerborder[1])
    tolerance = fromMm(tolerance)
    topRegister = makeTopRegister(board, jigsize, jigthickness, pcbthickness,
                                  outerBorder, innerBorder, tolerance)
    bottomRegister = makeBottomRegister(board, jigsize, jigthickness,
                                        pcbthickness, outerBorder, innerBorder,
                                        tolerance)

    topRegisterFile = os.path.join(outputdir, "topRegister.scad")
    solid.scad_render_to_file(topRegister, topRegisterFile)
    renderScad(topRegisterFile, os.path.join(outputdir, "topRegister.stl"))

    bottomRegisterFile = os.path.join(outputdir, "bottomRegister.scad")
    solid.scad_render_to_file(bottomRegister, bottomRegisterFile)
    renderScad(bottomRegisterFile, os.path.join(outputdir,
                                                "bottomRegister.stl"))
Beispiel #6
0
def exportOSHPark(board, outputdir, nametemplate, drc):
    """
    Prepare fabrication files for OSH Park
    """
    loadedBoard = pcbnew.LoadBoard(board)
    Path(outputdir).mkdir(parents=True, exist_ok=True)

    if drc:
        ensurePassingDrc(loadedBoard)

    gerberdir = os.path.join(outputdir, "gerber")
    shutil.rmtree(gerberdir, ignore_errors=True)
    gerberImpl(board,
               gerberdir,
               plot_plan=plotPlanNoVCuts,
               settings=exportSettingsOSHPark)
    archiveName = nametemplate.format("gerbers")
    shutil.make_archive(os.path.join(outputdir, archiveName), "zip", outputdir,
                        "gerber")
Beispiel #7
0
def exportJlcpcb(board, outputdir, assembly, schematic, forcesmd, ignore,
                 field, corrections, missingerror):
    """
    Prepare fabrication files for JLCPCB including their assembly service
    """
    loadedBoard = pcbnew.LoadBoard(board)
    refsToIgnore = parseReferences(ignore)
    removeComponents(loadedBoard, refsToIgnore)
    Path(outputdir).mkdir(parents=True, exist_ok=True)

    gerberdir = os.path.join(outputdir, "gerber")
    shutil.rmtree(gerberdir, ignore_errors=True)
    gerberImpl(board, gerberdir)
    shutil.make_archive(os.path.join(outputdir, "gerbers"), "zip", outputdir,
                        "gerber")

    if not assembly:
        return
    if schematic is None:
        raise RuntimeError(
            "When outputing assembly data, schematic is required")
    correctionFields = [x.strip() for x in corrections.split(",")]
    components = extractComponents(schematic)
    ordercodeFields = [x.strip() for x in field.split(",")]
    bom = collectBom(components, ordercodeFields, refsToIgnore)

    missingFields = False
    for type, references in bom.items():
        _, _, lcsc = type
        if not lcsc:
            missingFields = True
            for r in references:
                print(f"WARNING: Component {r} is missing ordercode")
    if missingFields and missingerror:
        sys.exit("There are components with missing ordercode, aborting")

    posData = collectPosData(loadedBoard,
                             correctionFields,
                             posFilter=genPosFilter(forcesmd),
                             bom=components)
    posDataToFile(posData, os.path.join(outputdir, "pos.csv"))
    bomToCsv(bom, os.path.join(outputdir, "bom.csv"))
Beispiel #8
0
def gerber(boardfile, outputdir):
    from kikit.export import gerberImpl
    gerberImpl(boardfile, outputdir)
Beispiel #9
0
def gerber(boardfile, outputdir):
    from kikit.export import gerberImpl
    from kikit.common import fakeKiCADGui
    app = fakeKiCADGui()

    gerberImpl(boardfile, outputdir)