Help creating a PCB board part (SVG help)

I’ve been working for a week on tutorials, messages, etc. to try and learn how the part making process works. I know I have 3 steps and am stuck on the first, creating the breadboard SVG. I created this file in Inkscape and manually edited tags using the Inkscape XML Editor. I created layers for the silkscreen and the connector, and header1 and header2 to try and keep things together. I’m unsure of using groups vs. using layers as it relates to Fritzing, though I’ve used vector based graphics programs for many years.

I manually added a tag for “breadboard” and indented things under it. If I indent the silkscreen and connector layers, they will then disappear because they are then below the breadboard. I am also unclear as to the connector naming. I wanted to start in the upper left of the board (PB0) and number counterclockwise. I started counting with PB0 as pin 0, skipped that header, and numbered the through holes as “connector10pin” through “connector15pin”. I thought I read that connector0 is different than the others which would affect my numbering. I renamed them from connector21pin-1 to connectorXpin. I’m not sure if that is correct. And I don’t understand the relationship of a “pin” to a “terminal” and how to rename them. I started with the through holes at the left that are in a group called “g1411”. Can I rename that “throughholes”?

Also, now I can’t click on any of the groups to select them because they are under “breadboard” and it always selects the board. I can only select them using the layer panel. Maybe that is by design. I know I probably need to group everything at the end anyway, but it would be nice when working to visually click on something instead of having to navigate using a text tree.

Could you please help me? I uploaded the file, but just see the image. I’m not sure how to upload it as a downloadable file.

MCP23017 Waveshare IO Expansion Board2

Some quick notes. This not extensive or complete.

There is a separate “name” and “id” for each connector. The “connector«n»pin” is the id that is used to link the graphics to the connector definition in the fzp file. The fzp file also has a name field for the connector, which is used for some hover and label information. The id is what we want to start at zero and increment.

The breadboard typically does not contain silkscreen or a silkscreen layer. That is only intended for the PCB view, which is a separate svg file.

Groups and layers are mostly interchangeable when talking about svg files. Svg has a “g” (group) element, but for purposes of Fritzing (and some other tools), a layer is implemented as a group with a special id. So "<g id="breadboard>… is a layer. If you want to also use a group for the headers, with or without an id, that is fine. Those are not layers in the Fritzing sense.

I can’t help much with Inkscape. I use it, but not extensively. I know svg well enough to edit that directly with a text editor. One ‘trick’ is to do an ungroup, to remove the outer breadboard layer, do the other edits, then select all and group again to put the layer back on. I think there are ways using ctrl or something to get access to nested group element contents as well. But not sure possible, not sure how.

1 Like

These two sets of tutorials apply to current versions of Fritzing:

schematic Inkscape plugin

the schematic Inkscape plugin is also extremely useful (I use it for all schematics these days.) That said on to your svg (you can download the svg by right clicking on it and selecting “save file as”.)
First some basics, a part (.fzpz file) consists of a .fzp file and 3 or 4 svg files. If you unzip a .fzpz you will get these 4 or 5 files (I often reuse breadboard as the icon svg which is why one less svg.) The breadboard svg has only the layerId (a group not a layer in Inkscape terms, I don’t know what layers do in Inkscape since I only use it for Fritzing nor as you will see how to get rid of them!) Next Fritzing uses the tiny svg spec and is often confused by Inkscapeisms, so the recommendation is to save your svg as plain svg rather than Inkscape SVG via the save as option in File. In your svg there is a transform in layer1 that I don’t know how to delete (along with the layer, which I don’t know if Fritzing will react to.)

defs are also a bad idea in Fritzing as it usually deletes them when copying svgs. I think it very likely this isn’t going to work as Fritzing doesn’t support it.

       id="rect80965" />

   style="white-space:pre;shape-inside:url(#rect80965);display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0;stroke-dasharray:none;stroke-opacity:1" />

You need to use standard text (nested tspans will also not work correctly) with the Fritzing supported fonts (OCRA and DroidSans, the font files for which are available on the Fritzing site.) Since I can’t figure out how to delete a layer in Inkscape, I resorted to a text editor and just removed the definitions to get a clean svg like this (the def is still there as it is used!)

Now on to pins and terminals. In this case the terminals are not needed. The purpose of a terminalId is to mark where a wire should terminate (most commonly in schematic) like this:

