element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Open Source Hardware
  • Technologies
  • More
Open Source Hardware
Blog Problem Solving with KiCad 7 and Python: Getting Data and Moving Components on Circuit Boards
  • Blog
  • Forum
  • Documents
  • Events
  • Polls
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Open Source Hardware requires membership for participation - click to join
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: shabaz
  • Date Created: 25 Jun 2023 11:37 PM Date Created
  • Views 4396 views
  • Likes 8 likes
  • Comments 1 comment
  • kicad 7
  • python
  • kicad 6
  • kicad
  • kipython
  • pcbnew
Related
Recommended

Problem Solving with KiCad 7 and Python: Getting Data and Moving Components on Circuit Boards

shabaz
shabaz
25 Jun 2023

Table of Contents

  • Introduction
  • Python Console
  • Getting Footprint Information
  • Python writing Python
  • Trying it Out
  • Holes in a Geometric Pattern
  • Summary


Introduction

One of the great advantages of KiCad is that it supports a decent language for scripts – Python!

Python can be used within the PCB editor, to extract information from or to modify the printed circuit board (PCB).

I recently (today) had a problem that needed fixing; I had a legacy PCB layout (from a different CAD package, EAGLE) that I needed to modify. The trouble was, all the footprints would move whenever I tried to import the latest schematic changes. It might be a bug, or it might be something I was doing wrong. In any case, I wanted to quickly solve this problem, without waiting for a bug report to be examined.

One solution would be to manually write down a note of the position of each component, and then after a schematic update, move the components back to where they ought to go.

However, I decided to see if KiCad’s Python capability could help me instead.

The information here may be useful if you need to retrieve data from a PCB or to modify certain attributes, such as the location of component footprints. An example of this could be if you wish to move LEDs into a special geometric arrangement programmatically, for instance.

The holes in the PCB render below could be used as speaker holes; the holes were implemented using the method described in this blog post.

image

Python Console

With the PCB file open, Tools->Scripting Console brings up the Python command prompt.

image

First off, I set up the path so that KiCad could see any code that I wrote, by typing the following:


import sys
sys.path.insert(1, "c:/development/kicad_python")

The path C:/development/kicad_python is where I intended to place my code (note: use forward-slashes!).

Next, a KiCad PCB module needs to be loaded:

import pcbnew

Now the pcbnew documentation can be used to explore!

Getting Footprint Information

Exploring the pcbnew documentation, it was possible to come up with the following code:

brd = pcbnew.GetBoard()
fp_list = brd.GetFootprints()

fp_list is simply a list of all the footprints on the board!

You can view the details of each one, by typing instructions such as:

fp_list[0].GetReference()

In my case, for the PCB in the screenshot below, the output was ‘R7’, i.e. the first item in the list was a footprint for a resistor with reference R7. In a similar vein, the coordinates and the rotational angle of any footprint can be obtained as well.

image

Now it was easy to get the footprint information for every component on the PCB:

for fp in fp_list:
    vect = fp.GetPosition()
    orient = fp.GetOrientation()
    print(fp.GetReference(), fp.GetValue(), vect.x/1e6, vect.y/1e6, orient.AsDegrees())

The output looked like this, where the third, fourth, and fifth items in each row are the X- and Y-co-ordinates (in millimeters), and the angle, respectively:

R7 10k 215.8211 119.4436 -90.0
C8 100u 135.1761 92.4561 0.0
C1 2.4p 135.1761 122.6186 90.0
C5 12u 93.9011 101.6636 90.0
D5 LED_GREEN 208.5011 146.0036 90.0
C20 10n 170.1011 119.4436 0.0
D1 LED_RED 203.5011 146.0036 90.0
R5 51R 167.8786 134.6836 180.0

Python writing Python

The information provided by the the program output so far was extremely useful. I now knew the precise locations of each component.

However, I wanted to automate the task of re-positioning every component to the same location, if the components moved. To do that, I’d need to write a Python function that could create Python code to do that for me:

The final code is shown here:

# Lists all footprint references, and the component value and co-ordinates
# if format is "python" then a Python script is generated to move footprints to the current co-ordinates
def list_coords(format = ""):
    brd = pcbnew.GetBoard()
    fp_list = brd.GetFootprints()
    if format == "python":
        print("import pcbnew")
        print("brd = pcbnew.GetBoard()")
        print("def move_items():")
    for fp in fp_list:
        vect = fp.GetPosition()
        orient = fp.GetOrientation()
        if format == "":
            print(fp.GetReference(), fp.GetValue(), vect.x/1e6, vect.y/1e6, orient.AsDegrees())
        elif format == "python":
            print(f'    fx = brd.FindFootprintByReference("{fp.GetReference()}")')
            print("    if fx is not None:")
            print(f'        fx.SetPosition(pcbnew.VECTOR2I(pcbnew.wxPoint({vect.x}, {vect.y})))')
            print(f'        fx.SetOrientation(pcbnew.EDA_ANGLE({orient.AsDegrees()}, pcbnew.DEGREES_T))')
    if format == "python":
        print('    pcbnew.Refresh()')


I saved everything to a file called ktools.py (attached) and placed it in the C:/development/kicad_python folder.

To run it, I typed:

import ktools as k
k.list_coords(format='python')

The output was a complete Python program:

image

I saved that off to another file (called myfix.py). Now, whenever I want the components to be reset to the positions that they were at, I can run the myfix code!

Trying it Out

I updated the PCB from the schematic, and saw that all the components had moved:

image

No problem; I can now solve it using the myfix.py file!

I typed the following in the Python console:

import myfix
myfix.move_items()

And voila, problem solved!

image

After running the Design Rule Check (DRC), I have a few minor issues to fix, but all-in-all, the EAGLE import went well, and I was able to solve my footprint-moving problem after the PCB was updated with schematic changes.

Holes in a Geometric Pattern

Just for fun, I put 36 holes in a schematic (obviously, using copy-paste to speed things up!):

image

Next, I opened up the PCB view, updated the PCB (based on that schematic), and then opened up the Python console as before.

I wrote up the following code (I took the PointsInCircum function from the Internet just to save a little time), and saved it to a file called pattern.py (the file is attached to the blog post):

image

Next, I typed the following in the Python console:

import pattern

pattern.move_all()

This was the result:

image

This is, of course, a trivial example, but you could (for instance) retrieve points from a list containing a more complex pattern.

Summary

Things might not always go to plan when trying unusual things, and it’s good to know that Python is available for accessing the PCB data and performing modifications if desired.

It is fairly straightforward to invoke a Python console, and then retrieve footprint positions, component references, and their orientation, and make modifications to it.

With the techniques discussed, another example use-case could be to (say) programmatically place components in a geometric layout, for instance, LEDs in a spiral, and so on. Alternatively, button and connector and LED component coordinates could be retrieved in order for enclosure hole-drilling operations to be spot-on.

Thanks for reading!

Zip file containing the Python code:

kicad_python_example_files.zip

  • Sign in to reply
Parents
  • genebren
    genebren over 1 year ago

    Very cool and very powerful.  It sure beats calculating each position and then placing each hole at the computed position.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
Comment
  • genebren
    genebren over 1 year ago

    Very cool and very powerful.  It sure beats calculating each position and then placing each hole at the computed position.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
Children
No Data
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube