Skill v1.0.0
currentAutomated scan100/100name: "easyeda-draw-wiring" description: "Wire routing, net labeling, and connection management for EasyEDA Pro schematics. Invoke when drawing wires, adding net labels, creating power/ground symbols, or managing signal connections." metadata: version: "1.0.0"
连线与网络管理
导线绘制、网络标签、总线、电源/地符号的完整指南。
核心原则
多使用网络标号,避免复杂连线。 网络标号可以减少导线交叉,提高可读性。
0. 关键规则(必读)
0.1 导线必须设置网络名
⚠️ 导线无网络名 = 电气连接不建立在 EasyEDA 中,导线的net属性为空时,该导线不参与电气网络构建。这会导致:网络表导出错误、PCB Layout 无法建立连接关系、DRC 检测不到开路/短路。正确做法(参考 POWER 页风格):- 每创建一条导线必须指定网络名- 芯片引脚到网络标签的导线:网络名 = 标签的网络名- 同网络名的标签 + 导线 = 完整的电气连接- 模块内部导线(开关→二极管):至少指定行/列网络名
0.2 防止跨网络自动合并(API 坑)
⚠️ EasyEDA `sch_PrimitiveWire.create()` 的 net 参数陷阱:当net参数为undefined(未指定)时,API 会自动从触碰的图元继承网络名:- 导线触碰一个已有网络的导线 → 新导线自动继承该网络名- 导线触碰多个不同网络的图元 → 创建失败这会导致跨网络合并:AI 画 ROW0 导线时,如果不指定 net,而导线端点碰巧触碰到 ROW1 的导线,新导线会静默变成 ROW1,造成电气短路。防护措施:1. CLI 已修复:draw_cli.py wire不指定 net 时传空字符串""而非undefined,阻止自动继承2. 安全模式:wire --safe先检查坐标是否触碰不同网络导线,冲突时中止创建3. 批量安全:wire-batch逐条调用安全模式,适合大规模走线4. 冲突检测:check-wire-conflicts检测已存在的导线网络冲突
0.3 标签唯一性:同一坐标不能有重复标签
⚠️ 禁止在同一坐标放置多个标签同一网络只需一个标签。重复放置会导致视觉叠加、网络冲突、DRC 异常。放置标签前先检查:```bash./scripts/draw_cli.py check-duplicates```
0.3 NC 未用引脚标记
⚠️ 不使用 IC 引脚必须标记 NCNC 标记告诉 DRC "此引脚有意不连接"。必须使用 CLI 的原生 NC API(禁止放置文本 "NC"):```bash# ✅ 正确:原生 NC 标记(引脚上显示标准叉号,DRC 正确识别)./scripts/draw_cli.py mark-nc U1 14./scripts/draw_cli.py mark-nc U1 14,16```原理:mark-nc调用sch_PrimitiveComponent.setState_NoConnected(true),EasyEDA 在引脚上显示标准 NC 叉号,DRC 将其识别为"有意不连接"。
0.4 电源/地优先级规则
参考 POWER 页风格: 电源/地使用 NetFlag (Power/Ground),信号仅用延伸导线(导线已含网络名)。- VCC/VDD/VBAT →createNetFlag("Power", ...)- GND/AGND/DGND →createNetFlag("Ground", ...)- 信号 (I2C/SPI/UART/GPIO) → 仅wire延伸,不附加任何标签/文本⚠️ 不使用 NetPort/文本标注 的原因:导线本身已承载网络名,额外的符号或文本只会增加 BBox 重叠风险。
1. 导线绘制
基本绘制
await eda.sch_PrimitiveWire.create([x1, y1, x2, y2], // 线段坐标组"NET_NAME", // 网络名(必须显式指定!)null, // 颜色null, // 线宽null // 线型);
多段导线
// 折线: 从 (100,100) → (150,100) → (150,150)await eda.sch_PrimitiveWire.create([100, 100, 150, 100, 150, 150],"SIGNAL_NET",null, null, null);
多段独立导线
// 两条独立线段await eda.sch_PrimitiveWire.create([[100, 100, 150, 100], [200, 200, 250, 200]],"SIGNAL_NET",null, null, null);
⚠️ 注意: 如果多段线彼此无任何连接,创建会失败。
修改已有导线的网络名
// 用 toAsync() 修改已有导线的网络名const wires = await eda.sch_PrimitiveWire.get([wireId]);const aw = wires[0].toAsync();aw.setState_Net("NEW_NET_NAME");aw.done();
2. 网络标签 (Net Flag) — 电源/地专用
网络标签用于标识电源和地,是最常用的连接方式。
电源标签
await eda.sch_PrimitiveComponent.createNetFlag("Power", // 类型: Power | Ground | AnalogGround | ProtectGround"VCC_3V3", // 网络名x, y, // 位置0, // 旋转角度false // 镜像);
地标签
await eda.sch_PrimitiveComponent.createNetFlag("Ground", "GND", x, y, 0, false);
电源命名规范
| 网络名 | 用途 | |
|---|---|---|
VCC | 通用电源 | |
VCC_3V3 | 3.3V 电源 | |
VCC_5V | 5V 电源 | |
VCC_1V8 | 1.8V 电源 | |
VBAT | 电池电源 | |
VBUS | USB 总线电源 | |
VDD | 数字电源 | |
VSS | 数字地 | |
GND | 通用接地 | |
AGND | 模拟地 | |
DGND | 数字地 | |
PGND | 电源地 |
3. 信号标注 — 延伸导线-only
⚠️ NetPort 已不推荐,文本标注也已不推荐。导线本身承载网络名,无需额外符号或文本。
策略 A — 信号引脚:仅延伸导线,导线网络名即信号名,不附加任何额外标签/文本。
wire "pinX,pinY,pinX ± distance,pinY" SIGNAL_NAME
策略 B — 电源/地引脚:延伸导线 + NetFlag。NetFlag 坐标必须 = 导线终点(否则电气不连接)。
wire "pinX,pinY,endX,endY" VCC # 先延伸导线netflag Power VCC endX endY # 再贴 NetFlag(坐标=导线终点)
标签摆放规则:
- 左侧引脚:文字左对齐,靠近导线末端,但远离 PIN 脚编号
- 右侧引脚:文字右对齐,同上
- 上侧引脚:文字上对齐,同上
- 下侧引脚:文字下对齐,同上
- 若文字覆盖编号:旋转 180° 或缩短导线长度
策略 C — 同侧同名电源/地合并:连续同名引脚,竖线段短接 → 一根水平引出 → 共 1 个 NetFlag。
wire "pin1X,pin1Y,pin1X,pin2Y" GND # 竖线短接连续同名引脚wire "pin1X,pin2Y,pin1X-100,pin2Y" GND # 水平引出netflag Ground GND pin1X-100 pin2Y # NetFlag 在终点
若已有页面使用了 NetPort,可一键转换:
./scripts/draw_cli.py replace-netports### 信号命名规范| 网络名 | 用途 ||--------|------|| `I2C_SDA` / `I2C_SCL` | I2C 总线 || `SPI_MOSI` / `SPI_MISO` / `SPI_SCK` / `SPI_CS` | SPI 总线 || `UART_TX` / `UART_RX` | UART 串口 || `ROW0` / `COL0` | 键盘矩阵行/列 || `ENC_A` / `ENC_B` | 编码器 || `RESET` / `RESET_N` | 复位信号 || `STATUS_BTN` | 状态按钮 || `D0` / `D1` | 调试/通用 IO || `RAW` | 原始电源输入 |---## 4. 总线 (Bus)多位信号线使用总线符号减少混乱。
// 创建总线 await eda.sch_PrimitiveBus.create( [x1, y1, x2, y2], // 总线路径 "DATA[7:0]", // 总线名 null, null, null );
**总线命名约定**:- `DATA[7:0]` — 8 位数据总线- `ADDR[15:0]` — 16 位地址总线- `GPIO[0:3]` — 4 个 GPIO 引脚---## 5. 连接策略:导线 vs 网络标签### 5.0 最高优先级规则(MUST FOLLOW)> **⚠️ 模块到模块也使用网络标签,禁止连接导线!**>> 无论模块到模块还是模块到主控,都必须通过网络标签(NetFlag/NetPort)连接,禁止用导线直接拉过去。> 如果一条导线的两端分别在两个不同功能模块的器件上 → 必须改用网络标签。### 5.1 三条核心原则| 原则 | 说明 | 示例 ||------|------|------|| **① 模块内部用导线** | 同一功能电路内的器件之间用导线直连,体现电路拓扑的完整性 | 按键 SW1 → 二极管 D1 → 行线 || **② 芯片周边用网络标签** | 主控/IC 的引脚引出用网络标签,不直接拉线到远端器件 | U1.D7 → NetPort(ROW0) || **③ 复杂走线优先调布局** | 当连线出现绕路或交叉时,先调整器件位置和方向简化走线,而非硬拉线 | 二极管旋转 270° 使 A/K 上下排列 |### 5.2 判断流程
两个引脚需要连接时:
┌─ 同一功能模块内?─┐ │ │ YES NO │ │ ▼ ▼ 用导线 芯片引脚引出? │ │ │ YES │ NO │ │ │ │ │ ▼ │ ▼ │ 用网络标签 │ 导线会交叉/绕路? │ + 短导线 │ │ │ │ YES NO │ │ │ │ │ │ ▼ ▼ │ │ 调整器件 直接导线 │ │ 位置/方向 │ │ 简化走线 └────────────────────┘
### 5.3 模块内部用导线同一功能模块内的连接必须用导线,体现电路拓扑完整性:
// 按键 pin2 → 二极管 A(L 形 2 段导线) await eda.sch_PrimitiveWire.create([220, 210, 220, 300, 200, 300]);
// 行线:连接多个二极管 K 端(必须指定网络名) await eda.sch_PrimitiveWire.create([200, 340, 600, 340], 'ROW0');
// 列线:连接同列开关 pin3,延伸到标签位置 await eda.sch_PrimitiveWire.create([180, 170, 180, 390], 'COL0');
**为什么不用网络标签?** 模块内部的连接关系是电路原理的核心,用导线直观展示拓扑结构,便于审阅和理解。满屏网络标签会让模块内部逻辑支离破碎。### 5.4 芯片周边用网络标签主控/IC 引脚的引出用**延伸导线**(导线网络名即信号名),见 [Section 3](#3-信号标注--延伸导线-only) 的三种策略:- **信号**:`wire "pinX,pinY,pinX±100,pinY" NET_NAME`- **电源/地**:`wire` + `netflag`,NetFlag 坐标 = 导线终点- **连续同名电源/地**:竖线短接 → 引出 → 共 1 个 NetFlag### 5.5 连线时动态调整器件布局> **核心思想:连线不是被动适应器件位置,而是主动调整器件位置和方向来简化连线。**>> 在规划连线时,如果发现两个待连引脚不在同一水平线或垂直线上,**先移动器件使引脚对齐,再画直线导线**,而不是画多段折线去凑。**Step 0: 连线前先对齐引脚(最重要)**在画导线之前,先检查两个待连引脚的坐标。如果不在同一行/列,**移动器件使引脚对齐**:
import utils from './scripts/draw-utils.js';
// 示例:开关 pin2(220, 210) 需要连接到二极管 A 端 // 二极管当前在 (200, 320),A 端在 (200, 300) // pin2 x=220, D.A x=200 → 水平偏移 20
// ❌ 错误:硬拉 L 形线 await utils.addWire([220, 210, 220, 300, 200, 300]);
// ✅ 正确:先把二极管移到 x=220 对齐,再画直线 const comps = await eda.sch_PrimitiveComponent.get(["二极管ID"]); const ac = comps[0].toAsync(); ac.setState_X(220); // 移动到与 pin2 对齐 ac.done(); // 现在 D.A 在 (220, 300),pin2 在 (220, 210) await utils.addWire([220, 210, 220, 300], 'MATRIX_NET'); // 一段垂直直线
**对齐策略表:**| 连接方向 | 对齐方式 | 移动哪个器件 ||---------|---------|------------|| 垂直连线(上下) | X 坐标对齐 | 移动器件使 pinX 相同 || 水平连线(左右) | Y 坐标对齐 | 移动器件使 pinY 相同 || 开关→二极管 | X 对齐到开关 pin | 移动二极管 || 二极管→行线 | X 对齐到二极管 K | 行线是导线,自动经过 || 编码器→标签 | 标签移到引脚延长线 | 移动标签 |**Step 1: 调整器件方向**旋转器件使引脚朝向合理方向,减少折线段数:
// 二极管默认水平放置:A 在左 K 在右 // 旋转 270° 后:A 在上 K 在下,正好对接开关(上)和行线(下) const comps = await eda.sch_PrimitiveComponent.get(["二极管ID"]); const ac = comps[0].toAsync(); ac.setState_Rotation(270); ac.done();
❌ 二极管水平放置:A(左) K(右) 开关在上,行线在下 → 需要 3 段折线
✅ 二极管旋转 270°:A(上) K(下) 开关→A 直线,K→行线直线 → 2 段直线
**Step 2: 调整器件间距**确保器件之间有足够间距,导线不会与其他器件引脚重叠:
// 检查间距:开关 pin y=210,二极管 A y=300 → 间距 90 // 如果间距 < 60,导线太短不美观,移动器件拉开距离
**Step 3: 仍然复杂则改用网络标签**如果调整布局后仍然需要 3 段以上折线,或会导致与其他导线交叉,改用网络标签。### 5.6 移动器件的 API
// 移动器件到新坐标 const comps = await eda.sch_PrimitiveComponent.get([primitiveId]); const ac = comps[0].toAsync(); ac.setState_X(newX); ac.setState_Y(newY); ac.done();
// 旋转器件 const ac2 = comps[0].toAsync(); ac2.setState_Rotation(90); // 0, 90, 180, 270 ac2.done();
// 镜像器件 const ac3 = comps[0].toAsync(); ac3.setState_Mirror(true); ac3.done();
> **⚠️ 注意**: 移动器件后引脚坐标会变化。如果之前已经画了导线,需要同步更新导线。建议先调整好所有器件位置,再统一画导线。### 5.7 混合使用示例
按键 ──导线── 二极管 ──导线(行线)── 文本标注 ──┐ │ 主控引脚 ──导线── 文本标注 ────────────────────┘
模块内部(开关→二极管→行线)用导线,模块边界(行线末端→主控)用网络标签。---## 6. 电源连接### 电源树结构
VCC_BAT ──[保险丝]── VCC_5V ──[LDO]── VCC_3V3 ──[滤波]── MCU_VCC │ ├── OLED_VCC ├── SENSOR_VCC └── LED_VCC
### 去耦电容放置
// 在 IC 电源引脚附近放置去耦电容 await eda.sch_PrimitiveComponent.create( { libraryUuid: "库UUID", uuid: "电容UUID" }, icX + 20, icY, "", 0, false, true, true );
// 连接电容到电源和地(必须指定网络名) await eda.sch_PrimitiveWire.create([icX + 20, icY, icX + 20, icY - 20], "VCC_3V3", null, null, null); await eda.sch_PrimitiveComponent.createNetFlag("Power", "VCC_3V3", icX + 20, icY - 20, 0, false); await eda.sch_PrimitiveWire.create([icX + 20, icY + 10, icX + 20, icY + 30], "GND", null, null, null); await eda.sch_PrimitiveComponent.createNetFlag("Ground", "GND", icX + 20, icY + 30, 0, false);
---## 7. 导线出口点规范从符号引脚直线前进至少一个网格点后再改变方向:
正确: 引脚 ───┬─── 网络标签 │ └─── 导线
错误: 引脚 ───┐ └───┐ └─── 网络标签
---## 8. 避免四向交叉**优先使用 T 形连接而不是四向交叉。**
正确 (T 形): ────┬──── │ └────
错误 (四向交叉): ────┼──── │ ────┘
如果必须交叉,确保交叉点没有连接点(表示导线跨越而不连接)。---## 9. 网络名继承规则导线创建时的网络名规则:1. **没有坐标落在任何图元上** → 默认为空网络2. **有一个坐标点在某个网络的图元上** → 跟随该图元的网络3. **有多个坐标点在多个不同网络的图元上** → 创建失败**指定网络名时的规则**:1. **有一个或多个坐标点在其他网络的图元上,且其他图元未显式指定网络** → 其他图元跟随指定的网络2. **其他图元指定了网络** → 创建失败---## 10. 芯片外围信号引出规范> 见 [Section 3](#3-信号标注--延伸导线-only) 的策略 A/B/C。---## 11. 导线高级操作 (CLI)### 11.1 查看导线详细信息
./scripts/draw_cli.py get-wire <primitiveId>
返回:网络名、坐标组、线宽、线型、颜色。### 11.2 修改已有导线(异步模式)导线放置后如需调整网络名、坐标、线宽/线型/颜色等,用 `modify-wire`:
修改网络名
./scripts/draw_cli.py modify-wire <id> --net "NEW_NET"
修改坐标(移动导线)
./scripts/draw_cli.py modify-wire <id> --line "100,200,150,200"
修改线宽
./scripts/draw_cli.py modify-wire <id> --width 3
修改线型(实线/短划线/点线/点划线)
./scripts/draw_cli.py modify-wire <id> --dashed ./scripts/draw_cli.py modify-wire <id> --solid
修改颜色
./scripts/draw_cli.py modify-wire <id> --color "#ff0000"
### 11.3 创建时指定线型/颜色/线宽`wire` 命令同样支持这些选项:
虚线导线
./scripts/draw_cli.py wire "100,100,200,100" NET --dashed
红色粗线
./scripts/draw_cli.py wire "100,100,200,100" NET --color "#ff0000" --width 5
线型取值(对应 `ESCH_PrimitiveLineType` 枚举):| 选项 | 值 | 说明 ||------|-----|------|| (默认) | 0 | 实线 (SOLID) || `--dashed` | 1 | 短划线 (DASHED) || `--dotted` | 2 | 点线 (DOTTED) || `--dot-dashed` | 3 | 点划线 (DOT_DASHED) |---## 12. 总线 (Bus) — 多位信号线分组总线用于标识一组相关的多位信号,减少原理图混乱。总线本身不具有电气连接属性,仅作视觉标识。### 12.1 创建总线
./scripts/draw_cli.py bus "DATA[7:0]" "100,200,300,200,300,500"
### 12.2 总线命名约定- `DATA[7:0]` — 8 位数据总线- `ADDR[15:0]` — 16 位地址总线- `GPIO[0:3]` — 4 个 GPIO 引脚- `ROW[0:3]` — 4 条行信号- `COL[0:15]` — 16 条列信号### 12.3 总线接入标识 (BUSENTRY)总线到导线之间必须通过 BUSENTRY(总线接入标识)连接,它定义了哪些导线信号属于总线的哪些位。> BUSENTRY 通过 EasyEDA 画布界面手动添加更方便,目前 API 不支持直接创建 BUSENTRY。### 12.4 查询和删除总线
列出所有总线
./scripts/draw_cli.py list-buses
删除指定总线
./scripts/draw_cli.py delete-buses id1 id2
---## 13. 多边形/折线 (Polygon) — 装饰区域标识多边形用于绘制功能区域边框、信号分组框等视觉装饰。**多边形没有电气属性(无 net)**,仅用于视觉标识。### 13.1 创建多边形
实线框(无填充)
./scripts/draw_cli.py polygon "100,100,300,100,300,300,100,300"
虚线框 + 浅色填充
./scripts/draw_cli.py polygon "100,100,300,100,300,300,100,300" \ --dashed --fill "#f0f0f0"
无填充
./scripts/draw_cli.py polygon "100,100,300,100,300,300,100,300" --fill none
**⚠️ 注意:** 多边形会自动闭合首尾端点,坐标不需要重复起始点。### 13.2 查询和删除
./scripts/draw_cli.py list-polygons ./scripts/draw_cli.py delete-polygons id1 id2
---## 14. 常见错误| 错误 | 原因 | 解决方案 ||------|------|----------|| `创建失败` | 多段线彼此无连接 | 确保所有线段有共同连接点 || `创建失败` | 多个不同网络的图元 | 使用网络标签替代直接连线 || 导线交叉混乱 | 未使用网络名连接 | 长距离连接用延伸导线+网络名 || 网络名冲突 | 同一网络名用于不同信号 | 检查网络名唯一性 || 电源未连接 | 忘记放置 NetFlag | 检查所有电源引脚有对应 NetFlag || **导线无网络名** | 创建导线时 net 参数为空 | 每创建一条导线必须指定网络名 || **标签重复** | 同一坐标放置两个相同标签 | 使用 `check-duplicates` 检测并删除 || **未用引脚无 NC** | IC 未用引脚没有标记 | 使用 `mark-nc` CLI 标记 |