C# 与三菱PLC通信的方法(第3篇)设备读取命令的用法

前言

在上一篇文章中,我们介绍了使用通信所需的 McpX 的各种设置(通信方式、帧格式、协议等)。

🔗 第2篇在这里

这次我们将重点介绍 McpX 所支持的 设备读取类命令,并配以示例代码进行说明。

使用的库

McpX

支持的设备读取命令一览

名称说明同步方法异步方法单一读取获取一个设备的值Read(Prefix prefix, string address)ReadAsync(...)批量读取从连续的设备中批量读取指定数量的数据BatchRead(Prefix prefix, string address, ushort length)BatchReadAsync(...)随机读取从不连续的地址中按字/双字读取RandomRead((Prefix, string)[] wordAddresses, (Prefix, string)[] doubleWordAddresses)RandomReadAsync(...)

设备地址的指定方法

在 McpX 中,指定PLC设备时,需要组合使用 Prefix(设备类型)和 Address(地址)。

Prefix 是一个枚举类型,例如要指定内部继电器(M),则使用 Prefix.M,指定数据寄存器(D)时则使用 Prefix.D。

Address 使用字符串表示。 指定十进制地址时,例如 "1234";指定十六进制地址时,例如 "4D2"。

设备类型(Prefix)一览

名称键值输入X输出Y内部继电器M保持继电器L报警器F边沿继电器V链路继电器B数据寄存器D链路寄存器W定时器接点TS定时器线圈TC定时器当前值TN累计定时器接点SS累计定时器线圈SC累计定时器当前值SN计数器接点CS计数器线圈CC计数器当前值CN链路特殊继电器SB链路特殊寄存器SW步进继电器S直接访问输入DX直接访问输出DY特殊继电器SM特殊寄存器SD索引寄存器Z文件寄存器(块)R文件寄存器(连续)ZR

若设备地址指定错误,将抛出异常 DeviceAddressException。

异常条件:

对于十进制设备,地址中包含非数字字符

对于十六进制设备,地址中包含无法转换为十六进制的字符

指定读取数据类型的方法

McpX 使用泛型来指定读取的数据类型,通过方法的泛型参数 T 指定。 例如要读取 short 类型的单个值,使用 Read(...) 即可。

支持的类型一览

类型分类bool布尔值(真/假)short16位有符号整数ushort16位无符号整数int32位有符号整数uint32位无符号整数long64位有符号整数ulong64位无符号整数float单精度浮点数double双精度浮点数

若指定了不支持的类型,将抛出 NotSupportedException 异常。

指定读取点数的方法

McpX 会根据指定的数据类型,自动计算所需的读取点数(字数)。

因此,各方法中的 length 参数应指定你希望在C#端获取的值的个数(数组元素数)。

例如读取2个 float 类型的值,每个值在PLC中占2个字(如 D0-D1, D2-D3),此时 length 设为 2 即可。 McpX 会根据类型自动处理字数,因此只需关注“类型”和“数量”。

各类型所需的字数

类型占用字数bool1位(位设备)short1个字int2个字float2个字double4个字

MC协议的批量读取命令对一次读取的最大点数有限制。

但 McpX 提供了自动拆包机制,即使超过协议限制,也会自动分包发送,因此无需用户关心协议细节。

但请注意:读取数量越多,通信负载越大,可能影响性能。

📎 性能测试结果请见此处

单一读取

读取指定的一个设备,并返回指定类型的值。

同步方法示例

从 D0 读取 16位有符号整数

short shortValue = mcpx.Read(Prefix.D, "0");

异步方法示例

从 D10 读取 32位有符号整数

int intValue = await mcpx.ReadAsync(Prefix.D, "10");

批量读取

从连续的设备中批量读取指定数量的数据,并以数组形式返回。

同步方法示例

从 D0 开始读取 100 个 short 值

short[] shortValues = mcpx.BatchRead(Prefix.D, "0", 100);

异步方法示例

从 D10 开始读取 200 个 int 值

int[] intValues = await mcpx.BatchReadAsync(Prefix.D, "10", 200);

随机读取

按字/双字单位读取指定的非连续设备,并返回各自类型的数组。

异步方法示例

从 D100, D110 读取 short,从 D120, D130 读取 int

var drrArr = await mcpx.RandomReadAsync(

wordAddresses: [

(Prefix.D, "100"),

(Prefix.D, "110")

],

doubleWordAddresses: [

(Prefix.D, "120"),

(Prefix.D, "130")

]

);

Console.WriteLine($"D100: { drrArr.wordValues[0] }");

Console.WriteLine($"D110: { drrArr.wordValues[1] }");

Console.WriteLine($"D120: { drrArr.doubleValues[0] }");

Console.WriteLine($"D130: { drrArr.doubleValues[1] }");

同步方法示例

从 D200, D210 读取 short,从 D220, D230 读取 int

var drrArr = mcpx.RandomRead(

wordAddresses: [

(Prefix.D, "200"),

(Prefix.D, "210")

],

doubleWordAddresses: [

(Prefix.D, "220"),

(Prefix.D, "230")

]

);

Console.WriteLine($"D200: { drrArr.wordValues[0] }");

Console.WriteLine($"D210: { drrArr.wordValues[1] }");

Console.WriteLine($"D220: { drrArr.doubleValues[0] }");

Console.WriteLine($"D230: { drrArr.doubleValues[1] }");

如何选择同步/异步方法

McpX 为所有读取命令都提供了同步和异步两种版本。

选择标准如下

适合使用同步方法的场景

控制台应用或批处理流程

不在意通信等待时的阻塞

希望保持逻辑简单(例如学习或调试阶段)

适合使用异步方法的场景

WPF、WinForms、ASP.NET 等需保持UI响应或服务器并发

通信过程中需保证应用不被阻塞

并行处理多个PLC或长时间通信

总结

本文介绍了用于与三菱PLC通信的 McpX 库中读取类命令的使用方法:

如何使用 Prefix + Address 指定设备

如何指定读取数量

如何使用 Read, BatchRead, RandomRead 方法

同步与异步方法的选用原则

另外,我们在 GitHub 上提供了示例项目,欢迎参考

👉 https://github.com/YudaiKitamura/McpX/tree/main/Example

下回我们将介绍 McpX 所支持的设备写入命令及其使用方法,并附带具体示例代码。

参考链接

McpX 文档

McpX GitHub 仓库

McpX NuGet 页面

如果你觉得这个项目对你有帮助,欢迎在 GitHub 上点个 ⭐Star 支持一下!

👉 GitHub地址:https://github.com/YudaiKitamura/McpX