<< All versions

Skill v1.0.0

currentAutomated scan100/100
kukucaicndy/embedded_ai_skills/symbol
──Details
PublishedOctober 31, 2026 at 03:22 AM
Content Hashsha256:5a0c5f6aecfed257...
Git SHA306d42a2b27b
──Files
Files (1 file, 15.0 KB)
SKILL.md15.0 KBactive
SKILL.md · 338 lines · 15.0 KB

name: "easyeda-draw-symbol" description: "Create custom schematic symbols for EasyEDA Pro. Invoke when creating custom symbols, building devices from symbols, or when system library lacks required components." metadata: version: "1.0.0"


自定义符号创建

系统库中找不到所需器件符号时(如开发板模块、定制 IC),通过此流程创建自定义符号。


1. 什么时候需要自定义符号

  • 系统库搜索不到(如 nice!nano v2、Pro Micro 等开发板模块)
  • 有现成符号但引脚功能与设计不匹配
  • 需要自定义引脚排列以优化原理图可读性

2. 创建流程

创建空符号 → 添加引脚/形状/文本 → 创建器件 → 在原理图中使用

Step 1: 创建空符号

javascript
const personalLib = await eda.lib_LibrariesList.getPersonalLibraryUuid();
const symbolUuid = await eda.lib_Symbol.create(personalLib, "nice!nano v2");
// symbolUuid = "57ad2c820a1646eb8a6cfa1ff35c8922"

Step 2: 在符号编辑器中添加引脚和形状

打开符号编辑器,然后使用 SCH_Primitive* API 添加图元:

javascript
// 打开符号编辑器
await eda.lib_Symbol.openInEditor(symbolUuid, personalLib);
// 创建矩形主体
// ⚠️ 符号编辑器 Y 轴向上增长(数学坐标系),topLeftY 是矩形最高点
// 矩形从 topLeftY 向下延伸 height,所以 topLeftY=130 → 覆盖 y=-130~130
await eda.sch_PrimitiveRectangle.create(-80, 130, 160, 260, 0, 0, null, null, null, null, null);
// 创建引脚
// SCH_PrimitivePin.create(x, y, pinNumber, pinName?, rotation?, pinLength?, pinColor?, pinShape?, pinType?)
// ⚠️ 重要:(x, y) 是引脚连接点(圆点)的位置,不是引脚端点
// 连接点应该放在矩形边缘上,引脚从连接点向外延伸
// ⚠️ 重要:rotation 参数会被 API 反转存储
// 传 0 → 存储 180 → 引脚向左延伸(适合左侧引脚)
// 传 180 → 存储 0 → 引脚向右延伸(适合右侧引脚)
// 左侧引脚: x = 矩形左边缘, rotation=0 (传0→存180→向左延伸)
// 右侧引脚: x = 矩形右边缘, rotation=180 (传180→存0→向右延伸)
// ⚠️ 重要:符号编辑器 Y 轴向上增长。y=-110 在矩形中间偏上位置(屏幕上方),
// 与原理图编辑器的直觉相反(原理图 Y 轴向下增长)。
await eda.sch_PrimitivePin.create(-80, -110, "1", "D0", 0, 20, null, "None", "BI");
await eda.sch_PrimitivePin.create(80, -110, "13", "D10", 180, 20, null, "None", "BI");
// 创建方向标识圆点(指示引脚 1 位置,在矩形左上角内部)
// 圆点坐标 (-70, 120):X 比左边缘 (-80) 略靠内,Y 在矩形顶部内侧
await eda.sch_PrimitiveCircle.create(-70, 120, 5, null, null, null, null, null);

Step 3: 创建器件(绑定符号)

javascript
const deviceUuid = await eda.lib_Device.create(personalLib, "nice!nano v2", undefined, {
symbolType: "sch",
symbol: { uuid: symbolUuid, libraryUuid: personalLib },
});

Step 4: 在原理图中使用

javascript
// 搜索自定义器件(需指定个人库 UUID)
const results = await eda.lib_Device.search("nice!nano v2", personalLib);
// 放置器件
await eda.sch_PrimitiveComponent.create(
{ libraryUuid: personalLib, uuid: results[0].uuid },
x, y, "", 0, false, true, true
);

3. 引脚创建 API

参数说明

