diff --git a/diylc/catalog_full.json b/diylc/catalog_full.json index cbd0396c..cb9c9320 100644 --- a/diylc/catalog_full.json +++ b/diylc/catalog_full.json @@ -1,5 +1,5 @@ { - "version" : "6.9.0", + "version" : "6.10.0", "components" : [ { "name" : "Blank Board", "className" : "boards.BlankBoard", @@ -17332,7 +17332,8 @@ "namePrefix" : "Q", "description" : "Transistor with small metal body", "creationMethod" : "SINGLE_CLICK", - "notes" : [ "The first control point is the anchor; with 'Orientation' DEFAULT the third pin is 2 x 'Pin spacing' below it and the middle pin 'Pin spacing' below and 'Pin spacing' to the left, a triangle under the round can. 'Folded' puts the three pins in a straight line down from the anchor and lays the body flat on the right of them. The other orientations rotate this around the anchor", "On a 0.1in grid board the default 0.05in 'Pin spacing' puts the middle pin between holes: set 'Pin spacing' to 0.1in to land all three pins on holes" ], + "notes" : [ "The first control point is the anchor; with 'Orientation' DEFAULT the third pin is 2 x 'Pin spacing' below it and the middle pin 'Pin spacing' below and 'Pin spacing' to the left, a triangle under the round can. 'Folded' puts the three pins in a straight line down from the anchor and lays the body flat on the right of them. The other orientations rotate this around the anchor", "On a 0.1in grid board the default 0.05in 'Pin spacing' puts the middle pin between holes: set 'Pin spacing' to 0.1in to land all three pins on holes", "'Pinout' values list pins 1, 2, 3 in control point order. Seen from above, a metal can's leads run counter-clockwise from the tab, which sits beside pin 1; most parts, silicon TO-18/TO-39 and germanium alike, are E-B-C" ], + "datasheetModels" : [ "BC107", "BC108", "BC109", "2N2222A", "2N2369A", "2N2219A", "2N1613", "2N1711", "2N3053", "2N3866", "BFY51", "BC177", "BC178", "BC179", "2N2907A", "2N2905A", "AC127", "AC176", "AC187", "2N1308", "AC126", "AC128", "AC188", "OC44", "OC45", "OC71", "OC75", "OC76", "OC81", "2N404", "2N1305" ], "properties" : [ { "name" : "Alpha", "type" : "Percentage", @@ -17382,7 +17383,7 @@ }, { "name" : "Pinout", "type" : "TransistorPinout", - "possibleValues" : [ "BJT_EBC", "BJT_CBE", "BJT_BCE", "BJT_ECB", "JFET_DSG", "JFET_GSD", "JFET_DGS", "JFET_SGD", "JFET_GDS", "MOSFET_DSG", "MOSFET_GSD", "MOSFET_DGS", "MOSFET_SGD", "MOSFET_GDS", "REGULATOR_IGO", "REGULATOR_OGI", "REGULATOR_GOI", "REGULATOR_AOI", "REGULATOR_GIO" ] + "possibleValues" : [ "BJT_EBC", "BJT_CBE", "BJT_BCE", "BJT_ECB", "BJT_BEC", "BJT_CEB", "JFET_DSG", "JFET_GSD", "JFET_DGS", "JFET_SGD", "JFET_GDS", "JFET_SDG", "MOSFET_DSG", "MOSFET_GSD", "MOSFET_DGS", "MOSFET_SGD", "MOSFET_GDS", "REGULATOR_IGO", "REGULATOR_OGI", "REGULATOR_GOI", "REGULATOR_AOI", "REGULATOR_AIO", "REGULATOR_IOG", "REGULATOR_IOA", "REGULATOR_GIO" ] }, { "name" : "Value", "type" : "String" @@ -17445,6 +17446,34 @@ "i" : 2, "label" : "B" } ] + }, { + "when" : { + "Pinout" : "BJT_BEC" + }, + "pins" : [ { + "i" : 0, + "label" : "B" + }, { + "i" : 1, + "label" : "E" + }, { + "i" : 2, + "label" : "C" + } ] + }, { + "when" : { + "Pinout" : "BJT_CEB" + }, + "pins" : [ { + "i" : 0, + "label" : "C" + }, { + "i" : 1, + "label" : "E" + }, { + "i" : 2, + "label" : "B" + } ] }, { "when" : { "Pinout" : "JFET_DSG" @@ -17515,6 +17544,20 @@ "i" : 2, "label" : "S" } ] + }, { + "when" : { + "Pinout" : "JFET_SDG" + }, + "pins" : [ { + "i" : 0, + "label" : "S" + }, { + "i" : 1, + "label" : "D" + }, { + "i" : 2, + "label" : "G" + } ] }, { "when" : { "Pinout" : "MOSFET_DSG" @@ -17641,6 +17684,48 @@ "i" : 2, "label" : "I" } ] + }, { + "when" : { + "Pinout" : "REGULATOR_AIO" + }, + "pins" : [ { + "i" : 0, + "label" : "A" + }, { + "i" : 1, + "label" : "I" + }, { + "i" : 2, + "label" : "O" + } ] + }, { + "when" : { + "Pinout" : "REGULATOR_IOG" + }, + "pins" : [ { + "i" : 0, + "label" : "I" + }, { + "i" : 1, + "label" : "O" + }, { + "i" : 2, + "label" : "G" + } ] + }, { + "when" : { + "Pinout" : "REGULATOR_IOA" + }, + "pins" : [ { + "i" : 0, + "label" : "I" + }, { + "i" : 1, + "label" : "O" + }, { + "i" : 2, + "label" : "A" + } ] }, { "when" : { "Pinout" : "REGULATOR_GIO" @@ -17664,6 +17749,8 @@ "namePrefix" : "Q", "description" : "Transistors with a hole for heat sink mounting", "creationMethod" : "SINGLE_CLICK", + "notes" : [ "The first control point is the anchor and pin 1; with 'Orientation' DEFAULT the three pins run straight down from it 0.1in apart, and the other orientations rotate this around the anchor", "'Pinout' values list the pins as a datasheet does, facing the printed front with the metal back away and the legs down, left to right; BD139-style parts are E-C-B" ], + "datasheetModels" : [ "BD135", "BD137", "BD139", "BD237", "MJE340", "MJE180", "2SC3423", "KSC3503", "2SD669A", "BF469", "BD136", "BD138", "BD140", "BD238", "MJE350", "MJE170", "2SA1360", "KSA1381", "2SB649A", "BF470", "BD681", "BD682" ], "properties" : [ { "name" : "Alpha", "type" : "Percentage", @@ -17713,7 +17800,7 @@ }, { "name" : "Pinout", "type" : "TransistorPinout", - "possibleValues" : [ "BJT_EBC", "BJT_CBE", "BJT_BCE", "BJT_ECB", "JFET_DSG", "JFET_GSD", "JFET_DGS", "JFET_SGD", "JFET_GDS", "MOSFET_DSG", "MOSFET_GSD", "MOSFET_DGS", "MOSFET_SGD", "MOSFET_GDS", "REGULATOR_IGO", "REGULATOR_OGI", "REGULATOR_GOI", "REGULATOR_AOI", "REGULATOR_GIO" ] + "possibleValues" : [ "BJT_EBC", "BJT_CBE", "BJT_BCE", "BJT_ECB", "BJT_BEC", "BJT_CEB", "JFET_DSG", "JFET_GSD", "JFET_DGS", "JFET_SGD", "JFET_GDS", "JFET_SDG", "MOSFET_DSG", "MOSFET_GSD", "MOSFET_DGS", "MOSFET_SGD", "MOSFET_GDS", "REGULATOR_IGO", "REGULATOR_OGI", "REGULATOR_GOI", "REGULATOR_AOI", "REGULATOR_AIO", "REGULATOR_IOG", "REGULATOR_IOA", "REGULATOR_GIO" ] }, { "name" : "Value", "type" : "String" @@ -17776,6 +17863,34 @@ "i" : 2, "label" : "B" } ] + }, { + "when" : { + "Pinout" : "BJT_BEC" + }, + "pins" : [ { + "i" : 0, + "label" : "B" + }, { + "i" : 1, + "label" : "E" + }, { + "i" : 2, + "label" : "C" + } ] + }, { + "when" : { + "Pinout" : "BJT_CEB" + }, + "pins" : [ { + "i" : 0, + "label" : "C" + }, { + "i" : 1, + "label" : "E" + }, { + "i" : 2, + "label" : "B" + } ] }, { "when" : { "Pinout" : "JFET_DSG" @@ -17846,6 +17961,20 @@ "i" : 2, "label" : "S" } ] + }, { + "when" : { + "Pinout" : "JFET_SDG" + }, + "pins" : [ { + "i" : 0, + "label" : "S" + }, { + "i" : 1, + "label" : "D" + }, { + "i" : 2, + "label" : "G" + } ] }, { "when" : { "Pinout" : "MOSFET_DSG" @@ -17972,6 +18101,48 @@ "i" : 2, "label" : "I" } ] + }, { + "when" : { + "Pinout" : "REGULATOR_AIO" + }, + "pins" : [ { + "i" : 0, + "label" : "A" + }, { + "i" : 1, + "label" : "I" + }, { + "i" : 2, + "label" : "O" + } ] + }, { + "when" : { + "Pinout" : "REGULATOR_IOG" + }, + "pins" : [ { + "i" : 0, + "label" : "I" + }, { + "i" : 1, + "label" : "O" + }, { + "i" : 2, + "label" : "G" + } ] + }, { + "when" : { + "Pinout" : "REGULATOR_IOA" + }, + "pins" : [ { + "i" : 0, + "label" : "I" + }, { + "i" : 1, + "label" : "O" + }, { + "i" : 2, + "label" : "A" + } ] }, { "when" : { "Pinout" : "REGULATOR_GIO" @@ -17996,6 +18167,7 @@ "description" : "Transistors with metal tab for heat sink mounting", "creationMethod" : "SINGLE_CLICK", "notes" : [ "The first control point is the anchor; with 'Orientation' DEFAULT the three pins run straight down from it 0.1in apart, and the other orientations rotate this around the anchor", "Seen from above, the metal tab is on the right of the pin row in DEFAULT orientation and the printed front faces left; 'Folded' lays the body flat on the right of the pin row, 'Lead Length' away from it, with the tab and its mounting hole at the far end", "'Pinout' values list the pins as a datasheet does, facing the printed front with the legs down, left to right; pick the value that matches the part's datasheet as written" ], + "datasheetModels" : [ "TIP29C", "TIP31C", "TIP41C", "MJE3055T", "MJE15028", "MJE15030", "MJE15032", "BD243C", "BD911", "TIP30C", "TIP32C", "TIP42C", "MJE2955T", "MJE15029", "MJE15031", "MJE15033", "BD244C", "BD912", "TIP120", "TIP121", "TIP122", "TIP125", "TIP126", "TIP127", "IRF510", "IRF520", "IRF530", "IRF540N", "IRF610", "IRF640", "IRF840", "IRFZ44N", "IRLZ44N", "IRF3205", "FQP30N06L", "IRF9530", "IRF9540N", "IRF9610", "IRF9640", "7805", "7806", "7808", "7809", "7812", "7815", "7818", "7824", "LM317T", "LM338T", "LM350T", "LM1084-ADJ", "LM1085-ADJ", "LM1086-ADJ", "LM1086-3.3", "LM1086-5.0", "LM1117T-ADJ", "LM1117T-3.3", "LM1117T-5.0", "LD1117V", "LD1117V33", "LD1117V50", "LM2940CT-5.0", "LM2940CT-12", "7905", "7912", "7915", "LM337T" ], "properties" : [ { "name" : "Alpha", "type" : "Percentage", @@ -18045,7 +18217,7 @@ }, { "name" : "Pinout", "type" : "TransistorPinout", - "possibleValues" : [ "BJT_EBC", "BJT_CBE", "BJT_BCE", "BJT_ECB", "JFET_DSG", "JFET_GSD", "JFET_DGS", "JFET_SGD", "JFET_GDS", "MOSFET_DSG", "MOSFET_GSD", "MOSFET_DGS", "MOSFET_SGD", "MOSFET_GDS", "REGULATOR_IGO", "REGULATOR_OGI", "REGULATOR_GOI", "REGULATOR_AOI", "REGULATOR_GIO" ] + "possibleValues" : [ "BJT_EBC", "BJT_CBE", "BJT_BCE", "BJT_ECB", "BJT_BEC", "BJT_CEB", "JFET_DSG", "JFET_GSD", "JFET_DGS", "JFET_SGD", "JFET_GDS", "JFET_SDG", "MOSFET_DSG", "MOSFET_GSD", "MOSFET_DGS", "MOSFET_SGD", "MOSFET_GDS", "REGULATOR_IGO", "REGULATOR_OGI", "REGULATOR_GOI", "REGULATOR_AOI", "REGULATOR_AIO", "REGULATOR_IOG", "REGULATOR_IOA", "REGULATOR_GIO" ] }, { "name" : "Tab", "type" : "Color", @@ -18118,6 +18290,34 @@ "i" : 2, "label" : "B" } ] + }, { + "when" : { + "Pinout" : "BJT_BEC" + }, + "pins" : [ { + "i" : 0, + "label" : "B" + }, { + "i" : 1, + "label" : "E" + }, { + "i" : 2, + "label" : "C" + } ] + }, { + "when" : { + "Pinout" : "BJT_CEB" + }, + "pins" : [ { + "i" : 0, + "label" : "C" + }, { + "i" : 1, + "label" : "E" + }, { + "i" : 2, + "label" : "B" + } ] }, { "when" : { "Pinout" : "JFET_DSG" @@ -18188,6 +18388,20 @@ "i" : 2, "label" : "S" } ] + }, { + "when" : { + "Pinout" : "JFET_SDG" + }, + "pins" : [ { + "i" : 0, + "label" : "S" + }, { + "i" : 1, + "label" : "D" + }, { + "i" : 2, + "label" : "G" + } ] }, { "when" : { "Pinout" : "MOSFET_DSG" @@ -18314,6 +18528,48 @@ "i" : 2, "label" : "I" } ] + }, { + "when" : { + "Pinout" : "REGULATOR_AIO" + }, + "pins" : [ { + "i" : 0, + "label" : "A" + }, { + "i" : 1, + "label" : "I" + }, { + "i" : 2, + "label" : "O" + } ] + }, { + "when" : { + "Pinout" : "REGULATOR_IOG" + }, + "pins" : [ { + "i" : 0, + "label" : "I" + }, { + "i" : 1, + "label" : "O" + }, { + "i" : 2, + "label" : "G" + } ] + }, { + "when" : { + "Pinout" : "REGULATOR_IOA" + }, + "pins" : [ { + "i" : 0, + "label" : "I" + }, { + "i" : 1, + "label" : "O" + }, { + "i" : 2, + "label" : "A" + } ] }, { "when" : { "Pinout" : "REGULATOR_GIO" @@ -18337,6 +18593,8 @@ "namePrefix" : "Q", "description" : "Transistor with large metal body", "creationMethod" : "SINGLE_CLICK", + "notes" : [ "The first control point is pin 1; with 'Orientation' DEFAULT pin 2 is 10.9mm below it and the mounting holes lie left and right of the pins, which sit 1.8mm left of the case centre. The third control point is the case, at the centre of the left mounting hole: connect a wire or solder lug there to reach the collector", "'Pinout' values list pin 1, pin 2, then the case, e.g. B-E-C for a 2N3055 whose case is the collector" ], + "datasheetModels" : [ "2N3055", "2N3442", "2N3773", "MJ15003", "MJ15015", "MJ15022", "MJ15024", "MJ2955", "2N6609", "MJ15004", "MJ15016", "MJ15023", "MJ15025", "MJ11016", "MJ11032", "MJ11015", "MJ11033", "IRF150", "LM317K", "LM338K", "LM350K", "LM309K", "LM323K", "LM340K-5.0", "LM340K-12", "LM340K-15", "LM337K" ], "properties" : [ { "name" : "Alpha", "type" : "Percentage", @@ -18352,67 +18610,11 @@ "type" : "Color", "format" : "hex", "defaultValue" : "#868686" - }, { - "name" : "Display", - "type" : "Display", - "possibleValues" : [ "NAME", "VALUE", "NONE", "BOTH" ], - "defaultValue" : "NAME" - }, { - "name" : "Font Size Override", - "type" : "Integer" - }, { - "name" : "Label", - "type" : "Color", - "format" : "hex", - "defaultValue" : "#000000" - }, { - "name" : "Name", - "type" : "String" - }, { - "name" : "Orientation", - "type" : "Orientation", - "possibleValues" : [ "DEFAULT", "_90", "_180", "_270" ], - "defaultValue" : "DEFAULT" - }, { - "name" : "Value", - "type" : "String" - } ], - "pinout" : { - "pinCount" : 2, - "labels" : "sequential" - } - }, { - "name" : "Transistor (TO-92)", - "className" : "semiconductors.TransistorTO92", - "category" : "Semiconductors", - "namePrefix" : "Q", - "description" : "Transistor with small plastic or epoxy body", - "creationMethod" : "SINGLE_CLICK", - "notes" : [ "The first control point is the anchor; with 'Orientation' DEFAULT the three pins run straight down from it 'Pin spacing' apart, and the other orientations rotate this around the anchor", "Seen from above, the flat face is on the left of the pin row in DEFAULT orientation; 'Folded' lays the body flat on the right of the pin row instead", "'Pinout' values list the pins as a datasheet does, facing the flat side with the legs down, left to right; pick the value that matches the part's datasheet as written", "On a 0.1in grid board the default 0.05in 'Pin spacing' puts the middle pin between holes: set 'Pin spacing' to 0.1in, or use two or three jumpers acting as flexible leads and connecting TO-92 terminals to the holes on the board" ], - "properties" : [ { - "name" : "Alpha", - "type" : "Percentage", - "format" : "number without the % sign, e.g. 100", - "defaultValue" : "100" - }, { - "name" : "Body", - "type" : "Color", - "format" : "hex", - "defaultValue" : "#808080" - }, { - "name" : "Border", - "type" : "Color", - "format" : "hex", - "defaultValue" : "#595959" }, { "name" : "Display", "type" : "TransistorDisplay", "possibleValues" : [ "NAME", "VALUE", "NONE", "BOTH", "PINOUT" ], "defaultValue" : "NAME" - }, { - "name" : "Folded", - "type" : "Boolean", - "defaultValue" : "false" }, { "name" : "Font Size Override", "type" : "Integer" @@ -18429,16 +18631,10 @@ "type" : "Orientation", "possibleValues" : [ "DEFAULT", "_90", "_180", "_270" ], "defaultValue" : "DEFAULT" - }, { - "name" : "Pin spacing", - "type" : "Size", - "format" : "(value)(unit)", - "possibleUnits" : [ "px", "mm", "cm", "m", "in", "ft", "yd" ], - "defaultValue" : "0.05in" }, { "name" : "Pinout", "type" : "TransistorPinout", - "possibleValues" : [ "BJT_EBC", "BJT_CBE", "BJT_BCE", "BJT_ECB", "JFET_DSG", "JFET_GSD", "JFET_DGS", "JFET_SGD", "JFET_GDS", "MOSFET_DSG", "MOSFET_GSD", "MOSFET_DGS", "MOSFET_SGD", "MOSFET_GDS", "REGULATOR_IGO", "REGULATOR_OGI", "REGULATOR_GOI", "REGULATOR_AOI", "REGULATOR_GIO" ] + "possibleValues" : [ "BJT_EBC", "BJT_CBE", "BJT_BCE", "BJT_ECB", "BJT_BEC", "BJT_CEB", "JFET_DSG", "JFET_GSD", "JFET_DGS", "JFET_SGD", "JFET_GDS", "JFET_SDG", "MOSFET_DSG", "MOSFET_GSD", "MOSFET_DGS", "MOSFET_SGD", "MOSFET_GDS", "REGULATOR_IGO", "REGULATOR_OGI", "REGULATOR_GOI", "REGULATOR_AOI", "REGULATOR_AIO", "REGULATOR_IOG", "REGULATOR_IOA", "REGULATOR_GIO" ] }, { "name" : "Value", "type" : "String" @@ -18501,6 +18697,34 @@ "i" : 2, "label" : "B" } ] + }, { + "when" : { + "Pinout" : "BJT_BEC" + }, + "pins" : [ { + "i" : 0, + "label" : "B" + }, { + "i" : 1, + "label" : "E" + }, { + "i" : 2, + "label" : "C" + } ] + }, { + "when" : { + "Pinout" : "BJT_CEB" + }, + "pins" : [ { + "i" : 0, + "label" : "C" + }, { + "i" : 1, + "label" : "E" + }, { + "i" : 2, + "label" : "B" + } ] }, { "when" : { "Pinout" : "JFET_DSG" @@ -18571,6 +18795,20 @@ "i" : 2, "label" : "S" } ] + }, { + "when" : { + "Pinout" : "JFET_SDG" + }, + "pins" : [ { + "i" : 0, + "label" : "S" + }, { + "i" : 1, + "label" : "D" + }, { + "i" : 2, + "label" : "G" + } ] }, { "when" : { "Pinout" : "MOSFET_DSG" @@ -18697,6 +18935,465 @@ "i" : 2, "label" : "I" } ] + }, { + "when" : { + "Pinout" : "REGULATOR_AIO" + }, + "pins" : [ { + "i" : 0, + "label" : "A" + }, { + "i" : 1, + "label" : "I" + }, { + "i" : 2, + "label" : "O" + } ] + }, { + "when" : { + "Pinout" : "REGULATOR_IOG" + }, + "pins" : [ { + "i" : 0, + "label" : "I" + }, { + "i" : 1, + "label" : "O" + }, { + "i" : 2, + "label" : "G" + } ] + }, { + "when" : { + "Pinout" : "REGULATOR_IOA" + }, + "pins" : [ { + "i" : 0, + "label" : "I" + }, { + "i" : 1, + "label" : "O" + }, { + "i" : 2, + "label" : "A" + } ] + }, { + "when" : { + "Pinout" : "REGULATOR_GIO" + }, + "pins" : [ { + "i" : 0, + "label" : "G" + }, { + "i" : 1, + "label" : "I" + }, { + "i" : 2, + "label" : "O" + } ] + } ] + } + }, { + "name" : "Transistor (TO-92)", + "className" : "semiconductors.TransistorTO92", + "category" : "Semiconductors", + "namePrefix" : "Q", + "description" : "Transistor with small plastic or epoxy body", + "creationMethod" : "SINGLE_CLICK", + "notes" : [ "The first control point is the anchor; with 'Orientation' DEFAULT the three pins run straight down from it 'Pin spacing' apart, and the other orientations rotate this around the anchor", "Seen from above, the flat face is on the left of the pin row in DEFAULT orientation; 'Folded' lays the body flat on the right of the pin row instead", "'Pinout' values list the pins as a datasheet does, facing the flat side with the legs down, left to right; pick the value that matches the part's datasheet as written", "On a 0.1in grid board the default 0.05in 'Pin spacing' puts the middle pin between holes: set 'Pin spacing' to 0.1in, or use two or three jumpers acting as flexible leads and connecting TO-92 terminals to the holes on the board" ], + "datasheetModels" : [ "2N3904", "2N4401", "PN2222A", "2N4124", "2N5088", "2N5089", "2N5210", "2N5551", "MPSA06", "MPSA18", "MPSA42", "MPS5179", "S8050", "S9013", "S9014", "S9018", "BC546", "BC547", "BC548", "BC549", "BC550", "BC337", "BC182", "BC184", "BC239", "P2N2222A", "BC639", "BC182L", "BC184L", "2SC1815", "2SC945", "2SC2240", "2SC1845", "KSC1845", "2SC2458", "BF199", "BF494", "MPSH10", "2N3906", "2N4403", "PN2907A", "2N4126", "2N5087", "2N5401", "MPSA56", "MPSA92", "S8550", "S9012", "S9015", "KSP2907A", "BC556", "BC557", "BC558", "BC559", "BC560", "BC327", "BC212", "BC214", "BC640", "2SA1015", "2SA970", "2SA992", "KSA992", "KSP2907AC", "MPSA13", "MPSA14", "MPSA63", "MPSA64", "J201", "J202", "J111", "J112", "J113", "J310", "2N5457", "2N5458", "2N5459", "2N5484", "2N5485", "2N5486", "PN4416", "MPF102", "BF245A", "BF245B", "BF245C", "2N3819", "BF256B", "2SK170", "LSK170", "J174", "J175", "J176", "2N3820", "2N5460", "2N7000", "LND150", "BS170", "78L05", "78L09", "78L12", "78L15", "LP2950-5.0", "LM2936Z-5.0", "LM317LZ", "LR8", "79L05", "79L12", "79L15", "LM337LZ" ], + "properties" : [ { + "name" : "Alpha", + "type" : "Percentage", + "format" : "number without the % sign, e.g. 100", + "defaultValue" : "100" + }, { + "name" : "Body", + "type" : "Color", + "format" : "hex", + "defaultValue" : "#808080" + }, { + "name" : "Border", + "type" : "Color", + "format" : "hex", + "defaultValue" : "#595959" + }, { + "name" : "Display", + "type" : "TransistorDisplay", + "possibleValues" : [ "NAME", "VALUE", "NONE", "BOTH", "PINOUT" ], + "defaultValue" : "NAME" + }, { + "name" : "Folded", + "type" : "Boolean", + "defaultValue" : "false" + }, { + "name" : "Font Size Override", + "type" : "Integer" + }, { + "name" : "Label", + "type" : "Color", + "format" : "hex", + "defaultValue" : "#000000" + }, { + "name" : "Name", + "type" : "String" + }, { + "name" : "Orientation", + "type" : "Orientation", + "possibleValues" : [ "DEFAULT", "_90", "_180", "_270" ], + "defaultValue" : "DEFAULT" + }, { + "name" : "Pin spacing", + "type" : "Size", + "format" : "(value)(unit)", + "possibleUnits" : [ "px", "mm", "cm", "m", "in", "ft", "yd" ], + "defaultValue" : "0.05in" + }, { + "name" : "Pinout", + "type" : "TransistorPinout", + "possibleValues" : [ "BJT_EBC", "BJT_CBE", "BJT_BCE", "BJT_ECB", "BJT_BEC", "BJT_CEB", "JFET_DSG", "JFET_GSD", "JFET_DGS", "JFET_SGD", "JFET_GDS", "JFET_SDG", "MOSFET_DSG", "MOSFET_GSD", "MOSFET_DGS", "MOSFET_SGD", "MOSFET_GDS", "REGULATOR_IGO", "REGULATOR_OGI", "REGULATOR_GOI", "REGULATOR_AOI", "REGULATOR_AIO", "REGULATOR_IOG", "REGULATOR_IOA", "REGULATOR_GIO" ] + }, { + "name" : "Value", + "type" : "String" + } ], + "pinout" : { + "drivers" : [ "Pinout" ], + "variants" : [ { + "when" : { + "Pinout" : "BJT_EBC" + }, + "pins" : [ { + "i" : 0, + "label" : "E" + }, { + "i" : 1, + "label" : "B" + }, { + "i" : 2, + "label" : "C" + } ] + }, { + "when" : { + "Pinout" : "BJT_CBE" + }, + "pins" : [ { + "i" : 0, + "label" : "C" + }, { + "i" : 1, + "label" : "B" + }, { + "i" : 2, + "label" : "E" + } ] + }, { + "when" : { + "Pinout" : "BJT_BCE" + }, + "pins" : [ { + "i" : 0, + "label" : "B" + }, { + "i" : 1, + "label" : "C" + }, { + "i" : 2, + "label" : "E" + } ] + }, { + "when" : { + "Pinout" : "BJT_ECB" + }, + "pins" : [ { + "i" : 0, + "label" : "E" + }, { + "i" : 1, + "label" : "C" + }, { + "i" : 2, + "label" : "B" + } ] + }, { + "when" : { + "Pinout" : "BJT_BEC" + }, + "pins" : [ { + "i" : 0, + "label" : "B" + }, { + "i" : 1, + "label" : "E" + }, { + "i" : 2, + "label" : "C" + } ] + }, { + "when" : { + "Pinout" : "BJT_CEB" + }, + "pins" : [ { + "i" : 0, + "label" : "C" + }, { + "i" : 1, + "label" : "E" + }, { + "i" : 2, + "label" : "B" + } ] + }, { + "when" : { + "Pinout" : "JFET_DSG" + }, + "pins" : [ { + "i" : 0, + "label" : "D" + }, { + "i" : 1, + "label" : "S" + }, { + "i" : 2, + "label" : "G" + } ] + }, { + "when" : { + "Pinout" : "JFET_GSD" + }, + "pins" : [ { + "i" : 0, + "label" : "G" + }, { + "i" : 1, + "label" : "S" + }, { + "i" : 2, + "label" : "D" + } ] + }, { + "when" : { + "Pinout" : "JFET_DGS" + }, + "pins" : [ { + "i" : 0, + "label" : "D" + }, { + "i" : 1, + "label" : "G" + }, { + "i" : 2, + "label" : "S" + } ] + }, { + "when" : { + "Pinout" : "JFET_SGD" + }, + "pins" : [ { + "i" : 0, + "label" : "S" + }, { + "i" : 1, + "label" : "G" + }, { + "i" : 2, + "label" : "D" + } ] + }, { + "when" : { + "Pinout" : "JFET_GDS" + }, + "pins" : [ { + "i" : 0, + "label" : "G" + }, { + "i" : 1, + "label" : "D" + }, { + "i" : 2, + "label" : "S" + } ] + }, { + "when" : { + "Pinout" : "JFET_SDG" + }, + "pins" : [ { + "i" : 0, + "label" : "S" + }, { + "i" : 1, + "label" : "D" + }, { + "i" : 2, + "label" : "G" + } ] + }, { + "when" : { + "Pinout" : "MOSFET_DSG" + }, + "pins" : [ { + "i" : 0, + "label" : "D" + }, { + "i" : 1, + "label" : "S" + }, { + "i" : 2, + "label" : "G" + } ] + }, { + "when" : { + "Pinout" : "MOSFET_GSD" + }, + "pins" : [ { + "i" : 0, + "label" : "G" + }, { + "i" : 1, + "label" : "S" + }, { + "i" : 2, + "label" : "D" + } ] + }, { + "when" : { + "Pinout" : "MOSFET_DGS" + }, + "pins" : [ { + "i" : 0, + "label" : "D" + }, { + "i" : 1, + "label" : "G" + }, { + "i" : 2, + "label" : "S" + } ] + }, { + "when" : { + "Pinout" : "MOSFET_SGD" + }, + "pins" : [ { + "i" : 0, + "label" : "S" + }, { + "i" : 1, + "label" : "G" + }, { + "i" : 2, + "label" : "D" + } ] + }, { + "when" : { + "Pinout" : "MOSFET_GDS" + }, + "pins" : [ { + "i" : 0, + "label" : "G" + }, { + "i" : 1, + "label" : "D" + }, { + "i" : 2, + "label" : "S" + } ] + }, { + "when" : { + "Pinout" : "REGULATOR_IGO" + }, + "pins" : [ { + "i" : 0, + "label" : "I" + }, { + "i" : 1, + "label" : "G" + }, { + "i" : 2, + "label" : "O" + } ] + }, { + "when" : { + "Pinout" : "REGULATOR_OGI" + }, + "pins" : [ { + "i" : 0, + "label" : "O" + }, { + "i" : 1, + "label" : "G" + }, { + "i" : 2, + "label" : "I" + } ] + }, { + "when" : { + "Pinout" : "REGULATOR_GOI" + }, + "pins" : [ { + "i" : 0, + "label" : "G" + }, { + "i" : 1, + "label" : "O" + }, { + "i" : 2, + "label" : "I" + } ] + }, { + "when" : { + "Pinout" : "REGULATOR_AOI" + }, + "pins" : [ { + "i" : 0, + "label" : "A" + }, { + "i" : 1, + "label" : "O" + }, { + "i" : 2, + "label" : "I" + } ] + }, { + "when" : { + "Pinout" : "REGULATOR_AIO" + }, + "pins" : [ { + "i" : 0, + "label" : "A" + }, { + "i" : 1, + "label" : "I" + }, { + "i" : 2, + "label" : "O" + } ] + }, { + "when" : { + "Pinout" : "REGULATOR_IOG" + }, + "pins" : [ { + "i" : 0, + "label" : "I" + }, { + "i" : 1, + "label" : "O" + }, { + "i" : 2, + "label" : "G" + } ] + }, { + "when" : { + "Pinout" : "REGULATOR_IOA" + }, + "pins" : [ { + "i" : 0, + "label" : "I" + }, { + "i" : 1, + "label" : "O" + }, { + "i" : 2, + "label" : "A" + } ] }, { "when" : { "Pinout" : "REGULATOR_GIO" diff --git a/diylc/catalog_index.json b/diylc/catalog_index.json index e9a2a77e..5f65907d 100644 --- a/diylc/catalog_index.json +++ b/diylc/catalog_index.json @@ -1,5 +1,5 @@ { - "version" : "6.9.0", + "version" : "6.10.0", "categories" : { "Boards" : [ { "name" : "Blank Board", diff --git a/diylc/diylc-core/src/main/resources/update.xml b/diylc/diylc-core/src/main/resources/update.xml index 4822df6a..5d0da07a 100644 --- a/diylc/diylc-core/src/main/resources/update.xml +++ b/diylc/diylc-core/src/main/resources/update.xml @@ -514,16 +514,16 @@ Added 'Pin Labels' property to 'SIP IC' and 'Multiwatt IC' to show pin names or pin numbers next to the pins - IMPROVEMENT - Re-modeled factory variants of Resistor component type as datasheet in order to make them available to the AI; this will produce more accurate AI-driven edits - - - IMPROVEMENT - Derive the z-order of a building blocks placed as a single component based on its child components + NEW_FEATURE + Added datasheets to 'DIP IC', 'SIP IC' and 'Multiwatt IC' - pick a part by its number from the component's submenu to set its pin count, spacing and pin names at once - more than 100 chips in total; the AI Assistant can place these parts by part number too NEW_FEATURE - Added datasheets to 'DIP IC', 'SIP IC' and 'Multiwatt IC' - pick a part by its number from the component's submenu to set its pin count, spacing and pin names at once - more than 100 chips in total; the AI Assistant can place these parts by part number too + Added datasheets to 'Transistor (TO-92)', 'Transistor (TO-1)', 'Transistor (TO-126)', 'Transistor (TO-220)' and 'Transistor (TO-3)' - pick a part by its number from the component's submenu to set its value and pinout at once - more than 250 transistors, JFETs, MOSFETs and voltage regulators used in guitar effects, hi-fi, radio and synth projects; the AI Assistant can place these parts by part number too + + + NEW_FEATURE + Added 'Pinout' property to 'Transistor (TO-3)' and a terminal in the mounting hole next to the pins, so the case (collector) can be wired and shows up in netlists and AI analysis NEW_FEATURE @@ -533,10 +533,26 @@ NEW_FEATURE Added a datasheet to 'Enclosure' with Hammond 1590, 1550, 1441 and 1444 enclosures and the 125B size - more than 130 variations + + IMPROVEMENT + Re-modeled factory variants of Resistor component type as datasheet in order to make them available to the AI; this will produce more accurate AI-driven edits + + + IMPROVEMENT + Derive the z-order of a building blocks placed as a single component based on its child components + IMPROVEMENT Moved 'Enclosure', cutouts, 'Drill Hole' and 'Dial Scale' to the new 'Hardware' category + + IMPROVEMENT + Transistor pins are now drawn on top of the body in the same color on every package, so they stay visible whatever the body transparency + + + IMPROVEMENT + Added B-E-C, C-E-B and S-D-G transistor pinouts and ADJ-IN-OUT, IN-OUT-GND and IN-OUT-ADJ regulator pinouts + BUG_FIX 'DIP IC' with 'Display Pin #s' set to 'No' numbered its pins in the wrong order in netlists and AI analysis, e.g. pin 8 of an 8-pin IC was reported as pin 5 @@ -553,6 +569,10 @@ BUG_FIX 'SIP IC' body was drawn too short when 'Pin Spacing' is not a multiple of 0.1 inch, leaving the last pin outside the body + + BUG_FIX + SPICE netlists listed the pins of transistors with E-C-B pinout in the wrong order + https://github.com/bancika/diy-layout-creator/releases diff --git a/diylc/diylc-library/src/main/java/org/diylc/components/semiconductors/AbstractTransistorPackage.java b/diylc/diylc-library/src/main/java/org/diylc/components/semiconductors/AbstractTransistorPackage.java index b82e7130..b0bdbe21 100644 --- a/diylc/diylc-library/src/main/java/org/diylc/components/semiconductors/AbstractTransistorPackage.java +++ b/diylc/diylc-library/src/main/java/org/diylc/components/semiconductors/AbstractTransistorPackage.java @@ -24,21 +24,26 @@ package org.diylc.components.semiconductors; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; +import java.awt.Shape; import java.awt.geom.Area; +import java.awt.geom.Ellipse2D; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import org.diylc.awt.StringUtils; import org.diylc.common.HorizontalAlignment; +import org.diylc.common.ObjectCache; import org.diylc.common.Orientation; import org.diylc.common.VerticalAlignment; import org.diylc.components.AbstractLabeledComponent; +import org.diylc.core.IDatasheetSupport; import org.diylc.core.VisibilityPolicy; import org.diylc.core.annotations.EditableProperty; import org.diylc.core.gerber.IGerberComponentSimple; import org.diylc.netlist.ISpiceMapper; -public abstract class AbstractTransistorPackage extends AbstractLabeledComponent implements ISpiceMapper, IGerberComponentSimple { +public abstract class AbstractTransistorPackage extends AbstractLabeledComponent implements ISpiceMapper, IGerberComponentSimple, + IDatasheetSupport { private static final long serialVersionUID = 1L; @@ -58,59 +63,23 @@ public abstract class AbstractTransistorPackage extends AbstractLabeledComponent public AbstractTransistorPackage() { } + // columns: group, part number, pinout + @Override + public void applyModel(String[] model) { + setValue(model[1]); + setPinout(TransistorPinout.valueOf(model[2])); + } + protected abstract void updateControlPoints(); public abstract Area[] getBody(); @Override public int mapToSpiceNode(int index) { - if (getPinout() == null) + if (getPinout() == null) { return index; - - switch (getPinout()) { - case BJT_CBE: - return index; - case BJT_EBC: - return 2 - index; - case JFET_DGS: - case MOSFET_DGS: - return index; - case JFET_DSG: - case MOSFET_DSG: - switch (index) { - case 0: return 0; - case 1: return 2; - case 2: return 1; - } - case JFET_GSD: - case MOSFET_GSD: - switch (index) { - case 0: return 1; - case 1: return 2; - case 2: return 0; - } - case JFET_GDS: - case MOSFET_GDS: - switch (index) { - case 0: return 1; - case 1: return 0; - case 2: return 2; - } - case JFET_SGD: - case MOSFET_SGD: - return 2 - index; - case BJT_BCE: - switch (index) { - case 0: return 1; - case 1: return 0; - case 2: return 2; - } - break; - default: - break; } - - return index; + return getPinout().mapToSpiceNode(index); } @Override @@ -282,6 +251,22 @@ public abstract class AbstractTransistorPackage extends AbstractLabeledComponent return new Rectangle2D.Double(minX - margin, minY - margin, maxX - minX + 2 * margin, maxY - minY + 2 * margin); } + // drawn after the body so that pins stay visible whatever its alpha; a null pinColor draws only + // the outline + protected void drawPins(Graphics2D g2d, int pinSize, Color pinColor, Color pinBorderColor) { + g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1f)); + for (Point2D point : controlPoints) { + Shape pin = new Ellipse2D.Double(point.getX() - pinSize / 2, point.getY() - pinSize / 2, + pinSize, pinSize); + if (pinColor != null) { + g2d.setColor(pinColor); + g2d.fill(pin); + } + g2d.setColor(pinBorderColor); + g2d.draw(pin); + } + } + protected boolean flipPinoutLabel() { return false; } diff --git a/diylc/diylc-library/src/main/java/org/diylc/components/semiconductors/TransistorPinout.java b/diylc/diylc-library/src/main/java/org/diylc/components/semiconductors/TransistorPinout.java index 1638f295..295117e7 100644 --- a/diylc/diylc-library/src/main/java/org/diylc/components/semiconductors/TransistorPinout.java +++ b/diylc/diylc-library/src/main/java/org/diylc/components/semiconductors/TransistorPinout.java @@ -2,7 +2,7 @@ package org.diylc.components.semiconductors; public enum TransistorPinout { - BJT_EBC, BJT_CBE, BJT_BCE, BJT_ECB, JFET_DSG, JFET_GSD, JFET_DGS, JFET_SGD, JFET_GDS, MOSFET_DSG, MOSFET_GSD, MOSFET_DGS, MOSFET_SGD, MOSFET_GDS, REGULATOR_IGO, REGULATOR_OGI, REGULATOR_GOI, REGULATOR_AOI, REGULATOR_GIO; + BJT_EBC, BJT_CBE, BJT_BCE, BJT_ECB, BJT_BEC, BJT_CEB, JFET_DSG, JFET_GSD, JFET_DGS, JFET_SGD, JFET_GDS, JFET_SDG, MOSFET_DSG, MOSFET_GSD, MOSFET_DGS, MOSFET_SGD, MOSFET_GDS, REGULATOR_IGO, REGULATOR_OGI, REGULATOR_GOI, REGULATOR_AOI, REGULATOR_AIO, REGULATOR_IOG, REGULATOR_IOA, REGULATOR_GIO; @Override public String toString() { @@ -21,4 +21,20 @@ public enum TransistorPinout { String[] parts = name().split("_"); return parts[1]; } + + /** + * Position of the pin at {@code index} in SPICE node order: C B E for a BJT, D G S for a FET. + * Regulators have no SPICE element, so their pins keep their own order. + */ + public int mapToSpiceNode(int index) { + String spiceOrder; + if (name().startsWith("BJT")) { + spiceOrder = "CBE"; + } else if (name().startsWith("REGULATOR")) { + return index; + } else { + spiceOrder = "DGS"; + } + return spiceOrder.indexOf(toPinout().charAt(index)); + } } diff --git a/diylc/diylc-library/src/main/java/org/diylc/components/semiconductors/TransistorTO1.java b/diylc/diylc-library/src/main/java/org/diylc/components/semiconductors/TransistorTO1.java index 7ce710ac..99ccb0fa 100644 --- a/diylc/diylc-library/src/main/java/org/diylc/components/semiconductors/TransistorTO1.java +++ b/diylc/diylc-library/src/main/java/org/diylc/components/semiconductors/TransistorTO1.java @@ -27,7 +27,6 @@ import java.awt.Composite; import java.awt.FontMetrics; import java.awt.Graphics2D; import java.awt.Rectangle; -import java.awt.Shape; import java.awt.geom.Area; import java.awt.geom.Ellipse2D; import java.awt.geom.Point2D; @@ -54,10 +53,12 @@ import org.diylc.utils.Constants; @AiNote("The first control point is the anchor; with 'Orientation' DEFAULT the third pin is 2 x 'Pin spacing' below it and the middle pin 'Pin spacing' below and 'Pin spacing' to the left, a triangle under the round can. 'Folded' puts the three pins in a straight line down from the anchor and lays the body flat on the right of them. The other orientations rotate this around the anchor") @AiNote("On a 0.1in grid board the default 0.05in 'Pin spacing' puts the middle pin between holes: set 'Pin spacing' to 0.1in to land all three pins on holes") +@AiNote("'Pinout' values list pins 1, 2, 3 in control point order. Seen from above, a metal can's leads run counter-clockwise from the tab, which sits beside pin 1; most parts, silicon TO-18/TO-39 and germanium alike, are E-B-C") @ComponentDescriptor(name = "Transistor (TO-1)", author = "Branislav Stojkovic", category = "Semiconductors", instanceNamePrefix = "Q", description = "Transistor with small metal body", zOrder = IDIYComponent.COMPONENT, keywordPolicy = KeywordPolicy.SHOW_VALUE, transformer = TO1Transformer.class, - enableCache = true) + enableCache = true, enableDatasheet = true, datasheetCreationStepCount = 2, + datasheetModelColumn = 1) public class TransistorTO1 extends AbstractTransistorPackage { private static final long serialVersionUID = 1L; @@ -83,6 +84,12 @@ public class TransistorTO1 extends AbstractTransistorPackage { borderColor = BORDER_COLOR; } + public TransistorTO1(String[] model) { + this(); + + applyModel(model); + } + @Override protected void updateControlPoints() { int pinSpacing = (int) getPinSpacing().convertToPixels(); @@ -172,18 +179,8 @@ public class TransistorTO1 extends AbstractTransistorPackage { } int pinSize = (int) PIN_SIZE.convertToPixels() / 2 * 2; Theme theme = (Theme) ConfigurationManager.getInstance().readObject(IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME); - - g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1f)); - for (Point2D point : controlPoints) { - Shape shape = new Ellipse2D.Double(point.getX() - pinSize / 2, point.getY() - pinSize / 2, pinSize, pinSize); - if (!outlineMode) { - g2d.setColor(PIN_COLOR); - g2d.fill(shape); - } - g2d.setColor(outlineMode ? theme.getOutlineColor() : PIN_BORDER_COLOR); - g2d.draw(shape); - } - + + Area mainArea = getBody()[0]; Composite oldComposite = applyAlpha(g2d, componentState); g2d.setColor(outlineMode ? Constants.TRANSPARENT_COLOR : bodyColor); @@ -204,7 +201,10 @@ public class TransistorTO1 extends AbstractTransistorPackage { } g2d.setColor(finalBorderColor); g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1)); - g2d.draw(mainArea); + g2d.draw(mainArea); + + drawPins(g2d, pinSize, outlineMode ? null : PIN_COLOR, + outlineMode ? theme.getOutlineColor() : PIN_BORDER_COLOR); // Draw label. g2d.setFont(project.getFont()); diff --git a/diylc/diylc-library/src/main/java/org/diylc/components/semiconductors/TransistorTO126.java b/diylc/diylc-library/src/main/java/org/diylc/components/semiconductors/TransistorTO126.java index 1a4e275b..43fd8446 100644 --- a/diylc/diylc-library/src/main/java/org/diylc/components/semiconductors/TransistorTO126.java +++ b/diylc/diylc-library/src/main/java/org/diylc/components/semiconductors/TransistorTO126.java @@ -44,6 +44,7 @@ import org.diylc.core.IDIYComponent; import org.diylc.core.IDrawingObserver; import org.diylc.core.Project; import org.diylc.core.Theme; +import org.diylc.core.annotations.AiNote; import org.diylc.core.annotations.ComponentDescriptor; import org.diylc.core.annotations.EditableProperty; import org.diylc.core.annotations.KeywordPolicy; @@ -51,10 +52,13 @@ import org.diylc.core.measures.Size; import org.diylc.core.measures.SizeUnit; import org.diylc.utils.Constants; +@AiNote("The first control point is the anchor and pin 1; with 'Orientation' DEFAULT the three pins run straight down from it 0.1in apart, and the other orientations rotate this around the anchor") +@AiNote("'Pinout' values list the pins as a datasheet does, facing the printed front with the metal back away and the legs down, left to right; BD139-style parts are E-C-B") @ComponentDescriptor(name = "Transistor (TO-126)", author = "Branislav Stojkovic", category = "Semiconductors", instanceNamePrefix = "Q", description = "Transistors with a hole for heat sink mounting", zOrder = IDIYComponent.COMPONENT, keywordPolicy = KeywordPolicy.SHOW_VALUE, transformer = TO220Transformer.class, - enableCache = true) + enableCache = true, enableDatasheet = true, datasheetCreationStepCount = 2, + datasheetModelColumn = 1) public class TransistorTO126 extends AbstractTransistorPackage { private static final long serialVersionUID = 1L; @@ -84,6 +88,12 @@ public class TransistorTO126 extends AbstractTransistorPackage { borderColor = BORDER_COLOR; } + public TransistorTO126(String[] model) { + this(); + + applyModel(model); + } + @Override protected void updateControlPoints() { int pinSpacing = (int) PIN_SPACING.convertToPixels(); @@ -203,8 +213,8 @@ public class TransistorTO126 extends AbstractTransistorPackage { componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR : theme.getOutlineColor(); } else { - finalPinColor = METAL_COLOR; - finalPinBorderColor = METAL_COLOR.darker(); + finalPinColor = PIN_COLOR; + finalPinBorderColor = PIN_BORDER_COLOR; } Line2D line; for (Point2D point : controlPoints) { @@ -256,17 +266,6 @@ public class TransistorTO126 extends AbstractTransistorPackage { } } } - } else { - if (!outlineMode) { - for (Point2D point : controlPoints) { - - g2d.setColor(PIN_COLOR); - Shape pin = new Ellipse2D.Double(point.getX() - pinSize / 2, point.getY() - pinSize / 2, pinSize, pinSize); - g2d.fill(pin); - g2d.setColor(outlineMode ? theme.getOutlineColor() : PIN_BORDER_COLOR); - g2d.draw(pin); - } - } } @@ -298,6 +297,9 @@ public class TransistorTO126 extends AbstractTransistorPackage { g2d.setComposite(oldComposite); + drawPins(g2d, pinSize, outlineMode ? null : PIN_COLOR, + outlineMode ? theme.getOutlineColor() : PIN_BORDER_COLOR); + // Draw label. g2d.setFont(project.getFont()); diff --git a/diylc/diylc-library/src/main/java/org/diylc/components/semiconductors/TransistorTO220.java b/diylc/diylc-library/src/main/java/org/diylc/components/semiconductors/TransistorTO220.java index 82b8f011..329b9ff2 100644 --- a/diylc/diylc-library/src/main/java/org/diylc/components/semiconductors/TransistorTO220.java +++ b/diylc/diylc-library/src/main/java/org/diylc/components/semiconductors/TransistorTO220.java @@ -58,7 +58,8 @@ import org.diylc.utils.Constants; @ComponentDescriptor(name = "Transistor (TO-220)", author = "Branislav Stojkovic", category = "Semiconductors", instanceNamePrefix = "Q", description = "Transistors with metal tab for heat sink mounting", zOrder = IDIYComponent.COMPONENT, keywordPolicy = KeywordPolicy.SHOW_VALUE, transformer = TO220Transformer.class, - enableCache = true) + enableCache = true, enableDatasheet = true, datasheetCreationStepCount = 2, + datasheetModelColumn = 1) public class TransistorTO220 extends AbstractTransistorPackage { private static final long serialVersionUID = 1L; @@ -93,6 +94,12 @@ public class TransistorTO220 extends AbstractTransistorPackage { borderColor = BORDER_COLOR; } + public TransistorTO220(String[] model) { + this(); + + applyModel(model); + } + @Override protected void updateControlPoints() { int pinSpacing = (int) PIN_SPACING.convertToPixels(); @@ -234,8 +241,8 @@ public class TransistorTO220 extends AbstractTransistorPackage { componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR : theme.getOutlineColor(); } else { - finalPinColor = METAL_COLOR; - finalPinBorderColor = METAL_COLOR.darker(); + finalPinColor = PIN_COLOR; + finalPinBorderColor = PIN_BORDER_COLOR; } Line2D line; for (Point2D point : controlPoints) { @@ -287,17 +294,6 @@ public class TransistorTO220 extends AbstractTransistorPackage { } } } - } else { - if (!outlineMode) { - for (Point2D point : controlPoints) { - - g2d.setColor(PIN_COLOR); - Shape pin = new Ellipse2D.Double(point.getX() - pinSize / 2, point.getY() - pinSize / 2, pinSize, pinSize); - g2d.fill(pin); - g2d.setColor(outlineMode ? theme.getOutlineColor() : PIN_BORDER_COLOR); - g2d.draw(pin); - } - } } @@ -339,6 +335,9 @@ public class TransistorTO220 extends AbstractTransistorPackage { g2d.draw(tabArea); } + drawPins(g2d, pinSize, outlineMode ? null : PIN_COLOR, + outlineMode ? theme.getOutlineColor() : PIN_BORDER_COLOR); + // Draw label. g2d.setFont(project.getFont()); diff --git a/diylc/diylc-library/src/main/java/org/diylc/components/semiconductors/TransistorTO3.java b/diylc/diylc-library/src/main/java/org/diylc/components/semiconductors/TransistorTO3.java index 78375f0e..8308ab3e 100644 --- a/diylc/diylc-library/src/main/java/org/diylc/components/semiconductors/TransistorTO3.java +++ b/diylc/diylc-library/src/main/java/org/diylc/components/semiconductors/TransistorTO3.java @@ -36,26 +36,35 @@ import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import org.diylc.appframework.miscutils.ConfigurationManager; +import org.diylc.awt.StringUtils; import org.diylc.awt.TwoCircleTangent; import org.diylc.common.*; import org.diylc.components.AbstractLabeledComponent; +import org.diylc.components.semiconductors.AbstractTransistorPackage.TransistorDisplay; import org.diylc.core.ComponentState; +import org.diylc.core.IDatasheetSupport; import org.diylc.core.IDIYComponent; import org.diylc.core.IDrawingObserver; import org.diylc.core.Project; import org.diylc.core.Theme; import org.diylc.core.VisibilityPolicy; +import org.diylc.core.annotations.AiNote; import org.diylc.core.annotations.ComponentDescriptor; import org.diylc.core.annotations.EditableProperty; import org.diylc.core.annotations.KeywordPolicy; import org.diylc.core.measures.Size; import org.diylc.core.measures.SizeUnit; +import org.diylc.netlist.ISpiceMapper; import org.diylc.utils.Constants; +@AiNote("The first control point is pin 1; with 'Orientation' DEFAULT pin 2 is 10.9mm below it and the mounting holes lie left and right of the pins, which sit 1.8mm left of the case centre. The third control point is the case, at the centre of the left mounting hole: connect a wire or solder lug there to reach the collector") +@AiNote("'Pinout' values list pin 1, pin 2, then the case, e.g. B-E-C for a 2N3055 whose case is the collector") @ComponentDescriptor(name = "Transistor (TO-3)", author = "Branislav Stojkovic", category = "Semiconductors", instanceNamePrefix = "Q", description = "Transistor with large metal body", - zOrder = IDIYComponent.COMPONENT, keywordPolicy = KeywordPolicy.SHOW_VALUE, enableCache = true) -public class TransistorTO3 extends AbstractLabeledComponent { + zOrder = IDIYComponent.COMPONENT, keywordPolicy = KeywordPolicy.SHOW_VALUE, enableCache = true, + enableDatasheet = true, datasheetCreationStepCount = 2, datasheetModelColumn = 1) +public class TransistorTO3 extends AbstractLabeledComponent + implements ISpiceMapper, IDatasheetSupport { private static final long serialVersionUID = 1L; @@ -76,12 +85,17 @@ public class TransistorTO3 extends AbstractLabeledComponent { private String value = ""; private Orientation orientation = Orientation.DEFAULT; - private Point2D[] controlPoints = new Point2D[] {new Point2D.Double(0, 0), new Point2D.Double(0, 0)}; + // pin 1, pin 2 and the case, reached through the mounting hole on the side of the pins + private Point2D[] controlPoints = + new Point2D[] {new Point2D.Double(0, 0), new Point2D.Double(0, 0), new Point2D.Double(0, 0)}; transient private Area[] body; private Color bodyColor = BODY_COLOR; private Color borderColor = BORDER_COLOR; private Color labelColor = LABEL_COLOR; + @Deprecated protected Display display = Display.NAME; + private TransistorDisplay transistorDisplay = TransistorDisplay.NAME; + private TransistorPinout pinout; public TransistorTO3() { super(); @@ -89,6 +103,19 @@ public class TransistorTO3 extends AbstractLabeledComponent { this.alphaPercent = new Percentage(100); } + public TransistorTO3(String[] model) { + this(); + + applyModel(model); + } + + // columns: group, part number, pinout of pin 1, pin 2 and the case + @Override + public void applyModel(String[] model) { + setValue(model[1]); + setPinout(TransistorPinout.valueOf(model[2])); + } + @EditableProperty public String getValue() { return value; @@ -110,14 +137,67 @@ public class TransistorTO3 extends AbstractLabeledComponent { body = null; } + @EditableProperty + public TransistorPinout getPinout() { + return pinout; + } + + public void setPinout(TransistorPinout pinout) { + this.pinout = pinout; + } + @Override public int getControlPointCount() { - return controlPoints.length; + return getControlPoints().length; } @Override public Point2D getControlPoint(int index) { - return controlPoints[index]; + return getControlPoints()[index]; + } + + // files saved before the case point existed hold only the two pins + private Point2D[] getControlPoints() { + if (controlPoints.length < 3) { + controlPoints = new Point2D[] {controlPoints[0], controlPoints[1], new Point2D.Double(0, 0)}; + updateCasePoint(); + } + return controlPoints; + } + + @Override + public boolean canPointMoveFreely(int pointIndex) { + return false; + } + + @Override + public String getControlPointNodeName(int index) { + if (getPinout() != null) { + return getPinout().toPinout().substring(index, index + 1); + } + return super.getControlPointNodeName(index); + } + + @Override + public int mapToSpiceNode(int index) { + if (getPinout() == null) { + return index; + } + return getPinout().mapToSpiceNode(index); + } + + @Override + public String getComment() { + return getPinout() == null ? "Pinout not configured, validate this line" + : (getPinout().toString() + " pinout"); + } + + @Override + public String getPrefix() { + if (getPinout() == null) { + return null; + } + return getPinout().name().substring(0, 1); } @Override @@ -132,11 +212,12 @@ public class TransistorTO3 extends AbstractLabeledComponent { @Override public void setControlPoint(Point2D point, int index) { - controlPoints[index].setLocation(point); + getControlPoints()[index].setLocation(point); body = null; } private void updateControlPoints() { + Point2D[] controlPoints = getControlPoints(); int pinSpacing = (int) PIN_SPACING.convertToPixels(); // Update control points. double x = controlPoints[0].getX(); @@ -157,10 +238,37 @@ public class TransistorTO3 extends AbstractLabeledComponent { default: throw new RuntimeException("Unexpected orientation: " + orientation); } + updateCasePoint(); + } + + // the centre of the mounting hole on the side the pins are offset towards, rounded as getBody() + // rounds it + private void updateCasePoint() { + int pinOffset = (int) PIN_OFFSET.convertToPixels(); + int holeDistance = getClosestOdd(HOLE_DISTANCE.convertToPixels()); + double x = (controlPoints[0].getX() + controlPoints[1].getX()) / 2; + double y = (controlPoints[0].getY() + controlPoints[1].getY()) / 2; + switch (orientation) { + case DEFAULT: + controlPoints[2].setLocation(x + pinOffset - holeDistance / 2, y); + break; + case _90: + controlPoints[2].setLocation(x, y + pinOffset - holeDistance / 2); + break; + case _180: + controlPoints[2].setLocation(x - pinOffset + holeDistance / 2, y); + break; + case _270: + controlPoints[2].setLocation(x, y - pinOffset + holeDistance / 2); + break; + default: + throw new RuntimeException("Unexpected orientation: " + orientation); + } } public Area[] getBody() { if (body == null) { + Point2D[] controlPoints = getControlPoints(); body = new Area[2]; int pinOffset = (int) PIN_OFFSET.convertToPixels(); double x = (controlPoints[0].getX() + controlPoints[1].getX()) / 2; @@ -233,15 +341,6 @@ public class TransistorTO3 extends AbstractLabeledComponent { Theme theme = (Theme) ConfigurationManager.getInstance().readObject(IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME); g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1f)); - for (Point2D point : controlPoints) { - if (!outlineMode) { - g2d.setColor(PIN_COLOR); - g2d.fillOval((int) Math.round(point.getX() - pinSize / 2), (int) Math.round(point.getY() - pinSize / 2), pinSize, pinSize); - } - g2d.setColor(outlineMode ? theme.getOutlineColor() : PIN_BORDER_COLOR); - g2d.drawOval((int) Math.round(point.getX() - pinSize / 2), (int) Math.round(point.getY() - pinSize / 2), pinSize, pinSize); - } - Area mainArea = getBody()[0]; Area innerArea = getBody()[1]; Composite oldComposite = applyAlpha(g2d, componentState); @@ -264,7 +363,21 @@ public class TransistorTO3 extends AbstractLabeledComponent { g2d.setColor(finalBorderColor); g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1)); g2d.draw(mainArea); - g2d.draw(innerArea); + g2d.draw(innerArea); + + // the pins leave through the bottom of the case, so they are drawn over it to stay visible + // whatever its alpha + for (int i = 0; i < 2; i++) { + Point2D point = getControlPoint(i); + if (!outlineMode) { + g2d.setColor(PIN_COLOR); + g2d.fillOval((int) Math.round(point.getX() - pinSize / 2), + (int) Math.round(point.getY() - pinSize / 2), pinSize, pinSize); + } + g2d.setColor(outlineMode ? theme.getOutlineColor() : PIN_BORDER_COLOR); + g2d.drawOval((int) Math.round(point.getX() - pinSize / 2), + (int) Math.round(point.getY() - pinSize / 2), pinSize, pinSize); + } // Draw label. g2d.setFont(project.getFont()); @@ -284,12 +397,16 @@ public class TransistorTO3 extends AbstractLabeledComponent { : getLabelColor(); } g2d.setColor(finalLabelColor); + if (getTransistorDisplay() == TransistorDisplay.PINOUT) { + drawPinout(g2d); + return; + } String label = ""; - label = (getDisplay() == Display.NAME) ? getName() : getValue(); - if (getDisplay() == Display.NONE) { + label = (getTransistorDisplay() == TransistorDisplay.NAME) ? getName() : getValue(); + if (getTransistorDisplay() == TransistorDisplay.NONE) { label = ""; } - if (getDisplay() == Display.BOTH) { + if (getTransistorDisplay() == TransistorDisplay.BOTH) { label = getName() + " " + (getValue() == null ? "" : getValue().toString()); } FontMetrics fontMetrics = g2d.getFontMetrics(g2d.getFont()); @@ -303,6 +420,47 @@ public class TransistorTO3 extends AbstractLabeledComponent { g2d.drawString(label, x, y); } + // each letter sits beside its pin or hole on the side of the body centre + private void drawPinout(Graphics2D g2d) { + if (getPinout() == null) { + return; + } + g2d.setFont(g2d.getFont().deriveFont((float) (g2d.getFont().getSize() * 0.7))); + String pinout = getPinout().toPinout(); + int pinD = (int) PIN_DIAMETER.convertToPixels(); + int holeD = (int) HOLE_SIZE.convertToPixels(); + for (int i = 0; i < pinout.length(); i++) { + Point2D point = getControlPoint(i); + int d = (i < 2 ? pinD : holeD) / 2 + 2; + int dx = 0; + int dy = 0; + HorizontalAlignment ha = HorizontalAlignment.CENTER; + VerticalAlignment va = VerticalAlignment.CENTER; + switch (getOrientation()) { + case DEFAULT: + dx = d; + ha = HorizontalAlignment.LEFT; + break; + case _90: + dy = d; + va = VerticalAlignment.BOTTOM; + break; + case _180: + dx = -d; + ha = HorizontalAlignment.RIGHT; + break; + case _270: + dy = -d; + va = VerticalAlignment.TOP; + break; + default: + throw new RuntimeException("Unexpected orientation: " + orientation); + } + StringUtils.drawCenteredText(g2d, pinout.substring(i, i + 1), point.getX() + dx, + point.getY() + dy, ha, va); + } + } + @Override public void drawIcon(Graphics2D g2d, int width, int height) { g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE); @@ -351,7 +509,7 @@ public class TransistorTO3 extends AbstractLabeledComponent { this.labelColor = labelColor; } - @EditableProperty + @Deprecated public Display getDisplay() { if (display == null) { display = Display.NAME; @@ -359,9 +517,22 @@ public class TransistorTO3 extends AbstractLabeledComponent { return display; } + @Deprecated public void setDisplay(Display display) { this.display = display; } + + @EditableProperty(name = "Display") + public TransistorDisplay getTransistorDisplay() { + if (transistorDisplay == null) { + transistorDisplay = TransistorDisplay.valueOf(getDisplay().name()); + } + return transistorDisplay; + } + + public void setTransistorDisplay(TransistorDisplay transistorDisplay) { + this.transistorDisplay = transistorDisplay; + } @Override public Rectangle2D getCachingBounds() { diff --git a/diylc/diylc-library/src/main/java/org/diylc/components/semiconductors/TransistorTO92.java b/diylc/diylc-library/src/main/java/org/diylc/components/semiconductors/TransistorTO92.java index dedf5c56..7fc3ed75 100644 --- a/diylc/diylc-library/src/main/java/org/diylc/components/semiconductors/TransistorTO92.java +++ b/diylc/diylc-library/src/main/java/org/diylc/components/semiconductors/TransistorTO92.java @@ -28,7 +28,6 @@ import java.awt.FontMetrics; import java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.RenderingHints; -import java.awt.Shape; import java.awt.geom.Area; import java.awt.geom.Ellipse2D; import java.awt.geom.Point2D; @@ -59,7 +58,8 @@ import org.diylc.utils.Constants; @ComponentDescriptor(name = "Transistor (TO-92)", author = "Branislav Stojkovic", category = "Semiconductors", instanceNamePrefix = "Q", description = "Transistor with small plastic or epoxy body", zOrder = IDIYComponent.COMPONENT, keywordPolicy = KeywordPolicy.SHOW_VALUE, transformer = TO92Transformer.class, - enableCache = true) + enableCache = true, enableDatasheet = true, datasheetCreationStepCount = 2, + datasheetModelColumn = 1) public class TransistorTO92 extends AbstractTransistorPackage { private static final long serialVersionUID = 1L; @@ -83,6 +83,12 @@ public class TransistorTO92 extends AbstractTransistorPackage { borderColor = BORDER_COLOR; } + public TransistorTO92(String[] model) { + this(); + + applyModel(model); + } + @EditableProperty(name = "Pin spacing") public Size getPinSpacing() { if (pinSpacing == null) { @@ -195,18 +201,9 @@ public class TransistorTO92 extends AbstractTransistorPackage { } drawingObserver.stopTracking(); int pinSize = (int) PIN_SIZE.convertToPixels() / 2 * 2; - g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1f)); - - if (!outlineMode) { - for (Point2D point : controlPoints) { - Shape pin = new Ellipse2D.Double(point.getX() - pinSize / 2, point.getY() - pinSize / 2, pinSize, pinSize); - g2d.setColor(PIN_COLOR); - g2d.fill(pin); - g2d.setColor(PIN_BORDER_COLOR); - g2d.draw(pin); - } - } - + Theme theme = + (Theme) ConfigurationManager.getInstance().readObject(IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME); + Area mainArea = getBody()[0]; Composite oldComposite = applyAlpha(g2d, componentState); g2d.setColor(outlineMode ? Constants.TRANSPARENT_COLOR : bodyColor); @@ -216,8 +213,6 @@ public class TransistorTO92 extends AbstractTransistorPackage { g2d.setComposite(oldComposite); Color finalBorderColor; if (outlineMode) { - Theme theme = - (Theme) ConfigurationManager.getInstance().readObject(IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME); finalBorderColor = componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR : theme.getOutlineColor(); @@ -230,6 +225,9 @@ public class TransistorTO92 extends AbstractTransistorPackage { g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1)); g2d.draw(mainArea); + drawPins(g2d, pinSize, outlineMode ? null : PIN_COLOR, + outlineMode ? theme.getOutlineColor() : PIN_BORDER_COLOR); + // Draw label. g2d.setFont(project.getFont()); @@ -239,8 +237,6 @@ public class TransistorTO92 extends AbstractTransistorPackage { Color finalLabelColor; if (outlineMode) { - Theme theme = - (Theme) ConfigurationManager.getInstance().readObject(IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME); finalLabelColor = componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? LABEL_COLOR_SELECTED : theme.getOutlineColor(); diff --git a/diylc/diylc-library/src/main/resources/datasheets/TransistorTO1.datasheet b/diylc/diylc-library/src/main/resources/datasheets/TransistorTO1.datasheet new file mode 100644 index 00000000..359d3f75 --- /dev/null +++ b/diylc/diylc-library/src/main/resources/datasheets/TransistorTO1.datasheet @@ -0,0 +1,31 @@ +BJT (NPN),BC107,BJT_EBC +BJT (NPN),BC108,BJT_EBC +BJT (NPN),BC109,BJT_EBC +BJT (NPN),2N2222A,BJT_EBC +BJT (NPN),2N2369A,BJT_EBC +BJT (NPN),2N2219A,BJT_EBC +BJT (NPN),2N1613,BJT_EBC +BJT (NPN),2N1711,BJT_EBC +BJT (NPN),2N3053,BJT_EBC +BJT (NPN),2N3866,BJT_EBC +BJT (NPN),BFY51,BJT_EBC +BJT (PNP),BC177,BJT_EBC +BJT (PNP),BC178,BJT_EBC +BJT (PNP),BC179,BJT_EBC +BJT (PNP),2N2907A,BJT_EBC +BJT (PNP),2N2905A,BJT_EBC +Germanium (NPN),AC127,BJT_EBC +Germanium (NPN),AC176,BJT_EBC +Germanium (NPN),AC187,BJT_EBC +Germanium (NPN),2N1308,BJT_EBC +Germanium (PNP),AC126,BJT_EBC +Germanium (PNP),AC128,BJT_EBC +Germanium (PNP),AC188,BJT_EBC +Germanium (PNP),OC44,BJT_EBC +Germanium (PNP),OC45,BJT_EBC +Germanium (PNP),OC71,BJT_EBC +Germanium (PNP),OC75,BJT_EBC +Germanium (PNP),OC76,BJT_EBC +Germanium (PNP),OC81,BJT_EBC +Germanium (PNP),2N404,BJT_EBC +Germanium (PNP),2N1305,BJT_EBC diff --git a/diylc/diylc-library/src/main/resources/datasheets/TransistorTO126.datasheet b/diylc/diylc-library/src/main/resources/datasheets/TransistorTO126.datasheet new file mode 100644 index 00000000..59e63e38 --- /dev/null +++ b/diylc/diylc-library/src/main/resources/datasheets/TransistorTO126.datasheet @@ -0,0 +1,22 @@ +BJT (NPN),BD135,BJT_ECB +BJT (NPN),BD137,BJT_ECB +BJT (NPN),BD139,BJT_ECB +BJT (NPN),BD237,BJT_ECB +BJT (NPN),MJE340,BJT_ECB +BJT (NPN),MJE180,BJT_ECB +BJT (NPN),2SC3423,BJT_ECB +BJT (NPN),KSC3503,BJT_ECB +BJT (NPN),2SD669A,BJT_ECB +BJT (NPN),BF469,BJT_ECB +BJT (PNP),BD136,BJT_ECB +BJT (PNP),BD138,BJT_ECB +BJT (PNP),BD140,BJT_ECB +BJT (PNP),BD238,BJT_ECB +BJT (PNP),MJE350,BJT_ECB +BJT (PNP),MJE170,BJT_ECB +BJT (PNP),2SA1360,BJT_ECB +BJT (PNP),KSA1381,BJT_ECB +BJT (PNP),2SB649A,BJT_ECB +BJT (PNP),BF470,BJT_ECB +Darlington (NPN),BD681,BJT_ECB +Darlington (PNP),BD682,BJT_ECB diff --git a/diylc/diylc-library/src/main/resources/datasheets/TransistorTO220.datasheet b/diylc/diylc-library/src/main/resources/datasheets/TransistorTO220.datasheet new file mode 100644 index 00000000..3db21328 --- /dev/null +++ b/diylc/diylc-library/src/main/resources/datasheets/TransistorTO220.datasheet @@ -0,0 +1,67 @@ +BJT (NPN),TIP29C,BJT_BCE +BJT (NPN),TIP31C,BJT_BCE +BJT (NPN),TIP41C,BJT_BCE +BJT (NPN),MJE3055T,BJT_BCE +BJT (NPN),MJE15028,BJT_BCE +BJT (NPN),MJE15030,BJT_BCE +BJT (NPN),MJE15032,BJT_BCE +BJT (NPN),BD243C,BJT_BCE +BJT (NPN),BD911,BJT_BCE +BJT (PNP),TIP30C,BJT_BCE +BJT (PNP),TIP32C,BJT_BCE +BJT (PNP),TIP42C,BJT_BCE +BJT (PNP),MJE2955T,BJT_BCE +BJT (PNP),MJE15029,BJT_BCE +BJT (PNP),MJE15031,BJT_BCE +BJT (PNP),MJE15033,BJT_BCE +BJT (PNP),BD244C,BJT_BCE +BJT (PNP),BD912,BJT_BCE +Darlington (NPN),TIP120,BJT_BCE +Darlington (NPN),TIP121,BJT_BCE +Darlington (NPN),TIP122,BJT_BCE +Darlington (PNP),TIP125,BJT_BCE +Darlington (PNP),TIP126,BJT_BCE +Darlington (PNP),TIP127,BJT_BCE +MOSFET (N),IRF510,MOSFET_GDS +MOSFET (N),IRF520,MOSFET_GDS +MOSFET (N),IRF530,MOSFET_GDS +MOSFET (N),IRF540N,MOSFET_GDS +MOSFET (N),IRF610,MOSFET_GDS +MOSFET (N),IRF640,MOSFET_GDS +MOSFET (N),IRF840,MOSFET_GDS +MOSFET (N),IRFZ44N,MOSFET_GDS +MOSFET (N),IRLZ44N,MOSFET_GDS +MOSFET (N),IRF3205,MOSFET_GDS +MOSFET (N),FQP30N06L,MOSFET_GDS +MOSFET (P),IRF9530,MOSFET_GDS +MOSFET (P),IRF9540N,MOSFET_GDS +MOSFET (P),IRF9610,MOSFET_GDS +MOSFET (P),IRF9640,MOSFET_GDS +Regulator (+),7805,REGULATOR_IGO +Regulator (+),7806,REGULATOR_IGO +Regulator (+),7808,REGULATOR_IGO +Regulator (+),7809,REGULATOR_IGO +Regulator (+),7812,REGULATOR_IGO +Regulator (+),7815,REGULATOR_IGO +Regulator (+),7818,REGULATOR_IGO +Regulator (+),7824,REGULATOR_IGO +Regulator (+),LM317T,REGULATOR_AOI +Regulator (+),LM338T,REGULATOR_AOI +Regulator (+),LM350T,REGULATOR_AOI +Regulator (+),LM1084-ADJ,REGULATOR_AOI +Regulator (+),LM1085-ADJ,REGULATOR_AOI +Regulator (+),LM1086-ADJ,REGULATOR_AOI +Regulator (+),LM1086-3.3,REGULATOR_GOI +Regulator (+),LM1086-5.0,REGULATOR_GOI +Regulator (+),LM1117T-ADJ,REGULATOR_AOI +Regulator (+),LM1117T-3.3,REGULATOR_GOI +Regulator (+),LM1117T-5.0,REGULATOR_GOI +Regulator (+),LD1117V,REGULATOR_AOI +Regulator (+),LD1117V33,REGULATOR_GOI +Regulator (+),LD1117V50,REGULATOR_GOI +Regulator (+),LM2940CT-5.0,REGULATOR_IGO +Regulator (+),LM2940CT-12,REGULATOR_IGO +Regulator (-),7905,REGULATOR_GIO +Regulator (-),7912,REGULATOR_GIO +Regulator (-),7915,REGULATOR_GIO +Regulator (-),LM337T,REGULATOR_AIO diff --git a/diylc/diylc-library/src/main/resources/datasheets/TransistorTO3.datasheet b/diylc/diylc-library/src/main/resources/datasheets/TransistorTO3.datasheet new file mode 100644 index 00000000..d9709d2f --- /dev/null +++ b/diylc/diylc-library/src/main/resources/datasheets/TransistorTO3.datasheet @@ -0,0 +1,27 @@ +BJT (NPN),2N3055,BJT_BEC +BJT (NPN),2N3442,BJT_BEC +BJT (NPN),2N3773,BJT_BEC +BJT (NPN),MJ15003,BJT_BEC +BJT (NPN),MJ15015,BJT_BEC +BJT (NPN),MJ15022,BJT_BEC +BJT (NPN),MJ15024,BJT_BEC +BJT (PNP),MJ2955,BJT_BEC +BJT (PNP),2N6609,BJT_BEC +BJT (PNP),MJ15004,BJT_BEC +BJT (PNP),MJ15016,BJT_BEC +BJT (PNP),MJ15023,BJT_BEC +BJT (PNP),MJ15025,BJT_BEC +Darlington (NPN),MJ11016,BJT_BEC +Darlington (NPN),MJ11032,BJT_BEC +Darlington (PNP),MJ11015,BJT_BEC +Darlington (PNP),MJ11033,BJT_BEC +MOSFET (N),IRF150,MOSFET_GSD +Regulator (+),LM317K,REGULATOR_AIO +Regulator (+),LM338K,REGULATOR_AIO +Regulator (+),LM350K,REGULATOR_AIO +Regulator (+),LM309K,REGULATOR_IOG +Regulator (+),LM323K,REGULATOR_IOG +Regulator (+),LM340K-5.0,REGULATOR_IOG +Regulator (+),LM340K-12,REGULATOR_IOG +Regulator (+),LM340K-15,REGULATOR_IOG +Regulator (-),LM337K,REGULATOR_AOI diff --git a/diylc/diylc-library/src/main/resources/datasheets/TransistorTO92.datasheet b/diylc/diylc-library/src/main/resources/datasheets/TransistorTO92.datasheet new file mode 100644 index 00000000..28ac6877 --- /dev/null +++ b/diylc/diylc-library/src/main/resources/datasheets/TransistorTO92.datasheet @@ -0,0 +1,109 @@ +BJT (NPN),2N3904,BJT_EBC +BJT (NPN),2N4401,BJT_EBC +BJT (NPN),PN2222A,BJT_EBC +BJT (NPN),2N4124,BJT_EBC +BJT (NPN),2N5088,BJT_EBC +BJT (NPN),2N5089,BJT_EBC +BJT (NPN),2N5210,BJT_EBC +BJT (NPN),2N5551,BJT_EBC +BJT (NPN),MPSA06,BJT_EBC +BJT (NPN),MPSA18,BJT_EBC +BJT (NPN),MPSA42,BJT_EBC +BJT (NPN),MPS5179,BJT_EBC +BJT (NPN),S8050,BJT_EBC +BJT (NPN),S9013,BJT_EBC +BJT (NPN),S9014,BJT_EBC +BJT (NPN),S9018,BJT_EBC +BJT (NPN),BC546,BJT_CBE +BJT (NPN),BC547,BJT_CBE +BJT (NPN),BC548,BJT_CBE +BJT (NPN),BC549,BJT_CBE +BJT (NPN),BC550,BJT_CBE +BJT (NPN),BC337,BJT_CBE +BJT (NPN),BC182,BJT_CBE +BJT (NPN),BC184,BJT_CBE +BJT (NPN),BC239,BJT_CBE +BJT (NPN),P2N2222A,BJT_CBE +BJT (NPN),BC639,BJT_ECB +BJT (NPN),BC182L,BJT_ECB +BJT (NPN),BC184L,BJT_ECB +BJT (NPN),2SC1815,BJT_ECB +BJT (NPN),2SC945,BJT_ECB +BJT (NPN),2SC2240,BJT_ECB +BJT (NPN),2SC1845,BJT_ECB +BJT (NPN),KSC1845,BJT_ECB +BJT (NPN),2SC2458,BJT_ECB +BJT (NPN),BF199,BJT_CEB +BJT (NPN),BF494,BJT_CEB +BJT (NPN),MPSH10,BJT_BEC +BJT (PNP),2N3906,BJT_EBC +BJT (PNP),2N4403,BJT_EBC +BJT (PNP),PN2907A,BJT_EBC +BJT (PNP),2N4126,BJT_EBC +BJT (PNP),2N5087,BJT_EBC +BJT (PNP),2N5401,BJT_EBC +BJT (PNP),MPSA56,BJT_EBC +BJT (PNP),MPSA92,BJT_EBC +BJT (PNP),S8550,BJT_EBC +BJT (PNP),S9012,BJT_EBC +BJT (PNP),S9015,BJT_EBC +BJT (PNP),KSP2907A,BJT_EBC +BJT (PNP),BC556,BJT_CBE +BJT (PNP),BC557,BJT_CBE +BJT (PNP),BC558,BJT_CBE +BJT (PNP),BC559,BJT_CBE +BJT (PNP),BC560,BJT_CBE +BJT (PNP),BC327,BJT_CBE +BJT (PNP),BC212,BJT_CBE +BJT (PNP),BC214,BJT_CBE +BJT (PNP),BC640,BJT_ECB +BJT (PNP),2SA1015,BJT_ECB +BJT (PNP),2SA970,BJT_ECB +BJT (PNP),2SA992,BJT_ECB +BJT (PNP),KSA992,BJT_ECB +BJT (PNP),KSP2907AC,BJT_ECB +Darlington (NPN),MPSA13,BJT_EBC +Darlington (NPN),MPSA14,BJT_EBC +Darlington (PNP),MPSA63,BJT_EBC +Darlington (PNP),MPSA64,BJT_EBC +JFET (N),J201,JFET_DSG +JFET (N),J202,JFET_DSG +JFET (N),J111,JFET_DSG +JFET (N),J112,JFET_DSG +JFET (N),J113,JFET_DSG +JFET (N),J310,JFET_DSG +JFET (N),2N5457,JFET_DSG +JFET (N),2N5458,JFET_DSG +JFET (N),2N5459,JFET_DSG +JFET (N),2N5484,JFET_DSG +JFET (N),2N5485,JFET_DSG +JFET (N),2N5486,JFET_DSG +JFET (N),PN4416,JFET_DSG +JFET (N),MPF102,JFET_DSG +JFET (N),BF245A,JFET_DSG +JFET (N),BF245B,JFET_DSG +JFET (N),BF245C,JFET_DSG +JFET (N),2N3819,JFET_SGD +JFET (N),BF256B,JFET_GSD +JFET (N),2SK170,JFET_DGS +JFET (N),LSK170,JFET_DGS +JFET (P),J174,JFET_DGS +JFET (P),J175,JFET_DGS +JFET (P),J176,JFET_DGS +JFET (P),2N3820,JFET_DGS +JFET (P),2N5460,JFET_SDG +MOSFET (N),2N7000,MOSFET_SGD +MOSFET (N),LND150,MOSFET_SGD +MOSFET (N),BS170,MOSFET_DGS +Regulator (+),78L05,REGULATOR_OGI +Regulator (+),78L09,REGULATOR_OGI +Regulator (+),78L12,REGULATOR_OGI +Regulator (+),78L15,REGULATOR_OGI +Regulator (+),LP2950-5.0,REGULATOR_OGI +Regulator (+),LM2936Z-5.0,REGULATOR_OGI +Regulator (+),LM317LZ,REGULATOR_AOI +Regulator (+),LR8,REGULATOR_IOA +Regulator (-),79L05,REGULATOR_GIO +Regulator (-),79L12,REGULATOR_GIO +Regulator (-),79L15,REGULATOR_GIO +Regulator (-),LM337LZ,REGULATOR_AOI diff --git a/diylc/diylc-library/src/test/java/org/diylc/components/semiconductors/TransistorDatasheetTest.java b/diylc/diylc-library/src/test/java/org/diylc/components/semiconductors/TransistorDatasheetTest.java new file mode 100644 index 00000000..5f749917 --- /dev/null +++ b/diylc/diylc-library/src/test/java/org/diylc/components/semiconductors/TransistorDatasheetTest.java @@ -0,0 +1,86 @@ +/* + + DIY Layout Creator (DIYLC). + Copyright (c) 2009-2025 held jointly by the individual authors. + + This file is part of DIYLC. + + DIYLC is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + DIYLC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with DIYLC. If not, see . + +*/ +package org.diylc.components.semiconductors; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.diylc.core.IDIYComponent; +import org.diylc.presenter.DatasheetService; +import org.junit.Assert; +import org.junit.Test; + +/** The datasheets of all transistor packages, which share one row format. */ +public class TransistorDatasheetTest { + + private static final List>> PACKAGES = + Arrays.asList(TransistorTO1.class, TransistorTO3.class, TransistorTO92.class, + TransistorTO126.class, TransistorTO220.class); + + @Test + public void everyRowApplies() throws Exception { + for (Class> type : PACKAGES) { + for (String[] row : datasheet(type)) { + String context = type.getSimpleName() + ": " + String.join(",", row); + Assert.assertEquals(context, 3, row.length); + IDIYComponent transistor = + type.getConstructor(String[].class).newInstance((Object) row); + Assert.assertEquals(context, row[1], transistor.getValue()); + String pinout = TransistorPinout.valueOf(row[2]).toPinout(); + for (int i = 0; i < pinout.length(); i++) { + Assert.assertEquals(context, pinout.substring(i, i + 1), + transistor.getControlPointNodeName(i)); + } + } + } + } + + @Test + public void partNumbersAreUnique() { + for (Class> type : PACKAGES) { + Set parts = new HashSet(); + for (String[] row : datasheet(type)) { + Assert.assertTrue(type.getSimpleName() + " repeats " + row[1], + parts.add(row[1].toUpperCase())); + } + } + } + + @Test + public void partIsFoundByNumberNotByGroup() { + DatasheetService service = DatasheetService.getInstance(); + for (Class> type : PACKAGES) { + String[] first = datasheet(type).get(0); + Assert.assertEquals(1, service.findSeries(type, first[1]).size()); + Assert.assertTrue(service.findSeries(type, first[0]).isEmpty()); + } + } + + private static List datasheet(Class> type) { + List datasheet = DatasheetService.getInstance().loadDatasheet(type); + Assert.assertNotNull(type.getSimpleName(), datasheet); + Assert.assertFalse(type.getSimpleName(), datasheet.isEmpty()); + return datasheet; + } +} diff --git a/diylc/diylc-library/src/test/java/org/diylc/components/semiconductors/TransistorPinoutTest.java b/diylc/diylc-library/src/test/java/org/diylc/components/semiconductors/TransistorPinoutTest.java new file mode 100644 index 00000000..bab07b27 --- /dev/null +++ b/diylc/diylc-library/src/test/java/org/diylc/components/semiconductors/TransistorPinoutTest.java @@ -0,0 +1,70 @@ +/* + + DIY Layout Creator (DIYLC). + Copyright (c) 2009-2025 held jointly by the individual authors. + + This file is part of DIYLC. + + DIYLC is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + DIYLC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with DIYLC. If not, see . + +*/ +package org.diylc.components.semiconductors; + +import org.junit.Assert; +import org.junit.Test; + +public class TransistorPinoutTest { + + @Test + public void bjtPinsMapToCollectorBaseEmitter() { + assertSpiceNodes(TransistorPinout.BJT_EBC, 2, 1, 0); + assertSpiceNodes(TransistorPinout.BJT_CBE, 0, 1, 2); + assertSpiceNodes(TransistorPinout.BJT_BCE, 1, 0, 2); + assertSpiceNodes(TransistorPinout.BJT_ECB, 2, 0, 1); + } + + @Test + public void fetPinsMapToDrainGateSource() { + assertSpiceNodes(TransistorPinout.JFET_DSG, 0, 2, 1); + assertSpiceNodes(TransistorPinout.JFET_GSD, 1, 2, 0); + assertSpiceNodes(TransistorPinout.JFET_SGD, 2, 1, 0); + assertSpiceNodes(TransistorPinout.MOSFET_GDS, 1, 0, 2); + } + + @Test + public void regulatorPinsKeepTheirOrder() { + assertSpiceNodes(TransistorPinout.REGULATOR_IGO, 0, 1, 2); + } + + /** Every value names three distinct pins with letters its type knows. */ + @Test + public void everyPinoutIsAPermutationOfItsRoles() { + for (TransistorPinout pinout : TransistorPinout.values()) { + String pins = pinout.toPinout(); + Assert.assertEquals(pinout.name(), 3, pins.length()); + Assert.assertEquals(pinout.name(), 3, pins.chars().distinct().count()); + String roles = pinout.name().startsWith("BJT") ? "BCE" + : pinout.name().startsWith("REGULATOR") ? "IOGA" : "DGS"; + for (char c : pins.toCharArray()) { + Assert.assertTrue(pinout.name(), roles.indexOf(c) >= 0); + } + } + } + + private static void assertSpiceNodes(TransistorPinout pinout, int... expected) { + for (int i = 0; i < expected.length; i++) { + Assert.assertEquals(pinout + " pin " + i, expected[i], pinout.mapToSpiceNode(i)); + } + } +} diff --git a/diylc/diylc-library/src/test/java/org/diylc/components/semiconductors/TransistorTO3Test.java b/diylc/diylc-library/src/test/java/org/diylc/components/semiconductors/TransistorTO3Test.java new file mode 100644 index 00000000..5da84610 --- /dev/null +++ b/diylc/diylc-library/src/test/java/org/diylc/components/semiconductors/TransistorTO3Test.java @@ -0,0 +1,86 @@ +/* + + DIY Layout Creator (DIYLC). + Copyright (c) 2009-2025 held jointly by the individual authors. + + This file is part of DIYLC. + + DIYLC is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + DIYLC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with DIYLC. If not, see . + +*/ +package org.diylc.components.semiconductors; + +import java.awt.geom.Area; +import java.awt.geom.Point2D; +import java.lang.reflect.Field; + +import org.diylc.common.Display; +import org.diylc.common.Orientation; +import org.diylc.components.semiconductors.AbstractTransistorPackage.TransistorDisplay; +import org.junit.Assert; +import org.junit.Test; + +public class TransistorTO3Test { + + @Test + public void caseIsReachedThroughAMountingHole() { + for (Orientation orientation : Orientation.values()) { + TransistorTO3 transistor = new TransistorTO3(); + transistor.setOrientation(orientation); + Point2D casePoint = transistor.getControlPoint(2); + Area body = transistor.getBody()[0]; + Assert.assertTrue(orientation.name(), body.getBounds2D().contains(casePoint)); + Assert.assertFalse(orientation.name(), body.contains(casePoint)); + } + } + + @Test + public void fileWithoutCasePointGainsIt() throws Exception { + TransistorTO3 expected = new TransistorTO3(); + expected.setOrientation(Orientation._90); + TransistorTO3 legacy = new TransistorTO3(); + legacy.setOrientation(Orientation._90); + setField(legacy, "controlPoints", + new Point2D[] {legacy.getControlPoint(0), legacy.getControlPoint(1)}); + + Assert.assertEquals(3, legacy.getControlPointCount()); + Assert.assertEquals(expected.getControlPoint(2), legacy.getControlPoint(2)); + } + + @Test + public void nodeNamesFollowThePinout() { + TransistorTO3 transistor = new TransistorTO3(); + Assert.assertEquals("1", transistor.getControlPointNodeName(0)); + Assert.assertEquals("3", transistor.getControlPointNodeName(2)); + transistor.setPinout(TransistorPinout.BJT_BEC); + Assert.assertEquals("B", transistor.getControlPointNodeName(0)); + Assert.assertEquals("E", transistor.getControlPointNodeName(1)); + Assert.assertEquals("C", transistor.getControlPointNodeName(2)); + } + + @SuppressWarnings("deprecation") + @Test + public void displayIsReadFromTheLegacyField() throws Exception { + TransistorTO3 transistor = new TransistorTO3(); + transistor.setDisplay(Display.BOTH); + setField(transistor, "transistorDisplay", null); + Assert.assertEquals(TransistorDisplay.BOTH, transistor.getTransistorDisplay()); + } + + private static void setField(Object target, String name, Object value) throws Exception { + Field field = TransistorTO3.class.getDeclaredField(name); + field.setAccessible(true); + field.set(target, value); + } +} diff --git a/diylc/diylc-library/src/test/resources/pinout-drivers.txt b/diylc/diylc-library/src/test/resources/pinout-drivers.txt index c260ee84..05587892 100644 --- a/diylc/diylc-library/src/test/resources/pinout-drivers.txt +++ b/diylc/diylc-library/src/test/resources/pinout-drivers.txt @@ -152,7 +152,7 @@ semiconductors.SchottkyDiodeSymbol = fixed semiconductors.TransistorTO1 = Pinout semiconductors.TransistorTO126 = Pinout semiconductors.TransistorTO220 = Pinout -semiconductors.TransistorTO3 = fixed +semiconductors.TransistorTO3 = Pinout semiconductors.TransistorTO92 = Pinout semiconductors.ZenerDiodeSymbol = fixed shapes.Ellipse = none diff --git a/diylc/docs/plans/transistor-pinouts.md b/diylc/docs/plans/transistor-pinouts.md new file mode 100644 index 00000000..02ffb7db --- /dev/null +++ b/diylc/docs/plans/transistor-pinouts.md @@ -0,0 +1,230 @@ +# Transistor Pinouts and Datasheet Models + +Giving every transistor package a pinout, and applying a known part's pinout from a datasheet. + +## 1. Goal + +Builds on [DIP IC Pin Names](dip-ic-pin-names.md). A transistor whose pins are anonymous gives the +netlist, the AI and the schematic view nothing to tell a base from a collector. The packages that +extend `AbstractTransistorPackage` (TO-1, TO-92, TO-126, TO-220) already have a "Pinout" property, +but users rarely set it: of 35 package transistors in the sample corpus, 6 have a pinout. A +datasheet of the parts DIYers actually use (guitar pedals, effects, hi-fi, radio, synth) sets the +pinout and the value in one step, from the toolbox or from the AI. + +TO-3 was the one package without a pinout: a separate class with two numbered pins and no way to +reach the case, which is the collector. + +## 2. Design decisions + +| # | Decision | Choice | Rationale | +|---|---|---|---| +| T1 | Datasheet row | `group, part, pinout`, e.g. `BJT (NPN),2N3904,BJT_EBC`. The pinout column is a `TransistorPinout` constant name | The enum already carries everything a part needs. Constant names are unambiguous and greppable; the display strings (`E-B-C BJT`) are not. | +| T2 | Model identity | `datasheetModelColumn = 1`, `datasheetCreationStepCount = 2` on every package, as on the ICs | The toolbox groups by family while the AI names the part. | +| T3 | `applyModel` | Sets value and pinout only, implemented once in `AbstractTransistorPackage` (and in `TransistorTO3`, which does not extend it). Each package has a `(String[] model)` constructor | The datasheet says what the part is, not how it is drawn. | +| T4 | Pin order | A pinout lists control points in order, and control point 0 is pin 1: for TO-92 facing the flat side, for TO-126 and TO-220 facing the printed front, legs down, left to right. Rows are written as the manufacturer's pin 1, 2, 3 | Already the convention of the TO-92 and TO-220 `@AiNote`s, so existing projects keep their meaning. | +| T5 | One package per datasheet | A part goes in the datasheet of the package it ships in. `TransistorTO1` is the only metal can, so it also holds TO-18, TO-5, TO-39 and the germanium cans | Datasheets are per class. | +| T6 | SPICE mapping | `TransistorPinout.mapToSpiceNode` places each letter in SPICE order (C B E, D G S); regulators keep their own order | Replaces a hand-written switch with fall-throughs that had no `BJT_ECB` case, so ECB parts went out in the wrong order. Shared by `AbstractTransistorPackage` and `TransistorTO3`. | +| T7 | TO-3 case | A third control point at the centre of the mounting hole on the side the pins are offset towards. The pinout lists pin 1, pin 2, case (`BJT_BEC` for a 2N3055) | A wire or solder lug at the hole puts the collector into the netlist. Without it a TO-3 collector could never be connected. | +| T8 | TO-3 compatibility | Old files hold a two-point `controlPoints`; `getControlPoints()` extends it lazily and places the case point from the two pins. `TransistorTO3` keeps extending `AbstractLabeledComponent` | Moving it under `AbstractTransistorPackage` would change field types. Lazy migration is the established pattern. | +| T9 | TO-3 display | New `transistorDisplay` field (`TransistorDisplay`), shown as "Display", read lazily from the deprecated `display` (`Display`) field | Adds the Pinout option the other packages have without changing a serialized field's type. All old `Display` values exist in `TransistorDisplay`. | +| T10 | Pins over the body | Every package draws its pins after the body: `AbstractTransistorPackage.drawPins` for TO-1, TO-92, TO-126 and TO-220, its own loop in `TransistorTO3`. Round pins in the TO-92 colours (`#00B2EE`, border one shade darker), outline only in outline mode; folded TO-126/TO-220 leads use the same colours instead of `METAL_COLOR`. TO-3 pinout letters sit beside each pin and beside the case hole, towards the body centre | Bodies used to hide the pins at full alpha and tint them below it, so pin colour varied with the body, and the folded leads were grey. Now pins look the same on every package and show at any alpha, as on `MultiwattIC`. | +| T11 | New pinout values | Added only when a sourced part needs them, inserted next to their family in the enum | Values are serialized by name, so order is free. Added: `BJT_BEC` (TO-3 transistors, MPSH10), `BJT_CEB` (BF199, BF494), `REGULATOR_AIO` (LM337T, LM317K), `REGULATOR_IOG` (TO-3 fixed regulators). | + +### Explicitly out of scope + +- TO-247, TO-3P, TO-264 packages (2SC5200, TIP3055, IRFP240, 2SK1058) - no package in DIYLC yet. +- SCRs, triacs and TL431-style references: their roles are not in `TransistorPinout`. +- SPICE export of regulators (`getPrefix` returns `R`, a resistor). Pre-existing, left as is. +- Translating datasheet group names, as for the ICs. + +## 3. Changes + +### diylc-library + +- `TransistorPinout`: `mapToSpiceNode(int)` (T6), `BJT_BEC` (T7). +- `AbstractTransistorPackage`: `implements IDatasheetSupport`, `applyModel`; `mapToSpiceNode` + delegates to the enum; `drawPins` (T10). +- `TransistorTO1`, `TransistorTO92`, `TransistorTO126`, `TransistorTO220`: datasheet attributes on + the descriptor, a model constructor, and pins drawn through `drawPins` after the body (T10). +- `TransistorTO3`: case point (T7, T8), `pinout`, `ISpiceMapper`, `IDatasheetSupport`, model + constructor, `transistorDisplay` (T9), pins over the case and pinout letters (T10). +- `datasheets/TransistorTO1.datasheet`, `TransistorTO3`, `TransistorTO92`, `TransistorTO126`, + `TransistorTO220`: rows per T1, each read from a manufacturer pin table or two independent + sources. + +### Generated + +- `catalog_full.json` regenerated (run `ComponentCatalogGenerator` from `diylc-swing`; with a + hand-built classpath it reads the version as 5.0.0, so check that the `version` line matches the + latest release in `update.xml`). +- `diylc-library/src/test/resources/pinout-drivers.txt`: TO-3 is driven by "Pinout". + +## 4. Datasheet inventory + +Groups: `BJT (NPN)`, `BJT (PNP)`, `Darlington (NPN)`, `Darlington (PNP)`, `Germanium (NPN)`, +`Germanium (PNP)`, `JFET (N)`, `JFET (P)`, `MOSFET (N)`, `MOSFET (P)`, `Regulator`. + +`TransistorTO1.datasheet` holds 31 parts, all `BJT_EBC`: + +| Group | Parts | +|---|---| +| BJT (NPN) | BC107, BC108, BC109, 2N2222A, 2N2369A, 2N2219A, 2N1613, 2N1711, 2N3053, 2N3866, BFY51 | +| BJT (PNP) | BC177, BC178, BC179, 2N2907A, 2N2905A | +| Germanium (NPN) | AC127, AC176, AC187, 2N1308 | +| Germanium (PNP) | AC126, AC128, AC188, OC44, OC45, OC71, OC75, OC76, OC81, 2N404, 2N1305 | + +TO-1 sourcing and modelling notes: + +- Read from Mullard/Valvo data-book scans (AC, OC), Central and Philips datasheets (silicon cans), + and TI bulletin DL-S 1136 (2N1305/2N1308). 2N2219A, 2N2905A and BFY51 were seen only through + search snippets of the Philips sheets - the weakest rows. +- Seen from the bottom, E-B-C run clockwise from the tab, so from above (DIYLC's view) they run + counter-clockwise: control points 0, 1, 2 in the default orientation. The AC cans have B at the + apex of the triangle, matching control point 1. No tab is drawn. +- The OC series are glass envelopes with in-line leads (wider B-C gap, red dot at the collector), not + TO-1 cans; they are listed here because TO-1 is DIYLC's only small round package and the lead + order is the same. +- On 2N1305/2N1308 the case is the base, not the collector. +- Left out, no manufacturer drawing or two agreeing sources: AC125, OC72, OC139/140, NKT275, 2N527, + 2N388A, 2N2613, 2SB75, 2SB175, AC151, 2N5320. Soviet MP39-MP42 use a flanged can that is not + TO-1-like. 2N4416 has four leads (S-D-G-case) and cannot fit. + +`TransistorTO92.datasheet` bipolar rows, 68 parts: + +| Group | Pinout | Parts | +|---|---|---| +| BJT (NPN) | `BJT_EBC` | 2N3904, 2N4401, PN2222A, 2N4124, 2N5088, 2N5089, 2N5210, 2N5551, MPSA06, MPSA18, MPSA42, MPS5179, S8050, S9013, S9014, S9018 | +| BJT (NPN) | `BJT_CBE` | BC546-BC550, BC337, BC182, BC184, BC239, P2N2222A | +| BJT (NPN) | `BJT_ECB` | BC639, BC182L, BC184L, 2SC1815, 2SC945, 2SC2240, 2SC1845, KSC1845, 2SC2458 | +| BJT (NPN) | `BJT_CEB` / `BJT_BEC` | BF199, BF494 / MPSH10 | +| BJT (PNP) | `BJT_EBC` | 2N3906, 2N4403, PN2907A, 2N4126, 2N5087, 2N5401, MPSA56, MPSA92, S8550, S9012, S9015, KSP2907A | +| BJT (PNP) | `BJT_CBE` | BC556-BC560, BC327, BC212, BC214 | +| BJT (PNP) | `BJT_ECB` | BC640, 2SA1015, 2SA970, 2SA992, KSA992, KSP2907AC | +| Darlington (NPN) / (PNP) | `BJT_EBC` | MPSA13, MPSA14 / MPSA63, MPSA64 | + +TO-92 sourcing notes: + +- **Philips/NXP (SOT54) and CDIL number TO-92 pins in reverse**, from the right as seen facing the + flat side; onsemi, Central, Toshiba, NEC, UTC and MCC number from the left. Philips "1 emitter 2 + base 3 collector" on a BC547 is physically C-B-E. Copying Philips or CDIL numbers literally is the + usual source of wrong pinouts online; rows here are the physical order. onsemi CASE 29 style 1 = + EBC, style 14 = ECB, style 17 = CBE. +- Same name, different pinout, each listed under its full name: BC182L/BC184L (ECB) vs BC182/BC184 + (CBE); P2N2222A (CBE) vs PN2222A (EBC); KSP2907AC (ECB) vs KSP2907A (EBC); MPS5179 (EBC) vs + PN5179 (BEC, not listed). onsemi's MPSA92 package page prints style 14, contradicting its own + symbol and Central (EBC). +- 2N5179 itself is TO-72 only. 2SC2458 is Toshiba's smaller 2-4E1A body at 1.27 mm pitch. +- Weakest rows: BF494 (one Philips sheet plus a search quote), 2SC1845 and 2SA992 (second-source + and NEC text copies), 2N4124/2N4126 (Central only), BC239 (CDIL only). +- Left out: BC212L/BC214L (CDIL table is an image; inferred only), 2SC828 (second source only), + PN5179, KTC3198/KTA1266 (mirror previews only), 8050S/8550S (ECB at UTC; 8550S not read). + +`TransistorTO126.datasheet` holds 22 parts, all `BJT_ECB`: BD135/137/139, BD136/138/140, +BD237/238, MJE340/350, MJE170/180, 2SC3423/2SA1360, KSC3503/KSA1381, 2SD669A/2SB649A, BF469/470, +and the BD681/682 darlingtons. + +`TransistorTO220.datasheet` holds 67 parts: + +| Group | Parts | Pinout | +|---|---|---| +| BJT (NPN) / (PNP) | TIP29C-TIP42C, MJE3055T/2955T, MJE15028-15033, BD243C/244C, BD911/912 | `BJT_BCE` | +| Darlington (NPN) / (PNP) | TIP120-122, TIP125-127 | `BJT_BCE` | +| MOSFET (N) / (P) | IRF510, IRF520, IRF530, IRF540N, IRF610, IRF640, IRF840, IRFZ44N, IRLZ44N, IRF3205, FQP30N06L; IRF9530, IRF9540N, IRF9610, IRF9640 | `MOSFET_GDS` | +| Regulator (+) | 7805-7824 and LM2940CT-5.0/-12 | `REGULATOR_IGO` | +| Regulator (+) | LM317T, LM338T, LM350T, LM1084/1085/1086-ADJ, LM1117T-ADJ, LD1117V | `REGULATOR_AOI` | +| Regulator (+) | LM1086-3.3/-5.0, LM1117T-3.3/-5.0, LD1117V33/V50 | `REGULATOR_GOI` | +| Regulator (-) | 7905, 7912, 7915 / LM337T | `REGULATOR_GIO` / `REGULATOR_AIO` | + +`TransistorTO3.datasheet` holds 27 parts; the pinout's third letter is the case: + +| Group | Parts | Pinout | +|---|---|---| +| BJT (NPN) / (PNP) | 2N3055, 2N3442, 2N3773, MJ15003, MJ15015, MJ15022, MJ15024; MJ2955, 2N6609, MJ15004, MJ15016, MJ15023, MJ15025 | `BJT_BEC` | +| Darlington (NPN) / (PNP) | MJ11016, MJ11032; MJ11015, MJ11033 | `BJT_BEC` | +| MOSFET (N) | IRF150 | `MOSFET_GSD` | +| Regulator (+) | LM317K, LM338K, LM350K | `REGULATOR_AIO` | +| Regulator (+) | LM309K, LM323K, LM340K-5.0/-12/-15 | `REGULATOR_IOG` | +| Regulator (-) | LM337K | `REGULATOR_AOI` | + +Power package sourcing notes: + +- Read mostly from onsemi (TO-225 style 1, TO-220 CASE 221A styles 1 and 5, TO-3 CASE 1-07 style 1) + and TI regulator pin tables. Rows taken from a family rule rather than the part's own sheet: + BD136/138/140, MJE170/180, BD682, BD238, 2SA1360, BF469, TIP29C/30C, BD911/912, the IRF parts + other than IRF510/IRF540N, MJ15015/16, 2N6609, LM350K. IRF150 is from two search snippets. +- TO-3 geometry from onsemi CASE 1-07 (with ST and Central agreeing): pins 10.92 mm apart on a line + square to the hole axis, about 1.8 mm off centre towards the nearer hole. Seen from above with the + holes left and right and the pins left of centre, pin 1 is the upper pin - control point 0 in the + default orientation, so the TO-3 geometry needed no change. ST numbers TO-3 pins the other way + round (its LM137 "1 = Output"); the rows follow onsemi/TI/National, whose pin functions match ST's + physically. +- LM309K/LM323K/LM340K: TI and National draw the pin positions but give no pin numbers; numbers were + assigned from the physical position. The weakest TO-3 rows. +- Left out: TIP142/147 (SOT-93/TO-247 at onsemi), LM2941 (5 leads), ECX10N20/P20 (TO-247), the + lateral 2SK134/135 and 2SJ49/50 (case is probably source, not drain - no Hitachi sheet found), and + TO-3 79xx (unsourced). + +`TransistorTO92.datasheet` FET and regulator rows, 41 parts: + +| Group | Pinout | Parts | +|---|---|---| +| JFET (N) | `JFET_DSG` | J201, J202, J111, J112, J113, J310, 2N5457, 2N5458, 2N5459, 2N5484, 2N5485, 2N5486, PN4416, MPF102, BF245A/B/C | +| JFET (N) | `JFET_SGD` / `JFET_GSD` / `JFET_DGS` | 2N3819 / BF256B / 2SK170, LSK170 | +| JFET (P) | `JFET_DGS` / `JFET_SDG` | J174, J175, J176, 2N3820 / 2N5460 | +| MOSFET (N) | `MOSFET_SGD` / `MOSFET_DGS` | 2N7000, LND150 / BS170 | +| Regulator (+) | `REGULATOR_OGI` | 78L05, 78L09, 78L12, 78L15, LP2950-5.0, LM2936Z-5.0 | +| Regulator (+) | `REGULATOR_AOI` / `REGULATOR_IOA` | LM317LZ / LR8 | +| Regulator (-) | `REGULATOR_GIO` / `REGULATOR_AOI` | 79L05, 79L12, 79L15 / LM337LZ | + +TO-92 FET and regulator notes: + +- TI's TO-92 outline (LP0003A) and its TL431, LM317L and LM385 tables number from the right, like + Philips; the parts are physically the same as onsemi's. Rows are the physical order. +- JFET makers often differ by a drain/source swap (InterFET lists J201, J310, 2N5457, 2N5484-86 and + PN4416 as S-D-G; Fairchild, Linear Systems, Central and onsemi as D-S-G). The gate position, which + is what matters, agrees, and the rows follow the majority. 2N3819: S-G-D at onsemi, InterFET and + Vishay, D-G-S at Central. J174/J175: D-G-S at Linear Systems, S-G-D at InterFET. +- **BF245 is a real conflict**: Philips (the original, the classic European part) is D-S-G, onsemi + is G-S-D - the gate at opposite ends. Both are discontinued; the rows follow Philips. A layout + built around an onsemi BF245 needs `JFET_GSD`. +- BS170 follows onsemi's TO-92 (D-G-S); Diodes' "TO-92 compatible" E-Line BS170P is marked on the + rounded face and is S-G-D seen from the flat side. +- LND150 is from Microchip's numbered pin table. LR8 (IN, OUT, ADJ - not the LM317 order) is from + the same Supertex 3D drawing, read with the LND150 as calibration; the weakest row in the file. + 2N5459 and 2N3820 rest on one sheet each. +- Left out: MPF4393, 2SK30A, 2SK117, 2SJ74, LSJ74, VN10KM (unsourced); BS250 and VP2106 (drawing + only, not requested); 79L09 (not a listed voltage); TL431, LM385 and LM336 (roles are not in + `TransistorPinout`). + +## 5. Tests + +- `TransistorPinoutTest`: SPICE order per type, including the `BJT_ECB` fix; every value is a + permutation of its type's roles. +- `TransistorTO3Test`: case point sits in a mounting hole in every orientation; a two-point + instance gains the case point where a new one has it; node names follow the pinout; display is + read from the legacy field. +- `TransistorDatasheetTest`: across all five datasheets, every row has three columns, parses and + applies; part numbers unique per package; `findSeries` finds a part and not a group. + +## 6. Verification + +- Done: `mvn -q test` over the whole reactor passes (core 227, library 504, swing 29). + `pinout-drivers.txt` was updated because TO-3 terminals are now driven by "Pinout". +- Done: TO-3 rendered headlessly in all four orientations at 100 % and 50 % alpha with Display = + Pinout - pins show over the case, the case point sits in the pin-side hole, letters beside each. + All five packages rendered standing, folded and at 50 % alpha: pins on top in one colour. +- Open: the regression suite. Every project with a transistor package now renders differently + (pins visible over the body, blue folded leads), TO-3 projects carry a third, normally + unconnected, node, and ECB parts change SPICE order. Reference outputs are regenerated only after the diffs are confirmed to + be exactly that. + +## 7. Phases + +1. **Pinout everywhere**: done (T6 to T11, `TransistorPinoutTest`, `TransistorTO3Test`, `@AiNote`s on + pin order for TO-1, TO-126 and TO-3). +2. **Datasheet support**: done (T1 to T3, `TransistorDatasheetTest`). +3. **Library**: done - 256 parts: TO-92 109, TO-220 67, TO-1 31, TO-3 27, TO-126 22. + `catalog_full.json` regenerated. Further parts on request, each read from a manufacturer pin + table first. +4. **Next**: the regression run of ยง6; then, if wanted, the TO-247/TO-3P package (2SC5200/2SA1943, + TIP3055/2955, IRFP240/9240, lateral MOSFETs) and a role set for shunt references (TL431).