mirror of
https://github.com/zhaopeiym/IoTClient
synced 2025-10-05 19:16:16 +08:00
1、Modbus按位读取如:ReadUInt16Bit("1.11")
2、ModbusHelper异常码
This commit is contained in:
parent
d8921ff486
commit
bb47ec9642
|
@ -14,7 +14,7 @@ namespace IoTClient.Tests.Modbus
|
|||
byte stationNumber = 1;//站号
|
||||
public ModbusRtuClient_tests()
|
||||
{
|
||||
client = new ModbusRtuClient("COM3", 9600, 8, StopBits.One, Parity.None);
|
||||
client = new ModbusRtuClient("COM2", 9600, 8, StopBits.One, Parity.None);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using IoTClient.Clients.Modbus;
|
||||
using IoTClient.Common.Helpers;
|
||||
using IoTClient.Enums;
|
||||
using IoTClient.Models;
|
||||
using System;
|
||||
|
@ -22,9 +23,18 @@ namespace IoTClient.Tests.Modbus
|
|||
client = new ModbusTcpClient(new IPEndPoint(ip, port));
|
||||
}
|
||||
|
||||
public bool ShortToBit(int value, int index)
|
||||
{
|
||||
var binaryArray = DataConvert.IntToBinaryArray(value, 16);
|
||||
var length = binaryArray.Length - 16;
|
||||
return binaryArray[length + index].ToString() == "1";
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task 短连接自动开关()
|
||||
{
|
||||
var aa1 = client.ReadUInt16Bit("0.1").Value;
|
||||
|
||||
Random rnd = new Random((int)Stopwatch.GetTimestamp());
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
|
@ -129,7 +139,7 @@ namespace IoTClient.Tests.Modbus
|
|||
|
||||
[Fact]
|
||||
public void 批量读取()
|
||||
{
|
||||
{
|
||||
var result1 = client.ReadInt16("12");
|
||||
|
||||
client.WarningLog = (msg, ex) =>
|
||||
|
|
|
@ -24,6 +24,8 @@ namespace IoTClient.Tests.PLCTests
|
|||
|
||||
var reuslt = client.Open();
|
||||
|
||||
client.ReadInt16("D6402");
|
||||
|
||||
Random rnd = new Random((int)Stopwatch.GetTimestamp());
|
||||
|
||||
short short_number = (short)rnd.Next(short.MinValue, short.MaxValue);
|
||||
|
@ -37,6 +39,11 @@ namespace IoTClient.Tests.PLCTests
|
|||
|
||||
client.Write("D300", short_number);
|
||||
client.Write("D301", short_number_1);
|
||||
client.Write("D100", (short)100);
|
||||
|
||||
Assert.True(client.ReadInt16("D100").Value == 100);
|
||||
Assert.True(client.ReadInt16("D300").Value == short_number);
|
||||
Assert.True(client.ReadUInt16("D301").Value == short_number_1);
|
||||
|
||||
client.Write("D310", int_number);
|
||||
client.Write("D312", int_number_1);
|
||||
|
@ -117,6 +124,11 @@ namespace IoTClient.Tests.PLCTests
|
|||
Assert.True(Convert.ToUInt64(result.Value["D354"]) == Convert.ToUInt64(int_number_1));
|
||||
Assert.True(Convert.ToDouble(result.Value["D358"]) == Convert.ToDouble(float_number));
|
||||
|
||||
client.Write("H400.15", false);
|
||||
Assert.True(client.ReadBoolean("H400.15").Value == false);
|
||||
client.Write("H400.15", true);
|
||||
Assert.True(client.ReadBoolean("H400.15").Value == true);
|
||||
|
||||
client.Close();
|
||||
}
|
||||
|
||||
|
|
|
@ -129,6 +129,38 @@ namespace IoTClient.Clients.Modbus
|
|||
return result.EndTime();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 按位的方式读取
|
||||
/// </summary>
|
||||
/// <param name="address">寄存器地址:如1.00 ... 1.14、1.15</param>
|
||||
/// <param name="stationNumber">站号</param>
|
||||
/// <param name="functionCode">功能码</param>
|
||||
/// <param name="left">按位取值从左边开始取</param>
|
||||
/// <returns></returns>
|
||||
public Result<short> ReadInt16Bit(string address, byte stationNumber = 1, byte functionCode = 3, bool left = true)
|
||||
{
|
||||
string[] adds = address.Split('.');
|
||||
var readResut = Read(adds[0].Trim(), stationNumber, functionCode);
|
||||
var result = new Result<short>(readResut);
|
||||
if (result.IsSucceed)
|
||||
{
|
||||
result.Value = BitConverter.ToInt16(readResut.Value, 0);
|
||||
if (adds.Length >= 2)
|
||||
{
|
||||
var index = int.Parse(adds[1].Trim());
|
||||
var binaryArray = DataConvert.IntToBinaryArray(result.Value, 16);
|
||||
if (left)
|
||||
{
|
||||
var length = binaryArray.Length - 16;
|
||||
result.Value = short.Parse(binaryArray[length + index].ToString());
|
||||
}
|
||||
else
|
||||
result.Value = short.Parse(binaryArray[binaryArray.Length - 1 - index].ToString());
|
||||
}
|
||||
}
|
||||
return result.EndTime();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取UInt16
|
||||
/// </summary>
|
||||
|
@ -145,6 +177,38 @@ namespace IoTClient.Clients.Modbus
|
|||
return result.EndTime();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 按位的方式读取
|
||||
/// </summary>
|
||||
/// <param name="address">寄存器地址:如1.00 ... 1.14、1.15</param>
|
||||
/// <param name="stationNumber">站号</param>
|
||||
/// <param name="functionCode">功能码</param>
|
||||
/// <param name="left">按位取值从左边开始取</param>
|
||||
/// <returns></returns>
|
||||
public Result<ushort> ReadUInt16Bit(string address, byte stationNumber = 1, byte functionCode = 3, bool left = true)
|
||||
{
|
||||
string[] adds = address.Split('.');
|
||||
var readResut = Read(adds[0].Trim(), stationNumber, functionCode);
|
||||
var result = new Result<ushort>(readResut);
|
||||
if (result.IsSucceed)
|
||||
{
|
||||
result.Value = BitConverter.ToUInt16(readResut.Value, 0);
|
||||
if (adds.Length >= 2)
|
||||
{
|
||||
var index = int.Parse(adds[1].Trim());
|
||||
var binaryArray = DataConvert.IntToBinaryArray(result.Value, 16);
|
||||
if (left)
|
||||
{
|
||||
var length = binaryArray.Length - 16;
|
||||
result.Value = ushort.Parse(binaryArray[length + index].ToString());
|
||||
}
|
||||
else
|
||||
result.Value = ushort.Parse(binaryArray[binaryArray.Length - 1 - index].ToString());
|
||||
}
|
||||
}
|
||||
return result.EndTime();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取Int32
|
||||
/// </summary>
|
||||
|
|
|
@ -59,6 +59,16 @@ namespace IoTClient.Clients.Modbus
|
|||
/// <returns></returns>
|
||||
Result<short> ReadInt16(string address, byte stationNumber = 1, byte functionCode = 3);
|
||||
|
||||
/// <summary>
|
||||
/// 按位的方式读取
|
||||
/// </summary>
|
||||
/// <param name="address">寄存器地址:如1.00 ... 1.14、1.15</param>
|
||||
/// <param name="stationNumber">站号</param>
|
||||
/// <param name="functionCode">功能码</param>
|
||||
/// <param name="left">按位取值从左边开始取</param>
|
||||
/// <returns></returns>
|
||||
Result<short> ReadInt16Bit(string address, byte stationNumber = 1, byte functionCode = 3, bool left = true);
|
||||
|
||||
/// <summary>
|
||||
/// 从批量读取的数据字节提取对应的地址数据
|
||||
/// </summary>
|
||||
|
@ -86,6 +96,16 @@ namespace IoTClient.Clients.Modbus
|
|||
/// <returns></returns>
|
||||
Result<ushort> ReadUInt16(string beginAddress, string address, byte[] values);
|
||||
|
||||
/// <summary>
|
||||
/// 按位的方式读取
|
||||
/// </summary>
|
||||
/// <param name="address">寄存器地址:如1.00 ... 1.14、1.15</param>
|
||||
/// <param name="stationNumber">站号</param>
|
||||
/// <param name="functionCode">功能码</param>
|
||||
/// <param name="left">按位取值从左边开始取</param>
|
||||
/// <returns></returns>
|
||||
Result<ushort> ReadUInt16Bit(string address, byte stationNumber = 1, byte functionCode = 3, bool left = true);
|
||||
|
||||
/// <summary>
|
||||
/// 读取Int32
|
||||
/// </summary>
|
||||
|
|
|
@ -65,6 +65,11 @@ namespace IoTClient.Clients.Modbus
|
|||
result.Err = "响应结果CRC16验证失败";
|
||||
//return result.EndTime();
|
||||
}
|
||||
else if (ModbusHelper.VerifyFunctionCode(functionCode, responsePackage[1]))
|
||||
{
|
||||
result.IsSucceed = false;
|
||||
result.Err = ModbusHelper.ErrMsg(responsePackage[2]);
|
||||
}
|
||||
|
||||
byte[] resultData = new byte[responsePackage.Length - 2 - 3];
|
||||
Array.Copy(responsePackage, 3, resultData, 0, resultData.Length);
|
||||
|
@ -123,6 +128,11 @@ namespace IoTClient.Clients.Modbus
|
|||
result.Err = "响应结果CRC16验证失败";
|
||||
//return result.EndTime();
|
||||
}
|
||||
else if (ModbusHelper.VerifyFunctionCode(functionCode, responsePackage[1]))
|
||||
{
|
||||
result.IsSucceed = false;
|
||||
result.Err = ModbusHelper.ErrMsg(responsePackage[2]);
|
||||
}
|
||||
byte[] resultBuffer = new byte[responsePackage.Length - 2];
|
||||
Buffer.BlockCopy(responsePackage, 0, resultBuffer, 0, resultBuffer.Length);
|
||||
result.Response = string.Join(" ", responsePackage.Select(t => t.ToString("X2")));
|
||||
|
@ -175,6 +185,11 @@ namespace IoTClient.Clients.Modbus
|
|||
result.Err = "响应结果CRC16验证失败";
|
||||
//return result.EndTime();
|
||||
}
|
||||
else if (ModbusHelper.VerifyFunctionCode(functionCode, responsePackage[1]))
|
||||
{
|
||||
result.IsSucceed = false;
|
||||
result.Err = ModbusHelper.ErrMsg(responsePackage[2]);
|
||||
}
|
||||
byte[] resultBuffer = new byte[responsePackage.Length - 2];
|
||||
Array.Copy(responsePackage, 0, resultBuffer, 0, resultBuffer.Length);
|
||||
result.Response = string.Join(" ", responsePackage.Select(t => t.ToString("X2")));
|
||||
|
|
|
@ -230,6 +230,38 @@ namespace IoTClient.Clients.Modbus
|
|||
return result.EndTime();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 按位的方式读取
|
||||
/// </summary>
|
||||
/// <param name="address">寄存器地址:如1.00 ... 1.14、1.15</param>
|
||||
/// <param name="stationNumber">站号</param>
|
||||
/// <param name="functionCode">功能码</param>
|
||||
/// <param name="left">按位取值从左边开始取</param>
|
||||
/// <returns></returns>
|
||||
public Result<short> ReadInt16Bit(string address, byte stationNumber = 1, byte functionCode = 3, bool left = true)
|
||||
{
|
||||
string[] adds = address.Split('.');
|
||||
var readResut = Read(adds[0].Trim(), stationNumber, functionCode);
|
||||
var result = new Result<short>(readResut);
|
||||
if (result.IsSucceed)
|
||||
{
|
||||
result.Value = BitConverter.ToInt16(readResut.Value, 0);
|
||||
if (adds.Length >= 2)
|
||||
{
|
||||
var index = int.Parse(adds[1].Trim());
|
||||
var binaryArray = DataConvert.IntToBinaryArray(result.Value, 16);
|
||||
if (left)
|
||||
{
|
||||
var length = binaryArray.Length - 16;
|
||||
result.Value = short.Parse(binaryArray[length + index].ToString());
|
||||
}
|
||||
else
|
||||
result.Value = short.Parse(binaryArray[binaryArray.Length - 1 - index].ToString());
|
||||
}
|
||||
}
|
||||
return result.EndTime();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取UInt16
|
||||
/// </summary>
|
||||
|
@ -246,6 +278,38 @@ namespace IoTClient.Clients.Modbus
|
|||
return result.EndTime();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 按位的方式读取
|
||||
/// </summary>
|
||||
/// <param name="address">寄存器地址:如1.00 ... 1.14、1.15</param>
|
||||
/// <param name="stationNumber">站号</param>
|
||||
/// <param name="functionCode">功能码</param>
|
||||
/// <param name="left">按位取值从左边开始取</param>
|
||||
/// <returns></returns>
|
||||
public Result<ushort> ReadUInt16Bit(string address, byte stationNumber = 1, byte functionCode = 3, bool left = true)
|
||||
{
|
||||
string[] adds = address.Split('.');
|
||||
var readResut = Read(adds[0].Trim(), stationNumber, functionCode);
|
||||
var result = new Result<ushort>(readResut);
|
||||
if (result.IsSucceed)
|
||||
{
|
||||
result.Value = BitConverter.ToUInt16(readResut.Value, 0);
|
||||
if (adds.Length >= 2)
|
||||
{
|
||||
var index = int.Parse(adds[1].Trim());
|
||||
var binaryArray = DataConvert.IntToBinaryArray(result.Value, 16);
|
||||
if (left)
|
||||
{
|
||||
var length = binaryArray.Length - 16;
|
||||
result.Value = ushort.Parse(binaryArray[length + index].ToString());
|
||||
}
|
||||
else
|
||||
result.Value = ushort.Parse(binaryArray[binaryArray.Length - 1 - index].ToString());
|
||||
}
|
||||
}
|
||||
return result.EndTime();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取Int32
|
||||
/// </summary>
|
||||
|
|
|
@ -183,6 +183,11 @@ namespace IoTClient.Clients.Modbus
|
|||
result.Err = $"读取 地址:{address} 站号:{stationNumber} 功能码:{functionCode} 失败。响应结果校验失败";
|
||||
socket?.SafeClose();
|
||||
}
|
||||
else if (ModbusHelper.VerifyFunctionCode(functionCode, dataPackage[7]))
|
||||
{
|
||||
result.IsSucceed = false;
|
||||
result.Err = ModbusHelper.ErrMsg(dataPackage[8]);
|
||||
}
|
||||
}
|
||||
catch (SocketException ex)
|
||||
{
|
||||
|
@ -220,6 +225,38 @@ namespace IoTClient.Clients.Modbus
|
|||
return result.EndTime();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 按位的方式读取
|
||||
/// </summary>
|
||||
/// <param name="address">寄存器地址:如1.00 ... 1.14、1.15</param>
|
||||
/// <param name="stationNumber">站号</param>
|
||||
/// <param name="functionCode">功能码</param>
|
||||
/// <param name="left">按位取值从左边开始取</param>
|
||||
/// <returns></returns>
|
||||
public Result<short> ReadInt16Bit(string address, byte stationNumber = 1, byte functionCode = 3, bool left = true)
|
||||
{
|
||||
string[] adds = address.Split('.');
|
||||
var readResut = Read(adds[0].Trim(), stationNumber, functionCode);
|
||||
var result = new Result<short>(readResut);
|
||||
if (result.IsSucceed)
|
||||
{
|
||||
result.Value = BitConverter.ToInt16(readResut.Value, 0);
|
||||
if (adds.Length >= 2)
|
||||
{
|
||||
var index = int.Parse(adds[1].Trim());
|
||||
var binaryArray = DataConvert.IntToBinaryArray(result.Value, 16);
|
||||
if (left)
|
||||
{
|
||||
var length = binaryArray.Length - 16;
|
||||
result.Value = short.Parse(binaryArray[length + index].ToString());
|
||||
}
|
||||
else
|
||||
result.Value = short.Parse(binaryArray[binaryArray.Length - 1 - index].ToString());
|
||||
}
|
||||
}
|
||||
return result.EndTime();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取Int16类型数据
|
||||
/// </summary>
|
||||
|
@ -247,6 +284,38 @@ namespace IoTClient.Clients.Modbus
|
|||
return result.EndTime();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 按位的方式读取
|
||||
/// </summary>
|
||||
/// <param name="address">寄存器地址:如1.00 ... 1.14、1.15</param>
|
||||
/// <param name="stationNumber">站号</param>
|
||||
/// <param name="functionCode">功能码</param>
|
||||
/// <param name="left">按位取值从左边开始取</param>
|
||||
/// <returns></returns>
|
||||
public Result<ushort> ReadUInt16Bit(string address, byte stationNumber = 1, byte functionCode = 3, bool left = true)
|
||||
{
|
||||
string[] adds = address.Split('.');
|
||||
var readResut = Read(adds[0].Trim(), stationNumber, functionCode);
|
||||
var result = new Result<ushort>(readResut);
|
||||
if (result.IsSucceed)
|
||||
{
|
||||
result.Value = BitConverter.ToUInt16(readResut.Value, 0);
|
||||
if (adds.Length >= 2)
|
||||
{
|
||||
var index = int.Parse(adds[1].Trim());
|
||||
var binaryArray = DataConvert.IntToBinaryArray(result.Value, 16);
|
||||
if (left)
|
||||
{
|
||||
var length = binaryArray.Length - 16;
|
||||
result.Value = ushort.Parse(binaryArray[length + index].ToString());
|
||||
}
|
||||
else
|
||||
result.Value = ushort.Parse(binaryArray[binaryArray.Length - 1 - index].ToString());
|
||||
}
|
||||
}
|
||||
return result.EndTime();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取UInt16类型数据
|
||||
/// </summary>
|
||||
|
@ -1053,7 +1122,7 @@ namespace IoTClient.Clients.Modbus
|
|||
result.IsSucceed = tempResult.IsSucceed;
|
||||
result.Exception = tempResult.Exception;
|
||||
result.ErrCode = tempResult.ErrCode;
|
||||
result.Err = $"读取 地址:{minAddress} 站号:{stationNumber} 功能码:{functionCode} 失败。{tempResult.Err}";
|
||||
result.Err = tempResult.Err;// $"读取 地址:{minAddress} 站号:{stationNumber} 功能码:{functionCode} 失败。{tempResult.Err}";
|
||||
result.AddErr2List();
|
||||
return result.EndTime();
|
||||
}
|
||||
|
@ -1146,6 +1215,11 @@ namespace IoTClient.Clients.Modbus
|
|||
result.Err = "响应结果校验失败";
|
||||
socket?.SafeClose();
|
||||
}
|
||||
else if (ModbusHelper.VerifyFunctionCode(functionCode, dataPackage[7]))
|
||||
{
|
||||
result.IsSucceed = false;
|
||||
result.Err = ModbusHelper.ErrMsg(dataPackage[8]);
|
||||
}
|
||||
}
|
||||
catch (SocketException ex)
|
||||
{
|
||||
|
@ -1203,6 +1277,11 @@ namespace IoTClient.Clients.Modbus
|
|||
result.Err = "响应结果校验失败";
|
||||
socket?.SafeClose();
|
||||
}
|
||||
else if (ModbusHelper.VerifyFunctionCode(functionCode, dataPackage[7]))
|
||||
{
|
||||
result.IsSucceed = false;
|
||||
result.Err = ModbusHelper.ErrMsg(dataPackage[8]);
|
||||
}
|
||||
}
|
||||
catch (SocketException ex)
|
||||
{
|
||||
|
|
|
@ -221,7 +221,7 @@ namespace IoTClient.Clients.PLC
|
|||
Array.Copy(dataPackage, dataPackage.Length - length, responseData, 0, length);
|
||||
result.Response = string.Join(" ", dataPackage.Select(t => t.ToString("X2")));
|
||||
if (setEndian)
|
||||
result.Value = responseData.ToArray().ByteFormatting(endianFormat, false);
|
||||
result.Value = responseData.ToArray().ByteFormatting2(endianFormat, false);
|
||||
else
|
||||
result.Value = responseData.ToArray();
|
||||
}
|
||||
|
@ -388,7 +388,7 @@ namespace IoTClient.Clients.PLC
|
|||
{
|
||||
var interval = (addressInt - startAddressInt) / 2;
|
||||
var offset = (addressInt - startAddressInt) % 2 * 2;//取余 乘以2(每个地址16位,占两个字节)
|
||||
var byteArry = values.Skip(interval * 2 * 2 + offset).Take(2 * 2).ToArray().ByteFormatting(endianFormat, false);
|
||||
var byteArry = values.Skip(interval * 2 * 2 + offset).Take(2 * 2).ToArray().ByteFormatting2(endianFormat, false);
|
||||
return new Result<int>
|
||||
{
|
||||
Value = BitConverter.ToInt32(byteArry, 0)
|
||||
|
@ -424,7 +424,7 @@ namespace IoTClient.Clients.PLC
|
|||
{
|
||||
var interval = (addressInt - startAddressInt) / 2;
|
||||
var offset = (addressInt - startAddressInt) % 2 * 2;//取余 乘以2(每个地址16位,占两个字节)
|
||||
var byteArry = values.Skip(interval * 2 * 2 + offset).Take(2 * 2).ToArray().ByteFormatting(endianFormat, false);
|
||||
var byteArry = values.Skip(interval * 2 * 2 + offset).Take(2 * 2).ToArray().ByteFormatting2(endianFormat, false);
|
||||
return new Result<uint>
|
||||
{
|
||||
Value = BitConverter.ToUInt32(byteArry, 0)
|
||||
|
@ -460,7 +460,7 @@ namespace IoTClient.Clients.PLC
|
|||
{
|
||||
var interval = (addressInt - startAddressInt) / 4;
|
||||
var offset = (addressInt - startAddressInt) % 4 * 2;
|
||||
var byteArry = values.Skip(interval * 2 * 4 + offset).Take(2 * 4).ToArray().ByteFormatting(endianFormat, false);
|
||||
var byteArry = values.Skip(interval * 2 * 4 + offset).Take(2 * 4).ToArray().ByteFormatting2(endianFormat, false);
|
||||
return new Result<long>
|
||||
{
|
||||
Value = BitConverter.ToInt64(byteArry, 0)
|
||||
|
@ -496,7 +496,7 @@ namespace IoTClient.Clients.PLC
|
|||
{
|
||||
var interval = (addressInt - startAddressInt) / 4;
|
||||
var offset = (addressInt - startAddressInt) % 4 * 2;
|
||||
var byteArry = values.Skip(interval * 2 * 4 + offset).Take(2 * 4).ToArray().ByteFormatting(endianFormat, false);
|
||||
var byteArry = values.Skip(interval * 2 * 4 + offset).Take(2 * 4).ToArray().ByteFormatting2(endianFormat, false);
|
||||
return new Result<ulong>
|
||||
{
|
||||
Value = BitConverter.ToUInt64(byteArry, 0)
|
||||
|
@ -532,7 +532,7 @@ namespace IoTClient.Clients.PLC
|
|||
{
|
||||
var interval = (addressInt - beginAddressInt) / 2;
|
||||
var offset = (addressInt - beginAddressInt) % 2 * 2;//取余 乘以2(每个地址16位,占两个字节)
|
||||
var byteArry = values.Skip(interval * 2 * 2 + offset).Take(2 * 2).ToArray().ByteFormatting(endianFormat, false);
|
||||
var byteArry = values.Skip(interval * 2 * 2 + offset).Take(2 * 2).ToArray().ByteFormatting2(endianFormat, false);
|
||||
return new Result<float>
|
||||
{
|
||||
Value = BitConverter.ToSingle(byteArry, 0)
|
||||
|
@ -568,7 +568,7 @@ namespace IoTClient.Clients.PLC
|
|||
{
|
||||
var interval = (addressInt - beginAddressInt) / 4;
|
||||
var offset = (addressInt - beginAddressInt) % 4 * 2;
|
||||
var byteArry = values.Skip(interval * 2 * 4 + offset).Take(2 * 4).ToArray().ByteFormatting(endianFormat, false);
|
||||
var byteArry = values.Skip(interval * 2 * 4 + offset).Take(2 * 4).ToArray().ByteFormatting2(endianFormat, false);
|
||||
return new Result<double>
|
||||
{
|
||||
Value = BitConverter.ToDouble(byteArry, 0)
|
||||
|
@ -607,7 +607,7 @@ namespace IoTClient.Clients.PLC
|
|||
Result result = new Result();
|
||||
try
|
||||
{
|
||||
data = data.Reverse().ToArray().ByteFormatting(endianFormat);
|
||||
data = data.Reverse().ToArray().ByteFormatting2(endianFormat);
|
||||
//发送写入信息
|
||||
var arg = ConvertArg(address, isBit: isBit);
|
||||
byte[] command = GetWriteCommand(arg, data);
|
||||
|
@ -842,7 +842,7 @@ namespace IoTClient.Clients.PLC
|
|||
addressInfo.BitCode = 0x02;
|
||||
addressInfo.WordCode = 0x82;
|
||||
addressInfo.TypeChar = address.Substring(0, 1);
|
||||
addressInfo.BeginAddress = Convert.ToInt32(address.Substring(1));
|
||||
addressInfo.BeginAddress = Convert.ToInt32(address.Substring(1).Split('.')[0]);
|
||||
break;
|
||||
}
|
||||
case 'C'://CIO区
|
||||
|
@ -850,7 +850,7 @@ namespace IoTClient.Clients.PLC
|
|||
addressInfo.BitCode = 0x30;
|
||||
addressInfo.WordCode = 0xB0;
|
||||
addressInfo.TypeChar = address.Substring(0, 1);
|
||||
addressInfo.BeginAddress = Convert.ToInt32(address.Substring(1));
|
||||
addressInfo.BeginAddress = Convert.ToInt32(address.Substring(1).Split('.')[0]);
|
||||
break;
|
||||
}
|
||||
case 'W'://WR区
|
||||
|
@ -858,7 +858,7 @@ namespace IoTClient.Clients.PLC
|
|||
addressInfo.BitCode = 0x31;
|
||||
addressInfo.WordCode = 0xB1;
|
||||
addressInfo.TypeChar = address.Substring(0, 1);
|
||||
addressInfo.BeginAddress = Convert.ToInt32(address.Substring(1));
|
||||
addressInfo.BeginAddress = Convert.ToInt32(address.Substring(1).Split('.')[0]);
|
||||
break;
|
||||
}
|
||||
case 'H'://HR区
|
||||
|
@ -866,7 +866,7 @@ namespace IoTClient.Clients.PLC
|
|||
addressInfo.BitCode = 0x32;
|
||||
addressInfo.WordCode = 0xB2;
|
||||
addressInfo.TypeChar = address.Substring(0, 1);
|
||||
addressInfo.BeginAddress = Convert.ToInt32(address.Substring(1));
|
||||
addressInfo.BeginAddress = Convert.ToInt32(address.Substring(1).Split('.')[0]);
|
||||
break;
|
||||
}
|
||||
case 'A'://AR区
|
||||
|
@ -874,7 +874,7 @@ namespace IoTClient.Clients.PLC
|
|||
addressInfo.BitCode = 0x33;
|
||||
addressInfo.WordCode = 0xB3;
|
||||
addressInfo.TypeChar = address.Substring(0, 1);
|
||||
addressInfo.BeginAddress = Convert.ToInt32(address.Substring(1));
|
||||
addressInfo.BeginAddress = Convert.ToInt32(address.Substring(1).Split('.')[0]);
|
||||
break;
|
||||
}
|
||||
case 'E':
|
||||
|
@ -1070,9 +1070,11 @@ namespace IoTClient.Clients.PLC
|
|||
switch (tempMax.DataTypeEnum)
|
||||
{
|
||||
case DataTypeEnum.Bool:
|
||||
throw new Exception("暂时不支持Bool类型批量读取");
|
||||
case DataTypeEnum.Byte:
|
||||
readLength = tempMax.BeginAddress + 1 - minAddress;
|
||||
break;
|
||||
throw new Exception("暂时不支持Byte类型批量读取");
|
||||
//readLength = tempMax.BeginAddress + 1 - minAddress;
|
||||
//break;
|
||||
case DataTypeEnum.Int16:
|
||||
case DataTypeEnum.UInt16:
|
||||
readLength = tempMax.BeginAddress * 2 + 2 - minAddress * 2;
|
||||
|
|
|
@ -115,11 +115,12 @@ namespace IoTClient.Common.Helpers
|
|||
/// Int转二进制
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <param name="minLength">补0长度</param>
|
||||
/// <returns></returns>
|
||||
public static string IntToBinaryArray(this int value)
|
||||
public static string IntToBinaryArray(this int value, int minLength = 0)
|
||||
{
|
||||
//Convert.ToString(12,2); // 将12转为2进制字符串,结果 “1100”
|
||||
return Convert.ToString(value, 2);
|
||||
return Convert.ToString(value, 2).PadLeft(minLength, '0');
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -116,5 +116,53 @@ namespace IoTClient.Common.Helpers
|
|||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 字节格式转换
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <param name="format"></param>
|
||||
/// <param name="reverse">是否经过了反转</param>
|
||||
/// <returns></returns>
|
||||
public static byte[] ByteFormatting2(this byte[] value, EndianFormat format = EndianFormat.ABCD, bool reverse = true)
|
||||
{
|
||||
if (!reverse)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case EndianFormat.ABCD:
|
||||
format = EndianFormat.DCBA;
|
||||
break;
|
||||
case EndianFormat.BADC:
|
||||
format = EndianFormat.CDAB;
|
||||
break;
|
||||
case EndianFormat.CDAB:
|
||||
format = EndianFormat.BADC;
|
||||
break;
|
||||
case EndianFormat.DCBA:
|
||||
format = EndianFormat.ABCD;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
byte[] buffer;
|
||||
if (value.Length == 2)
|
||||
{
|
||||
buffer = new byte[2];
|
||||
switch (format)
|
||||
{
|
||||
case EndianFormat.BADC:
|
||||
buffer[0] = value[1];
|
||||
buffer[1] = value[0];
|
||||
break;
|
||||
default:
|
||||
buffer = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
return ByteFormatting(value, format, true);
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
62
IoTClient/Common/Helpers/ModbusHelper.cs
Normal file
62
IoTClient/Common/Helpers/ModbusHelper.cs
Normal file
|
@ -0,0 +1,62 @@
|
|||
using System;
|
||||
|
||||
namespace IoTClient.Common.Helpers
|
||||
{
|
||||
/// <summary>
|
||||
/// 帮助类
|
||||
/// </summary>
|
||||
public class ModbusHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// 是否为异常功能码
|
||||
/// </summary>
|
||||
/// <param name="resultCode"></param>
|
||||
/// <param name="responseCode"></param>
|
||||
/// <returns></returns>
|
||||
public static bool VerifyFunctionCode(byte resultCode, byte responseCode)
|
||||
{
|
||||
return responseCode - resultCode == 128;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异常码描述
|
||||
/// https://www.likecs.com/show-204655077.html?sc=5546
|
||||
/// </summary>
|
||||
/// <param name="errCode"></param>
|
||||
public static string ErrMsg(byte errCode)
|
||||
{
|
||||
var err = "未知异常";
|
||||
switch (errCode)
|
||||
{
|
||||
case 0x01:
|
||||
err = $"异常码{errCode}:⾮法功能";
|
||||
break;
|
||||
case 0x02:
|
||||
err = $"异常码{errCode}:⾮法数据地址";
|
||||
break;
|
||||
case 0x03:
|
||||
err = $"异常码{errCode}:⾮法数据值";
|
||||
break;
|
||||
case 0x04:
|
||||
err = $"异常码{errCode}:从站设备故障";
|
||||
break;
|
||||
case 0x05:
|
||||
err = $"异常码{errCode}:确认";
|
||||
break;
|
||||
case 0x06:
|
||||
err = $"异常码{errCode}:从属设备忙";
|
||||
break;
|
||||
case 0x08:
|
||||
err = $"异常码{errCode}:存储奇偶性差错";
|
||||
break;
|
||||
case 0x0A:
|
||||
err = $"异常码{errCode}:不可⽤⽹关路径";
|
||||
break;
|
||||
case 0x0B:
|
||||
err = $"异常码{errCode}:⽹关⽬标设备响应失败";
|
||||
break;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -12,7 +12,7 @@
|
|||
<Copyright>Copyright (c) 2022 农码一生. All rights reserved.</Copyright>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
<RepositoryUrl>https://github.com/zhaopeiym/IoTClient</RepositoryUrl>
|
||||
<PackageTags>IoT,物联网,PLC,Modbus,Bacnet</PackageTags>
|
||||
<PackageTags>Modbus,Bacnet,PLC,S7,ModbusTcp,三菱,西门子,欧姆龙,IoT,物联网,边缘计算</PackageTags>
|
||||
<PackageIconUrl>https://user-images.githubusercontent.com/5820324/66972725-12bccf80-f0c8-11e9-9468-3cfc57915dc9.png</PackageIconUrl>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
|
@ -53,6 +53,16 @@
|
|||
<param name="functionCode">功能码</param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IoTClient.Clients.Modbus.ModbusSerialBase.ReadInt16Bit(System.String,System.Byte,System.Byte,System.Boolean)">
|
||||
<summary>
|
||||
按位的方式读取
|
||||
</summary>
|
||||
<param name="address">寄存器地址:如1.00 ... 1.14、1.15</param>
|
||||
<param name="stationNumber">站号</param>
|
||||
<param name="functionCode">功能码</param>
|
||||
<param name="left">按位取值从左边开始取</param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IoTClient.Clients.Modbus.ModbusSerialBase.ReadUInt16(System.String,System.Byte,System.Byte)">
|
||||
<summary>
|
||||
读取UInt16
|
||||
|
@ -62,6 +72,16 @@
|
|||
<param name="functionCode">功能码</param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IoTClient.Clients.Modbus.ModbusSerialBase.ReadUInt16Bit(System.String,System.Byte,System.Byte,System.Boolean)">
|
||||
<summary>
|
||||
按位的方式读取
|
||||
</summary>
|
||||
<param name="address">寄存器地址:如1.00 ... 1.14、1.15</param>
|
||||
<param name="stationNumber">站号</param>
|
||||
<param name="functionCode">功能码</param>
|
||||
<param name="left">按位取值从左边开始取</param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IoTClient.Clients.Modbus.ModbusSerialBase.ReadInt32(System.String,System.Byte,System.Byte)">
|
||||
<summary>
|
||||
读取Int32
|
||||
|
@ -415,6 +435,16 @@
|
|||
<param name="functionCode">功能码</param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IoTClient.Clients.Modbus.IModbusClient.ReadInt16Bit(System.String,System.Byte,System.Byte,System.Boolean)">
|
||||
<summary>
|
||||
按位的方式读取
|
||||
</summary>
|
||||
<param name="address">寄存器地址:如1.00 ... 1.14、1.15</param>
|
||||
<param name="stationNumber">站号</param>
|
||||
<param name="functionCode">功能码</param>
|
||||
<param name="left">按位取值从左边开始取</param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IoTClient.Clients.Modbus.IModbusClient.ReadInt16(System.String,System.String,System.Byte[])">
|
||||
<summary>
|
||||
从批量读取的数据字节提取对应的地址数据
|
||||
|
@ -442,6 +472,16 @@
|
|||
<param name="values"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IoTClient.Clients.Modbus.IModbusClient.ReadUInt16Bit(System.String,System.Byte,System.Byte,System.Boolean)">
|
||||
<summary>
|
||||
按位的方式读取
|
||||
</summary>
|
||||
<param name="address">寄存器地址:如1.00 ... 1.14、1.15</param>
|
||||
<param name="stationNumber">站号</param>
|
||||
<param name="functionCode">功能码</param>
|
||||
<param name="left">按位取值从左边开始取</param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IoTClient.Clients.Modbus.IModbusClient.ReadInt32(System.String,System.Byte,System.Byte)">
|
||||
<summary>
|
||||
读取Int32
|
||||
|
@ -836,6 +876,16 @@
|
|||
<param name="functionCode">功能码</param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IoTClient.Clients.Modbus.ModbusRtuOverTcpClient.ReadInt16Bit(System.String,System.Byte,System.Byte,System.Boolean)">
|
||||
<summary>
|
||||
按位的方式读取
|
||||
</summary>
|
||||
<param name="address">寄存器地址:如1.00 ... 1.14、1.15</param>
|
||||
<param name="stationNumber">站号</param>
|
||||
<param name="functionCode">功能码</param>
|
||||
<param name="left">按位取值从左边开始取</param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IoTClient.Clients.Modbus.ModbusRtuOverTcpClient.ReadUInt16(System.String,System.Byte,System.Byte)">
|
||||
<summary>
|
||||
读取UInt16
|
||||
|
@ -845,6 +895,16 @@
|
|||
<param name="functionCode">功能码</param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IoTClient.Clients.Modbus.ModbusRtuOverTcpClient.ReadUInt16Bit(System.String,System.Byte,System.Byte,System.Boolean)">
|
||||
<summary>
|
||||
按位的方式读取
|
||||
</summary>
|
||||
<param name="address">寄存器地址:如1.00 ... 1.14、1.15</param>
|
||||
<param name="stationNumber">站号</param>
|
||||
<param name="functionCode">功能码</param>
|
||||
<param name="left">按位取值从左边开始取</param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IoTClient.Clients.Modbus.ModbusRtuOverTcpClient.ReadInt32(System.String,System.Byte,System.Byte)">
|
||||
<summary>
|
||||
读取Int32
|
||||
|
@ -1206,6 +1266,16 @@
|
|||
<param name="functionCode">功能码</param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IoTClient.Clients.Modbus.ModbusTcpClient.ReadInt16Bit(System.String,System.Byte,System.Byte,System.Boolean)">
|
||||
<summary>
|
||||
按位的方式读取
|
||||
</summary>
|
||||
<param name="address">寄存器地址:如1.00 ... 1.14、1.15</param>
|
||||
<param name="stationNumber">站号</param>
|
||||
<param name="functionCode">功能码</param>
|
||||
<param name="left">按位取值从左边开始取</param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<!-- Badly formed XML comment ignored for member "M:IoTClient.Clients.Modbus.ModbusTcpClient.ReadInt16(System.Int32,System.Byte,System.Byte)" -->
|
||||
<member name="M:IoTClient.Clients.Modbus.ModbusTcpClient.ReadUInt16(System.String,System.Byte,System.Byte)">
|
||||
<summary>
|
||||
|
@ -1216,6 +1286,16 @@
|
|||
<param name="functionCode">功能码</param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IoTClient.Clients.Modbus.ModbusTcpClient.ReadUInt16Bit(System.String,System.Byte,System.Byte,System.Boolean)">
|
||||
<summary>
|
||||
按位的方式读取
|
||||
</summary>
|
||||
<param name="address">寄存器地址:如1.00 ... 1.14、1.15</param>
|
||||
<param name="stationNumber">站号</param>
|
||||
<param name="functionCode">功能码</param>
|
||||
<param name="left">按位取值从左边开始取</param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IoTClient.Clients.Modbus.ModbusTcpClient.ReadUInt16(System.Int32,System.Byte,System.Byte)">
|
||||
<summary>
|
||||
读取UInt16类型数据
|
||||
|
@ -3286,11 +3366,12 @@
|
|||
<param name="str"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IoTClient.Common.Helpers.DataConvert.IntToBinaryArray(System.Int32)">
|
||||
<member name="M:IoTClient.Common.Helpers.DataConvert.IntToBinaryArray(System.Int32,System.Int32)">
|
||||
<summary>
|
||||
Int转二进制
|
||||
</summary>
|
||||
<param name="value"></param>
|
||||
<param name="minLength">补0长度</param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IoTClient.Common.Helpers.DataConvert.BinaryArrayToInt(System.String)">
|
||||
|
@ -3314,6 +3395,15 @@
|
|||
<param name="reverse">是否经过了反转</param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IoTClient.Common.Helpers.EndianConversion.ByteFormatting2(System.Byte[],IoTClient.Enums.EndianFormat,System.Boolean)">
|
||||
<summary>
|
||||
字节格式转换
|
||||
</summary>
|
||||
<param name="value"></param>
|
||||
<param name="format"></param>
|
||||
<param name="reverse">是否经过了反转</param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="T:IoTClient.Common.Helpers.EnumerableExtension">
|
||||
<summary>
|
||||
|
||||
|
@ -3348,6 +3438,26 @@
|
|||
<param name="value"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="T:IoTClient.Common.Helpers.ModbusHelper">
|
||||
<summary>
|
||||
帮助类
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:IoTClient.Common.Helpers.ModbusHelper.VerifyFunctionCode(System.Byte,System.Byte)">
|
||||
<summary>
|
||||
是否为异常功能码
|
||||
</summary>
|
||||
<param name="resultCode"></param>
|
||||
<param name="responseCode"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IoTClient.Common.Helpers.ModbusHelper.ErrMsg(System.Byte)">
|
||||
<summary>
|
||||
异常码描述
|
||||
https://www.likecs.com/show-204655077.html?sc=5546
|
||||
</summary>
|
||||
<param name="errCode"></param>
|
||||
</member>
|
||||
<member name="T:IoTClient.Common.Helpers.SocketHelper">
|
||||
<summary>
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user