Executing ULP when creating new Schematic/layout

Executing ULP when creating new Schematic/layout

decee.server
Enthusiast Enthusiast
1,386 Views
7 Replies
Message 1 of 8

Executing ULP when creating new Schematic/layout

decee.server
Enthusiast
Enthusiast

Hello,
To fix some of the stupid things I Eaglecad I want to run a ULP every time I start a new layout(specifically 'cmd-snap-board.ULP') but until now I haven't found a post explaining how to do that. Can anyone tell me? I want to automate it as I spend time fixing coordinates every time I start a new Layout..

0 Likes
Accepted solutions (1)
1,387 Views
7 Replies
Replies (7)
Message 2 of 8

RichardHammerl
Community Manager
Community Manager

Hi @decee.server 

 

thank you for you participation in the EAGLE Forum and your post. 
Do I understand correctly that you do not want to have the components initially placed in the default grid of 50 mil ? If yes, you could simply type the BOARD command into the command line in the schematic for creating the new board. Use BOARD with a grid unit and all footprints will be placed in the given grid, for example 

 

GRID 0.2mm  

 

places all parts in 0.2mm grid.

I hope this helps

 

Regards,

Richard Hammerl

Autodesk
0 Likes
Message 3 of 8

decee.server
Enthusiast
Enthusiast

Yes exactly,

I hate how components are placed so "random" and is placed with 0.01mm or whatever 50mil is in mm 

 

It works well with specifying 'board 0.1 mm' didn't know that command!.. But that means every time I need to start a new layout i'll have to remember to write board 0.1 mm which I know I will forget
Can you configure this to be a default thing in the Eagle.scr file? 
I already got a GRID MM 0.1; in my Eagle.scr but that doesn't solve anything. I think I read somewhere it is because the Eagle.scr board settings is loaded after the components is placed and not before so that sucks.. 

0 Likes
Message 4 of 8

decee.server
Enthusiast
Enthusiast

Still looking for a solution...

0 Likes
Message 5 of 8

RichardHammerl
Community Manager
Community Manager

Hi @decee.server 

 

there is no simply solution.  The ALIGN command could do this and move all components to the current grid, but ALIGN does not have command line parameters. So we can't use it in a script file. 

 

There are some ULPs that deal with snapping components to a grid. Please check http://eagle.autodesk.com/eagle/ulp

I saw for example snap.ulp and snap2grid.ulp.
I did not look closer, but they probably do what you would like to achieve. 

If you add a command like  RUN snap.ulp;   in the eagle.scr it should do what you are looking for. 

 

Hope this helps.  Regards,

Richard Hammerl

Autodesk
0 Likes
Message 6 of 8

decee.server
Enthusiast
Enthusiast

Hello,

Adding RUN snap.ulp to my Eagle.scr means everytime i open my brd it will align which is really impractical. 
Why does they not have a option which allows you to select the grid which components are placed in when initially starting a layout?.. 

0 Likes
Message 7 of 8

lukas.roeder
Advocate
Advocate
Accepted solution

this is not hard. you need to write your own ulp to run the other ulp when creating a new board.

int IsNewFile ()
{
   int isNew = 0;
   string name;
   if (board) board(B) name = B.name;
   if (library) library(L) name = L.name;
   if (schematic) schematic(S) name = S.name;

   if (FileExists (name) == 0) return 1;
   return 0;
}

// entry point
if (IsNewFile ())
{
   exit ("RUN myUlp")
}

exit (0);

 

Message 8 of 8

decee.server
Enthusiast
Enthusiast

**** nice! I have no experience with ULP tho..
OH so you just tell Eagle.scr to run that ULP every time? 

