Skip to main content

easyeda-draw-checking

Schematic verification and quality checking for EasyEDA Pro. Invoke when verifying layout, checking for overlaps, validating designators, or running design rule checks.

Quellinformationen

Repository
kukucaiCndy/embedded_ai_skills
Letzte Quellaktivität
30. Juli 2026 um 08:53
Erkannte Sprache von SKILL.md
Chinesisch
Sterne
60
Forks
12

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
easyeda-draw-checking
description
Schematic verification and quality checking for EasyEDA Pro. Invoke when verifying layout, checking for overlaps, validating designators, or running design rule checks.
# 原理图检查 布局验证、重叠检测、位号检查、DRC 的完整指南。 > **⚠️ 重要**:所有检查必须通过 CLI 执行,禁止使用 curl 直接调用 API。 --- ## 0. 快捷入口:CLI 一键检查 按绘制阶段使用不同的检查命令: ```bash # 摆放一个模块后(每个模块摆放完必须执行) ./scripts/draw_cli.py verify-placement # 连线一个模块后(每个模块连线完必须执行) ./scripts/draw_cli.py verify-wiring # 全部模块完成后(最终提交前必须执行) ./scripts/draw_cli.py check-all # DRC 不通过时查看逐项详情 ./scripts/draw_cli.py drc --show-ui ``` --- ## 1. DRC 检查(Design Rule Check) ### 1.0 DRC API 限制(重要) > **⚠️ EasyEDA SCH_Drc API 只返回聚合统计**: > ```javascript > // check(true, false, true) 返回的是: > [{ type: "fatalError", count: 1 }, { type: "warn", count: 11 }] > ``` > **不返回每个错误的具体信息**(器件名、引脚号、错误描述等)。 > > **查看逐项详细错误的唯一方式**: > ```bash > ./scripts/draw_cli.py drc --show-ui > ``` > 这会呼出 EasyEDA 底部的 DRC 面板,面板中可看到每个错误的器件、引脚、具体描述。 ### 1.1 基础 DRC ```javascript // 仅知道是否通过 const passed = await eda.sch_Drc.check(true, false, false); // passed: true = 通过, false = 有错误 // 获取详细错误统计 const errors = await eda.sch_Drc.check(true, false, true); // 返回数组:[{ type: "fatalError"|"warn", count: N }] ``` ### 1.2 DRC 问题排查流程 ``` DRC 不通过 │ ├─ fatalError(致命错误) │ ├─ 未连接引脚 → 补全连线 或 添加 NC 标记 │ ├─ 网络短路 → 检查同一网络是否有不该连接的引脚 │ └─ 缺失网络标签 → 添加 NetFlag / NetPort │ └─ warn(警告) ├─ 空网络导线 → 为导线设置网络名 ├─ 未使用引脚 → 确认是否需要 NC 标记 └─ 去耦电容缺失 → 在 IC 电源引脚附近补充 ``` ### 1.3 使用 easyeda-draw 函数 ```javascript import utils from './scripts/draw-utils.js'; // 运行 DRC 详细检查 const result = await utils.runDrc(); // { passed: boolean, fatalErrors: number, warnings: number, details: Array } ``` --- ## 2. 重复标签检测 ### 2.1 检测原理 遍历所有 NetFlag/NetPort 图元,按坐标分组,找出同一位置放置多次的图元。 ### 2.2 使用函数 ```javascript import utils from './scripts/draw-utils.js'; // 检测重复标签 const result = await utils.detectDuplicateLabels(); // { duplicates: [{ position, items: [{id, net, type}] }] } // 自动删除重复标签(每组保留第一个) const cleanup = await utils.cleanupDuplicateLabels(); // { deleted: N, details: [...] } ``` ### 2.3 手动检测 ```javascript const allComps = await eda.sch_PrimitiveComponent.getAll(); const posMap = new Map(); for (const c of allComps || []) { // 只检查 NetFlag/NetPort (designator 为空或 "?") if (c.designator && c.designator !== '?') continue; const key = `${c.x},${c.y}`; if (!posMap.has(key)) posMap.set(key, []); posMap.get(key).push({ id: c.primitiveId, type: c.net ? 'NetFlag' : 'NetPort', net: c.net, rotation: c.rotation, }); } const duplicates = []; for (const [pos, items] of posMap) { if (items.length > 1) duplicates.push({ position: pos, items }); } ``` --- ## 3. 导线网络名完整性检查 ### 3.1 检测原理 遍历所有导线,检查网络名是否为空。 ### 3.2 使用函数 ```javascript import utils from './scripts/draw-utils.js'; // 检测无网络名的导线 const result = await utils.checkWireNets(); // { total: N, noNet: M, wiresNoNet: [{id, line}] } ``` ### 3.3 修复导线网络名 ```javascript // 逐个修复:用 getPrimitiveByPrimitiveId 获取导线 → toAsync → setState_Net → done const w = await eda.sch_Primitive.getPrimitiveByPrimitiveId(wireId); const aw = w.toAsync(); aw.setState_Net("NET_NAME"); aw.done(); ``` --- ## 4. 未连接引脚检测 ### 4.1 检测原理 对每个真实器件(有设计位号的),检查各引脚是否被导线可达或连接了网络标签。 **改进点(与旧版本差异):** | 特性 | 旧版本 | 新版本 | |------|--------|--------| | 4PIN 轻触开关 | 所有引脚都检查 | PIN1↔PIN2 内部短接,PIN3↔PIN4 内部短接,只接一对即可 | | NC 标记 | 不识别 | 有 NC 标记的引脚不算未连接 | | 分级 | 全部报 error | 区分 error (应连接) 和 warning (4PIN 冗余引脚,正常) | ### 4.2 使用 CLI ```bash ./scripts/draw_cli.py check-unconnected # 返回: { errorCount, warningCount, errors: [...], warnings: [...] } # errors: 应连接但未连接的引脚 # warnings: 4PIN 开关内部短接的冗余引脚 (正常) ``` ### 4.3 输出解读 - `errorCount > 0` → 有引脚应连接但未连接,必须修复 - `warningCount > 0` 且 `errorCount = 0` → 4PIN 开关冗余引脚,正常无需修复 - 4PIN 开关判断: 器件有 4 个引脚且符号名包含 SWITCH/轻触/4PIN/SMD_4 --- ## 4.5 短路检测(NEW) ### 原理 用并查集 (union-find) 合并物理上相连的连接点,如果同一个连通分量中有 2+ 个不同网络名 → 短路。 ### 使用 CLI ```bash ./scripts/draw_cli.py check-shorts # 返回: { shortCount, shorts: [{nets, points, wireCount, wireIds}], passed } ``` ### 典型短路场景 - VCC 和 GND 通过导线直接连通 - ROW0 和 ROW1 通过同一连接点误连 - 两个不同信号通过 NetPort 标签放在同一坐标 ## 4.7 冗余导线检测(NEW) ### 原理 检查同两个物理点之间是否有多条导线。冗余导线不会引起电气错误,但让原理图凌乱。 ### 使用 CLI ```bash ./scripts/draw_cli.py check-redundant-wires # 返回: { redundantCount, redundant: [{endpoints, count, wires}], passed } ``` --- ## 5. 布局验证(重叠检测) ### 检测所有器件重叠 ```javascript import utils from './scripts/draw-utils.js'; const { overlaps } = await utils.checkOverlaps(); // overlaps: [{comp1, comp2}] ``` ### 手动检测 ```javascript const compIds = await eda.sch_PrimitiveComponent.getAllPrimitiveId(); const bboxes = []; for (const id of compIds) { const comps = await eda.sch_PrimitiveComponent.get([id]); if (!comps || comps.length === 0) continue; const c = comps[0]; const pins = await eda.sch_PrimitiveComponent.getAllPinsByPrimitiveId(id); if (pins && pins.length > 0) { let minX = Infinity, maxX = -Infinity, minY = Infinity, maxY = -Infinity; for (const p of pins) { minX = Math.min(minX, p.x); maxX = Math.max(maxX, p.x); minY = Math.min(minY, p.y); maxY = Math.max(maxY, p.y); } bboxes.push({ id, designator: c.designator, name: c.name, bbox: [minX, minY, maxX, maxY], area: (maxX - minX) * (maxY - minY), }); } } // 检查重叠 const overlaps = []; for (let i = 0; i < bboxes.length; i++) { for (let j = i + 1; j < bboxes.length; j++) { const a = bboxes[i].bbox; const b = bboxes[j].bbox; if (a[0] < b[2] && a[2] > b[0] && a[1] < b[3] && a[3] > b[1]) { overlaps.push({ comp1: bboxes[i].designator, comp2: bboxes[j].designator, }); } } } ``` ### 间距检查 ```javascript const minSpacing = 40; // 最小间距 40 单位 (0.4 inch) const tooClose = []; for (let i = 0; i < bboxes.length; i++) { for (let j = i + 1; j < bboxes.length; j++) { const a = bboxes[i].bbox; const b = bboxes[j].bbox; const ax = (a[0] + a[2]) / 2; const ay = (a[1] + a[3]) / 2; const bx = (b[0] + b[2]) / 2; const by = (b[1] + b[3]) / 2; const dist = Math.sqrt((ax - bx) ** 2 + (ay - by) ** 2); if (dist < minSpacing) { tooClose.push({ comp1: bboxes[i].designator, comp2: bboxes[j].designator, distance: dist, minRequired: minSpacing, }); } } } ``` --- ## 6. 位号检查 ### 检查缺失或异常位号 ```javascript const compIds = await eda.sch_PrimitiveComponent.getAllPrimitiveId(); const issues = []; for (const id of compIds) { const comps = await eda.sch_PrimitiveComponent.get([id]); if (!comps || comps.length === 0) continue; const c = comps[0]; // 检查位号是否存在 if (!c.designator) { issues.push({ id, type: "missing_designator", name: c.name }); continue; } // 检查位号是否包含 ?(未分配) if (c.designator.includes("?")) { issues.push({ id, type: "unassigned_designator", designator: c.designator, name: c.name }); } // 检查位号格式(字母+数字) if (!/^[A-Z]+\d+$/.test(c.designator)) { issues.push({ id, type: "invalid_format", designator: c.designator, name: c.name }); } } ``` ### 位号重复检查 ```javascript const designatorMap = new Map(); const duplicates = []; for (const id of compIds) { const comps = await eda.sch_PrimitiveComponent.get([id]); const c = comps[0]; if (c.designator) { if (designatorMap.has(c.designator)) { duplicates.push({ designator: c.designator, ids: [designatorMap.get(c.designator), id], }); } else { designatorMap.set(c.designator, id); } } } ``` --- ## 7. 文本标注检查 ### 检测重复文本 ```javascript const textIds = await eda.sch_PrimitiveText.getAllPrimitiveId(); const textMap = new Map(); for (const tid of textIds) { const t = await eda.sch_PrimitiveText.get([tid]); if (t && t[0]) { const key = `${t[0].x},${t[0].y}`; if (!textMap.has(key)) textMap.set(key, []); textMap.get(key).push({ id: tid, content: t[0].content, fontSize: t[0].fontSize }); } } const duplicateTexts = []; for (const [pos, items] of textMap) { if (items.length > 1) duplicateTexts.push({ position: pos, items }); } ``` ### 检查文本位置是否合理 ```javascript // 检查文本是否与器件重叠 const textOverlaps = []; for (const t of texts) { for (const b of bboxes) { if (t.x > b.bbox[0] && t.x < b.bbox[2] && t.y > b.bbox[1] && t.y < b.bbox[3]) { textOverlaps.push({ text: t.content, component: b.designator, }); } } } ``` --- ## 8. 导线穿过器件检测(NEW) ### 8.1 检测原理 遍历所有导线的每个线段,与所有真实器件的 BBox(边界框)做交叉检测: - 若导线端点在器件 BBox 内部(排除 ±3 容差的引脚边缘)→ 报出 - 若线段与器件 BBox 相交,且交叉长度 > 5 单位 → 报出 这能发现像 R7、R8 被 ROW 网络导线直接穿过的问题。 ### 8.2 使用 CLI ```bash ./scripts/draw_cli.py check-wire-through ``` ### 8.3 使用函数 ```javascript import utils from './scripts/draw-utils.js'; const result = await utils.checkWireThroughComponent();
Auf GitHub ansehen
Diese SKILL.md ist sehr gross, daher zeigt SkillsMP hier nur den ersten Abschnitt. Auf GitHub ansehen