without the terminalId the wire will terminate in the center of the pin (which is wrong!) With the terminalId it will terminate in the center of the terminalId (which is why terminalIds are usually squares) like this:

here the wire will terminate on the end of the pin as desired. For a connector in breadboard that is a square or a circle (as opposed to a line as in schematic) you don’t need a terminalId. In this case the parts factory generates (incorrectly in my view!) terminalIds for pins that don’t need them. As long as the appropriate terminalId is defined in the fzp file that however doesn’t matter, it is just sloppy. Pins are supposed to start at connector0 and increase in sequence. However mostly they work with any value (although there are some problems with displaying pin descriptions if the pins are out of order.) so it is preferable that the pins start at connector0 and increase in order. Typically connector0 should be at pin1 on an Ic like this in this case:

which just happens to be connector0pin as it should be. I would delete the connector0terminal (but you also need to remove it from the fzp file, although it isn’t in the svg it will be just ignored!) I prefer to move the pins to the bottom of the svg like this:

as I have tools that will renumber and move pins in this position (which are not yet publicly available.) This pin doesn’t appear to have a connector definition (and it appears to need one as it is a place that can accept connections.) To correct that I duped connector9pin and moved it via the tool bar (set to inches) like this to keep the new pin on the 0.1in grid. First in x

then in y

it is a little misaligned with the actual connector, but is on the 0.1in grid which is preferred. Now you need to manually set the id to connector10pin (I would just run a script to renumber the pins when I am finished.) Then duplicate that pin and move it up one position in y to make the next pin, rinse and repeat til done. This looks to be a 2mm connector so the pins are a little misaligned. You could and perhaps should move them to 2mm boundaries. Now on to the top connector:

then the end pins

with all the wanted connectors done, we now need to deal with the unwanted connectors. It looks like this svg came from Eagle2Fritzing and thus has extra connectors. Again I have a script (again not yet public) that will remove uneeded connectors and replace them with their element id (circle, rect, etc.) because I use Eagle2Fritzing a lot.

Finally I did Edit->select all, then Edit->resize page to selection to rebuild the svg to start at 0 0 then rescaled the svg by saving the width (in px for maximum resolution) with width locked to height and scale stroke width enabled (the lock of w to h keeps circles circles instead of ellipses!) then modified the scale to be 0.001 (drawing unit = 1 thousandth of an in) as specified in the part file format document.

then edit->select all and group to create the breadboard layerId group which in turn when saved as plainsvg creates a valid breadboard svg (other than the def I didn’t remove and maybe the text although the one I looked at is Droid Sans.) Here is the resulting svg:


Note this still needs to be run through or to have the px removed from the font-sizes with a text editor before it is suitable for use in Fritzing as with px in the font size Fritizng and/or parts editor will get the font size either too large or too small (set to 0 typically.) Hope this helps.


Wow! So much to learn. I’ll make another board from this, so it is a good learning experience. I’ll fix the connector so the pins are at .2 and line everything up. I’ll have to see how to get rid of the transform and the “defs” and figure out how to make the .fpz file that I see is an index of the other 3 or 4 files.

Ok, here is what I have now. I have some questions, if I may:

  1. Are things aligned properly? I guess it only matters that pins line up relative to each other, but the centers of the round through holes on the left and the square invisible connect points on the right connector don’t align to the grid. I imagine the corners of a box containing round holes is what is aligning to the grid. So I zoomed in and got the rectangular connectors lined up close.

  2. How should I have sized the fonts and how to fix them now? I changed the unit in Inkscape to inches and saved the file, but it didn’t change the internal dimension to in. Do I just change 22.22px to .02222 to make it inches in the xml? Do I put “in” at the end in place of “px”?

  3. I am going to try to use, but would like to just install it in my Windows Python 3.10.6 install. The instructions say I might be able to install lxml and run the script from there.



Aligned properly is a slippery term :slight_smile: usually it is desirable in breadboard to align connectors on the 0.1in grid, but at the same time it is desirable to depict the board as it exists (which in the Arduino case makes some of the connectors be 0.05in misaligned.) Then there is a Fritzing quirk where it selects the pin to align to the grid apparently at random (although it isn’t likely to really be random.) That means when you load a part like the arduino sometimes it will be offset 0.05in (because it chose to align one of the offset pins to the grid.) The next time it may go back to a pin on the grid. In this specific case I duplicated a pin and then moved it with the tool bar, which should have left it aligned (but may not have!) To fix that the best bet is to use the position from the tool bar like this:

