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

Emacs Joy

I used the following in emacs to replace a load of strings in a gschem symbol – I’d set pinseq to be 0 for all pins but needed it to be different for all pins. Each replacement was suffixed with a separate number. It was cool.

(setq rob-counter 0)

(defun ff ()
  "temp function."
  (let (matchedText newText)
    (setq matchedText
          (buffer-substring
           (match-beginning 0) (match-end 0)))
    (setq newText
          (replace-regexp-in-string "0" (number-to-string rob-counter) matchedText) )
    newText
    )
  (setq rob-counter (+ rob-counter 1))
  )
Posted at 3:01 pm on Monday 3rd September 2007

Site by Rob Gilton. © 2008 - 2019