typescript
SCH_PrimitivePin.create(
x: number, // 引脚连接点 X 坐标(圆点位置,放在矩形边缘)
y: number, // 引脚连接点 Y 坐标
pinNumber: string, // 引脚编号(如 "1", "2")
pinName?: string, // 引脚名称(如 "D0", "VCC")
rotation?: number, // 旋转角度: 0, 90, 180, 270(⚠️ 传入值与存储值相反,见下方说明)
pinLength?: number, // 引脚长度(从连接点向外延伸)
pinColor?: string | null, // 引脚颜色,null=默认
pinShape?: ESCH_PrimitivePinShape, // 引脚形状,"None"|"Clock"|"Inverted"|"Inverted Clock"
pinType?: ESCH_PrimitivePinType // 引脚类型
)
⚠️ pinName 为空时的行为:pinName 传 undefined 或 null 时,引脚只显示编号不显示名称。传空字符串 "" 效果相同。如果符号中部分引脚不需要名称(如仅用于内部连接的 GND 引脚),可省略 pinName 参数。
⚠️ 重要:`(x, y)` 是引脚连接点(圆点)的位置,不是引脚端点。
引脚从连接点沿 rotation 方向延伸 pinLength 单位。
连接点应该放在矩形边缘上,这样引脚才能正确对齐。
错误示例:x=-100, rotation=0, 矩形边缘=-80 → 连接点和矩形之间有 20 单位间隙 ❌
正确示例:x=-80, rotation=0, 矩形边缘=-80 → 连接点正好在矩形边缘 ✅

引脚类型 (pinType)

类型说明适用场景
"BI"双向GPIO 引脚
"IN"输入RESET、中断输入
"OUT"输出TX、PWM 输出
"Power"电源VCC、VDD、RAW
"Ground"地GND、VSS
"Passive"无源模拟引脚
"Undefined"未定义不使用的引脚

引脚方向 (rotation)

⚠️ API 反转行为:`sch_PrimitivePin.create()` 传入的 rotation 值会被反转为存储值。
传 0 → 存储 180(向左)→ 引脚向左延伸
传 180 → 存储 0(向右)→ 引脚向右延伸
传 90 → 存储 270(向下)→ 引脚向下延伸
传 270 → 存储 90(向上)→ 引脚向上延伸
传入 rotation存储 rotation引脚方向适用侧
0180向左符号左侧引脚
90270向下符号底部引脚
1800向右符号右侧引脚
27090向上符号顶部引脚

4. 矩形创建 API

typescript
SCH_PrimitiveRectangle.create(
topLeftX: number, // 左上角 X
topLeftY: number, // 左上角 Y(⚠️ Y 轴向上增长,topLeftY 是矩形最高点,向下延伸 height)
width: number, // 宽度
height: number, // 高度(从 topLeftY 向下延伸)
cornerRadius?: number, // 圆角半径
rotation?: number, // 旋转角度
color?: string | null, // 边框颜色
fillColor?: string | null, // 填充颜色
lineWidth?: number | null, // 线宽 1-10
lineType?: ESCH_PrimitiveLineType | null,
fillStyle?: ESCH_PrimitiveFillStyle | null
)
⚠️ 符号编辑器 Y 轴方向:与屏幕坐标不同,符号编辑器 Y 轴向上增长(数学坐标系)。
topLeftY 是矩形的最高点(Y 值最大的边),矩形从此点向下延伸 height。
例如:要让矩形覆盖 y=-130 到 y=130,应传 topLeftY=130, height=260(不是 topLeftY=-130)。

5. CLI 命令

bash
# 创建空符号到个人库
./scripts/draw_cli.py create-symbol "器件名称"
# 在编辑器中打开符号
./scripts/draw_cli.py open-symbol <symbolUuid> <libUuid>
# 从符号创建器件
./scripts/draw_cli.py create-device <名称> <symUuid> <libUuid>
# 一键构建符号(创建+打开+等待编辑)
./scripts/draw_cli.py build-symbol "器件名称"
# 搜索器件(默认系统库,指定个人库 UUID)
./scripts/draw_cli.py search "nice!nano v2" 5 --lib <libraryUuid>

6. 参考示例

6.1 符号编辑器与原理图编辑器 API 差异

