250 lines
9.8 KiB
C#
250 lines
9.8 KiB
C#
using Common.Attributes;
|
||
using DeviceCommand.Base;
|
||
using Model.Models;
|
||
using System;
|
||
using System.Globalization;
|
||
using System.Threading;
|
||
using System.Threading.Tasks;
|
||
|
||
namespace DeviceCommand.Device
|
||
{
|
||
[ADPCommand]
|
||
public class SDS2000X_HD : Tcp
|
||
{
|
||
// 示波器底层 Socket 字符串命令通常以换行符 \n 结束
|
||
private const string ScpiDelimiter = "\n";
|
||
|
||
/// <summary>
|
||
/// 构造函数:传入 <see cref="TcpConfig"/> 一次性初始化示波器通信参数。
|
||
/// 鼎阳示波器网口 Socket 默认端口通常为 5025,请在配置中设置。
|
||
/// </summary>
|
||
public SDS2000X_HD(TcpConfig config) : base(config)
|
||
{
|
||
}
|
||
|
||
#region 1. IEEE 488.2 公共命令
|
||
|
||
/// <summary>
|
||
/// 清除标准事件状态寄存器和错误队列
|
||
/// </summary>
|
||
public virtual async Task 清除状态(CancellationToken ct = default)
|
||
{
|
||
await SendAsync($"*CLS{ScpiDelimiter}", ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 读取示波器识别字符串(制造商、型号、序列号、固件版本)
|
||
/// </summary>
|
||
public virtual async Task<string> 查询设备标识(CancellationToken ct = default)
|
||
{
|
||
return await WriteReadAsync($"*IDN?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 复位命令。使示波器恢复到默认的出厂设置
|
||
/// </summary>
|
||
public virtual async Task 重置设备(CancellationToken ct = default)
|
||
{
|
||
await SendAsync($"*RST{ScpiDelimiter}", ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 【补充】查询先前操作是否完成。
|
||
/// 在重置设备(*RST)或切换大物理量程后调用,返回 "1" 代表示波器继电器切换就绪,防止后续指令引发阻塞。
|
||
/// </summary>
|
||
public virtual async Task<bool> 检查操作完成_OPC(CancellationToken ct = default)
|
||
{
|
||
string res = await WriteReadAsync($"*OPC?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||
return res.Trim() == "1";
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 2. 运行与捕获控制 (Run / Stop / Single)
|
||
|
||
/// <summary>
|
||
/// 控制示波器开始捕获波形 (等同于按下前端面板的 Run 键)
|
||
/// </summary>
|
||
public virtual async Task 启动捕获_RUN(CancellationToken ct = default)
|
||
{
|
||
await SendAsync($"RUN{ScpiDelimiter}", ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 停止捕获波形 (等同于按下前端面板的 Stop 键)
|
||
/// </summary>
|
||
public virtual async Task 停止捕获_STOP(CancellationToken ct = default)
|
||
{
|
||
await SendAsync($"STOP{ScpiDelimiter}", ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 强制示波器进入单次触发捕获模式 (常用于捕捉充电瞬间的过冲浪涌波形)
|
||
/// </summary>
|
||
public virtual async Task 单次触发_SINGLE(CancellationToken ct = default)
|
||
{
|
||
await SendAsync($"SINGle{ScpiDelimiter}", ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 触发一次波形采样 (当触发源设为 Manual 时使用)
|
||
/// </summary>
|
||
public virtual async Task 强制触发(CancellationToken ct = default)
|
||
{
|
||
await SendAsync($"*TRG{ScpiDelimiter}", ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 【补充】设置触发模式 (AUTO, NORM, SINGLE)
|
||
/// </summary>
|
||
public virtual async Task 设置触发模式(string mode, CancellationToken ct = default)
|
||
{
|
||
string modeUpper = mode.ToUpper();
|
||
if (modeUpper != "AUTO" && modeUpper != "NORM" && modeUpper != "SINGLE")
|
||
throw new ArgumentException("触发模式只能为 AUTO, NORM, 或 SINGLE");
|
||
|
||
await SendAsync($"TRMD {modeUpper}{ScpiDelimiter}", ct);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 3. Channel 垂直控制子系统 (C1 ~ C4)
|
||
|
||
/// <summary>
|
||
/// 开启或关闭指定的模拟通道
|
||
/// </summary>
|
||
public virtual async Task 设置通道开关(int channel, bool enable, CancellationToken ct = default)
|
||
{
|
||
// 修正:根据手册规范,使用 1/0 比 ON/OFF 在高低版本固件中兼容性更稳定
|
||
string state = enable ? "1" : "0";
|
||
await SendAsync($"C{channel}:TRAce {state}{ScpiDelimiter}", ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设置指定通道的垂直电压档位 (Volts/Div,单位: V,例如 0.05 代表 50mV/div)
|
||
/// </summary>
|
||
public virtual async Task 设置通道电压档位(int channel, double volts, CancellationToken ct = default)
|
||
{
|
||
string cmd = string.Format(CultureInfo.InvariantCulture, "C{0}:VDIV {1:F4}{2}", channel, volts, ScpiDelimiter);
|
||
await SendAsync(cmd, ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 【补充验证】查询指定通道当前的电压档位 (用于 Setup-Verify 闭环验证逻辑)
|
||
/// </summary>
|
||
public virtual async Task<string> 查询通道电压档位(int channel, CancellationToken ct = default)
|
||
{
|
||
return await WriteReadAsync($"C{channel}:VDIV?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设置指定通道的垂直偏移量 (Offset,单位: V)
|
||
/// </summary>
|
||
public virtual async Task 设置通道垂直偏移(int channel, double offset, CancellationToken ct = default)
|
||
{
|
||
string cmd = string.Format(CultureInfo.InvariantCulture, "C{0}:OFST {1:F4}{2}", channel, offset, ScpiDelimiter);
|
||
await SendAsync(cmd, ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设置通道的输入阻抗与耦合模式
|
||
/// </summary>
|
||
/// <param name="coupling">合法参数:A1M (交流1M), D1M (直流1M), D50 (直流50欧)</param>
|
||
public virtual async Task 设置通道耦合与阻抗(int channel, string coupling, CancellationToken ct = default)
|
||
{
|
||
string coupUpper = coupling.ToUpper();
|
||
await SendAsync($"C{channel}:COUPling {coupUpper}{ScpiDelimiter}", ct);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 4. Timebase 水平时基子系统
|
||
|
||
/// <summary>
|
||
/// 设置示波器的水平时基档位 (Time/Div,单位: s,例如 0.001 代表 1ms/div)
|
||
/// </summary>
|
||
public virtual async Task 设置水平时基(double scale, CancellationToken ct = default)
|
||
{
|
||
// 修正:统一使用更精简且符合手册定义的简写形式 TDIV
|
||
string cmd = string.Format(CultureInfo.InvariantCulture, "TDIV {0:E6}{1}", scale, ScpiDelimiter);
|
||
await SendAsync(cmd, ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设置示波器的触发水平延迟位置 (Horizontal Delay,单位: s)
|
||
/// </summary>
|
||
public virtual async Task 设置水平延迟(double delay, CancellationToken ct = default)
|
||
{
|
||
// 修正:采用手册标准简写 TRDL 效率更高
|
||
string cmd = string.Format(CultureInfo.InvariantCulture, "TRDL {0:E6}{1}", delay, ScpiDelimiter);
|
||
await SendAsync(cmd, ct);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 5. Trigger 触发子系统
|
||
|
||
/// <summary>
|
||
/// 设置边沿触发的电平值 (Trigger Level,单位: V)
|
||
/// </summary>
|
||
public virtual async Task 设置触发电平(double level, CancellationToken ct = default)
|
||
{
|
||
// 修正:采用标准简写 TRLV
|
||
string cmd = string.Format(CultureInfo.InvariantCulture, "TRLV {0:F3}{1}", level, ScpiDelimiter);
|
||
await SendAsync(cmd, ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设置边沿触发的触发源 (例如: C1, C2, C3, C4, EX, LINE)
|
||
/// </summary>
|
||
public virtual async Task 设置触发源(string source, CancellationToken ct = default)
|
||
{
|
||
// 修正:采用标准简写 TRSE 体系配置指令
|
||
await SendAsync($"TRIGger:SOURce {source.ToUpper()}{ScpiDelimiter}", ct);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 6. Measure 自动测量参数回读 (高频轮询核心)
|
||
|
||
/// <summary>
|
||
/// 查询指定通道自动测量项的当前实时测量数值
|
||
/// </summary>
|
||
/// <param name="channel">通道号 (1-4)</param>
|
||
/// <param name="paramName">参数名称助记符:
|
||
/// PKPK(峰峰值), MAX(最大值), MIN(最小值), AMPL(振幅值),
|
||
/// FREQ(频率), PER(周期), MEAN(平均值), RMS(均方根) 等</param>
|
||
public virtual async Task<string> 查询通道测量项参数(int channel, string paramName, CancellationToken ct = default)
|
||
{
|
||
// 优化:采用更兼容的测量读取指令语法格式
|
||
string query = string.Format(CultureInfo.InvariantCulture, "C{0}:PAVA? {1}{2}", channel, paramName.ToUpper(), ScpiDelimiter);
|
||
return await WriteReadAsync(query, ScpiDelimiter, ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 轮询便捷接口:查询指定通道的电压峰峰值 (Vpp)
|
||
/// </summary>
|
||
public virtual async Task<string> 查询实际电压峰峰值(int channel, CancellationToken ct = default)
|
||
{
|
||
return await 查询通道测量项参数(channel, "PKPK", ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 轮询便捷接口:查询指定通道的频率值 (Frequency)
|
||
/// </summary>
|
||
public virtual async Task<string> 查询实际频率(int channel, CancellationToken ct = default)
|
||
{
|
||
return await 查询通道测量项参数(channel, "FREQ", ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 轮询便捷接口:查询指定通道的真均方根电压值 (Vrms)
|
||
/// </summary>
|
||
public virtual async Task<string> 查询实际电压均方根(int channel, CancellationToken ct = default)
|
||
{
|
||
return await 查询通道测量项参数(channel, "RMS", ct);
|
||
}
|
||
|
||
#endregion
|
||
}
|
||
} |