This 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.
Today'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.
A 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"
In 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/.
For 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"
Remaining 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.
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Ω</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: