Created
July 28, 2016 00:13
-
-
Save hyOzd/0188f509b70cad031beafefd2700a3fc to your computer and use it in GitHub Desktop.
a version of my pcbannotate.py script that uses native api of kicad
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
# | |
# This script will re-annotate board companents according to their x,y | |
# positions and back-annotate those changes to schematic files. | |
# | |
# Make sure you have backups of all your files! | |
# | |
# Forked from https://github.com/cculpepper/kicad-python/blob/master/examples/pcbannotate.py | |
# | |
# You should run the script from inside pcbnew script console. After | |
# running script, re-open your schematic files, update the netlist | |
# file and import net list changes to pcbnew. This should update some | |
# net names, but shouldn't change any component footprints. | |
# | |
# Copyright © 2015 Hasan Yavuz Özderya | |
# | |
# 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. | |
# | |
import pcbnew | |
import re | |
import glob | |
import os | |
import codecs | |
import sys | |
try: | |
if len(sys.argv) != 2: | |
print("Usage ", __file__, "<board.pcbnew") | |
sys.exit(1) | |
input_path = sys.argv[1] | |
b = pcbnew.LoadBoard(input_path) | |
except AttributeError: | |
b = pcbnew.GetBoard() | |
input_path = b.GetFileName() | |
mods = list(b.GetModules()) | |
def sortkeys(mod): | |
return (mod.GetLayer(), mod.GetPosition()[0], mod.GetPosition()[1]) | |
return (mod.layer, mod.y, mod.x) | |
#if mod.layer == Layer.Front: | |
#return (mod.layer, mod.y, mod.x) | |
#else: # Layer.Back | |
## Components in the back are sorted from right to | |
## left according to their canvas position. When you flip the | |
## board at your hand, they will be sorted 'left to right'. | |
#return (mod.layer, mod.y, -mod.x) | |
mods = sorted(mods, key=sortkeys) | |
ref_counter = {} # dictionary of reference names | |
changes = [] # a list of tuples | |
for mod in mods: | |
prev_ref = mod.GetReference() | |
m = re.match('^((?:[a-zA-Z_\d]+[a-zA-Z_])|(?:[a-zA-Z_]+))(\d+)$', prev_ref) | |
if m: | |
name, number = m.groups() # for ex: R16 -> name:'R' , number: '16' | |
else: | |
print("Skipping: %s." % prev_ref) | |
continue | |
if name in ref_counter: | |
next_ref = name + str(ref_counter[name]+1) | |
ref_counter[name] += 1 | |
else: | |
next_ref = name + str(1) | |
ref_counter[name] = 1 | |
if next_ref == prev_ref: | |
continue | |
print('Re-naming %s -> %s' % (prev_ref, next_ref)) | |
mod.SetReference(next_ref) | |
changes.append((prev_ref, next_ref)) | |
if changes: | |
b.Save(input_path) | |
print("PCB annotated.") | |
# PCB annotation completed, now back-annotate schematics | |
# prepare replacer | |
changes = dict(changes) | |
def replacer(match): | |
return changes[match.group(0)] | |
regx = re.compile('|'.join(r'\b%s\b' % k for k in changes.keys())) | |
# get a list of schematic files by globbing | |
directory = os.path.dirname(input_path) | |
sch_files = glob.glob(directory + '/*.sch') | |
for sch_file in sch_files: | |
print("Updating %s..." % sch_file) | |
# read file | |
s = codecs.open(sch_file, mode='r+', encoding='utf-8').read() | |
# make changes | |
s = regx.sub(replacer, s) | |
# update file contents | |
codecs.open(sch_file, mode='w', encoding='utf-8').write(s) | |
else: | |
print("No changes were made! This is normal if your components were already named in correct order.") |
@nrrdzilla I'm sorry I haven't used KiCad in a while so I can't help atm. This is not a complicated script, as long as KiCad python API doesn't change you shouldn't have any problems.
I remember that there were other back annotation scripts on kicad forums. Maybe you can try those? FYI I've also heard that KiCad 6 will have builtin back annotation support.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi,
Which version of KiCAD and Python does this need? Could you please add some info on the most recent version, in each case, that this has been tested with, in the comments?
I got a bytecode file generated in pycache that indicates some error, but it's not entirely clear to me what the issue is, though I suspect it's python version. System info:
KiCAD 5.1.9
Python 3.8.5
Linux Mint 20.1 x86_64
Thanks!
M