Идея
Большинство моих плат — вариации одной темы: микроконтроллер, сотовый модем, реле, входы контроля сети, дерево питания. Чертить пятую вариацию руками — не инженерия, а набор текста. Поэтому 8 июля 2026 я попробовал наоборот: описать плату на Python и дать скрипту выдать проект KiCad. tools/kigen.py со спутниками — около 1 500 строк.
Что делает генератор
- Разбирает s-выражения KiCad. Небольшой парсер с нуля читает библиотеки
.kicad_sym(в том числе конвертации easyeda2kicad для компонентов LCSC), так что генератор встраивает ровно те символы, которые нужны плате. - Расставляет экземпляры символов по сетке 2,54 мм и вычисляет координаты выводов с учётом поворота, чтобы метки попадали на выводы при любой ориентации.
- Подключает каждый вывод глобальными метками. Никаких нарисованных проводов; каждая цепь — метка на каждом выводе. Некрасиво, зато однозначно, без ошибок ERC и легко сравнивается в diff.
- Строит плату через Python API pcbnew: расстановка посадочных мест по функциональным группам, контур, медные зоны, классы цепей.
- Трассирует и экспортирует через freerouting (по файлу Specctra DSN) и
kicad-cli, после чего пост-обработка заново применяет зоны и правила.
Цепочка — одна команда: gen_sch → ERC → netlist → gen_pcb → DSN → freerouting → post_route → export_all. Поменял компонент в генераторе, перезапустил — получил новый проект.
Какая плата получилась
Контроллер освещения 220 В на двухслойной плате 175 × 115 мм:
- четыре релейных выхода HF32FV-16 на 16 А с драйверами S8050, обратными диодами, светодиодами состояния и съёмными клеммами 5,08 мм с коммутируемыми L и N на каждый канал;
- восемь входов контроля 220 В через оптопары LTV-817S — 3 × 100 кОм последовательно, встречно-параллельный 1N4148 и RC-фильтр 47 кОм / 1 мкФ, закрывающий провалы между полупериодами;
- дерево питания: AC-DC HLK-10M05 за предохранителем 5 × 20 T2A и варистором 10D471K → понижающий TLV62585 на 3 А для шины модема 3,8 В с полимерными конденсаторами → AMS1117 на 3,3 В;
- ESP32-S3 с нативным USB-C (разъём GCT USB4145, защита USBLC6), кнопки BOOT/RESET, Wi-Fi/BLE как резервная связь;
- SIMCom A7682E LTE Cat-1 с micro-SIM, защитными сборками, краевой антенной SMA на копланарной дорожке ~50 Ом и преобразователями уровня SN74LVC1T45 для UART на 1,8 В;
- часы DS3231MZ с TCXO, батарейкой CR2032 и прерыванием будильника на GPIO.
Сетевая и логическая части физически разнесены и имеют свои классы цепей: MAINS с зазорами 2,5 мм / 1,5 мм, MAINS_SENSE, POWER и RF. Все компоненты намеренно из наличия LCSC/JLCPCB.
Честный статус
Сгенерированная схема проходит ERC; плата расставлена, зоны и правила заданы. Она пока не оттрассирована — freerouting есть в цепочке, но прогон не доведён до конца, — так что это демонстрация генератора и проектное исследование, а не изготовленная плата. Изготовленные платы того же семейства — контроллеры FOURLEDS, начерченные в KiCad вручную.
Зачем это
Потому что вторая плата занимает вечер вместо недели, потому что каждое проектное решение лежит в системе контроля версий как код, и потому что рецензент прочитает gen_sch.py быстрее, чем прощёлкает сорок листов. Парсер и помощники расстановки переиспользуются; меняется только описание платы.
Что сделал бы иначе
Генерировал бы настоящие провода для коротких локальных цепей (развязка, резисторы светодиодов), а глобальные метки оставил только для шин и питания: схема из одних меток корректна, но чужому человеку её тяжело читать. И довёл бы freerouting до конца, прежде чем заканчивать день.