更新2026
This commit is contained in:
@@ -9,14 +9,18 @@ namespace TabletTester2025.Services
|
|||||||
Task<bool> CheckConnectionAsync();
|
Task<bool> CheckConnectionAsync();
|
||||||
//从 PLC 的指定起始地址,读取 1 个 32 位浮点型(float)数据。
|
//从 PLC 的指定起始地址,读取 1 个 32 位浮点型(float)数据。
|
||||||
Task<float> ReadFloatAsync(ushort startAddress);
|
Task<float> ReadFloatAsync(ushort startAddress);
|
||||||
//从 PLC 的指定起始地址,读取 1 个 32 位整型(int)数据。
|
//从 PLC 的指定地址,读取 1 个 16 位整型数据。
|
||||||
Task<int> ReadIntAsync(ushort startAddress);
|
Task<int> ReadIntAsync(ushort startAddress);
|
||||||
|
//从 PLC 的指定起始地址,读取 1 个 32 位整型(int)数据。
|
||||||
|
Task<int> ReadInt32Async(ushort startAddress);
|
||||||
//向 PLC 的指定线圈地址,写入一个布尔值(开关量)。
|
//向 PLC 的指定线圈地址,写入一个布尔值(开关量)。
|
||||||
Task WriteCoilAsync(ushort coilAddress, bool value);
|
Task WriteCoilAsync(ushort coilAddress, bool value);
|
||||||
//读取 PLC 指定线圈地址的布尔状态,是 WriteCoilAsync 的配套读取方法。
|
//读取 PLC 指定线圈地址的布尔状态,是 WriteCoilAsync 的配套读取方法。
|
||||||
Task<bool> ReadCoilAsync(ushort coilAddress);
|
Task<bool> ReadCoilAsync(ushort coilAddress);
|
||||||
//向 PLC 的指定寄存器地址,写入 1 个 16 位无符号整型(ushort)数据。
|
//向 PLC 的指定寄存器地址,写入 1 个 16 位无符号整型(ushort)数据。
|
||||||
Task WriteRegisterAsync(ushort registerAddress, ushort value);
|
Task WriteRegisterAsync(ushort registerAddress, ushort value);
|
||||||
|
//向 PLC 的指定起始地址,写入 1 个 32 位整型(int)数据。
|
||||||
|
Task WriteInt32Async(ushort startAddress, int value);
|
||||||
//向 PLC 的指定起始地址,写入 1 个 32 位浮点型(float)数据。
|
//向 PLC 的指定起始地址,写入 1 个 32 位浮点型(float)数据。
|
||||||
Task WriteFloatAsync(ushort startAddress, float value);
|
Task WriteFloatAsync(ushort startAddress, float value);
|
||||||
//批量读取 PLC 的保持寄存器数据,是工业通信中最高效的批量读取方法。
|
//批量读取 PLC 的保持寄存器数据,是工业通信中最高效的批量读取方法。
|
||||||
|
|||||||
@@ -105,6 +105,12 @@ namespace TabletTester2025.Services
|
|||||||
return registers[0];
|
return registers[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<int> ReadInt32Async(ushort startAddress)
|
||||||
|
{
|
||||||
|
var registers = await ReadHoldingRegistersAsync(startAddress, 2);
|
||||||
|
return RegistersToInt32(registers[0], registers[1]);
|
||||||
|
}
|
||||||
|
|
||||||
public Task WriteCoilAsync(ushort coilAddress, bool value)
|
public Task WriteCoilAsync(ushort coilAddress, bool value)
|
||||||
{
|
{
|
||||||
return ExecuteAsync(master => master.WriteSingleCoilAsync(_config.SlaveId, coilAddress, value));
|
return ExecuteAsync(master => master.WriteSingleCoilAsync(_config.SlaveId, coilAddress, value));
|
||||||
@@ -121,6 +127,12 @@ namespace TabletTester2025.Services
|
|||||||
return ExecuteAsync(master => master.WriteSingleRegisterAsync(_config.SlaveId, registerAddress, value));
|
return ExecuteAsync(master => master.WriteSingleRegisterAsync(_config.SlaveId, registerAddress, value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Task WriteInt32Async(ushort startAddress, int value)
|
||||||
|
{
|
||||||
|
ushort[] registers = Int32ToRegisters(value);
|
||||||
|
return ExecuteAsync(master => master.WriteMultipleRegistersAsync(_config.SlaveId, startAddress, registers));
|
||||||
|
}
|
||||||
|
|
||||||
public Task WriteFloatAsync(ushort startAddress, float value)
|
public Task WriteFloatAsync(ushort startAddress, float value)
|
||||||
{
|
{
|
||||||
if (!float.IsFinite(value))
|
if (!float.IsFinite(value))
|
||||||
@@ -178,6 +190,13 @@ namespace TabletTester2025.Services
|
|||||||
: WordsToFloat(secondRegister, firstRegister);
|
: WordsToFloat(secondRegister, firstRegister);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int RegistersToInt32(ushort firstRegister, ushort secondRegister)
|
||||||
|
{
|
||||||
|
return _config.FloatWordOrder == PlcFloatWordOrder.HighWordFirst
|
||||||
|
? WordsToInt32(firstRegister, secondRegister)
|
||||||
|
: WordsToInt32(secondRegister, firstRegister);
|
||||||
|
}
|
||||||
|
|
||||||
private static float WordsToFloat(ushort highWord, ushort lowWord)
|
private static float WordsToFloat(ushort highWord, ushort lowWord)
|
||||||
{
|
{
|
||||||
byte[] bytes =
|
byte[] bytes =
|
||||||
@@ -190,6 +209,11 @@ namespace TabletTester2025.Services
|
|||||||
return BitConverter.ToSingle(bytes, 0);
|
return BitConverter.ToSingle(bytes, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static int WordsToInt32(ushort highWord, ushort lowWord)
|
||||||
|
{
|
||||||
|
return (int)(((uint)highWord << 16) | lowWord);
|
||||||
|
}
|
||||||
|
|
||||||
private ushort[] FloatToRegisters(float value)
|
private ushort[] FloatToRegisters(float value)
|
||||||
{
|
{
|
||||||
byte[] bytes = BitConverter.GetBytes(value);
|
byte[] bytes = BitConverter.GetBytes(value);
|
||||||
@@ -201,6 +225,17 @@ namespace TabletTester2025.Services
|
|||||||
: new[] { lowWord, highWord };
|
: new[] { lowWord, highWord };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ushort[] Int32ToRegisters(int value)
|
||||||
|
{
|
||||||
|
uint raw = unchecked((uint)value);
|
||||||
|
ushort highWord = (ushort)(raw >> 16);
|
||||||
|
ushort lowWord = (ushort)(raw & 0xFFFF);
|
||||||
|
|
||||||
|
return _config.FloatWordOrder == PlcFloatWordOrder.HighWordFirst
|
||||||
|
? new[] { highWord, lowWord }
|
||||||
|
: new[] { lowWord, highWord };
|
||||||
|
}
|
||||||
|
|
||||||
private void CloseConnection()
|
private void CloseConnection()
|
||||||
{
|
{
|
||||||
try { _master?.Dispose(); } catch { }
|
try { _master?.Dispose(); } catch { }
|
||||||
|
|||||||
@@ -45,6 +45,16 @@ namespace TabletTester2025.Services
|
|||||||
return Task.FromResult(value);
|
return Task.FromResult(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Task<int> ReadInt32Async(ushort startAddress)
|
||||||
|
{
|
||||||
|
int value = startAddress switch
|
||||||
|
{
|
||||||
|
400 => 50, // 硬度破损判定
|
||||||
|
_ => _rand.Next(0, 1000)
|
||||||
|
};
|
||||||
|
return Task.FromResult(value);
|
||||||
|
}
|
||||||
|
|
||||||
public Task WriteCoilAsync(ushort coilAddress, bool value) => Task.CompletedTask;
|
public Task WriteCoilAsync(ushort coilAddress, bool value) => Task.CompletedTask;
|
||||||
|
|
||||||
public Task<bool> ReadCoilAsync(ushort coilAddress)
|
public Task<bool> ReadCoilAsync(ushort coilAddress)
|
||||||
@@ -55,6 +65,8 @@ namespace TabletTester2025.Services
|
|||||||
|
|
||||||
public Task WriteRegisterAsync(ushort registerAddress, ushort value) => Task.CompletedTask;
|
public Task WriteRegisterAsync(ushort registerAddress, ushort value) => Task.CompletedTask;
|
||||||
|
|
||||||
|
public Task WriteInt32Async(ushort startAddress, int value) => Task.CompletedTask;
|
||||||
|
|
||||||
public Task WriteFloatAsync(ushort startAddress, float value) => Task.CompletedTask;
|
public Task WriteFloatAsync(ushort startAddress, float value) => Task.CompletedTask;
|
||||||
|
|
||||||
public Task<ushort[]> ReadHoldingRegistersAsync(ushort startAddress, ushort count)
|
public Task<ushort[]> ReadHoldingRegistersAsync(ushort startAddress, ushort count)
|
||||||
|
|||||||
@@ -409,12 +409,14 @@ namespace TabletTester2025.ViewModels
|
|||||||
|
|
||||||
public async Task UpdateRealTimeData()
|
public async Task UpdateRealTimeData()
|
||||||
{
|
{
|
||||||
if (!IsAnyTestRunning()) return;
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
await LoadMediumTemperatureAsync();
|
||||||
|
|
||||||
|
if (!IsAnyTestRunning()) return;
|
||||||
|
|
||||||
if (_isDisintegrationRunning)
|
if (_isDisintegrationRunning)
|
||||||
{
|
{
|
||||||
DisintegrationTemp = await _plc.ReadFloatAsync(_plcConfig.DisintegrationTemp);
|
|
||||||
IsBasketMovingUp = await _plc.ReadCoilAsync(_plcConfig.DisintegrationMovingUpCoil);
|
IsBasketMovingUp = await _plc.ReadCoilAsync(_plcConfig.DisintegrationMovingUpCoil);
|
||||||
for (int i = 0; i < _plcConfig.DisintegrationCompleteCoils.Length; i++)
|
for (int i = 0; i < _plcConfig.DisintegrationCompleteCoils.Length; i++)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -210,7 +210,7 @@ namespace TabletTester2025
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
int value = await App.PlcService.ReadIntAsync(registerAddress);
|
int value = await App.PlcService.ReadInt32Async(registerAddress);
|
||||||
if (value >= 0)
|
if (value >= 0)
|
||||||
HardnessDamageThresholdBox.Text = value.ToString();
|
HardnessDamageThresholdBox.Text = value.ToString();
|
||||||
}
|
}
|
||||||
@@ -226,7 +226,7 @@ namespace TabletTester2025
|
|||||||
if (registerAddress == 0)
|
if (registerAddress == 0)
|
||||||
throw new InvalidOperationException("硬度破损判定PLC寄存器地址未配置。");
|
throw new InvalidOperationException("硬度破损判定PLC寄存器地址未配置。");
|
||||||
|
|
||||||
await App.PlcService.WriteRegisterAsync(registerAddress, (ushort)Math.Clamp(value, 0, ushort.MaxValue));
|
await App.PlcService.WriteInt32Async(registerAddress, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ushort ResolveHardnessDamageThresholdRegister()
|
private static ushort ResolveHardnessDamageThresholdRegister()
|
||||||
|
|||||||
Reference in New Issue
Block a user