9부까지는 4층 IO 보드 한 장의 이야기였습니다. 이번엔 새 보드입니다 — RP2040에 DC24V 입력, 옵토 절연 입력 4채널, 릴레이 출력 4채널, 4층 72×84 mm.
그리고 이번 편의 주제는 하나입니다.
한 문장 요약
미연결이 남았다는 것은 결론이 아니라, 다음 조사의 시작점입니다.
이번 작업에서 저는 “이건 물리적으로 불가능하다”고 세 번 결론 냈습니다. 세 번 다 틀렸고, 세 번 다 원인은 보드가 아니라 제 코드가 통로를 못 본 것이었습니다.
1. 제조 최소 사양은 “풀기 위해” 건드리는 변수가 아니다
비아 드릴 사양을 먼저 건드렸습니다. 배선이 안 빠지길래 비아를 0.35/0.20으로 줄였더니 문제가 풀렸습니다. DRC도 통과했습니다. 그런데 이건 푼 게 아니라 미룬 것이었습니다.
돌아온 지적은 명확했습니다.
“비아는 너무 작게 뚫으면 비아가 터지거나 내층이 정상으로 안 뚫린다. 라인도 마찬가지로 너무 얇으면 특수 PCB가 아닌 이상 정상으로 프린트되지 않는다.”
그래서 사양을 실측으로 고정했습니다. 사내 양산 CAM 9세트의 드릴 테이블을 전부 열어 보니 최소 드릴이 예외 없이 0.300~0.305 mm였습니다. 설계 원본의 비아 스택도 같은 말을 했습니다: 표준 비아 드릴 0.305 / 패드 0.610.
교차검증도 됐습니다. 9장 전부에서 이 셋이 정확히 일치합니다.
보드의 비아 개수 = 드릴 1번 툴(0.30) 개수 = 0.61 패드 어퍼처 개수
예) 352 = 352 = 352, 173 = 173 = 173
여기서 얻은 규칙은 이겁니다.
제조 사양을 낮춰서 풀리는 문제는 대개 푼 게 아니라 미룬 것입니다. 사양은 마지막까지 고정 변수로 두고, 움직이는 것은 배선과 배치입니다.
그래서 빌드 마지막에 비아 게이트를 넣었습니다. 규격 미달 비아가 하나라도 있으면 빌드가 멈춥니다. 규칙을 문서에만 적으면 지켜지지 않습니다 — 코드로 박아야 지켜집니다.
2. 0.4 mm 피치 옆에는 비아가 “안 들어가는 게 맞다”
QFN-56 핀 피치는 0.4 mm입니다. 여기에 표준 비아를 놓으려면 얼마가 필요한지 산수로 확인했습니다.
비아 반지름 0.300 + 클리어런스 0.150 + 이웃 배선 반폭 0.075 = 0.525 mm
필요 0.525 > 가용 0.400 → 안 된다
이건 도구 결함이 아니라 진짜 기하입니다. 그런데 여기서 제가 틀린 건 결론이었습니다. “비아가 안 들어가니 이 핀은 못 뺀다”고 했는데, 애초에 거기에 비아를 놓을 이유가 없었습니다. 핀에서는 선만 평행 차선으로 빼고, 보드가 열리는 지점까지 나간 다음 거기서 층을 바꾸면 됩니다.
막힌 것은 “핀 옆에 비아”였지 “그 핀의 탈출”이 아니었습니다. 안 되는 것을 정확히 좁히지 않으면, 되는 것까지 같이 포기하게 됩니다.

