Skip to content

Instantly share code, notes, and snippets.

@hyOzd
Created July 28, 2016 00:13
Show Gist options
  • 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.")
@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