Tales from the Evil Empire

Bertrand Le Roy's blog

News


Bertrand Le Roy

BoudinFatal's Gamercard

Tales from the Evil Empire - Blogged

Blogs I read

My other stuff

Archives

August 2011 - Posts

Building a simple Fritzing component

Yak shaving for dummiesThis is me shaving a yak. Shaving the yak, if you don't know, is what you do when a seemingly simple task necessitates many recursive and unforeseen sub-tasks in order to be carried out.

The story goes like this… Let's say that I want to paint a picture, but I'm in a shack in the middle of the desert and I don't have a canvas, brushes or paint. I do have a piece of strong cloth, a few pieces of wood, and the rocks around the shack can provide some pigments that I can mix with some oil. For the nails, I can extract some from the shack's structure itself. For the brush, I'll need some quality hair. Well, long story short, before I know it, here I am, in the middle of the desert, shaving a yak.

The little buggerToday's metaphorical yak is the representation in Fritzing of a $0.95 part, a knob potentiometer. Fritzing is a wonderful Open Source tool for designing electronic circuits. Its only shortcoming is that its library of components is not yet complete enough that it can be used to design all circuits. In my case, it's lacking the SD card reader that I'm using, analog sticks and… this small $0.95 potentiometer. Well, in fact, for the potentiometer, I could have easily used one of the stock components from Fritzing that is close enough, but for my first component design, I wanted to start with a fairly simple part so I went ahead with it anyways, with the hope of having a better fit in the end.

imageFritzing viewsA Fritzing component is typically made of five XML files that can be optionally packaged together using a zip format. Four of these files are SVG: the icon, the breadboard view, the schema view and the PCB view. The fifth file is a special XML format with extension .fzp.

Each of the SVG files should be crafted with precision, following the component's datasheet, that always contains the precise dimensions of the part. I showed some of the techniques for this in my previous post. I found that manually authored SVG is a lot easier to debug for Fritzing, and debugging you will do…

The SVG elements constituting the graphical representation of the component in each of the views should be enclosed in layers (g elements) that bear a specific id. For the breadboard view, that is "breadboard", for the schema view, "schematic", and for the PCB, you need at least three layers: "silkscreen", "copper0" and "copper1". The silkscreen describes the white indications on the PCB, whereas copper0 and copper1 are the top and bottom copper layers.

In addition to the graphical representation of the component, the file must also contain objects that represent the connectors for the part. In the case of the potentiometer, there are three connectors named leg1, leg2 and wiper.

<rect id="connector0pin" x="184.5" y="440" fill="none"
width="76" height="76"/> <rect id="connector1pin" x="438.5" y="440" fill="none"
width="76" height="76"/> <rect id="connector2pin" x="692.5" y="440" fill="none"
width="76" height="76"/> <rect id="connector0terminal" x="184.5" y="440" fill="none"
width="76" height="76"/> <rect id="connector1terminal" x="438.5" y="440" fill="none"
width="76" height="76"/> <rect id="connector2terminal" x="692.5" y="440" fill="none"
width="76" height="76"/>

