Files
ASTM-D7896-19TransientHot-W…/Services/FiveHalfDmmService.cs
2026-05-23 21:18:46 +08:00

160 lines
5.2 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 System;
using System.IO.Ports;
using System.Threading.Tasks;
using System.Linq;
namespace ASTM_D7896_Tester.Services
{
public class FiveHalfDmmService : IDisposable
{
private SerialPort _serialPort;
private bool _disposed;
public FiveHalfDmmService(string portName, int baudRate = 115200)
{
_serialPort = new SerialPort(portName, baudRate, Parity.None, 8, StopBits.One);
_serialPort.ReadTimeout = 2000;
_serialPort.WriteTimeout = 1000;
_serialPort.NewLine = "\n";
}
public void Open()
{
if (!_serialPort.IsOpen)
_serialPort.Open();
}
public void Close()
{
if (_serialPort.IsOpen)
_serialPort.Close();
}
public bool IsOpen => _serialPort?.IsOpen == true;
/// <summary>
/// 发送命令并等待响应同步读写但因在Task.Run中执行不阻塞UI
/// </summary>
private async Task<string> QueryAsync(string command)
{
if (!_serialPort.IsOpen) throw new InvalidOperationException("串口未打开");
return await Task.Run(() =>
{
lock (_serialPort)
{
// 清空缓冲区
_serialPort.DiscardInBuffer();
_serialPort.DiscardOutBuffer();
_serialPort.WriteLine(command);
System.Diagnostics.Debug.WriteLine($"[发送] {command}");
string response = _serialPort.ReadLine();
System.Diagnostics.Debug.WriteLine($"[接收] {response}");
return response.Trim();
}
});
}
public string TestCommunication()
{
if (!_serialPort.IsOpen) throw new InvalidOperationException("串口未打开");
_serialPort.DiscardInBuffer();
_serialPort.WriteLine("*IDN?");
return _serialPort.ReadLine().Trim();
}
private async Task SendCommandAsync(string command)
{
if (!_serialPort.IsOpen) throw new InvalidOperationException("串口未打开");
await Task.Run(() =>
{
lock (_serialPort)
{
_serialPort.WriteLine(command);
}
});
}
/// <summary>
/// 配置为高速直流电压测量根据8255文档
/// </summary>
public async Task ConfigureHighSpeedDcvAsync()
{
// 配置直流电压,自动量程
await SendCommandAsync("CONFigure:VOLTage:DC AUTO");
// 设置精度为FAST高速模式
await SendCommandAsync("SENSe:VOLTage:DC:RESolution FAST");
// 使用软件触发
await SendCommandAsync("TRIGger:SOURce BUS");
// 关闭自动延迟
await SendCommandAsync("TRIGger:DELay:AUTO OFF");
await SendCommandAsync("TRIGger:DELay 0");
}
/// <summary>
/// 预置采样点数并进入等待触发状态
/// </summary>
public async Task PrepareBatchAsync(int sampleCount)
{
await SendCommandAsync($"SAMPle:COUNt {sampleCount}");
await SendCommandAsync("INITiate");
}
/// <summary>
/// 发送软件触发信号
/// </summary>
public async Task TriggerAsync()
{
await SendCommandAsync("*TRG");
}
/// <summary>
/// 获取批量采集结果
/// </summary>
public async Task<double[]> FetchBatchAsync()
{
string response = await QueryAsync("FETCh?");
if (string.IsNullOrWhiteSpace(response))
throw new Exception("FETCh? 返回空响应");
// 文档示例返回值如 "+1.234500E-02,+2.345600E-02"
string[] parts = response.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
double[] values = new double[parts.Length];
for (int i = 0; i < parts.Length; i++)
{
string valStr = parts[i].Trim();
if (!double.TryParse(valStr, System.Globalization.NumberStyles.Float,
System.Globalization.CultureInfo.InvariantCulture, out values[i]))
{
throw new Exception($"解析失败: {valStr},原始响应: {response}");
}
}
return values;
}
/// <summary>
/// 单次读取电压
/// </summary>
public async Task<double> ReadVoltageAsync()
{
string resp = await QueryAsync("MEASure:VOLTage:DC?");
if (double.TryParse(resp, System.Globalization.NumberStyles.Float,
System.Globalization.CultureInfo.InvariantCulture, out double value))
return value;
throw new Exception($"无效响应: {resp}");
}
public void Dispose()
{
if (!_disposed)
{
Close();
_serialPort?.Dispose();
_disposed = true;
}
}
}
}