操作原理图编辑器符号编辑器
查询引脚sch_PrimitivePin.getAll() ✅sch_PrimitivePin.getAll() ✅
查询矩形sch_PrimitiveRectangle.getAll() ✅❌ 返回空数组
查询圆sch_PrimitiveCircle.getAll() ✅❌ 返回空数组
查询引脚 IDsch_PrimitivePin.getAllPrimitiveId() ✅sch_PrimitivePin.getAllPrimitiveId() ✅
查询矩形 IDsch_PrimitiveRectangle.getAllPrimitiveId() ✅❌ 返回空数组
查询圆 IDsch_PrimitiveCircle.getAllPrimitiveId() ✅❌ 返回空数组
查询所有图元各类型 getAll() 方法sch_SelectControl.getAllSelectedPrimitives() ✅(需先选中)
获取图元类型sch_Primitive.getPrimitiveTypeByPrimitiveId(id) ✅✅ 可用
获取图元属性sch_Primitive.getPrimitiveByPrimitiveId(id) ✅✅ 可用

结论:在符号编辑器中,不要依赖 `sch_PrimitiveRectangle.getAll()` 和 `sch_PrimitiveCircle.getAll()` 等类型专属批量查询方法。 应使用 sch_PrimitivePin.getAllPrimitiveId() 获取所有引脚 ID,再通过 sch_Primitive.getPrimitiveByPrimitiveId(id) 逐个查询。或使用 sch_SelectControl.getAllSelectedPrimitives() 获取已选中图元(圆、矩形等均可用此方式查询)。

6.2 nice!nano v2 符号

符号参数:

  • 24 个引脚(左 12 + 右 12)
  • 引脚间距 20 单位
  • 主体矩形 160×260(topLeftX=-80, topLeftY=130)
  • 引脚长度 20
  • 方向标识:圆点在矩形左上角内部 (-70, 120),半径 5,指示引脚 1 位置
  • 引脚顺序(DIP 标准):
  • 左列 Pin 1-12:从上到下,y = 110, 90, 70, 50, 30, 10, -10, -30, -50, -70, -90, -110
  • 右列 Pin 13-24:从下到上,y = -110, -90, -70, -50, -30, -10, 10, 30, 50, 70, 90, 110

6.3 引脚布局规范

引脚名称在器件主体内部(推荐):

───┐ D0 GND ├───
───┤ D1 VCC ├───
───┤ D2 GND ├───
───┤ D3 ┌────────┐ RAW ├───
───┤ D4 │ 器件主体 │ VCC ├───
───┤ D5 │ 160×260 │ GND ├───
───┤ D6 └────────┘ RESET ├──
───┤ D7 连接点 D21 ├───
───┤ D8 x=-80/80 D20 ├───
───┤ D9 D19 ├───
───┤ D14 D18 ├───
───┘ D15 D16 └───
引脚连接点 (x,y) 在矩形边缘,引脚线在外侧
名称文本在矩形内部,编号在引脚线上方
左侧 (rotation=0): 名称在引脚线右侧(矩形内),偏移 +30
右侧 (rotation=180): 名称在引脚线左侧(矩形内),偏移 -30

7. 引脚名称位置调整(重要发现)

⚠️ 关键发现:引脚名称是 ATTR 图元(不是独立的 Text 图元),通过 `parentPrimitiveId` 精确关联到 PIN!
通过 sch_PrimitiveAttribute.getAllPrimitiveId() 可以获取所有 ATTR,包括 "Pin Name" 和 "Pin Number"。

7.1 问题现象

sch_PrimitivePin.create() 创建引脚时,EasyEDA 会自动生成 ATTR 图元作为名称和编号,但初始位置通常不正确:

PIN2 (正确): 引脚连接点(-80, 90), 名称ATTR(-50, 90) → 名称在矩形内部 ✅
PIN1 (异常): 引脚连接点(-80, 110), 名称ATTR(-103, 110) → 名称在矩形外部 ❌

7.2 原因

  • 修改 rotation 只会旋转引脚线,不会同步调整已生成的 ATTR 图元位置
  • ATTR 的 alignMode(对齐方式)和 x, y 坐标需要手动修正
  • 同名引脚(如多个 GND)不能靠 `value + y` 匹配,必须用 `parentPrimitiveId` 精确匹配