One thing tho..  FileExists is not a function in the manual.  But i did find the example
https://www.element14.com/community/thread/20948/l/ulp-how-check-if-file-exists-or-not
After playing around i finally got it to execute the ULP.. It didn't support arguments or should i say it was coded wrong but i kinda gave up and just gave it fixed variables.
Sadly it doesn't work for some reason when you execute it using a ULP. So i had to modifty the RUN.ULP to also include the code from the grid snapping ULP. 
Man what a goddamn mess of work just to do what the align function does but they are just too lazy to add **** arguments to their function

 

Code:

int xdd;
string etxt;

#usage "<b>Snap objects in a board</b>\n"
       "<p>"
       "Snaps components, wires and vias of the current "
       "board to a given grid. "
       "If 'Show script' is checked, you can edit the MOVE commands "
       "before they are executed. So you are able to exclude certain "
       "elements from the snap procedure."
       "<p>"
       "<author>Author: support@cadsoft.de</author>"

// THIS PROGRAM IS PROVIDED AS IS AND WITHOUT WARRANTY OF ANY KIND, EXPRESSED OR IMPLIED

string Version = "Version 1.1"; // 2009-01-28 move step by step
                                // 1. Packages
                                // 2. Vias
                                // 3. Wires    alf@cadsoft.de

real   GridDist = 0.05;
enum   { unitINCH, unitMIL, unitMM, unitMIC };
string h, cmd = "";
int    unit = unitMM;   // predefined unit, can be changed to unitMM, unitINCH, unitMIC
int    Result;
string Status = "";
string script_name;

int cntm = 0;             // count unsnaped

int n = 0, x[], y[], l[], UsedLayers[];


real u2unit(int u) {
  if (unit == unitMIL)  return u2mil(u);
  if (unit == unitMM)   return u2mm(u);
  if (unit == unitINCH) return u2inch(u);
  if (unit == unitMIC)  return u2mic(u);
}


real snap(int n) {  // returns next grid point
  return round(u2unit(n) / GridDist)  * GridDist;
}


int isNew(int X, int Y, int L) {
  for (int i = 0; i < n; i++) {
    if (x[i] == X && y[i] == Y && (l[i] == L || l[i] == LAYER_VIAS )) return 0;
  }
  return 1;
}


void Move(int Layer) {
  if (UsedLayers[Layer]) {
    sprintf(h, "DISPLAY NONE %d;\n", Layer);
    cmd += h;
    // Snap the signal wires and vias:
    for (int i = 0; i < n; i++) {
      if (l[i] == Layer && (u2unit(x[i]) != snap(x[i]) || u2unit(y[i]) != snap(y[i]))) {
        sprintf(h, "MOVE (%f %f) (%f %f);\n", u2unit(x[i]), u2unit(y[i]), snap(x[i]), snap(y[i]));
        cmd += h;
        cntm++;
      }
    }
  }
  return;
}

real check_coord(int x, int y) {
  real v1, v2;
  v1 = snap(x) - u2unit(x);
  v2 = snap(y) - u2unit(y);
  if (v1) return v1;
  else if(v2) return v2;
  else return 0;
}


