10부까지는 24 V 보드였습니다. 이번엔 220 V가 올라오는 판입니다.
먼저 범위를 분명히 해두겠습니다. 회로도와 아트웍은 20년 넘게 그려왔지만, 그동안 다룬 건 전부 저전압 제어 보드였습니다. 모터 브레이크 정류 회로는 이번이 처음입니다. 전자석 브레이크에 넣는 정류 회로도, 계통 전압이 올라오는 판의 절연 설계도 제가 해온 분야가 아닙니다. 그래서 이 보드는 제품이 아니라 안 해본 분야를 AI와 같이 더듬어 본 프로토타입입니다.
모터 브레이크는 전자석이라 전원을 끊으면 스프링이 브레이크를 겁니다. 그 전자석에 정류된 DC를 넣어주고, 동시에 “제동 명령을 내렸는데 전류가 계속 흐르는” 상태를 감시하는 판을 만들어보고 싶었습니다.
정류 회로 쪽에서 제가 스스로 판단할 수 있는 건 거의 없었습니다. 그래서 판단은 문서와 도구에 넘기고, 저는 그 둘이 서로 맞는지만 봤습니다. 결과적으로 이 글은 회로 이야기가 아니라, 그 “서로 맞는지 보는” 일이 열 번 어긋났다는 이야기입니다.

