EagleでViaをたくさん打ちたい

 回路cad Eagleで基板レイアウトの設計をしたあと,GNDを安定化させるためにViaをたくさん打つ人は多いかと思います.僕はいつもGNDに名前をつけたViaをコピペして描いていたのですが,配線の手直しが入ると,すでに描いたViaに手をつける必要があって面倒でした.

f:id:sunsun-ele:20180414155531p:plain
コピペしたviaの例

ULPで自動化を目指す

 東工大のロ技研には,Eagleのプロがいてゲームを作っていたり,Tweetしたりしてます*1. それは,ULP(User Language Programs)とスクリプトでEagleのコマンドを叩いているようですが,これでVia打ちを自動化できないかと思ったわけです. 彼(彼女)に話を聞いたところ,ULP(User Language Programs)はC言語のような言語で書けるようなので早速書いてみました.

先行研究

 でもやっぱ同じことを考える人はいるようで,過去にもVia打ちを自動化しようと試みた方がいました.

  1. GitHubで見つけたいい感じなソース
  2. ULPでDRCをする方法についての質問

 しかし,1.の場合は配線の上を避けるようにviaを打つというもので,DRC(Design Rule Check)のいくつかに引っかかるという問題がありました.そこで,DRCのError数の増加をみることでViaを打つか打たないか決めるプログラムを作成しようと考えました.しかし,2.をみるとULPからは直接,DRCコマンドを叩くことができないらしく,1時間くらい悩んでいました.

 結局,先行研究のプログラムを組み合わせ,ULPでスクリプトを作成しそれを実行することで解決しました.スクリプトは,viaを置くコマンド,DRCコマンド,Error数をチェックするULPを組み合わせて作成します.

中身

via-fill.ULP

 先行研究1のvia-fill.ulpを書きかえます.

最初にDRCの結果をみてErrorの数を数える関数を追加します.

int error_count(void)
{
    int ErrCnt=0;

    if(board) board(B)
    {
        if(B.checked)
        {
            B.errors(ER)
            {
                if(ER.state == ERROR_STATE_ACTIVE)
                {
                    ErrCnt++;
                }
            }
        }
    }
    return ErrCnt;
}

以下の点線の行間を追加します.やっていることは,VIAコマンド,DRCコマンド,自作したcheck_error.ulpを実行するコマンドを繰り返しスクリプトファイルに出力するだけです.

//check if via on polgyon
nVias = n;
nAddedVias = 0;
for(n=0;n<nVias;n++)
{
  sSignal=IsOnPolygonSignal(nXVia[n], nYVia[n]);    //see if vias has a signal under two layers and return signal name
  if(sSignal!="")
    {
      //write a via of that signal to that position
      sprintf(t,"VIA '%s' (%f %f)\r\n", sSignal, nXVia[n], nYVia[n]);
      printf(t);
      -----------------------------------------------------------------
      sprintf(t,"DRC (%f %f) (%f %f)\r\n",nXVia[0],nYVia[0],nXVia[nVias-1],nYVia[nVias-1]);
      printf(t);
      sprintf(t,"RUN check_error %d\r\n",initError);
      printf(t);
      -----------------------------------------------------------------
      nAddedVias++;
    }
}

error_check.ULP

初期のerror数を引数としてわたすと,現在のerror数と比較して直前のViaを消すか否かを判断するULPを書きます.argv[1]は引数となる初期error数です.undoコマンドは,一つ戻るコマンドです.

int error_count(void)
{
    int ErrCnt=0;

    if(board) board(B)
    {
        if(B.checked)
        {
            B.errors(ER)
            {
                if(ER.state == ERROR_STATE_ACTIVE)
                {
                    ErrCnt++;
                }
            }
        }
    }
    return ErrCnt;
}

if(error_count() > strtol(argv[1]))
{
    exit("undo");
}
exit(0);

これらのulpをulpフォルダに追加します.

使ってみる

  1. 最初に通常通り,DRCを実行します.これは初期error数をカウントする準備であり,任意のDRUファイルをloadするためでもあります.
  2. 次にvia-fill.ulpを実行します.するとUIがでるので,Viaの名前を選択してaddします.よく調べていないのですが,おそらくベタ塗りのポリゴン名から名前をリストアップしていると思われます.また,Viaを打つ間隔も設定します.そして,place viaをクリックします.
    f:id:sunsun-ele:20180414154954p:plain
    via-fill.ulpのUI
  3. 実行終了まで時間がかかります.すると,viapos.scrとviaposundo.scrが作成されます.その後,scrでviapos.scrを実行すると,viaを自動で打ってくれます.打ち終わった後,viaを消したい場合はviaposundo.scrを実行すれば,undoを繰り返してvia打ち前まで戻ってくれます.
    f:id:sunsun-ele:20180414155001p:plain
    viapos.scrの例
    f:id:sunsun-ele:20180414154958p:plain
    via自動配置の結果

さいごに

完全な自動化には至りませんでしたが,すごく楽になりました.いわゆる半自動ってやつですが,スクリプトを実行するスクリプトを作成すれば解決すると思われます.

でも今回は,回路cadの一つであるkicadの次バージョンで自動via打ちが実装される噂を聞いて,Eagleで先にやってしまおうという不純な動機で始めたことなのでこの結果で許してほしいところです()

ではまた.

*1:rogy公式blog:https://goo.gl/qacMB1