7.3 解决方案

使用 set-pin-labels-position CLI 命令批量修正引脚名称位置:

bash
# 修正左侧引脚名称位置(名称在引脚线右侧,矩形内,左对齐)
./scripts/draw_cli.py set-pin-labels-position --side left --offset 30
# 修正右侧引脚名称位置(名称在引脚线左侧,矩形内,右对齐)
./scripts/draw_cli.py set-pin-labels-position --side right --offset 30

实现原理(已固化到 `fixPinLabels`):

  1. 通过 sch_PrimitivePin.getAllPrimitiveId() 获取所有引脚
  2. 通过 sch_PrimitiveAttribute.getAllPrimitiveId() 获取所有 ATTR 图元
  3. 用 `parentPrimitiveId` 精确匹配 PIN 和 ATTR(避免同名引脚错乱)
  4. 设置正确的 alignMode 和 x, y 坐标

或手动用 sch_PrimitiveAttribute API 调整:

javascript
// 1. 获取所有 ATTR
const attrIds = await eda.sch_PrimitiveAttribute.getAllPrimitiveId();
// 2. 找到 Pin Name ATTR(必须用 parentPrimitiveId 匹配,不能只用 value)
const attr = await eda.sch_PrimitiveAttribute.get([attrId]);
// 3. 修改位置和对齐方式
const at = attr[0].toAsync();
at.setState_AlignMode(2); // 左侧=2(左中),右侧=8(右中)
at.setState_X(-50);
at.setState_Y(-pin.y); // ⚠️ Y 坐标 = -pin.y(符号编辑器坐标系)
await at.done();

7.4 名称位置规律(已验证)

引脚侧rotationalignMode 设置值alignMode 存储值含义X 坐标Y 坐标
左侧02 (左中)3 (左中)文字从锚点向右延伸,左对齐pin.x + offset-pin.y
右侧1808 (右中)5 (右中)文字从锚点向左延伸,右对齐pin.x - offset-pin.y
顶部2705 (正中)4 (正中)文字水平居中,在矩形内部pin.x-pin.y + offset
底部905 (正中)4 (正中)文字水平居中,在矩形内部pin.x-pin.y - offset

⚠️ 关键规则(实测验证):

  1. Y 坐标 = `-pin.y`:setState_Y(-pin.y) 后 EasyEDA 内部自动翻转为 pin.y 存储,显示位置正确
  2. alignMode 设置值与存储值不同:EasyEDA 内部使用列优先九宫格存储
  • 设置值(setState_AlignMode):1=左上 2=左中 3=左下 4=中上 5=正中 6=中下 7=右上 8=右中 9=右下
  • 存储值(alignMode 属性 / getState_AlignMode()):0=左上 1=中上 2=右上 3=左中 4=正中 5=右中 6=左下 7=中下 8=右下
  1. alignMode 必须用"中"锚点(设置值 2/8/5),不要用"上/下"锚点,否则 Y 位置会偏移
  2. X 坐标是文字锚点位置,不是文字中心:左中(2)时 X 是文字左边缘,右中(8)时 X 是文字右边缘,正中(5)时 X 是文字中心
  3. offset 推荐值 5~10:名称与矩形边缘的距离,默认 5

ATTR 属性说明:

  • key: "Pin Name" 或 "Pin Number"
  • value: 引脚名称或编号
  • x, y: ATTR 锚点位置(设置 -pin.y 或 -pin.y ± offset,存储为 pin.y 或 pin.y ∓ offset)
  • alignMode: 对齐方式存储值(左侧=3 左中,右侧=5 右中,上下=4 正中)
  • parentPrimitiveId: 精确关联的 PIN ID(匹配时必须使用)

7. 常见错误

错误原因解决
"无法创建引脚图元"pinShape 传了 null改为传 "None"
搜索不到自定义器件搜索的是系统库传入个人库 UUID
引脚不显示符号编辑器未激活先 openInEditor 再操作
引脚与矩形未对齐(x,y) 位置错误,放在矩形边缘 + 长度位置(x,y) 应放在矩形边缘上,不是边缘 + 长度
矩形查询不到sch_PrimitiveRectangle.getAll() 在符号编辑器中无效改用 sch_SelectControl.getAllSelectedPrimitives()
All versions