<< All versions

Skill v1.0.0

currentAutomated scan100/100
kukucaicndy/embedded_ai_skills/wiring
──Details
PublishedOctober 31, 2026 at 10:02 PM
Content Hashsha256:0e7f2a72dc481da1...
Git SHA306d42a2b27b
──Files
Files (1 file, 20.0 KB)
SKILL.md20.0 KBactive
SKILL.md · 642 lines · 20.0 KB

name: "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 引脚必须标记 NC
NC 标记告诉 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. 导线绘制

基本绘制

javascript
await eda.sch_PrimitiveWire.create(
[x1, y1, x2, y2], // 线段坐标组
"NET_NAME", // 网络名(必须显式指定!)
null, // 颜色
null, // 线宽
null // 线型
);

多段导线

javascript
// 折线: 从 (100,100) → (150,100) → (150,150)
await eda.sch_PrimitiveWire.create(
[100, 100, 150, 100, 150, 150],
"SIGNAL_NET",
null, null, null
);

多段独立导线

javascript
// 两条独立线段
await eda.sch_PrimitiveWire.create(
[[100, 100, 150, 100], [200, 200, 250, 200]],
"SIGNAL_NET",
null, null, null
);

⚠️ 注意: 如果多段线彼此无任何连接,创建会失败。

修改已有导线的网络名

javascript
// 用 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) — 电源/地专用

网络标签用于标识电源和地,是最常用的连接方式。

电源标签

javascript
await eda.sch_PrimitiveComponent.createNetFlag(
"Power", // 类型: Power | Ground | AnalogGround | ProtectGround
"VCC_3V3", // 网络名
x, y, // 位置
0, // 旋转角度
false // 镜像
);

地标签

javascript
await eda.sch_PrimitiveComponent.createNetFlag("Ground", "GND", x, y, 0, false);

电源命名规范

网络名用途
VCC通用电源
VCC_3V33.3V 电源
VCC_5V5V 电源
VCC_1V81.8V 电源
VBAT电池电源
VBUSUSB 总线电源
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,可一键转换:

bash
./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 标记 |
All versions