first get the x and y of the reference pin

then compare it to the pin you want to align. Here x is fine but y is offset 0.002in (probably not enough to matter!) so it should be set to 0.684 in y if we are being picky (which I usually am :slight_smile: )

The part file format document available here

has recommended font sizes in px (Inkscape will add the px for CSS compliance so I don’t think you can use in in font sizes) nor get rid of the px which is desirable. Basically pin labels should be 49px

so to fix that change the font size above to 49 px (unfortunately Inkscape loves to add transforms to text and if you have a transform the font size will be wrong here!) For breadboard (unlike schematic where it is desirable to match other parts) font size can be set to match the real board without paying too much attention to recommended font sizes.

As noted in the instructions I use cygwin, so my case is different, but in a standard python3 install

python -m pip install lxml

should load all the requirements for lxml (note I haven’t tried this though!)


  1. I can verify that this works using just the standard Windows Python install:
    a. Make a directory called “PythonProgs” off root of C:
    b. Unzip the files from from GitHub into the PythonProgs folder
    c. Copy the .svg file I want to test to the same folder
    d. Open a CMD window and type “pip install lxml” (works if python is in the path)
    e. Type “python myfilename.svg” and press enter
    f. It dumps a bunch of messages to the screen

  2. You have a pending pull request on the GitHub repo that looks like might be good to merge, though it would take a while to look at every change. It is from 2020.

  3. Could you give me permission just to make PRs to the Repo? I have a fix for spelling in 2 files. I am “FrightRisk” on GH.

  4. Here is an image of some of the results of the check. What is the “Droid Sans is invalid…” error?
    How do I get rid of “nested t-spans”? There are 20 or so
    Got an “error 69”: Found a drawing element before a layer ID (or no layer id) on line 19. Pic included

This is an inkscapeism, it adds a Inkscape definition (which Fritzing ignores) to the svg. It gets deleted as not useful in the output svg.

I have a development version of check part that removes them (most of the time, there are problems if space=preserve is set.) But in the current version, manually removing the tspans and replacing them with a standard text element is likely the way to go. Trying the svg in Fritzing to see if it works OK is another way to go. FritzingCheckPart was written well before development restarted and some of the old faults may not be present anymore.

there isn’t a layerId in the named svg. Assuming this is breadboard then g13380 should be breadboard like this:

the only thing I know of that this affects is the part won’t be exported as an image (svg, jpg, png etc.) from Fritzing. The layerId needs to match the assigned layerId in the fzp file (usually but not always, breadboard, schematic, copper1, copper0 and silkscreen.)

As far as I know (I’m not all that github literate :slight_smile: ) anyone should be able to make pr requests. Whether they will be acted on is another matter though. What needs to happen is a total rewrite, but my motivation (and skill level!) isn’t all that high so progress is being slow. Not all that many people use FritzingCheckPart, there is some desire by the developers to include it in the part validation tool chain on github, but it needs some substantial changes to get there and as noted my motivation has been lacking. I’m currently working on a python version of the parts factory (currently implemented in c++ in the fritzing application) which is making me learn more about proper python coding. After that I may tackle a new Checkpart. I suppose I could also push my development version which has a number of improvements (but not those needed to be part of the tool chain.) which is what I am using locally.


I am a GitHub guy, but not a Python guy. Someone would have to fork your repo to their own repo, make changes, then issue a PR from theirs to yours. It would be easier to either create a team with permissions and add people to it so others can help, or just add people individually. You can control what level of access they have, but you have to add them or invite them. Go to the repo, click on settings, then under “access” at the left, click on “collaborators & teams”. Then on the right you can select the “add people” button and type in their GH name, like “frightrisk”. Then under “manage access” you can select what level of access you want to give them. A normal user can issue a PR, but not merge it. Or you can search the 2 files that have “apparant” and “apparantly” and change them to “apparent” with an “e” :slight_smile:

