# Elliptical board edges in KiCAD or CircuitPro?

I am trying to use KiCAD to design a PCB which must fit into an existing case. One side of the PCB needs to be shaped as a specific elliptical arc segment. I can figure out the parameters of the desired ellipse, but I do not see how to actually draw such an Edge Cut in KiCAD.

Is this possible in KiCAD, or am I using the wrong software for this? The board will be made on LPKF ProtoMat, so I'll be using CircuitPro software to create the final instructions for the plotter (don't know how that works yet).

So my questions is whether I should be thinking about design of the board shape in KiCAD, or leave it until a later step?

Thank you.

• This is possible with KiCad and I have created such board outlines before. I am on mobile now, however I can write an answer when I am available. May 7, 2013 at 8:40
• @abdullahkahraman: I'd appreciate your insight. May 7, 2013 at 17:07

I think an example worth a million words, so I wanted to make a tutorial on this.

Here is the box I am going to create an outline for:

Here is an example PCB drawing from the datasheet of the box:

After opening up Pcbnew, select the layer for edges. In the current version of KiCad (BZR4008), it is called "Edge.Cuts". First, I am going to draw the upper and lower edges, which are 62 mm. Then the left and right edges, which are 32 mm. I am using the tool below which has a tooltip of "Add graphic line or polygon".

Now that everything is fine, I can draw the other shapes:

Here is the tool we are going to use for that:

This tool is basically a partial circle. To use it, click on the point which will be the center of your circle, then with the mouse, you will set the radius with a visual aid of the KiCad. A very helpful thing is to change the cursor so it shows full coordinates, with the button shown below:

Just for the sake of an example, let's make the edge facing outside:

You cannot make correct ellipses with this method, unfortunately. You have to use the graphic embedding, or the approximation methods for that, which were mentioned by Nick Alexeev.

KiCad's saving grace, in my opinion, is that the files it creates are human-readable and the file format is reasonably well-documented. X and Y coordinates are specified in ten-thousandths of an inch, referenced to (0,0) in the upper left. A board outline can be represented by line segments and semicircular arcs.

It is straightforward to manipulate Kicad's .brd files using your scripting language of choice (e.g. Python). If I were you, I'd probably write a script that calculates the piecewise line segments to approximate your elliptical outline and write the line segments into your .brd file.

• That is exactly what I ended up doing. Thanks Rob! I'll post a full description of the solution in a bit. May 9, 2013 at 22:17

It took me a couple of days to digest all this info, but I ended with 2 solutions to this problem. I'll describe both solutions here.

I'd like to thank Lorenzo and Rob Gilliom from the kicad-users forum, who have provided me with all of the ideas and information that I needed to put together the solutions below (http://tech.groups.yahoo.com/group/kicad-users/message/15220).

= Option 1 =

If you want to import a single elliptical segment and design the rest of the board in KiCAD, then this Ruby script is probably the easiest way to go:

#
# Generates an ellipse for Kicad. You have to copy the
# generated lines into an existing template inside a .kicad_pcb file
#

Xo = 200.0
Yo = 150.0
MAJOR = 60.0
MINOR = 40.0
N = 256 # Number of points on the ellipse

TEMPLATE = "(gr_line (start %.2f %.2f) (end %.2f %.2f) (layer Edge.Cuts) (width 0.15))\n"

step = Math::PI * 2 / N
points = Array.new

# Calculate coordinates for all N points
(0..N).each {|s|
x = Xo + MAJOR * Math::cos(step * s)
y = Yo - MINOR * Math::sin(step * s)
points << [x, y]
}

# For each pair of points, print a gr_line
points.each_cons(2) { |line|
printf(TEMPLATE, line[0][0], line[0][1], line[1][0], line[1][1])
}


In order to use this script, just save a blank .kicad_pcb file in Kicad and then insert the lines generated by this script after the last section before the closing brace.

