内容
# 电赛信号题统一 MCP
本项目通过 USBTMC + NI-VISA/PyVISA 安全读取和控制以下仪器:
- SIGLENT SDS2000X Plus 系列示波器;实机验证型号为 SDS2502X Plus。
- SIGLENT SDG6000X/SDG6000X-E 系列信号发生器;实机验证型号为 SDG6032X-E。
项目同时提供 MCP Server 和 `econtest-signal-bench` Agent Skill,适用于电赛中的低压波形产生、示波器配置、幅频测量、扫频和证据化报告。
## 当前能力
- 仅支持 USB + VISA,不支持 LAN、无线、Telnet 或 WebControl。
- 信号源支持 SINE、SQUARE、RAMP、PULSE 和扫频。
- 服务器输出软上限为 3 Vpp;当前完整回路在 1 Vpp 下通过验证。
- 支持 SDS 通道、时基、边沿触发、RUN/STOP/SINGLE、示波器原生测量和有界 BYTE 波形读取。
- 幅度、Vpp、频率的验收优先使用 `scope_measure_simple` 返回的示波器原生测量;波形导出仅用于证据和诊断。
- 所有写操作均执行身份校验、`*OPC?`、设置回读和证据记录。
- 完整回路工具会在失败和正常结束时关闭信号源输出,并确认示波器 STOP。
### TODO:PNG 截图
`PRIN? BMP/PNG` 在 SDS2502X Plus 固件 `5.0.1.3.7R5` 上通过 USB-VISA 不返回数据并超时,因此当前版本不暴露截图工具。
后续需要确认该固件的 USB 截图协议、替代命令或安全的仪器文件读取方法。完成实机验证前,不得宣称支持 PNG 截图。
## 安装
先安装 NI-VISA,并在 NI MAX 中确认两台仪器都以 USB INSTR 资源出现。然后在本项目目录运行:
```powershell
python -m pip install -e ".[mcp]"
python -m unittest discover -s tests -v
```
`econtest-bench-mcp` 是 **stdio MCP Server**,应由 MCP 客户端启动,不是可交互的终端程序。直接在 PowerShell 运行后按回车会向 Server 输入空行,因而出现 `Invalid JSON: EOF while parsing`;这表示输入不是 JSON-RPC 消息,不是仪器通信失败。
将下列命令填入 MCP 客户端配置即可启动:
```powershell
econtest-bench-mcp
```
未安装命令行入口时,客户端也可以运行:
```powershell
python -m econtest_bench_mcp
```
## MCP 客户端配置
安装为命令行程序后,可使用以下 stdio 配置:
```json
{
"mcpServers": {
"econtest-bench": {
"command": "econtest-bench-mcp"
}
}
}
```
如果没有安装命令行入口,可指定 Python 和项目目录:
```json
{
"mcpServers": {
"econtest-bench": {
"command": "python",
"args": ["-m", "econtest_bench_mcp"],
"cwd": "D:/CodeStudy/电赛/econtest-bench-mcp/econtest-bench-mcp"
}
}
}
```
具体配置字段以所用 MCP 客户端为准。Server 使用标准输入输出通信,不要把普通日志写入标准输出。
## Agent Skill 安装
源码中的 canonical Skill 位于:
```text
skill/econtest-signal-bench/
```
安装包还提供拒绝覆盖的导出命令:
```powershell
econtest-bench-mcp-skill C:\目标目录\econtest-signal-bench
```
将导出的目录放入客户端支持的 Skill 目录,然后使用 `$econtest-signal-bench` 调用。
## MCP 工具
### 发现与状态
| 工具 | 用途 |
| --- | --- |
| `bench_list_devices` | 枚举 USBTMC 设备并识别角色 |
| `bench_identify` | 校验指定资源、角色和序列号 |
| `scope_status` | 读取示波器通道、采集和触发状态 |
| `generator_status` | 读取双通道输出和基本波状态 |
| `bench_status` | 生成双设备只读基线证据 |
### 信号发生器
| 工具 | 用途 |
| --- | --- |
| `generator_configure_basic` | 输出 OFF 时配置四种基本波 |
| `generator_set_load` | 输出 OFF 时设置 High-Z 或 50 Ω 显示负载 |
| `generator_set_output` | 开启或关闭输出;ON 需要确认、目标和负载 |
| `generator_configure_sweep` | 输出 OFF 时配置或关闭扫频 |
扫频关闭后,实机可能停留在扫频过程中的载波频率。需要继续使用固定频率时,应再次调用 `generator_configure_basic` 恢复基本波。
### 示波器
| 工具 | 用途 |
| --- | --- |
| `scope_configure_channel` | 设置通道开关、耦合、探头倍率、档位和偏移 |
| `scope_configure_timebase` | 设置主时基 |
| `scope_configure_edge_trigger` | 设置边沿触发 |
| `scope_control` | 控制 RUN、STOP 或 SINGLE;SINGLE 可有界等待并返回新鲜度状态 |
| `scope_measure_simple` | 只读获取示波器原生 PKPK/FREQ/RMS 等读数、单位、无效值、统计量和完整配置上下文 |
| `scope_capture_waveform` | 确认 STOP 后读取有界 BYTE 波形证据;不能作为精密 Vpp 验收值 |
### 完整回路
| 工具 | 用途 |
| --- | --- |
| `bench_capture_response` | 自动执行 OFF 配置、输出 ON、测量、波形采集、输出 OFF 和示波器 STOP |
| `artifacts_remove_runs` | 仅在明确确认后删除逐个指定的失败或过期证据 run |
## 最小只读教程
1. 调用 `bench_list_devices`。
2. 记录 scope 和 generator 的 VISA resource、型号及序列号。
3. 调用 `bench_status`,同时传入两个 resource 和 serial。
4. 检查返回的 `evidence.manifest` 和设备回读。
任何后续操作都应继续传入序列号,避免 USB 资源顺序变化后选错设备。
## 完整回路教程
推荐的安全入门回路:
```text
SDG CH1 OUTPUT ── 50 Ω BNC 同轴线 ── SDS CH1 INPUT
```
连接条件:无 DUT、两台仪器正常保护接地、SDS CH1 为 1 MΩ、SDG 显示负载为 High-Z、两路信号源输出均为 OFF。
确认物理条件后,优先调用 `bench_capture_response`:
```json
{
"scope_resource": "USB0::...SDS...::INSTR",
"generator_resource": "USB0::...SDG...::INSTR",
"scope_serial": "示波器序列号",
"generator_serial": "信号源序列号",
"waveform": "SINE",
"frequency_hz": 1000,
"amplitude_vpp": 1,
"expected_destination": "SDS CH1 直连 BNC,1 MΩ,无 DUT",
"confirm_output_enable": true,
"load_mode": "HZ",
"scope_channel": 1,
"generator_channel": 1,
"points": 4000,
"settle_time_s": 0.5
}
```
成功结果应包含:
- 信号源配置和输出开启回读;
- 示波器 PKPK、FREQ、RMS、DUTY 测量;
- 波形 Vpp、均值、时间跨度等摘要;
- `output_final_state: confirmed_off`;
- `scope_final_state: Stop`;
- evidence manifest 路径。
若工具失败,应检查返回错误中的 cleanup 和部分证据路径。输出状态为 unknown 时,必须立即人工查看信号源前面板。
## 分步控制教程
需要人工编排时,严格按以下顺序:
1. `bench_status`:确认身份和基线,目标 SDG 通道必须为 OFF。
2. `generator_set_load`:设置与实际接线一致的 `HZ` 或 `50`。
3. `generator_configure_basic`:配置波形,幅度不得超过 3 Vpp。
4. 配置示波器通道、时基和触发。
5. `scope_control(RUN)`。
6. `generator_set_output(ON)`:提供 `confirm_output_enable=true`、目标说明和负载。
7. 幅度/频率验收使用 `scope_measure_simple`;波形形状诊断或留证使用 `scope_capture_waveform`。
8. `generator_set_output(OFF)` 并检查 `confirmed_off`。
9. `scope_control(STOP)`。
不要在输出 ON 时调用基本波、负载或扫频配置工具。
## 证据目录
所有产物固定写入:
```text
artifacts/runs/<UTC时间>_<run_id>/
```
常见文件包括 `manifest.json`、`events.jsonl`、设备身份、配置回读、原始波形码、波形元数据和数值摘要。`manifest.json` 的 `calibration_eligible` 默认是 `false`;只有未来具备完整的原生测量、配置回读、外部 DUT 回显和新鲜采集闭环时才允许标记为 `true`。MCP 只返回摘要和路径,不把大型数组放入对话。
校验证据:
```powershell
python skill\econtest-signal-bench\scripts\validate_evidence.py artifacts\runs\某次运行\manifest.json
```
如需清理产物,只能调用 `artifacts_remove_runs`,逐个传入目录名(形如 `20260722T...Z_<run_id>`)、失败或过期原因,并设置 `confirm_cleanup=true`。它不会接受任意路径、通配符或父目录;以 `failed` 原因删除时还会校验 manifest 确实为失败状态。
## 外部 DUT(例如串口控制 MCU)教程
`bench_capture_response` 只适用于 `SDG → DUT → SDS` 的完整回路。若 DUT 由串口、调试器或其他控制器驱动,应由该控制器先完成 DUT 操作,再使用 MCP 的只读原生测量工具:
1. 发送 DUT 命令并确认可解析回显。例如记录 `RX r4 1000 2.0` 与 `OUT R4 1000 2.0`。
2. 从**回显完成时刻**起,按 DUT 特性明确设定稳定时间;低频、高 Q 或长时间常数电路不可套用固定短等待。
3. 如需新鲜的单帧,调用 `scope_control(action="SINGLE", confirm_state_change=true, single_wait_timeout_s=...)`。只有 `single.completed=true` 时才可认为该帧已完成;`Ready`、超时或无效测量均为 `inconclusive`。
4. 调用 `scope_measure_simple`,例如:
```json
{
"resource": "USB0::...SDS...::INSTR",
"serial": "示波器序列号",
"channel": 1,
"items": ["PKPK", "FREQ", "RMS"],
"require_scope_state": "STOP",
"samples": 3,
"measurement_point_id": "round1.r4.1000hz.2vpp",
"dut_context": {
"command": "r4 1000 2.0",
"echo": "OUT R4 1000 2.0",
"command_sent_at_utc": "由 DUT 控制器记录",
"echo_received_at_utc": "由 DUT 控制器记录"
}
}
```
5. 检查 `scope_measure_simple.measurement_validity`。任何原生项目无效时均为 `inconclusive`,不得更新校准表。再调用 `scope_capture_waveform`,传入相同的 `measurement_point_id` 和 `dut_context` 保存可复现波形证据。其 `waveform.vpp_v` 是导出 BYTE 波形摘要,绝不能覆盖原生 `PKPK`。
6. 最终调用 `scope_control(STOP)` 并回读确认。外部 DUT 的最终输出状态只能由其控制器记录,MCP 不会宣称已经关闭它。
当原生值与波形摘要的 Vpp 差异超过项目预先设定的门限时,停止自动校准并人工判断。不得用单一软件拟合值宣称满足 1% 指标;批量校准前,先以 1 至 3 个代表点验证两类数值的一致性。
## 安全边界
- 软件不能验证接地、隔离、探头位置和额定值;这些由操作者负责。
- 不得将 BNC 地端接到非隔离高侧节点。
- 不支持任意 SCPI、`*RST`、固件、网络或仪器文件系统操作。
- 输出 ON 必须明确确认目标和负载,关闭输出不需要确认。
- 通信丢失时不得声称输出已经关闭。
- USB 软件操作不是硬件同步触发。
## 开发验证
```powershell
python -m unittest discover -s tests -v
python -m compileall -q src tests
```
已验证硬件和已知差异见 [硬件验证记录](docs/hardware-validation.md),支持矩阵见 [兼容性矩阵](docs/compatibility-matrix.md)。