void snap_to_grid(void) {
  board(B) {
    script_name = filesetext(B.name, "~snap.scr");
    // Remember the active layers:
    int ActiveLayers[];
    B.layers(L) {
      ActiveLayers[L.number] = L.visible;
    }
    if (unit == unitMIL)  {
      sprintf(h, "GRID MIL FINEST;\n");
      cmd += h;
    }
    if (unit == unitMM)   {
      sprintf(h, "GRID MM FINEST;\n");
      cmd += h;
    }
    if (unit == unitINCH) {
      sprintf(h, "GRID INCH FINEST;\n");
      cmd += h;
    }
    if (unit == unitMIC)  {
      sprintf(h, "GRID MIC FINEST;\n");
      cmd += h;
    }
    sprintf(h, "SET OPTIMIZING OFF;\n"); // 2009-01-28
    cmd += h;
    if (!argv[1]) {  // 1. snap elements
      // Snap the elements:
      B.elements(E) {
        status("Element: "+E.name);
        if (u2unit(E.x) != snap(E.x) || u2unit(E.y) != snap(E.y)) {
          sprintf(h, "MOVE %s (%f %f);\n", E.name, snap(E.x), snap(E.y));
          cmd += h;
          cntm++;
        }
      }
    }
    // snap check vias
    if (argv[1] == "V") {  // 2. snap vias
      // Collect all (unique!) signal via coordinates:
      B.signals(S) {
        status("Signal: "+S.name);
        S.vias(V) {
          UsedLayers[LAYER_VIAS] = 1;
          x[n] = V.x;
          y[n] = V.y;
          l[n] = LAYER_VIAS;
          if(check_coord(V.x, V.y)) n++;
        }
      }
    }
    if (argv[1] == "E" && n) {
      cmd  = "";
      for (int vn = 0; vn < n; vn++) {
        sprintf(h, "(%.4f %.4f);\n", u2unit(x[vn]), u2unit(y[vn]) );
      }
      cmd+=h;
      sprintf(h, "Kann %d VIAs nicht snapen\n", n);
      dlgMessageBox(h+cmd, "OK");
      exit(-1);
    }
    // snap check wires
    if (argv[1] == "W") {   // 3. snap wires
      // Collect all (unique!) signal wire coordinates:
      B.signals(S) {
        status("Signal: "+S.name);
        S.wires(W) {
          UsedLayers[W.layer] = 1;
          if (isNew(W.x1, W.y1, W.layer)) {
            x[n] = W.x1;
            y[n] = W.y1;
            l[n] = W.layer;
            if (check_coord(W.x1, W.y1)) n++;
          }
          if (isNew(W.x2, W.y2, W.layer)) {
            x[n] = W.x2;
            y[n] = W.y2;
            l[n] = W.layer;
            if (check_coord(W.x2, W.y2)) n++;
          }
        }
      }
    }

    // Go through the used layers (this avoids problems with wires on different
    // layers that are selected at the same coordinates):
    for (int u = LAYER_TOP; u <= LAYER_BOTTOM; u++) {
      Move(u);
    }
    Move(LAYER_VIAS);

    // Reactivate the active layers:
    sprintf(h, "DISPLAY");
    cmd += h;
    for (int j = 1; j < 256; j++) {
      if (ActiveLayers[j]) {
        sprintf(h, " %d", j);
        cmd += h;
      }
    }
    sprintf(h, ";\n");
    cmd += h;
    if (!argv[1]) {
      sprintf(h, "RUN '%s' 'V' %d %.4f;\n", argv[0], unit, GridDist);
    }
    else if (argv[1] == "V") {
      sprintf(h, "RUN '%s' 'W' %d %.4f;\n", argv[0], unit, GridDist);
    }
    else if (argv[1] == "W") {
      sprintf(h, "RUN '%s' 'E' %d %.4f;\n", argv[0], unit, GridDist);
    }
    else if (argv[1] == "E") {
      exit(0);
    }
  }
  return;
}


//---- main ----------------------------------------------------------------------

if (!board) {
  dlgMessageBox(usage + "<hr><b>ERROR: No board!</b><p>\nThis program can only work in the board editor.");
  exit(1);
}


int FileExists( string name ) {
     string files[];
     return (fileglob(files, name) != 0);
}


int IsNewFile () {
   int isNew = 0;
   string name;
   if (board) board(B) name = B.name;
   if (library) library(L) name = L.name;
   if (schematic) schematic(S) name = S.name;

   if (FileExists (name) == 0) return 1;
   return 0;
}

// entry point
if (IsNewFile ()) {
   
   unit = 2;
  GridDist = 0.05;
  
  snap_to_grid();
  
}

output(script_name, "wtD") printf(cmd);
string s;
sprintf(s, "SCRIPT '%s'\n;GRID LAST;\n%s;\n", script_name, h);
exit(s);

 

0 Likes