729 lines
33 KiB
C#
729 lines
33 KiB
C#
using Common.Attributes;
|
||
using DeviceCommand.Base;
|
||
using Model.Models;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.Globalization;
|
||
using System.Text.RegularExpressions;
|
||
using System.Threading;
|
||
using System.Threading.Tasks;
|
||
|
||
namespace DeviceCommand.Devices
|
||
{
|
||
/// <summary>
|
||
/// 交流源 一拖三 (Chroma 61800系列)
|
||
/// </summary>
|
||
[ACPCommand]
|
||
public class Chroma61800 : Tcp
|
||
{
|
||
// Chroma SCPI 默认使用 \n 作为结束符
|
||
private const string ScpiDelimiter = "\n";
|
||
|
||
public Chroma61800(TcpConfig config) : base(config)
|
||
{
|
||
}
|
||
|
||
/// <summary>
|
||
/// 从设备返回的 SCPI 响应字符串中提取数值部分并转换为 double。
|
||
/// 支持科学计数法(如 2.48E-03),结果保留两位小数。
|
||
/// </summary>
|
||
/// <param name="raw">设备返回的原始字符串</param>
|
||
/// <returns>提取到的数值(保留两位小数),解析失败时返回 0</returns>
|
||
private static double ExtractDouble(string raw)
|
||
{
|
||
if (string.IsNullOrWhiteSpace(raw)) return 0;
|
||
|
||
// 从响应中提取第一个数值(含正负号、小数点、科学计数法),可自动忽略单位后缀与命令头
|
||
var match = Regex.Match(raw, @"[+-]?(?:\d+\.?\d*|\.\d+)(?:[Ee][+-]?\d+)?");
|
||
return match.Success && double.TryParse(match.Value, NumberStyles.Float, CultureInfo.InvariantCulture, out double val)
|
||
? Math.Round(val, 2)
|
||
: 0;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 从设备返回的 SCPI 响应字符串中提取全部数值并按顺序转换为 double 数组。
|
||
/// 用于解析形如 "1.2,3.4,5.6" 的多值响应(如谐波振幅数组 MEAS:HARM:ARR?)。
|
||
/// 兼容逗号/分号/空格分隔及科学计数法。
|
||
/// </summary>
|
||
/// <param name="raw">设备返回的原始字符串</param>
|
||
/// <returns>按出现顺序排列的数值数组,无有效数值时返回空数组</returns>
|
||
private static double[] ExtractDoubleArray(string raw)
|
||
{
|
||
if (string.IsNullOrWhiteSpace(raw)) return Array.Empty<double>();
|
||
|
||
var values = new List<double>();
|
||
foreach (Match m in Regex.Matches(raw, @"[+-]?(?:\d+\.?\d*|\.\d+)(?:[Ee][+-]?\d+)?"))
|
||
{
|
||
if (double.TryParse(m.Value, NumberStyles.Float, CultureInfo.InvariantCulture, out double v))
|
||
values.Add(v);
|
||
}
|
||
return values.ToArray();
|
||
}
|
||
|
||
#region 1. 基础系统与公共指令
|
||
|
||
/// <summary>
|
||
/// 清除错误队列 (*CLS)
|
||
/// </summary>
|
||
public virtual async Task 清除错误队列Async(CancellationToken ct = default)
|
||
{
|
||
await SendAsync($"*CLS{ScpiDelimiter}", ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 重设仪器为初始状态 (*RST)
|
||
/// </summary>
|
||
public virtual async Task 复位Async(CancellationToken ct = default)
|
||
{
|
||
await SendAsync($"*RST{ScpiDelimiter}", ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 查询仪器识别码 (*IDN?)
|
||
/// </summary>
|
||
public virtual async Task<string> 查询设备信息Async(CancellationToken ct = default)
|
||
{
|
||
return await WriteReadAsync($"*IDN?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 命令流延时 (*D)
|
||
/// <para>在 SCPI 命令流中插入一段延时(单位: ms),常用于 LIST 参数下发完成后、切换 OUTP:MODE 之前等待仪器就绪</para>
|
||
/// </summary>
|
||
/// <param name="milliseconds">延时时长 (ms)</param>
|
||
public virtual async Task 延时Async(double milliseconds, CancellationToken ct = default)
|
||
{
|
||
string valStr = milliseconds.ToString("0.###", CultureInfo.InvariantCulture);
|
||
await SendAsync($"*D {valStr}{ScpiDelimiter}", ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 退出远程状态、回到本地 (SYST:LOC,即 SYSTem:LOCal)
|
||
/// <para>设定后仪器回到 LOCAL 状态,前面板恢复可用。手册注明本命令僅可用於 RS-232 控制之下,
|
||
/// 经 Ethernet/USB 发送时仪器可能不响应</para>
|
||
/// </summary>
|
||
public virtual async Task 退出远程Async(CancellationToken ct = default)
|
||
{
|
||
await SendAsync($"SYST:LOC{ScpiDelimiter}", ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 进入远程状态 (SYST:REM,即 SYSTem:REMote)
|
||
/// <para>设定后除 LOCAL/REMOTE 键外前面板其他键皆无效。手册注明本命令僅可用於 RS-232 控制之下</para>
|
||
/// </summary>
|
||
public virtual async Task 进入远程Async(CancellationToken ct = default)
|
||
{
|
||
await SendAsync($"SYST:REM{ScpiDelimiter}", ct);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 2. 基础输出与耦合控制 (OUTPut 子系统)
|
||
|
||
/// <summary>
|
||
/// 设置输出开关状态 (OUTP ON / OFF)
|
||
/// </summary>
|
||
/// <param name="isOn">true: 开启输出, false: 关闭输出</param>
|
||
public virtual async Task 设置输出开关Async(bool isOn, CancellationToken ct = default)
|
||
{
|
||
string state = isOn ? "ON" : "OFF";
|
||
await SendAsync($"OUTP {state}{ScpiDelimiter}", ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设置输出耦合模式 (OUTP:COUP AC | DC | ACDC)
|
||
/// </summary>
|
||
public virtual async Task 设置耦合模式Async(string couplingMode, CancellationToken ct = default)
|
||
{
|
||
// 有效参数: AC, DC, ACDC
|
||
await SendAsync($"OUTP:COUP {couplingMode}{ScpiDelimiter}", ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设置输出继电器状态 (OUTP:REL ON | OFF)
|
||
/// </summary>
|
||
public virtual async Task 设置输出继电器Async(bool isOn, CancellationToken ct = default)
|
||
{
|
||
string state = isOn ? "ON" : "OFF";
|
||
await SendAsync($"OUTP:REL {state}{ScpiDelimiter}", ct);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 3. 电源核心参数设置 (SOURCE 子系统)
|
||
|
||
/// <summary>
|
||
/// 设置交流电压 (VOLT:AC)
|
||
/// </summary>
|
||
/// <param name="voltage">电压值 (0 ~ 300V 或高压选配范围)</param>
|
||
public virtual async Task 设置交流电压Async(double voltage, CancellationToken ct = default)
|
||
{
|
||
string valStr = voltage.ToString("0.###", CultureInfo.InvariantCulture);
|
||
await SendAsync($"VOLT:AC {valStr}{ScpiDelimiter}", ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设置直流电压 (VOLT:DC)
|
||
/// </summary>
|
||
public virtual async Task 设置直流电压Async(double voltage, CancellationToken ct = default)
|
||
{
|
||
string valStr = voltage.ToString("0.###", CultureInfo.InvariantCulture);
|
||
await SendAsync($"VOLT:DC {valStr}{ScpiDelimiter}", ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设置输出频率 (FREQ)
|
||
/// </summary>
|
||
/// <param name="frequency">频率值 (Hz)</param>
|
||
public virtual async Task 设置频率Async(double frequency, CancellationToken ct = default)
|
||
{
|
||
string valStr = frequency.ToString("0.###", CultureInfo.InvariantCulture);
|
||
await SendAsync($"FREQ {valStr}{ScpiDelimiter}", ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设置波形选择 (FUNC:SHAP:A SINE / SQUA / CSIN 等)
|
||
/// </summary>
|
||
public virtual async Task 设置波形Async(string shape, CancellationToken ct = default)
|
||
{
|
||
await SendAsync($"FUNC:SHAP:A {shape}{ScpiDelimiter}", ct);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 4. 相位与多相模式控制 (INST & PHASE 子系统)
|
||
|
||
/// <summary>
|
||
/// 设置单/三相工作模式 (INST:PHAS THREE / SINGLE)
|
||
/// </summary>
|
||
/// <param name="isThreePhase">true: 三相模式, false: 单相模式</param>
|
||
public virtual async Task 设置单三相模式Async(bool isThreePhase, CancellationToken ct = default)
|
||
{
|
||
string mode = isThreePhase ? "THREE" : "SINGLE";
|
||
await SendAsync($"INST:PHAS {mode}{ScpiDelimiter}", ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设置三相模式下的相互关系 (PHASE:THREE INDEPEND / SAMEFREQ / BALANCE)
|
||
/// </summary>
|
||
public virtual async Task 设置三相关系Async(string relation, CancellationToken ct = default)
|
||
{
|
||
// 有效参数: INDEPEND, SAMEFREQ, BALANCE
|
||
await SendAsync($"PHASE:THREE {relation}{ScpiDelimiter}", ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设置相位耦合模式 (INST:COUP)
|
||
/// <para>ALL: 后续命令发送至所有相位; NONE: 仅发送至 NSEL 选定的相位</para>
|
||
/// </summary>
|
||
/// <param name="coupling">耦合模式: ALL | NONE</param>
|
||
public virtual async Task 设置相位耦合Async(string coupling, CancellationToken ct = default)
|
||
{
|
||
await SendAsync($"INST:COUP {coupling}{ScpiDelimiter}", ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 按编号选择输出相位 (INST:NSEL)
|
||
/// <para>仅在 INST:COUP NONE 时生效,后续 SOURCE 命令将作用于选定相位</para>
|
||
/// </summary>
|
||
/// <param name="phase">相位编号: 1(A相) | 2(B相) | 3(C相)</param>
|
||
public virtual async Task 选择相位Async(int phase, CancellationToken ct = default)
|
||
{
|
||
await SendAsync($"INST:NSEL {phase}{ScpiDelimiter}", ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设置参数编辑方式 (INST:EDIT)
|
||
/// <para>EACH: 逐相独立编辑,配合 <see cref="选择相位Async"/> 分别为 A/B/C 三相下发各自的 LIST/参数;
|
||
/// ALL: 三相统一编辑,一次下发同时作用于三相</para>
|
||
/// </summary>
|
||
/// <param name="mode">编辑方式: EACH | ALL</param>
|
||
public virtual async Task 设置编辑方式Async(string mode, CancellationToken ct = default)
|
||
{
|
||
await SendAsync($"INST:EDIT {mode}{ScpiDelimiter}", ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设置输出开启相位角 (PHASE:ON)
|
||
/// </summary>
|
||
public virtual async Task 设置开机角度Async(double degree, CancellationToken ct = default)
|
||
{
|
||
string valStr = degree.ToString("0.###", CultureInfo.InvariantCulture);
|
||
await SendAsync($"PHASE:ON {valStr}{ScpiDelimiter}", ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设置输出关闭相位角 (PHASE:OFF)
|
||
/// </summary>
|
||
public virtual async Task 设置关机角度Async(double degree, CancellationToken ct = default)
|
||
{
|
||
string valStr = degree.ToString("0.###", CultureInfo.InvariantCulture);
|
||
await SendAsync($"PHASE:OFF {valStr}{ScpiDelimiter}", ct);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 5. 参数测量查询 (MEASure 子系统)
|
||
|
||
/// <summary>
|
||
/// 查询交流电压均方根值 (MEAS:VOLT:AC?)
|
||
/// </summary>
|
||
/// <param name="ct">取消令牌</param>
|
||
/// <returns>交流电压均方根值 (单位: V,保留两位小数)</returns>
|
||
public virtual async Task<double> 读取交流电压Async(CancellationToken ct = default)
|
||
{
|
||
string resp = await WriteReadAsync($"MEAS:VOLT:AC?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||
return ExtractDouble(resp);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 查询交流电流均方根值 (MEAS:CURR:AC?)
|
||
/// </summary>
|
||
/// <param name="ct">取消令牌</param>
|
||
/// <returns>交流电流均方根值 (单位: A,保留两位小数)</returns>
|
||
public virtual async Task<double> 读取交流电流Async(CancellationToken ct = default)
|
||
{
|
||
string resp = await WriteReadAsync($"MEAS:CURR:AC?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||
return ExtractDouble(resp);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 查询输出频率 (MEAS:FREQ?)
|
||
/// </summary>
|
||
/// <param name="ct">取消令牌</param>
|
||
/// <returns>输出频率值 (单位: Hz,保留两位小数)</returns>
|
||
public virtual async Task<double> 读取频率Async(CancellationToken ct = default)
|
||
{
|
||
string resp = await WriteReadAsync($"MEAS:FREQ?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||
return ExtractDouble(resp);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 查询真实输出功率 (MEAS:POW:AC?)
|
||
/// </summary>
|
||
/// <param name="ct">取消令牌</param>
|
||
/// <returns>真实输出功率值 (单位: W,保留两位小数)</returns>
|
||
public virtual async Task<double> 读取真实功率Async(CancellationToken ct = default)
|
||
{
|
||
string resp = await WriteReadAsync($"MEAS:POW:AC?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||
return ExtractDouble(resp);
|
||
}
|
||
|
||
#endregion
|
||
#region 6. LIST 模式子系统 (LIST 子系统)
|
||
|
||
/// <summary>
|
||
/// 设定列表功能的模态 (SOUR:LIST:COUP)
|
||
/// </summary>
|
||
/// <param name="coupling">耦合模态: ALL | NONE</param>
|
||
public virtual async Task 设置列表耦合模态Async(string coupling, CancellationToken ct = default)
|
||
{
|
||
await SendAsync($"SOUR:LIST:COUP {coupling}{ScpiDelimiter}", ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设定列表功能的触发形态 (SOUR:LIST:TRIG)
|
||
/// </summary>
|
||
/// <param name="triggerMode">触发形态: AUTO | MANUAL | EXCITE</param>
|
||
public virtual async Task 设置列表触发形态Async(string triggerMode, CancellationToken ct = default)
|
||
{
|
||
await SendAsync($"SOUR:LIST:TRIG {triggerMode}{ScpiDelimiter}", ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 查询列表功能的有效序列数 (SOUR:LIST:POIN?)
|
||
/// </summary>
|
||
/// <param name="ct">取消令牌</param>
|
||
/// <returns>有效序列数 (0 ~ 100)</returns>
|
||
public virtual async Task<int> 查询列表有效序列数Async(CancellationToken ct = default)
|
||
{
|
||
string resp = await WriteReadAsync($"SOUR:LIST:POIN?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||
return int.TryParse(resp.Trim(), out int val) ? val : 0;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设定列表执行完成前的执行次数 (SOUR:LIST:COUN)
|
||
/// </summary>
|
||
/// <param name="count">执行次数 (0 ~ 65535)</param>
|
||
public virtual async Task 设置列表执行次数Async(int count, CancellationToken ct = default)
|
||
{
|
||
await SendAsync($"SOUR:LIST:COUN {count}{ScpiDelimiter}", ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 查询当前相位上下文的列表执行次数 (SOUR:LIST:COUN?),用于下发后回读校验
|
||
/// </summary>
|
||
/// <returns>执行次数 (0 = 无限循环);解析失败返回 -1</returns>
|
||
public virtual async Task<int> 查询列表执行次数Async(CancellationToken ct = default)
|
||
{
|
||
string resp = await WriteReadAsync($"SOUR:LIST:COUN?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||
return int.TryParse(resp.Trim(), out int val) ? val : -1;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设定列表点的静止时间顺序 (SOUR:LIST:DWEL)
|
||
/// </summary>
|
||
/// <param name="dwellTimes">静止时间序列 (单位: ms,每个值 0 ~ 99999999.9)</param>
|
||
public virtual async Task 设置列表静止时间顺序Async(double[] dwellTimes, CancellationToken ct = default)
|
||
{
|
||
string valStr = string.Join(",", Array.ConvertAll(dwellTimes, v => v.ToString("0.#", CultureInfo.InvariantCulture)));
|
||
await SendAsync($"SOUR:LIST:DWEL {valStr}{ScpiDelimiter}", ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设定波形缓冲区列表点数的顺序 (SOUR:LIST:SHAP)
|
||
/// </summary>
|
||
/// <param name="shapes">波形缓冲区顺序,每个元素为 A 或 B</param>
|
||
public virtual async Task 设置列表波形顺序Async(string[] shapes, CancellationToken ct = default)
|
||
{
|
||
string valStr = string.Join(",", shapes);
|
||
await SendAsync($"SOUR:LIST:SHAP {valStr}{ScpiDelimiter}", ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设定列表的时间基础 (SOUR:LIST:BASE)
|
||
/// </summary>
|
||
/// <param name="timeBase">时间基础: TIME | CYCLE</param>
|
||
public virtual async Task 设置列表时间基础Async(string timeBase, CancellationToken ct = default)
|
||
{
|
||
await SendAsync($"SOUR:LIST:BASE {timeBase}{ScpiDelimiter}", ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设定 AC 起始电压列表点数的顺序 (SOUR:LIST:VOLT:AC:STAR)
|
||
/// </summary>
|
||
/// <param name="voltages">AC 起始电压序列 (单位: V,每个值 0.0 ~ 300.0)</param>
|
||
public virtual async Task 设置列表AC起始电压顺序Async(double[] voltages, CancellationToken ct = default)
|
||
{
|
||
string valStr = string.Join(",", Array.ConvertAll(voltages, v => v.ToString("0.###", CultureInfo.InvariantCulture)));
|
||
await SendAsync($"SOUR:LIST:VOLT:AC:STAR {valStr}{ScpiDelimiter}", ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设定 AC 结束电压列表点数的顺序 (SOUR:LIST:VOLT:AC:END)
|
||
/// </summary>
|
||
/// <param name="voltages">AC 结束电压序列 (单位: V,每个值 0.0 ~ 300.0)</param>
|
||
public virtual async Task 设置列表AC结束电压顺序Async(double[] voltages, CancellationToken ct = default)
|
||
{
|
||
string valStr = string.Join(",", Array.ConvertAll(voltages, v => v.ToString("0.###", CultureInfo.InvariantCulture)));
|
||
await SendAsync($"SOUR:LIST:VOLT:AC:END {valStr}{ScpiDelimiter}", ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设定 DC 起始电压列表点数的顺序 (SOUR:LIST:VOLT:DC:STAR)
|
||
/// </summary>
|
||
/// <param name="voltages">DC 起始电压序列 (单位: V,每个值 -424.2 ~ 414.2)</param>
|
||
public virtual async Task 设置列表DC起始电压顺序Async(double[] voltages, CancellationToken ct = default)
|
||
{
|
||
string valStr = string.Join(",", Array.ConvertAll(voltages, v => v.ToString("0.###", CultureInfo.InvariantCulture)));
|
||
await SendAsync($"SOUR:LIST:VOLT:DC:STAR {valStr}{ScpiDelimiter}", ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设定 DC 结束电压列表点数的顺序 (SOUR:LIST:VOLT:DC:END)
|
||
/// </summary>
|
||
/// <param name="voltages">DC 结束电压序列 (单位: V,每个值 -424.2 ~ 414.2)</param>
|
||
public virtual async Task 设置列表DC结束电压顺序Async(double[] voltages, CancellationToken ct = default)
|
||
{
|
||
string valStr = string.Join(",", Array.ConvertAll(voltages, v => v.ToString("0.###", CultureInfo.InvariantCulture)));
|
||
await SendAsync($"SOUR:LIST:VOLT:DC:END {valStr}{ScpiDelimiter}", ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设定起始频率列表点数的顺序 (SOUR:LIST:FREQ:STAR)
|
||
/// </summary>
|
||
/// <param name="frequencies">起始频率序列 (单位: Hz,每个值 15.00 ~ 100.00)</param>
|
||
public virtual async Task 设置列表起始频率顺序Async(double[] frequencies, CancellationToken ct = default)
|
||
{
|
||
string valStr = string.Join(",", Array.ConvertAll(frequencies, v => v.ToString("0.##", CultureInfo.InvariantCulture)));
|
||
await SendAsync($"SOUR:LIST:FREQ:STAR {valStr}{ScpiDelimiter}", ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设定结束频率列表点数的顺序 (SOUR:LIST:FREQ:END)
|
||
/// </summary>
|
||
/// <param name="frequencies">结束频率序列 (单位: Hz,每个值 15.00 ~ 100.00)</param>
|
||
public virtual async Task 设置列表结束频率顺序Async(double[] frequencies, CancellationToken ct = default)
|
||
{
|
||
string valStr = string.Join(",", Array.ConvertAll(frequencies, v => v.ToString("0.##", CultureInfo.InvariantCulture)));
|
||
await SendAsync($"SOUR:LIST:FREQ:END {valStr}{ScpiDelimiter}", ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设定相位角度列表点数的顺序 (SOUR:LIST:DEGR)
|
||
/// </summary>
|
||
/// <param name="degrees">相位角度序列 (单位: °,每个值 0.0 ~ 359.9)</param>
|
||
public virtual async Task 设置列表相位角度顺序Async(double[] degrees, CancellationToken ct = default)
|
||
{
|
||
string valStr = string.Join(",", Array.ConvertAll(degrees, v => v.ToString("0.#", CultureInfo.InvariantCulture)));
|
||
await SendAsync($"SOUR:LIST:DEGR {valStr}{ScpiDelimiter}", ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设定操作模态 (OUTP:MODE)
|
||
/// </summary>
|
||
/// <param name="mode">操作模态: FIXED | LIST | PULSE | STEP | SYNTH | INTERHAR</param>
|
||
public virtual async Task 设置操作模态Async(string mode, CancellationToken ct = default)
|
||
{
|
||
await SendAsync($"OUTP:MODE {mode}{ScpiDelimiter}", ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 在 LIST 模态下设定执行状态 (TRIG)
|
||
/// <para>需先通过 <see cref="设置操作模态Async"/> 将 OUTP:MODE 设为 LIST</para>
|
||
/// </summary>
|
||
/// <param name="isOn">true: 开始执行 LIST, false: 停止 LIST</param>
|
||
public virtual async Task 触发列表执行Async(bool isOn, CancellationToken ct = default)
|
||
{
|
||
string state = isOn ? "ON" : "OFF";
|
||
await SendAsync($"TRIG {state}{ScpiDelimiter}", ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 查询列表触发执行状态 (TRIG:STATE?)
|
||
/// <para>返回 ON 表示 LIST 正在执行,OFF 表示已执行完毕;
|
||
/// 重新下发 LIST 参数前应先轮询本命令等待其变为 OFF,避免执行中被改写</para>
|
||
/// </summary>
|
||
/// <param name="ct">取消令牌</param>
|
||
/// <returns>true: 正在执行(ON); false: 已结束(OFF)</returns>
|
||
public virtual async Task<bool> 查询触发状态Async(CancellationToken ct = default)
|
||
{
|
||
string resp = await WriteReadAsync($"TRIG:STATE?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||
return resp != null && resp.Trim().StartsWith("ON", StringComparison.OrdinalIgnoreCase);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 7. 谐波量测 (Harmonic Sense 子系统)
|
||
|
||
/// <summary>
|
||
/// 设置谐波分析的测量来源 (CONFigure:HARMonic:SOURce)
|
||
/// </summary>
|
||
/// <param name="source">VOLT: 输出电压; CURR: 输出电流</param>
|
||
public virtual async Task 设置谐波量测源Async(string source, CancellationToken ct = default)
|
||
{
|
||
// 有效参数: VOLT, CURR
|
||
await SendAsync($"CONF:HARM:SOUR {source}{ScpiDelimiter}", ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设置谐波量测结果显示方式 (CONFigure:HARMonic:TIMES)
|
||
/// <para>SINGLE: 保留单次测量结果,约需 3 秒; CONTINUE: 持续更新,约需 10 秒稳定</para>
|
||
/// </summary>
|
||
/// <param name="times">显示方式: SINGLE | CONTINUE</param>
|
||
public virtual async Task 设置谐波量测方式Async(string times, CancellationToken ct = default)
|
||
{
|
||
// 有效参数: SINGLE, CONTINUE
|
||
await SendAsync($"CONF:HARM:TIM {times}{ScpiDelimiter}", ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设置每个谐波阶的数据格式 (CONFigure:HARMonic:PARameter)
|
||
/// </summary>
|
||
/// <param name="parameter">VALUE: 绝对值; PERCENT: 基频百分率</param>
|
||
public virtual async Task 设置谐波数据格式Async(string parameter, CancellationToken ct = default)
|
||
{
|
||
// 有效参数: VALUE, PERCENT
|
||
await SendAsync($"CONF:HARM:PAR {parameter}{ScpiDelimiter}", ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设置谐波分析的原始波形基频 (CONFigure:HARMonic:FREQuency)
|
||
/// </summary>
|
||
/// <param name="frequency">基频: 50 或 60 (Hz)</param>
|
||
public virtual async Task 设置谐波基频Async(int frequency, CancellationToken ct = default)
|
||
{
|
||
await SendAsync($"CONF:HARM:FREQ {frequency}{ScpiDelimiter}", ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 开启/关闭谐波量测 (SENSe:HARMonic)
|
||
/// <para>每次新的 Fetch
|
||
/// ./Measure 前必须先 ON,约需 3 秒得到结果;
|
||
/// 若要量测其他数据,须先设回 OFF。分相量测配合 INST:COUP NONE + INST:NSEL 逐相进行</para>
|
||
/// </summary>
|
||
/// <param name="isOn">true: 开启谐波量测(ON); false: 关闭(OFF)</param>
|
||
public virtual async Task 设置谐波量测开关Async(bool isOn, CancellationToken ct = default)
|
||
{
|
||
string state = isOn ? "ON" : "OFF";
|
||
await SendAsync($"SENS:HARM {state}{ScpiDelimiter}", ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 查询总谐波失真 (MEASure:HARMonic:THD?)
|
||
/// </summary>
|
||
/// <param name="ct">取消令牌</param>
|
||
/// <returns>总谐波失真 THD (单位: %,保留两位小数)</returns>
|
||
public virtual async Task<double> 查询谐波总失真Async(CancellationToken ct = default)
|
||
{
|
||
string resp = await WriteReadAsync($"MEAS:HARM:THD?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||
return ExtractDouble(resp);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 查询输出电压/电流的基频幅值 (MEASure:HARMonic:FUNDamental?)
|
||
/// </summary>
|
||
/// <param name="ct">取消令牌</param>
|
||
/// <returns>基频幅值 (单位依 CONF:HARM:PAR 为 V/A 绝对值或百分率)</returns>
|
||
public virtual async Task<double> 查询谐波基频幅值Async(CancellationToken ct = default)
|
||
{
|
||
string resp = await WriteReadAsync($"MEAS:HARM:FUND?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||
return ExtractDouble(resp);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 查询所有谐波阶的振幅数组 (MEASure:HARMonic:ARRay?)
|
||
/// <para>手册 5.7 谐波测量:可量测 2~50 阶谐波,来源可选输出电压(VOLT)或电流(CURR)。
|
||
/// 注意:仅返回各阶振幅,不含各阶相位角,故据此重构的波形形状为"同相叠加"近似</para>
|
||
/// </summary>
|
||
/// <param name="ct">取消令牌</param>
|
||
/// <returns>各次谐波振幅数组(按阶次升序;单位依 CONF:HARM:PAR)</returns>
|
||
public virtual async Task<double[]> 查询谐波振幅数组Async(CancellationToken ct = default)
|
||
{
|
||
string resp = await WriteReadAsync($"MEAS:HARM:ARR?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||
return ExtractDoubleArray(resp);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 8. SYNTHESIS 波形合成子系统 (SYNThesis 子系统 · 自定义谐波波形输出)
|
||
|
||
/// <summary>
|
||
/// 设定每个谐波阶的数据格式 (SOUR:SYNT:COMP)
|
||
/// <para>VALUE: 绝对值; PERCENT: 基频电压的百分率。后缀 1/2/3 对应三段可编程波形</para>
|
||
/// </summary>
|
||
/// <param name="compose">数据格式: VALUE1 | VALUE2 | VALUE3 | PERCENT1 | PERCENT2 | PERCENT3</param>
|
||
public virtual async Task 设置合成数据格式Async(string compose, CancellationToken ct = default)
|
||
{
|
||
await SendAsync($"SOUR:SYNT:COMP {compose}{ScpiDelimiter}", ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设定每个谐波阶的振幅 (SOUR:SYNT:AMPL)
|
||
/// <para>最大位阶数为 50;各阶取值上限随阶次递减(2~10 阶 0~90.0,11~20 阶 0~60.0,
|
||
/// 21~30 阶 0~30.0,31~40 阶 0~30.0,41~50 阶 0~15.0;PERCENT 格式对应减半)</para>
|
||
/// </summary>
|
||
/// <param name="amplitudes">各次谐波振幅序列(按阶次升序,逗号下发)</param>
|
||
public virtual async Task 设置合成谐波振幅Async(double[] amplitudes, CancellationToken ct = default)
|
||
{
|
||
string valStr = string.Join(",", Array.ConvertAll(amplitudes, v => v.ToString("0.###", CultureInfo.InvariantCulture)));
|
||
await SendAsync($"SOUR:SYNT:AMPL {valStr}{ScpiDelimiter}", ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设定每个谐波阶的相位角 (SOUR:SYNT:PHAS)
|
||
/// </summary>
|
||
/// <param name="phases">各次谐波相位角序列(单位: °,每个值 0.0 ~ 359.9)</param>
|
||
public virtual async Task 设置合成谐波相位Async(double[] phases, CancellationToken ct = default)
|
||
{
|
||
string valStr = string.Join(",", Array.ConvertAll(phases, v => v.ToString("0.#", CultureInfo.InvariantCulture)));
|
||
await SendAsync($"SOUR:SYNT:PHAS {valStr}{ScpiDelimiter}", ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设定 SYNTHESIS 模式的基波交流电压 (SOUR:SYNT:FUND)
|
||
/// </summary>
|
||
/// <param name="voltage">基波交流电压 (单位: V,0.0 ~ 300.0)</param>
|
||
public virtual async Task 设置合成基波电压Async(double voltage, CancellationToken ct = default)
|
||
{
|
||
string valStr = voltage.ToString("0.###", CultureInfo.InvariantCulture);
|
||
await SendAsync($"SOUR:SYNT:FUND {valStr}{ScpiDelimiter}", ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设定叠加于 SYNTHESIS 波形的直流电压 (SOUR:SYNT:DC)
|
||
/// </summary>
|
||
/// <param name="voltage">直流电压 (单位: V,-424.2 ~ 424.2)</param>
|
||
public virtual async Task 设置合成直流电压Async(double voltage, CancellationToken ct = default)
|
||
{
|
||
string valStr = voltage.ToString("0.###", CultureInfo.InvariantCulture);
|
||
await SendAsync($"SOUR:SYNT:DC {valStr}{ScpiDelimiter}", ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设定 SYNTHESIS 模式的基频 (SOUR:SYNT:FREQ)
|
||
/// </summary>
|
||
/// <param name="frequency">基频: 50 或 60 (Hz)</param>
|
||
public virtual async Task 设置合成基频Async(int frequency, CancellationToken ct = default)
|
||
{
|
||
await SendAsync($"SOUR:SYNT:FREQ {frequency}{ScpiDelimiter}", ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设定 SYNTHESIS 模式的起始相位角 (SOUR:SYNT:SPH)
|
||
/// </summary>
|
||
/// <param name="degree">起始相位角 (单位: °,0.0 ~ 359.9)</param>
|
||
public virtual async Task 设置合成起始相位Async(double degree, CancellationToken ct = default)
|
||
{
|
||
string valStr = degree.ToString("0.#", CultureInfo.InvariantCulture);
|
||
await SendAsync($"SOUR:SYNT:SPH {valStr}{ScpiDelimiter}", ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 查询当前合成数据格式 (SOUR:SYNT:COMP?),用于下发后回读校验
|
||
/// </summary>
|
||
/// <returns>VALUE1|2|3 / PERCENT1|2|3</returns>
|
||
public virtual async Task<string> 查询合成数据格式Async(CancellationToken ct = default)
|
||
{
|
||
string resp = await WriteReadAsync($"SOUR:SYNT:COMP?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||
return resp?.Trim() ?? string.Empty;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 查询 SYNTHESIS 基波交流电压 (SOUR:SYNT:FUND?),用于下发后回读校验
|
||
/// </summary>
|
||
public virtual async Task<double> 查询合成基波电压Async(CancellationToken ct = default)
|
||
{
|
||
string resp = await WriteReadAsync($"SOUR:SYNT:FUND?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||
return ExtractDouble(resp);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 查询 SYNTHESIS 基频 (SOUR:SYNT:FREQ?),返回 50 或 60
|
||
/// </summary>
|
||
public virtual async Task<int> 查询合成基频Async(CancellationToken ct = default)
|
||
{
|
||
string resp = await WriteReadAsync($"SOUR:SYNT:FREQ?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||
return (int)ExtractDouble(resp);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 查询 SYNTHESIS 叠加直流电压 (SOUR:SYNT:DC?)
|
||
/// </summary>
|
||
public virtual async Task<double> 查询合成直流电压Async(CancellationToken ct = default)
|
||
{
|
||
string resp = await WriteReadAsync($"SOUR:SYNT:DC?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||
return ExtractDouble(resp);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 查询 SYNTHESIS 起始相位角 (SOUR:SYNT:SPH?)
|
||
/// </summary>
|
||
public virtual async Task<double> 查询合成起始相位Async(CancellationToken ct = default)
|
||
{
|
||
string resp = await WriteReadAsync($"SOUR:SYNT:SPH?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||
return ExtractDouble(resp);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 查询各谐波阶振幅数组 (SOUR:SYNT:AMPL?),首值对应 2 次谐波
|
||
/// </summary>
|
||
public virtual async Task<double[]> 查询合成谐波振幅Async(CancellationToken ct = default)
|
||
{
|
||
string resp = await WriteReadAsync($"SOUR:SYNT:AMPL?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||
return ExtractDoubleArray(resp);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 查询各谐波阶相位角数组 (SOUR:SYNT:PHAS?),首值对应 2 次谐波
|
||
/// </summary>
|
||
public virtual async Task<double[]> 查询合成谐波相位Async(CancellationToken ct = default)
|
||
{
|
||
string resp = await WriteReadAsync($"SOUR:SYNT:PHAS?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||
return ExtractDoubleArray(resp);
|
||
}
|
||
|
||
#endregion
|
||
|
||
}
|
||
} |