-
Notifications
You must be signed in to change notification settings - Fork 823
2.1 Part file format
A Fritzing part is made up of a number of files: one required metadata file (file suffix is .fzp, so the metadata file is also referred to as an fzp), and up to four SVG files. We went with multiple image files because each part may appear in four different views (breadboard, schematic, pcb, and Parts Bin icon), often with a different image for each view. We decided not to merge all the SVGs and the metadata together in a single file because keeping them separate makes it easier for different parts to share the same image (for example, many parts share the same pcb footprint), and also because keeping the SVGs in separate files makes it easier to access individual images, e.g., for inspection, or to load into the Parts Editor. The metadata file lists a part's title, description, and other properties, as well as a references to the part's SVG files. It also specifies a part's connectors and internal buses. Each connector's graphic is an element found in the relevant view SVG file. Since any SVG element can have an id attribute, the metadata file refers to a connector's graphic element using that element's id. We don't have a schema yet for the FZP, so your best bet is to use an existing FZP file—one from the set of Fritzing core parts—as an example. Start with the smallest simplest ones, and work your way up. Folder structure Because of the multitude of files and links between them, the folder structure might seem complicated at first. The metadata files for all the parts that are shipped with Fritzing can be found in the pdb folder in the following subfolders:
`pdb/core` | FZPs of all parts in the core |
`pdb/contrib` | FZPs of all parts in the contrib bin |
`pdb/obsolete` | FZPs of obsolete parts, for backwards compatibility |
Within the parts/svg
folder, you will find matching core, contrib and obsolete folders.
Within one of these subfolders, the structure is:
`parts/svg/core/breadboard` | SVGs for the breadboard view of the core library parts |
`parts/svg/core/icon` | SVGs for the parts bin icon of the core library parts |
`parts/svg/core/pcb` | SVGs for the PCB view of the core library parts (aka footprints) |
`parts/svg/core/schematic` | SVGs for the schematic view of the core library parts (aka schematic symbols) |
Some parts are generated
on-the-fly rather than simply loaded, for example, rulers, resistors,
pin headers, generic DIPs. Templates for these parts are compiled in
with the program and won't be found in the /pdb
or /parts/svg
folders. You will also not find your own,
custom-created parts in the /parts
or /pdb
folders. These are stored
in your application local storage folder, so that they don’t
get lost when you install new versions of Fritzing. The location of
this folder differs depending on your operating system, and might
even be hidden by default:
Windows Vista/7 | `C:\Users\\AppData\Roaming\Fritzing` |
Windows XP | `C:\Documents and Settings\\Application Data\Fritzing` |
Mac OS X | `~/.config/Fritzing` |
Linux | `~/.config/Fritzing` |
Inside the application storage area you will find a number of subfolders:
- The fzz folder contains a folder for each fzz file that is currently open. If there are custom parts in the sketch, the svg and fzp files will be in the fzz folder.
- The partfactory folder contains files for generated parts, such as pin headers and generic DIPs.
- Custom part files can be found in the parts folder. Your custom parts are in parts/user (fzp files) and parts/svg/user; imported parts will be in parts/contrib and parts/svg/contrib
You can find the location of a specific part SVG in Fritzing by opening the part in the Parts Editor. Switch to the view you are interested in and choose Show in folder under the File menu.
Fritzing core parts are compiled into a database when Fritzing is shipped--using the data from the fzp files. This database is used for swapping parts (this is a quick mechanism for switching between related parts). The database is an Sqlite file, and the assumption is that it's quicker to load the database than to parse all the part fzp files. Once a Fritzing part is in the database, its fzp is stored in the pdb folder (this does not apply to custom parts). New part fzp files are stored in the parts folder, but you can also override the database definition of an exiting part by moving its fzp back into the parts folder. To compile the database run Fritzing from the command line: fritzing.exe -db path/to/parts/parts.db. Once this is complete, all fzps will be moved into the pdb folder.
And now to the metafile format. Let's start with a typical example of the first couple of lines:
<?xml version='1.0' encoding='UTF-8'?>
<module moduleId="1a4bfb87a0f0fd2c59be43f3497d72e6" fritzingVersion="0.3.16b.02.24.4002">
After the usual introductory XML boilerplate, the outermost element in an FZP file is always . The moduleId attribute is important—this must be unique across all parts—and Fritzing will reject a part if it has already loaded one with the same moduleId. It would be appropriate to use something like a GUID for the moduleId attribute value though better might be to use the part-type + a GUID. For the fritzingVersion attribute, your best bet is to launch Fritzing and open up the about box, from which you can copy the version string. The first half of the version string is the most important: from the example above that means just the “0.3.16b”.
Next comes:
<author>Stefan Hermann</author>
<version>2</version>
<title>Blue LED - 5mm</title>
<url></url>
<label>LED</label>
<date>2008-10-10</date>
<description>A generic blue LED (~1.8V)</description>
<tags>
<tag>LED</tag>
<tag>Blue LED</tag>
<tag>indicator</tag>
<tag>fritzing core</tag>
</tags>
Most of these seem self-explanatory:
- Obsolete parts use a
special version syntax
<version replacedby="">
The value of the replacedby attribute is the moduleId of the part which replaces the obsolete part. There are many examples of this in the pdb/obsolete folder. The replacedby attribute can also be applied to individual connectors; see the Connectors section below. - The
<label>
element is the part's default label string when it appears in a Fritzing sketch. - The
<description>
can be plain text or rich text format. Rich text is a subset of html that can be displayed in certain Qt widgets (Qt is Fritzing's underlying GUI framework). If you use rich text, it must be xml-escaped, so the FZPs xml structure doesn't get confused. - At present we're not doing much with
tags
, but in Fritzing you can do a search for parts from the Parts Bin, and the tags are included in that search. You should probably substitute “fritzing user” for “fritzing core” if you are creating a custom part.
Now for properties. Here's a sample from a potentiometer:
<properties>
<property name="family">Potentiometer</property>
<property name="type">Trimmer Potentiometer</property>
<property name="Maximum Resistance">10kΩ</property>
<property name="Track">Linear</property>
<property name="Size">Trimmer - 6mm</property>
</properties>
Properties are important—Fritzing uses them to make it easy to swap between related parts in a sketch. When the properties are loaded, they're stored in a database; searching that database gives a set of related parts. The most important property is the “family”—Fritzing only swaps between parts in the same family. The family property is required: Fritzing will reject parts that don't have a family property.
The values of the other properties are used to populate popup-menus in Fritzing's Inspector window. For example, when you select a potentiometer in a sketch, a popup menu will appear in the Inspector window labeled “type”, with the options “Trimmer Potentiometer”, “Slide Potentiometer”, and “Rotary Shaft Potentiometer”. These values come from several parts in the "potentiometer" family; each part in that family has a different value in the "type" property.
A property may have the attribute displayInLabel set to yes, which means that by default, that property should appear when the part's label is visible. For example, the resistor:
<property name="Resistance" showInLabel="yes">220</property>
Now comes the element which references the SVG files used by the part:
<views>
<iconView>
<layers image="icon/LED-blue-5mmicon.svg" >
<layer layerId="icon" />
</layers>
</iconView>
<breadboardView fliphorizontal="true" flipvertical="true" >
<layers image="breadboard/LED-5mm-blue.svg" >
<layer layerId="breadboard" />
</layers>
</breadboardView>
<schematicView>
<layers image="schematic/led.svg" >
<layer layerId="schematic" />
</layers>
</schematicView>
<pcbView>
<layers image="pcb/T1.75_LED.svg" >
<layer layerId="copper0" />
<layer layerId="copper1" />
<layer layerId="silkscreen" />
</layers>
</pcbView>
</views>
But before diving into details, some explanation is required. Remember that a part generally has a different SVG file for each view. But beyond that, each view has a number of layers. The layers have a particular z-ordering, and from the Fritzing UI a given layer can be set visible or hidden. All part images in Fritzing are assigned to particular layers. Connectors in Fritzing parts can only be assigned to certain layers. Note that in some views, most especially pcb view, a part exists on multiple layers. This doesn't mean the entire part SVG image appears on each of those layers. Rather, internally, the view SVG is split into multiple sub-SVGs, one per layer. The way a given layer is marked in the SVG file is by using the element id attribute again, usually inside a element. So, with the example above, it means that the T1.75_LED.svg file has a number of elements:
- ...
- ...
- ...
If a layer is specified in the FZP file, it is very important that an element with that id exists in the SVG file, even if it's only an empty element. At one point we considered having separate SVG files for each layer, but we felt that having more individual files per part would make it more difficult to keep part files organized, and also when creating the SVG image for a view for a given part, having a single SVG would make it much easier to keep the elements on the different layers aligned with each other.
So, back to the sample element, notice that the four views are listed: iconView, breadboardView, schematicView, and pcbView; and notice that there are three layers in PCB view. Something you might overlook the first time through are the flipVertical and flipHorizontal attributes. In Fritzing, the default is that parts in breadboard and pcb view are not flippable, since this usually doesn't correspond well with how you work with real physical parts. By contrast, in schematic view, parts are flippable by default. However, you can enable flipping in any view, and for each of the two axes individually, by setting the corresponding flip- attribute value to “true”.
In Fritzing, through-hole
parts are defined as those which use both copper0
and copper1
layers;
SMD parts use only the copper1
layer. By "use" I mean use
in the FZP for <views>
and <connectors>
, and as element
ids in the associated pcb view svg file. If an SMD part is placed
onto the bottom layer in Fritzing, the layer is dynamically updated
to copper0
. Some older THT parts use only the copper0
layer; this is
no longer correct, however Fritzing will treat these parts as if both
copper0
and copper1
were specified. Note that it is very important
that if you specify layers in the FZP, you have matching layers in
the relevant SVG (more on this below).
Now onto the connectors element:
<connectors>
<connector type="male" id="connector0" name="cathode" >
<description>cathode pin</description>
<views>
<breadboardView>
<p svgId="connector0pin" layer="breadboard" terminalId="connector0terminal" />
</breadboardView>
<schematicView>
<p svgId="connector0pin" layer="schematic" terminalId="connector0terminal" />
</schematicView>
<pcbView>
<p svgId="connector0pad" layer="copper0" />
<p svgId="connector0pad" layer="copper1" />
</pcbView>
</views>
</connector>
<connector type="male" id="connector1" name="anode" >
<description>anode pin</description>
<views>
<breadboardView>
<p svgId="connector1pin" layer="breadboard" terminalId="connector1terminal" />
</breadboardView>
<schematicView>
<p svgId="connector1pin" layer="schematic" terminalId="connector1terminal" />
</schematicView>
<pcbView>
<p svgId="connector1pad" layer="copper0" />
<p svgId="connector1pad" layer="copper1" />
</pcbView>
</views>
</connector>
</connectors>
Connector type only matters in breadboard view, where parts with male connectors can be directly attached to parts with female connectors. In all other views, you must use wires to connect connectors. Parts with female connectors include breadboards and Arduinos, but the great majority of parts have male connectors. Wires have wire type connectors, and SMD parts will usually use pad type connectors.
The element and name attributes seem self-explanatory. But it is important to note that within a part, a connector's name and id attributes must be unique—that is, no two connectors in a given part should have the same id or the same name.
Each connector has sub-elements that reference a particular view. Each sub-element has a layer attribute (at present all parts have all their connectors on a single layer, and it's unlikely that will change).
The svgId attribute refers to the an element in the view's SVG file with a matching id attribute. This element defines the shape of the connector and gives its position in the part—it may also define the connector's actual graphic, but that could be elsewhere in the SVG. So in the above example, the “connector0pin” value for the svgId attribute in breadboard view refers to an element in the SVG file LED-5mm-blue.svg:
<rect id="connector0pin" x="4.793" y="65.307" fill="none" width="2.989" height="9.442"/>
The terminalId attribute is optional. Each connector takes up a certain area in a part (in the example above, it's a rectangle), but a wire will actually attach to a connector at a single point within the connector's area. This point of attachment is called a terminal point. The default terminal point is the center of the connector area. If you want the terminal point elsewhere, the terminalId attribute points to yet another element in the SVG file. Here is the SVG element for the terminalId attribute “connector0terminal” in breadboard view:
<rect id="connector0terminal" x="4.793" y="74.192" fill="none" width="2.989" height="0.562"/>
If you use a terminalId attribute in your FZP file, make sure an element with that id really exists in the associated SVG file. Also, although in theory you can name your terminalId attribute anything you want, as long as there's an associated SVG element with that id, in practice we find that it's best to use the connector name followed by “terminal”.
You may recall that an obsolete part can use a replacedby attribute to point to the moduleId of the newer version of the part. Usually, for each connector on the obsolete part, there is a matching connector on the replacement part, and usually the replacement connector has the same id as the obsolete connector, so that it's easy for the software to maintain connections when swapping out an obsolete part. But sometimes the replacement connector does not have the same id. In this case you can use the replacedby attribute on the obsolete connector, with the value being either the id or name of the replacement connector. Here is an example using the name:
<connector id='connector15' name='D0RX' type='female' replacedby='RX/D0'>
In breadboard view, a number of parts feature rubber-band legs (also referred to as bendable legs). Rubber-band legs can be stretched and bendpoints added. Legs can use straight lines or bezier curves. From the fzp side, setting this up is pretty straightforward, for example, here is one from the reed switch: Pin 1
Note the legId attribute in the breadboardView element. The legId only works in breadboard view. A single element may not have a layer both legId and terminalId attributes. As you probably will have guessed at this point, there must be a corresponding element with id="connector0leg" in the breadboard view SVG for the reed switch. This element should always be a . Of the line's two endpoints, the one that is nearest to the center of the part is treated as the attached end of the leg. The other end of the line is the one that can be dragged. Here is the matching leg from the reed switch (I have included the connector for additional context): It is something of an art to position the leg element nicely in relation to the connector element. There is a leg variant used by a number of parts, such as capacitors and LEDs, in which the leg extends beyond the body of the part. The trick here is to set the draggable endpoint of the line outside the viewBox which defines the rest of the part (some of this will make more sense after you have read the About SVGs section below). Here is an extract of the SVG for a capacitor: <svg ... width="0.243056in" height="0.400278in" viewBox="0 0 17.5 28.82" > Notice how the y2 coordinate for each line extends past the viewBox bottom border at 28.82. Hybrid connectors 'Hybrid' is not a good name. A hybrid connector is a connector that is not visible in certain views. For example there are a number of parts which have prototyping areas in breadboard view that are not visible in other views. There are around a dozen of these--mostly Sparkfun shields--that ship with Fritzing. . 5V@1 I think this mechanism might be unnecessary, and that it would be sufficient to hide the connectors in a given view by assigning them a layer id not visible in that view. In this case setting the layer attribute to 'breadboard' in the schematic and pcb views (and getting rid of the secondelement in pcb view) . Internal connections A bus is what we call an internal connection between connectors (I don't think this term has this meaning outside of Fritzing). Breadboards and stripboards make heavy use of buses (and with stripboards, the user can change the bus structure dynamically). A number of other parts come with buses, most notably with GND and various ICSP pins on various Arduinos, but also the humble 4-pin pushbutton. The Parts Editor has a 'show internal connections' mode which allows one to visualize and edit buses by treating each of them as a wire. Here's the buses section for the 4-pin pushbutton. Notice there are two separate buses described: The connectorId attribute refers to the connector id attribute in the element. The bus names are arbitrary, as long as each bus name is unique within a given part (i.e within the fzp file). SPICE modeling We are beginning to add SPICE modeling information to Fritzing parts. The element is a child of the top-level element. Here is an example from a resistor: R{instanceTitle} {net connector0} {net connector1} {resistance} There can be only one element per part, but each element can have multiple elements. One element usually translates into a single line of SPICE output. The items in curly brackets can be thought of as variables which are filled in for each part in the sketch when the SPICE netlist is exported:
- {instanceTitle} is the a part's label. A resistor label is typically something like R1.
- {net connector-id} is the SPICE node number to which the named connector is connected
- {property-name} is the value of the named property. In the above example, {resistance} might be 220 ohms. If one of the elements contains the SPICE .include command, fritzing will attempt to find that file in the spicemodels subfolder of the Fritzing pdb or parts folder, or in the user local storage parts folder. If the file is found, the contents are pasted into the SPICE output. You may also have multiple elements:
COPYRIGHT FRITZING.ORG ALL RIGHTS RESERVED