I grabbed a sparkfun board part (3 axis accelerometer) and dropped it on a breadboard. I took the file I ran through your .py utility and it loaded It doesn’t look like there is anything wrong with it, but I will have to go through all the rest to complete the part and then try to use it. Here is an example of text that I have to learn how to fix. Though it does display correctly in the parts editor.

That can be done easily enough (I just realized my development version doesn’t have updates to the message text file which it both needs and are a lot of work. I think the best way forward is to get motivated (and learn enough python) to make the new version (which has admittedly been in progress for 5 or 6 years with no end in sight :slight_smile: )

These should both work as is. The tspans are not nested and Fritzing should be happy with them. A nested tspan has another tspan as a subgroup of the first one usually with a transform or two and Fritzing usually chokes on them and can’t display the text (as noted later Fritzing versions may also have fixed this!) I automatically use when making new parts, and when reviewing parts people have posted in the forums but against core parts or parts I have found on the net I sometimes just use them until they cause a problem and then use FritzingCheckPart to evaluate what the issue is (or just read the fzp and svgs of course!)


I think I will either take a different board as a starting point, like some Adafruit breakout, where the schematic and PCB footprint are close, or use the Inkscape schematic plugin to make the schematic from scratch. I had to do a pip install of both cssselect and numpy to get it to work. There is a bug in the dependencies for Inkscape 1.2.

How would you create the schematic for this board (shown below)? I could make it look like the board, but most schematics seem to look more like a chip in that they put Vcc at the top, GND at the bottom, and just put connector pins to one side just like they are on a chip. Basically, where would you put what pins on all 4 sides?

How does Fritzing handle duplicate pins? Are they linked somehow? For example, my connector and through holes are duplicated. So in breadboard view, you can connect a wire to Vcc at the connector, the through holes, or at the pin header. The schematic may show just one Vcc, but no matter where you connect at the breadboard, the schematic should see that as the same connection.

I (with emphasis on the I :slight_smile: ) would usually make schematic match the breadboard because I find that easiest for debugging. The downside to that is with multiple grounds (as in this instance) you can have a case in schematic where you can’t make a connection because there is already a connection elsewhere in the same net and it only allows one. The conventional solution to that is to overlay all the pins in schematic (which I don’t like, but may be convinced to switch to.) In this discussion of a schematic for the motor driver the guide lines for KiCad guidelines for their schematics. This is one of many grey areas in Fritzing that I think should be better documented but aren’t.

Some of the other issues are discussed in this thread (which is pretty inactive)

As noted there are a variety of issues that need discussing and documenting but there doesn’t appear to be a lot of interest in doing so.


Great! And thank you so much for all the in depth help. I can payback by helping with documentation for the things I learn. I’ll start following the Fritzing board and GitHub.

The last (at least for now :wink: ) issue is that the through holes and the screw holes are not transparent. I thought I read that if I made them white, Fritzing would figure it out and that would keep the circles as circles in case you need to resize them. Or do I use the traditional vector graphics approach of making the holes and board “paths” and then just subtracting the circles by using “path → difference”? However, I tried that and it was just a mess due to layer position. It either made holes and lost the gold trace around the holes or turned everything white, or left some round traces and lost others…


In general for breadboard I use a circle like this:


with the fill set to white (#ffffff) so the “hole” appears. For pcb fill should be none (although as I recall Fritzing doesn’t care and a fill value will work fine and be ignored.) like this

paths are undesirable for several reasons, gerber processing is picky. A path will only work in pcb if a circle is the only element in it, an oblong path won’t work (you need the oblong path with a circle to be the connector.) As well it is much harder to set or change the hole size for a path. For a circle in Inkscape the hole size will be

hole_size = pad_diameter - (2 * stroke-width)

which is much easier to change if you need to.


Still struggling with this part. First, I can’t get it to have transparent holes. I am guessing it may have to do with the main board being a path? I don’t remember making it a path, but perhaps when you take a rectangle and round the corners it makes it a path.

The next thing is putting it on a breadboard. The through holes and connector pins are not the same spacing. The round holes don’t line up (except for the bottom one) when the board is “seated” in the breadboard, but the right ones on the connector do. That is not the way a breadboard is wired. All of the pins are wired together vertically. So I am guessing I want to space the connector pins closer so that they won’t snap into holes on the breadboard? That is what I did on this version.

Do I have the group correct now named breadboard? I’ve run it through the Thanks!


Nope, a path for a rectangle with corners is standard. To get “transparent holes” in the pads you need to set the fill for the pad to #ffffff (white) which you have done. They however won’t be transparent in breadboard but rather red (unconnected) or green (connected) which overwrites the color of the fill.

To make this usable on a breadboard the pins circled in green here

need to be changed from type=“male” to type=“female” in the fzp file like this:


<connector id="connector1" name="pin2" type="male">


<connector id="connector1" name="pin2" type="female">

That causes the labeled pin to not connect to a breadboard pin (which is also female) it will still connect to a wire though. That also suppresses the fill being replaced with red or green. You have some alignment issues in your svg but they are probably not large enough to worry about (the header pins are 0.01in larger in x on some pins which shouldn’t be enough to matter.) More of a problem may be the left end pins being 0.01 in offset in x.

The problem this causes (which I believe is a bug!) is that Fritzing picks a pin (how is unknown) to align to the grid. All well and good, but it changes which pin it uses on each load so one time it may pick the first pin and the end connectors will align with breadboard (but the yellow header will be 0.01in offset in x.) The next time it may select tha pin in the yellow connector and that will align to breadboard but the left end pins will be 0.01in offset. The only thing that will fix this is a code change which hasn’t happened yet.

[quote=“FlightRisk, post:16, topic

Do I have the group correct now named breadboard? I’ve run it through the

Yes. The group is now correct. You may have a problem with tspans however (I am running a development version of check part that does more checking) as these errors show up:

Error 92: File
At line 291

Tspan removal error: xml:space=“preserve” found.

Error 92: File
At line 295

Nested tspans are not supported by Fritzing (so if your text doesn’t show up you likely have nested tspans.) They can be replaced by a standard text segment (no tspan) but not if space=“preserve” is set which is the case here (Illistrator sets space=“preserve” for some reason.) If your text is showing up in Fritzing ok you can ignore this. Hope this helps!


I just can’t get it. I went into the parts editor and changed the pads on the left and connector “pins” on the right from “pad” to “female” and no difference. They are just not transparent. I looked at the .fpz file and it is changed in there.

I don’t know if the X values you mentioned above matter since I only care about the headers as far as the breaboard goes. I didn’t think it mattered where the pads were if I don’t want them to connect to the breadboard, but I can moved the headers over .01" to the left. And do I need to measure from the centers of the pins or does it work itself out no matter what sizes the squares are the the pins or pads sit inside? IOW, the left pads are round and inside a big square. The header pins are square and sit in a smaller square.

Even with setting the pads from to “female”, the Vcc pin on the left (connector 32) still turns green as if it is trying to connect to something.

Now I can’t click on the mounting holes, which I assume is because they are not connectors, but that’s fine since they aren’t connectors, but I can’t get them to be transparent either. I’m trying to learn more about the XML to be able to edit it manually, but the files are too big. It would be nice to have automatic renumbering because every time I change the image and import it, the pins are all off by one and I have to manually assign them in the parts editor.

I also don’t know how to get rid of nested tspans. But unless they are the reason the holes aren’t transparent or the Vcc pin thinks it should turn green to connect to the breadboard, it doesn’t seem to cause a problem. The problem happens every time I try to re-edit the file in Inkscape, save it as a “plain SVG” and it messes up the fonts so they appear as a mess on the breadboard image in Fritzing. So I have to run your parts fix python script each time and it removes what it needs to remove so it works again. I exported the part to show the whole thing.


Waveshare MCP23017 Breakout.fzpz (41.4 KB)

The mounting holes are currently white (which looks correct to me!) To make them transparent you would set the fill to none, but that will then set the center blue (the color of the underlying board) which I expect is not what you want. This breadboard image shows the problem with header placement (although that isn’t the 0.01 offset I was referring to)

Fritzing appears to have used the pin circled in green as the reference pin for the grid. As you see the headers are about 0.05in offset from the grid and thus don’t connect to the breadboard. To fix that you would need to move both the right and left headers (which are female) to be exactly 0.1in offset from the headers so as to make the headers always align with the grid so it will connect to the breadboard. As you see the headers are currently red as they are not connected. They will turn green (but not transparent) when correctly aligned to the breadboard.

This is likely being caused by an incorrect bus definition in the .fzp file:

<bus id=com>
   <nodeMember connectorId=connector19/>
   <nodeMember connectorId=connector32/>
   <nodeMember connectorId=connector60/>

This buses connector19 to connector32 (and connector60 which doesn’t exist and will be ignored.) If connector19 is connected then connector32 will turn green. You need to correct the bus definitions to fix this. Connectors19 and 32 look to be the only ones actually present. There need to be buses for VCC and GND on the headers and all of the connectors on the left and right (as they look to connect to each other.)

Then the tspans aren’t nested and likely are fine. I can run the svg through check part after removing the space=“preserve” and that will clear the tspans so you can see how to do it manually if you want.

This is caused by Inkscape adding px to the font-size for CSS compliance. Fritzing objects to font sizes with px, and either sets the font size to 0 or a large number affecting the text. As you note removes the px (among other things) to avoid the problem. Looks like there is a problem with aligning the headers. The lines here are 0.1in increments from the center of the header. To align to the breadboard correctly the right and left connectors need to move down about 0.05in (and possibly in x as well) as seen in this image. You could move just the connectors (which are invisible) down the 0.05in but that would make connecting to them difficult. You could also make the right and left pins not connectors which will also clear the problem. In the end I made the pins invisible and moved them down 0.05in and a bit in x to fix the breadboard alignment.

breadboard has the tspans removed. In the fzp file I replaced the bus section with this

       <nodeMember connectorId="connector12"/>
       <nodeMember connectorId="connector25"/>
       <nodeMember connectorId="connector31"/>
      <bus id="SDA">
       <nodeMember connectorId="connector13"/>
       <nodeMember connectorId="connector30"/>
      <bus id="SCL">
       <nodeMember connectorId="connector14"/>
       <nodeMember connectorId="connector29"/>
      <bus id="INTA">
       <nodeMember connectorId="connector15"/>
       <nodeMember connectorId="connector28"/>
      <bus id="INTB">
       <nodeMember connectorId="connector16"/>
       <nodeMember connectorId="connector27"/>
     <label>Waveshare MCP23017 Breakout</label>

which should be a correct bus configuration. The pcb svg is incorrect it doesn’t have the correct number or position of pins so I copied breadboard in to it and set it up as a proper pcb. Note the right connector is suppressed in pcb but the right side holes are in the correct place. Schematic is missing terminalIds on the pins so I added them to all pins like this:


      <p layer="schematic" svgId="connector1pin"/>


      <p layer="schematic" svgId="connector1pin" terminalId="connector1terminal"/>

The effect is that the wire connects to the end of the pin rather than the middle as it does now:

to this

and pcb now works:

the changes are in this part

Waveshare MCP23017 Breakout-fixed.fzpz (28.1 KB)

you will need to delete the current part before being able to load this one. You need to delete the part then shut down Fritzing (answering yes to the two save the part changes prompts) then restart Fritzing before being able to load the new part.


1 Like

Am I wrong in thinking that the headers and the pins on the left and right don’t need to match each other? Because of the way a breadboard is designed, you can’t use both headers and connectors. The breadboard is connected in vertical rows. You either use the headers with the board horizontal or the pins with the board twisted vertically. There are only 5 holes vertically in the board, so you can’t use either sets of connectors vertically anyway and if you had the headers aligned, the pins on the right and left would be shorted.

And back to the transparent holes. You mentioned that #fffff for fill should work, so I’m confused about that. Am I supposed to cut holes in the right spot in the blue board since it is a path anyway? I’m assuming you can see that the fill on the holes is correct, but it isn’t working for you either? Thank you for the help and fixing the PCB. That was the first thing I was going to work on.

I stumbled upon the “Sparkfun MyoWare Cable Shield” that either comes with Fritzing or I installed the Sparkfun parts from GitHub. It has transparent mounting holes and transparent solder through holes. I don’t know if I really need them, I guess I can leave them white and it will work. But it looks like boards with transparencies are cutting out holes in the board, then using a ring of gold around the hole. One board shows the ring is a “path”, not a circle. But the board file I attached here is a circles with a strokes of gold in the ring width and no fill. The IDs are “ConnectorXPin”