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);
|
|
}
|
|
}
|
|
}
|