IoT Device Communication Protocol Client Developed in C#

IoT Device Communication Protocol Client Developed in C#

Introduction

IoT Device Communication Protocol Client Developed in C#

IoTClient is a client implementing communication protocols for IoT devices, including mainstream PLC communication reading, ModBus protocol, Bacnet protocol, and other commonly used industrial communication protocols. This component is based on .NET Standard 2.0 and can be used for cross-platform development in .NET, such as Windows, Linux, and even on Raspberry Pi.

Technical Architecture

  1. 1. Programming Language: C#

  2. 2. Development Tool: Visual Studio 2019

  3. 3. Runtime Environment: .netstandard2.0

Supported Device Protocols

  1. 1. ModBusTcp read/write operations

  2. 2. ModBusRtu read/write operations

  3. 3. ModBusAscii read/write operations

  4. 4. ModbusRtuOverTcp read/write operations

  5. 5. SiemensClient read/write operations

  6. 6. MitsubishiClient read/write operations

  7. 7. OmronFinsClient read/write operations

  8. 8. AllenBradleyClient read/write operations

Usage Instructions

Reference Component

Nuget installation Install-Package IoTClient 

IoT Device Communication Protocol Client Developed in C#

ModBusTcp Read/Write Operations

//1. Instantiate the client - Enter the correct IP and port
ModBusTcpClient client = new ModBusTcpClient("127.0.0.1", 502);

//2. Write operation - Parameters are: address, value, station number, function code
client.Write("4", (short)33, 2, 16);

//2.1. [Note] When writing data, you need to specify the data type
client.Write("0", (short)33, 2, 16);    // Write short type value
client.Write("4", (ushort)33, 2, 16);   // Write ushort type value
client.Write("8", (int)33, 2, 16);      // Write int type value
client.Write("12", (uint)33, 2, 16);    // Write uint type value
client.Write("16", (long)33, 2, 16);    // Write long type value
client.Write("20", (ulong)33, 2, 16);   // Write ulong type value
client.Write("24", (float)33, 2, 16);   // Write float type value
client.Write("28", (double)33, 2, 16);  // Write double type value
client.Write("32", true, 2, 5);         // Write coil type value
client.Write("100", "orderCode", stationNumber);  // Write string

//3. Read operation - Parameters are: address, station number, function code
var value = client.ReadInt16("4", 2, 3).Value;

//3.1. Other types of data reading
client.ReadInt16("0", stationNumber, 3);    // Read short type data
client.ReadUInt16("4", stationNumber, 3);   // Read ushort type data
client.ReadInt32("8", stationNumber, 3);    // Read int type data
client.ReadUInt32("12", stationNumber, 3);  // Read uint type data
client.ReadInt64("16", stationNumber, 3);   // Read long type data
client.ReadUInt64("20", stationNumber, 3);  // Read ulong type data
client.ReadFloat("24", stationNumber, 3);   // Read float type data
client.ReadDouble("28", stationNumber, 3);  // Read double type data
client.ReadCoil("32", stationNumber, 1);    // Read coil type data
client.ReadDiscrete("32", stationNumber, 2);// Read discrete type data
client.ReadString("100", stationNumber,10); // Read string

//4. If not actively opened, the connection will automatically open and close with each read/write operation, which greatly reduces efficiency. It is recommended to manually open and close.
client.Open();

//5. Read/write operations will return the operation result object Result
var result = client.ReadInt16("4", 2, 3);
//5.1 Check if reading was successful (true or false)
var isSucceed = result.IsSucceed;
//5.2 Read failure exception message
var errMsg = result.Err;
//5.3 Read operation actual request message sent
var requst  = result.Requst;
//5.4 Read operation server response message
var response = result.Response;
//5.5 Read value
var value3 = result.Value;

//6. Batch reading
var list = new List<ModBusInput>();
list.Add(new ModBusInput()
{
    Address = "2",
    DataType = DataTypeEnum.Int16,
    FunctionCode = 3,
    StationNumber = 1
});
list.Add(new ModBusInput()
{
    Address = "2",
    DataType = DataTypeEnum.Int16,
    FunctionCode = 4,
    StationNumber = 1
});
list.Add(new ModBusInput()
{
    Address = "199",
    DataType = DataTypeEnum.Int16,
    FunctionCode = 3,
    StationNumber = 1
});
var result = client.BatchRead(list);

