Open vanepp opened 1 year ago
As a start towards better documentation/standards for part creation I would like to float the idea of a common .fzp file format. Because it is xml it doesn't need a common format, but I think a common format (which automated tools can then enforce) may be useful. So starting from the parts file format document here
https://github.com/fritzing/fritzing-app/wiki/2.1-Part-file-format
these two are clear
fritzing-parts/core # parts in the core parts bin fritzing-parts/obsolete # obsolete parts from core
fritzing-parts/contrib
this one is less clear. It is currently empty. I assume (but don't know for sure) that it was intended for user contributed parts but current practice is to load those in to core. So this may be a candidate for removal?
A currently missing part of this document that I think we should add is the .fzpz file format and how it relates to the folder layout as it currently isn't documented anywhere that I know of and it should be documented somewhere.
part.part_name.fzp loads in to
Documents\Fritzing\parts\user\part_name.fzp
with the svgs (breadboard, icon, schematic and pcb) going in to the associated svg directory i.e.
svg.breadboard.part_name.breadboard.svg
goes in to
Documents\Fritzing\parts\svg\user\breadboard\part_name.breadboard.svg
again there are empty (and apparently unused) contrib directories here which maybe should be removed?
on to FZP format
the current example is
<?xml version='1.0' encoding='UTF-8'?>
but most of the actual fzp files in core are of the form
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
I don't know what standalone='no' does or if it is worth making it the standard or not. Opinions? Then there is the next line, currently
the current example is but most of the actual fzp files in core are of the form
Did something go wrong here? It seems that there is something missing...
The standalone='no', is part of the XML standard. Basically: "The XML standalone element defines the existence of an externally-defined DTD." "A DTD is a Document Type Definition. A DTD defines the structure and the legal elements and attributes of an XML document."
but a more common in core parts version has the parts editor added "referenceFile" as well. I believe it is only added by parts editor and not actually used for anything except reference to where the part was cloned from, so the question becomes do we want to keep it and if so require it or leave it as an option.
If it is not used for anything else, I would also drop this.
Stefan Hermann I would add the advise if you are making a change to a part you should add something like this to the author field Stefan Hermann (modified by vanepp Apr 2023) to document who and when made the last modification.
Fine with me
< is what the part will be displayed as in the parts bin is worth documenting I think so people know where the name > comes from. The version field could use some advise too 4 is the most common version in core parts, I think not because it is correct, but because it is the version of most parts in core > and doesn't get changed when the part it modified or cloned. I think a policy of "if this is an updated version of the current > part, increase the version field by 1 for the new part, if this is a new part being cloned from an existing part set the version > > number to 1" is likely a good bet. My changes to the obsolete.py script already do this (no version number is replaced by > > version>1< in the original and version>2< in the modified files otherwise the current version number is increased by 1.) I'd > also suggest that the version number get appended to the moduleId and all the file names as done by the _1 in the > > > > > moduleId and reference file name in the module line above. Comments? Disagreement? Issues I haven't thought of?
I'm ok with this.
Another thing to consider is the date filed. There are several standards used in the core parts.
Maybe it could be a good idea to create a template of a part with comments explaining all the fields. That could help to keep the standard in place.
Did something go wrong here? It seems that there is something missing...
I expect yes (although I didn't know it was part of the standard) I think we just need to update the part file format document to include it. It either got missed initially or has changed (and the part file document not) later as I expect (but as usual don't know for sure!) that the part file format document is probably pretty old.
Another thing to consider is the date filed. There are several standards used in the core parts.
Good point. I like this format (and it should be possible to automate converting other styles to this I expect (although different OS language settings may be a challenge, as this is English centric and formats in other languages may not be that easy to reformat automatically.)
Sat Jul 18 2022
Maybe it could be a good idea to create a template of a part with comments explaining all the fields. That could help to keep the standard in place.
I think adding those comments to the Part file format document is probably the best bet with an explanation of what each field is intended to do (and where else it needs to match such as the svg files!) Only one place to remember to make the change in future then and it serves as a primer for making parts, anyone see a problem with that (or a better alternative?) Another issue that probably needs discussion is the family field. I tend to use specific names for the family to avoid swaps with parts with a different number of pins (which breaks the views, with red rectangles for missing pin definitions often), but I know @mMerlin prefers broad family names so you can easily see all available parts for a class of parts. From discussions years ago in the forum, I think the intent of Inspector part swapping was for different packages in pcb (mostly anyway) where the pins were identical so the swap didn't break connections. I would prefer to see a check that a part as part of a family has the identical pins so swap will work correctly, but I can also see the advantage of seeing all parts of a given class that are available. I just wonder if there isn't a better way to do that (possibly bins for a class of part?) without causing error responses.
I would also remove the numbers of the connectors that there are in the svg file. I think they are redundant and confusing. First, these numbers do not match with the name of the pins, see the transistor below (the base is numbered as 1 in the svg file and when you hover ober the connector you see that that is pin 2). In addittion, the connectors are highlighted in red/green and can be found without the numbers. The only place I can see that they might be useful are for ICs, but for small parts, I think they do not help. And there are plenty of parts without the numbers (e.g., Arduino Uno as they do not make sense). My students get sometimes confused as the pin number 1 in Fritzing does not match the pin number 1 of the datasheet of the transistor. Thoughts?
The internal connector numbering is usually not the same as displayed one.
There was some code to avoid counting from zero, Fritzing tried to be smart about this if connectors were numbered like 'connector0, connector1...' . We have removed that 'feature' it in the 1.0.0 release, so it is more consistent now. But I don't think it is anywhere near redundant?
BUT:
To be clear: The internal connector numbering is now more consistent with the gray number displayed on mouse-over. Before, it would sometimes match, and sometimes be one-off. But the gray number is not necessarily related to what he part designer had labeled the pins.
But I don't think it is anywhere near redundant?
Just to be clear, I was talking about the small number in grey next to the connectors, not the message that appears when hovering the mouse over the connector. I think they are quite arbitrary. If you want to keep them, at least, I would change the numbers in transistors by letters (E B C) and in diodes (A K).
For the generic ic dip 8: In the schematic svg we have:
<line fill='none' stroke='#787878' stroke-linejoin='round' stroke-linecap='round' stroke-width='9.7222' x1='4.8611' y1='100' x2='200' y2='100' />
<rect x='0' y='95.1389' fill='none' width='200' height='9.7222' id='connector0pin' connectorName='1' stroke-width='0' />
<rect x='0' y='95.1389' fill='none' width='0.1' height='9.7222' id='connector0terminal' stroke-width='0' />
<text id='label0' x='219.444' y='109.722' font-family="'Droid Sans'" stroke='none' fill='#8c8c8c' text-anchor='start' font-size='48.6111' >1</text>
<text class='text' font-family='Droid Sans' stroke='none' stroke-width='0' fill='#8c8c8c' font-size='34.7222' x='100' y='85.4167' text-anchor='middle'>1</text>
And in the fzp:
<connectors>
<connector id="connector0" name="pin1" type="male">
<description>pin 1</description>
<views>
<breadboardView>
<p layer="breadboard" svgId="connector0pin" terminalId="connector0terminal"/>
</breadboardView>
<schematicView>
<p layer="schematic" svgId="connector0pin" terminalId="connector0terminal"/>
</schematicView>
<pcbView>
<p layer="copper0" svgId="connector0pin"/>
<p layer="copper1" svgId="connector0pin"/></pcbView>
</views>
</connector>
However, not all parts have pin labels. If a parts designer wants to create a transistor with pin labels (E B C), then it would be hard-coded in the SVG. It would be much better of course if Fritzing would display the actual connector name, and a connector description on mouseover or similar.
But most parts have these arbitrary numbers in the SVG file. See the NPN transistor:
...
<text class='text' font-family="'Droid Sans'" stroke='none' stroke-width='0' fill='#8c8c8c' font-size='0.881944' x='1.39347' y='4.83306' text-anchor='middle'>1</text>
<line class='pin' id='connector2pin' connectorname='E' x1='5.20347' y1='10.2835' x2='5.20347' y2='7.74347' stroke='#787878' stroke-width='0.246944' stroke-linecap='round'/>
<rect class='terminal' id='connector2terminal' x='5.20347' y='10.2835' width='0.0001' height='0.0001' stroke='none' stroke-width='0' fill='none'/>
<g transform='translate(4.83306,9.01347)'><g transform='rotate(270)'>
<text class='text' font-family="'Droid Sans'" stroke='none' stroke-width='0' fill='#8c8c8c' font-size='0.881944' x='0' y='0' text-anchor='middle'>2</text>
</g></g>
<line class='pin' id='connector1pin' connectorname='C' x1='5.20347' y1='0.123472' x2='5.20347' y2='2.66347' stroke='#787878' stroke-width='0.246944' stroke-linecap='round'/>
<rect class='terminal' id='connector1terminal' x='5.20347' y='0.123472' width='0.0001' height='0.0001' stroke='none' stroke-width='0' fill='none'/>
<g transform='translate(4.83306,1.39347)'><g transform='rotate(270)'>
<text class='text' font-family="'Droid Sans'" stroke='none' stroke-width='0' fill='#8c8c8c' font-size='0.881944' x='0' y='0' text-anchor='middle'>3</text>
</g></g>
</g>
</svg>
The numbers 1, 2 and 3 are there as text elements. Should we keep these arbitrary numbers? If so, I guess it would make more sense to replace the 1 2 3 by E B and C. I am not talking about the name or numbering of the connectors in the FPZ file.
Icons are often just copies of the breadboard view, which is supported by Fritzing (it ignores the 'breadboard' id for icons). I'd suggest to not neglect them. Add the "icon" id, simplify the icon, no connector ids and such. And check that the icons still look good when rendered small.
For example, here I cut the sensor, otherwise it would render as a very thin line:
The internal connector numbering is usually not the same as displayed one.
There was some code to avoid counting from zero, Fritzing tried to be smart about this if connectors were numbered like 'connector0, connector1...' . We have removed that 'feature' it in the 1.0.0 release, so it is more consistent now. But I don't think it is anywhere near redundant?
This particular example is something that I would like to eliminate. It is caused by trying to reuse a single schematic by changing the pin numbers in the .fzp file. The example above looks like this in the .fzp
<connector id="connector0" type="male" name="E">
<description>Emitter</description>
<views>
<breadboardView>
<p layer="breadboard" svgId="connector0pin" legId="connector0leg"/>
</breadboardView>
<schematicView>
<p terminalId="connector2terminal" layer="schematic" svgId="connector2pin"/>
</schematicView>
<pcbView>
<p layer="copper0" svgId="connector2pin"/>
<p layer="copper1" svgId="connector2pin"/>
</pcbView>
</views>
</connector>
Note the connectorId is connector0 in the connection definition and breadboard, but the schematic and copper layers are connector2 (in order to use a single svg for multiple different parts.) I would prefer to have more svgs with the connector number consistent (all connector0 in this case.) FritzingCheckPart.py will currently issue a warning about the connector numbers not being consistent (as that is normally an indication of a typo) and I would prefer to see this banned (as it is very confusing when you try and troubleshoot a part if you don't notice the different connector numbering in the fzp file. It also confuses Fritzing about what the pin number should be called which is what looks to be happening in this case, and banning it would solve that issue too I think. That said, I agree the text label in the svg for the pin number (which typically is one larger than the connector number to compensate for Fritzing pin numbering starting at 0) is probably redundant and should be discouraged and/or actively removed. If we need that number, generating it from the connectorId would be a better bet as it will then be in some sense consistent as it is being automatically generated.
@vanepp We will always need some kind of ID, that can be easily processed by an algorithm, for example numbered. Almost every database works like that. This ID is usually not user facing, and only the people working directly with the database ever use it. It is independent of the name or the description of a pin. One condition applies: It must be unique.
Now, two examples where it would be difficult to enforce IDs to be used "user facing":
The unique constraint does not apply to names of the pins, e.g it is pretty common to have multiple GND pins.
I don't think we have this in Fritzing, but I am sure it exists: If the shape of a connector on top and bottom layers differ, you will want different a svgId for copper0 and copper1.
- The unique constraint does not apply to names of the pins, e.g it is pretty common to have multiple GND pins.
I agree with that, but the current Wiki states that the name also needs to be unique: " 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."
That said, I agree the text label in the svg for the pin number (which typically is one larger than the connector number to compensate for Fritzing pin numbering starting at 0) is probably redundant and should be discouraged and/or actively removed. If we need that number, generating it from the connectorId would be a better bet as it will then be in some sense consistent as it is being automatically generated.
I agree too with that. The numbers of the pins specified in the SVG file (the ones in red circles below) seem unnecessary to me except for ICs.
And of course, themessage displayed when hovering on the connector could be better as "Pin 0: Pin 0 (1)" is quite confusing.
Something I am thinking about for future versions of Fritzing: The current mechanism will still work. But if the views are not specified for a connector, defaults would apply.
This
<connectors>
<connector id="connector0" name="pin1" type="male" aperture="custom_tht">
<description>pin 1</description>
</connector>
</connector>
Would expand to a usual fritzing connector definition with two layers, terminals and leg:
<connectors>
<connector id="connector0" name="pin1" type="male">
<description>pin 1</description>
<views>
<breadboardView>
<p layer="breadboard" svgId="connector0pin" terminalId="connector0terminal"/>
</breadboardView>
<schematicView>
<p layer="schematic" svgId="connector0pin" terminalId="connector0terminal"/>
</schematicView>
<pcbView>
<p layer="copper0" svgId="connector0pin"/>
<p layer="copper1" svgId="connector0pin"/></pcbView>
</views>
</connector>
While on it 'type' could be more descriptive. It is used for the breadboard view, to describe how it would connect or not connect. In another issue: I think this should describe real connectors: male_header, headphone_jack, jst-3 ...
For the schematic svg: Instead of simply removing the pin numbers, we could show the pin names. The svg would contain a text element with the connector id. If the text is empty or equals "default", fritzing would fill in the pin name?
Since you brought up "type", I will add that it is being inappropriately "overloaded" in breadboard view. That is also used to limit when a dragged connector will or will not attach to an existing connector. Apparently designed for breadboards, so female connectors will accept male pins. However, where are modules with male headers that should be able to accept dragged female connections. To get the desired functionality, I have had to 'lie' about male and female pins in created parts.
My 'solution' would be to add additional details to the connector information. Whether it is on the top of a part (and can then accept matching 'opposite' connectors), or on the bottom (and can then be dropped on matching 'opposite' connectors). Information on matching and opposite may need additional definitions. If there was no top or bottom information, or the type did not have a defined opposite, the connector would never auto attach to an existing connector when dragged, and no dragged connector would attach to it. This should also handle a connector that is both top and bottom (type = pass through) for stackable parts like shields and hats. Maybe
dragaccept = "true" dragconnect = "true" or drag = "accept,connect" accept="male,passthrough" connect="female,passthrough"
@KjellMorgenstern
@vanepp We will always need some kind of ID, that can be easily processed by an algorithm, for example numbered. Almost every database works like that.
I am not arguing we should remove the numbers, but rather would like to see the numbers be consistent in a connection. I find it very annoying to have pins in a connection that are different than the connector number at the start of the connection. The cases I know of do this to reuse svgs but as noted I'd rather not reuse the svg if that is the only way it can be done.
The unique constraint does not apply to names of the pins, e.g it is pretty common to have multiple GND pins.
Here I agree, but at present that only applies to the description field because the name field is used (under rare circumstances) to differentiate parts apparently and thus is specified as "should be unique" in the parts format document. FritzingCheckPart.py can (but by default doesn't because it rarely matters) check if the names are unique. We either need to disable the code that checks the names or have the names unique I think.
@failiz
I agree too with that. The numbers of the pins specified in the SVG file (the ones in red circles below) seem unnecessary to me except for ICs.
They are sometimes useful (although there are other ways of telling), because pin numbers are important in other views, for example a resistor that is aligned 1 - 2 in breadboard but 2 - 1 (inverted) in schematic can cause a short and is a fairly common new user error. I think this is one of the ways we get routing database corruption, by having the wrong pin order in another view that causes a short. To me it is usually obvious and you should be able to tell from hovering over the pin, but to new comers it is hard to grasp apparently (given the number of times it happens!)
And of course, themessage displayed when hovering on the connector could be better as "Pin 0: Pin 0 (1)" is quite confusing.
I agree, this I think is caused by Fritzing starting at 0 but pin numbers typically starting at 1. Adding one to the internal pin number before displaying it would probably be the best solution here I expect.
@KjellMorgenstern
Something I am thinking about for future versions of Fritzing: The current mechanism will still work. But if the views are not specified for a connector, defaults would apply.
I like this idea, it would make much less editing for pins in the general case!
While on it 'type' could be more descriptive. It is used for the breadboard view, to describe how it would connect or not connect.
I agree this could use work. At present it accepts male, (the usual default), female (don't connect to the breadboard for pins that would short because they run parallel to the breadboard) and pad which I don't know what it does or means, perhaps something SMD related? It is a source of confusion to new users who don't know what the field means. @mMerlin 's suggestion is probably a good one although backwards compatibility may be an issue.
Backward compatibility should not be an issue. If none of the new fields exist, default to whatever would get the current functionality. That is a male connector can be dragged on top of a female connector to get automatic attachment. It may be a little more than that. Something is 'pinching' at my memory that the female connector needs to be part of a breadboard.
@vanepp I am not arguing we should remove the numbers, but rather would like to see the numbers be consistent in a connection. I find it very annoying to have pins in a connection that are different than the connector number at the start of the connection. The cases I know of do this to reuse svgs but as noted I'd rather not reuse the svg if that is the only way it can be done.
I do not have examples of your svg reuse cases. Would never including any of the unique id fields for a connector in the displayed, hovered, etc text help? Possible extension to that, an empty, special, tagged svg text element that will be populated from data in the fzp connection information Possibly more than one text field. Let the fzp content drive some of what is displayed for the view. So (for PCB) a single 3 terminal footprint could show "C E B" for one part, and "D S G" for another. For things with varying pinouts (CEB versus CBE and others), if the pin number is to be displayed, the fzp file can specify the ordering.
User facing pin numbers normally start at 1, but for complete flexibility, the starting pin number could be specified in the fzp with auto increment. Also, for modules with multiple headers, an override could be provided to restart the number for the next header. If desired. Even better, add an optional header/group/block prefix. IE: H1P1 and H2P1 with prefixes of H1P and H2P. Going further, some of that could be set/changed in parts inspector
@mMerlin I do not have examples of your svg reuse cases.
Easy to provide one. From @failiz 's example above, all the npn transistors appear to use this svg (which when I look at it is wrong!):
Fritzing\fritzing-parts\svg\core\schematic\basic_transistor_npn.svg
which looks like this:
here the pin labeled "3" is connector1 (when it should be connector2) and the one labeled "2" is connector2 when it should be connector1, as I think it will currently display wrong when you click on the pin in a view, as Fritzing will add 1 to the connector number for the display. It then gets worse in the associated fzp files (which is the part I was originally complaining about!) as the pin numbers associated with the pins change from fzp to fzp to reuse the svg which I think is a mistake, as it unnecessarily (at least in my view) complicates the fzp file.
Fritzing\fritzing-parts\core\transistor_signal_NPN_TO92_CBE.fzp
<schematicView fliphorizontal="true" flipvertical="true">
<layers image="schematic/basic_transistor_npn.svg">
...
<connectors>
<connector id="connector0" name="E" type="male">
<description>Emitter</description>
<views>
<breadboardView>
<p layer="breadboard" svgId="connector0pin" legId="connector0leg"/>
</breadboardView>
<schematicView>
<p layer="schematic" svgId="connector2pin" terminalId="connector2terminal"/>
</schematicView>
<pcbView>
<p layer="copper0" svgId="connector2pin"/>
<p layer="copper1" svgId="connector2pin"/></pcbView>
</views>
</connector>
<connector id="connector1" name="B" type="male">
<description>Base</description>
<views>
<breadboardView>
<p layer="breadboard" svgId="connector1pin" legId="connector1leg"/>
</breadboardView>
<schematicView>
<p layer="schematic" svgId="connector0pin" terminalId="connector0terminal"/>
</schematicView>
<pcbView>
<p layer="copper0" svgId="connector1pin"/>
<p layer="copper1" svgId="connector1pin"/></pcbView>
</views>
</connector>
<connector id="connector2" name="C" type="male">
<description>Collector</description>
<views>
<breadboardView>
<p layer="breadboard" svgId="connector2pin" legId="connector2leg"/>
</breadboardView>
<schematicView>
<p layer="schematic" svgId="connector1pin" terminalId="connector1terminal"/>
</schematicView>
<pcbView>
<p layer="copper0" svgId="connector0pin"/>
<p layer="copper1" svgId="connector0pin"/></pcbView>
</views>
</connector>
</connectors>
In the schematic svg
connector0pin is the base connector1pin is the collector connector2pin is the emitter
In the fzp file
connector0 is description "Emitter", connector0 in breadboard but connector2 in schematic and pcb
connector1 is description "Base", connector1 in breadboard and pcb but connector0 in schematic
connector2 is description "Collector", connector2 in breadboard but connector1 in schematic and connector0 in pcb.
Which I find is needlessly confusing in the fzp and will (probably!) screw up the hover on pin display since they won't match the static text in the svg as Fritzing will likely add 1 to the connector number to format the field.
Fritzing\fritzing-parts\core\transistor_signal_NPN_TO92_EBC.fzp
<schematicView fliphorizontal="true" flipvertical="true">
<layers image="schematic/basic_transistor_npn.svg">
...
<connectors>
<connector id="connector0" name="E" type="male">
<description>Emitter</description>
<views>
<breadboardView>
<p layer="breadboard" svgId="connector0pin" legId="connector0leg"/>
</breadboardView>
<schematicView>
<p layer="schematic" svgId="connector2pin" terminalId="connector2terminal"/>
</schematicView>
<pcbView>
<p layer="copper0" svgId="connector2pin"/>
<p layer="copper1" svgId="connector2pin"/></pcbView>
</views>
</connector>
<connector id="connector1" name="B" type="male">
<description>Base</description>
<views>
<breadboardView>
<p layer="breadboard" svgId="connector1pin" legId="connector1leg"/>
</breadboardView>
<schematicView>
<p layer="schematic" svgId="connector0pin" terminalId="connector0terminal"/>
</schematicView>
<pcbView>
<p layer="copper0" svgId="connector1pin"/>
<p layer="copper1" svgId="connector1pin"/></pcbView>
</views>
</connector>
<connector id="connector2" name="C" type="male">
<description>Collector</description>
<views>
<breadboardView>
<p layer="breadboard" svgId="connector2pin" legId="connector2leg"/>
</breadboardView>
<schematicView>
<p layer="schematic" svgId="connector1pin" terminalId="connector1terminal"/>
</schematicView>
<pcbView>
<p layer="copper0" svgId="connector0pin"/>
<p layer="copper1" svgId="connector0pin"/></pcbView>
</views>
</connector>
</connectors>
Here connector0 is description "Emitter" connector0 in breadboard but connector2 in schematic and pcb
connector1 is description "Base" connector1 in breadboard and pcb but connector0 in schematic
connector2 is description "Collector" connector2 in breadboard connector1 in schematic and connector0 in pcb
Fritzing\fritzing-parts\core\transistor_signal_NPN_TO92_ECB.fzp
<schematicView fliphorizontal="true" flipvertical="true">
<layers image="schematic/basic_transistor_npn.svg">
...
<connectors>
<connector id="connector0" name="E" type="male">
<description>Emitter</description>
<views>
<breadboardView>
<p layer="breadboard" svgId="connector0pin" legId="connector0leg"/>
</breadboardView>
<schematicView>
<p layer="schematic" svgId="connector2pin" terminalId="connector2terminal"/>
</schematicView>
<pcbView>
<p layer="copper0" svgId="connector2pin"/>
<p layer="copper1" svgId="connector2pin"/></pcbView>
</views>
</connector>
<connector id="connector1" name="B" type="male">
<description>Base</description>
<views>
<breadboardView>
<p layer="breadboard" svgId="connector2pin" legId="connector2leg"/>
</breadboardView>
<schematicView>
<p layer="schematic" svgId="connector0pin" terminalId="connector0terminal"/>
</schematicView>
<pcbView>
<p layer="copper0" svgId="connector0pin"/>
<p layer="copper1" svgId="connector0pin"/></pcbView>
</views>
</connector>
<connector id="connector2" name="C" type="male">
<description>Collector</description>
<views>
<breadboardView>
<p layer="breadboard" svgId="connector1pin" legId="connector1leg"/>
</breadboardView>
<schematicView>
<p layer="schematic" svgId="connector1pin" terminalId="connector1terminal"/>
</schematicView>
<pcbView>
<p layer="copper0" svgId="connector1pin"/>
<p layer="copper1" svgId="connector1pin"/></pcbView>
</views>
</connector>
</connectors>
Here connector0 is description "Emitter" connector0 in breadboard but connector2 in schematic and pcb
connector1 is description "Base" connector2 in breadboard but connector0 in schematic and pcb
connector2 is description "Collector" connector1 in breadboard schematic and pcb
I think there is also another layout CEB that I made a part for, for someone who had a transistor with that layout that didn't exist in Fritzing. I would like to settle on a method that doesn't mix connector numbers in the fzp (i.e. all the connectors are the same connector number as the connector associated with the description field if we can.) as being more readable and maintainable at the cost of more svg files. I think that is a cost worth paying to avoid the current complexity which I think is causing problems!
How about adding / promoting a history tag? This would attribute to the fact that many Fritzing parts are handled outside of git. See for the example my v2 of the Arduino Giga in the Forum. There I added
<history date="Jul 23 2023" author="Peter Van Epp">First version</history>
<history date="Jul 27 2023" author="Kjell Morgenstern">Added PCB Footprint. Minor adjustments and mounting holes in Breadboard. </history>
This doesn't do any harm for current and probably even older releases of Fritzing.
Future versions could even be aware of it, display it in the Inspector.
Further, we could use the <title>
or an additional identifier in the history, so that Fritzing could even list or suggest alternative versions of the part.
How about adding / promoting a history tag?
I am fine with that. It will make it easier to decide what to do when you modify a part. Currently, some of use are expanding the author field: e.g.: <author>Andres Faina (modified by vanepp Nov 2020)</author>
This thread is getting very long and as we are planning to add some parts to the core soon (new Arduino boards), it makes sense to settle on some guidelines to homogenize the parts. I took the liberty to resume the main points discussed and the proposal when we agree or the different alternatives when we have not reached a consensus. @vanepp and @mMerlin could you check if I missed anything or you want to discuss something more? @KjellMorgenstern , could you check if you agree and take a decision for the ones without a consensus? It would be great to write these down on the wiki.
<history date="Jul 23 2023" author="Peter Van Epp">First version</history>
<history date="Jul 27 2023" author="Kjell Morgenstern">Added PCB Footprint. Minor adjustments and mounting holes in Breadboard. </history>
date="Jul 23 2023"
This avoids confusion between American (MM/DD/YYYY) and European (DD/MM/YYYY) formats.drag = "accept,connect" accept="male,passthrough" connect="female,passthrough"
see https://github.com/fritzing/fritzing-parts/issues/369#issuecomment-1528075070Thanks a lot for the summary.
I have an objection about the date format.
Date format: If we want a machine-readable (and unambiguous) date time format, there is a standard for that, ISO 8601. This easily avoids entangling the fzp format with some custom date-time parser. The alternative would be to leave it as is, a free text field.
Maybe these two points can get a check mark?
Unique pin names: I think we have many parts with duplicate Pin names like "GND". I am not aware of any problem, we have the connector id to tell them apart.
Permanent display of pin numbers:
The way the display on hover currently works is not sufficient. I think this is more an implementation problem.
What could help in the part format is to associate the pin labels with their connectors:
Example : <text id="connector0name"> GND </text>
Future versions of Fritzing then could
And of course for very basic cases, like resistors, we can remove the "1" and "2" pin labels. But even for a switch with four connectors, I would be careful about this.
This thread is bouncing back and forth between policy / documentation for creating parts using the current code, and changes to the code to allow creating better parts.
Having a programming background, I much prefer the ISO 8601 yyyy-mm-dd format. It is usually unambiguous, and easy to process. Another problem with the mmm dd yyyy format, is the language of the person creating the part. I have seen parts where the "mmm" abbreviation is not English. Without knowing the language, I can not tell which month is intended. Straight numeric dates do not have that problem. Even as free form text, we could recommend using (or including) yyyymmdd numeric formats.
The version field is used by Fritzing code to properly handle parts that were created before certain code changes, so that the older parts still work the same.
Taxonomy information would be good.
The connector type additions are likely 'wish list'. I expect the code would need some significant changes to implement any version of that. That could also overlap with having a 'sticky' flag, so that stacked parts stay connected when the bottom part is moved.
Pin organization: My preference is for logical grouping, as I think the whole schematic is a logic view. There are enough others that want to it to match the physical view though, that 'standardizing' on one or the other might not be the best idea. It should be possible to let the use pick the style using a 'schematic style' tag that parts inspector can use to pick the graphic to use. Currently that would require duplicate parts, with only the schematic svg being different. Another code enhancement would be to expand the xxxView information in the fzp file, to allow selection of different image files based on user specified (Inspector) tag values. To go with that, add to user preferences the default selection values.
<schematicView>
<layers image="schematic/part-specification-logical.svg" viewmode="logical">
<layers image="schematic/part-specification-physical.svg" viewmode="physical">
</schematicView>
That would still need the extra image file, but not a full part. The same logic would allow selecting alternate footprints for pcb view.
I suspect that the preference here is based on how people learned electronics. I learned theory first, from reading and looking at schematics. People that learned by building physical projects first are more likely to want the schematic to match the physical parts. That's my guess.
Proper icons are already 'possible', if parts creators want to take the time to create them. Reusing the breadboard svg is just a simplification for those that do not want to take the time.
I am not aware of any problems with duplicate pin names either, for regular active parts. Some of the "options" that can be used when obsoleting and replacing parts, to map pins from the old part to the new part, can have issues. Both the pin name and connector id can be used in the mapping. Problems would occur if a non unique pin name was used. Duplicate pin names like "GND" are useful. I think what is needed (short term) is to update the documentation, to remove the unique pin names requirement, and add to the obsolete tag information to say that the pin name can only be used if it is unique. Scripts to check for that, and reject the obsoleting fzp if a non-unique pin name was used in the mapping.
An enhancement to that, would be to have a 'name' associated with any bus, then use that for the connectors in the bus group. The bus id could be used for that. Just leaving the name="xx" out of the connector definition would let it default to the bus.
Given the minimal nature of the bus data, it could be completely removed by adding an optional 'bus="bus-id"' attribute to the connector definition. Or even use the existing connector name as a bus id. All connectors with the same name would be on the same bus. Special case: Multiple "N/C" pins should not be a bus.
permanent pin number display. Any change that would allow the user to show or hide the pin numbers would require changes to the part svg file(s). If the names in the fzp file are incorrect, or incomplete, they would need to be updated at the same time. I do not see that as a particular problem. It just means that the process defined for making the svg changes needs to include a step to verify/update the fzp as well. Multiple fzp files if the svg is shared among parts.
Removing hard coded pin numbers from the svg file also allows more reuse. Transistor is a simple example where both cbe and bce use the same schematic symbol, but the pin numbers are different.
Updated version, documentation, and policy changes separated from code changes. Please, check the changes and state if you agree/disagree.
<history date="2023-07-23" author="Peter Van Epp">First version</history>
<history date="2023-07-27" author="Kjell Morgenstern">Added PCB Footprint. Minor adjustments and mounting holes in Breadboard. </history>
drag = "accept,connect" accept="male,passthrough" connect="female,passthrough"
see https://github.com/fritzing/fritzing-parts/issues/369#issuecomment-1528075070Some comments:
I suspect that the preference here is based on how people learned electronics. I learned theory first, from reading and looking at schematics. People that learned by building physical projects first are more likely to want the schematic to match the physical parts. That's my guess.
Probably you are right, but I see Fritzing as a tool for learning and I think the sch view should keep the standard way of drawing schematics. If not, the SCH view will look very similar to the BB view. I think that the core parts should be organized logically to force beginners to be exposed to "normal" schematics. This should also be complemented with improving the examples https://github.com/fritzing/fritzing-app/issues/3962
The version field is used by Fritzing code to properly handle parts that were created before certain code changes, so that the older parts still work the same.
There are two version fields, the "version" and the "fritzingVersion". E.g: <version>4</version>
and <module moduleId="DCPulseSourceModuleID" fritzingVersion="0.9.10">
Most of the parts have version 4, but I have made parts with version set to 1 and I have not experienced problems. @KjellMorgenstern , could you check if the version field is used for anything? To me seems that the fritzingVersion field could be enough to trigger specific code if necessary.
fritzingVersion The fritzingVersion should always be there, and I really recommend to keep it in sync with the Fritzing version that the part was originally tested against. This will allow us to migrate parts for future changes. A similar thing applies for projects. For example in Fritzing 1.0.0 we fixed a bug that labels were cut off in certain cases. The fix required us to move the bounding box of these. We only migrate these bounding boxes in projects that are Fritzing < 1.0.0 .
version and moduleId
The part version is currently not used to my knowledge. I think
Before Fritzing 1.0.0, the version was shown right of the icons in the Inspector. I have moved it to the end, after the tags section, to make space for bigger icons. Old: Fritzing 1.0.0:
@KjellMorgenstern :
Unique pin names: I think we have many parts with duplicate Pin names like "GND". I am not aware of any problem, we have the connector id to tell them apart.
The part file format specifies they should be unique. I think @mMerlin found that sometimes (but very rarely) they get used to differentiate parts. I too have never seen a problem with dup pins (that test in fact used to be disabled in FritzingCheckPart but I re enabled it after he found that so now it complains!) So we probably need to check that out to make sure it isn't going to be a problem (and perhaps changes to code to make it not a problem?), otherwise I agree common pin names are often useful (i.e. GND is better as always GND in my view!)
@KjellMorgenstern :
version and moduleId The part version is currently not used to my knowledge. I think tags would be much better versioning for parts. Requires code change: During developing and testing new parts, it can get quite messy when you have multiple variants of the part, and few people use git for this. Code support required: A version attribute in the history tag could help to identify intermediate versions of a part, and Fritzing could combine it with the moduleId. So the moduleId would be kind of a main version, that defined the part. And the history tags would be subversions. Instead of random changes and adding hashes to the moduleId, the history tag would be updated, which I imagine is a more natural and intuitive workflow.
I agree, this would be a much better idea and I would like to see it implemented!
@failiz :
Probably you are right, but I see Fritzing as a tool for learning and I think the sch view should keep the standard way of drawing schematics.
I just realized there is another reason why I prefer to do it this way (although that isn't a reason for not changing to this model!): it makes making schematics with Randy's Inkscape extension easier. Being identical to breadboard makes the pin number layout in the extension easier. All that means is we would need to change the extension somehow to make the new format better match the way the extension wants the pin numbers arranged (or use the specify pin numbers option) which should be possible I think.
@failiz :
There are two version fields, the "version" and the "fritzingVersion". E.g:
4 andMost of the parts have version 4, but I have made parts with version set to 1 and I have not experienced problems.
I agree, I think most parts are set to version 4 just because they started as version 4 and no one changes them (I am not aware of any documentation that talks about this which is probably why!) I make new parts version 1 but eliminating this field and using the history tags to me makes much more sense. I think the source usually uses the fritzingVersion when deciding if a part needs modifying, but there may be some cases that use the version too.
Updated version, with changes in fritzingVersion, version field, ModuleID and Implement tags. Please, check the changes and state if you agree/disagree. We are moving forward. @KjellMorgenstern , what about the referenceFile field and the file name conventions?
<history date="2023-07-23" author="Peter Van Epp">First version</history>
<history date="2023-07-27" author="Kjell Morgenstern">Added PCB Footprint. Minor adjustments and mounting holes in Breadboard. </history>
drag = "accept,connect" accept="male,passthrough" connect="female,passthrough"
see https://github.com/fritzing/fritzing-parts/issues/369#issuecomment-1528075070[ ] Show history of the part: I do not think this is really necessary and will make the inspector pane more difficult to navigate.
Edit: Added utf-8 suggestion
the part file format specifies they should be unique. I think @mMerlin found that sometimes (but very rarely) they get used to differentiate parts. I too have never seen a problem with dup pins (that test in fact used to be disabled in FritzingCheckPart but I re enabled it after he found that so now it complains!) So we probably need to check that out to make sure it isn't going to be a problem (and perhaps changes to code to make it not a problem?), otherwise I agree common pin names are often useful (i.e. GND is better as always GND in my view!)
I think that the only problem arises when the obsolete mechanism is employed and the ids do not match. From the wiki: "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'>
"
As soon the connectorIDs are unique and the parts have the same connectors, the name of the connector does not matter. I think for now we can create parts with non-unique names. We could also add a check in the code. If the obsolete mechanism uses the name of a connector, check that name is unique. If not, stop the process, give a warning, and ask the user to manually replace the old part for the new one.
… [ ] ModuleID Do not add a unique identifier (hash) in the moduleID. If necessary, add a version number in the moduleID to make it unique. In the future, the moduleID will be combined with tags or versions of the part to handle the different versions, see below. … [ ] Implement tags and combine moduleID to provide unique identifiers: During developing and testing new parts, it can get quite messy when you have multiple variants of the part, and few people use git for this. Code support required: A version attribute in the history tag could help to identify intermediate versions of a part, and Fritzing could combine it with the moduleId. So the moduleId would be kind of a main version, that defined the part. And the history tags would be subversions. Instead of random changes and adding hashes to the moduleId, the history tag would be updated, which I imagine is a more natural and intuitive workflow.
The module ID needs to be 'globally' unique when parts are shared. Using the version related tags to attempt to make the module id unique will fail in this scenario. … Two different people take a copy of the same part to make changes. They both increment the version number. Now the 2 different modifications will have the same (combined) module id. If really need to do this style, at least include the date in the unique key.
It is much 'safer' to create a new module id guid each time. The version information is good to have as well, but it is bad to rely on that to create a unique module id. It is generally bad (programming) practice to reuse data for 2 different purposes. Information for the user, and creating a unique id. That is a variation of have 'meaning' built into a unique identifier.
The module ID needs to be 'globally' unique when parts are shared. Using the version related tags to attempt to make the module id unique will fail in this scenario. … Two different people take a copy of the same part to make changes. They both increment the version number. Now the 2 different modifications will have the same (combined) module id. If really need to do this style, at least include the date in the unique key.
It is much 'safer' to create a new module id guid each time. The version information is good to have as well, but it is bad to rely on that to create a unique module id. It is generally bad (programming) practice to reuse data for 2 different purposes. Information for the user, and creating a unique id. That is a variation of have 'meaning' built into a unique identifier.
Yes, it can fail in that case. What about creating a unique identifier based on the contents of the fpz file? We keep the module_id for the part and then a unique identifier is automatically generated by creating a string variable with the contents of the fpz file, removing the spaces and format characters (such as return carriages and end of lines) and then creating a hash based on that string. Thus, if there is a new version of the part, a new unique id is automatically generated and we do not depend on the user to remember to generate an unique id. As soon as there is a change in the file, a new id is generated.
We could even include the svgs in the string used to generate the hash, if necessary.
mMerlin is right, allowing ModuleID + a version is asking for collisions, especially if the version is just a single digit.
Also, I agree with mMerlin about not having multiple concerns in one data field. The ModuleID already determines the behavior, is human readable (describing the part), and serves as ID. That already happened, and we can only avoid making it worse.
And there are other (more severe and likely) collisions, like, the filenames in fzpz.
Technically, Fritzing could (and probably should) create a directory for each imported fzpz, that has some auto generated md5 substring, store all related files there, and use the directory name for internal references.
A hash on the content sounds a bit like what git is doing. A good way to have the part mostly free of collisions is to just add it to this fritzing-parts repo.
Probably, other mechanisms are not very useful until they are in some way backed up by the fritzing-app?
Sticking to what version 1.0.0 is capable of: The ModuleID needs to be unique. Possibly add the part to this fritzing-parts repo. There are no other safety nets.
Now, the recommendation could be: Add a 7 digit alphanumeric prefix to the Module id. Add the same 7 digit alphanumeric as a suffix to the fzp and the svg files. I am not sure about this recommendation, because it would be hard to follow (updating the id and renaming all the files all time is horribly error-prone, and feels kind of dump). Again, the Fritzing implementation side is needed to fix this, for example my above suggestion, to let fritzing create a subfolder for each fzpz. Or simply keep the fzpz sitting there, unzip on the fly.
Using UTF-8: In 2008, it seems it was decided to not use UTF-8: https://github.com/fritzing/fritzing-app/issues/431 The reasoning behind this is not available, and from nowadays perspective, it looks quite odd to me. I have seen some parts with broken encodings recently, which could have been avoided by using utf-8.
I think that decision can be thrown over in favor of UTF-8.
A quick look into fritzing-parts show that it is not yet widespread, but already in use: 10:22 $ python utf8stats.py Statistics for fzp files: Encoding: ascii, Count: 1872 Encoding: Windows-1252, Count: 80 Encoding: utf-8, Count: 154 Encoding: ISO-8859-1, Count: 56
Statistics for svg files: Encoding: ascii, Count: 7547 Encoding: Windows-1252, Count: 6 Encoding: ISO-8859-1, Count: 6 Encoding: utf-8, Count: 5
@KjellMorgenstern
Using UTF-8: In 2008, it seems it was decided to not use UTF-8: https://github.com/fritzing/fritzing-app/issues/431 The reasoning behind this is not available, and from nowadays perspective, it looks quite odd to me. I have seen some parts with broken encodings recently, which could have been avoided by using utf-8.
While allowing (or requiring) UTF-8 in parts seems sensible, I worry that it will break something not necessarily obvious. I have concern that they had a good (if as usual not documented) reason for not doing UTF-8 in parts that may or may not still hold true. It may be the only way forward it try it and see if anything breaks though.
Qt internally used UTF-16, and switched to UTF-8 as default with Qt6. ASCII is a subset of UTF-8, so no problems here, ASCII would still be allowed. I guess issues appear with formats like Windows-1252 , ISO-8859-1 and many others. The utf8stats.py script could be extended to warn about these in our CI pipeline
I looked a bit closer at those ISO-8859 and Windows-1252 files, and it turns out that they are UTF-8. The detector (chardet) uses heuristics that don't fit well for our FZP and SVG files. Often it is just a single Ω or é , and the rest is ASCII. I have replaced the detector with another one, and now everying is either UTF-8 or ASCII. I also added a highlight to the script that show every non ascii char. I turned the script into a github action check, so it would error if a part is clearly not UTF-8.
On the taxonomy of the "family" property. The family property is used by Fritzing to enable swapping parts.
For example, a 4001 can be swapped with a 4011 logic IC. Or a THT resistor can be swapped with a SMD version.
The is possible even when the part is already wired and routed in the circuit. Fritzing will do its best to rewire the part. For this to make sense, swapping of parts should make sense. For example parts with Arduino UNO layout could also be in the same family. But a Arduino UNO and a Arduino MEGA would not be the same. The later case is somewhat a grey area, since a UNO can be replaced with a MEGA in many cases.
But for example, when I created the Sony Spresense parts, I put them all in the same family, which is not correct. It does not make sense to swap the camera board with the main board, or the extension board.
I'd suggest these rule of thumb:
Related articles:
https://forum.fritzing.org/t/part-creation-howto-part6-family-and-variant-howto/7917
https://github.com/fritzing/fritzing-app/wiki/2.1-Part-file-format
Terminal IDs and rectangles should become fully optional. Defaults that work in almost every case can be used. See https://github.com/fritzing/fritzing-app/issues/4130 .
The rule of thumb looks good. The details of what 'act as replacements' needs expansion.
That description of swapping and family property is based on being able to do physical 'drop in' replacements. To decide what 'makes sense' to be able to swap, and thus what can (should) be in the same family, requires defining the constraints on what can and cannot change. What are practical 'replacements for each other'?
The phycial footprint? In all views? That would actually not allow most THT to SMB swaps. The SMD version is smaller. The available (used) connectors? A Raspberry Pi could be swapped with a computer module, An UNO could be swapped to a MEGA, but only back if none of the extra pins are in use. Functional? Replace an Arduino board with an ESP. The pin numbers might change, but they both have somewhat standard UART, SPI, I2C 'functions'.
Depending what stage a project is at, any of those are 'reasonable'. In the early stages, much more drastic changes are reasonble. But auto rewiring not so much.
Fritzing can obviously not handle all of the scenarios a user might conceivable want. Especially with automatic rewiring. That is only practical if the physical/logical footprints in each view are the same. Or at least very close.
Bring into this mix, the parts that use a DIP compatible carrier board for breadboard view but SMD footprint on PCB. Do you want to be able to swap back and forth one of those with a DIP package for both? Logically they are identical, but both breadboard and PCB footprint could change. Another case would be a standard rPi in breadboard, but a compute module for PCB.
The way that swapping currently works, changing from one part to another within a family is done by changing a property value in inspector. That means that parts in a family must also have other common properties with different values. Changing a property value is what actually initiates a swap. So any consideration of what belongs together in a family needs to include properties. For assembly parts, those property changes can break some of the other features that make rewiring practical. A simple example is an Arduino board with or without some of the extra headers. Like ICSP. For some of the factory parts, like headers, that can be drastic change. Number of pins, number of rows, spacing.
Another problematic swap is breadboards. Those have widely different numbers of pins and bus lines. With no consistent ordering to make automatic re-conection easy. The spacing is the same, so visually it looks trivial. Other than the sometimes .05in offset for the bus lines. However programmatic identification of matching connectors is not easy. The connectors do not have enough geometry information about what are the neighbouring pins.
So some thought is needed to decide what are reasonable 'replacements' that should have the same family property. That could vary depending on the 'type' of part. Discrete components (IC and smaller) could have a lot tighter constraints than assemblies.
For your Spresense case, tags probably make more sense than a single family or even other properties. Another area that could use some consistent taxonomy, to help categorize, and search for, part files.
This is a continuation (with a better topic name) from #367 . The intent is to modify and possibly write new standards for parts. We have the part file format document
https://github.com/fritzing/fritzing-app/wiki/2.1-Part-file-format
and the graphics standards
https://fritzing.org/fritzings-graphic-standards
both of which may need updates as part of this discussion, but which provide the basis for this discussion.
@KjellMorgenstern @mMerlin @failiz where suggested in #367 as people who need to be involved, but I expect anyone else that is interested should also be welcome to join in.
My broad outline is to get a parts policy in place that allows automated checking of parts and consistency of parts (at least those included in core parts) so schematic as one instance looks the same and interoperates well with other parts. The longer term goal is, once a policy is in place, to start a project to update the parts in core parts to meet the new standard. (that is likely to be a lot of work, but requires the policy to be in place to allow it!) That would also allow the automated checking of parts that are submitted to core parts to make sure they meet the standards. However it leaves the user able to create custom parts that don't meet the standards (either due to time constraints or lack of need of some views) for their personal use which has been one objection raised in past discussions on this topic. Another topic is the layout of the repository as discussed in #4018 . Documenting the format of the .fzpz file and its association / conversion to the repository format should be done. I am not aware of any documentation on the format of the .fzpz file existing (pointers to anything I have missed are welcome!) Documentation on each field in the fzp file would be useful. For instance the version field is often set to 4 where I think it should start at 1 for a new part and increase by one for each new version of the part. My update to the obsolete.py script available in #347 addresses that by setting the version field to 1 if there isn't one already or increasing the current version field by 1 if there is one.. Issue #365 to standardize the parts labels (which affects the label field in the fzp file) also enters in to this discussion as I think it is desirable to standardize the label field in parts. File name conventions for fzp and svg files are also an issue that needs to come up. I would prefer that the version number appear in the files so for the first version of the part the fzp and svg files end in _1 such as part.fc-51_1.fzp for the first version of a part. One question would be is there a need to add a guid field (a globally unique identifier) to the file name as parts editor currently does when editing parts? As noted I think we need to update the part file format document to specify all the fields in a fzp file along with their suggested initial value and what they relate to in other files. As an example
The layerId field here needs to match the group id (in both case and spelling) in the svg file specified in the image file a couple of lines above it. Documenting the special case properties and what they do would be good. An example is all the special formats for a breadboard such as
where the trailing ModuleID in the moduleId field suppresses rotation by 45degrees in a breadboard
the family needs to be Breadboard with the size property selecting between the possibilities (and that the combination of family and size need to be unique!)
and the breadboard layerId "breadboardbreaddboard" trips special code that allows the part to move down to the same level as the breadboards. This is used by the Arduinos for instance (which are otherwise not a breadboard) I think to allow shields to be mounted above them. That will probably do to start this discussion rolling I hope!