xGoat
More tea please.

Playing with footprints and constraints

I’ve been using gEDA for a couple of years now. It’s a great project, and I think there’s a lot of ways that it can be improved. One of the biggest annoyances for me is the process for designing PCB footprints. The generally recommended way of creating footprints is to manually edit the absolute co-ordinates of its features in a text-editor. This works, but it leaves a lot to be desired. Making a mistake in calculations at the beginning of this process can lead to having to completely redo the entire thing. I have previously spent hours on simple footprints because of this. I think there are even stronger arguments for using a different approach. Let me explain…

If you pick up a component datasheet, you’ll find that it’ll give you a diagram that looks something like this:

In the datasheet there’s also a table in which you can look up what each dimension means. For example, “E” might be 2.8mm, in which case the diagram above that tells you that there are 2.8mm between the tips of the pins. It is easy for you to understand what that means.

Now imagine that you live in another dimension. In this alternative reality, the footprint diagrams in a component’s datasheet look something like this:

The arrows indicating the relative position of one feature from another have gone. Instead, the chip manufacturers in your universe decided that it would be a good idea to tell you the absolute co-ordinates of the features of the chip with respect to some origin. I’ve omitted the numbers in the above diagram, but I’m sure you can imagine that each red point could be associated with a co-ordinate that might be written in a table or written next to each point. To understand what the distance is between the tips of the pins is, you now have to do a small sum in your head.

It’s harder to understand the size of components in this alternative reality than our own. I think datasheets specify feature sizes as they do, with arrows indicating relative distances, because it is easier for people to perceive what this means. Despite this, many PCB tools require that one positions the parts of components in an absolute fashion. If it’s gEDA PCB you’re using then you need to know the co-ordinates of each of the footprint’s features, as presented in the alternative datasheet reality. If it’s the popular closed-source EAGLE that you’re using, then you graphically position the features on a grid in an absolute fashion — still essentially requiring the non-intuitive information from our parallel universe. Creating footprints in these CAD tools requires one to perform a load of manual calculations to translate what the datasheet says in one ‘language’ into that of the CAD tool.

The Beginnings of a Solution

Armed with my frustration at hours lost to lots of manual calculations, I decided to lose a few hours trying to create something that would make designing gEDA PCB footprints considerably easier, faster, and less error-prone. This git repository contains what I came up with:

git clone https://bitbucket.org/rspanton/pcbcons.git

It’s a functional proof-of-concept. Don’t expect things like API to remain constant, and certainly don’t expect me to maintain it in any way right now! This git repository contains two python modules which one imports:

#!/usr/bin/env python
import pcons, render_pcb

In this system there are two genres of thing:

  1. Features of footprints, such as pads and holes.
  2. Constraints that define how these are positioned relative to each other

Let’s create a new design and put a pad and a hole in it: (oh, and for convenience let’s add this import too)

from decimal import Decimal as D

#Create the design
des = pcons.Design()

p = des.add_pad( size = ( D("0.5"), D("1") ),
                   name = "1" )
h = des.add_hole( D("0.6") )

Now we’ve got the pad and the hole, we need to explain the position of one with respect to the other. So, we state that the bottom-left of the pad is aligned with the centre of the hole in the x-axis, and there’s 2mm between them in the y-axis:

des.cons += [
    pcons.FixedDist( 0, p.bl.x, h.pos.x ),
    pcons.FixedDist( D(2), p.bl.y, h.pos.y )
]

Since we need to provide some translation between the relative co-ordinate space and absolute space, we then fix an arbitrary point from our design to the origin:

# Set the bottom-left of the pad to be the origin
des.set_origin( p.bl )

Now all that’s left for us to do is to tell pcbcons to resolve all the constraints its been given, and then get it to render the output into a PCB footprint for us:

des.resolve()
render_pcb.render(des.ents)

Running the resulting program gets the following output:

Element[0x00 "Thing" "" "Thing" 0 0 0 0 0 100 0x00000000]
(
	Pad[ 0.25mm -0.25mm 0.25mm -0.75mm 0.50mm 0.1mm 0.1mm "1" "1" "square"]
	Pin[0mm 2mm 0.6mm 0mm 0mm 0.6mm"" "" "hole"]
)

This is what a gEDA footprint file looks like. Let’s pipe that into a file and have a look at it in PCB:

