diff --git a/battery_connector_jst_ph_2.js b/battery_connector_jst_ph_2.js index 9fe7529..934b154 100644 --- a/battery_connector_jst_ph_2.js +++ b/battery_connector_jst_ph_2.js @@ -24,6 +24,15 @@ // reversible: default is false // if true, the footprint will be placed on both sides so that the PCB can be // reversible +// use_3_thru_holes: false +// if true, use three through holes instead of jumper pads for reversible PCB. +// Only effective when reversible is true. +// Middle pin is positive and the other two pins connect to GND. This allows choosing +// either left or right pin to be positive on each side of the PCB. +// housing_positive_on_left: false +// if true, when inserting the housing into the header of the connector (and looking +// from housing to header), the positive pin is on the left side. +// (This is the same polarity used by Adafruit and SparkFun products.) // include_traces: default is true // if true it will include traces that connect the jumper pads to the connector pins // trace_width: default is 0.250mm @@ -32,6 +41,9 @@ // include_silkscreen: default is true // if true it will include the silkscreen. Recommended to be true to ensure connector // polarity is not reversed, which can lead to shorting and damage to the MCU +// include_silkscreen_on_both_sides: false +// if true it will include the silkscreen on both sides of the PCB. Only effective +// when reversible is false. // include_fabrication: default is true // if true it will include the outline of the connector in the fabrication layer // include_courtyard: default is true @@ -58,9 +70,12 @@ module.exports = { designator: 'JST', side: 'F', reversible: false, + use_3_thru_holes: false, + housing_positive_on_left: false, include_traces: true, trace_width: 0.250, include_silkscreen: true, + include_silkscreen_on_both_sides: false, include_fabrication: true, include_courtyard: true, battery_connector_3dmodel_filename: '', @@ -76,6 +91,12 @@ module.exports = { p.local_net("2"), ]; + // For variable names, housing "positive_{right,left}" is based on connector mounted on front side. + // For back side mounting, left and right are reversed. + const use_positive_left = + (p.side == "F" && p.housing_positive_on_left) || + (p.side == "B" && !p.housing_positive_on_left); + const standard_opening = ` (footprint "ceoloide:battery_connector_jst_ph_2" (layer "${p.side}.Cu") @@ -87,71 +108,65 @@ module.exports = { (effects (font (size 1 1) (thickness 0.15))) ) ` - const front_fabrication = ` - (fp_line (start -2.95 -1.35) (end -2.95 6.25) (stroke (width 0.1) (type solid)) (layer "F.Fab")) - (fp_line (start -2.95 6.25) (end 2.95 6.25) (stroke (width 0.1) (type solid)) (layer "F.Fab")) - (fp_line (start -2.25 -1.35) (end -2.95 -1.35) (stroke (width 0.1) (type solid)) (layer "F.Fab")) - (fp_line (start -2.25 0.25) (end -2.25 -1.35) (stroke (width 0.1) (type solid)) (layer "F.Fab")) - (fp_line (start 2.25 -1.35) (end 2.25 0.25) (stroke (width 0.1) (type solid)) (layer "F.Fab")) - (fp_line (start 2.25 0.25) (end -2.25 0.25) (stroke (width 0.1) (type solid)) (layer "F.Fab")) - (fp_line (start 2.95 -1.35) (end 2.25 -1.35) (stroke (width 0.1) (type solid)) (layer "F.Fab")) - (fp_line (start 2.95 6.25) (end 2.95 -1.35) (stroke (width 0.1) (type solid)) (layer "F.Fab")) - ` - const front_courtyard = ` - (fp_line (start -3.45 -1.85) (end -3.45 10.5) (stroke (width 0.05) (type solid)) (layer "F.CrtYd")) - (fp_line (start -3.45 10.5) (end 3.45 10.5) (stroke (width 0.05) (type solid)) (layer "F.CrtYd")) - (fp_line (start 3.45 -1.85) (end -3.45 -1.85) (stroke (width 0.05) (type solid)) (layer "F.CrtYd")) - (fp_line (start 3.45 10.5) (end 3.45 -1.85) (stroke (width 0.05) (type solid)) (layer "F.CrtYd")) - ` - const front_silkscreen = ` - (fp_line (start -1.5 7.40) (end -0.5 7.40) (stroke (width 0.1) (type solid)) (layer "F.SilkS")) - (fp_line (start 1.5 7.40) (end 0.5 7.40) (stroke (width 0.1) (type solid)) (layer "F.SilkS")) - (fp_line (start 1 6.90) (end 1 7.90) (stroke (width 0.1) (type solid)) (layer "F.SilkS")) - (fp_line (start -2.06 -1.46) (end -3.06 -1.46) (stroke (width 0.12) (type solid)) (layer "F.SilkS")) - (fp_line (start -3.06 -1.46) (end -3.06 -0.46) (stroke (width 0.12) (type solid)) (layer "F.SilkS")) - (fp_line (start 2.14 -1.46) (end 3.06 -1.46) (stroke (width 0.12) (type solid)) (layer "F.SilkS")) - (fp_line (start 3.06 -1.46) (end 3.06 -0.46) (stroke (width 0.12) (type solid)) (layer "F.SilkS")) - (fp_line (start -2.14 6.36) (end -3.06 6.36) (stroke (width 0.12) (type solid)) (layer "F.SilkS")) - (fp_line (start -3.06 6.36) (end -3.06 5.36) (stroke (width 0.12) (type solid)) (layer "F.SilkS")) - (fp_line (start 2.14 6.36) (end 3.06 6.36) (stroke (width 0.12) (type solid)) (layer "F.SilkS")) - (fp_line (start 3.06 6.36) (end 3.06 5.36) (stroke (width 0.12) (type solid)) (layer "F.SilkS")) + // offset is for using 3 thru holes for reversible PCB. The connector's mount position is different on each side. + const fabrication = (side, offset = 0) => ` + (fp_line (start ${-2.95 + offset} -1.35) (end ${-2.95 + offset} 6.25) (stroke (width 0.1) (type solid)) (layer "${side}.Fab")) + (fp_line (start ${-2.95 + offset} 6.25) (end ${2.95 + offset} 6.25) (stroke (width 0.1) (type solid)) (layer "${side}.Fab")) + (fp_line (start ${-2.25 + offset} -1.35) (end ${-2.95 + offset} -1.35) (stroke (width 0.1) (type solid)) (layer "${side}.Fab")) + (fp_line (start ${-2.25 + offset} 0.25) (end ${-2.25 + offset} -1.35) (stroke (width 0.1) (type solid)) (layer "${side}.Fab")) + (fp_line (start ${2.25 + offset} -1.35) (end ${2.25 + offset} 0.25) (stroke (width 0.1) (type solid)) (layer "${side}.Fab")) + (fp_line (start ${2.25 + offset} 0.25) (end ${-2.25 + offset} 0.25) (stroke (width 0.1) (type solid)) (layer "${side}.Fab")) + (fp_line (start ${2.95 + offset} -1.35) (end ${2.25 + offset} -1.35) (stroke (width 0.1) (type solid)) (layer "${side}.Fab")) + (fp_line (start ${2.95 + offset} 6.25) (end ${2.95 + offset} -1.35) (stroke (width 0.1) (type solid)) (layer "${side}.Fab")) ` - const back_fabrication = ` - (fp_line (start -2.95 -1.35) (end -2.25 -1.35) (stroke (width 0.1) (type solid)) (layer "B.Fab")) - (fp_line (start -2.95 6.25) (end -2.95 -1.35) (stroke (width 0.1) (type solid)) (layer "B.Fab")) - (fp_line (start -2.25 -1.35) (end -2.25 0.25) (stroke (width 0.1) (type solid)) (layer "B.Fab")) - (fp_line (start -2.25 0.25) (end 2.25 0.25) (stroke (width 0.1) (type solid)) (layer "B.Fab")) - (fp_line (start 2.25 -1.35) (end 2.95 -1.35) (stroke (width 0.1) (type solid)) (layer "B.Fab")) - (fp_line (start 2.25 0.25) (end 2.25 -1.35) (stroke (width 0.1) (type solid)) (layer "B.Fab")) - (fp_line (start 2.95 -1.35) (end 2.95 6.25) (stroke (width 0.1) (type solid)) (layer "B.Fab")) - (fp_line (start 2.95 6.25) (end -2.95 6.25) (stroke (width 0.1) (type solid)) (layer "B.Fab")) + const courtyard = (side, offset = 0) => ` + (fp_line (start ${-3.45 + offset} -1.85) (end ${-3.45 + offset} 10.5) (stroke (width 0.05) (type solid)) (layer "${side}.CrtYd")) + (fp_line (start ${-3.45 + offset} 10.5) (end ${3.45 + offset} 10.5) (stroke (width 0.05) (type solid)) (layer "${side}.CrtYd")) + (fp_line (start ${3.45 + offset} -1.85) (end ${-3.45 + offset} -1.85) (stroke (width 0.05) (type solid)) (layer "${side}.CrtYd")) + (fp_line (start ${3.45 + offset} 10.5) (end ${3.45 + offset} -1.85) (stroke (width 0.05) (type solid)) (layer "${side}.CrtYd")) ` - const back_courtyard = ` - (fp_line (start -3.45 -1.85) (end -3.45 10.5) (stroke (width 0.05) (type solid)) (layer "B.CrtYd")) - (fp_line (start -3.45 10.5) (end 3.45 10.5) (stroke (width 0.05) (type solid)) (layer "B.CrtYd")) - (fp_line (start 3.45 -1.85) (end -3.45 -1.85) (stroke (width 0.05) (type solid)) (layer "B.CrtYd")) - (fp_line (start 3.45 10.5) (end 3.45 -1.85) (stroke (width 0.05) (type solid)) (layer "B.CrtYd")) + // This draws four corners of a square for the connector. + const silkscreen_common = (side, offset = 0) => ` + (fp_line (start ${-2.06 + offset} -1.46) (end ${-3.06 + offset} -1.46) (stroke (width 0.12) (type solid)) (layer "${side}.SilkS")) + (fp_line (start ${-3.06 + offset} -1.46) (end ${-3.06 + offset} -0.46) (stroke (width 0.12) (type solid)) (layer "${side}.SilkS")) + (fp_line (start ${2.14 + offset} -1.46) (end ${3.06 + offset} -1.46) (stroke (width 0.12) (type solid)) (layer "${side}.SilkS")) + (fp_line (start ${3.06 + offset} -1.46) (end ${3.06 + offset} -0.46) (stroke (width 0.12) (type solid)) (layer "${side}.SilkS")) + (fp_line (start ${-2.14 + offset} 6.36) (end ${-3.06 + offset} 6.36) (stroke (width 0.12) (type solid)) (layer "${side}.SilkS")) + (fp_line (start ${-3.06 + offset} 6.36) (end ${-3.06 + offset} 5.36) (stroke (width 0.12) (type solid)) (layer "${side}.SilkS")) + (fp_line (start ${2.14 + offset} 6.36) (end ${3.06 + offset} 6.36) (stroke (width 0.12) (type solid)) (layer "${side}.SilkS")) + (fp_line (start ${3.06 + offset} 6.36) (end ${3.06 + offset} 5.36) (stroke (width 0.12) (type solid)) (layer "${side}.SilkS")) + ` + const positive_right_silkscreen = (side, offset = 0) => { + return ` + (fp_line (start ${1 + offset} 6.90) (end ${1 + offset} 7.90) (stroke (width 0.1) (type solid)) (layer "${side}.SilkS")) + (fp_line (start ${1.5 + offset} 7.40) (end ${0.5 + offset} 7.40) (stroke (width 0.1) (type solid)) (layer "${side}.SilkS")) + (fp_line (start ${-1.5 + offset} 7.40) (end ${-0.5 + offset} 7.40) (stroke (width 0.1) (type solid)) (layer "${side}.SilkS")) + ${silkscreen_common(side, offset)} ` - const back_silkscreen = ` - (fp_line (start 1.5 7.40) (end 0.5 7.40) (stroke (width 0.1) (type solid)) (layer "B.SilkS")) - (fp_line (start -1.5 7.40) (end -0.5 7.40) (stroke (width 0.1) (type solid)) (layer "B.SilkS")) - (fp_line (start -1 6.90) (end -1 7.90) (stroke (width 0.1) (type solid)) (layer "B.SilkS")) - (fp_line (start -2.06 -1.46) (end -3.06 -1.46) (stroke (width 0.12) (type solid)) (layer "B.SilkS")) - (fp_line (start -3.06 -1.46) (end -3.06 -0.46) (stroke (width 0.12) (type solid)) (layer "B.SilkS")) - (fp_line (start 2.14 -1.46) (end 3.06 -1.46) (stroke (width 0.12) (type solid)) (layer "B.SilkS")) - (fp_line (start 3.06 -1.46) (end 3.06 -0.46) (stroke (width 0.12) (type solid)) (layer "B.SilkS")) - (fp_line (start -2.14 6.36) (end -3.06 6.36) (stroke (width 0.12) (type solid)) (layer "B.SilkS")) - (fp_line (start -3.06 6.36) (end -3.06 5.36) (stroke (width 0.12) (type solid)) (layer "B.SilkS")) - (fp_line (start 2.14 6.36) (end 3.06 6.36) (stroke (width 0.12) (type solid)) (layer "B.SilkS")) - (fp_line (start 3.06 6.36) (end 3.06 5.36) (stroke (width 0.12) (type solid)) (layer "B.SilkS")) + } + const positive_left_silkscreen = (side, offset = 0) => { + return ` + (fp_line (start ${-1 + offset} 6.90) (end ${-1 + offset} 7.90) (stroke (width 0.1) (type solid)) (layer "${side}.SilkS")) + (fp_line (start ${-1.5 + offset} 7.40) (end ${-0.5 + offset} 7.40) (stroke (width 0.1) (type solid)) (layer "${side}.SilkS")) + (fp_line (start ${1.5 + offset} 7.40) (end ${0.5 + offset} 7.40) (stroke (width 0.1) (type solid)) (layer "${side}.SilkS")) + ${silkscreen_common(side, offset)} ` - const front_pads = ` + } + const positive_right_pad_2nd_gnd = p.reversible && p.use_3_thru_holes + ? `(pad "3" thru_hole roundrect (at 3 0 ${p.r}) (size 1.2 1.75) (drill 0.75) (layers "*.Cu" "*.Mask") (roundrect_rratio 0.20) ${p.BAT_N.str})` + : `` + const positive_right_pads = ` (pad "1" thru_hole roundrect (at -1 0 ${p.r}) (size 1.2 1.75) (drill 0.75) (layers "*.Cu" "*.Mask") (roundrect_rratio 0.20) ${p.BAT_N.str}) (pad "2" thru_hole oval (at 1 0 ${p.r}) (size 1.2 1.75) (drill 0.75) (layers "*.Cu" "*.Mask") ${p.BAT_P.str}) + ${positive_right_pad_2nd_gnd} ` - const back_pads = ` + const positive_left_pad_2nd_gnd = p.reversible && p.use_3_thru_holes + ? `(pad "3" thru_hole roundrect (at -3 0 ${p.r}) (size 1.2 1.75) (drill 0.75) (layers "*.Cu" "*.Mask") (roundrect_rratio 0.20) ${p.BAT_N.str})` + : `` + const positive_left_pads = ` (pad "1" thru_hole roundrect (at 1 0 ${p.r}) (size 1.2 1.75) (drill 0.75) (layers "*.Cu" "*.Mask") (roundrect_rratio 0.20) ${p.BAT_N.str}) (pad "2" thru_hole oval (at -1 0 ${p.r}) (size 1.2 1.75) (drill 0.75) (layers "*.Cu" "*.Mask") ${p.BAT_P.str}) + ${positive_left_pad_2nd_gnd} ` const reversible_pads = ` (pad "11" thru_hole oval (at -1 0 ${p.r}) (size 1.2 1.75) (drill 0.75) (layers "*.Cu" "*.Mask") ${local_nets[0].str}) @@ -228,7 +243,7 @@ module.exports = { ) ${local_nets[1]} ) - (pad "1" smd custom (at -1 2.816 ${180 + p.r}) (size 1.2 0.5) (layers "F.Cu" "F.Mask" "F.Paste") ${p.BAT_P.str} + (pad "1" smd custom (at -1 2.816 ${180 + p.r}) (size 1.2 0.5) (layers "F.Cu" "F.Mask" "F.Paste") ${use_positive_left ? p.BAT_P.str : p.BAT_N.str} (clearance 0.1) (zone_connect 0) (options (clearance outline) (anchor rect)) (primitives @@ -245,7 +260,7 @@ module.exports = { ) ) ) - (pad "1" smd custom (at 1 2.816 ${180 + p.r}) (size 1.2 0.5) (layers "B.Cu" "B.Mask" "B.Paste") ${p.BAT_P.str} + (pad "1" smd custom (at 1 2.816 ${180 + p.r}) (size 1.2 0.5) (layers "B.Cu" "B.Mask" "B.Paste") ${use_positive_left ? p.BAT_P.str : p.BAT_N.str} (clearance 0.1) (zone_connect 0) (options (clearance outline) (anchor rect)) (primitives @@ -262,7 +277,7 @@ module.exports = { ) ) ) - (pad "2" smd custom (at -1 2.816 ${180 + p.r}) (size 1.2 0.5) (layers "B.Cu" "B.Mask" "B.Paste") ${p.BAT_N.str} + (pad "2" smd custom (at -1 2.816 ${180 + p.r}) (size 1.2 0.5) (layers "B.Cu" "B.Mask" "B.Paste") ${use_positive_left ? p.BAT_N.str : p.BAT_P.str} (clearance 0.1) (zone_connect 0) (options (clearance outline) (anchor rect)) (primitives @@ -279,7 +294,7 @@ module.exports = { ) ) ) - (pad "2" smd custom (at 1 2.816 ${180 + p.r}) (size 1.2 0.5) (layers "F.Cu" "F.Mask" "F.Paste") ${p.BAT_N.str} + (pad "2" smd custom (at 1 2.816 ${180 + p.r}) (size 1.2 0.5) (layers "F.Cu" "F.Mask" "F.Paste") ${use_positive_left ? p.BAT_N.str : p.BAT_P.str} (clearance 0.1) (zone_connect 0) (options (clearance outline) (anchor rect)) (primitives @@ -318,40 +333,49 @@ module.exports = { let final = standard_opening; - if (p.side == "F" || p.reversible) { - if (p.include_fabrication) { - final += front_fabrication; - } - if (p.include_courtyard) { - final += front_courtyard; - } - if (p.include_silkscreen) { - final += front_silkscreen; + if (p.include_fabrication) { + final += fabrication(p.side); + } + if (p.include_courtyard) { + final += courtyard(p.side); + } + + const reverse_side = p.side == "F" ? "B" : "F"; + const silkscreen = use_positive_left ? positive_left_silkscreen : positive_right_silkscreen; + const silkscreen_reverse_side = use_positive_left ? positive_right_silkscreen : positive_left_silkscreen; + if (p.include_silkscreen) { + final += silkscreen(p.side); + if (!p.reversible && p.include_silkscreen_on_both_sides) { + // Non-reversible PCB showing exactly the same silkscreen on both sides. + final += silkscreen(reverse_side); } } - if (p.side == "B" || p.reversible) { + + if (p.reversible) { + const offset = p.use_3_thru_holes ? (p.side == "F" ? -2 : 2) : 0; if (p.include_fabrication) { - final += back_fabrication; + final += fabrication(reverse_side, offset); } if (p.include_courtyard) { - final += back_courtyard; + final += courtyard(reverse_side, offset); } if (p.include_silkscreen) { - final += back_silkscreen; + final += silkscreen_reverse_side(reverse_side, offset); } } - if (p.reversible) { + + if (p.reversible && !p.use_3_thru_holes) { final += reversible_pads; - } else if (p.side == "F") { - final += front_pads; - } else if (p.side == "B") { - final += back_pads; + } else if (use_positive_left) { + final += positive_left_pads; + } else { + final += positive_right_pads; } if (p.battery_connector_3dmodel_filename) { final += battery_connector_3dmodel } final += standard_closing; - if (p.reversible && p.include_traces) { + if (p.reversible && p.include_traces && !p.use_3_thru_holes) { final += reversible_traces; } return final;