완성한 판의 3D 렌더입니다. 위쪽 계통 구역에 파란 바리스터 세 개와 유리관 퓨즈,
오른쪽에 큰 릴레이가 있고, 아래쪽 저전압 구역에 작은 부품과 단자대가 몰려 있습니다.
왼쪽 모서리 실크에 찍힌 S E L V 가 이 글에서 계속 이야기할 그 경계입니다.
절연 장벽 — 연면거리와 공간거리는 정하는 것이 다르다
절연 장벽은 220 V 쪽과 사람이 만질 수 있는 저전압(SELV) 쪽 사이에 있는, 넘으면 안 되는 선입니다. 두 종류의 거리를 지켜야 합니다.
- 공간거리(clearance) — 공기를 가로지르는 최단 직선
- 연면거리(creepage) — 기판 표면을 따라가는 거리
둘은 결정 요인이 다릅니다. 공간거리는 순간적인 과전압이 정하고, 연면거리는 정상 상태의 작동 전압이 정합니다. 저는 처음에 이걸 섞어서, 서지 전압 620 V를 연면거리 표에 집어넣고 있었습니다. 그러면 요구치가 부풀어서 배선이 아무 데도 못 들어갑니다. 실제로 한동안 “이 배치로는 불가능하다”는 결론을 반복해서 냈는데, 불가능했던 건 배치가 아니라 제가 만든 요구치였습니다.
이런 건 검색해서 답을 맞춰볼 수 있습니다. 문제는 다음이었습니다.
내 격자와 KiCad DRC가 열 번 어긋났다
격자 기반 이격 판정이 이 파이프라인의 심장입니다. 배선을 자동으로 깔려면 “여기에 선을 놓아도 되는가”를 스스로 판정해야 하니까요. 저는 0.25 mm 격자를 깔고 각 칸이 막혔는지 칠하는 방식을 씁니다. 그 판정이 KiCad 자신의 DRC와 열 번 달랐습니다. 그리고 열 번 다 제 쪽이 더 관대했습니다.
| # | 어긋난 곳 | 증상 |
|---|---|---|
| 1 | DSN 보호 표시 치환문에 \1 누락 | 선행 배선이 통째로 지워져 라우터가 그 위를 지나감 |
| 2 | KiCad가 붙인 (type route)를 보호로 오인 | 82개 전부 건너뛰고 “보호 0개”를 초록불로 통과 |
| 3 | 임시 보드 객체 수명 | 무작위 넷에서 프로세스가 트레이스백 없이 사망 |
| 4 | 넷클래스 이격 미반영 | 0.45~0.48 mm를 놓고 DRC는 0.50 요구 |
| 5 | A* 예산 소진 = “경로 없음” | 길이 있는데 12만 팝에서 포기 |
| 6 | 패드 반경을 max(w,h)/2로 | 각형 패드 158개 과소평가 |
| 7 | 패키지 예외가 절연 장벽을 넘음 | 계통 배선이 SELV 패드에 3.88 mm까지 접근 |
| 8 | A*가 출발·도착 층을 안 가림 | SMD 패드에 안 닿는 배선을 “깔았다”고 보고 |
| 9 | 부품 몸통을 장애물로 안 봄 | 패드가 바리스터 밑에 들어가 납땜 불가 |
| 10 | 후보 격자를 1 mm로 반올림 | 있는 답을 없다고 보고 |
7번만 성격이 다릅니다. 나머지는 배선이 안 되거나 도구가 죽는 문제인데, 7번은 그대로 두면 통과하는 결함입니다.
패키지 예외는 절연 장벽을 넘지 못한다 — KiCad의 규칙 순서
패키지 예외는 원래 필요한 장치입니다. 빽빽한 IC 밑에서는 이격을 그대로 적용할 수 없습니다. 핀 간격이 0.28 mm인데 이격을 0.50 mm 요구하면 그 핀에는 애초에 선을 붙일 수 없으니까요. 그래서 부품 몸통 안에서는 그 부품의 핀 간격만큼 예외를 둡니다.
문제는 이 판에 장벽을 가로지르는 부품이 있다는 것이었습니다. 안전 릴레이는 한쪽 열이 220 V, 반대쪽 열이 SELV입니다. 제 격자는 “이 부품 안이니까 예외”라고 판단해서, 계통 배선이 그 부품의 SELV 패드에 3.88 mm까지 붙는 것을 허용했습니다. 요구치는 보강절연 5.00 mm입니다.
KiCad는 이걸 잡아냈습니다. 규칙 순서가 (쌍별 → 단자대 → 패키지 예외 → 장벽)이고 KiCad는 마지막에 맞는 규칙을 씁니다. 그래서 장벽이 예외를 이깁니다. 제 격자만 그 순서를 몰랐던 겁니다.
soft = _need[n2] if crosses_barrier(net, n2) else _pkg_gap(ref)
한 줄입니다. 그런데 이 한 줄이 없는 동안 제 게이트는 계속 초록불이었습니다.
여기서 배운 것 — 자동화의 위험은 “틀린 답을 낸다”가 아니라 **“틀린 답에 초록불을 준다”**입니다. 게이트가 통과했다는 건 게이트가 맞다는 뜻이 아닙니다.
도구가 아니라 ‘재는 법’을 고쳤다 — reach · why · unblock
실패 원인을 물어볼 곳이 없다는 게 진짜 문제였습니다. 같은 자리에서 여섯 번쯤 막히고 나서야 방식을 바꿨습니다. 그전까지 저는 이랬습니다 — 배선을 시도한다 → 실패한다 → 배치를 탓한다 → 판을 키워본다. 매번 몇십 분씩 태우고 아무것도 안 남았습니다.
왜 실패했는지 아무도 말해주지 않았습니다. A*는 “못 찾았다”고만 하고, 그게 길이 없어서인지 예산이 떨어져서인지 구분이 안 됐습니다.
그래서 도구를 세 개 만들었습니다. 전부 판을 건드리지 않고, 항상 끝납니다.
reach.py— 플러드필로 “여기서 저기까지 갈 수 있나”를 답합니다. O(칸)이라 몇 초면 끝나고, 못 가면 막고 있는 벽의 좌표와 넷 이름을 찍어줍니다.why.py— 배선을 실제로 깔아보고 새로 생긴 위반만 좌표와 함께 보여준 뒤 판을 원래대로 되돌립니다. “위반 7건(기준 5)“이 아니라 “D1의 이 패드와 2.29 mm”를 알려줍니다.unblock.py— 스냅샷에서만 넷을 하나씩 지워가며 몇 개를 걷어내면 길이 열리는지 셉니다. 디스크 쓰기도, DRC도, 되돌리기도 없습니다.
효과가 즉각적이었습니다. 마지막까지 안 풀리던 넷을 reach.py에 물었더니
판 전체 47만 칸 중 1,040칸밖에 못 간다고 나왔습니다. 그리고 그 벽이 30분 전에
제가 직접 깐 배선이었습니다. 배치 탓이 아니었던 겁니다.
unblock.py는 한술 더 떴습니다. “이 둘을 걷어내면 열린다”까지 몇 초 만에 답했습니다.
그전까지 저는 그 답을 얻으려고 매번 걷어내고 → 깔고 → 되깔고 → DRC를 돌렸습니다.
한 번에 몇 분씩이었고, 벽이 연쇄로 나오면 그 값을 다 치른 뒤에야 “아직 막혔다”를
알았습니다.
몸통으로 재느냐 패드로 재느냐 — 내가 틀렸다고 확인한 순간
병목의 위치를 찾았다고 생각한 적이 있습니다. 바리스터 두 개 사이 통로가 9.34 mm인데 계통 배선 두 줄에는 9.5 mm가 필요하다 — 0.16 mm 차이로 안 들어간다, 그러니 부품을 옮겨야 한다. 그럴듯했습니다.
다시 재보니 9.34는 몸통 기준이었습니다. 구리가 신경 쓰는 패드 기준으로는 17.55 mm였습니다. 통로는 넉넉했고, 병목은 배치가 아니라 배선 순서였습니다.
이 프로젝트에서 반복되는 법칙이 있습니다 — 같은 판을 두 가지 자로 재면 두 가지 답이 나오고, 틀린 쪽은 늘 제 자였습니다.
배선으로 못 풀면 부품을 만든다 — 절연 전선 링크
마지막 한 연결이 끝내 안 들어갔습니다. 172개 연결 중 171개까지 갔고, 하나가 남았습니다.
unblock.py가 이유를 정확히 말해줬습니다. 세 넷이 같은 통로를 쓰는데 둘까지만
들어갑니다. 순서를 바꾸면 못 들어가는 넷이 바뀔 뿐이었습니다(여섯 번 확인).
Freerouting에 셋을 통째로 맡겨도 같았고, 부품을 돌려보니 주변 배선과 34건 충돌했습니다.
2층 판에서 마지막 한 줄이 안 들어갈 때의 표준 해법은 절연 전선 링크입니다. 전선은 판 위를 지나가므로 구리의 채널 경쟁에서 아예 빠집니다. 라이브러리에 없으니 만들었습니다.
여기서 배운 게 하나 더 있습니다. KiCad에게 “이 두 패드는 구리로 안 이어도 된다”를 알리려면 넷을 둘로 나눠야 합니다. 전기적으로는 같은 노드인데 이름만 다르게 두고, 그 사이를 2핀 부품(전선)이 잇습니다. 그러면 미연결이 사라집니다.
그리고 새 넷은 원래 넷이 갖고 있던 절연 요구를 전부 물려받아야 합니다. 손으로 옮겨 적으면 이름이 바뀔 때 조용히 빠지므로, 표에서 유도하게 했습니다.
for (a, b), (v, why) in list(PAIR_V.items()):
if a == "COIL_N":
_hv("COIL_N_J", b, v, why + " (전선 링크 건너편)")
전선 자리도 눈대중으로 정하지 않았습니다. 양쪽에서 배선으로 닿을 수 있는 영역 안, 계통 이격을 만족하고, 두 자리 모두 계통 구역 안(전선이 장벽을 넘지 않도록)이라는 세 조건으로 탐색해서 (21.00, 28.75) ↔ (56.00, 26.50), 전선 35.1 mm가 나왔습니다.
3D 렌더에서 부품이 사라진 이유 — 모델 경로와 offset
3D 렌더 검수를 마무리로 돌렸더니 릴레이도, 퓨즈도, 옵토도 안 보였습니다.
원인이 허무했습니다. 모델 생성기의 출력 경로 상수가 이전 보드 이름으로 남아 있었습니다. 스크립트를 복사하면서 경로만 안 바꾼 것이고, 그래서 이 프로젝트엔 3D 폴더가 아예 생기지 않았습니다. 풋프린트 10개가 없는 파일을 가리키고 있었습니다.
없는 모델 5종은 만들었습니다. 비슷한 표준 모델로 때우지 않았습니다 — 그렇게 하면 렌더에 다른 부품이 서고, 그건 렌더로 검수하려던 바로 그 오류입니다. 치수는 전부 데이터시트나 풋프린트 도면에서 읽었고, 근거를 못 찾은 값 하나(퓨즈 축 높이)는 **“전형값 선언(미확인)“**이라고 주석에 남겼습니다.
여기서도 한 번 자빠졌습니다. 모델 블록을 일괄로 갈아 끼우면서 offset을 전부 0으로
덮었더니 바리스터 세 개가 실크 상자 밖으로 어긋났습니다. 원본은 (3.750, -1.600, 0)
이었습니다. 규칙은 기하를 어디에 두었느냐로 갈립니다 — WRL 기하가 원점 중심이면
offset은 (cx, −cy, 0), 풋프린트 좌표면 0입니다. 덮어쓰기 전에 원본을 읽어야 했습니다.

