Since the 4.0 version of KiCad, Pcbnew supports Python scripts, and it is possible to acquire information from the board, change attributes collectively, and automate work, so I created this script as well as studying Python. Did. Even if you take the parts layout into consideration when drawing the circuit diagram, it is no wonder that such information disappears when you try to import the net into the board CAD.
Some commercial CAD can reflect not only the component layout but also the wiring order and the point of one-point grounding, but it will be much easier just to reflect the approximate layout.
Script execution video (Youtube)
Tokyo Institute of Technology Robot Technology Study Group
This is a document of Eeschema file format translated by volunteers of kicad.jp before, but the structure of the schematic file is the same in 4.0.1 version as in BZR4022 version. is.
Regarding various formats of KiCad, there was a document in the installation directory in the previous version, but it is not found in v4.0 or later, and pdf is published on launchpad. http://bazaar.launchpad.net/~stambaughw/kicad/doc-read-only/download/head:/1115%4016bec504-3128-0410-b3e8-8e38c2123bca:trunk%252Fkicad-doc%252Fdoc%252Fhelp%252Ffile_formats%252Ffile_formats.pdf/file_formats.pdf
The script is as follows. The basic flow is
is.
ki_pre_place.py
# coding: utf-8
# KiCad footprint pre place tool (2016-01-30)
#
# This script places footprints based on the XY coordinate
# of Eeschema's schematic components.
# import sys
import codecs
import pcbnew
def input_num():
while True:
try:
v = float(sys.stdin.readline())
return v
except ValueError:
print 'Value Error!'
comp_flg = False # For Detect $Comp section
qty = -1 # Comp counter
zuwaku = [] # Sch sheet size
sch_comp = [] # All Comp info (expect PWR-Symbol)
sch_comp_xy = [] # Comp Location List
pcb_comp_xy = [] # pcb location
scl_size = float(0.4) # Scaling for pcb
offset_x = float(2000) # PCB Place offset X(mils)
offset_y = float(2000) # Y(mils)
pcb = pcbnew.GetBoard() # Get pcb all info
pcb_name = pcb.GetFileName() # current pcb file name
sch_name = pcb_name.replace('.kicad_pcb','.sch') # Generate Sch file name
org_aux = pcb.GetAuxOrigin() # fab. origin(gerber etc.) and conv string (non used)
org_grid = pcb.GetGridOrigin() # grid origin and conv string (non used)
#Start Sch operation
f = codecs.open(sch_name,'r','utf-8') # Sch file reading (utf-8)
sch = f.readlines()
f.close()
for line in sch: # reading each sch lines...
line = line.lstrip().rstrip() # Del \t and \n
if line.startswith('$Descr') : # Detect $Descr section...
zuwaku = line.replace('$Descr ','').split(' ')
zuwaku[1] = float(zuwaku[1]) # X size
zuwaku[2] = float(zuwaku[2]) # Y size
if line.startswith('$Comp') : # Detect $Comp section...
comp_flg = True # flg on
qty += 1 # Component count
sch_comp.append([]) # ex) sch_comp[0] = [] , sch_comp[1] = [] ....
elif line.startswith('$EndComp') : # $EndComp -> flg off
comp_flg = False
if comp_flg : # from $Comp to $EndComp
if not line.startswith('$Comp') : # except 1st line($Comp)
sch_comp[qty].append(line) # add comp all info
# ex) sch_comp[0][0] <- 'L 74AC04 U2'
# [0][1] <- 'U 1 1 512E0139'
# [0][2] <- 'P 4050 6950'
# ....
# Get Ref.No and XY
for c_line in sch_comp:
if '#' not in c_line[0] : # except PWR SYMBOL (GND,Vcc,PWR_FLG etc.)
ref = c_line[0].split(' ')
unit_num = c_line[1].split(' ')
xy = c_line[2].split(' ')
angle = c_line[-1] # orientation matrix (angle and mirror)
if unit_num[1] == '1': # detect 1st unit ( for OPAMP , logic IC etc.)
xy_raw = [ref[2],float(xy[1]),float(xy[2]),angle] # make Ref,x,y list
sch_comp_xy.append(xy_raw)
# ex) sch_comp_xy[0][0] <- R1
# [0][1] <- X(mils)
# [0][2] <- Y(mils)
# [0][3] <- orientation matrix
#
# [1][0] <- C1
# .....
# End Sch operation
# print sch_comp <- all comp list
# print sch_comp_xy <- comp xy list
# print zuwaku <- Sch paper size
# Start PCB operation
place_flg = 'n'
judge = 'n'
while place_flg == 'n' :
if judge != 'n' :
pass
else :
print 'scale = ' + str(scl_size)
print 'offset x,y(mil) = ' + '(' +str(offset_x) + ',' + str(offset_y) + ')'
for posi in sch_comp_xy:
pcb_x = int(posi[1] * scl_size) # convert xy Sch --> PCB (scaling)
pcb_y = int(posi[2] * scl_size)
module = pcb.FindModuleByReference(posi[0]) # Get Footprint info
module.SetPosition(pcbnew.wxPointMils(pcb_x , pcb_y)) # Move abs x,y(mils)
module.Move(pcbnew.wxPointMils(offset_x , offset_y)) # Move inc(offset from origin, mils)
print '''
Place Finished , Press[F3] Key(Redraw).
'''
print 'Is this floor plan all right(y/n,a:abort)?' # Layout check...
judge = sys.stdin.readline()
if judge == 'y': # Layout OK
print 'Place Completed.'
place_flg = 'y'
elif judge == 'n': # Change place scale and origin
print 'place scale = '
scl_size = input_num()
print 'offset x(mil) = '
offset_x = input_num()
print 'offset y(mil) = '
offset_y = input_num()
elif judge == 'a': # abort
print 'Aborted.'
place_flg = 'a'
else :
pass
I'm lucky if I can use the intermediate netlist that Eeschema spits out! I thought, but of course, unfortunately, there is no coordinate information of the symbol. Therefore, I create a schematic file name from the name of the board file that is currently open, read the schematic file from the beginning, and extract the necessary parts. My environment is Win7 64bit, but since the Eeschema file was UTF-8, I have specified the character code for the time being.
Part names starting with \ # are excluded because they are GND symbols and PWR_FLG. Moreover, when there are multiple units in one package such as operational amplifiers and logic ICs, only the first unit is extracted.
Although it is unused, the placement angle and mirror information of each symbol are stored in the "angle" (orientation matrix). I think that the angle is often rotated later, and since it was quite troublesome to judge the matrix, it is stored as an array. It also stores the schematic sheet size.
After extracting the reference and coordinates, use the acquired board information to rotate the for statement in the coordinate value list and place (move) it on the board in absolute coordinates. Since the actual size arrangement in A4 is too wide, the coordinate values are scaled before arrangement.
I thought about getting the board size from PCBNew and scaling it automatically, but at present it seems that the approximate board size cannot be obtained with the script, so I am using the method of inputting the scale value. Eeschema's grid is 50mil by default, so a scale value of 0.25 to 0.5 seems to be just right.
We also modify the script to extract the grid origin and mounting origin so that the placement origin can be selected. ~~ (Commented out on lines 22 and 23) ~~
Before running the script
To make it look like the figure below.
Place the script in a suitable location, from the Pcbnew menu bar, from the Python script window.
execfile ('absolute path \ ki_pre_place.py')
Execute as, enter the placement origin and scale, and redisplay with the F3 key, the placement will be as shown below.
――It may be only my environment, but ** If you skip step 4 above, it will not be placed. ** It seems that the footprint needs to be on the board before running the script. -** It will not be redisplayed after placement , so please do it manually. We are investigating whether it can be redisplayed in a script. - It does not support hierarchical files of schematics. ** ** --You can undo after execution, but if you save the file once in the state of 4 above, reopen it, and execute it immediately after execution, it seems that you cannot undo. It may be a problem on the Pcbnew side, but it is unknown. Please note that the actual harm is small. --We have confirmed the operation on Win7. --Please note that no error handling is done.
-~~ The placement origin and scale are given as initial values, but if there is a way to redisplay with a script after footprint placement, a dialogue such as changing the scale and placement origin after seeing the result and re-executing I want to change it to input. ~~
--As for the correspondence to the hierarchical file, the $ Sch section has the hierarchical file name and coordinates, so it seems quite so, but is the above realization prioritized? .. .. ――Please point out any problems.
2016-03-21 Addendum It supports scaling, origin specification, and retry, but it is still convenient.
I also tried to study Python, but I was impressed to be able to realize the functions I wanted. We would like to thank the developers and those who provided the script information.
Although it is a solid script, I would like to be able to reuse the part that extracts the circuit diagram information. Since all the information in the "$ Comp" section is stored in the list once, it may be easier to pull it out of the list than to create a Bom from the intermediate netlist. I think it's until Eeschema supports scripts. ..
As an aside, it seems that the 3D CAD "FreeCAD" of OSS also has a Python script function. It seems that it can be conveniently used for linking libraries and board outlines with each other and checking for interference.
Recommended Posts