풀린 뒤의 MCU 주변입니다. 핀에서 나온 선들이 평행 차선으로 곧게 빠져나가고, 비아는 그 차선이 끝나 자리가 생기는 지점에 모여 있습니다. 핀 바로 옆에 구멍이 하나도 없는 것이 이 그림의 요점입니다.
3. “물리적으로 불가능” 세 번, 전부 도구 결함
| 제가 내린 결론 | 실제 원인 |
|---|---|
| “차선 끝이 갇혀서 못 나간다” | 패드 크기를 GetSizeX/Y(패드 자기 좌표계)로 재서 회전 부품에서 가로세로가 뒤바뀜 |
| “미로가 경로를 못 찾는다” | 격자 0.10이 팽창에 한 칸을 더해, 0.288 mm 여유를 0.325 필요로 오판 |
| “패드가 완전히 둘러싸였다” | 접지 포어를 벽으로 취급해서, 1 mm 비어 있는 곳을 막힌 것으로 봄 |
세 번 다 화면상으로는 “보드가 꽉 찼다”로 보였습니다.
GetSizeX/Y 함정은 이 프로젝트에서만 세 번 밟았습니다.
그래서 순서를 규칙으로 만들었습니다.
- 좌표로 잽니다. 인상이 아니라 숫자로. 여유 vs 필요폭.
- 여유가 필요폭보다 크면 도구를 의심합니다.
- 판정 기준을 통일합니다. 마감 루프와 최종 게이트가 다르게 재면, 루프는 자기 기준으로만 좋아지고 게이트는 계속 끊김을 봅니다.
- 그래도 남으면 배치를 바꿔 다시 돌립니다.
4. 배치를 사람이 고르면 재현이 깨진다 — 루프 안에 넣었다
배치 탐색 루프(위 4번)가 이번 편의 핵심입니다. 배치를 바꾸면 결과가 실제로 달라집니다.
| 바꾼 것 | 미연결 |
|---|---|
| QFN 여유(halo) 4.0 → 6.0 | 9 → 4 |
| QFN 위치 (30,26) → (36,30) | 4 → 2 |
| 라우터 1회 → 5회 중 최선 | 1~9로 흔들리던 것이 1로 안정 |
여기서 하나 더 알게 된 게 있습니다. 라우터 편차가 배치보다 큽니다. 같은 입력으로 미완주가 1에서 20까지 나옵니다. 편차가 지배하면 그걸 없애려 애쓸 게 아니라 자동화 안에 집어넣으면 됩니다 — 여러 번 돌려서 가장 좋은 것을 씁니다. 복권이 아니라 정해진 비용입니다(시도 수 × 라우팅 시간).
그래서 최종 형태는 이렇게 됐습니다.
후보 배치를 순회하며 전 파이프라인을 돌린다
├ 라우팅은 매번 5회 시도해 미완주가 가장 적은 것을 채택
├ 미연결 0 + 단락 0 이면 즉시 중단하고 저장
└ 후보를 다 돌아도 0이 아니면 → 라우터 시도 배가 → 보드 확대(76×88 → 80×92 …)
포인트는 후보를 다 돌고도 끝내지 않는다는 것입니다. 부품이 보드를 꽉 채운 경우가 아니라면, 열릴 때까지 단계를 올립니다.
5. 정작 제일 많이 잡아먹은 건 “루프 자체가 죽는 방식”이었다
자동화 인프라에서 시간이 녹았습니다. 배치 루프를 돌리기 시작하자 배선이 아니라 거기서 시간이 갔고, 네 가지 전부 조용히 틀리는 종류였습니다.
① 두 빌드가 같은 보드 파일을 썼습니다.
앞 빌드가 아직 도는데 락 파일을 rm으로 밀어버렸습니다. 결과가 섞였습니다.
→ 락은 지우는 게 아니라 작업 디렉터리를 분리하는 것이 답입니다.
② 작업 사본의 트리 위치를 안 지켰습니다.
스크립트가 ROOT = 상위의 상위 로 공유 라이브러리를 찾는데, 보드 폴더만 복사하니
FootprintLoad가 None을 돌려주고 배치가 통째로 죽었습니다.
③ 사본을 만드는 sed 한 줄이 문법 오류였습니다.
그래서 실행 스크립트가 아예 만들어지지 않았고, 후보 12개가 전부 “실패”로
집계됐습니다. 로그가 0줄이라는 게 신호였는데 늦게 봤습니다.
후보가 전부 똑같이 실패하면 후보를 의심할 게 아니라 루프를 의심해야 합니다. 12개가 하나도 빠짐없이 같은 지점에서 죽는 건 설계 문제일 수가 없습니다.
④ 살아 있는 빌드를 제가 죽였습니다.
파이프의 grep이 블록 버퍼링을 해서, 멀쩡히 돌던 빌드가 로그상 멈춘 것처럼 보였습니다.
“죽었네” 하고 전역 taskkill을 세 번 했습니다. 병렬로 돌던 후보가 전부 같이 죽었고,
저는 그걸 “후보가 완주를 못 했다”고 읽었습니다.
→ 살았는지 죽었는지는 로그가 아니라 프로세스 목록으로 판단합니다.
진행을 보고 싶으면 bash -x 추적(stderr, 무버퍼)을 씁니다.
6. 배치 루프가 찾은 결과
배치 루프가 찾은 답은 제가 “실측으로 최적”이라 믿던 값이 아니었습니다.
U1(36, 30), 여유 5.0, 보드 72×84 → 미연결 0 / 단락 0
스윕에서는 여유 6.0이 더 좋아 보였는데, 실제로 0을 낸 건 5.0이었습니다. 라우터 편차가 그만큼 크다는 뜻이고, 그래서 사람이 스윕 표를 보고 고르는 것보다 루프가 끝까지 도는 편이 낫습니다.

