leomcelroy / svg-pcb

Design PCBs in the Browser
https://www.leomcelroy.com/svg-pcb-website
GNU General Public License v3.0
64 stars 9 forks source link

Add updated gerber download code #70

Closed kr15h closed 8 months ago

kr15h commented 9 months ago

I do it again with new updates

kr15h commented 9 months ago

Just tested with text on silkscreen layers and it works in tracespace.io. It would be nice to have the original text available via global state so that one could take advantage of the Gerber X2 text markup (Gerber Spec p. 147).

kr15h commented 9 months ago

So I tried to design a board, export Gerbers and mill with CopperCAM. All works, except CopperCAM does not work well if pads are defined as polygons - it recognizes them as copper fills and it causes problems with layer alignment. I suppose that is no problem with tracespace as everything shows up there nicely.

Code:

2/* 
@version: v0.1.0

a basic starter design 
*/

/* -- DECLARE_PCB -- */
const board = new PCB();

/* -- DECLARE_COMPONENTS -- */
const batt_holder = footprint({"1_1":{"pos":[-0.2559055118110236,0],"shape":"M -0.07874015748031496 0.10039370078740156 L 0.07874015748031496 0.10039370078740156 L 0.07874015748031496 -0.10039370078740156 L -0.07874015748031496 -0.10039370078740156 L -0.07874015748031496 0.10039370078740156 ","layers":["F.Cu","F.Paste","F.Mask"]},"1_2":{"pos":[0.2559055118110236,0],"shape":"M -0.07874015748031496 0.04606299212598425 L 0.07874015748031496 0.04606299212598425 L 0.07874015748031496 -0.04606299212598425 L -0.07874015748031496 -0.04606299212598425 L -0.07874015748031496 0.04606299212598425 ","layers":["F.Cu","F.Paste","F.Mask"]}});
const buton_6x3mm = footprint({"1":{"pos":[-0.15748031496062992,0],"shape":"M -0.049212598425196846 0.02952755905511811 L 0.049212598425196846 0.02952755905511811 L 0.049212598425196846 -0.02952755905511811 L -0.049212598425196846 -0.02952755905511811 L -0.049212598425196846 0.02952755905511811 ","layers":["F.Cu","F.Paste","F.Mask"]},"2":{"pos":[0.15748031496062992,0],"shape":"M -0.049212598425196846 0.02952755905511811 L 0.049212598425196846 0.02952755905511811 L 0.049212598425196846 -0.02952755905511811 L -0.049212598425196846 -0.02952755905511811 L -0.049212598425196846 0.02952755905511811 ","layers":["F.Cu","F.Paste","F.Mask"]}});
const header_2H = footprint({"1":{"shape":"M -0.05,0.025L 0.05,0.025L 0.05,-0.025L -0.05,-0.025L -0.05,0.025","pos":[0,0.05],"layers":["F.Cu","F.Mask"],"index":1},"2":{"shape":"M -0.05,0.025L 0.05,0.025L 0.05,-0.025L -0.05,-0.025L -0.05,0.025","pos":[0,-0.05],"layers":["F.Cu","F.Mask"],"index":2}});
const R_1206 = footprint({"1":{"shape":"M -0.032,0.034L 0.032,0.034L 0.032,-0.034L -0.032,-0.034L -0.032,0.034","pos":[-0.06,0],"layers":["F.Cu","F.Mask"],"index":1},"2":{"shape":"M -0.032,0.034L 0.032,0.034L 0.032,-0.034L -0.032,-0.034L -0.032,0.034","pos":[0.06,0],"layers":["F.Cu","F.Mask"],"index":2}});

/* -- CONSTANTS -- */
// I wish I could use millimeters
const limitMargin = 0.1;
const width = 4.8;
const height = 0.4;
const filletRadius = 0.08;
const holeRadius = 0.05;
const holeDistanceBetween = 0.24;
const holeFromRightEdge = 0.16;
const holeFromLeftEdge = 0.16;
const battClipOffset = 0.15; // Distance from center of the battery clip to terminal
const battLength = 1.73; // Length of single AA battery in Finland
const battOffsetFromLeftEdge = 0.5;
const buttonFromRightEdge = 1.65;
const headerFromRightEdge = 0.59;
const viaHoleDia = 0.032;
const viaRingDia = 0.064;
const wireWidth = 0.025;