배선이 끝난 상면입니다. 왼쪽 실크의 MAINS 220V~ 와 S E L V 사이로 판이 위아래
두 구역으로 갈려 있고, 그 사이에 아무것도 지나가지 않는 빈 띠가 보입니다.
그 띠가 절연 장벽이고, 이 글의 열 번은 전부 저 띠를 제대로 재는 문제였습니다.
결과 — DRC 0, 절연 위반 0
최종 수치입니다. 시작과 끝만 놓고 보면 이렇게 됐습니다.
| 항목 | 시작 | 끝 |
|---|---|---|
| DRC 위반 | 163 | 0 |
| 미연결 부품 패드 | 8개 넷 | 0 |
| 연면·공간거리 | — | 26,702쌍 미달 0 |
| 절연 장벽 | — | 위반 0 |
118 × 125 mm 2층, 부품 96, 트랙 1,185구간 3,758 mm, 비아 166.
남는 생각 — 자가 두 개일 때가 제일 위험하다
열 번의 어긋남 중 제가 스스로 찾은 건 하나도 없습니다. 이번 판에서 제 도구는 열 번 틀렸고, 그 열 번을 전부 KiCad가 잡아줬거나 제가 재는 법을 바꿔서 찾았습니다.
안 해본 분야를 AI와 같이 만들 때 제일 위험한 순간은 답을 모를 때가 아니었습니다. 서로 다른 두 개의 자를 가지고 있는데 그걸 모를 때였습니다. 제 격자가 “여기 놓아도 된다”고 하고 KiCad가 “안 된다”고 할 때, 저는 여러 번 KiCad를 의심했습니다. 열 번 다 제가 틀렸습니다.
그래서 이번에 얻은 진짜 산출물은 보드가 아니라 도구 세 개인 것 같습니다.
reach · why · unblock — 셋 다 판을 건드리지 않고, 항상 끝나고, 왜인지 말해줍니다.
“안 된다”고 말하기 전에 물어볼 곳이 생겼다는 게 제일 큰 차이였습니다.
안 해본 분야를 AI와 같이 만들 때 제일 위험한 순간은 답을 모를 때가 아니라, 서로 다른 두 개의 자를 들고 있으면서 그걸 모를 때입니다.
🔧 시리즈 전체: 1부 · 2부 · 3부 · 4부 · 5부 · 6부 · 7부 · 8부 — 완성 · 9부 — 리뷰 · 10부 — 배치 루프
문의
- Email : [email protected]
- Insta : https://www.instagram.com/going.sen/
- Website : https://intosen.com/kr/consult/
댓글
닉네임만 입력하면 바로 댓글을 남길 수 있어요. Google/GitHub 로그인도 가능합니다.