Footprint generator with @pointhi module

hello,

I am new to kicad (2 days) I loved the online symbol generator but the online footprint generator use a old file format so I have been looking for other possibilities. I found the good work of @pointhi (here) which i understood to be a known member of the forum and using one of his examples I make an almost dumb-proof example which i hope would be easy to use for everyone

With it i generated this

changing just a few lines of code in SETUP you can generate any kind of dip, smd board with two lines of pins

"""
Prerequisites:
git
setuptools

Installation:
git clone https://github.com/pointhi/kicad-footprint-generator
cd kicad-footprint-generator
sudo python setup.py install
"""

from KicadModTree import Footprint, Text, RectLine, Pad, Model, KicadFileHandler
import os

############################# SETUP #############################

folder = 'Custom' # no need to add .pretty
name = 'lolin32_lite' # no need to add .kicad_mod
description = 'esp32 dev board'
tags = 'esp32'

auto_centering = True

reference_text = 'LOLIN32 LITE'
reference_position = [0, -1]
reference_layer = 'F.SilkS'

value_text = ''
value_position = [0, 1]
value_layer = 'F.Fab'

pads_number = 26
pads_type = Pad.TYPE_THT    # TYPE_THT - TYPE_SMT
pads_layer = Pad.LAYERS_THT # LAYERS_THT - LAYERS_SMT
pads_shape = Pad.SHAPE_CIRCLE # SHAPE_RECT - SHAPE_CIRCLE
pads_spacing = 2.54         # distance between two contiguous pins
pads_line_to_line = 23      # distance between the two rows of pins
pads_size = [2,2]
pads_drill = 1.2
pads_first_pin_rect = True  # use SHAPE_RECT for the first pin

silkscreen_use = True
silkscreen_layer = 'F.SilkS'
silkscreen_auto = True
pads_to_silkscreen = [12, 1.5]    # distance between pads and silkscreen
silkscreen_start = [-2, -2] # not needed if auto
silkscreen_end = [5, 2]     # not needed if auto

courtyard_use = True
courtyard_layer = 'F.CrtYd'
courtyard_auto = True
courtyard_to_silkscreen = [0.25, 0.25] # distance between courtyard and silkscreen
courtyard_start = [-2, -2]  # not needed if auto
courtyard_end = [5, 2]      # not needed if auto


############################# SCRIPT #############################

# make .pretty folder
if not os.path.exists(folder+'.pretty'):
    os.mkdir(folder+'.pretty')
    print('Directory "' + folder+'.pretty' +  '" created')
else:    
    print('Directory "' + folder+'.pretty' +  '" already exists')

# make packages3d folder
if not os.path.exists('packages3d'):
    os.mkdir('packages3d')

# make .3dshapes folder
if not os.path.exists('packages3d/'+folder+'.3dshapes'):
    os.mkdir('packages3d/'+folder+'.3dshapes')

# make a backup of the last generated file
if os.path.exists(folder+'.pretty/'+name+'.kicad_mod'):
    print('File "' + name+'.kicad_mod' +  '" already exists, saving a copy')
    os.rename(folder+'.pretty/'+name+'.kicad_mod', folder+'.pretty/'+name+'-old.kicad_mod')

# init kicad footprint
kicad_mod = Footprint(name)
kicad_mod.setDescription(description)
kicad_mod.setTags(tags)

# set general values
kicad_mod.append(Text(type='reference', text=reference_text, at=reference_position, layer=reference_layer))
kicad_mod.append(Text(type='value', text=value_text, at=value_position, layer=value_layer))

# centering
pad_initial = [0,0]
if auto_centering is True:
    pad_initial[0] = -round(pads_number / 4 * pads_spacing - (pads_spacing/2),2)
    pad_initial[1] = round(pads_line_to_line/2,2)
#print('Stating from: ' + str(pad_initial))

if silkscreen_use is True and silkscreen_auto is True:
    silkscreen_start = [round(pad_initial[0]-pads_to_silkscreen[0], 2), round(pad_initial[1]+pads_to_silkscreen[1], 2)]