루프가 찾아낸 배치로 다시 깐 결과입니다. 주황이 상면, 초록이 내층 배선이고 빨강은 내층 평면입니다. 아래쪽 릴레이 구역이 성기고 위쪽 MCU 구역이 빽빽한 것이 이 보드의 성격을 그대로 보여줍니다 — 막히는 곳은 언제나 같은 자리였습니다.

같은 보드의 하면입니다. 가운데 정사각형이 0.4 mm 피치 QFN이고, 그 둘레로 저항과 커패시터가 촘촘히 붙어 있습니다. 위 배선 그림에서 빽빽하던 구역이 실제로는 이런 모습입니다 — 부품이 이만큼 몰려 있으니 탈출 통로가 그렇게 좁았던 것입니다.
검증은 루프가 낸 숫자를 믿지 않고 다시 쟀습니다.
| 항목 | 결과 |
|---|---|
| 넷리스트 | NETS MATCH |
| DRC 3회(최악값) | 미연결 0, 단락 0 |
| 남은 위반 | starved_thermal 1 (서멀 릴리프 — 없애면 납땜이 안 되므로 그대로 뒀습니다) |
| 비아 215개 | 전부 0.60/0.30 이상 |
| 각도 | 자유각 0 |
이번 편에서 얻은 규칙
“안 된다”는 보고서를 닫기 전에 네 단계를 다 밟았는지 확인합니다: 좌표 · 도구 · 판정 기준 · 배치.
- 제조 최소 사양은 마지막까지 고정 변수입니다. 낮춰서 풀리면 미룬 것입니다
- 안 되는 것을 정확히 좁힙니다 — “핀 옆 비아”가 막힌 것과 “그 핀의 탈출”이 막힌 것은 다릅니다
- 편차가 지배하면 편차를 자동화 안에 넣습니다(best-of-N)
- 후보가 전부 똑같이 실패하면 루프를 의심합니다
- 로그가 멈춘 것처럼 보인다고 죽은 게 아닙니다 — 프로세스로 확인합니다
- 배치 선택을 사람 손에 두면 재현이 깨집니다. 루프 안에 있어야 합니다
미연결이 남았다는 것은 결론이 아니라, 좌표 · 도구 · 판정 기준 · 배치를 차례로 확인하라는 신호입니다.
다음 편에서는 이 보드를 사내 양산 도면 9장과 나란히 놓고 뜯어본 이야기를 쓸 생각입니다. 카파(구리 포어)를 어떻게 까는지, 거버에서 무엇을 읽을 수 있고 무엇을 읽으면 안 되는지 — 거기서 제가 예전에 잘못 적어둔 수치 하나도 정정하게 됐습니다.
▶️ 11부 — 220V 절연 장벽: 이번엔 계통 전압이 올라오는 판입니다. 절연 장벽을 재는 제 격자가 KiCad DRC와 열 번 어긋났고, 열 번 다 제 쪽이 더 관대했습니다.
🔧 시리즈 전체: 1부 · 2부 · 3부 · 4부 · 5부 · 6부 · 7부 · 8부 — 완성 · 9부 — 리뷰
문의
- Email : [email protected]
- Insta : https://www.instagram.com/going.sen/
- Website : https://intosen.com/kr/consult/
댓글
닉네임만 입력하면 바로 댓글을 남길 수 있어요. Google/GitHub 로그인도 가능합니다.