//7. Other parameters of the constructor
// IP, port, timeout, endian setting
ModBusTcpClient client = new ModBusTcpClient("127.0.0.1", 502, 1500, EndianFormat.ABCD);

ModBusRtu Read/Write Operations

// Instantiate the client - [COM port name, baud rate, data bits, stop bits, parity]
ModBusRtuClient client = new ModBusRtuClient("COM3", 9600, 8, StopBits.One, Parity.None);

// Other read/write operations are consistent with ModBusTcpClient's read/write operations

ModBusAscii Read/Write Operations

// Instantiate the client - [COM port name, baud rate, data bits, stop bits, parity]
ModbusAsciiClient client = new ModbusAsciiClient("COM3", 9600, 8, StopBits.One, Parity.None);

// Other read/write operations are consistent with ModBusTcpClient's read/write operations

ModbusRtuOverTcp Read/Write Operations

// Serial port transparent transmission, i.e., sending Rtu format messages in Tcp way

// Instantiate the client - IP, port, timeout, endian setting
ModbusRtuOverTcpClient client = new ModbusRtuOverTcpClient("127.0.0.1", 502, 1500, EndianFormat.ABCD);

// Other read/write operations are consistent with ModBusTcpClient's read/write operations

SiemensClient Read/Write Operations

//1. Instantiate the client - Enter model, IP, and port
// Other models: SiemensVersion.S7_200, SiemensVersion.S7_300, SiemensVersion.S7_400, SiemensVersion.S7_1200, SiemensVersion.S7_1500
SiemensClient client = new SiemensClient(SiemensVersion.S7_200Smart, "127.0.0.1",102);

//2. Write operation
client.Write("Q1.3", true);
client.Write("V2205", (short)11);
client.Write("V2209", 33);
client.Write("V2305", "orderCode");             // Write string

//3. Read operation
var value1 = client.ReadBoolean("Q1.3").Value;
var value2 = client.ReadInt16("V2205").Value;
var value3 = client.ReadInt32("V2209").Value;
var value4 = client.ReadString("V2305").Value; // Read string

//4. If not actively opened, the connection will automatically open and close with each read/write operation, which greatly reduces efficiency. It is recommended to manually open and close.
client.Open();

//5. Read/write operations will return the operation result object Result
var result = client.ReadInt16("V2205");
//5.1 Check if reading was successful (true or false)
var isSucceed = result.IsSucceed;
//5.2 Read failure exception message
var errMsg = result.Err;
//5.3 Read operation actual request message sent
var requst  = result.Requst;
//5.4 Read operation server response message
var response = result.Response;
//5.5 Read value
var value4 = result.Value;

About Siemens PLC Address

VB263, VW263, VD263 where B, W, D represent: byte type (8 bits), word type (16 bits), double word type (32 bits).

When passing the address in this component, there is no need to include the data type, just use the corresponding method to read the corresponding type, such as:
VB263       - client.ReadByte("V263")
VD263       - client.ReadFloat("V263")
VD263       - client.ReadInt32("V263")
DB108.DBW4  - client.ReadUInt16("DB108.4")
DB1.DBX0.0  - client.ReadBoolean("DB1.0.0")
DB1.DBD0    - client.ReadFloat("DB1.0")
C# Data Types smart200 smart200
bit V1.0 DB1.DBX1.0
byte VB1 DB1.DBB1
short ushort VW2 DB1.DBW2
int uint float VD4 DB1.DBD4

SiemensClient Best Practices

1. When not to actively open
Siemens PLC generally allows a maximum of 8 long connections. Therefore, when the number of connections is insufficient or during testing, do not actively open, as the component will automatically open and immediately close.

2. When to actively open
When the number of long connections is still sufficient and you want to improve read/write performance.

3. In addition to actively opening connections, batch read/write can also greatly improve read/write performance.
// Batch read
Dictionary<string, DataTypeEnum> addresses = new Dictionary<string, DataTypeEnum>();
addresses.Add("DB4.24", DataTypeEnum.Float);
addresses.Add("DB1.434.0", DataTypeEnum.Bool);
addresses.Add("V4109", DataTypeEnum.Byte);
...
var result = client.BatchRead(addresses);

