Files
2025-08-26 08:37:44 +08:00

132 lines
4.6 KiB
C#

using MES.Utility.Core;
using System;
using System.Linq;
namespace SharpModbus
{
public class ModbusMaster : IDisposable
{
public delegate void OnSendedData(byte[] bytes, string hexString);
public event OnSendedData OnSended;
public delegate void OnRecivedData(byte[] bytes, string hexString);
public event OnRecivedData OnRecived;
public static ModbusMaster RTU(SerialSettings settings, int timeout = 400)
{
var stream = new ModbusSerialStream(settings, timeout);
var protocol = new ModbusRTUProtocol();
return new ModbusMaster(stream, protocol);
}
public static ModbusMaster IsolatedRTU(SerialSettings settings, int timeout = 400)
{
var stream = new ModbusIsolatedStream(settings, timeout);
var protocol = new ModbusRTUProtocol();
return new ModbusMaster(stream, protocol);
}
public static ModbusMaster TCP(string ip, int port, int timeout = 400)
{
var socket = Tools.ConnectWithTimeout(ip, port, timeout);
var stream = new ModbusSocketStream(socket, timeout);
var protocol = new ModbusTCPProtocol();
return new ModbusMaster(stream, protocol);
}
private readonly IModbusProtocol protocol;
private readonly IModbusStream stream;
public ModbusMaster(IModbusStream stream, IModbusProtocol protocol)
{
this.stream = stream;
this.protocol = protocol;
}
public void Dispose()
{
Tools.Dispose(stream);
}
public bool ReadCoil(byte slave, ushort address)
{
return ReadCoils(slave, address, 1)[0]; //there is no code for single read
}
public bool ReadInput(byte slave, ushort address)
{
return ReadInputs(slave, address, 1)[0]; //there is no code for single read
}
public ushort ReadInputRegister(byte slave, ushort address)
{
return ReadInputRegisters(slave, address, 1)[0]; //there is no code for single read
}
public ushort ReadHoldingRegister(byte slave, ushort address)
{
return ReadHoldingRegisters(slave, address, 1)[0]; //there is no code for single read
}
public bool[] ReadCoils(byte slave, ushort address, ushort count)
{
return Execute(new ModbusF01ReadCoils(slave, address, count)) as bool[];
}
public bool[] ReadInputs(byte slave, ushort address, ushort count)
{
return Execute(new ModbusF02ReadInputs(slave, address, count)) as bool[];
}
public ushort[] ReadInputRegisters(byte slave, ushort address, ushort count)
{
return Execute(new ModbusF04ReadInputRegisters(slave, address, count)) as ushort[];
}
public ushort[] ReadHoldingRegisters(byte slave, ushort address, ushort count)
{
return Execute(new ModbusF03ReadHoldingRegisters(slave, address, count)) as ushort[];
}
public void WriteCoil(byte slave, ushort address, bool value)
{
Execute(new ModbusF05WriteCoil(slave, address, value));
}
public void WriteRegister(byte slave, ushort address, ushort value)
{
Execute(new ModbusF06WriteRegister(slave, address, value));
}
public void WriteCoils(byte slave, ushort address, params bool[] values)
{
Execute(new ModbusF15WriteCoils(slave, address, values));
}
public void WriteRegisters(byte slave, ushort address, params ushort[] values)
{
Execute(new ModbusF16WriteRegisters(slave, address, values));
}
private object Execute(IModbusCommand cmd)
{
var wrapper = protocol.Wrap(cmd);
var request = new byte[wrapper.RequestLength];
var response = new byte[wrapper.ResponseLength];
wrapper.FillRequest(request, 0);
OnSended?.Invoke(request, DataHexString(request));
stream.Write(request);
var count = stream.Read(response);
OnRecived?.Invoke(response, DataHexString(response));
if (count < response.Length) wrapper.CheckException(response, count);
return wrapper.ParseResponse(response, 0);
}
private string DataHexString(byte[] bytes)
{
if (bytes == null)
return string.Empty;
return bytes.Select(it => Convert.ToString(it, 16).PadLeft(2, '0').ToUpper()).ToList().GetStrArray(" ");
}
}
}