添加项目文件。
This commit is contained in:
114
Service/ModbusTcpPlcService.cs
Normal file
114
Service/ModbusTcpPlcService.cs
Normal file
@@ -0,0 +1,114 @@
|
||||
using System;
|
||||
using System.Net.Sockets;
|
||||
using System.Threading.Tasks;
|
||||
using Modbus.Device;
|
||||
|
||||
namespace MembranePoreTester.Communication
|
||||
{
|
||||
public class ModbusTcpPlcService : IPlcService, IDisposable
|
||||
{
|
||||
private readonly PlcConfiguration _config;
|
||||
private TcpClient _tcpClient;
|
||||
private IModbusMaster _master;
|
||||
|
||||
public ModbusTcpPlcService(PlcConfiguration config)
|
||||
{
|
||||
_config = config;
|
||||
}
|
||||
|
||||
private async Task EnsureConnectedAsync()
|
||||
{
|
||||
if (_tcpClient == null || !_tcpClient.Connected)
|
||||
{
|
||||
_tcpClient = new TcpClient();
|
||||
await _tcpClient.ConnectAsync(_config.IpAddress, _config.Port);
|
||||
_master = ModbusIpMaster.CreateIp(_tcpClient);
|
||||
}
|
||||
}
|
||||
|
||||
// 读取两个连续的保持寄存器,转换为32位浮点数(假设大端模式)
|
||||
private async Task<float> ReadFloatAsync(ushort startAddress)
|
||||
{
|
||||
await EnsureConnectedAsync();
|
||||
|
||||
// 读取两个寄存器(从站地址由配置指定)
|
||||
ushort[] registers = await _master.ReadHoldingRegistersAsync(_config.SlaveId, startAddress, 2);
|
||||
|
||||
// 将两个16位寄存器合并为32位浮点数(大端)
|
||||
byte[] bytes = new byte[4];
|
||||
bytes[0] = (byte)(registers[0] >> 8);
|
||||
bytes[1] = (byte)(registers[0] & 0xFF);
|
||||
bytes[2] = (byte)(registers[1] >> 8);
|
||||
bytes[3] = (byte)(registers[1] & 0xFF);
|
||||
|
||||
if (BitConverter.IsLittleEndian)
|
||||
Array.Reverse(bytes); // 如果系统是小端,需要反转字节顺序
|
||||
|
||||
return BitConverter.ToSingle(bytes, 0);
|
||||
}
|
||||
|
||||
public async Task<float> ReadPressureAsync() =>
|
||||
await ReadFloatAsync(_config.PressureRegister) * (float)_config.PressureFactor;
|
||||
|
||||
public async Task<float> ReadWetFlowAsync() =>
|
||||
await ReadFloatAsync(_config.WetFlowRegister) * (float)_config.WetFlowFactor;
|
||||
|
||||
public async Task<float> ReadDryFlowAsync() =>
|
||||
await ReadFloatAsync(_config.DryFlowRegister) * (float)_config.DryFlowFactor;
|
||||
|
||||
|
||||
public async Task WriteCoilAsync(ushort coilAddress, bool value)
|
||||
{
|
||||
await EnsureConnectedAsync();
|
||||
await _master.WriteSingleCoilAsync(_config.SlaveId, coilAddress, value);
|
||||
}
|
||||
|
||||
public async Task WriteRegisterAsync(ushort registerAddress, ushort value)
|
||||
{
|
||||
await EnsureConnectedAsync();
|
||||
await _master.WriteSingleRegisterAsync(_config.SlaveId, registerAddress, value);
|
||||
}
|
||||
|
||||
|
||||
public async Task<bool> ReadCoilAsync(ushort coilAddress)
|
||||
{
|
||||
await EnsureConnectedAsync();
|
||||
bool[] result = await _master.ReadCoilsAsync(_config.SlaveId, coilAddress, 1);
|
||||
return result[0];
|
||||
}
|
||||
|
||||
|
||||
public async Task<ushort[]> ReadHoldingRegistersAsync(ushort startAddress, ushort count)
|
||||
{
|
||||
await EnsureConnectedAsync();
|
||||
return await _master.ReadHoldingRegistersAsync(_config.SlaveId, startAddress, count);
|
||||
}
|
||||
|
||||
public async Task WriteSingleRegisterAsync(ushort registerAddress, ushort value)
|
||||
{
|
||||
await EnsureConnectedAsync();
|
||||
await _master.WriteSingleRegisterAsync(_config.SlaveId, registerAddress, value);
|
||||
}
|
||||
|
||||
|
||||
// 新增读取压力(根据工位)
|
||||
public async Task<float> ReadPressureAsync(int stationId)
|
||||
{
|
||||
ushort startAddress = stationId switch
|
||||
{
|
||||
1 => _config.PressureRegisterStation1,
|
||||
2 => _config.PressureRegisterStation2,
|
||||
3 => _config.PressureRegisterStation3,
|
||||
_ => throw new ArgumentException("Invalid station")
|
||||
};
|
||||
return await ReadFloatAsync(startAddress);
|
||||
}
|
||||
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_master?.Dispose();
|
||||
_tcpClient?.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user