Files
ACP/DeviceCommand/Devices/Chroma61800.cs
2026-08-04 11:37:26 +08:00

207 lines
7.9 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using Common.Attributes;
using DeviceCommand.Base;
using Model.Models;
using System;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace DeviceCommand.Devices
{
/// <summary>
/// 交流源 一拖三
/// </summary>
[ACPCommand]
public class Chroma61800 : Tcp
{
// Chroma SCPI 默认使用 \n 作为结束符
private const string ScpiDelimiter = "\n";
public Chroma61800(TcpConfig config) : base(config)
{
}
#region 1.
public virtual async Task (CancellationToken ct = default)
{
await SendAsync($"*CLS{ScpiDelimiter}", ct);
}
#endregion
#region 2. LIST
/// <summary>
/// 初始化 LIST 模式的三相独立编辑环境
/// </summary>
/// <param name="loopCount">循环次数0代表无限循环</param>
public virtual async Task List模式(int loopCount = 0, CancellationToken ct = default)
{
await SendAsync($"INST:PHAS THRE{ScpiDelimiter}", ct); // 选择三相模式
await SendAsync($"INST:EDIT EACH{ScpiDelimiter}", ct); // 选择编辑电压方式为分别编辑
await SendAsync($"LIST:COUN {loopCount}{ScpiDelimiter}", ct); // 循环次数设定
await SendAsync($"LIST:TRIG AUTO{ScpiDelimiter}", ct); // 设定触发方式
await SendAsync($"LIST:BASE TIME{ScpiDelimiter}", ct); // 选择执行时间类别
}
#endregion
#region 3. LIST ( - )
/// <summary>
/// 切换目标相位并设置波形为正弦波
/// 建议在发送具体 LIST 参数前调用一次即可
/// </summary>
/// <param name="phase">相位 (1: L1, 2: L2, 3: L3)</param>
public virtual async Task Async(int phase, CancellationToken ct = default)
{
if (phase < 1 || phase > 3)
throw new ArgumentOutOfRangeException(nameof(phase), "相位必须为 1, 2, 或 3");
await SendAsync($"INST:NSEL {phase}{ScpiDelimiter}", ct);
await SendAsync($"FUNC:SHAP:A SINE{ScpiDelimiter}", ct);
}
/// <summary>
/// 配置 LIST 各步起始角度
/// </summary>
public virtual async Task List起始角度Async(double step1, double step2, double step3, CancellationToken ct = default)
{
string strValues = JoinParameters(step1, step2, step3);
await SendAsync($"LIST:DEGR {strValues}{ScpiDelimiter}", ct);
}
/// <summary>
/// 配置 LIST 各步交流起始电压
/// </summary>
public virtual async Task List交流起始电压Async(double step1, double step2, double step3, CancellationToken ct = default)
{
string strValues = JoinParameters(step1, step2, step3);
await SendAsync($"LIST:VOLT:AC:STAR {strValues}{ScpiDelimiter}", ct);
}
/// <summary>
/// 配置 LIST 各步交流结束电压
/// </summary>
public virtual async Task List交流结束电压Async(double step1, double step2, double step3, CancellationToken ct = default)
{
string strValues = JoinParameters(step1, step2, step3);
await SendAsync($"LIST:VOLT:AC:END {strValues}{ScpiDelimiter}", ct);
}
/// <summary>
/// 配置 LIST 各步直流起始电压
/// </summary>
public virtual async Task List直流起始电压Async(double step1, double step2, double step3, CancellationToken ct = default)
{
string strValues = JoinParameters(step1, step2, step3);
await SendAsync($"LIST:VOLT:DC:STAR {strValues}{ScpiDelimiter}", ct);
}
/// <summary>
/// 配置 LIST 各步直流结束电压
/// </summary>
public virtual async Task List直流结束电压Async(double step1, double step2, double step3, CancellationToken ct = default)
{
string strValues = JoinParameters(step1, step2, step3);
await SendAsync($"LIST:VOLT:DC:END {strValues}{ScpiDelimiter}", ct);
}
/// <summary>
/// 配置 LIST 各步起始频率
/// </summary>
public virtual async Task List起始频率Async(double step1, double step2, double step3, CancellationToken ct = default)
{
string strValues = JoinParameters(step1, step2, step3);
await SendAsync($"LIST:FREQ:STAR {strValues}{ScpiDelimiter}", ct);
}
/// <summary>
/// 配置 LIST 各步结束频率
/// </summary>
public virtual async Task List结束频率Async(double step1, double step2, double step3, CancellationToken ct = default)
{
string strValues = JoinParameters(step1, step2, step3);
await SendAsync($"LIST:FREQ:END {strValues}{ScpiDelimiter}", ct);
}
/// <summary>
/// 配置 LIST 各步执行时间 (单位: 毫秒)
/// </summary>
public virtual async Task List执行时间Async(double step1, double step2, double step3, CancellationToken ct = default)
{
string strValues = JoinParameters(step1, step2, step3);
await SendAsync($"LIST:DWEL {strValues}{ScpiDelimiter}", ct);
}
/// <summary>
/// 辅助方法:将三个 double 值转换为逗号分隔的字符串,确保小数点格式正确
/// </summary>
private string JoinParameters(double val1, double val2, double val3)
{
return $"{val1.ToString("0.###", CultureInfo.InvariantCulture)}," +
$"{val2.ToString("0.###", CultureInfo.InvariantCulture)}," +
$"{val3.ToString("0.###", CultureInfo.InvariantCulture)}";
}
#endregion
#region 4. LIST
/// <summary>
/// 切换到 LIST 模式并触发输出
/// </summary>
public virtual async Task List输出(CancellationToken ct = default)
{
await SendAsync($"OUTP:MODE LIST{ScpiDelimiter}", ct);
await SendAsync($"TRIG ON{ScpiDelimiter}", ct);
}
/// <summary>
/// 查询 LIST 序列是否正在运行
/// </summary>
public virtual async Task<bool> List是否运行中(CancellationToken ct = default)
{
string state = await WriteReadAsync($"TRIG:STATE?{ScpiDelimiter}", ScpiDelimiter, ct);
state = state?.Trim().ToUpper();
return state == "ON" || state == "1";
}
/// <summary>
/// 阻塞异步等待直到 LIST 序列执行完毕 (带安全超时保护)
/// </summary>
/// <param name="timeoutMs">最大等待超时时间建议比实际LIST总时长多5-10秒</param>
public virtual async Task List执行结束(int timeoutMs = 60000, CancellationToken ct = default)
{
// 给仪器留出响应触发的时间
await Task.Delay(500, ct);
Stopwatch sw = Stopwatch.StartNew();
bool isRunning = true;
while (isRunning)
{
ct.ThrowIfCancellationRequested();
if (sw.ElapsedMilliseconds > timeoutMs)
{
throw new TimeoutException($"等待 LIST 执行结束超时 ({timeoutMs} ms)。");
}
// 读取当前状态
isRunning = await List是否运行中(ct);
if (isRunning)
{
// 还在运行,适当休眠后继续轮询,避免总线阻塞
await Task.Delay(500, ct);
}
}
}
#endregion
}
}