KiCad を使わずに、Python だけで基板を“配線”してみる — 素朴な迷路法で
- python
- 電子工作
- pcb
- アルゴリズム
- プリント基板
まとめ(先に結論)
- プリント基板の設計といえば KiCad のような GUI ツールが定番ですが、Python のコードだけでも基板データ(製造に出す Gerber やドリルファイル一式)を作れます。
pcbflowというライブラリを使いました - 部品を置いたあとの 「配線」(どのピンとどのピンを、どの線でつなぐか)を、自分で書いた素朴なプログラムにやらせてみました。アルゴリズムは 「迷路法」 という、迷路の最短ルートを探すのと同じ考え方です
- 2 層基板で、表だけで詰まったら ビア(表と裏の配線をつなぐ穴) で裏に逃がして回り込みます。線幅 0.3 mm・線どうしのすきま 0.3 mm・曲がり角は 45°、という扱いやすいルールも入れました
- 結果、22 本の配線がぜんぶ通りました。「素朴なやり方でも、今回くらいゆったりした基板なら案外いけるんだな」というのが、正直な感想です
配線を自動でやってくれるソフト(オートルータ)の中身が、私はずっと「なんとなくすごいもの」くらいの理解でした。今回はその一番素朴なところを、自分の手で作って確かめた記録です。専門でやってきたわけではないので、間違いや「ここはこう書くともっと良い」があれば、ぜひ教えてください。
そもそも:Python だけで基板って描けるの?
「基板を作る」というと、ふつうは KiCad などの画面で部品を並べて線を引くイメージだと思います。でも調べてみると、コードで基板を記述して、そのまま製造データまで吐き出せるライブラリがいくつかありました。今回使ったのは pcbflow です。
製造データというのは Gerber(ガーバー) という、基板屋さんに渡すための業界標準フォーマットのこと。銅の線がどこを通っていて、シルク(白い文字)が何と書いてあるか…を層ごとに記録したものです。穴あけの位置は、これとは別の「ドリルファイル」として出します。pcbflow は、このあたりを Python のコードから組み立てて、save_gerbers() の一発で書き出せます。KiCad は使いません。
試しに、IC(DIP=足が 2 列に並んだパッケージ)やコネクタ、抵抗、パスコン(ノイズを抑えるための小さなコンデンサ)を置いてみたのがこちらです。白い枠と文字がシルク、緑の丸がスルーホール(足を通す穴つきのパッド)です。

ちなみに小さなつまずきもありました。汎用の DIP(IC のパッケージ)を置く部分で、ピン数が 4 の倍数でないと左右の列が 1 ピッチぶんズレて並んでしまう現象に出くわしました。中身を読んでみると、列の中心を求める式が「4 の倍数のときだけ」きれいに合うようになっていたんですね。なので、任意のピン数で対称になるように自分で直しました。中を覗いて自分で直せるのも、ソースが読めるオープンソースと Python のありがたいところですよね。
配線を「格子の上の探索」にする
部品が置けたら、次は 配線です。配線とは要するに「このピンとこのピンを銅の線でつなぐ」こと。どのピン同士を同じ線でつなぐか、をまとめた一覧を ネットリスト と呼びます(今回はすべて「2 つのピンを 1 本でつなぐ」形だけにしました)。
これをプログラムに解かせるために、基板を細かい 格子(グリッド) に区切ります。線はこの格子の線の上だけを通る、というルールにすると、「配線」は「格子の上で、あるマスから別のマスへ道を見つける」問題になります。迷路を解くのとそっくりですよね。
部品のピンが必ず格子の交点に乗るように置いたのが下の図です(全部のピンが緑=格子上に乗っています)。

格子の細かさは、製造のルール(デザインルール)から決めました。線幅 0.3 mm、線と線のすきま(クリアランス)0.3 mm なら、線の中心どうしは最低 0.6 mm 離れていればぶつかりません。そこで格子を 0.635 mm 刻み(部品のピン間隔 2.54 mm をちょうど 4 分割した値)にしました。これなら、隣り合う格子線に線を通しても 0.3 / 0.3 mm のルールをぎりぎり満たせます。
素朴な「迷路法」で 1 本ずつ引いてみる
道の探し方には A*(エースター)という定番のアルゴリズムを使いました。もともと迷路の最短経路は、スタートから水がしみ出すように 1 マスずつ全方向へ広げて探します(幅優先探索)。A* はそこに「ゴールに近そうな方を先に調べる」という当たりをつけて、ムダな広げ方を減らしたもの。名前はいかついですが、やっていることは迷路解きの延長です。すでに引いた線や他の部品のパッドは「壁」として避けます(正確には、線やパッドそのものだけでなく、クリアランスぶん近づけない範囲も壁あつかいです)。
ただ、1 層(片面)だけだと、線どうしの交差を避けきれずに行き詰まることがあります。そこで 2 層にして、表(赤)で詰まったら ビア(内側が銅めっきされ、表と裏の配線をつなぐ穴)で裏(青)に潜り、表では通れない場所を裏の空いた経路で回り込んでまた表に戻る、という逃げ道を用意します。ちなみにビアを通るのは少し「割高」に設定して、できるだけ同じ層を走らせるようにしました。

今回のプログラムは、いちばん素朴に 「ネットを上から順番に、1 本ずつ引いていくだけ」。先に引いた線が場所を占有して、あとの線はそれを避ける――それだけの、ゆずり合いも引き直しもしない素朴版です。
やってみた
結果がこちらです。左が部品を置いただけの状態、右が素朴な迷路法で配線したあと。探索そのものは縦横(直交)の格子で動かして、最後に直角の曲がり角だけを短い 45° の線に置き換えています(こうすると見た目が基板っぽくなります。本当はこの後、面取りした線が他の線やパッドに近づきすぎていないかの確認も要ります)。

| 指標 | 値 |
|---|---|
| ネット数 | 22 |
| 配線できた本数 | 22 / 22 |
| ビア | 1 |
| 総配線長 | 約 485 mm |
| 計算時間(手元の PC) | 約 60 ミリ秒 |
(電源・GND は今回は基板の広い銅面(ベタ面)でまとめてつなぐ想定にして、信号の線だけを数えています。)
正直に言うと、やる前は「素朴な順番引きだと、何本かは引けずに残るだろうな」と思っていました。ところが、ぜんぶ通ってしまった。ちょっと拍子抜けするくらい、あっさりです。
正直な感想と、次回への宿題
種明かしをすると、今回の基板は 部品がゆったり並んでいて、配線の通り道(チャンネル)に余裕があるんです。だから、ゆずり合いのない素朴なやり方でも、すんなり通ってしまった。逆に言うと、自動配線が本当に難しくなるのは、部品を詰め込んで通り道が減ったときや、守るべき制約(電源・ノイズ・線の長さなど)が増えたとき。今回はそのどれもがゆるいから、すんなり通ったんだな、と手を動かして腑に落ちました。
なので次回は、
- 賢いやり方(一度引いた線を消して引き直す「rip-up & reroute」や、ネットを引く順番を工夫する…など)を入れたら、素朴版とどう違うのか
- 部品を詰め込んでいくと、素朴なやり方がどこで破綻するのか
このあたりを試してみたいと思っています。
ここまで、いちばん素朴なところだけを試した、最初のステップの記録でした。「基板の配線って、結局は格子の上の迷路解きなんだ」という感覚が、少しでも伝わっていたら嬉しいです。読んでくださって、ありがとうございました。
この記事は Zenn に初出したものを加筆・補足したものです ── Zenn の元記事を見る