Abstract
Fritzing (www.fritzing.org) is an open-source Electronic Design Automation (EDA) tool aimed primarily at non-engineers. The approach is GUI-based, using the metaphor of working with a breadboard and electronic parts. After designing a circuit board, the user can export to any of several graphics formats for either “do it yourself” PCB etching, or to send it to a professional PCB production facility.
Fritzing makes use of many of the features of SVG: fast rendering; scaling with no degradation; compact representation; precise real-world measurements; ease of conversion to other formats; XML manipulation for generation and modification; and familiarity to our intended user-base of artists, designers, and hobbyists.
Table of Contents
Fritzing is an Open Source project to support designers and artists in taking the step from physical prototyping to actual product. We have created the Fritzing software in the spirit of Processing[W11] and Arduino[W12], producing a tool that allows the designer / artist / researcher / hobbyist to document their microcontroller-based prototype and to create Printed Circuit Board (PCB) layouts for manufacturing. The associated Fritzing website helps users share, remix and discuss designs and experiences.
Fritzing is essentially Electronic Design Automation (EDA) software with a low barrier to entry, suited to the needs of designers and artists. It uses the metaphor of the breadboard to facilitate the transfer between hardware sketches and software representation. From there, it is possible to create a specification for turning the circuit into a PCB. The PCBs can be fabricated using do-it-yourself (DIY) etching techniques[W13], or sent out to a manufacturer for professional production. Thus, the Fritzing process enables the designer to build a robust circuit which can be used in permanent installations or small-multiple batch production runs.[W1]
Fritzing runs on Windows, Mac and Linux platforms. It is implemented in C++ using the Qt framework[W2]. One of the factors that led us to choose Qt was its support for SVG rendering. In Fritzing, we use SVGs to represent the individual electronic parts in a circuit. The user manipulates these parts on a canvas.
In an earlier version of Fritzing,[1]parts were implemented as bitmaps (even SVGs were internally rendered into bitmaps), and the resulting performance was very slow, especially when zooming. In addition, scaling bitmaps produced aliasing artifacts, and a multi-resolution bitmap scheme was written in an attempt to work around these limitations. Thus we learned the hard way that the next Fritzing platform should use "native" vector graphics for fast rendering and scaling with no degradation.
Another advantage of SVG for Fritzing is the ability to be able locate elements precisely, using measurements that translate accurately to real world units. Tolerances for printed circuit boards are quite small, and if one were to design a PCB with only approximate measurements, the circuit created could contain short circuits from unintended cross-connections, not to mention potential power and signal noise issues. Two other important factors led us to use SVG: our intended user base is familiar with SVG editing tools, and its XML-basis makes it easy to parse and generate programmatically.
In Fritzing, a document or sketch represents a circuit, which can be loosely defined as a set of parts linked by wires. A single sketch can be visualized in three different views: Breadboard, Schematic, and PCB; in each view the parts and wires are rendered differently. The breadboard view is a somewhat abstract, but still immediately recognizable model of the way many of our users work: start with a breadboard and realistic-looking parts, and wire them together in an iterative fashion. Schematic view hews fairly closely to a conventional electrical engineering schematic, and PCB view is a layered printed circuit board design model similar to that seen in CAD applications. Although a typical user might start with Breadboard view and gradually migrate to PCB view, we have found that different users have different approaches to circuit building and therefore how they use the three views. Fritzing must be flexible enough to accommodate these diverse workflows.
The part is the main user-manipulable unit in Fritzing, and it is SVG-based. In the process of creating a sketch, a user assembles multiple parts by dragging them from a parts bin, and connects them with graphical wires. Each part includes a set of connectors. Each connector has a particular location on a part, it has a gender (male or female) and other metadata, and it has a terminal point--the point at which wires (or, in the case of female connectors, other parts) may attach. The wiring can be made more readable by changing colors, using bend points or by using autorouting tools.
A single part is defined by multiple files: an XML-based metadata
file (.fzp), which refers to multiple SVG files: one for each of the
three views, plus one more for an icon. The metadata file also lists a
part's connectors, and associates each of them with an
svgId attribute. This attribute matches the id
attribute of one element in each of the SVG files. So the metadata about
each connector is found in the fzp file, but the shape and the location
of the connector on the part are found in the SVG files. Similarly, a
connector's terminal point has a terminalId attribute in
the fzp file which matches the id attribute of one element
in each of the SVG files. (Note: connectors and terminal points don't
necessarily have to appear in all views).
One advantage of this structure, in which a metadata file points to SVG files, is the possibility to reuse SVG files both within and between parts. This is especially helpful for PCB graphics (footprints) as these generally conform to specific industry standard package geometries. This means that once a standard footprint SVG is defined, it can be reused by many parts and the part author will only have to make slight changes to the images for the Breadboard and Schematic views. (Going up a level from parts to sketches, a sketch file is yet a different metadata file, which refers to the parts contained in the sketch as external files.)
Parts can also have multiple layers which are
specific to a particular view. In any given view, a user can easily
change which layers are visible. For example, in PCB view, a part might
have Copper0 and Silkscreen layers, and a user might not want to see the
Silkscreen layer when he is wrestling with the details of routing
connections on the Copper0 layer. As with the previous id-correspondence
schemes, a layer is identified in the metadata file using a
layerId attribute, which corresponds to an element
id in its associated view SVG file. One difference from the
other schemes however, is that while connectors and terminal points tend
to be fairly simple elements, layers can be quite complex hierarchies of
elements. For example, all connector elements are usually found inside a
single layer element.
A composite view of a relay showing, respectively, both Copper0 and Silkscreen layers, Copper0 only, and Silkscreen only.
Figure 2. Layers in a relay
Qt provides SVG rendering support via the QSvgRenderer class. This
class implements a superset of SVG 1.2 Tiny. However, it is not possible
to selectively hide/show individual SVG elements using Qt's
implementation. So our approach to the problem is to split a single view
SVG file into multiple SVG files, one for each layer, at the time the
part is loaded. To generate each SVG file, the header from the original
SVG file is copied, and then the element identified by the layer's
id attribute is extracted from the original file and pasted
into the new layer SVG file.
We considered having separate SVG files for each layer, but we planned for users to create their own parts using standard vector drawing tools like Inkscape[W8] and Adobe Illustrator[W9], and we concluded that large collections of files would unnecessarily complicate the process. In addition, working with a single image file for each view makes it easier to preserve the spatial correspondence between layers in that view. We also considered keeping everything, metadata and all the view SVGs, in a single SVG file, but we concluded that this would make part creation more difficult and would complicate image reuse.
While we provide a set of common and useful core parts it is quite impossible to maintain a library that could even begin to hold every part that any user could possibly want to use. Therefore, we encourage users to create their own parts and we provide a Parts Editor for that purpose. As many of our users are artists and designers, we know that they have both the capacity and motivation to create part images for the different views. Furthermore, most of them are familiar with vector graphics tools, such as Illustrator or Inkscape. The parts editor allows them to integrate these images into a part definition, define connectors for each view, and add metadata for the part and each individual connector.
In the Parts Editor, the user imports an SVG for each view, and the
software allows the user to attach connectors by representing them as
on-screen manipulable rectangles. The user can then move and resize the
connectors. The Parts Editor ensures that the correspondence between SVG
element ids and their metadata references are consistent.
Since these SVGs can come from any source, it is often convenient to
recycle images from existing similar parts. If an SVG already has
connectors defined, they are represented on-screen and if the user should
delete any of them, the connector references are removed from the SVG file
as it is saved. While maintaining this consistency has been a little
painful for the programmers, it has proved to be a popular feature with
our users.
As Fritzing is intended for "non-technical" users, one of our goals is to avoid forcing the user to hand-edit markup files. As a result, we have come to be highly dependent on Inkscape and Illustrator, and this has exposed us to a number of bugs and idiosyncrasies in their respective SVG implementations.
In general, our userbase is most familiar with Illustrator. From
our point of view, as mentioned above, its main flaw is that it converts
all units into px, but doesn't bother to convert
stroke-width values. And for those who are willing to work
with mark-up, losing their original units can be very frustrating.
Another issue with Illustrator is its treatment of transparency and
gradients, which are part of SVG 1.2 Tiny. Unfortunately, Illustrator
doesn't seem to agree. And if you don't save to 1.2 Tiny, then the
transparency is saved in rasterized form.
Our main trouble with Inkscape is that most users don't remember
to save their SVGs using the "Save As... Plain SVG" option, and aside
from the extra verbosity of the many sodipodi namespace
attributes in the "Inkscape" SVG, the mirroring of sodipodi
attributes with regular SVG attributes sometimes confuses Qt's XML
parsing (at least we think that is what is happening). For example, we
will see a circle element with both cx attributes and
sodipodi:cx attributes. Our second trouble with Inkscape is
it tends to pack many name-value pairs inside a single CSS-like
style attribute rather than saving these as individual XML
attributes, which rather defeats the point of an XML-based markup.
Third, when an element is moved inside Inkscape, rather than having its
coordinates directly updated, the item is given a transform. This and
the style idiosyncrasy makes Fritzing's SVG parsing job
just a little harder.
In general, all the tools, Illustrator, Inkscape, and Qt's SVG renderer, seem to have slightly different ideas about what an implementation of SVG 1.2 Tiny really is (for example, though gradients are in the spec, Qt's renderer rasterizes them). It would be very nice if every SVG renderer and editor would run their software against the SVG Test Suite[W6] and publish the results. And though we would like to validate the SVGs that we load, we have not found an easy way to integrate a Relax-NG validator into our codebase (and if it were integrated, and a validation fails, how exactly can we or our users fix the problem?).
These issues have led us to question our strategy of using external tools to produce SVGs for Fritzing. And in terms of how they are used for Fritzing, both Inkscape and Illustrator are more powerful than most users will ever need. So we have been fantasizing lately about offering our own simplified standards-compliant SVG editor, and giving it a very nice UI. But this is really not in the main line of Fritzing development, and so will probably remain a fantasy.
The electronics industry has produced an astounding number and variation of components. Even with Open Source crowdsourcing techniques, mirroring this diversity by hand-producing Fritzing parts is a futile task. But thanks to powerful templating tools for XML we were able to create a set of scripts that enable us to quickly generate sets of similar SVG images, such as resistors, capacitors, and ICs. Templates can be created using standard SVG tools and then modified to turn out parts with various combinations of colors, sizes, and numbers of pins.
While Fritzing itself is written in C++, our website and many of our development utilities are coded in Python. We chose to use Cheetah's powerful templating system[W5] for our parts generators as it integrates nicely with Python. A typical script will iterate over a range or set of variables and create the unique SVGs and XML metadata files for each part. This process was extremely useful in the early stages of development when the file format was frequently changing.
Finally, we have integrated these scripts into our web site so that users can simply fill out a web form to create custom parts to their specification [W10]. These parts can be modified using the Parts Editor and SVG authoring tools, just as with parts made from scratch. Our hope is that given a sufficient collection of these scripts, the majority of special parts could be generated and only the most exotic parts would need to be created by hand.
Once a user has finished creating a sketch (i.e. laying out a circuit), for purposes of production or documentation it must be converted to other formats. Fritzing provides a number of different export options, depending on the end production technology. PDF and PostScript outputs are provided by Qt, and once we figured out that Qt stores images internally at 90 dpi, we were able to ensure that parts would be printed at their true real-world sizes. PNG and JPEG outputs are also provided by Qt, so we simply had to set the right image resolution to output images at the proper size.
However, exporting to SVG proved a little more complicated. Qt does not provide a method to take a sketch composed of separately rendered parts and wires, and convert that to a single SVG file, so we had to devise our own approach:
The first step is to take all of the individual part SVGs and
normalize them. That is, we set up the target SVG
with width , height , and
viewBox attributes so that coordinates are expressed in
1000 dpi units. Then we go through each part, converting its
coordinates and other scale-relative attribute values (
radius , stroke-width , etc) to 1000 dpi
units.
During this step we also translate the part coordinates to absolute coordinates within the full sketch-- this makes subsequent parsing easier.
Depending on the purpose of the export, we may change the value
of an element's stroke and fill attributes.
For example, if you are exporting a PCB for DIY etching, which needs a
solid black image, we will set the stroke and
fill attributes to black .
Next, we convert all the wires in the sketch to
line elements.
Again, depending on the purpose of the export, only certain layers of a given part will be visible, so elements belonging to the non-visible layers are ignored.
We originally picked 1/1000 inch resolution because it is the most common standard unit in professional PCB manufacturing. However, we found that many of our users import the Fritzing-exported SVGs into Adobe Illustrator, which converts everything internally to 72 dpi. This would not be a problem if Illustrator also converted the stroke-width attribute, but Illustrator does not, so user sketches showed up in Illustrator rendered dramatically incorrect. So we now export our SVGs at 72dpi as a workaround.
While exporting a printable graphic image is very useful and effective for home or small lab production, almost all professional PCB production houses expect files in the Gerber RS-274-X format[W7]. This format, often simply called Gerber, was created in the 1970s by the Gerber Systems Corp (now owned by Mania Technologie AG) to drive photoplotting machines. The file describes the movement of a photoplotter head with a series of commands: move, light-on, light-off, aperture size change and shape change. The action of exposing a photo-sensitive film to light creates a resist which is used to define the areas of the circuit board which will be etched. While most modern photoplotters are actually raster based, the legacy standard lives on.
To export to Gerber format, we first go through the SVG export process (using 1000dpi), then walk through the SVG element tree, where there is a more-or-less one-to-one correspondence between Gerber elements and SVG elements. Gerber has some limitations, however. The only curves supported in Gerber are complete circles or circular arc segments, so currently there are no footprints in Fritzing with bezier curves. While it has not yet been implemented, we have considered several algorithms to convert SVG curves to poly-lines or arc segments. In addition there is no support in Gerber for fonts or generic text. One possible solution is to map SVG path-based font tables to straight lines and circular arc segments.
There is one further manipulation to perform when Fritzing exports for etching (or to Gerber format): when part footprints and traces are exported, it leaves large areas of the PCB unfilled, and removing all the copper from these areas is time consuming; wasteful of etchant chemicals; and depending on the production process, less environmentally sound. Furthermore, some or all of these unfilled areas can be connected to ground, which makes routing the PCB much easier. Finally, using a ground plane in printed circuits can reduce signal noise.
Our first idea for how to implement a ground plane was once again to generate a single sketch SVG but increase each element's stroke-width attribute by some percent, and then subtract this modified sketch shape from the shape of the board. However, we couldn't find an easy way to perform subtraction directly in SVG space. So our next idea was to render the fattened sketch into a bitmap, then find some way to vectorize that back into an SVG. It is unnecessary to work with such a bitmap at a high resolution: it is much more important to set the stroke-width on all parts and wires wide enough to avoid any short circuits. We looked at using Potrace[W4] for doing the vectorization, but as that seemed to be more than we needed, and as perhaps there would be some difficulty integrating it into our codebase across all three platforms (and because it was an interesting problem to work on), we developed our own solution.
The first version simply went through the bitmap line-by-line and
generated a horizontal line element for each set of
contiguous horizontal empty pixels. Our second version was a little more
clever and used the endpoints of all those horizontal empty lines to
create a set of filled polygon elements (i.e. a polygon for
each empty "island" in the bitmap). There is still room for optimization
by removing redundant endpoints in the polygons, but our ground plane
implementation is working. Similar techniques could be used to create a
more flexible solder mask layer.
A composite view of an exported sketch, shown, respectively, without ground plane and with ground plane. We allow the ground plane to intersect with ground wires.
Figure 4. Sketch exported for etching
Our original motivation for choosing vector graphics for Fritzing
arose from our experience with an earlier raster-based version. The switch
to SVG gave us much faster rendering and smooth scalingpreviously our
users had complained about the sluggishness of the program in these two
regards. But as we began to work more deeply with SVG, we were able to
take advantage of some of its other features. For example, it is very
important that the true sizes of parts and connectors are preserved
between Fritzing and various export formats (including the printed page),
and the width, height, viewBox
coordinate scheme greatly facilitates that. Furthermore, as an XML-based
standard, SVG makes it straightforward to programmatically manipulate SVG
images, and we have taken advantage of this for exporting sketches to
various formats, as well as generating and editing parts.
Due to our unique requirements, in which a single part is visualized differently between views, we decided that SVG alone wasn't sufficient to represent a part, so we adopted a multi-file format in which a metadata file points to a set of SVG files. Splitting up the files this way gave us the advantage that individual SVG files could easily be reused both within and between parts.
The one less-than-positive note we strike is one which arises from our intended workflow, in which SVGs move back and forth between Fritzing and external tools (particularly Inkscape and Illustrator). Because each of these tools, as well as the Qt renderer, take a slightly different tack with regard to SVG creation and rendering, we have found ourselves attempting to provide an extra insulating layer of code in Fritzing to smooth the transition from program to program (note: going from Inkscape to Illustrator, or vice versa, is another frustrating exercise). It would be nice if SVG editors would all seriously conform to the SVG Test Suite[W6] to help guarantee interoperability. It would also be nice to find a C++ reference library for SVG manipulation.
In the end, we can confidently assert that SVG has made our application easier to develop, and has enabled many important features in Fritzing. Despite the difficulties we have mentioned, we are able to take advantage of powerful external tools for editing and creating SVG images. Overall, SVG makes Fritzing more user-friendly, more powerful, faster and generally more pleasant to develop and use.
Thanks to Reto and André for initiating the Fritzing project; and to Dirk, Lionel, Omer, Stefan and all the others who have struggled with our ever-evolving parts creation process. We gratefully thank the Brandenburg Ministry of Science, Research, and Culture (MWFK) for funding.
[W1] Fritzing – A tool for advancing electronic prototyping for designers. In Proceedings of the 3rd International Conference on Tangible and Embedded Interaction. 2009. International Conference on Tangible and Embedded Interaction. February 16-18, 2009. Cambridge, England. .
[W2] Qt Framework. http://qt.nokia.com/.
[W3] GEF: Graphical Editing Framework. http://www.eclipse.org/gef/.
[W4] Potrace. Transforming bitmaps into vector graphics. http://potrace.sourceforge.net/.
[W5] Cheetah. The Python-powered template engine. http://www.cheetahtemplate.org/.
[W6] SVG Test Suite. http://www.w3.org/Graphics/SVG/WG/wiki/Test_Suite_Overview.
[W7] Gerber RS-274X Format. User's Guide. Copyright © 1998. http://www.artwork.com/gerber/274x/rs274xrevd_e.pdf.
[W8] Inkscape. http://www.inkscape.org.
[W9] Adobe Illustrator. http://www.adobe.com/products/illustrator/.
[W10] Part-o-matic. http://fritzing.org/parts/generator/choose/.
[W11] Processing. http://processing.org/.
[W12] Arduino. http://arduino.cc/.
[W13] DIY PCB Etching Tutorial. http://fritzing.org/learning/tutorials/pcb-production-tutorials/diy-pcb-etching/.