OMG HOLY SMOKING PONIES! It did what we asked it to. The centre of that hole is 2mm below the bottom-left corner of the pad. Now it may seem like that was a lot of work for such a simple footprint. This is true. That footprint only contains a hole and a pad. When it comes to creating much more complex footprints, there are lots of constraints that one needs to specify. Furthermore, if one gets a number wrong early in the design stage, one just has to change one number rather than all of them.

So, this is essentially a quick hack at the moment. It’s got quite a few limitations. For example, pads cannot be rotated and must be aligned to the axes, silkscreen is not yet supported, nor are copper and soldermask clearances etc. I think the API could be cleaner in some ways that I don’t yet know. pcbcons already contains a helper function for creating a set of pads and the constraints needed to get them into a line. By attaching constraints to just one of the pads from that set, the whole set can be moved around easily.

My ultimate footprint design dream is for a graphical CAD tool in which one just draws the constraints onto the various footprint entities. Perhaps there is a future in creating a file-format that can spec’ the constraints between entities, then this can be either edited in a text-editor or graphically. Patches and discussion welcome.

Update 2016/03/30: Gitorious is no more, so I have moved the repository over to bitbucket, and updated the git clone URL provided above.

Posted at 3:36 am on Monday 8th August 2011
One Comment

Excellon Drill Files and pygoocanvas

Just knocked a quick script up to read in an excellon drill file and display it using pygoocanvas:

The lines show the path in the file. Tool changes aren’t yet shown.

Source coming later. After sleep.

Posted at 2:33 am on Monday 20th August 2007
3 Comments

Scraping John’s Site…

Have just spent an hour or so setting up an RSS for John’s New Zealand adventures. Should update every half an hour.

Source used to generate it available here :-)

2012-08-10 Edit: John’s site has been down for a long time now, so this is definitely not going to work any more!

Posted at 11:48 pm on Monday 6th August 2007

Python shared library configure option

Particularly uninteresting for anyone but me. I need to log this for my project, you see.

Just created a patch for optionally building the python shared library.

Posted at 4:16 pm on Monday 26th March 2007

Squishing Python

Getting python onto the gumstix requires some work. By selecting python, the file system goes from 4 Mb (4131692 bytes to be exact) to 11Mb (11495444 bytes). That’s OK for the 16Mb gumstix boxes, but seems a little wasteful. After close inspection with the help of baobab, I find that a lot of it’s taken up by the python libraries:

Disk usage with python.

(more…)

Posted at 2:32 am on Monday 26th March 2007

avahi… mmmm… yum.

Over the past few days I’ve been working on a yum plugin that will pick-up local yum repository mirrors using avahi. It wouldn’t have taken that long to sort out if I hadn’t failed to read the bit of the dbus tutorial I was reading that said I’d need “import dbus.glib” to make callbacks work.

I spent many hours trying to work out what was going on. Steve found the problem with me not importing dbus.glib. Thanks Mr Steve.

I’ve put the code up here. It’s a git repository. Grab it using:

git clone http://www.ecs.soton.ac.uk/~rds204/yum-avahi/.git

There are two python files: repos_announce.py and repos_listen.py

repos_announce.py: This is to be run on the server. It uses avahi to tell the rest of the network that a yum repository is available locally. It points to the http server that it runs which servers the “conf” file, which contains the configuration for the various yum repositories.
repos_listen.py: This is the yum plugin. Stick it in the yum plugins directory (defaults to /usr/lib/yum-plugins). The yum plugin also requires a configuration file called “repos_listen.conf” which sits in the yum plugin config directory (/etc/yum/pluginconf.d), and this needs to contain:

[main]
enabled = 1

Currently it will only attempt to grab repositories that you already have configured.
I reckon it’s a relatively safe thing to have enabled even in potentially unfriendly networks, as long as you have gpgkey checking enabled.

Comments welcome.

Posted at 2:31 pm on Thursday 2nd November 2006
2 Comments

Blog archiving

Just written a python script to keep a local backup of my blog. I need a backup because I want to post my thoughts about my third year project without the fear of something web-related going wrong and losing important things. So I used the python library from feedparser.org and I now have a script which does what I want. I’ve inserted it into cron accordingly.

Posted at 12:24 am on Tuesday 24th October 2006

Site by Robert Spanton. © 2008 - 2011