Breadboard viewIn the breadboard view, those connectors are each represented by a pin and a terminal (see code above). The way I understand those is that the pin is the representation of the physical pin, whereas the terminal is the part of it that plugs into the breadboard, where the actual contact is made. The terminal, therefore, has to be precisely positioned and dimensioned to align with breadboard holes. [UPDATE: Jonathan Cohen from the Fritzing team is telling me that the terminal doesn't have to be of a specific size but that the center of the element is used as the contact point. The terminal element is not even mandatory; if it's not there, the center of the pin element is used. Still, the distance between the pins/terminals needs to be precisely 0.1 inch in breadboard view (it doesn't matter in schema view, and PCB view should be precisely matching reality)] I found Fritzing to be quite touchy with this, with earlier designs I've made failing to click easily into the breadboard if at all, or partial fits of only some of the connectors. With the hand-written SVG for the potentiometer though, I found the fit to be easy and error-free. The terminals must be, in my experience, named "connectorNterminal" where N is the index of the terminal, starting at 0. The pins are named similarly "connectorNpin". Terminals should be 0.76mm squares (0.03 inch in the weird and irrational unit system some parts of the world insist on using) and 2.54mm apart (or 0.1 inch). The full set of conventions that Fritzing expects can be found here: http://fritzing.org/fritzings-graphic-standards/.

Schema viewFor the schema view, I re-used the existing potentiometer template, something that one should not shy away from. I also has similarly id'ed pins and connectors as in breadboard view:

 <rect width="1.894" x="17.797" y="1.824" height="9.783"
id="connector2pin" /> <rect width="0.867" x="18.276" y="1.14" height="0.684"
id="connector2terminal" /> <rect width="1.893" x="17.801" y="52.541" height="9.783"
id="connector0pin" /> <rect width="0.867" x="18.28" y="62.253" height="0.687"
id="connector0terminal" /> <rect width="1.894" x="29.861" y="42.203" height="9.783"
id="connector1pin" /> <rect width="0.866" x="30.409" y="51.986" height="0.684"
id="connector1terminal" />

PCB viewRemaining is the PCB view, the most important if you are doing all this with the purpose of having a real PCB printed, like I do. No mistake is allowed here, the dimensions have to come exactly right as they will have to fit with reality, in other words the actual physical component. As I described before, the PCB view has at least three layers, the silkscreen (that I like to be the outline of the component to facilitate assembly), and the two copper sides of the PCB. One difference with the other views is that connectors have to be described as patches of copper on one or both of the copper layers (usually both, unless you're doing a surface-mounted component). The two copper layers are described from the same point of view, and are not mirror images of one another, so if they are identical one can be a simple copy of the other:

<g id="copper0">
    <rect
        style="fill:none;stroke:#FFBF00;stroke-width:50.8"
        x="152.5" y="408" height="140" width="140"/>
    <circle id="connector0pin"
        style="fill:none;stroke:#FFBF00;stroke-width:50.8"
        cx="222.5" cy="478" r="69.85"/>
    <circle id="connector1pin"
        style="fill:none;stroke:#FFBF00;stroke-width:50.8"
        cx="476.5" cy="478" r="69.85"/>
    <circle id="connector2pin"
        style="fill:none;stroke:#FFBF00;stroke-width:50.8"
        cx="730.5" cy="478" r="69.85"/>
</g>
<g id="copper1">
    <rect
        style="fill:none;stroke:#FFBF00;stroke-width:50.8"
        x="152.5" y="408" height="140" width="140"/>
    <circle id="connector0pin"
        style="fill:none;stroke:#FFBF00;stroke-width:50.8"
        cx="222.5" cy="478" r="69.85"/>
    <circle id="connector1pin"
        style="fill:none;stroke:#FFBF00;stroke-width:50.8"
        cx="476.5" cy="478" r="69.85"/>
    <circle id="connector2pin"
        style="fill:none;stroke:#FFBF00;stroke-width:50.8"
        cx="730.5" cy="478" r="69.85"/>
</g>

Each pin in PCB view is usually a thick circle (with a thick square around it for pin 0), and there is no terminal in this view.

Now here's a pitfall I fell into: one might be tempted to include the connector description only once, and to surround it with nested g tags for copper0 and copper1. I had seen this in existing components and thought it was a neat way of not repeating myself. Well, I had to pay for that economy with a good hour of debugging why my component was not loading in Fritzing, giving me a cryptic "unable to create renderer for svg" message. The weird thing was that the PCB view was rendering fine in the component palette, but not on the design surface. Once I unwound the copper layers and just made them plain and boring copies of each other, the component started to work.

Once you have your four SVG files, all that remains is to build the .fzp file that will tie it all together. Fritzing contains a decent tool for this, where you pick the four files and then start identifying additional properties and connectors. I used this as a starting point and then edited the file it produced in a text editor, once again for better control.The component design tool in Fritzing

One thing you need to know when you do this is where Fritzing is putting your files. You will need to get acquainted with the \Users\YourUserName\AppData\Roaming\Fritzing\parts directory (may be hidden on your system, requiring some tweaking of your OS settings to appear). The .fzp is in the user subdirectory, and the SVG files have been copied into the respective subdirectories of svg\user. Fritzing also renames the file to include some goo for unicity. I prefer to rename those files to something entirely human-readable and then modify the corresponding references inside the .fzp file.

The .fzp has fields for author, title is the name of the part that will appear in the component palette, and label is what Fritzing will use to generate a unique name for the component instance on the design surface (R23 for example for the 23rd resistor on the surface). You can optionally include a url tag that will appear as a hyperlink above the component's description. Great to point to the datasheet or to a place where the component can be purchased.

<module fritzingVersion="0.6.2b.07.11.5217" moduleId="TSR-3386UT">
    <author>Bertrand Le Roy</author>
    <title>TSR-3386UT Square Trimming Potentiometer</title>
    <label>R</label>
    <date>2011-08-07</date>
    <url>http://www.sparkfun.com/products/9806</url>

Then we have tags, to facilitate search.

<tags>
    <tag>potentiometer</tag>
    <tag>poti</tag>
    <tag>adjustable</tag>
    <tag>resistor</tag>
    <tag>sparkfun</tag>
</tags>

The properties section should compile relevant data about the component, usually a copy of what can be found in the datasheet. Important pieces of information are the family and the Size, because that will neatly classify your component together with others of the same kind. For example, for my little knob, I can drag the stock potentiometer onto the design surface and then pick "Rotary – 9.53mm" in the size drop-down to switch from the default potentiometer to the one I designed.

<properties>
    <property name="Manufacturer">Suntan</property>
    <property name="Size">Rotary - 9.53mm</property>
    <property name="Maximum Resistance">10k&#937;</property>
    <property name="family">Potentiometer</property>
    <property name="Track">linear</property>
    <property name="Type">Rotary Shaft Potentiometer</property>
    <property name="part number">TSR-3386</property>
</properties>

The description can be simple, or quite complex, with support for encoded HTML.

<description>Trimpot 10K with Knob</description>

Then comes the meat of the file, with first pointers to the four views and declaration of the relevant layers.

<views>
    <iconView>
        <layers image="icon/TSR3386UT_icon.svg">
            <layer layerId="icon"/>
        </layers>
    </iconView>
    <breadboardView>
        <layers image="breadboard/TSR3386UT_breadboard.svg">
            <layer layerId="breadboard"/>
        </layers>
    </breadboardView>
    <schematicView>
        <layers image="schematic/TSR3386UT_schematic.svg">
            <layer layerId="schematic"/>
        </layers>
    </schematicView>
    <pcbView>
        <layers image="pcb/TSR3386UT_pcb.svg">
            <layer layerId="copper0"/>
            <layer layerId="silkscreen"/>
            <layer layerId="copper1"/>
        </layers>
    </pcbView>
</views>

Then we have the description of the connectors. Each connector is described by an id, a type (male or female), a friendly name, and a description. Under this come pointers to the elements inside each view that represent the connector. The layer attribute is what you expect, the name of the layer containing the connector (don't try to be too smart, stick to the standard names). The svgId attribute is the id of the pin object, and terminalId is the id of the terminal object. In PCB view, there is no terminal, but there is a p tag for each copper layer.

<connector id="connector0" type="male" name="Leg1">
    <description>Leg1</description>
    <views>
        <breadboardView>
            <p layer="breadboard" svgId="connector0pin"
terminalId="connector0terminal"/> </breadboardView> <schematicView> <p layer="schematic" svgId="connector0pin"
terminalId="connector0terminal"/> </schematicView> <pcbView> <p layer="copper1" svgId="connector0pin"/> <p layer="copper0" svgId="connector0pin"/> </pcbView> </views> </connector>

And… this is it, we're done. All we have to do now to share our creation is to package it (select an instance of the component on the design surface and select Part/Export in the menu) and upload it to the contribution bug: http://code.google.com/p/fritzing/issues/detail?id=875.

You'll be able to download my own potentiometer from there, or you can use this direct link.

Have fun shaving your yak, and don't hesitate to tell me in the comments what I did wrong or misunderstood. I'm a n00b.

Reference documentation on Fritzing components can be found here:
http://fritzing.org/support-us/developer/fritzing-part-format/

Authoring SVG with a text editor

A portraitSVG definitely is an increasingly interesting skill, especially as it's making its way into HTML 5 as an officially allowed grammar inside of HTML documents. Most SVG is authored through some kind of tool, and it's absolutely the way to go for artistic drawings. I used Inkscape (open source) and Expression Design in the past for that (I can't afford Illustrator), and I've been happy with the results (to your right and left).Horrible Bertrand

When you are doing this kind of artwork, the quality of the generated SVG doesn't matter much, and well, it's a good thing as what those tools spit out is rather horrendous. Think HTML from Word.

There is a category of drawing though that is better authored by hand, because it needs to be human-readable and tweakable, and because it requires a level of precision in coordinates that would be tedious to achieve in a tool. A lot of technical drawing enters this category.

One of the things I do outside of work is electronics. I use Fritzing to design printed circuit boards (PCBs), and it's an excellent open source tool, but its library of components is not as complete as what can be found in commercial offerings, so I have to author some of the components I need myself. Today I'm working on a very simple one, a potentiometer I got from Sparkfun (illustration to your right).

Fritzing has three views: breadboard, were components are drawn in a semi-realistic fashion, schema and PCB. In this post, I'm going to explain how I built the breadboard view of the potentiometer.

At the beginning of the document is some rather uninteresting doctype declaration:

<?xml version="1.0" standalone="no"?>

<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

Then we have the svg tag where, apart from some namespace declarations, the size of the document is declared:

<svg width="9.53mm"
    height="9.53mm"
    viewBox="0 0 953 953"
    id="TSR3386U-T_Breadboard"
    version="1.1"
    xmlns="http://www.w3.org/2000/svg"
    xmlns:xlink="http://www.w3.org/1999/xlink">

DatasheetWe define the size in millimeters here to make the design from the component's datasheet as easy to translate as possible. The viewport attribute is here to map a system of coordinates on these dimensions. The values we set here maps 9.53mm to 953 coordinate steps. The result of this is that a coordinate of 100 will be a millimeter from the origin (all the other coordinates in the document will be without units and will use those proportions). This also means that you can resize the whole document from this single place.

A very important construct to understand in SVG is groups, represented by <g/> tags. This allows us to make logical grouping of forms and give structure to the document. For Fritzing components, I put a group with id "breadboard" around all shapes to identify the breadboard view of the component. Inside of that group, I have subgroups for the outline of the component, and another for the shapes forming the knob.

The outline is made of a single filled path tag:

<path
   style="fill:#0000A0;stroke:none"
   d="m 0,0 l 953,0 0,953 -75,0 0,-38 -803,0 0,38 -75,0 z" />

The style is self-explanatory (and familiar if you know CSS), but the unexpressive d attribute demands more attention. It describes the path using a small DSL. Each command in the path DSL consists in a letter and a set of coordinates. The convention is that a lowercase letter is used for relative coordinates, and uppercase is for absolute coordinates. We use relative coordinates here. We start by moving (m command) the pen to the top-left corner (0,0), then we draw lines (l command) 9.53mm to the right, 9.53mm down, 0.75mm left, 0.38mm up, 8.03mm left, 0.38mm down, and 0.75mm left. Then z (like zero) closes the path.

The design of the knob needs three concentric circles, an arrow on top and small grooves around the knob. When adding the shapes for each of those elements, it's important to order them from the bottom up as SVG uses that to determine how overlaps are handled. The circles are simple shapes, described by the coordinates of the center (cx, cy) and the radius (r):

<circle
   style="fill:none;stroke:black;stroke-width:20"
   cx="476.5" cy="419" r="419" />

The grooves around the knob are more interesting. They are thin lines going from the center of the knob, all around it. We could draw each line by computing its extremities' coordinates, but that would be no fun at all. Fortunately, SVG has a special tag, <use/>, that can make clones of other elements, simple or complex, and apply geometrical transforms to them. So all we have to do is draw one line, and then we can rotate copies of it for all the others.

<line id="grooveception0"
    style="fill:none;stroke:black;stroke-width:5"
    x1="476.5" y1="419" x2="57.5" y2="419" />

Here's a use tag that takes the line above and rotates it 4 degrees around the center of the knob:

<use xlink:href="#grooveception0" transform="rotate(4, 476.5, 419)" />

The transform here is a simple rotation specifying the angle in degrees, and the x and y coordinates of the center of the rotation. Now we could make 88 more copies of this to complete the circle but that would be boring. Instead, let's divide and conquer, and make increasingly big recursive copies of the grooves.

<g id="grooveception5">
 <g id="grooveception4">
  <g id="grooveception3">
   <g id="grooveception2">
    <g id="grooveception1">
     <line id="grooveception0"
       style="fill:none;stroke:black;stroke-width:5"
       x1="476.5" y1="419" x2="57.5" y2="419" />
     <use xlink:href="#grooveception0" transform="rotate(4, 476.5, 419)" />
    </g>
    <use xlink:href="#grooveception1" transform="rotate(8, 476.5, 419)" />
   </g>
   <use xlink:href="#grooveception2" transform="rotate(16, 476.5, 419)" />
  </g>
  <use xlink:href="#grooveception3" transform="rotate(32, 476.5, 419)" />
 </g>
 <use xlink:href="#grooveception4" transform="rotate(64, 476.5, 419)" />
</g>
<use xlink:href="#grooveception5" transform="rotate(128, 476.5, 419)" />
<use xlink:href="#grooveception5" transform="rotate(256, 476.5, 419)" />

The neat thing about this method is that the number of copies necessary only grows with the logarithm of the number of grooves. In our case, we have 7 use tags instead of 89.

And this is pretty much it. I'm attaching the finished SVG file to this post so you can check it out in its entirety, and here is the result:The SVG'ed potentiometer

Download the SVG file:
http://weblogs.asp.net/blogs/bleroy/Samples/TSR3386U-T_Breadboard.zip

More Posts