1264 lines
44 KiB
C#
1264 lines
44 KiB
C#
using SharpModbus;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.Text;
|
||
|
||
namespace MES.Utility.Network
|
||
{
|
||
public class ModbusHelper : 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;
|
||
|
||
|
||
private object _lock = new object();
|
||
private ModbusMaster master;
|
||
private byte slaveId;
|
||
public ModbusHelper(string ip, int port)
|
||
{
|
||
master = ModbusMaster.TCP(ip, port);
|
||
master.OnSended += Master_OnSended; ;
|
||
master.OnRecived += Master_OnRecived; ;
|
||
slaveId = 1;
|
||
}
|
||
|
||
|
||
|
||
public ModbusHelper(string ip, int port, byte slaveId)
|
||
{
|
||
master = ModbusMaster.TCP(ip, port);
|
||
master.OnSended += Master_OnSended;
|
||
master.OnRecived += Master_OnRecived;
|
||
this.slaveId = slaveId;
|
||
|
||
}
|
||
public ModbusHelper(SerialSettings setting, int timeout, byte slaveId)
|
||
{
|
||
master = ModbusMaster.RTU(setting, timeout);
|
||
master.OnSended += Master_OnSended;
|
||
master.OnRecived += Master_OnRecived;
|
||
this.slaveId = slaveId;
|
||
}
|
||
|
||
#region ushort INT16 操作
|
||
|
||
/// <summary>
|
||
/// 读取一个地址
|
||
/// </summary>
|
||
/// <param name="address">地址</param>
|
||
/// <param name="value">传递:数据值</param>
|
||
/// <returns>bool 读取成功还是失败</returns>
|
||
public bool ReadHoldRegisterInt16(int address, out ushort value)
|
||
{
|
||
return ReadHoldRegisterInt16(slaveId, address, out value);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 读取一个地址
|
||
/// </summary>
|
||
/// <param name="slaveId">从站Id</param>
|
||
/// <param name="address">地址</param>
|
||
/// <param name="value">传递:数据值</param>
|
||
/// <returns>bool 读取成功还是失败</returns>
|
||
public bool ReadHoldRegisterInt16(byte slaveId, int address, out ushort value)
|
||
{
|
||
bool flag = ReadHoldRegistersInt16(slaveId, address, 1, out ushort[] values);
|
||
value = flag ? values[0] : (ushort)0;
|
||
return flag;
|
||
}
|
||
|
||
|
||
|
||
/// <summary>
|
||
/// 读取某个地址连续N个数据
|
||
/// </summary>
|
||
/// <param name="address">地址</param>
|
||
/// <param name="count">读取的数量</param>
|
||
/// <param name="value">传递:数据值</param>
|
||
/// <returns>bool 读取成功还是失败</returns>
|
||
public bool ReadHoldRegistersInt16(int address, int count, out ushort[] value)
|
||
{
|
||
return ReadHoldRegistersInt16(slaveId, address, count, out value);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 读取某个地址连续N个数据
|
||
/// </summary>
|
||
/// <param name="slaveId"></param>
|
||
/// <param name="address"></param>
|
||
/// <param name="count"></param>
|
||
/// <param name="value"></param>
|
||
/// <returns></returns>
|
||
public bool ReadHoldRegistersInt16(byte slaveId, int address, int count, out ushort[] value)
|
||
{
|
||
lock (_lock)
|
||
try
|
||
{
|
||
value = master.ReadHoldingRegisters(slaveId, (ushort)address, (ushort)count);
|
||
return true;
|
||
}
|
||
catch
|
||
{
|
||
value = null;
|
||
return false;
|
||
}
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 写入一个地址
|
||
/// </summary>
|
||
/// <param name="address">地址</param>
|
||
/// <param name="value">写入的数据</param>
|
||
/// <returns>bool 写入成功还是失败</returns>
|
||
public bool WriteHoldRegisterInt16(int address, ushort value)
|
||
{
|
||
return WriteHoldRegisterInt16(slaveId, address, value);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 写入一个地址
|
||
/// </summary>
|
||
/// <param name="slaveId"></param>
|
||
/// <param name="address"></param>
|
||
/// <param name="value"></param>
|
||
/// <returns></returns>
|
||
public bool WriteHoldRegisterInt16(byte slaveId, int address, ushort value)
|
||
{
|
||
return WriteHoldRegistersInt16(slaveId, address, new ushort[] { value });
|
||
}
|
||
|
||
/// <summary>
|
||
/// 写入一个地址
|
||
/// </summary>
|
||
/// <param name="address"></param>
|
||
/// <param name="value"></param>
|
||
/// <returns></returns>
|
||
public bool WriteHoldRegistersInt16(int address, ushort[] value)
|
||
{
|
||
return WriteHoldRegistersInt16(slaveId, address, value);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 写入一个地址
|
||
/// </summary>
|
||
/// <param name="slaveId"></param>
|
||
/// <param name="address"></param>
|
||
/// <param name="value"></param>
|
||
/// <returns></returns>
|
||
public bool WriteHoldRegistersInt16(byte slaveId, int address, ushort[] value)
|
||
{
|
||
lock (_lock)
|
||
try
|
||
{
|
||
master.WriteRegisters(slaveId, (ushort)address, value);
|
||
return true;
|
||
}
|
||
catch
|
||
{
|
||
return false;
|
||
}
|
||
}
|
||
#endregion
|
||
|
||
#region int INT32 操作
|
||
/// <summary>
|
||
/// 读取一个地址
|
||
/// </summary>
|
||
/// <param name="address">地址</param>
|
||
/// <param name="value">传递:数据值</param>
|
||
/// <returns>bool 读取成功还是失败</returns>
|
||
public bool ReadHoldRegisterInt32(int address, out int value)
|
||
{
|
||
return ReadHoldRegisterInt32(slaveId, address, out value);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 读取一个地址
|
||
/// </summary>
|
||
/// <param name="slaveId">从站Id</param>
|
||
/// <param name="address">地址</param>
|
||
/// <param name="value">传递:数据值</param>
|
||
/// <returns>bool 读取成功还是失败</returns>
|
||
public bool ReadHoldRegisterInt32(byte slaveId, int address, out int value)
|
||
{
|
||
bool flag = ReadHoldRegistersInt32(slaveId, address, 1, out int[] values);
|
||
value = flag ? values[0] : 0;
|
||
return flag;
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 读取一个地址
|
||
/// </summary>
|
||
/// <param name="address">地址</param>
|
||
/// <param name="count">int32数据的数量,不是地址数</param>
|
||
/// <param name="value">传递:数据值</param>
|
||
/// <returns>bool 读取成功还是失败</returns>
|
||
public bool ReadHoldRegistersInt32(int address, int count, out int[] value)
|
||
{
|
||
return ReadHoldRegistersInt32(slaveId, address, count, out value);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 读取一个地址
|
||
/// </summary>
|
||
/// <param name="slaveId">从站Id</param>
|
||
/// <param name="address">地址</param>
|
||
/// <param name="count">int32数据的数量,不是地址数</param>
|
||
/// <param name="value">传递:数据值</param>
|
||
/// <returns>bool 读取成功还是失败</returns>
|
||
public bool ReadHoldRegistersInt32(byte slaveId, int address, int count, out int[] value)
|
||
{
|
||
lock (_lock)
|
||
try
|
||
{
|
||
List<int> valueList = new List<int>();
|
||
ushort[] values = master.ReadHoldingRegisters(slaveId, (ushort)address, (ushort)(2 * count));
|
||
for (int i = 0; i < values.Length; i += 2)
|
||
{
|
||
valueList.Add(ConvertRegistersToInt(new ushort[] { values[i], values[i + 1] }));
|
||
}
|
||
value = valueList.ToArray();
|
||
return true;
|
||
}
|
||
catch
|
||
{
|
||
value = null;
|
||
return false;
|
||
}
|
||
}
|
||
|
||
|
||
// <summary>
|
||
/// 写入一个地址
|
||
/// </summary>
|
||
/// <param name="address"></param>
|
||
/// <param name="value"></param>
|
||
/// <returns></returns>
|
||
public bool WriteHoldRegisterInt32(int address, int value)
|
||
{
|
||
return WriteHoldRegisterInt32(slaveId, address, value);
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
///
|
||
/// </summary>
|
||
/// <param name="slaveId">从站Id</param>
|
||
/// <param name="address">地址</param>
|
||
/// <param name="value">数据</param>
|
||
/// <returns>bool 写入成功还是失败</returns>
|
||
public bool WriteHoldRegisterInt32(byte slaveId, int address, int value)
|
||
{
|
||
return WriteHoldRegistersInt32(slaveId, address, new int[] { value });
|
||
}
|
||
|
||
// <summary>
|
||
/// 写入一个地址
|
||
/// </summary>
|
||
/// <param name="address">地址</param>
|
||
/// <param name="value">数据</param>
|
||
/// <returns></returns>
|
||
public bool WriteHoldRegistersInt32(int address, int[] values)
|
||
{
|
||
return WriteHoldRegistersInt32(slaveId, address, values);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 写入一个地址
|
||
/// </summary>
|
||
/// <param name="slaveId">从站Id</param>
|
||
/// <param name="address">地址</param>
|
||
/// <param name="values">数据</param>
|
||
/// <returns></returns>
|
||
public bool WriteHoldRegistersInt32(byte slaveId, int address, int[] values)
|
||
{
|
||
lock (_lock)
|
||
try
|
||
{
|
||
List<ushort> list = new List<ushort>();
|
||
foreach (int value in values)
|
||
{
|
||
ushort[] ushortValues = ConvertIntToRegisters(value);
|
||
list.AddRange(ushortValues);
|
||
}
|
||
master.WriteRegisters(slaveId, (ushort)address, list.ToArray());
|
||
return true;
|
||
}
|
||
catch
|
||
{
|
||
return false;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
#endregion
|
||
|
||
#region long INT64 操作
|
||
/// <summary>
|
||
/// 读取一个地址
|
||
/// </summary>
|
||
/// <param name="address">地址</param>
|
||
/// <param name="value">传递:数据值</param>
|
||
/// <returns>bool 读取成功还是失败</returns>
|
||
public bool ReadHoldRegisterInt64(int address, out long value)
|
||
{
|
||
return ReadHoldRegisterInt64(slaveId, address, out value);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 读取一个地址
|
||
/// </summary>
|
||
/// <param name="slaveId">从站Id</param>
|
||
/// <param name="address">地址</param>
|
||
/// <param name="value">传递:数据值</param>
|
||
/// <returns>bool 读取成功还是失败</returns>
|
||
public bool ReadHoldRegisterInt64(byte slaveId, int address, out long value)
|
||
{
|
||
bool flag = ReadHoldRegistersInt64(slaveId, address, 1, out long[] values);
|
||
value = flag ? values[0] : 0;
|
||
return flag;
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 读取一个地址
|
||
/// </summary>
|
||
/// <param name="address">地址</param>
|
||
/// <param name="count">int32数据的数量,不是地址数</param>
|
||
/// <param name="value">传递:数据值</param>
|
||
/// <returns>bool 读取成功还是失败</returns>
|
||
public bool ReadHoldRegistersInt64(int address, int count, out long[] value)
|
||
{
|
||
return ReadHoldRegistersInt64(slaveId, address, count, out value);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 读取一个地址
|
||
/// </summary>
|
||
/// <param name="slaveId">从站Id</param>
|
||
/// <param name="address">地址</param>
|
||
/// <param name="count">int32数据的数量,不是地址数</param>
|
||
/// <param name="value">传递:数据值</param>
|
||
/// <returns>bool 读取成功还是失败</returns>
|
||
public bool ReadHoldRegistersInt64(byte slaveId, int address, int count, out long[] value)
|
||
{
|
||
lock (_lock)
|
||
try
|
||
{
|
||
List<long> valueList = new List<long>();
|
||
ushort[] values = master.ReadHoldingRegisters(slaveId, (ushort)address, (ushort)(4 * count));
|
||
for (int i = 0; i < values.Length; i += 4)
|
||
{
|
||
valueList.Add(ConvertRegistersToLong(new ushort[] { values[i], values[i + 1], values[i + 2], values[i + 3] }));
|
||
}
|
||
value = valueList.ToArray();
|
||
return true;
|
||
}
|
||
catch
|
||
{
|
||
value = null;
|
||
return false;
|
||
}
|
||
}
|
||
|
||
|
||
// <summary>
|
||
/// 写入一个地址
|
||
/// </summary>
|
||
/// <param name="address"></param>
|
||
/// <param name="value"></param>
|
||
/// <returns></returns>
|
||
public bool WriteHoldRegisterInt64(int address, long value)
|
||
{
|
||
return WriteHoldRegisterInt64(slaveId, address, value);
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
///
|
||
/// </summary>
|
||
/// <param name="slaveId">从站Id</param>
|
||
/// <param name="address">地址</param>
|
||
/// <param name="value">数据</param>
|
||
/// <returns>bool 写入成功还是失败</returns>
|
||
public bool WriteHoldRegisterInt64(byte slaveId, int address, long value)
|
||
{
|
||
return WriteHoldRegistersInt64(slaveId, address, new long[] { value });
|
||
}
|
||
|
||
// <summary>
|
||
/// 写入一个地址
|
||
/// </summary>
|
||
/// <param name="address">地址</param>
|
||
/// <param name="value">数据</param>
|
||
/// <returns></returns>
|
||
public bool WriteHoldRegistersInt64(int address, long[] values)
|
||
{
|
||
return WriteHoldRegistersInt64(slaveId, address, values);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 写入一个地址
|
||
/// </summary>
|
||
/// <param name="slaveId">从站Id</param>
|
||
/// <param name="address">地址</param>
|
||
/// <param name="values">数据</param>
|
||
/// <returns></returns>
|
||
public bool WriteHoldRegistersInt64(byte slaveId, int address, long[] values)
|
||
{
|
||
lock (_lock)
|
||
try
|
||
{
|
||
List<ushort> list = new List<ushort>();
|
||
foreach (int value in values)
|
||
{
|
||
ushort[] ushortValues = ConvertLongToRegisters(value);
|
||
list.AddRange(ushortValues);
|
||
}
|
||
master.WriteRegisters(slaveId, (ushort)address, list.ToArray());
|
||
return true;
|
||
}
|
||
catch
|
||
{
|
||
return false;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
#endregion
|
||
|
||
#region Float 32位数据操作
|
||
/// <summary>
|
||
/// 读取一个地址
|
||
/// </summary>
|
||
/// <param name="address">地址</param>
|
||
/// <param name="value">数据</param>
|
||
/// <returns></returns>
|
||
public bool ReadHoldRegisterFloat(int address, out float value)
|
||
{
|
||
return ReadHoldRegisterFloat(slaveId, address, out value);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 读取一个地址
|
||
/// </summary>
|
||
/// <param name="slaveId">从站Id</param>
|
||
/// <param name="address">地址</param>
|
||
/// <param name="value"></param>
|
||
/// <returns></returns>
|
||
public bool ReadHoldRegisterFloat(byte slaveId, int address, out float value)
|
||
{
|
||
bool flag = ReadHoldRegistersFloat(slaveId, address, 1, out float[] values);
|
||
value = flag ? (float)values[0] : (float)0;
|
||
return flag;
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 读取一个地址
|
||
/// </summary>
|
||
/// <param name="address">地址</param>
|
||
/// <param name="count">float数据的数量,不是地址数</param>
|
||
/// <param name="value"></param>
|
||
/// <returns></returns>
|
||
public bool ReadHoldRegistersFloat(int address, int count, out float[] value)
|
||
{
|
||
return ReadHoldRegistersFloat(slaveId, address, count, out value);
|
||
}
|
||
/// <summary>
|
||
/// 读取一个地址
|
||
/// </summary>
|
||
/// <param name="slaveId">从站Id</param>
|
||
/// <param name="address">地址</param>
|
||
/// <param name="count">float数据的数量,不是地址数</param>
|
||
/// <param name="value"></param>
|
||
/// <returns></returns>
|
||
public bool ReadHoldRegistersFloat(byte slaveId, int address, int count, out float[] value)
|
||
{
|
||
lock (_lock)
|
||
try
|
||
{
|
||
List<float> valueList = new List<float>();
|
||
ushort[] values = master.ReadHoldingRegisters(slaveId, (ushort)address, (ushort)(2 * count));
|
||
for (int i = 0; i < values.Length; i += 2)
|
||
{
|
||
valueList.Add(ConvertRegistersToFloat(values));
|
||
}
|
||
value = valueList.ToArray();
|
||
return true;
|
||
}
|
||
catch
|
||
{
|
||
value = null;
|
||
return false;
|
||
}
|
||
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 写入地址
|
||
/// </summary>
|
||
/// <param name="address">地址</param>
|
||
/// <param name="value">数据</param>
|
||
/// <returns></returns>
|
||
public bool WriteHoldRegisterFloat(int address, float value)
|
||
{
|
||
return WriteHoldRegisterFloat(slaveId, address, value);
|
||
}
|
||
/// <summary>
|
||
/// 写入地址
|
||
/// </summary>
|
||
/// <param name="slaveId">从站Id</param>
|
||
/// <param name="address">地址</param>
|
||
/// <param name="value">数据</param>
|
||
/// <returns></returns>
|
||
public bool WriteHoldRegisterFloat(byte slaveId, int address, float value)
|
||
{
|
||
return WriteHoldRegistersFloat(slaveId, address, new float[] { value });
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 写入地址
|
||
/// </summary>
|
||
/// <param name="address">地址</param>
|
||
/// <param name="values">数据</param>
|
||
/// <returns></returns>
|
||
public bool WriteHoldRegistersFloat(int address, float[] values)
|
||
{
|
||
return WriteHoldRegistersFloat(slaveId, address, values);
|
||
}
|
||
/// <summary>
|
||
/// 写入地址
|
||
/// </summary>
|
||
/// <param name="slaveId">从站Id</param>
|
||
/// <param name="address">地址</param>
|
||
/// <param name="values">数据</param>
|
||
/// <returns></returns>
|
||
public bool WriteHoldRegistersFloat(byte slaveId, int address, float[] values)
|
||
{
|
||
lock (_lock)
|
||
try
|
||
{
|
||
List<ushort> list = new List<ushort>();
|
||
foreach (float value in values)
|
||
{
|
||
list.AddRange(ConvertFloatToRegisters(value));
|
||
//byte[] bytes = BitConverter.GetBytes(value);
|
||
//ushort value1 = BitConverter.ToUInt16(new byte[] { bytes[0], bytes[1] }, 0);
|
||
//ushort value2 = BitConverter.ToUInt16(new byte[] { bytes[2], bytes[3] }, 0);
|
||
//list.Add(value1);
|
||
//list.Add(value2);
|
||
}
|
||
master.WriteRegisters(slaveId, (ushort)address, list.ToArray());
|
||
return true;
|
||
}
|
||
catch
|
||
{
|
||
return false;
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Double 64位操作
|
||
/// <summary>
|
||
/// 读取一个地址
|
||
/// </summary>
|
||
/// <param name="address">地址</param>
|
||
/// <param name="value">数据</param>
|
||
/// <returns></returns>
|
||
public bool ReadHoldRegisterDouble(int address, out double value)
|
||
{
|
||
return ReadHoldRegisterDouble(slaveId, address, out value);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 读取一个地址
|
||
/// </summary>
|
||
/// <param name="slaveId">从站Id</param>
|
||
/// <param name="address">地址</param>
|
||
/// <param name="value"></param>
|
||
/// <returns></returns>
|
||
public bool ReadHoldRegisterDouble(byte slaveId, int address, out double value)
|
||
{
|
||
bool flag = ReadHoldRegistersDouble(slaveId, address, 1, out double[] values);
|
||
value = flag ? (double)values[0] : (double)0;
|
||
return flag;
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 读取一个地址
|
||
/// </summary>
|
||
/// <param name="address">地址</param>
|
||
/// <param name="count">float数据的数量,不是地址数</param>
|
||
/// <param name="value"></param>
|
||
/// <returns></returns>
|
||
public bool ReadHoldRegistersDouble(int address, int count, out double[] value)
|
||
{
|
||
return ReadHoldRegistersDouble(slaveId, address, count, out value);
|
||
}
|
||
/// <summary>
|
||
/// 读取一个地址
|
||
/// </summary>
|
||
/// <param name="slaveId">从站Id</param>
|
||
/// <param name="address">地址</param>
|
||
/// <param name="count">float数据的数量,不是地址数</param>
|
||
/// <param name="value"></param>
|
||
/// <returns></returns>
|
||
public bool ReadHoldRegistersDouble(byte slaveId, int address, int count, out double[] value)
|
||
{
|
||
lock (_lock)
|
||
try
|
||
{
|
||
List<double> valueList = new List<double>();
|
||
ushort[] values = master.ReadHoldingRegisters(slaveId, (ushort)address, (ushort)(4 * count));
|
||
for (int i = 0; i < values.Length; i += 4)
|
||
{
|
||
valueList.Add(ConvertRegistersToDouble(values));
|
||
}
|
||
value = valueList.ToArray();
|
||
return true;
|
||
}
|
||
catch
|
||
{
|
||
value = null;
|
||
return false;
|
||
}
|
||
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 写入地址
|
||
/// </summary>
|
||
/// <param name="address">地址</param>
|
||
/// <param name="value">数据</param>
|
||
/// <returns></returns>
|
||
public bool WriteHoldRegisterDouble(int address, double value)
|
||
{
|
||
return WriteHoldRegisterDouble(slaveId, address, value);
|
||
}
|
||
/// <summary>
|
||
/// 写入地址
|
||
/// </summary>
|
||
/// <param name="slaveId">从站Id</param>
|
||
/// <param name="address">地址</param>
|
||
/// <param name="value">数据</param>
|
||
/// <returns></returns>
|
||
public bool WriteHoldRegisterDouble(byte slaveId, int address, double value)
|
||
{
|
||
return WriteHoldRegistersDouble(slaveId, address, new double[] { value });
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 写入地址
|
||
/// </summary>
|
||
/// <param name="address">地址</param>
|
||
/// <param name="values">数据</param>
|
||
/// <returns></returns>
|
||
public bool WriteHoldRegistersDouble(int address, double[] values)
|
||
{
|
||
return WriteHoldRegistersDouble(slaveId, address, values);
|
||
}
|
||
/// <summary>
|
||
/// 写入地址
|
||
/// </summary>
|
||
/// <param name="slaveId">从站Id</param>
|
||
/// <param name="address">地址</param>
|
||
/// <param name="values">数据</param>
|
||
/// <returns></returns>
|
||
public bool WriteHoldRegistersDouble(byte slaveId, int address, double[] values)
|
||
{
|
||
lock (_lock)
|
||
try
|
||
{
|
||
List<ushort> list = new List<ushort>();
|
||
foreach (double value in values)
|
||
{
|
||
list.AddRange(ConvertDoubleToRegisters(value));
|
||
}
|
||
master.WriteRegisters(slaveId, (ushort)address, list.ToArray());
|
||
return true;
|
||
}
|
||
catch
|
||
{
|
||
return false;
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 字符串操作
|
||
|
||
/// <summary>
|
||
/// 读取字符串
|
||
/// </summary>
|
||
/// <param name="address">地址</param>
|
||
/// <param name="length">字符串总长度(不是地址长度,一个地址两个字符)</param>
|
||
/// <param name="str"></param>
|
||
/// <returns></returns>
|
||
public bool ReadHoldRegisterString(int address, int length, out string str)
|
||
{
|
||
return ReadHoldRegisterString(slaveId, address, length, Encoding.ASCII, out str);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 读取字符串
|
||
/// </summary>
|
||
/// <param name="address">地址</param>
|
||
/// <param name="length">字符串总长度(不是地址长度,一个地址两个字符)</param>
|
||
/// <param name="str"></param>
|
||
/// <returns></returns>
|
||
public bool ReadHoldRegisterString(int address, int length, Encoding encoding, out string str)
|
||
{
|
||
return ReadHoldRegisterString(slaveId, address, length, encoding, out str);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 读取字符串
|
||
/// </summary>
|
||
/// <param name="slaveId">从站Id</param>
|
||
/// <param name="address">地址</param>
|
||
/// <param name="length">字符串总长度(不是地址长度,一个地址两个字符)</param>
|
||
/// <param name="str"></param>
|
||
/// <returns></returns>
|
||
public bool ReadHoldRegisterString(byte slaveId, int address, int length, out string str)
|
||
{
|
||
return ReadHoldRegisterString(slaveId, address, length, Encoding.ASCII, out str);
|
||
}
|
||
|
||
|
||
|
||
/// <summary>
|
||
/// 读取字符串
|
||
/// </summary>
|
||
/// <param name="slaveId">从站Id</param>
|
||
/// <param name="address">地址</param>
|
||
/// <param name="length">字符串总长度(不是地址长度,一个地址两个字符)</param>
|
||
/// <param name="str"></param>
|
||
/// <returns></returns>
|
||
public bool ReadHoldRegisterString(byte slaveId, int address, int length, Encoding encoding, out string str)
|
||
{
|
||
lock (_lock)
|
||
try
|
||
{
|
||
int count = length / 2 + length % 2;
|
||
ushort[] values = master.ReadHoldingRegisters(slaveId, (ushort)address, (ushort)(count));
|
||
str = ConvertRegistersToString(values, length, encoding);
|
||
return true;
|
||
}
|
||
catch
|
||
{
|
||
str = "";
|
||
return false;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
/// <summary>
|
||
/// 写入字符串
|
||
/// </summary>
|
||
/// <param name="address">地址</param>
|
||
/// <param name="length">字符串总长度(不是地址长度,一个地址两个字符)</param>
|
||
/// <param name="str">字符串内容</param>
|
||
/// <returns></returns>
|
||
public bool WriteHoldRegisterString(int address, int length, string str)
|
||
{
|
||
return WriteHoldRegisterString(slaveId, address, length, str, Encoding.ASCII);
|
||
}
|
||
|
||
public bool WriteHoldRegisterString(int address, int length, string str, Encoding encoding)
|
||
{
|
||
return WriteHoldRegisterString(slaveId, address, length, str, encoding);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 写入字符串
|
||
/// </summary>
|
||
/// <param name="slaveId">从站Id</param>
|
||
/// <param name="address">地址</param>
|
||
/// <param name="length">字符串总长度(不是地址长度,一个地址两个字符)</param>
|
||
/// <param name="str">字符串内容</param>
|
||
/// <returns></returns>
|
||
public bool WriteHoldRegisterString(byte slaveId, int address, int length, string str)
|
||
{
|
||
lock (_lock)
|
||
try
|
||
{
|
||
ushort[] value = ConvertStringToRegisters(str, length, Encoding.ASCII);
|
||
master.WriteRegisters(slaveId, (ushort)address, value);
|
||
return true;
|
||
}
|
||
catch
|
||
{
|
||
return false;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 写入字符串
|
||
/// </summary>
|
||
/// <param name="slaveId">从站Id</param>
|
||
/// <param name="address">地址</param>
|
||
/// <param name="length">字符串总长度(不是地址长度,一个地址两个字符)</param>
|
||
/// <param name="str">字符串内容</param>
|
||
/// <returns></returns>
|
||
public bool WriteHoldRegisterString(byte slaveId, int address, int length, string str, Encoding encoding)
|
||
{
|
||
lock (_lock)
|
||
try
|
||
{
|
||
ushort[] value = ConvertStringToRegisters(str, length, encoding);
|
||
master.WriteRegisters(slaveId, (ushort)address, value);
|
||
return true;
|
||
}
|
||
catch
|
||
{
|
||
return false;
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 通用操作,线圈,输入寄存器等操作
|
||
|
||
public bool ReadCoil(ushort address, out bool value)
|
||
{
|
||
return ReadCoil(slaveId, address, out value); //there is no code for single read
|
||
}
|
||
|
||
public bool ReadCoil(byte slave, ushort address, out bool value)
|
||
{
|
||
bool flag = ReadCoils(slave, address, 1, out bool[] values);
|
||
value = flag ? values[0] : false;
|
||
return flag;
|
||
}
|
||
public bool ReadCoils(ushort address, ushort count, out bool[] values)
|
||
{
|
||
return ReadCoils(slaveId, address, count, out values);
|
||
}
|
||
public bool ReadCoils(byte slave, ushort address, ushort count, out bool[] values)
|
||
{
|
||
lock (_lock)
|
||
{
|
||
try
|
||
{
|
||
values = master.ReadCoils(slave, address, count);
|
||
return true;
|
||
}
|
||
catch
|
||
{
|
||
values = null;
|
||
return false;
|
||
}
|
||
}
|
||
}
|
||
|
||
public bool WriteCoil(ushort address, bool value)
|
||
{
|
||
return WriteCoil(slaveId, address, value);
|
||
}
|
||
public bool WriteCoil(byte slave, ushort address, bool value)
|
||
{
|
||
lock (_lock)
|
||
try
|
||
{
|
||
master.WriteCoils(slave, address, value);
|
||
return true;
|
||
}
|
||
catch
|
||
{
|
||
return false;
|
||
}
|
||
|
||
}
|
||
public bool WriteCoils(ushort address, params bool[] values)
|
||
{
|
||
return WriteCoils(slaveId, address, values);
|
||
}
|
||
public bool WriteCoils(byte slave, ushort address, params bool[] values)
|
||
{
|
||
lock (_lock)
|
||
{
|
||
try
|
||
{
|
||
master.WriteCoils(slave, address, values);
|
||
return true;
|
||
}
|
||
catch
|
||
{
|
||
return false;
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
|
||
public bool ReadInput(ushort address, ushort count, out bool value)
|
||
{
|
||
return ReadInput(slaveId, address, out value);
|
||
}
|
||
|
||
public bool ReadInput(byte slave, ushort address, out bool value)
|
||
{
|
||
bool flag = ReadInputs(slave, address, 1, out bool[] values); //there is no code for single read
|
||
value = flag ? values[0] : false;
|
||
return flag;
|
||
}
|
||
public bool ReadInputs(ushort address, ushort count, out bool[] values)
|
||
{
|
||
return ReadInputs(slaveId, address, count, out values);
|
||
}
|
||
public bool ReadInputs(byte slave, ushort address, ushort count, out bool[] values)
|
||
{
|
||
lock (_lock)
|
||
{
|
||
try
|
||
{
|
||
values = master.ReadInputs(slave, address, count);
|
||
return true;
|
||
}
|
||
catch
|
||
{
|
||
values = null;
|
||
return false;
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
|
||
public bool ReadInputRegister(ushort address, out ushort value)
|
||
{
|
||
return ReadInputRegister(slaveId, address, out value);
|
||
}
|
||
public bool ReadInputRegister(byte slave, ushort address, out ushort value)
|
||
{
|
||
bool flag = ReadInputRegisters(slave, address, 1, out ushort[] values);
|
||
value = flag ? values[0] : (ushort)0;
|
||
return flag;
|
||
}
|
||
public bool ReadInputRegisters(ushort address, ushort count, out ushort[] values)
|
||
{
|
||
return ReadInputRegisters(slaveId, address, count, out values);
|
||
}
|
||
public bool ReadInputRegisters(byte slave, ushort address, ushort count, out ushort[] values)
|
||
{
|
||
lock (_lock)
|
||
{
|
||
try
|
||
{
|
||
values = master.ReadInputRegisters(slave, address, count);
|
||
return true;
|
||
}
|
||
catch
|
||
{
|
||
values = null;
|
||
return false;
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
|
||
public bool ReadHoldingRegister(ushort address, out ushort value)
|
||
{
|
||
return ReadHoldingRegister(slaveId, address, out value);
|
||
}
|
||
|
||
public bool ReadHoldingRegister(byte slave, ushort address, out ushort value)
|
||
{
|
||
bool flag = ReadHoldingRegisters(slave, address, 1, out ushort[] values);
|
||
value = flag ? values[0] : (ushort)0;
|
||
return flag;
|
||
}
|
||
public bool ReadHoldingRegisters(ushort address, ushort count, out ushort[] values)
|
||
{
|
||
return ReadHoldingRegisters(slaveId, address, count, out values);
|
||
}
|
||
|
||
public bool ReadHoldingRegisters(byte slave, ushort address, ushort count, out ushort[] values)
|
||
{
|
||
lock (_lock)
|
||
try
|
||
{
|
||
values = master.ReadHoldingRegisters(slave, address, count);
|
||
return true;
|
||
}
|
||
catch
|
||
{
|
||
values = null;
|
||
return false;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
public bool WriteRegister(ushort address, ushort value)
|
||
{
|
||
return WriteRegister(slaveId, address, value);
|
||
}
|
||
public bool WriteRegister(byte slave, ushort address, ushort value)
|
||
{
|
||
lock (_lock)
|
||
try
|
||
{
|
||
master.WriteRegister(slave, address, value);
|
||
return true;
|
||
}
|
||
catch
|
||
{
|
||
return false;
|
||
}
|
||
}
|
||
|
||
|
||
public bool WriteRegisters(ushort address, params ushort[] values)
|
||
{
|
||
return WriteRegisters(slaveId, address, values);
|
||
}
|
||
|
||
public bool WriteRegisters(byte slave, ushort address, params ushort[] values)
|
||
{
|
||
lock (_lock)
|
||
try
|
||
{
|
||
master.WriteRegisters(slave, address, values);
|
||
return true;
|
||
}
|
||
catch
|
||
{
|
||
return false;
|
||
}
|
||
}
|
||
#endregion
|
||
|
||
public void Dispose()
|
||
{
|
||
master.OnSended -= Master_OnSended;
|
||
master.OnRecived -= Master_OnRecived;
|
||
master.Dispose();
|
||
|
||
}
|
||
#region 数据转换功能
|
||
#region PLC寄存器与字符串数据转换
|
||
public static string ConvertRegistersToString(ushort[] registers, int stringLength, Encoding encoding)
|
||
{
|
||
byte[] result = new byte[stringLength];
|
||
byte[] registerResult = new byte[2];
|
||
for (int i = 0; i < stringLength / 2; i++)
|
||
{
|
||
registerResult = BitConverter.GetBytes(registers[i]);
|
||
result[i * 2] = registerResult[0];
|
||
result[i * 2 + 1] = registerResult[1];
|
||
}
|
||
return encoding.GetString(result).Trim('\0').Trim();
|
||
}
|
||
|
||
/// <summary>
|
||
///
|
||
/// </summary>
|
||
/// <param name="str"></param>
|
||
/// <param name="count">字符串长度</param>
|
||
/// <returns></returns>
|
||
public static ushort[] ConvertStringToRegisters(string str, int count, Encoding encoding)
|
||
{
|
||
//需要多少地址
|
||
int addressCount = count / 2 + count % 2;
|
||
//这些地址共有多少字节
|
||
byte[] bytesList = new byte[addressCount * 2];
|
||
//将字符串拆成字节数组
|
||
byte[] bytes = encoding.GetBytes(str);
|
||
//依次放入byteList中
|
||
for (int i = 0; i < bytesList.Length; i++)
|
||
{
|
||
//要考虑数组越界的情况
|
||
if (i >= bytes.Length)
|
||
{
|
||
bytesList[i] = 0x00;
|
||
}
|
||
else
|
||
{
|
||
bytesList[i] = bytes[i];
|
||
}
|
||
}
|
||
//封装ushort
|
||
List<ushort> shortList = new List<ushort>();
|
||
for (int i = 0; i < bytesList.Length; i += 2)
|
||
{
|
||
//将字节数组转为int存入list
|
||
shortList.Add(BitConverter.ToUInt16(new byte[] { bytesList[i], bytesList[i + 1] }, 0));
|
||
}
|
||
return shortList.ToArray();
|
||
}
|
||
#endregion
|
||
|
||
#region PLC寄存器与Double数据转换
|
||
public static double ConvertRegistersToDouble(ushort[] registers)
|
||
{
|
||
if (registers.Length != 4)
|
||
throw new ArgumentException("Input Array length invalid - Array langth must be '4'");
|
||
ushort highRegister = registers[3];
|
||
ushort highLowRegister = registers[2];
|
||
ushort lowHighRegister = registers[1];
|
||
ushort lowRegister = registers[0];
|
||
byte[] highRegisterBytes = BitConverter.GetBytes(highRegister);
|
||
byte[] highLowRegisterBytes = BitConverter.GetBytes(highLowRegister);
|
||
byte[] lowHighRegisterBytes = BitConverter.GetBytes(lowHighRegister);
|
||
byte[] lowRegisterBytes = BitConverter.GetBytes(lowRegister);
|
||
byte[] longBytes = {
|
||
lowRegisterBytes[0],
|
||
lowRegisterBytes[1],
|
||
lowHighRegisterBytes[0],
|
||
lowHighRegisterBytes[1],
|
||
highLowRegisterBytes[0],
|
||
highLowRegisterBytes[1],
|
||
highRegisterBytes[0],
|
||
highRegisterBytes[1]
|
||
};
|
||
return BitConverter.ToDouble(longBytes, 0);
|
||
}
|
||
public static ushort[] ConvertDoubleToRegisters(double doubleValue)
|
||
{
|
||
byte[] doubleBytes = BitConverter.GetBytes(doubleValue);
|
||
byte[] highRegisterBytes = { doubleBytes[6], doubleBytes[7] };
|
||
byte[] highLowRegisterBytes = { doubleBytes[4], doubleBytes[5] };
|
||
byte[] lowHighRegisterBytes = { doubleBytes[2], doubleBytes[3] };
|
||
byte[] lowRegisterBytes = { doubleBytes[0], doubleBytes[1] };
|
||
ushort[] returnValue =
|
||
{
|
||
BitConverter.ToUInt16(lowRegisterBytes,0),
|
||
BitConverter.ToUInt16(lowHighRegisterBytes,0),
|
||
BitConverter.ToUInt16(highLowRegisterBytes,0),
|
||
BitConverter.ToUInt16(highRegisterBytes,0)
|
||
};
|
||
return returnValue;
|
||
}
|
||
#endregion
|
||
|
||
#region PLC寄存器与INT64数据转换
|
||
public static float ConvertRegistersToFloat(ushort[] registers)
|
||
{
|
||
if (registers.Length != 2)
|
||
throw new ArgumentException("Input Array length invalid - Array langth must be '2'");
|
||
ushort highRegister = registers[1];
|
||
ushort lowRegister = registers[0];
|
||
byte[] highRegisterBytes = BitConverter.GetBytes(highRegister);
|
||
byte[] lowRegisterBytes = BitConverter.GetBytes(lowRegister);
|
||
byte[] floatBytes = {
|
||
lowRegisterBytes[0],
|
||
lowRegisterBytes[1],
|
||
highRegisterBytes[0],
|
||
highRegisterBytes[1]
|
||
};
|
||
return BitConverter.ToSingle(floatBytes, 0);
|
||
}
|
||
|
||
public static ushort[] ConvertFloatToRegisters(float floatValue)
|
||
{
|
||
byte[] floatBytes = BitConverter.GetBytes(floatValue);
|
||
byte[] highRegisterBytes = { floatBytes[2], floatBytes[3] };
|
||
byte[] lowRegisterBytes = { floatBytes[0], floatBytes[1] };
|
||
ushort[] returnValue = { BitConverter.ToUInt16(lowRegisterBytes, 0), BitConverter.ToUInt16(highRegisterBytes, 0) };
|
||
return returnValue;
|
||
}
|
||
#endregion
|
||
|
||
#region PLC寄存器与INT64数据转换
|
||
public static long ConvertRegistersToLong(ushort[] registers)
|
||
{
|
||
if (registers.Length != 4)
|
||
throw new ArgumentException("Input Array length invalid - Array langth must be '4'");
|
||
ushort highRegister = registers[3];
|
||
ushort highLowRegister = registers[2];
|
||
ushort lowHighRegister = registers[1];
|
||
ushort lowRegister = registers[0];
|
||
byte[] highRegisterBytes = BitConverter.GetBytes(highRegister);
|
||
byte[] highLowRegisterBytes = BitConverter.GetBytes(highLowRegister);
|
||
byte[] lowHighRegisterBytes = BitConverter.GetBytes(lowHighRegister);
|
||
byte[] lowRegisterBytes = BitConverter.GetBytes(lowRegister);
|
||
byte[] longBytes = {
|
||
lowRegisterBytes[0],
|
||
lowRegisterBytes[1],
|
||
lowHighRegisterBytes[0],
|
||
lowHighRegisterBytes[1],
|
||
highLowRegisterBytes[0],
|
||
highLowRegisterBytes[1],
|
||
highRegisterBytes[0],
|
||
highRegisterBytes[1]
|
||
};
|
||
return BitConverter.ToInt64(longBytes, 0);
|
||
}
|
||
public static ushort[] ConvertLongToRegisters(long longValue)
|
||
{
|
||
byte[] longBytes = BitConverter.GetBytes(longValue);
|
||
byte[] highRegisterBytes = { longBytes[6], longBytes[7] };
|
||
byte[] highLowRegisterBytes = { longBytes[4], longBytes[5] };
|
||
byte[] lowHighRegisterBytes = { longBytes[2], longBytes[3] };
|
||
byte[] lowRegisterBytes = { longBytes[0], longBytes[1] };
|
||
ushort[] returnValue =
|
||
{
|
||
BitConverter.ToUInt16(lowRegisterBytes,0),
|
||
BitConverter.ToUInt16(lowHighRegisterBytes,0),
|
||
BitConverter.ToUInt16(highLowRegisterBytes,0),
|
||
BitConverter.ToUInt16(highRegisterBytes,0)
|
||
};
|
||
return returnValue;
|
||
}
|
||
#endregion
|
||
|
||
#region PLC寄存器与INT32数据转换
|
||
public static int ConvertRegistersToInt(ushort[] registers)
|
||
{
|
||
if (registers.Length != 2)
|
||
throw new ArgumentException("Input Array length invalid - Array langth must be '2'");
|
||
ushort highRegister = registers[1];
|
||
ushort lowRegister = registers[0];
|
||
byte[] highRegisterBytes = BitConverter.GetBytes(highRegister);
|
||
byte[] lowRegisterBytes = BitConverter.GetBytes(lowRegister);
|
||
byte[] doubleBytes = {
|
||
lowRegisterBytes[0],
|
||
lowRegisterBytes[1],
|
||
highRegisterBytes[0],
|
||
highRegisterBytes[1]
|
||
};
|
||
return BitConverter.ToInt32(doubleBytes, 0);
|
||
}
|
||
|
||
public static ushort[] ConvertIntToRegisters(int intValue)
|
||
{
|
||
byte[] doubleBytes = BitConverter.GetBytes(intValue);
|
||
byte[] highRegisterBytes = { doubleBytes[2], doubleBytes[3] };
|
||
byte[] lowRegisterBytes = { doubleBytes[0], doubleBytes[1] };
|
||
ushort[] returnValue = { BitConverter.ToUInt16(lowRegisterBytes, 0), BitConverter.ToUInt16(highRegisterBytes, 0) };
|
||
return returnValue;
|
||
}
|
||
#endregion
|
||
#endregion
|
||
|
||
|
||
private void Master_OnRecived(byte[] bytes, string hexString)
|
||
{
|
||
OnRecived?.Invoke(bytes, hexString);
|
||
}
|
||
|
||
private void Master_OnSended(byte[] bytes, string hexString)
|
||
{
|
||
OnSended?.Invoke(bytes, hexString);
|
||
}
|
||
}
|
||
}
|