1
0
mirror of https://github.com/zhaopeiym/IoTClient synced 2025-10-12 21:20:37 +08:00

添加注释、补充使用说明

This commit is contained in:
BennyZhao 2021-04-19 20:19:51 +08:00
parent 9b8d98884d
commit c01ba65659
5 changed files with 528 additions and 150 deletions

View File

@ -1,7 +1,9 @@
using IoTClient.Clients.Modbus;
using IoTClient.Enums;
using IoTClient.Models;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net;
using System.Threading.Tasks;
using Xunit;
@ -19,6 +21,106 @@ namespace IoTClient.Tests.Modbus
client = new ModbusTcpClient(new IPEndPoint(ip, port));
}
[Fact]
public async Task ()
{
Random rnd = new Random((int)Stopwatch.GetTimestamp());
for (int i = 0; i < 10; i++)
{
#region
short short_number = (short)rnd.Next(short.MinValue, short.MaxValue);
ushort ushort_number = (ushort)rnd.Next(ushort.MinValue, ushort.MaxValue);
int int_number = rnd.Next(int.MinValue, int.MaxValue);
uint uint_number = (uint)Math.Abs(rnd.Next(int.MinValue, int.MaxValue));
long long_number = rnd.Next(int.MinValue, int.MaxValue);
ulong ulong_number = (ulong)Math.Abs(rnd.Next(int.MinValue, int.MaxValue));
float float_number = rnd.Next(int.MinValue, int.MaxValue) / 100;
double double_number = (double)rnd.Next(int.MinValue, int.MaxValue) / 100;
bool coil = int_number % 2 == 0;
#endregion
//写入地址:0 值为:short_number 站号:stationNumber 功能码:默认16(也可以自己传入对应的功能码)
client.Write("0", short_number, stationNumber, 16);
client.Write("4", ushort_number, stationNumber, 16);
client.Write("8", int_number, stationNumber, 16);
client.Write("12", uint_number, stationNumber, 16);
client.Write("16", long_number, stationNumber, 16);
client.Write("20", ulong_number, stationNumber, 16);
client.Write("24", float_number, stationNumber, 16);
client.Write("28", double_number, stationNumber, 16);
client.Write("32", coil, stationNumber, 5);
//写入可能有一定的延时500毫秒后检验
await Task.Delay(500);
//读取地址:0 站号:stationNumber 功能码:默认16(也可以自己传入对应的功能码)
var read_short_number = client.ReadInt16("0", stationNumber, 3).Value;
Assert.True(read_short_number == short_number);
Assert.True(client.ReadUInt16("4", stationNumber, 3).Value == ushort_number);
Assert.True(client.ReadInt32("8", stationNumber, 3).Value == int_number);
Assert.True(client.ReadUInt32("12", stationNumber, 3).Value == uint_number);
Assert.True(client.ReadInt64("16", stationNumber, 3).Value == long_number);
Assert.True(client.ReadUInt64("20", stationNumber, 3).Value == ulong_number);
Assert.True(client.ReadFloat("24", stationNumber, 3).Value == float_number);
Assert.True(client.ReadDouble("28", stationNumber, 3).Value == double_number);
Assert.True(client.ReadCoil("32", stationNumber, 1).Value == coil);
}
}
[Fact]
public async Task ()
{
client.Open();
Random rnd = new Random((int)Stopwatch.GetTimestamp());
for (int i = 0; i < 10; i++)
{
#region
short short_number = (short)rnd.Next(short.MinValue, short.MaxValue);
ushort ushort_number = (ushort)rnd.Next(ushort.MinValue, ushort.MaxValue);
int int_number = rnd.Next(int.MinValue, int.MaxValue);
uint uint_number = (uint)Math.Abs(rnd.Next(int.MinValue, int.MaxValue));
long long_number = rnd.Next(int.MinValue, int.MaxValue);
ulong ulong_number = (ulong)Math.Abs(rnd.Next(int.MinValue, int.MaxValue));
float float_number = rnd.Next(int.MinValue, int.MaxValue) / 100;
double double_number = (double)rnd.Next(int.MinValue, int.MaxValue) / 100;
bool coil = int_number % 2 == 0;
#endregion
//写入地址:0 值为:short_number 站号:stationNumber 功能码:默认16(也可以自己传入对应的功能码)
client.Write("0", short_number, stationNumber, 16);
client.Write("4", ushort_number, stationNumber, 16);
client.Write("8", int_number, stationNumber, 16);
client.Write("12", uint_number, stationNumber, 16);
client.Write("16", long_number, stationNumber, 16);
client.Write("20", ulong_number, stationNumber, 16);
client.Write("24", float_number, stationNumber, 16);
client.Write("28", double_number, stationNumber, 16);
client.Write("32", coil, stationNumber, 5);
//写入可能有一定的延时500毫秒后检验
await Task.Delay(500);
//读取地址:0 站号:stationNumber 功能码:默认16(也可以自己传入对应的功能码)
var read_short_number = client.ReadInt16("0", stationNumber, 3).Value;
Assert.True(read_short_number == short_number);
Assert.True(client.ReadUInt16("4", stationNumber, 3).Value == ushort_number);
Assert.True(client.ReadInt32("8", stationNumber, 3).Value == int_number);
Assert.True(client.ReadUInt32("12", stationNumber, 3).Value == uint_number);
Assert.True(client.ReadInt64("16", stationNumber, 3).Value == long_number);
Assert.True(client.ReadUInt64("20", stationNumber, 3).Value == ulong_number);
Assert.True(client.ReadFloat("24", stationNumber, 3).Value == float_number);
Assert.True(client.ReadDouble("28", stationNumber, 3).Value == double_number);
Assert.True(client.ReadCoil("32", stationNumber, 1).Value == coil);
}
client.Close();
}
[Fact]
public void ()
{
@ -61,91 +163,5 @@ namespace IoTClient.Tests.Modbus
});
var result = client.BatchRead(list);
}
/// <summary>
/// Modbus值的写入有一定的延时500毫秒后检验
/// </summary>
/// <returns></returns>
[Fact]
public async Task ()
{
short Number = 33;
client.Write("4", Number, stationNumber);
await Task.Delay(500);
Assert.True(client.ReadInt16("4", stationNumber).Value == Number);
Number = 34;
client.Write("4", Number, stationNumber);
await Task.Delay(500);
Assert.True(client.ReadInt16("4", stationNumber).Value == Number);
Number = 1;
client.Write("12", Number, stationNumber);
await Task.Delay(500);
Assert.True(client.ReadInt16("12", stationNumber).Value == 1);
Number = 0;
client.Write("12", Number, stationNumber);
await Task.Delay(500);
Assert.True(client.ReadInt16("12", stationNumber).Value == 0);
int numberInt32 = -12;
client.Write("4", numberInt32, stationNumber);
await Task.Delay(500);
Assert.True(client.ReadInt32("4", stationNumber).Value == numberInt32);
float numberFloat = 112;
client.Write("4", numberFloat, stationNumber);
await Task.Delay(500);
Assert.True(client.ReadFloat("4", stationNumber).Value == numberFloat);
double numberDouble = 32;
client.Write("4", numberDouble, stationNumber);
await Task.Delay(500);
Assert.True(client.ReadDouble("4", stationNumber).Value == numberDouble);
}
[Fact]
public async Task ()
{
client.Open();
short Number = 33;
client.Write("4", Number, stationNumber);
await Task.Delay(500);
Assert.True(client.ReadInt16("4", stationNumber).Value == Number);
Number = 34;
client.Write("4", Number, stationNumber);
await Task.Delay(500);
Assert.True(client.ReadInt16("4", stationNumber).Value == Number);
Number = 1;
client.Write("12", Number, stationNumber);
await Task.Delay(500);
Assert.True(client.ReadInt16("12", stationNumber).Value == 1);
Number = 0;
client.Write("12", Number, stationNumber);
await Task.Delay(500);
Assert.True(client.ReadInt16("12", stationNumber).Value == 0);
int numberInt32 = -12;
client.Write("4", numberInt32, stationNumber);
await Task.Delay(500);
Assert.True(client.ReadInt32("4", stationNumber).Value == numberInt32);
float numberFloat = 112;
client.Write("4", numberFloat, stationNumber);
await Task.Delay(500);
Assert.True(client.ReadFloat("4", stationNumber).Value == numberFloat);
double numberDouble = 32;
client.Write("4", numberDouble, stationNumber);
await Task.Delay(500);
Assert.True(client.ReadDouble("4", stationNumber).Value == numberDouble);
client.Close();
}
}
}

