EasyEDA 原理图绘制
在 EasyEDA Pro 中通过 API 绘制原理图。本 skill 为入口,详细子 skill 见下方目录。
使用方式
本 skill 支持两种使用模式:
- 完整流程模式——从头到尾绘制一张完整原理图。必须采用多 Agent 编排方式:主 Agent 做任务规划 → 每个模块召唤绘制子 Agent → 每个模块召唤检查子 Agent → 整改闭环。完整编排流程见 orchestration/;绘制细节按 SOP 标准绘制步骤 逐模块推进。
- 任务模式——选取合适的子技能完成单个特定任务(如"放一个器件""画一根导线""跑一次 DRC")。直接用 CLI 命令或查阅对应子 skill 文档即可,无需走完整 SOP。
判断依据:用户说"画原理图"/"绘制电路"→ 完整流程模式(必读 orchestration);用户说"放个电阻"/"检查 DRC"/"画根线"→ 任务模式。
多 Agent 编排:网络标签传递
每个模块完成后,主 Agent 必须执行
net-summary收集当前网络标签快照,并传递给下一个子 Agent。这样下一个子 Agent 知道:
- 哪些网络已存在(如 ROW0、COL0、VCC、GND)
- 这些网络在什么坐标
- 应该在哪些位置对接同名网络标签
避免子 Agent 盲目创建重复标签或放错坐标。
第一步:环境准备(必须先做)
⚠️ 在执行任何绘制命令之前,必须先完成以下两步,确认 Bridge Server 运行且 EDA 已连接。
1. 启动 Bridge Server
Bridge Server 是 AI 与 EasyEDA 之间的通信桥梁,由 easyeda-api skill 提供。
# 检查 bridge 是否已在运行 (扫描端口 49620-49629)
for port in $(seq 49620 49629); do
resp=$(curl -s http://localhost:$port/health 2>/dev/null)
if echo "$resp" | grep -q '"easyeda-bridge"'; then
echo "Bridge already running on port $port"
break
fi
done
# 若未运行,则启动 (后台运行,不阻塞)
node ../../easyeda-api/scripts/bridge-server.mjs &
sleep 2
同时确保 EasyEDA Pro 中已安装并加载 run-api-gateway.eext 扩展(下载:https://ext.lceda.cn/item/oshwhub/run-api-gateway )。
2. 检查连通性
# 一键检查 bridge + EDA 连通性 (CLI 自动扫描端口 49620-49629)
./scripts/draw_cli.py health
期望输出:
{"ok": true, "summary": "Bridge OK (port 49620), EDA connected", "bridge": true, "port": 49620, "edaConnected": true}
bridge: false→ Bridge 未启动,回到第 1 步edaConnected: false→ EasyEDA 扩展未加载,检查run-api-gateway.eext- 多窗口场景:输出中
windows列出所有已连接的 EDA 窗口,activeWindow为当前活动窗口
端口也可通过环境变量强制指定:
EDA_BRIDGE_PORT=49622 ./scripts/draw_cli.py health
子 Skill 目录
| 子 Skill | 路径 | 用途 |
|---|---|---|
| 多 Agent 编排 | orchestration/ | 完整流程模式必读:任务规划 → 绘制子 Agent → 检查子 Agent → 整改闭环 |
| 绘制规范 | rules/ | 原理图设计规范、信号流向、布局约定、命名标准 |
| 标准绘制步骤 | sop/ | 从主控到外围的标准绘制流程,含 NC 标记和检查 SOP |
| 模块子流程 | sop/subflow.md | 每个外围模块的详细绘制子流程(P0 布局规划→P8 策略检查) |
| 器件摆放 | placement/ | 元器件放置、位号分配、旋转镜像、间距控制 |
| 自定义符号 | symbol/ | 创建自定义符号/器件,系统库找不到时使用 |
| 连线 | wiring/ | 导线绘制、网络标签、NC 标记、电源/地符号 |
| 检查 | checking/ | 布局验证、DRC、重复标签、导线网络名、未连接引脚检查 |
| 绘制后优化策略 | strategies/ | 同名合并、NetFlag对齐、冗余合并、NC标注、信号规范、网络名、重复标签、DRC |
核心规则(MUST FOLLOW)
0. 完整流程模式必须多 Agent 编排
⚠️ 当用户要求"画完整原理图"时,禁止主 Agent 亲自下场逐个
place/wire。正确方式:
- 主 Agent 做 Phase A 任务规划(拆模块 + 写任务卡 + Zone Plan + 用户确认)
- 每个模块召唤《绘制子 Agent》按任务卡绘制
- 每个模块召唤《检查子 Agent》独立验收
- 不通过则整改闭环,直到 PASS
- 用户人工确认后进入下一模块
详见 orchestration/。
1. 必须使用语义化 CLI 命令
⚠️ 三条禁令:
- 禁止使用 curl 调用
/execute端点——无论是绘制操作还是只读查询。所有操作(包括获取库 UUID、查询引脚、搜索器件)都必须通过 CLI 命令完成。如果 CLI 缺少所需命令,应先补充 CLI 命令而非退回 curl。- 禁止使用
exec命令——本 CLI 已移除exec,强制使用语义化命令。- 禁止为单次操作编写脚本(如
*.mjs/*.py/*.js)——所有操作直接用 CLI 命令完成。所有放置、连线、验证操作必须通过:
./scripts/draw_cli.py <command> [options] # 或 python3 scripts/draw_cli.py <command> [options]输出格式:默认完整数据单行 JSON;
-v缩进 (调试);-q只输出 id (管道)。
2. 逐模块绘制,不能一次性摆完全部
禁止「先摆完全部器件,再统一连线」。
正确方式:模块A: 摆放→验证→连线→验证→人工确认 → 模块B
3. 每个模块完成后必须人工确认
停下来等用户说"继续"才能进入下一个模块。
4. 批量操作粒度由 AI 自主判断
单次操作的器件数量不设硬性上限,由 AI 根据模块复杂度和置信度自主决策。 简单重复操作(如放 6 个相同开关 + 6 个二极管)可一次完成;复杂或高风险操作应分批并逐步确认。
5. 模块间禁止连接导线(MUST FOLLOW)
⚠️ 模块到模块也使用网络标签,禁止连接导线。
场景 连接方式 示例 模块内部 导线直连 按键 SW1 → 二极管 D1 → 行线 模块到模块 网络标签,禁止导线 矩阵模块 ROW0 ← NetPort → 主控模块 U1.D7 模块到主控 网络标签,禁止导线 U1.D7 → NetPort(ROW0) 电源/地 NetFlag VCC / GND 判定标准:如果导线的两端分别在两个不同功能模块的器件上,就是跨模块连接导线,必须改用网络标签。
为什么:跨模块导线会导致原理图交叉凌乱、难以审阅、难以维护。网络标签让模块边界清晰,每个模块自包含。
脚本工具
本 skill 提供两个脚本文件,位于 scripts/ 目录:
1. CLI 工具 (scripts/draw_cli.py, Python)
命令行直接执行常用操作,无需编写代码。已移除 exec 命令,强制使用语义化命令。
# 检查 bridge + EDA 连通性 (第一步必做)
./scripts/draw_cli.py health
# 查看项目信息
./scripts/draw_cli.py project-info
# 符号创建
./scripts/draw_cli.py create-symbol "nice!nano v2" # 创建空符号到个人库
./scripts/draw_cli.py open-symbol <symbolUuid> <libUuid> # 在编辑器中打开符号
./scripts/draw_cli.py create-device <name> <symUuid> <libUuid> # 从符号创建器件
./scripts/draw_cli.py build-symbol <name> <pinCount> # 一键构建符号骨架(创建+添加矩形+引脚)
# 符号编辑(只能在符号编辑器标签页中使用)
./scripts/draw_cli.py list-primitives # 列出当前文档所有图元(符号/原理图通用)
# 搜索器件(默认系统库,--personal/--project 自动获取库 UUID)
./scripts/draw_cli.py search "nice!nano v2" 5
./scripts/draw_cli.py search "nice!nano v2" 5 --personal
./scripts/draw_cli.py search "nice!nano v2" 5 --project
./scripts/draw_cli.py search "nice!nano v2" 5 --lib <libraryUuid>
# 获取库 UUID(无需 curl)
./scripts/draw_cli.py lib-personal # 个人库 UUID
./scripts/draw_cli.py lib-project # 工程库 UUID
./scripts/draw_cli.py lib-list # 列出所有库
# 清理页面(保留指定器件)
./scripts/draw_cli.py clear --keep id1,id2
# 放置器件 (推荐加 --name 标识型号/规格)
./scripts/draw_cli.py place <libUuid> <uuid> <x> <y> [designator] [rotation] [mirror]
./scripts/draw_cli.py place <libUuid> <uuid> <x> <y> R1 --name "10kΩ"
./scripts/draw_cli.py place <libUuid> <uuid> <x> <y> C1 --name "100nF"
./scripts/draw_cli.py place <libUuid> <uuid> <x> <y> U1 --name "nice!nano v2"
# 查询器件完整信息 (含 name/spec)
./scripts/draw_cli.py get-component <primitiveId>
./scripts/draw_cli.py get-component --designator U1
# 修改器件规格 (对已放置的器件补设 name)
./scripts/draw_cli.py modify-component <id> --name "10kΩ"
./scripts/draw_cli.py modify-component <id> --name "nRF52840"
# 添加文本
./scripts/draw_cli.py text <x> <y> "文本内容" [fontSize]
# 添加矩形
./scripts/draw_cli.py rect <x> <y> <w> <h> [color]
# 添加网络标签
./scripts/draw_cli.py netflag Power VCC 100 100
# 添加网络标��(延伸导线)
```bash
# ⚠️ NetPort 已不推荐。信号引脚仅用延伸导线(导线已含网络名)
# Power/Ground 仍用 NetFlag
# ✅ 信号引脚:仅延伸导线
./scripts/draw_cli.py wire "620,290,520,290" I2C_SDA
# ✅ 电源/地:导线 + NetFlag
./scripts/draw_cli.py wire "780,270,880,270" VCC && ./scripts/draw_cli.py netflag Power VCC 890 270
# ✅ 或一键替换已有 NetPort
./scripts/draw_cli.py replace-netports
绘制导线 (必须指定网络名, 防止跨网络合并)
./scripts/draw_cli.py wire "100,100,150,100" NET_NAME ./scripts/draw_cli.py wire "100,100,150,100" NET_NAME --safe # 安全模式: 先查冲突再创建 (推荐)
批量创建导线 (逐条安全检查, 防止跨网络合并)
./scripts/draw_cli.py wire-batch --json '[{"points":[100,100,150,100],"net":"ROW0"},{"points":[200,100,250,100],"net":"ROW1"}]'
绘制导线(指定线型/颜色/线宽)
./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
线型选项: --dashed(短划线) --dotted(点线) --dot-dashed(点划线) 默认实线
查看导线详细信息
./scripts/draw_cli.py get-wire
修改已有导线(网络名/坐标/线宽/线型)
./scripts/draw_cli.py modify-wire --net "NEW_NET" ./scripts/draw_cli.py modify-wire --line "100,200,150,200"
创建总线(多位信号线分组标识)
./scripts/draw_cli.py bus "DATA[7:0]" "100,200,300,200,300,500" ./scripts/draw_cli.py list-buses ./scripts/draw_cli.py delete-buses id1 id2
创建多边形/折线(装饰框,无电气属性)
./scripts/draw_cli.py polygon "100,100,300,100,300,300,100,300" ./scripts/draw_cli.py polygon "100,100,300,300" --dashed --fill "#f0f0f0" ./scripts/draw_cli.py list-polygons ./scripts/draw_cli.py delete-polygons id1 id2
搜索器件
./scripts/draw_cli.py search "电阻" 10
检查重叠
./scripts/draw_cli.py check-overlap
寻找空白区域放置器件(避免与已有器件重叠)
./scripts/draw_cli.py find-space 200 150 100 100 1200 900
获取器件引脚实际坐标(旋转/镜像后的真实位置)
./scripts/draw_cli.py get-pins ./scripts/draw_cli.py get-pins --designator U1
删除器件(含周边导线/标签清理)
./scripts/draw_cli.py delete-component --designator J2 ./scripts/draw_cli.py delete-component --designator J2 --margin 80 --clean-text
一站式放置器件 + 自动打标签(应用 U1 连线/标签心得)
引脚密集时,标签分散到不同方向(左/右/下交替),避免重叠
./scripts/draw_cli.py place-with-labels
--pins "1:net=D1,type=port,side=right" "2:net=D0,type=port,side=bottom" "3:net=GND,type=ground,side=left"
--label "UART Debug"
可选 --find-space , 自动寻找空白区域
列出所有器件
./scripts/draw_cli.py list-components
收集网络标签快照 (按网络名分组, 含坐标)
./scripts/draw_cli.py collect-nets
生成网络摘要文本 (供下一个子 Agent 使用)
./scripts/draw_cli.py net-summary
缩放到所有图元
./scripts/draw_cli.py zoom-all
恢复标题块
./scripts/draw_cli.py restore-titleblock
=== 绘制中验证(每完成一个模块执行)===
./scripts/draw_cli.py verify-placement # 验证摆放质量(重叠/间距/旋转) ./scripts/draw_cli.py verify-wiring # 验证连线质量(网络名/标签重复/孤立标签)
=== 绘制后检查(每次提交前必须执行)===
./scripts/draw_cli.py drc # DRC 检查(聚合统计) ./scripts/draw_cli.py drc --show-ui # 打开 DRC 面板查看逐项详细错误 ./scripts/draw_cli.py check-duplicates # 检测重复标签 ./scripts/draw_cli.py check-duplicates --clean # 检测并自动清理 ./scripts/draw_cli.py check-wire-nets # 检测无网络名的导线 ./scripts/draw_cli.py check-wire-conflicts # 检测导线网络冲突 (触碰不同网络的导线) ./scripts/draw_cli.py check-wire-through # 检测导线穿过元器件本体 ./scripts/draw_cli.py check-unconnected # 检测未连接引脚 (4PIN开关感知+NC标记感知) ./scripts/draw_cli.py check-shorts # 检测短路 (不同网络名导线连接在一起) ./scripts/draw_cli.py check-redundant-wires # 检测冗余导线 (同两点间多条导线) ./scripts/draw_cli.py check-all # 一键全量检查(7步,推荐)
> **⚠️ 已移除 `exec` 命令**——禁止执行任意 JS 代码字符串。所有操作必须使用上面的语义化命令。
### 2. 底层 API 参考(Bridge Server `/execute` 直调)
> **⚠️ JS 脚本已全部删除**:`draw-utils.js` 和 `draw-cli.mjs` 已于 Python 迁移完成后清理。以下代码示例仅作底层 EDA API 参考,展示每个语义命令对应的 JS 实现。**新操作必须使用 `draw_cli.py` 的语义化命令**,禁止再编写 JS 脚本。
> 如需查询某 API 的具体实现,请阅读 `scripts/draw_cli.py` 中对应函数的 `code` 字符串(即发送到 bridge server `/execute` 的 JS 代码)。
以下示例展示底层 API 调用方式(仅供理解,不要复制使用):
```javascript
import utils from './scripts/draw-utils.js';
// 清理页面
await utils.clearPage(['keepId1', 'keepId2']);
// 放置器件
const id = await utils.placeComponent({
libraryUuid: '0819f05c4eef4c71ace90d822a990e87',
uuid: '839559ae8f084f08bc76562033e67b08',
x: 100, y: 150,
designator: 'SW1',
});
// 批量放置
await utils.placeComponents([
{ libraryUuid, uuid, x: 100, y: 150, designator: 'SW1' },
{ libraryUuid, uuid, x: 250, y: 150, designator: 'SW2' },
]);
// 添加文本
await utils.addText({ x: 100, y: 120, text: 'Key Matrix', fontSize: 8 });
// 添加网络标签
await utils.addNetFlag({ type: 'Power', net: 'VCC', x: 100, y: 100 });
// 绘制导线(指定线型/颜色/线宽)
await utils.addWire([100, 100, 200, 100], 'NET_NAME', { color: '#ff0000', lineWidth: 3 });
await utils.addWire([100, 100, 200, 100], null, { lineType: 1 }); // 1=短划线
// 查看导线详细信息
const info = await utils.getWireInfo(wirePrimitiveId);
// { id, net, line, lineWidth, lineType, color }
// 修改已有导线
await utils.modifyWire(wireId, { net: 'NEW_NET', lineType: 0 }); // 0=实线
// 创建总线
await utils.addBus('DATA[7:0]', [100, 200, 300, 200, 300, 500]);
// 查询/删除总线
const buses = await utils.getAllBuses();
await utils.deleteBuses(busId);
// 创建多边形(装饰框)
await utils.addPolygon([100, 100, 300, 100, 300, 300, 100, 300], { fillColor: 'none' });
await utils.addPolygon([100, 100, 300, 100, 300, 300, 100, 300], { lineType: 1, fillColor: '#f0f0f0' });
// 查询/删除多边形
const polys = await utils.getAllPolygons();
await utils.deletePolygons(polyId);
// 检查重叠
const { overlaps } = await utils.checkOverlaps();
// 寻找空白区域(避免与已有器件重叠)
const pos = await utils.findFreeSpace({ width: 200, height: 150 });
if (pos) { /* pos.x, pos.y */ }
// 获取器件引脚实际坐标(旋转后的真实位置)
const pins = await utils.getComponentPins(primitiveId);
// 按位号查找器件 ID
const id = await utils.findComponentByDesignator('U1');
// 删除器件(含周边导线/标签清理,替代手写 cleanup 脚本)
await utils.deleteComponent({ designator: 'J2', margin: 80, cleanText: true });
// 一站式放置 + 自动打标��(应用 U1 连线/标签心得)
// 引脚密集时标签分散到不同方向,避免重叠
const result = await utils.placeComponentWithLabels({
libraryUuid, uuid,
x: 750, y: 150,
designator: 'J2', rotation: 90,
pinMap: {
'1': { net: 'D1', type: 'port', side: 'right' },
'2': { net: 'D0', type: 'port', side: 'bottom' },
'3': { net: 'GND', type: 'ground', side: 'left' },
},
moduleLabel: 'UART Debug',
});
// === 绘制中验证函数 ===
// 验证器件摆放质量
const placement = await utils.verifyPlacement();
// 验证连线质量
const wiring = await utils.verifyWiring();
// === 绘制后检查函数 ===
// 运行 DRC
const drc = await utils.runDrc();
// 打开 DRC 面板查看逐项详细(showUi: true)
const drcDetail = await utils.runDrc({ showUi: true });
// 检测重复标签
const dup = await utils.detectDuplicateLabels();
// 自动清理重复标签
const cleaned = await utils.cleanupDuplicateLabels();
// 检查导线网络名
const wireNets = await utils.checkWireNets();
// 检测未连接引脚
const unconnected = await utils.detectUnconnectedPins();
// 检测导线穿过器件本体
const wireThrough = await utils.checkWireThroughComponent();
// 一键全量检查
const fullReport = await utils.runFullCheck();
// 创建自定义符号
const { symbolUuid, libraryUuid } = await utils.createSymbol("nice!nano v2");
// 在编辑器中打开符号(手动添加引脚和形状)
await utils.openSymbolInEditor(symbolUuid, libraryUuid);
// 从符号创建器件
const { deviceUuid } = await utils.createDeviceFromSymbol("nice!nano v2", symbolUuid, libraryUuid);
环境变量
| 变量 | 默认值 | 说明 |
|---|---|---|
EDA_BRIDGE_PORT |
自动发现 | Bridge server 端口。未设置时 CLI 自动扫描 49620-49629 找到运行中的 bridge |
快速入口
// 1. 确认当前文档为原理图
const doc = await eda.dmt_SelectControl.getCurrentDocumentInfo();
if (doc?.documentType !== 1) {
return "Error: Not a schematic page";
}
// 2. 放置器件(rotation: 0/90/180/270,传 90 时内部存储为 270 但视觉正确)
const result = await eda.sch_PrimitiveComponent.create(
{ libraryUuid: "库UUID", uuid: "器件UUID" },
x, y, "", 0, false, true, true
);
// 3. 设置位号
await eda.sch_PrimitiveComponent.modify(result?.primitiveId, {
designator: "SW1"
});
// 4. 添加网络标签
await eda.sch_PrimitiveComponent.createNetFlag("Power", "VCC", x, y, 0, false);
符号编辑器注意事项
⚠️ 重要:引脚位置与矩形对齐
SCH_PrimitivePin.create(x, y, ...)的(x, y)是**引脚连接点(圆点)**的位置,不是引脚端点。 引脚从连接点沿rotation方向延伸pinLength单位。⚠️ 重要:rotation 参数会被 API 反转存储 传 0 → 存储 180 → 引脚向左延伸(适合左侧引脚) 传 180 → 存储 0 → 引脚向右延伸(适合右侧引脚) 传 90 → 存储 270 → 引脚向下延伸(适合底部引脚) 传 270 → 存储 90 → 引脚向上延伸(适合顶部引脚)
正确做法:连接点放在矩形边缘
- 左侧引脚:
x = 矩形左边缘, rotation=0→ 传0→存180→向左延伸 ✅- 右侧引脚:
x = 矩形右边缘, rotation=180→ 传180→存0→向右延伸 ✅错误示例:
x=-100, 矩形左边缘=-80, rotation=0→ 连接点与矩形间有 20 单位间隙 ❌
⚠️ 重要:符号编辑器 Y 轴方向
符号编辑器 Y 轴向上增长(数学坐标系),
sch_PrimitiveRectangle.create(topLeftX, topLeftY, ...)的topLeftY是矩形最高点(Y 值最大),矩形从此点向下延伸height。 例如:要让矩形覆盖 y=-130 到 y=130,应传topLeftY=130, height=260。
⚠️ 重要:符号编辑器与原理图编辑器 API 差异
在符号编辑器(documentType=2)中,部分
sch_Primitive*的批量查询方法不可用:
sch_PrimitiveRectangle.getAll()→ ❌ 返回空数组sch_PrimitiveRectangle.getAllPrimitiveId()→ ❌ 返回空数组sch_PrimitiveCircle.getAll()→ ❌ 返回空数组符号编辑器中查询图元的方法:
- 查询所有引脚:
sch_PrimitivePin.getAllPrimitiveId()→ 返回引脚 ID 数组- 查询所有选中图元(包括矩形/圆): 先选中图元,再调用
sch_SelectControl.getAllSelectedPrimitives()- CLI 命令:
selected-primitives列出当前选中的全部图元(符号编辑器专用)正确做法:
- 使用
sch_PrimitivePin.getAllPrimitiveId()获取所有引脚 ID- 用
sch_Primitive.getPrimitiveByPrimitiveId(id)逐个查询图元属性- 用
sch_Primitive.getPrimitiveTypeByPrimitiveId(id)获取图元类型- 或使用
sch_SelectControl.getAllSelectedPrimitives()获取已选中图元详见 symbol/ 子 skill。
坐标系统
| 域 | 单位 | 换算 |
|---|---|---|
| 原理图 (SCH) | 0.01 inch = 10 mil = 0.254 mm | 100 单位 = 1 inch |
| PCB | 1 mil = 0.001 inch = 0.0254 mm | 1000 单位 = 1 inch |
器件放置坐标 (x, y) 是符号原点/锚点,不是器件中心。
UUID 说明
UUID 是 EasyEDA 系统库中每个器件的唯一标识符,由 libraryUuid(库 UUID)和 uuid(器件 UUID)两部分组成。
为什么不能硬编码
- 不同用户、不同时间安装的库版本不同,同一器件的 UUID 可能不同
- 工程库和个人库中的器件 UUID 完全由用户自己定义
- 即使系统库,不同地区的镜像也可能存在差异
如何动态获取 UUID
方法一:搜索(推荐)
// 在 EasyEDA 中搜索器件,获取 UUID
const results = await eda.lib_Device.search("SWITCH-轻触SMD_4PINS", "0819f05c4eef4c71ace90d822a990e87", undefined, undefined, 5, 1);
// results[0].uuid → 器件 UUID
// results[0].libraryUuid → 库 UUID
方法二:查看当前页面已有器件
// 获取页面上所有器件的 UUID 信息
const compIds = await eda.sch_PrimitiveComponent.getAllPrimitiveId();
for (const id of compIds) {
const comps = await eda.sch_PrimitiveComponent.get([id]);
const c = comps[0];
console.log({
designator: c.designator,
name: c.name,
libraryUuid: c.libraryUuid,
uuid: c.uuid,
});
}
方法三:在 EasyEDA 界面中查找
- 在 EasyEDA 左侧「库」面板中搜索器件
- 右键点击器件 → 属性 → 查看
libraryUuid和uuid - 或在「放置」→「器件」对话框中搜索,选中后查看底部信息
常用库 UUID(相对稳定,可缓存)
| 库 | UUID | 说明 |
|---|---|---|
| 系统库 | 0819f05c4eef4c71ace90d822a990e87 |
EasyEDA 官方系统库,相对稳定 |
| 个人库 | 通过 eda.lib_LibrariesList.getPersonalLibraryUuid() 获取 |
每位用户不同 |
| 工程库 | 通过 eda.lib_LibrariesList.getProjectLibraryUuid() 获取 |
每个工程不同 |
自定义符号创建
当系统库中找不到所需器件的符号时(如开发板模块、定制 IC),需要创建自定义符号。
什么时候需要自定义符号
- 系统库搜索不到(如
nice!nano v2、Pro Micro等开发板模块) - 有现成符号但引脚功能与设计不匹配
- 需要自定义引脚排列以优化原理图可读性
创建流程
创建空符号 → 打开符号编辑器 → 添加引脚/形状/文本 → 创建器件绑定 → 在原理图中使用
操作步骤
Step 1: 创建空符号
// 1. 获取个人库 UUID
const personalLib = await eda.lib_LibrariesList.getPersonalLibraryUuid();
if (!personalLib) return "Error: No personal library found";
// 2. 创建空符号
const symbolUuid = await eda.lib_Symbol.create(personalLib, "nice!nano v2");
if (!symbolUuid) return "Error: Failed to create symbol";
Step 2: 在符号编辑器中编辑
创建后通过 openInEditor 打开符号编辑器,在 EasyEDA 界面中手动添加引脚和形状:
// 在编辑器中打开符号
await eda.lib_Symbol.openInEditor(symbolUuid, personalLib);
在 EasyEDA 符号编辑器中,使用工具栏添加:
- 矩形: 绘制器件主体轮廓
- 引脚: 放置引脚并设置名称/编号/电气属性
- 文本/图形: 添加辅助说明
Step 3: 创建器件(绑定符号和封装)
// 创建器件,关联符号(可选关联封装)
const deviceUuid = await eda.lib_Device.create(personalLib, "nice!nano v2", undefined, {
symbolType: "sch",
symbol: { uuid: symbolUuid, libraryUuid: personalLib },
// footprint: { uuid: footprintUuid, libraryUuid: personalLib }, // 可选
});
Step 4: 在原理图中使用
// 搜索自定义器件
const results = await eda.lib_Device.search("nice!nano v2", personalLib);
if (results.length === 0) return "Error: Device not found";
// 放置器件
const comp = await eda.sch_PrimitiveComponent.create(
{ libraryUuid: personalLib, uuid: results[0].uuid },
x, y, "", 0, false, true, true
);
await eda.sch_PrimitiveComponent.modify(comp?.primitiveId, { designator: "U1" });
符号文档源码格式(进阶)
如果不想手动编辑,也可以通过 LIB_Symbol.updateDocumentSource() 直接设置符号的文档源码。格式如下:
// 构建符号文档源码
const source = [
`{ "type": "DOCHEAD" }||{ "docType": "SYMBOL", "uuid": "${symbolUuid}", "client": "clientID" }|`,
`{ "type": "CANVAS", "ticket": 1 }||{ "originX":0, "originY":0 }|`,
`{ "type": "PART","id":"", "ticket": 1 }||{"BBOX": [-100, -100, 100, 100]}|`,
// 矩形主体
`{ "type": "RECT", "id": "r1", "ticket": 1 }||{ "partId": "", "groupId": 0, "locked": false, "zIndex": 7.35, "dotX1": -80, "dotY1": -80, "dotX2": 80, "dotY2": 80, "radiusX": 0, "radiusY": 0, "rotation": 0, "strokeColor": null, "strokeStyle": 0, "fillColor": "", "strokeWidth": null, "fillStyle": 1 }|`,
// 引脚(需为每个引脚定义 PIN + ATTR)
`{ "type": "PIN", "id": "p1", "ticket": 1 }||{ "partId": "", "groupId": 0, "locked": false, "zIndex": 2.8772, "display": true, "electric": 2, "positionX": -100, "positionY": -60, "length": 20, "rotation": 0, "color": "#880000", "pinShape": 0 }|`,
`{ "type": "ATTR", "id": "a1", "ticket": 1 }||{ "partId": "", "groupId": 0, "locked": true, "zIndex": 0.1, "parentId": "p1", "key": "NAME", "value": "D0/TX", "keyVisible": true, "valueVisible": true, "positionX": -120, "positionY": -60, "rotation": 0, "color": null, "fillColor": null, "fontFamily": null, "fontSize": null, "strikeout": null, "underline": null, "italic": null, "fontWeight": null, "vAlign": 0, "hAlign": 2 }|`,
`{ "type": "ATTR", "id": "a2", "ticket": 1 }||{ "partId": "", "groupId": 0, "locked": true, "zIndex": 0.1, "parentId": "p1", "key": "NUMBER", "value": "1", "keyVisible": true, "valueVisible": true, "positionX": -120, "positionY": -60, "rotation": 0, "color": null, "fillColor": null, "fontFamily": null, "fontSize": null, "strikeout": null, "underline": null, "italic": null, "fontWeight": null, "vAlign": 0, "hAlign": 2 }|`,
].join("\n");
// 应用文档源码
await eda.lib_Symbol.updateDocumentSource(symbolUuid, personalLib, source);
注意:引脚坐标中,positionX/Y 是引脚最外端的坐标(远离符号主体的那一端),引脚长度由 length 控制。rotation 决定了引脚方向(0=左, 90=上, 180=右, 270=下)。
引脚属性说明
| PIN 属性 | 说明 | 值 |
|---|---|---|
electric |
电气特性 | 0=UNKNOWN 1=INPUT 2=OUTPUT 3=BI |
rotation |
引脚方向 | 0=向左 90=向上 180=向右 270=向下 |
length |
引脚长度 | 单位与原理图坐标一致 |
pinShape |
引脚样式 | 0=无 1=Clock 2=DOT(可组合 3=Clock|DOT) |
ATTR 属性说明
每个 PIN 必须有两个 ATTR:
key="NAME",value="引脚名"— 引脚名称,显示在图纸上key="NUMBER",value="引脚编号"— 引脚编号(序号)
parentId 必须指向对应的 PIN 的 id。
常用器件搜索关键词
⚠️ 以下 UUID 仅作示例参考,实际使用时必须通过搜索动态获取。
| 器件 | 搜索关键词 | 说明 |
|---|---|---|
| 轻触开关 | SWITCH-轻触SMD_4PINS |
4 脚 SMD 轻触开关 |
| 二极管 B5819WS | B5819WS |
肖特基二极管 |
| 旋转编码器 | EC11B152442D-STEC11B03 |
EC11 旋转编码器 |
| 4P Header | JP4 |
4 脚排针 |
| OLED 显示屏 | SSD1306-330MT |
SSD1306 OLED |
| 电阻 0402 | 0402WGF |
0402 封装贴片电阻 |
| 电容 0402 | 0402CG |
0402 封装贴片电容 |
| nRF52840 模块 | nRF52840 |
主控模块,搜索后选具体型号 |