Foreword
In front of us the ModBusTcp agreement . Today, we then introduce ModBusRtu agreement. And ModbusTCP ModBusRtu difference is based on serial communication, ModBusTcp Tcp is based on Ethernet communication.
So we will first introduce serial communication before explaining ModBusRtu agreement.
Skewer opening communication
Serial appeared in 1980, the original main purpose is used for connecting computer peripherals such as mice, keyboards and so on. Now the latest computer slowly removed the original serial interface, but is still widely used in industrial control and measurement equipment.
Serial communication parameters
Refers to a serial communication port bitwise (bit) bytes transmitted and received, the main parameters of serial communication baud rate, data bits, stop bits, parity bit.
Baud Rate
Baud rate is expressed in serial communication, the number of signal units (symbol) transmitted in one second. 10 typically comprises a signal unit (7 data bits, 1 parity bit, 1 or 2 stop bits). Note: The baud rate and inversely proportional to the distance
Data bits
The actual data communication, 7 and 8 valid values.
Stop bits
Finally, a single packet is used to indicate the effective values of 1, 1.5 and 2. Stop bits used to represent the end of a transmission clock synchronization and calibration. The more stop bits, the greater the degree of tolerance clock synchronization, but the data transfer rate will be slower: attention.
Check Digit
Parity error detection as a communication mode, re-transmission if an error is found.
Sample Data | Even parity bit | Odd parity bit |
---|---|---|
0000000 | 00000000 | 00000001 |
1010001 | 10100011 | 10100010 |
1101001 | 11010010 | 11010011 |
1111111 | 11111111 | 11111110 |
As can be seen from the parity of the data is the last one added to the number of data 1 is maintained even or odd.
Baud rate and bit rate (extended knowledge)
The bit rate is a method we used to express at broadband rates. Looks like the baud rate, the baud rate if the transmitted signal element only one bit ( 'bit), then between them are equal. If the baud rate of transmission signal element 10 bits, the baud rate is 10 times the bit rate. Therefore, the significance of the expression of the baud rate and bit rate is not the same, do not be confused.
The actual download speeds of broadband bit rates (extended knowledge)
Mbps and Mbit / s equivalent, kbit / s and equivalents kbps, bps and bit / s equivalent
1Mbps (Mbit / s). 1 = 1024 kbit (-kbit / S). 1 = 1024 * 1024BPS (bit / s), noted that they the units are bit (bit), rather than byte (byte), so the actual download speed is divided by eight. 1024/8 = 128 kb / s .
CRC16 checksum
CRC, Cyclic Redundancy Check the cyclic redundancy check is calculated based on a set of data validity check code for checking whether data changes during transmission or transmission error. The ModBusRtu used is one of the CRC16 check.
Calculating principle, reference may be 1 , 2 , 3
or less is reversed CRC16 algorithm ModBusRtu tested for use in the CRC calculation.
public class CRC16
{
/// <summary>
/// 验证CRC16校验码
/// </summary>
/// <param name="value">校验数据</param>
/// <param name="poly">多项式码</param>
/// <param name="crcInit">校验码初始值</param>
/// <returns></returns>
public static bool CheckCRC16(byte[] value, ushort poly = 0xA001, ushort crcInit = 0xFFFF)
{
if (value == null || !value.Any())
throw new ArgumentException("生成CRC16的入参有误");
var crc16 = GetCRC16(value, poly, crcInit);
if (crc16[crc16.Length - 2] == crc16[crc16.Length - 1] && crc16[crc16.Length - 1] == 0)
return true;
return false;
}
/// <summary>
/// 计算CRC16校验码
/// </summary>
/// <param name="value">校验数据</param>
/// <param name="poly">多项式码</param>
/// <param name="crcInit">校验码初始值</param>
/// <returns></returns>
public static byte[] GetCRC16(byte[] value, ushort poly = 0xA001, ushort crcInit = 0xFFFF)
{
if (value == null || !value.Any())
throw new ArgumentException("生成CRC16的入参有误");
//运算
ushort crc = crcInit;
for (int i = 0; i < value.Length; i++)
{
crc = (ushort)(crc ^ (value[i]));
for (int j = 0; j < 8; j++)
{
crc = (crc & 1) != 0 ? (ushort)((crc >> 1) ^ poly) : (ushort)(crc >> 1);
}
}
byte hi = (byte)((crc & 0xFF00) >> 8); //高位置
byte lo = (byte)(crc & 0x00FF); //低位置
byte[] buffer = new byte[value.Length + 2];
value.CopyTo(buffer, 0);
buffer[buffer.Length - 1] = hi;
buffer[buffer.Length - 2] = lo;
return buffer;
}
}
Protocol packet analysis
Data [read - Request packet]: 01 03 00 04 00 01 C5 CB
- Station No. 01
- 03 function code
- The read start address register 0004
- 00 01 The number of registers read
- C5 CB as CRC16 checksum CRC16 [classes using the above calculation results, CRC16.GetCRC16 ([01,03,00,04,00,01])]
Data [read - a response packet]: 01 03 02 00 21 78 5C
- Station No. 01
- 03 function code
- 02 data byte length
- 0021 data
- 78 5C is a checksum CRC16
[Write data - Request packet]: 01 10 00 04 00 01 02 00 21 67 CC
- Station No. 01
- 10 function code
- Writing start address register 0004
- The number 0001 is written to the register
- 02 the number of bytes to write
- 0021 data to be written
- 67 CC is a CRC16 checksum
Data written to [-] in response to message: 0,110,000,400,014,008
- Station No. 01
- 10 function code
- Writing start address register 0004
- The number 0001 is written to the register
- 4008 is a checksum CRC16
With packet analysis, it is not hard to achieve concrete agreements a. Complete implementation refer https://github.com/zhaopeiym/IoTClient/blob/master/IoTClient/Clients/ModBus/ModBusRtuClient.cs
Use IoTClient in ModBusRtu agreement
installation
Nuget installation Install-Package IoTClient
or graphical installation
use
//1、实例化客户端 - [COM端口名称,波特率,数据位,停止位,奇偶校验]
ModBusRtuClient client = new ModBusRtuClient("COM3", 9600, 8, StopBits.One, Parity.None);
//2、写操作 - 参数依次是:地址 、值 、站号 、功能码
client.Write("4", (short)33, 2, 16);
client.Write("4", (short)3344, 2, 16);
//3、读操作 - 参数依次是:地址 、站号 、功能码
var value = client.ReadInt16("4", 2, 3).Value;
var value2 = client.ReadInt32("4", 2, 3).Value;
//4、如果没有主动Open,则会每次读写操作的时候自动打开自动和关闭连接,这样会使读写效率大大减低。所以建议手动Open和Close。
client.Open();
//5、读写操作都会返回操作结果对象Result
var result = client.ReadInt16("4", 2, 3);
//5.1 读取是否成功(true或false)
var isSucceed = result.IsSucceed;
//5.2 读取失败的异常信息
var errMsg = result.Err;
//5.3 读取操作实际发送的请求报文
var requst = result.Requst;
//5.4 读取操作服务端响应的报文
var response = result.Response;
//5.5 读取到的值
var value3 = result.Value;
reference
- Synchronization to the index directory: "Things develop basic components IoTClient series"
- https://baike.baidu.com/item/%E4%B8%B2%E5%8F%A3%E9%80%9A%E4%BF%A1
- https://baike.baidu.com/item/%E6%AF%94%E7%89%B9%E7%8E%87/1022775
- https://zh.wikipedia.org/wiki/%E5%A5%87%E5%81%B6%E6%A0%A1%E9%AA%8C%E4%BD%8D
- https://www.cnblogs.com/esestt/archive/2007/08/09/848856.html
- https://zh.wikipedia.org/wiki/%E5%BE%AA%E7%92%B0%E5%86%97%E9%A4%98%E6%A0%A1%E9%A9%97