# create pads
for pad in range(1, pads_number+1):
    #print (str(pad) + ' at ' + str(pad_initial))
    if pads_first_pin_rect is True and pad == 1:
        kicad_mod.append(Pad(number=pad, type=pads_type, shape=Pad.SHAPE_RECT, at=pad_initial, size=pads_size, drill=pads_drill, layers=pads_layer))
    else:
        kicad_mod.append(Pad(number=pad, type=pads_type, shape=pads_shape, at=pad_initial, size=pads_size, drill=pads_drill, layers=pads_layer))
    
    if pad < pads_number/2:
        pad_initial[0] = round(pad_initial[0] + pads_spacing, 2)
    elif pad == pads_number/2:
        pad_initial[1] -= pads_line_to_line
        if silkscreen_use is True and silkscreen_auto is True:
            silkscreen_end = [round(pad_initial[0]+pads_to_silkscreen[0], 2), round(pad_initial[1]-pads_to_silkscreen[1], 2)]
    elif pad > pads_number/2:
        pad_initial[0] = round(pad_initial[0] - pads_spacing, 2)

# create silkscreen
if silkscreen_use is True:
    #print ('Silkscreen: from ' + str (silkscreen_start) + ' to ' + str (silkscreen_end))
    kicad_mod.append(RectLine(start=silkscreen_start, end=silkscreen_end, layer=silkscreen_layer))

# create courtyard
if courtyard_use is True:
    if courtyard_auto is True:
        courtyard_start = [silkscreen_start[0]-courtyard_to_silkscreen[0], silkscreen_start[1]+courtyard_to_silkscreen[1]]
        courtyard_end = [silkscreen_end[0]+courtyard_to_silkscreen[0], silkscreen_end[1]-courtyard_to_silkscreen[1]]
    #print ('Courtyard: from ' + str (courtyard_start) + ' to ' + str (courtyard_end))
    kicad_mod.append(RectLine(start=courtyard_start, end=courtyard_end, layer=courtyard_layer))

# add 3D model
kicad_mod.append(Model(filename=folder+'.3dshapes/'+name+'.wrl', at=[0, 0, 0], scale=[1, 1, 1], rotate=[0, 0, 0]))

# print render tree
#print(kicad_mod.getCompleteRenderTree())

# output kicad model
file_handler = KicadFileHandler(kicad_mod)
file_handler.writeFile(folder+'.pretty/'+name+'.kicad_mod')

print('Done. Saved as ' + folder+'.pretty/'+name+'.kicad_mod')

Note that Kicad now has a built in footprint editor in Pcbnew that covers most cases:
Capture

i wasn’t aware of it! my sketch does the same of the pid so it is useless :sneezing_face:

The kicad internal footprint generators are not really of high quality. Especially the qfn generator is completely useless as it always centers the pads at the body outline. This means there is no way to define the size of the toe and heel fillets. (either one is too large or the other one is too small.)
I am also not really happy about how it creates body outlines for most other parts. But at least the pads are kind of useable for these.
We plan to port the footprint generators by @pointhi to be usable for the wizard but this will take some time.

1 Like

Well in this case you already have the DIP and SOIC part ready for the game :joy:
@Rene_Poschl if you would like you can test it, i used it today to make more than 10 footprints without any problem
If needed i would be happy to help with the other footprint generator :slight_smile:

regarding your script: you don’t need to use a for loop to get a row of pads. Use the pad array node for that. (That one already takes care of making the first pad a rectangle or if you allow it a rounded rectangle.)

And the 3d model should contain an environment variable as the start. (KISYS3DMOD or maybe better make that part configurable.)

I knew about the pad array function but i decided to take a more flexible road drawing each pad on my own
Anyway thank you for the suggestion :grin:

I have also come across this website https://elnet.ch/ where the author has written two ‘wizards’ for IPC7351 compliant footprints; [edit] one for Discrete SMD (SOT/RES/CAP/IND/DIO) and another for Leaded/Leadless ICs (downloadable here)

I did briefly try these out a while ago and there were some problems running them - I managed to get then patched up but couldn’t get in touch with the author. Since then they seem to have done some more work on them & they now seem to be working OK without any patches.

I have not tried any of these footprints in production but I have not seen any glaring errors.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.