/* -- ADD_COMPONENTS -- */
const batt_holder_left = board.add(batt_holder, { translate: pt(battOffsetFromLeftEdge + battClipOffset, height/2), rotate: 0, label: "batt_holder_left", flip: true })
const batt_holder_center = board.add(batt_holder, { translate: pt(battOffsetFromLeftEdge + battLength - 0.05, height/2), rotate: 0, label: "batt_holder_center", flip: true })
const batt_holder_right = board.add(batt_holder, { translate: pt(battOffsetFromLeftEdge + (battLength*2) - battClipOffset, height/2), rotate: 180, label: "batt_holder_right", flip: true })
const buton_6x3mm_3R7 = board.add(buton_6x3mm, { translate: pt(width-buttonFromRightEdge, height/2), rotate: 0, label: "buton_6x3mm_3R7" })
const header_2H_YRu = board.add(header_2H, { translate: pt(width-headerFromRightEdge, height/2), rotate: 0, label: "header_2H_YRu" })
const R_1206_Six = board.add(R_1206, { translate: pt(2.75, height/4*3), rotate: 0, label: "R_1206_Six" })
const V1 = board.add(via(viaHoleDia, viaRingDia), {translate: pt(R_1206_Six.posX, height/2), label: 'V1'});
const V2 = board.add(via(viaHoleDia, viaRingDia), {translate: pt(batt_holder_left.padX("1_2")+0.194, height/2), label: 'V2'});

/* -- BOARD_SIZE_SHAPE -- */
let outline = geo.path(path(
  [filletRadius, 0],
  [width-filletRadius, 0],
  [width, filletRadius],
  [width, height-filletRadius],
  [width-filletRadius, height],
  [filletRadius, height],
  [0, height-filletRadius],
  [0, filletRadius]
));

// We want all corners fileted except one
const fillet = geo.circle(filletRadius);
geo.translate(fillet, [width-filletRadius, filletRadius]);
outline = geo.union(outline, fillet);
geo.translate(fillet, [(filletRadius*2)-width, 0]);
outline = geo.union(outline, fillet);
geo.translate(fillet, [0, height-(filletRadius*2)]);
outline = geo.union(outline, fillet);

// We need a few mouning holes here
const holeLeft = geo.circle(holeRadius);
const holeCenter = geo.circle(holeRadius);
const holeRight = geo.circle(holeRadius);
geo.translate(holeLeft, [holeFromLeftEdge, height/2]);
geo.translate(holeCenter, [width-holeFromRightEdge-holeDistanceBetween, height/2]);
geo.translate(holeRight, [width-holeFromRightEdge, height/2]);
outline = geo.difference(outline, holeLeft, holeCenter, holeRight);

// Outline done!
board.addShape("Outline", outline);

/* -- ADD_WIRES -- */
board.wire(path( R_1206_Six.pad("1"), [1.2, 0.3], V2.pad("via"),), wireWidth);
board.wire(path( V1.pad("via"), buton_6x3mm_3R7.pad("1"), ), wireWidth);
board.wire(path( buton_6x3mm_3R7.pad("2"), [3.4, 0.15], header_2H_YRu.pad("2"),  ), wireWidth);
board.wire(path( R_1206_Six.pad("2"), [4.1, 0.3], header_2H_YRu.pad("1"), header_2H_YRu.pad("1"),), wireWidth);

board.wire(path( batt_holder_left.pad("1_2"), batt_holder_left.pad("1_1"), batt_holder_left.pad("1_2"), V2.pad("via"),), wireWidth, "B.Cu");
board.wire(path( V1.pad("via"), batt_holder_right.pad("1_2"), batt_holder_right.pad("1_1"), ), wireWidth, "B.Cu");

/* -- RENDER_PCB -- */
const limit0 = pt(-limitMargin, -limitMargin);
const limit1 = pt(width + limitMargin, height + limitMargin);
const xMin = Math.min(limit0[0], limit1[0]);
const xMax = Math.max(limit0[0], limit1[0]);
const yMin = Math.min(limit0[1], limit1[1]);
const yMax = Math.max(limit0[1], limit1[1]);

renderPCB({
  pcb: board,
  layerColors: {
/* "F.Paste": "#000000ff", */
/* "B.Paste": "#000000ff", */
 "Outline": "#002d00ff",
 "F.Mask": "#00000000",
 "padLabels": "#ffff99e5",
 "componentLabels": "#00e5e5e5",
 "B.Mask": "#00000000",
 "B.Cu": "#ff4c007f",
 "F.Cu": "#ff8c00cc",
},
  limits: {
    x: [xMin, xMax],
    y: [yMin, yMax]
  },
  mm_per_unit: 25.4
});

Board: image

TraceSpace: image

JLCPCB: image

PCBWay: image