// Batch write
Dictionary<string, object> addresses = new Dictionary<string, object>();
addresses.Add("DB4.24", (float)1);
addresses.Add("DB4.0", (float)2);
addresses.Add("DB1.434.0", true);
...
var result = client.BatchWrite(addresses);

4. [Note] When writing data, you need to specify the data type
client.Write("DB4.12", 9);          // Writing is of int type
client.Write("DB4.12", (float)9);   // Writing is of float type

5. SiemensClient is a thread-safe class
Due to the limited number of long connections for PLC, SiemensClient is designed as a thread-safe class. You can set SiemensClient as a singleton and use the instance of SiemensClient across multiple threads for read/write operations on PLC.

MitsubishiClient Read/Write Operations

//1. Instantiate the client - Enter the correct IP and port
MitsubishiClient client = new MitsubishiClient(MitsubishiVersion.Qna_3E, "127.0.0.1",6000);

//2. Write operation
client.Write("M100", true);
client.Write("D200", (short)11);
client.Write("D210", 33);

//3. Read operation
var value1 = client.ReadBoolean("M100").Value;
var value2 = client.ReadInt16("D200").Value;
var value3 = client.ReadInt32("D210").Value;

//4. If not actively opened, the connection will automatically open and close with each read/write operation, which greatly reduces efficiency. It is recommended to manually open and close.
client.Open();

//5. Read/write operations will return the operation result object Result
var result = client.ReadInt16("D210");
//5.1 Check if reading was successful (true or false)
var isSucceed = result.IsSucceed;
//5.2 Read failure exception message
var errMsg = result.Err;
//5.3 Read operation actual request message sent
var requst  = result.Requst;
//5.4 Read operation server response message
var response = result.Response;
//5.5 Read value
var value4 = result.Value;

OmronFinsClient Read/Write Operations

//1. Instantiate the client - Enter the correct IP and port
OmronFinsClient client = new OmronFinsClient("127.0.0.1",6000);

//2. Write operation
client.Write("M100", true);
client.Write("D200", (short)11);
client.Write("D210", 33);

//3. Read operation
var value1 = client.ReadBoolean("M100").Value;
var value2 = client.ReadInt16("D200").Value;
var value3 = client.ReadInt32("D210").Value;

//4. If not actively opened, the connection will automatically open and close with each read/write operation, which greatly reduces efficiency. It is recommended to manually open and close.
client.Open();

//5. Read/write operations will return the operation result object Result
var result = client.ReadInt16("D210");
//5.1 Check if reading was successful (true or false)
var isSucceed = result.IsSucceed;
//5.2 Read failure exception message
var errMsg = result.Err;
//5.3 Read operation actual request message sent
var requst  = result.Requst;
//5.4 Read operation server response message
var response = result.Response;
//5.5 Read value
var value4 = result.Value;

AllenBradleyClient Read/Write Operations

//1. Instantiate the client - Enter the correct IP and port
AllenBradleyClient client = new AllenBradleyClient("127.0.0.1",44818);

//2. Write operation 
client.Write("A1", (short)11); 

//3. Read operation
var value = client.ReadInt16("A1").Value;

//4. If not actively opened, the connection will automatically open and close with each read/write operation, which greatly reduces efficiency. It is recommended to manually open and close.
client.Open();

//5. Read/write operations will return the operation result object Result
var result = client.ReadInt16("A1");
//5.1 Check if reading was successful (true or false)
var isSucceed = result.IsSucceed;
//5.2 Read failure exception message
var errMsg = result.Err;
//5.3 Read operation actual request message sent
var requst  = result.Requst;
//5.4 Read operation server response message
var response = result.Response;
//5.5 Read value
var value4 = result.Value;

IoTClient Source Code Address

https://github.com/zhaopeiym/IoTClient

Copyright Notice: This article is sourced from network materials collected or contributed by netizens, and the copyright belongs to the original author. If there is any infringement, please contact the editor to delete it.

IoT Device Communication Protocol Client Developed in C#

Leave a Comment

×