kicad-library-utils icon indicating copy to clipboard operation
kicad-library-utils copied to clipboard

Add F5.3 (4-9) courtyard clearance check

Open aewallin opened this issue 6 years ago • 5 comments
trafficstars

The courtyard clearance tolerance seems very tight, e.g. 0.5 +/- 0.05 mm for connectors. It would be good if the utils would check (and fix?) this.

aewallin avatar Dec 05 '18 08:12 aewallin

Hey @aewallin Is this still an issue you encounter? I would like to look into it, if you still find any inconvinience with it. Maybe you can elaborate a little?

JacobEFO avatar Feb 27 '20 19:02 JacobEFO

I assume the idea is to look at the fab-lines and all the copper. Make a union of them and offset that by the clearance. Then snap it to the 0.01mm grid. That should give you the proper courtyard. The same will also be possible for non connector parts.

The problem with automatic checking is that the scripts don't know which class of device they are working with. Is it a connector, a passive or a BGA? So selecting the proper clearance is not trivial.

And then there are quite a lot of corner cases (for example RJ45_Plug_Metz_AJP92A8813). But that might not be a real issue. We rather have a few more false positives than errors that are not found at all.

cpresser avatar Feb 27 '20 23:02 cpresser

For checking KLC-compliance, at least the script could determine what the courtyard clearance is, and inform the user what category of component the courtyard is OK for. That check might not be trivial, for example if the part is a square and the courtyard is a square then the distance from the courtyard-line to the component will be sqrt(2) larger in the corners... Maybe just a minimum distance between courtyard and the part (pads+fab) is enough?

For generating the courtyard, probably it makes sense to use a library like Clipper (or similar) http://www.angusj.com/delphi/clipper.php The algorithm would first assemble the part geometry (pads+fab), and then do an offset from that to generate the courtyard.

KLC F.5.3, for reference:

1 Courtyard uses 0.05mm line width 2 All courtyard line elements are placed on a 0.01mm grid 3 If the component requires a courtyard on the back of the PCB, a corresponding courtyard must be provided on the B.CrtYd layer. 4 Where the courtyard depends on the dimensions of the physical part body, clearance is calculated from the nominal part dimensions. Courtyard clearance should adhere to the following requirements: 5 Unless otherwise specified, clearance is 0.25mm 6 Components smaller than 0603 should have a clearance of 0.15mm 7 Connectors should have a clearance of 0.5mm, in addition to the clearance required for mating of connector 8 Canned capacitors should have a clearance of 0.5mm 9 Crystals should have a clearance of 0.5mm 10 BGA devices should have a clearance of 1.0mm

aewallin avatar Feb 28 '20 15:02 aewallin

I suggest to start with robust checking, refine that as needed, and then make courtyard creation a second step. That brings some benefit more quickly and allows discussion about how to create the courtyard to continue without holding up all activity.

evanshultz avatar Feb 28 '20 17:02 evanshultz

FWIW (not much) I cobbled together something like this for an 'auto-courtyard' generator. I find it almost impossible to draw 'by-hand' a courtyard that is KLC compliant using the standard footprint editor. I think most advanced reviewers use FreeCAD which has better dimensioning and drawing tools.

the script below assumes there is no existing courtyard, reads the f.fab and pads into a bounding box, and adds a new (hopefully KLC compliant) bounding box, saves the footprint with a new name.

something like this would be cool to have as a button-press-operation (plugin?) in the footprint editor.

    mod = kicad_mod.KicadMod(fname)
    
    # BB to contain pads and F.Fab
    box_all = kicad_mod.BoundingBox()
    bb = mod.geometricBoundingBox('F.Fab')
    bp = mod.overpadsBounds() 
    box_all.addBoundingBox(bb)
    box_all.addBoundingBox(bp)
    
    print "pads X", bp.xmin, bp.xmax
    print "pads Y", bp.ymin, bp.ymax
    
    print "fab X", bb.xmin, bb.xmax
    print "fab Y", bb.ymin, bb.ymax

    print "all X", box_all.xmin, box_all.xmax
    print "all Y", box_all.ymin, box_all.ymax
    
    # BB for Courtyard
    crt = kicad_mod.BoundingBox(box_all.xmin, box_all.ymin, box_all.xmax, box_all.ymax)
    clearance = 0.25
    #clearance = 0.5 # CONNECTORS
    
    crt.expand(clearance)
    grid = rules.klc_constants.KLC_CRTYD_GRID
    # snap to grid
    gxmin, gxmax, gymin, gymax = round(crt.xmin/grid), round(crt.xmax/grid), round(crt.ymin/grid), round(crt.ymax/grid)
    # new, snapped Courtyard BB
    crt_grid = kicad_mod.BoundingBox( gxmin*grid, gymin*grid, gxmax*grid, gymax*grid )
    print "crt X", crt.xmin, crt.xmax
    print "crt Y", crt.ymin, crt.ymax
    print "gcrt X", crt_grid.xmin, crt_grid.xmax
    print "gcrt Y", crt_grid.ymin, crt_grid.ymax
    # add Rectangle to footprint
    mod.addRectangle( (crt_grid.xmin, crt_grid.ymin), (crt_grid.xmax, crt_grid.ymax), 'F.CrtYd', 0.05)
    
    # write to disk
    fname2 = fname[:-10]+"_AutoCrtYd.kicad_mod"
    #mod.save(fname2)
    mod.save()

aewallin avatar Mar 01 '20 10:03 aewallin