132 lines
4.6 KiB
C#
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(" ");
|
|
}
|
|
}
|
|
} |