View File

@ -188,7 +188,7 @@ namespace IoTClient.Clients.Modbus
}
/// <summary>
/// 读取Int16
/// 读取Int16类型数据
/// </summary>
/// <param name="address">寄存器起始地址</param>
/// <param name="stationNumber">站号</param>
@ -210,13 +210,19 @@ namespace IoTClient.Clients.Modbus
return result.EndTime();
}
/// <summary>
/// 读取Int16类型数据
/// </summary>
/// <param name="address">寄存器起始地址</param>
/// <param name="stationNumber">站号</param>
/// <param name="functionCode">功能码</param
public Result<short> ReadInt16(int address, byte stationNumber = 1, byte functionCode = 3)
{
return ReadInt16(address.ToString(), stationNumber, functionCode);
}
/// <summary>
/// 读取UInt16
/// 读取UInt16类型数据
/// </summary>
/// <param name="address">寄存器起始地址</param>
/// <param name="stationNumber">站号</param>
@ -238,13 +244,20 @@ namespace IoTClient.Clients.Modbus
return result.EndTime();
}
/// <summary>
/// 读取UInt16类型数据
/// </summary>
/// <param name="address">寄存器起始地址</param>
/// <param name="stationNumber">站号</param>
/// <param name="functionCode">功能码</param>
/// <returns></returns>
public Result<ushort> ReadUInt16(int address, byte stationNumber = 1, byte functionCode = 3)
{
return ReadUInt16(address.ToString(), stationNumber, functionCode);
}
/// <summary>
/// 读取Int32
/// 读取Int32类型数据
/// </summary>
/// <param name="address">寄存器起始地址</param>
/// <param name="stationNumber">站号</param>
@ -266,6 +279,13 @@ namespace IoTClient.Clients.Modbus
return result.EndTime();
}
/// <summary>
/// 读取Int32类型数据
/// </summary>
/// <param name="address">寄存器起始地址</param>
/// <param name="stationNumber">站号</param>
/// <param name="functionCode">功能码</param>
/// <returns></returns>
public Result<int> ReadInt32(int address, byte stationNumber = 1, byte functionCode = 3)
{
return ReadInt32(address.ToString(), stationNumber, functionCode);
@ -273,7 +293,7 @@ namespace IoTClient.Clients.Modbus
/// <summary>
/// 读取UInt32
/// 读取UInt32类型数据
/// </summary>
/// <param name="address">寄存器起始地址</param>
/// <param name="stationNumber">站号</param>
@ -295,13 +315,20 @@ namespace IoTClient.Clients.Modbus
return result.EndTime();
}
/// <summary>
/// 读取UInt32类型数据
/// </summary>
/// <param name="address">寄存器起始地址</param>
/// <param name="stationNumber">站号</param>
/// <param name="functionCode">功能码</param>
/// <returns></returns>
public Result<uint> ReadUInt32(int address, byte stationNumber = 1, byte functionCode = 3)
{
return ReadUInt32(address.ToString(), stationNumber, functionCode);
}
/// <summary>
/// 读取Int64
/// 读取Int64类型数据
/// </summary>
/// <param name="address">寄存器起始地址</param>
/// <param name="stationNumber">站号</param>
@ -323,13 +350,20 @@ namespace IoTClient.Clients.Modbus
return result.EndTime();
}
/// <summary>
/// 读取Int64类型数据
/// </summary>
/// <param name="address">寄存器起始地址</param>
/// <param name="stationNumber">站号</param>
/// <param name="functionCode">功能码</param>
/// <returns></returns>
public Result<long> ReadInt64(int address, byte stationNumber = 1, byte functionCode = 3)
{
return ReadInt64(address.ToString(), stationNumber, functionCode);
}
/// <summary>
/// 读取UInt64
/// 读取UInt64类型数据
/// </summary>
/// <param name="address">寄存器起始地址</param>
/// <param name="stationNumber">站号</param>
@ -351,13 +385,20 @@ namespace IoTClient.Clients.Modbus
return result.EndTime();
}
/// <summary>
/// 读取UInt64类型数据
/// </summary>
/// <param name="address">寄存器起始地址</param>
/// <param name="stationNumber">站号</param>
/// <param name="functionCode">功能码</param>
/// <returns></returns>
public Result<ulong> ReadUInt64(int address, byte stationNumber = 1, byte functionCode = 3)
{
return ReadUInt64(address.ToString(), stationNumber, functionCode);
}
/// <summary>
/// 读取Float
/// 读取Float类型数据
/// </summary>
/// <param name="address">寄存器起始地址</param>
/// <param name="stationNumber">站号</param>
@ -379,13 +420,20 @@ namespace IoTClient.Clients.Modbus
return result.EndTime();
}
/// <summary>
/// 读取Float类型数据
/// </summary>
/// <param name="address">寄存器起始地址</param>
/// <param name="stationNumber">站号</param>
/// <param name="functionCode">功能码</param>
/// <returns></returns>
public Result<float> ReadFloat(int address, byte stationNumber = 1, byte functionCode = 3)
{
return ReadFloat(address.ToString(), stationNumber, functionCode);
}
/// <summary>
/// 读取Double
/// 读取Double类型数据
/// </summary>
/// <param name="address">寄存器起始地址</param>
/// <param name="stationNumber">站号</param>
@ -407,13 +455,20 @@ namespace IoTClient.Clients.Modbus
return result.EndTime();
}
/// <summary>
/// 读取Double类型数据
/// </summary>
/// <param name="address">寄存器起始地址</param>
/// <param name="stationNumber">站号</param>
/// <param name="functionCode">功能码</param>
/// <returns></returns>
public Result<double> ReadDouble(int address, byte stationNumber = 1, byte functionCode = 3)
{
return ReadDouble(address.ToString(), stationNumber, functionCode);
}
/// <summary>
/// 读取线圈
/// 读取线圈类型数据
/// </summary>
/// <param name="address">寄存器起始地址</param>
/// <param name="stationNumber">站号</param>
@ -435,17 +490,24 @@ namespace IoTClient.Clients.Modbus
return result.EndTime();
}
/// <summary>
/// 读取线圈类型数据
/// </summary>
/// <param name="address">寄存器起始地址</param>
/// <param name="stationNumber">站号</param>
/// <param name="functionCode">功能码</param>
/// <returns></returns>
public Result<bool> ReadCoil(int address, byte stationNumber = 1, byte functionCode = 1)
{
return ReadCoil(address.ToString(), stationNumber, functionCode);
}
/// <summary>
/// 读取离散
/// 读取离散类型数据
/// </summary>
/// <param name="address">读取地址</param>
/// <param name="stationNumber"></param>
/// <param name="functionCode"></param>
/// <param name="stationNumber">站号</param>
/// <param name="functionCode">功能码</param>
/// <returns></returns>
public Result<bool> ReadDiscrete(string address, byte stationNumber = 1, byte functionCode = 2)
{
@ -463,6 +525,13 @@ namespace IoTClient.Clients.Modbus
return result.EndTime();
}
/// <summary>
/// 读取离散类型数据
/// </summary>
/// <param name="address">读取地址</param>
/// <param name="stationNumber">站号</param>
/// <param name="functionCode">功能码</param>
/// <returns></returns>
public Result<bool> ReadDiscrete(int address, byte stationNumber = 1, byte functionCode = 2)
{
return ReadDiscrete(address.ToString(), stationNumber, functionCode);
@ -498,6 +567,13 @@ namespace IoTClient.Clients.Modbus
}
}
/// <summary>
/// 从批量读取的数据字节提取对应的地址数据
/// </summary>
/// <param name="beginAddress">批量读取的起始地址</param>
/// <param name="address">读取地址</param>
/// <param name="values">批量读取的值</param>
/// <returns></returns>
public Result<short> ReadInt16(int beginAddress, int address, byte[] values)
{
return ReadInt16(beginAddress.ToString(), address.ToString(), values);
@ -533,6 +609,13 @@ namespace IoTClient.Clients.Modbus
}
}
/// <summary>
/// 从批量读取的数据字节提取对应的地址数据
/// </summary>
/// <param name="beginAddress">批量读取的起始地址</param>
/// <param name="address">读取地址</param>
/// <param name="values">批量读取的值</param>
/// <returns></returns>
public Result<ushort> ReadUInt16(int beginAddress, int address, byte[] values)
{
return ReadUInt16(beginAddress.ToString(), address.ToString(), values);
@ -569,6 +652,13 @@ namespace IoTClient.Clients.Modbus
}
}
/// <summary>
/// 从批量读取的数据字节提取对应的地址数据
/// </summary>
/// <param name="beginAddress">批量读取的起始地址</param>
/// <param name="address">读取地址</param>
/// <param name="values">批量读取的值</param>
/// <returns></returns>
public Result<int> ReadInt32(int beginAddress, int address, byte[] values)
{
return ReadInt32(beginAddress.ToString(), address.ToString(), values);
@ -605,6 +695,13 @@ namespace IoTClient.Clients.Modbus
}
}
/// <summary>
/// 从批量读取的数据字节提取对应的地址数据
/// </summary>
/// <param name="beginAddress">批量读取的起始地址</param>
/// <param name="address">读取地址</param>
/// <param name="values">批量读取的值</param>
/// <returns></returns>
public Result<uint> ReadUInt32(int beginAddress, int address, byte[] values)
{
return ReadUInt32(beginAddress.ToString(), address.ToString(), values);
@ -641,6 +738,13 @@ namespace IoTClient.Clients.Modbus
}
}
/// <summary>
/// 从批量读取的数据字节提取对应的地址数据
/// </summary>
/// <param name="beginAddress">批量读取的起始地址</param>
/// <param name="address">读取地址</param>
/// <param name="values">批量读取的值</param>
/// <returns></returns>
public Result<long> ReadInt64(int beginAddress, int address, byte[] values)
{
return ReadInt64(beginAddress.ToString(), address.ToString(), values);
@ -677,6 +781,13 @@ namespace IoTClient.Clients.Modbus
}
}
/// <summary>
/// 从批量读取的数据字节提取对应的地址数据
/// </summary>
/// <param name="beginAddress">批量读取的起始地址</param>
/// <param name="address">读取地址</param>
/// <param name="values">批量读取的值</param>
/// <returns></returns>
public Result<ulong> ReadUInt64(int beginAddress, int address, byte[] values)
{
return ReadUInt64(beginAddress.ToString(), address.ToString(), values);
@ -713,6 +824,13 @@ namespace IoTClient.Clients.Modbus
}
}
/// <summary>
/// 从批量读取的数据字节提取对应的地址数据
/// </summary>
/// <param name="beginAddress">批量读取的起始地址</param>
/// <param name="address">读取地址</param>
/// <param name="values">批量读取的值</param>
/// <returns></returns>
public Result<float> ReadFloat(int beginAddress, int address, byte[] values)
{
return ReadFloat(beginAddress.ToString(), address.ToString(), values);
@ -749,6 +867,13 @@ namespace IoTClient.Clients.Modbus
}
}
/// <summary>
/// 从批量读取的数据字节提取对应的地址数据
/// </summary>
/// <param name="beginAddress">批量读取的起始地址</param>
/// <param name="address">读取地址</param>
/// <param name="values">批量读取的值</param>
/// <returns></returns>
public Result<double> ReadDouble(int beginAddress, int address, byte[] values)
{
return ReadDouble(beginAddress.ToString(), address.ToString(), values);
@ -788,6 +913,13 @@ namespace IoTClient.Clients.Modbus
}
}
/// <summary>
/// 从批量读取的数据字节提取对应的地址数据
/// </summary>
/// <param name="beginAddress">批量读取的起始地址</param>
/// <param name="address">读取地址</param>
/// <param name="values">批量读取的值</param>
/// <returns></returns>
public Result<bool> ReadCoil(int beginAddress, int address, byte[] values)
{
return ReadCoil(beginAddress.ToString(), address.ToString(), values);
@ -827,6 +959,13 @@ namespace IoTClient.Clients.Modbus
}
}
/// <summary>
/// 从批量读取的数据字节提取对应的地址数据
/// </summary>
/// <param name="beginAddress">批量读取的起始地址</param>
/// <param name="address">读取地址</param>
/// <param name="values">批量读取的值</param>
/// <returns></returns>
public Result<bool> ReadDiscrete(int beginAddress, int address, byte[] values)
{
return ReadDiscrete(beginAddress.ToString(), address.ToString(), values);
@ -1088,8 +1227,8 @@ namespace IoTClient.Clients.Modbus
/// </summary>
/// <param name="address">读取地址</param>
/// <param name="value"></param>
/// <param name="stationNumber"></param>
/// <param name="functionCode"></param>
/// <param name="stationNumber">站号</param>
/// <param name="functionCode">功能码</param>
public Result Write(string address, bool value, byte stationNumber = 1, byte functionCode = 5)
{
if (!socket?.Connected ?? true) Connect();
@ -1136,8 +1275,8 @@ namespace IoTClient.Clients.Modbus
/// </summary>
/// <param name="address">读取地址</param>
/// <param name="values">批量读取的值</param>
/// <param name="stationNumber"></param>
/// <param name="functionCode"></param>
/// <param name="stationNumber">站号</param>
/// <param name="functionCode">功能码</param>
/// <returns></returns>
public Result Write(string address, byte[] values, byte stationNumber = 1, byte functionCode = 16)
{

View File

@ -13,6 +13,7 @@ namespace IoTClient.Clients.PLC
{
/// <summary>
/// 欧姆龙PLC 客户端 - Beta
/// https://flat2010.github.io/2020/02/23/Omron-Fins%E5%8D%8F%E8%AE%AE/
/// </summary>
public class OmronFinsClient : SocketBase, IEthernetClient
{
@ -24,9 +25,11 @@ namespace IoTClient.Clients.PLC
/// </summary>
private byte[] BasicCommand = new byte[]
{
0x46, 0x49, 0x4E, 0x53, 0x00, 0x00, 0x00, 0x0C,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01
0x46, 0x49, 0x4E, 0x53,//Magic字段 0x46494E53 对应的ASCII码即FINS
0x00, 0x00, 0x00, 0x0C,//Length字段 表示其后所有字段的总长度
0x00, 0x00, 0x00, 0x00,//Command字段
0x00, 0x00, 0x00, 0x00,//Error Code字段
0x00, 0x00, 0x00, 0x01 //Client/Server Node Address字段
};
/// <summary>
@ -50,9 +53,12 @@ namespace IoTClient.Clients.PLC
public LoggerDelegate WarningLog { get; set; }
/// <summary>
/// 单元号地址
/// DA2(即Destination unit address目标单元地址)
/// 0x00PC(CPU)
/// 0xFE SYSMAC NET Link Unit or SYSMAC LINK Unit connected to network
/// 0x10~0x1FCPU总线单元 其值等于10 + 单元号(前端面板中配置的单元号)
/// </summary>
public byte UnitNumber { get; set; } = 0x00;
public byte UnitAddress { get; set; } = 0x00;
/// <summary>
///
@ -61,7 +67,7 @@ namespace IoTClient.Clients.PLC
/// <param name="port"></param>
/// <param name="timeout"></param>
/// <param name="endianFormat"></param>
public OmronFinsClient(string ip, int port, int timeout = 1500, EndianFormat endianFormat = EndianFormat.CDAB)
public OmronFinsClient(string ip, int port = 9600, int timeout = 1500, EndianFormat endianFormat = EndianFormat.CDAB)
{
IpAndPoint = new IPEndPoint(IPAddress.Parse(ip), port); ;
this.timeout = timeout;
@ -601,19 +607,19 @@ namespace IoTClient.Clients.PLC
tmp.CopyTo(command, 4);
command[11] = 0x02;
command[16] = 0x80; //信息控制字段
command[17] = 0x00;
command[18] = 0x02;
command[19] = 0x00;
command[20] = 0x13; //0x13; //01(节点地址:Ip地址的最后一位)
command[21] = UnitNumber; //单元号地址(传过来)
command[22] = 0x00;
command[23] = 0x0B; //0x0B; //01(节点地址:Ip地址的最后一位)
command[24] = 0x00;
command[25] = 0x00;
command[16] = 0x80; //ICF 信息控制字段
command[17] = 0x00; //RSV 保留字段
command[18] = 0x02; //GCT 网关计数
command[19] = 0x00; //DNA 目标网络地址 00:表示本地网络 0x01~0x7F:表示远程网络
command[20] = 0x13; //DA1 目标节点编号 0x01~0x3E:SYSMAC LINK网络中的节点号 0x01~0x7E:YSMAC NET网络中的节点号 0xFF:广播传输
command[21] = UnitAddress; //DA2 目标单元地址
command[22] = 0x00; //SNA 源网络地址 取值及含义同DNA字段
command[23] = 0x0B; //SA1 源节点编号 取值及含义同DA1字段
command[24] = 0x00; //SA2 源单元地址 取值及含义同DA2字段
command[25] = 0x00; //SID Service ID 取值0x00~0xFF产生会话的进程的唯一标识
command[26] = 0x01;
command[27] = 0x01; //
command[27] = 0x01; //Command Code 内存区域
command[28] = isBit ? arg.OmronFinsType.BitCode : arg.OmronFinsType.WordCode;
arg.Content.CopyTo(command, 29);
command[32] = (byte)(length / 256);
@ -632,19 +638,19 @@ namespace IoTClient.Clients.PLC
tmp.CopyTo(command, 4);
command[11] = 0x02;
command[16] = 0x80; //信息控制字段
command[17] = 0x00;
command[18] = 0x02;
command[19] = 0x00;
command[20] = 0x13; //0x13; //01(节点地址:Ip地址的最后一位)
command[21] = UnitNumber; //单元号地址(传过来)
command[22] = 0x00;
command[23] = 0x0B; //0x0B; //01(节点地址:Ip地址的最后一位)
command[24] = 0x00;
command[25] = 0x00;
command[16] = 0x80; //ICF 信息控制字段
command[17] = 0x00; //RSV 保留字段
command[18] = 0x02; //GCT 网关计数
command[19] = 0x00; //DNA 目标网络地址 00:表示本地网络 0x01~0x7F:表示远程网络
command[20] = 0x13; //DA1 目标节点编号 0x01~0x3E:SYSMAC LINK网络中的节点号 0x01~0x7E:YSMAC NET网络中的节点号 0xFF:广播传输
command[21] = UnitAddress; //DA2 目标单元地址
command[22] = 0x00; //SNA 源网络地址 取值及含义同DNA字段
command[23] = 0x0B; //SA1 源节点编号 取值及含义同DA1字段
command[24] = 0x00; //SA2 源单元地址 取值及含义同DA2字段
command[25] = 0x00; //SID Service ID 取值0x00~0xFF产生会话的进程的唯一标识
command[26] = 0x01;
command[27] = 0x02; //
command[27] = 0x02; //Command Code 内存区域
command[28] = isBit ? arg.OmronFinsType.BitCode : arg.OmronFinsType.WordCode;
arg.Content.CopyTo(command, 29);
command[32] = isBit ? (byte)(value.Length / 256) : (byte)(value.Length / 2 / 256);

View File

@ -1157,16 +1157,26 @@
</member>
<member name="M:IoTClient.Clients.Modbus.ModbusTcpClient.ReadInt16(System.String,System.Byte,System.Byte)">
<summary>
读取Int16
读取Int16类型数据
</summary>
<param name="address">寄存器起始地址</param>
<param name="stationNumber">站号</param>
<param name="functionCode">功能码</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>
读取UInt16
读取UInt16类型数据
</summary>
<param name="address">寄存器起始地址</param>
<param name="stationNumber">站号</param>
<param name="functionCode">功能码</param>
<returns></returns>
</member>
<member name="M:IoTClient.Clients.Modbus.ModbusTcpClient.ReadUInt16(System.Int32,System.Byte,System.Byte)">
<summary>
读取UInt16类型数据
</summary>
<param name="address">寄存器起始地址</param>
<param name="stationNumber">站号</param>
@ -1175,7 +1185,16 @@
</member>
<member name="M:IoTClient.Clients.Modbus.ModbusTcpClient.ReadInt32(System.String,System.Byte,System.Byte)">
<summary>
读取Int32
读取Int32类型数据
</summary>
<param name="address">寄存器起始地址</param>
<param name="stationNumber">站号</param>
<param name="functionCode">功能码</param>
<returns></returns>
</member>
<member name="M:IoTClient.Clients.Modbus.ModbusTcpClient.ReadInt32(System.Int32,System.Byte,System.Byte)">
<summary>
读取Int32类型数据
</summary>
<param name="address">寄存器起始地址</param>
<param name="stationNumber">站号</param>
@ -1184,7 +1203,16 @@
</member>
<member name="M:IoTClient.Clients.Modbus.ModbusTcpClient.ReadUInt32(System.String,System.Byte,System.Byte)">
<summary>
读取UInt32
读取UInt32类型数据
</summary>
<param name="address">寄存器起始地址</param>
<param name="stationNumber">站号</param>
<param name="functionCode">功能码</param>
<returns></returns>
</member>
<member name="M:IoTClient.Clients.Modbus.ModbusTcpClient.ReadUInt32(System.Int32,System.Byte,System.Byte)">
<summary>
读取UInt32类型数据
</summary>
<param name="address">寄存器起始地址</param>
<param name="stationNumber">站号</param>
@ -1193,7 +1221,16 @@
</member>
<member name="M:IoTClient.Clients.Modbus.ModbusTcpClient.ReadInt64(System.String,System.Byte,System.Byte)">
<summary>
读取Int64
读取Int64类型数据
</summary>
<param name="address">寄存器起始地址</param>
<param name="stationNumber">站号</param>
<param name="functionCode">功能码</param>
<returns></returns>
</member>
<member name="M:IoTClient.Clients.Modbus.ModbusTcpClient.ReadInt64(System.Int32,System.Byte,System.Byte)">
<summary>
读取Int64类型数据
</summary>
<param name="address">寄存器起始地址</param>
<param name="stationNumber">站号</param>
@ -1202,7 +1239,16 @@
</member>
<member name="M:IoTClient.Clients.Modbus.ModbusTcpClient.ReadUInt64(System.String,System.Byte,System.Byte)">
<summary>
读取UInt64
读取UInt64类型数据
</summary>
<param name="address">寄存器起始地址</param>
<param name="stationNumber">站号</param>
<param name="functionCode">功能码</param>
<returns></returns>
</member>
<member name="M:IoTClient.Clients.Modbus.ModbusTcpClient.ReadUInt64(System.Int32,System.Byte,System.Byte)">
<summary>
读取UInt64类型数据
</summary>
<param name="address">寄存器起始地址</param>
<param name="stationNumber">站号</param>
@ -1211,7 +1257,16 @@
</member>
<member name="M:IoTClient.Clients.Modbus.ModbusTcpClient.ReadFloat(System.String,System.Byte,System.Byte)">
<summary>
读取Float
读取Float类型数据
</summary>
<param name="address">寄存器起始地址</param>
<param name="stationNumber">站号</param>
<param name="functionCode">功能码</param>
<returns></returns>
</member>
<member name="M:IoTClient.Clients.Modbus.ModbusTcpClient.ReadFloat(System.Int32,System.Byte,System.Byte)">
<summary>
读取Float类型数据
</summary>
<param name="address">寄存器起始地址</param>
<param name="stationNumber">站号</param>
@ -1220,7 +1275,16 @@
</member>
<member name="M:IoTClient.Clients.Modbus.ModbusTcpClient.ReadDouble(System.String,System.Byte,System.Byte)">
<summary>
读取Double
读取Double类型数据
</summary>
<param name="address">寄存器起始地址</param>
<param name="stationNumber">站号</param>
<param name="functionCode">功能码</param>
<returns></returns>
</member>
<member name="M:IoTClient.Clients.Modbus.ModbusTcpClient.ReadDouble(System.Int32,System.Byte,System.Byte)">
<summary>
读取Double类型数据
</summary>
<param name="address">寄存器起始地址</param>
<param name="stationNumber">站号</param>
@ -1229,7 +1293,16 @@
</member>
<member name="M:IoTClient.Clients.Modbus.ModbusTcpClient.ReadCoil(System.String,System.Byte,System.Byte)">
<summary>
读取线圈
读取线圈类型数据
</summary>
<param name="address">寄存器起始地址</param>
<param name="stationNumber">站号</param>
<param name="functionCode">功能码</param>
<returns></returns>
</member>
<member name="M:IoTClient.Clients.Modbus.ModbusTcpClient.ReadCoil(System.Int32,System.Byte,System.Byte)">
<summary>
读取线圈类型数据
</summary>
<param name="address">寄存器起始地址</param>
<param name="stationNumber">站号</param>
@ -1238,11 +1311,20 @@
</member>
<member name="M:IoTClient.Clients.Modbus.ModbusTcpClient.ReadDiscrete(System.String,System.Byte,System.Byte)">
<summary>
读取离散
读取离散类型数据
</summary>
<param name="address">读取地址</param>
<param name="stationNumber"></param>
<param name="functionCode"></param>
<param name="stationNumber">站号</param>
<param name="functionCode">功能码</param>
<returns></returns>
</member>
<member name="M:IoTClient.Clients.Modbus.ModbusTcpClient.ReadDiscrete(System.Int32,System.Byte,System.Byte)">
<summary>
读取离散类型数据
</summary>
<param name="address">读取地址</param>
<param name="stationNumber">站号</param>
<param name="functionCode">功能码</param>
<returns></returns>
</member>
<member name="M:IoTClient.Clients.Modbus.ModbusTcpClient.ReadInt16(System.String,System.String,System.Byte[])">
@ -1254,6 +1336,15 @@
<param name="values">批量读取的值</param>
<returns></returns>
</member>
<member name="M:IoTClient.Clients.Modbus.ModbusTcpClient.ReadInt16(System.Int32,System.Int32,System.Byte[])">
<summary>
从批量读取的数据字节提取对应的地址数据
</summary>
<param name="beginAddress">批量读取的起始地址</param>
<param name="address">读取地址</param>
<param name="values">批量读取的值</param>
<returns></returns>
</member>
<member name="M:IoTClient.Clients.Modbus.ModbusTcpClient.ReadUInt16(System.String,System.String,System.Byte[])">
<summary>
从批量读取的数据字节提取对应的地址数据
@ -1263,6 +1354,15 @@
<param name="values">批量读取的值</param>
<returns></returns>
</member>
<member name="M:IoTClient.Clients.Modbus.ModbusTcpClient.ReadUInt16(System.Int32,System.Int32,System.Byte[])">
<summary>
从批量读取的数据字节提取对应的地址数据
</summary>
<param name="beginAddress">批量读取的起始地址</param>
<param name="address">读取地址</param>
<param name="values">批量读取的值</param>
<returns></returns>
</member>
<member name="M:IoTClient.Clients.Modbus.ModbusTcpClient.ReadInt32(System.String,System.String,System.Byte[])">
<summary>
从批量读取的数据字节提取对应的地址数据
@ -1272,6 +1372,15 @@
<param name="values">批量读取的值</param>
<returns></returns>
</member>
<member name="M:IoTClient.Clients.Modbus.ModbusTcpClient.ReadInt32(System.Int32,System.Int32,System.Byte[])">
<summary>
从批量读取的数据字节提取对应的地址数据
</summary>
<param name="beginAddress">批量读取的起始地址</param>
<param name="address">读取地址</param>
<param name="values">批量读取的值</param>
<returns></returns>
</member>
<member name="M:IoTClient.Clients.Modbus.ModbusTcpClient.ReadUInt32(System.String,System.String,System.Byte[])">
<summary>
从批量读取的数据字节提取对应的地址数据
@ -1281,6 +1390,15 @@
<param name="values">批量读取的值</param>
<returns></returns>
</member>
<member name="M:IoTClient.Clients.Modbus.ModbusTcpClient.ReadUInt32(System.Int32,System.Int32,System.Byte[])">
<summary>
从批量读取的数据字节提取对应的地址数据
</summary>
<param name="beginAddress">批量读取的起始地址</param>
<param name="address">读取地址</param>
<param name="values">批量读取的值</param>
<returns></returns>
</member>
<member name="M:IoTClient.Clients.Modbus.ModbusTcpClient.ReadInt64(System.String,System.String,System.Byte[])">
<summary>
从批量读取的数据字节提取对应的地址数据
@ -1290,6 +1408,15 @@
<param name="values">批量读取的值</param>
<returns></returns>
</member>
<member name="M:IoTClient.Clients.Modbus.ModbusTcpClient.ReadInt64(System.Int32,System.Int32,System.Byte[])">
<summary>
从批量读取的数据字节提取对应的地址数据
</summary>
<param name="beginAddress">批量读取的起始地址</param>
<param name="address">读取地址</param>
<param name="values">批量读取的值</param>
<returns></returns>
</member>
<member name="M:IoTClient.Clients.Modbus.ModbusTcpClient.ReadUInt64(System.String,System.String,System.Byte[])">
<summary>
从批量读取的数据字节提取对应的地址数据
@ -1299,6 +1426,15 @@
<param name="values">批量读取的值</param>
<returns></returns>
</member>
<member name="M:IoTClient.Clients.Modbus.ModbusTcpClient.ReadUInt64(System.Int32,System.Int32,System.Byte[])">
<summary>
从批量读取的数据字节提取对应的地址数据
</summary>
<param name="beginAddress">批量读取的起始地址</param>
<param name="address">读取地址</param>
<param name="values">批量读取的值</param>
<returns></returns>
</member>
<member name="M:IoTClient.Clients.Modbus.ModbusTcpClient.ReadFloat(System.String,System.String,System.Byte[])">
<summary>
从批量读取的数据字节提取对应的地址数据
@ -1308,6 +1444,15 @@
<param name="values">批量读取的值</param>
<returns></returns>
</member>
<member name="M:IoTClient.Clients.Modbus.ModbusTcpClient.ReadFloat(System.Int32,System.Int32,System.Byte[])">
<summary>
从批量读取的数据字节提取对应的地址数据
</summary>
<param name="beginAddress">批量读取的起始地址</param>
<param name="address">读取地址</param>
<param name="values">批量读取的值</param>
<returns></returns>
</member>
<member name="M:IoTClient.Clients.Modbus.ModbusTcpClient.ReadDouble(System.String,System.String,System.Byte[])">
<summary>
从批量读取的数据字节提取对应的地址数据
@ -1317,6 +1462,15 @@
<param name="values">批量读取的值</param>
<returns></returns>
</member>
<member name="M:IoTClient.Clients.Modbus.ModbusTcpClient.ReadDouble(System.Int32,System.Int32,System.Byte[])">
<summary>
从批量读取的数据字节提取对应的地址数据
</summary>
<param name="beginAddress">批量读取的起始地址</param>
<param name="address">读取地址</param>
<param name="values">批量读取的值</param>
<returns></returns>
</member>
<member name="M:IoTClient.Clients.Modbus.ModbusTcpClient.ReadCoil(System.String,System.String,System.Byte[])">
<summary>
从批量读取的数据字节提取对应的地址数据
@ -1326,6 +1480,15 @@
<param name="values">批量读取的值</param>
<returns></returns>
</member>
<member name="M:IoTClient.Clients.Modbus.ModbusTcpClient.ReadCoil(System.Int32,System.Int32,System.Byte[])">
<summary>
从批量读取的数据字节提取对应的地址数据
</summary>
<param name="beginAddress">批量读取的起始地址</param>
<param name="address">读取地址</param>
<param name="values">批量读取的值</param>
<returns></returns>
</member>
<member name="M:IoTClient.Clients.Modbus.ModbusTcpClient.ReadDiscrete(System.String,System.String,System.Byte[])">
<summary>
从批量读取的数据字节提取对应的地址数据
@ -1335,6 +1498,15 @@
<param name="values">批量读取的值</param>
<returns></returns>
</member>
<member name="M:IoTClient.Clients.Modbus.ModbusTcpClient.ReadDiscrete(System.Int32,System.Int32,System.Byte[])">
<summary>
从批量读取的数据字节提取对应的地址数据
</summary>
<param name="beginAddress">批量读取的起始地址</param>
<param name="address">读取地址</param>
<param name="values">批量读取的值</param>
<returns></returns>
</member>
<member name="M:IoTClient.Clients.Modbus.ModbusTcpClient.BatchRead(System.Collections.Generic.List{IoTClient.Models.ModbusInput})">
<summary>
分批读取(批量读取,内部进行批量计算读取)
@ -1348,8 +1520,8 @@
</summary>
<param name="address">读取地址</param>
<param name="value"></param>
<param name="stationNumber"></param>
<param name="functionCode"></param>
<param name="stationNumber">站号</param>
<param name="functionCode">功能码</param>
</member>
<member name="M:IoTClient.Clients.Modbus.ModbusTcpClient.Write(System.String,System.Byte[],System.Byte,System.Byte)">
<summary>
@ -1357,8 +1529,8 @@
</summary>
<param name="address">读取地址</param>
<param name="values">批量读取的值</param>
<param name="stationNumber"></param>
<param name="functionCode"></param>
<param name="stationNumber">站号</param>
<param name="functionCode">功能码</param>
<returns></returns>
</member>
<member name="M:IoTClient.Clients.Modbus.ModbusTcpClient.Write(System.String,System.Int16,System.Byte,System.Byte)">
@ -1756,6 +1928,7 @@
<member name="T:IoTClient.Clients.PLC.OmronFinsClient">
<summary>
欧姆龙PLC 客户端 - Beta
https://flat2010.github.io/2020/02/23/Omron-Fins%E5%8D%8F%E8%AE%AE/
</summary>
</member>
<member name="F:IoTClient.Clients.PLC.OmronFinsClient.BasicCommand">
@ -1783,9 +1956,12 @@
</summary>
</member>
<member name="P:IoTClient.Clients.PLC.OmronFinsClient.UnitNumber">
<member name="P:IoTClient.Clients.PLC.OmronFinsClient.UnitAddress">
<summary>
单元号地址
DA2(即Destination unit address目标单元地址)
0x00PC(CPU)
0xFE SYSMAC NET Link Unit or SYSMAC LINK Unit connected to network
0x10~0x1FCPU总线单元 其值等于10 + 单元号(前端面板中配置的单元号)
</summary>
</member>
<member name="M:IoTClient.Clients.PLC.OmronFinsClient.#ctor(System.String,System.Int32,System.Int32,IoTClient.Enums.EndianFormat)">

View File

@ -22,11 +22,32 @@ ModBusTcpClient client = new ModBusTcpClient("127.0.0.1", 502);
//2、写操作 - 参数依次是:地址 、值 、站号 、功能码
client.Write("4", (short)33, 2, 16);
client.Write("4", (short)3344, 2, 16);
//2.1、【注意】写入数据的时候需要明确数据类型
client.Write("0", (short)33, 2, 16); //写入的是short类型数值
client.Write("4", (ushort)33, 2, 16); //写入的是ushort类型数值
client.Write("8", (int)33, 2, 16); //写入的是int类型数值
client.Write("12", (uint)33, 2, 16); //写入的是uint类型数值
client.Write("16", (long)33, 2, 16); //写入的是long类型数值
client.Write("20", (ulong)33, 2, 16); //写入的是ulong类型数值
client.Write("24", (float)33, 2, 16); //写入的是float类型数值
client.Write("28", (double)33, 2, 16); //写入的是double类型数值
client.Write("32", true, 2, 5); //写入的是线圈类型数值
//3、读操作 - 参数依次是:地址 、站号 、功能码
var value = client.ReadInt16("4", 2, 3).Value;
var value2 = client.ReadInt32("4", 2, 3).Value;
//3.1、其他类型数据读取
client.ReadInt16("0", stationNumber, 3); //short类型数据读取
client.ReadUInt16("4", stationNumber, 3); //ushort类型数据读取
client.ReadInt32("8", stationNumber, 3); //int类型数据读取
client.ReadUInt32("12", stationNumber, 3); //uint类型数据读取
client.ReadInt64("16", stationNumber, 3); //long类型数据读取
client.ReadUInt64("20", stationNumber, 3); //ulong类型数据读取
client.ReadFloat("24", stationNumber, 3); //float类型数据读取
client.ReadDouble("28", stationNumber, 3); //double类型数据读取
client.ReadCoil("32", stationNumber, 1); //线圈类型数据读取
client.ReadDiscrete("32", stationNumber, 2);//离散类型数据读取
//4、如果没有主动Open则会每次读写操作的时候自动打开自动和关闭连接这样会使读写效率大大减低。所以建议手动Open和Close。
client.Open();
@ -74,6 +95,8 @@ var result = client.BatchRead(list);
ModBusTcpClient client = new ModBusTcpClient("127.0.0.1", 502, 1500, EndianFormat.ABCD);
```
### ModBusTcp更多使用方式请参考[单元测试](https://github.com/zhaopeiym/IoTClient/blob/master/IoTClient.Tests/Modbus_Tests/ModBusTcpClient_tests.cs)
## ModBusRtu读写操作
```
//实例化客户端 - [COM端口名称,波特率,数据位,停止位,奇偶校验]
@ -82,6 +105,24 @@ ModBusRtuClient client = new ModBusRtuClient("COM3", 9600, 8, StopBits.One, Pari
//其他读写操作和ModBusTcpClient的读写操作一致
```
## ModBusAscii读写操作
```
//实例化客户端 - [COM端口名称,波特率,数据位,停止位,奇偶校验]
ModbusAsciiClient client = new ModbusAsciiClient("COM3", 9600, 8, StopBits.One, Parity.None);
//其他读写操作和ModBusTcpClient的读写操作一致
```
## ModbusRtuOverTcp读写操作
```
//串口透传 即:用Tcp的方式发送Rtu格式报文
//实例化客户端 - IP、端口、超时时间、大小端设置
ModbusRtuOverTcpClient client = new ModbusRtuOverTcpClient("127.0.0.1", 502, 1500, EndianFormat.ABCD);
//其他读写操作和ModBusTcpClient的读写操作一致
```
## SiemensClient(西门子)读写操作
```
//1、实例化客户端 - 输入正确的IP和端口