Open the new board file in KiCAD and enjoy your ellipse interpolated by line segments :). Using 256 points makes the ellipse so smooth that you can't tell it consists of lines in KiCAD.

If you want only a portion of the ellipse (one edge of your PCB, for example), it is trivial to add a bounding box to the script above and discard all points that lie outside of the box.

= Option 2 =

Another approach would be to design your board entirely in Inkscape (or anything else that can export vector graphics), and find a way to import that into KiCAD.

Lorenzo has provided a solution that can go from Inkscape to Gerber here: http://tech.groups.yahoo.com/group/kicad-users/message/15229

I was then able to build on Lorenzo's solution to make a Ruby script that bypasses the Gerber stage and generates KiCAD board file lines directly.

The process goes like this:

1. Design your board in Inkscape
2. Export to HPGL
3. Convert HPGL to GnuPlot Ascii: hp2xx -t -m gpt file.hpgl
4. Generate board file lines: gpt2pcbnew file.hpgl.gpt

Here is the source for gpt2pcbnew script:

#
# Convert a GPT file created by hp2xx to Pcbnew gr_lines
#

# That's the line we'll write into the board file
TEMPLATE = "(gr_line (start %.5f %.5f) (end %.5f %.5f) (layer Edge.Cuts) (width 0.15))\n"

gpt_file = ARGV.shift

segments = Array.new

File.open(gpt_file, "r") do |file|
# Start a new segment
segment = Array.new

while (line = file.gets)
unless ( line.strip! =~ /^#/ ) # Skip comments
if ( line =~ /([0-9.]+) *([0-9.]+)/ )
# Found coordinates. Save this point in the current segment
#
segment << line.split
else
# No numbers on a line means that we are done drawing the segment,
# so we need to "lift up the pen" and move to the next segment
#

# Add current segment to the list of segments
segments << segment unless segment.empty?

# Start a new segment
segment = Array.new
end
end
end

segments << segment unless segment.empty?
end

# Print out gr_lines for all the segments
segments.each { |segment|
# For each pair of points print a line
segment.each_cons(2) { |line|
printf(TEMPLATE, line[0][0], "-#{line[0][1]}", line[1][0], "-#{line[1][1]}")
}
}


Just like in Option 1, the generated lines go into a blank board file saved in KiCAD.

This solution leverages the fact that HPGL format is very similar in its construction to Gerber files, in a sense that it is a series of coordinates with either "pen up" or "pen down", which corresponds to D01 and D02 codes in Gerber.

So all the hard work of converting from bezier splines to line segments is done by Inkscape in this case.

= Option 2 Limitations =

There are a couple of limitations with this approach:

1. It seems that Inkscape cannot export rectangles into HPGL. You can obviously workaround this by constructing your own rectangles.
2. I am currently not able to get the sizes of the exported objects right. The objects end up roughly twice as large in KiCAD. I'll be working on a solution to this soon.

I had a similar problem with Kicad a while back, it ever has limited support for non standard shapes or it's just not well documented. What I ended up doing was drawing my shape (non standard pad in my case) with Gimp and converting it to a module using the built in tool. I then opened up this module file and changed the layer to the copper layers. Open it back up in Kicad and you have nonstandard shapes of your choice on any layer. Not ideal but it works.

Steps:

1. Create a drawing in Gimp
2. Use bitmap2component included with Kicad to convert it to a component
3. Open the module in gedit/notepad and edit the layer information according to the following document (Section 3.4):

4.Save the changes and open the module in Pcbnew

Results (couldn't think of any other way of making a circular edge not covered by soldermask, it's actually a SMD pad with components inside it):

• Hmm - this looks like an interesting approach, but I am not sure what you mean by "opened up this module file and changed the layer to the copper layers". I thought that pads have a target layer, rather than the module itself. Could you expand a bit on how you go from a module of the desired shape to an actual drawing on the layer of your choice? Thanks! May 7, 2013 at 19:33