edge_wizard.py
edge_wizard.py (6998 bytes)
# Copy to ~/.local/share/kicad/9.0/scripting/plugins
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
#
from __future__ import division
import pcbnew
import FootprintWizardBase
import PadArray as PA
class EdgeGridArray(PA.PadGridArray):
def __init__(self, *args, **kwargs):
super(EdgeGridArray, self).__init__(*args, **kwargs)
def NamingFunction(self, x, y):
return 1 + x * self.ny + y
def AddPadsToModule(self, dc):
"""!
Create the pads and add them to the module in the correct positions
@param dc: the drawing context
"""
pin1posX = self.centre.x - self.px * (self.nx - 1) / 2
pin1posY = self.centre.y - self.py * (self.ny - 1) / 2
for x in range(0, self.nx):
posX = pin1posX + (x * self.px)
for y in range(self.ny):
posY = pin1posY + (self.py * y)
pos = dc.TransformPoint(posX, posY)
pad = self.GetPad(x == 0 and y == 0, pos)
print(x, y)
if y % 2:
print("flip")
l = pad.SMDMask()
print(l)
m = l.FlipStandardLayers()
print(m)
pad.SetLayerSet(m)
print(" flipped")
pad.SetName(self.GetName(x,y))
self.AddPad(pad)
class EdgeFootprint(FootprintWizardBase.FootprintWizard):
pad_count_key = 'pad count'
row_count_key = 'row count'
row_spacing_key = 'row spacing'
pad_length_key = 'pad length'
pad_width_key = 'pad width'
pad_pitch_key = 'pad pitch'
silkscreen_inside_key = 'silk screen inside'
outline_x_margin_key = 'outline x margin'
outline_y_margin_key = 'outline y margin'
def GenerateParameterList(self):
# defaults for a DIP package
self.AddParam("Pads", self.pad_count_key, self.uInteger, 24)
self.AddParam("Pads", self.row_count_key, self.uInteger, 2, min_value=1, max_value=2)
self.AddParam("Body", self.silkscreen_inside_key, self.uBool, False)
self.AddParam("Body", self.outline_x_margin_key, self.uMM, 0.5)
self.AddParam("Body", self.outline_y_margin_key, self.uMM, 0.5)
def CheckParameters(self):
self.CheckParam("Pads", self.pad_count_key, multiple=self.parameters['Pads'][self.row_count_key], info='Pads must be multiple of row count')
def BuildThisFootprint(self):
pads = self.parameters["Pads"]
body = self.parameters["Body"]
num_pads = pads[self.pad_count_key]
pad_length = pads[self.pad_length_key]
pad_width = pads[self.pad_width_key]
row_pitch = pads[self.row_spacing_key]
pad_pitch = pads[self.pad_pitch_key]
num_rows = pads[self.row_count_key]
pads_per_row = num_pads // num_rows
# add in the pads
pad = self.GetPad()
array = EdgeGridArray(pad, pads_per_row, num_rows, pad_pitch, row_pitch)
array.AddPadsToModule(self.draw)
# draw the Silk Screen
Hsize = pad_pitch * (num_pads / num_rows - 1)
Vsize = row_pitch * (num_rows - 1)
pin1_posY = -Vsize / 2
pin1_posX = -Hsize / 2
pad_length = pads[self.pad_length_key]
pad_width = pads[self.pad_width_key]
ssx_offset = -pad_width / 2 - body[self.outline_x_margin_key]
ssy_offset = -pad_length / 2 - body[self.outline_y_margin_key]
if body[self.silkscreen_inside_key]:
ssy_offset *= -1
ssx = -pin1_posX - ssx_offset
ssy = -pin1_posY - ssy_offset
cmargin = self.draw.GetLineThickness()
self.draw.SetLineThickness( pcbnew.FromMM( 0.12 ) ) #Default per KLC F5.1 as of 12/2018
self.DrawBox(ssx, ssy)
# Courtyard
self.draw.SetLayer(pcbnew.F_CrtYd)
cclearance = pcbnew.FromMM(0.25)
sizex = (-pin1_posX + cclearance) * 2 + pad_width
sizey = (-pin1_posY + cclearance) * 2 + pad_length
# round size to nearest 0.02mm, rectangle will thus land on a 0.01mm grid
sizex = pcbnew.PutOnGridMM(sizex, 0.02)
sizey = pcbnew.PutOnGridMM(sizey, 0.02)
# set courtyard line thickness to the one defined in KLC
self.draw.SetLineThickness(pcbnew.FromMM(0.05))
self.draw.Box(0, 0, sizex, sizey)
# restore line thickness to previous value
self.draw.SetLineThickness(pcbnew.FromMM(cmargin))
#reference and value
text_size = self.GetTextSize() # IPC nominal
if num_rows == 1:
text_py = ssy + text_size
self.draw.Value(0, -text_py, text_size)
self.draw.Reference(0, text_py, text_size)
else:
text_px = ssx + text_size
# self.draw.Value(text_px, 0, text_size, orientation_degree=90)
self.draw.Value(0, 0, text_size)
self.draw.Reference(-text_px, 0, text_size, orientation_degree=90)
# set the attribute
self.module.SetAttributes(pcbnew.FP_SMD)
class EDGEWizard(EdgeFootprint):
def GetName(self):
return "EDGE"
def GetDescription(self):
return "Edge connector footprint wizard"
def GetValue(self):
pad_count = self.parameters["Pads"][self.pad_count_key]
return "%s-%d" % ("EDGE", pad_count)
def GenerateParameterList(self):
EdgeFootprint.GenerateParameterList(self)
#and override some of them
self.AddParam("Pads", self.pad_pitch_key, self.uMM, 3.18)
self.AddParam("Pads", self.pad_width_key, self.uMM, 2.0)
self.AddParam("Pads", self.pad_length_key, self.uMM, 5.2)
self.AddParam("Pads", self.row_spacing_key, self.uMM, 0)
def GetPad(self):
pad_length = self.parameters["Pads"][self.pad_length_key]
pad_width = self.parameters["Pads"][self.pad_width_key]
return PA.PadMaker(self.module).SMDPad(
pad_length, pad_width, shape=pcbnew.PAD_SHAPE_RECT)
def DrawBox(self, ssx, ssy):
# ----------
# |8 7 6 5 |
# |1 2 3 4 |
# \---------
setback = pcbnew.FromMM(0.8)
if setback > ssy:
setback = ssy
self.draw.BoxWithDiagonalAtCorner(0, 0, ssx*2, ssy*2, setback, self.draw.flipY)
EDGEWizard().register()