Skip to content

Instantly share code, notes, and snippets.

@hyOzd
Created July 28, 2016 00:13
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hyOzd/0188f509b70cad031beafefd2700a3fc to your computer and use it in GitHub Desktop.
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
# -*- 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
Copy link

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

@hyOzd
Copy link
Author

hyOzd commented Jan 27, 2021

@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