3
\$\begingroup\$

For 3D CAD modeling, there is software called OpenSCAD which allows you to create 3D designs purely in code and then render them.

I'm wondering if something similar exists for PCB design where I could "write" a PCB, and then compile it to gerber files or similar which could then be sent to a fab site like easyEDA.

Edit: I should specify that by "in code", I mean in some language with support for things like named constants, functions, looping, etc. For example, in OpenSCAD, I can do things like

  for(i = [0 : num_planks-1]) {
       translate([i * plank_w, bb_w, top_height]) cube([plank_w, plank_l, top_thickness]);
  }

and so by changing constants, I can quickly alter the parameters of a model.

What I'm trying to do is create a pcb for a keyboard, but I'd like to be able to easily tweak the layout without having to shuffle each keyswitch around by hand. Adding or removing a row of keys, changing the staggering of the rows, etc. It seems like these sorts of things could be easy if the board was properly described in code rather than in a graphical editor.

\$\endgroup\$
  • 5
    \$\begingroup\$ You could write Gerber directly; or you could use one of the SVG->PCB format converters. Avoiding manual routing entirely is .. optimistic. \$\endgroup\$ – pjc50 Jun 18 '17 at 19:07
7
\$\begingroup\$

Though EAGLE is a graphical editor, it can be controlled entirely via command line, which is the single input line above the drawing area. The commands can also be written to a script file, and though I haven't looked for it, it is for sure possible to start EAGLE from the operating system's command line and tell it to run the script and then do a CAM job to generate the Gerber files.

This is the layout of the well known simple astable multivibrator:

enter image description here

and this is a (cleaned-up) script which would draw it. (I've drawn it and exported it via the export-board.ulp from here):

GRID INCH 0.005

ADD 'C1' C025-024X044@rcl R0.000 (0.300 0.700);
ADD 'C2' C025-024X044@rcl R0.000 (0.600 0.700);
ADD 'GND' P1-13@testpad R0.000 (1.000 0.150);
ADD 'R1' 0204V@rcl R90.000 (0.100 0.750);
ADD 'R2' 0204V@rcl R90.000 (0.350 0.900);
ADD 'R3' 0204V@rcl R90.000 (0.550 0.900);
ADD 'R4' 0204V@rcl R90.000 (0.800 0.750);
ADD 'T1' TO92@transistor R270.000 (0.800 0.400);
ADD 'T2' TO92@transistor R270.000 (0.100 0.400);
ADD 'VCC' P1-13@testpad R0.000 (1.000 0.950);


LAYER 20
WIRE 0.000 (0.000 0.000) (1.187 0.000);
WIRE 0.000 (1.187 0.000) (1.187 1.100);
WIRE 0.000 (1.187 1.100) (0.000 1.100);
WIRE 0.000 (0.000 1.100) (0.000 0.000);

LAYER 1
SIGNAL 'N$1' R1 1 C1 1 T2 3;

WIRE 'N$1' 0.016 (0.100 0.450) (0.100 0.700);
WIRE 'N$1' 0.016 (0.100 0.700) (0.250 0.700);

SIGNAL 'N$2' C1 2 R2 1 T1 2;
WIRE 'N$2' 0.016 (0.350 0.850) (0.350 0.700);
LAYER 16
WIRE 'N$2' 0.016 (0.875 0.400) (0.450 0.400);
WIRE 'N$2' 0.016 (0.450 0.400) (0.350 0.500);
WIRE 'N$2' 0.016 (0.350 0.500) (0.350 0.700);
LAYER 1

SIGNAL 'N$3' R3 1 C2 1 T2 2;
WIRE 'N$3' 0.016 (0.550 0.850) (0.550 0.700);
WIRE 'N$3' 0.016 (0.175 0.400) (0.450 0.400);
WIRE 'N$3' 0.016 (0.450 0.400) (0.550 0.500);
WIRE 'N$3' 0.016 (0.550 0.500) (0.550 0.700);

SIGNAL 'N$4' C2 2 R4 1 T1 3;
WIRE 'N$4' 0.016 (0.650 0.700) (0.800 0.700);
WIRE 'N$4' 0.016 (0.800 0.700) (0.800 0.450);

SIGNAL 'N$5' R1 2 R2 2 R3 2 R4 2 VCC TP;
WIRE 'N$5' 0.016 (0.100 0.800) (0.100 0.850);
WIRE 'N$5' 0.016 (0.100 0.850) (0.200 0.950);
WIRE 'N$5' 0.016 (0.200 0.950) (0.350 0.950);
WIRE 'N$5' 0.016 (0.350 0.950) (0.550 0.950);
WIRE 'N$5' 0.016 (0.550 0.950) (0.800 0.950);
WIRE 'N$5' 0.016 (0.800 0.950) (1.000 0.950);
WIRE 'N$5' 0.016 (0.800 0.800) (0.800 0.950);

SIGNAL 'N$7' T2 1 T1 1 GND TP;
WIRE 'N$7' 0.016 (0.100 0.350) (0.100 0.250);
WIRE 'N$7' 0.016 (0.100 0.250) (0.200 0.150);
WIRE 'N$7' 0.016 (0.200 0.150) (0.800 0.150);
WIRE 'N$7' 0.016 (0.800 0.150) (1.000 0.150);
WIRE 'N$7' 0.016 (0.800 0.350) (0.800 0.150);

One could simplify this, but yet, that's something for someone with way too much time...

\$\endgroup\$
  • \$\begingroup\$ Thanks for your response sweber - I should have given more detail in my original question (I have updated it), but I was hoping for sort of a more powerful scripting language with looping constructs and the like - in any case, it looks like it wouldn't be too difficult to generate this kind of script, so thanks for the example! \$\endgroup\$ – Matt Jun 24 '17 at 16:45
  • \$\begingroup\$ @Matt: Eagle has a built-in scripting language with a C-like syntax, it's called ULP. See the various ULP programs delivered with your Eagle installation. \$\endgroup\$ – Janka Jun 24 '17 at 16:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.