259 lines
10 KiB
C#
259 lines
10 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.Devices
|
||
{
|
||
[ACPCommand]
|
||
public class SPAW7000 : Tcp
|
||
{
|
||
//只有两个,八台产品公用两两分组各用一个
|
||
// 根据通用 SCPI 与远宽指令规范,使用换行符 (ASCII 字符 LF,即 \n) 作为标准结束符
|
||
private const string ScpiDelimiter = "\n";
|
||
|
||
/// <summary>
|
||
/// 构造函数:传入 <see cref="TcpConfig"/> 一次性初始化 SPAW7000 功率分析记录仪通信参数。
|
||
/// </summary>
|
||
public SPAW7000(TcpConfig config) : base(config)
|
||
{
|
||
}
|
||
|
||
#region 1. IEEE 488.2 公共命令
|
||
|
||
/// <summary>
|
||
/// 清除状态命令。清除标准事件状态寄存器和错误队列
|
||
/// </summary>
|
||
public virtual async Task 清除错误队列和状态字节(CancellationToken ct = default)
|
||
{
|
||
await SendAsync($"*CLS{ScpiDelimiter}", ct);
|
||
}
|
||
/// <summary>
|
||
/// 查询错误信息 发hsl居然可以但是手册上没有而且软件上也用不了这个命令
|
||
/// </summary>
|
||
//public virtual async Task<string> 查询错误信息(CancellationToken ct = default)
|
||
//{
|
||
// string query = string.Format(":SYSTem:ERRor?", ScpiDelimiter);
|
||
// return await WriteReadAsync(query, ScpiDelimiter, ct);
|
||
//}
|
||
/// <summary>
|
||
/// 读取功率分析仪识别字符串(制造商、产品型号、系统 SN、软件版本号)
|
||
/// </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>
|
||
/// 读取标准状态字节寄存器
|
||
/// </summary>
|
||
public virtual async Task<string> 读取状态字节(CancellationToken ct = default)
|
||
{
|
||
return await WriteReadAsync($"*STB?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 2. NUMeric 核心数据测量与轮询 (动态单项读取)
|
||
|
||
/// <summary>
|
||
/// 查询指定通道的实时 RMS 电压值 (单位: V)
|
||
/// </summary>
|
||
public virtual async Task<string> 查询实际电压(int channel, CancellationToken ct = default)
|
||
{
|
||
// 1. 先配置 ITEM1 为指定通道的电压有效值 (URMS)
|
||
string setItem = string.Format(CultureInfo.InvariantCulture, ":NUMeric:NORMal:ITEM1 URMS,{0}{1}", channel, ScpiDelimiter);
|
||
await SendAsync(setItem, ct);
|
||
|
||
// 2. 再读取 ITEM1 的值
|
||
string query = string.Format(CultureInfo.InvariantCulture, ":NUMeric:NORMal:VALue? 1{0}", ScpiDelimiter);
|
||
return await WriteReadAsync(query, ScpiDelimiter, ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 查询指定通道的实时 RMS 电流值 (单位: A)
|
||
/// </summary>
|
||
public virtual async Task<string> 查询实际电流(int channel, CancellationToken ct = default)
|
||
{
|
||
// 1. 配置 ITEM1 为指定通道的电流有效值 (IRMS)
|
||
string setItem = string.Format(CultureInfo.InvariantCulture, ":NUMeric:NORMal:ITEM1 IRMS,{0}{1}", channel, ScpiDelimiter);
|
||
await SendAsync(setItem, ct);
|
||
|
||
// 2. 读取 ITEM1 的值
|
||
string query = string.Format(CultureInfo.InvariantCulture, ":NUMeric:NORMal:VALue? 1{0}", ScpiDelimiter);
|
||
return await WriteReadAsync(query, ScpiDelimiter, ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 查询指定通道的实时有功功率值 (单位: W)
|
||
/// </summary>
|
||
public virtual async Task<string> 查询实际功率(int channel, CancellationToken ct = default)
|
||
{
|
||
// 1. 配置 ITEM1 为指定通道的有功功率 (P)
|
||
string setItem = string.Format(CultureInfo.InvariantCulture, ":NUMeric:NORMal:ITEM1 P,{0}{1}", channel, ScpiDelimiter);
|
||
await SendAsync(setItem, ct);
|
||
|
||
// 2. 读取 ITEM1 的值
|
||
string query = string.Format(CultureInfo.InvariantCulture, ":NUMeric:NORMal:VALue? 1{0}", ScpiDelimiter);
|
||
return await WriteReadAsync(query, ScpiDelimiter, ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 查询指定通道的实时频率值 (单位: Hz)
|
||
/// </summary>
|
||
public virtual async Task<string> 查询频率(int channel, CancellationToken ct = default)
|
||
{
|
||
// 1. 配置 ITEM1 为指定通道的电压频率 (FU)
|
||
string setItem = string.Format(CultureInfo.InvariantCulture, ":NUMeric:NORMal:ITEM1 FU,{0}{1}", channel, ScpiDelimiter);
|
||
await SendAsync(setItem, ct);
|
||
|
||
// 2. 读取 ITEM1 的值
|
||
string query = string.Format(CultureInfo.InvariantCulture, ":NUMeric:NORMal:VALue? 1{0}", ScpiDelimiter);
|
||
return await WriteReadAsync(query, ScpiDelimiter, ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 查询指定通道的功率因数 (Power Factor)
|
||
/// </summary>
|
||
public virtual async Task<string> 查询功率因数(int channel, CancellationToken ct = default)
|
||
{
|
||
// 1. 配置 ITEM1 为指定通道的功率因数 (LAMBda)
|
||
string setItem = string.Format(CultureInfo.InvariantCulture, ":NUMeric:NORMal:ITEM1 LAMBda,{0}{1}", channel, ScpiDelimiter);
|
||
await SendAsync(setItem, ct);
|
||
|
||
// 2. 读取 ITEM1 的值
|
||
string query = string.Format(CultureInfo.InvariantCulture, ":NUMeric:NORMal:VALue? 1{0}", ScpiDelimiter);
|
||
return await WriteReadAsync(query, ScpiDelimiter, ct);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 3. INPut 通道电气参数配置
|
||
/// <summary>
|
||
/// SPAW7000 电压量程枚举 (单位: V)
|
||
/// </summary>
|
||
public enum VoltageRange
|
||
{
|
||
V_15 = 15,
|
||
V_30 = 30,
|
||
V_60 = 60,
|
||
V_100 = 100,
|
||
V_150 = 150,
|
||
V_300 = 300,
|
||
V_600 = 600,
|
||
V_1000 = 1000
|
||
}
|
||
|
||
/// <summary>
|
||
/// SPAW7000 电流量程枚举 (单位: A)
|
||
/// </summary>
|
||
public enum CurrentRange
|
||
{
|
||
A_1 = 1,
|
||
A_2 = 2,
|
||
A_5 = 5,
|
||
A_10 = 10,
|
||
A_20 = 20,
|
||
A_50 = 50
|
||
}
|
||
/// <summary>
|
||
/// 设置指定通道的电压量程
|
||
/// </summary>
|
||
/// <param name="channel">通道号/单元号 (1 - 7)</param>
|
||
/// <param name="range">电压量程枚举</param>
|
||
/// <param name="ct">取消令牌</param>
|
||
public virtual async Task 设置电压量程(int channel, VoltageRange range, CancellationToken ct = default)
|
||
{
|
||
// 正确格式例如: :INPut:VOLTage:RANGe:ELEMent1 300\n
|
||
string cmd = string.Format(CultureInfo.InvariantCulture,
|
||
":INPut:VOLTage:RANGe:ELEMent{0} {1}{2}",
|
||
channel, (int)range, ScpiDelimiter);
|
||
|
||
await SendAsync(cmd, ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设置指定通道的电流量程
|
||
/// </summary>
|
||
/// <param name="channel">通道号/单元号 (1 - 7)</param>
|
||
/// <param name="range">电流量程枚举</param>
|
||
/// <param name="ct">取消令牌</param>
|
||
public virtual async Task 设置电流量程(int channel, CurrentRange range, CancellationToken ct = default)
|
||
{
|
||
// 正确格式例如: :INPut:CURRent:RANGe:ELEMent1 5\n
|
||
string cmd = string.Format(CultureInfo.InvariantCulture,
|
||
":INPut:CURRent:RANGe:ELEMent{0} {1}{2}",
|
||
channel, (int)range, ScpiDelimiter);
|
||
|
||
await SendAsync(cmd, ct);
|
||
}
|
||
#endregion
|
||
|
||
#region 4. SYSTem 系统设置与状态查询
|
||
/// <summary>
|
||
/// 14. 查询仪器型号名称
|
||
/// </summary>
|
||
public virtual async Task<string> 查询设备型号(CancellationToken ct = default)
|
||
{
|
||
return await WriteReadAsync($":SYSTem:MODel?{ScpiDelimiter}", ScpiDelimiter, ct); //
|
||
}
|
||
|
||
/// <summary>
|
||
/// 16. 查询仪器唯一序列号
|
||
/// </summary>
|
||
public virtual async Task<string> 查询设备序列号(CancellationToken ct = default)
|
||
{
|
||
return await WriteReadAsync($":SYSTem:SERial?{ScpiDelimiter}", ScpiDelimiter, ct); //
|
||
}
|
||
|
||
/// <summary>
|
||
/// 15. 设置数值数据显示的分辨率 (5位或6位)
|
||
/// </summary>
|
||
/// <param name="resolution">有效值只能为 5 或 6</param>
|
||
public virtual async Task 设置显示分辨率(int resolution, CancellationToken ct = default)
|
||
{
|
||
if (resolution != 5 && resolution != 6) throw new ArgumentException("分辨率只能设置为 5 或 6 位");
|
||
await SendAsync($":SYSTem:RESolution {resolution}{ScpiDelimiter}", ct); //
|
||
}
|
||
|
||
/// <summary>
|
||
/// 13. 设置或查询屏幕 LCD 的亮度级别 (1-10)
|
||
/// </summary>
|
||
public virtual async Task 设置显示亮度(int brightness, CancellationToken ct = default)
|
||
{
|
||
if (brightness < 1 || brightness > 10) throw new ArgumentOutOfRangeException(nameof(brightness), "亮度范围必须在 1~10 之间");
|
||
await SendAsync($":SYSTem:LCD:BRIGhtness {brightness}{ScpiDelimiter}", ct); //
|
||
}
|
||
|
||
/// <summary>
|
||
/// 18. 设置或查询触摸锁的开/关状态 (锁定时防止人工误触触控屏)
|
||
/// </summary>
|
||
public virtual async Task 设置屏幕触摸锁定(bool isLocked, CancellationToken ct = default)
|
||
{
|
||
string state = isLocked ? "ON" : "OFF";
|
||
await SendAsync($":SYSTem:TLOCK {state}{ScpiDelimiter}", ct); //
|
||
}
|
||
|
||
/// <summary>
|
||
/// 17. 设置或读取分析仪当前的系统内部时间
|
||
/// </summary>
|
||
/// <param name="timeStr">格式必须为 "HH:MM:SS"</param>
|
||
public virtual async Task 设置系统时间(string timeStr, CancellationToken ct = default)
|
||
{
|
||
await SendAsync($":SYSTem:TIME \"{timeStr}\"{ScpiDelimiter}", ct); //
|
||
}
|
||
|
||
#endregion
|
||
}
|
||
} |