C# WPF PLC通信管理标准化接口设计文档
1. 引言
本文档定义了一套用于WPF应用程序的PLC通信管理标准化接口。该设计旨在统一多种PLC通信方式(串口、TCP/IP)及常见协议(Modbus RTU/ASCII/TCP、三菱MC协议),为上层应用提供一致的编程模型,简化PLC数据读写和状态管理。通过标准化接口,开发人员可以灵活替换底层协议实现,同时保持业务代码不变。
2. 通信状态枚举
表示PLC连接的当前状态。
///
/// 表示PLC通信连接的状态。
///
public enum PlcConnectionState
{
/// 初始状态,未连接。
Disconnected,
/// 正在建立连接。
Connecting,
/// 已成功连接。
Connected,
/// 连接发生错误,无法通信。
Error,
/// 正在断开连接。
Disconnecting
}
3. 通信参数配置接口 IPlcConnectionConfig
用于封装不同协议和传输方式所需的连接参数。
///
/// PLC连接配置的基接口。
///
public interface IPlcConnectionConfig
{
///
/// 获取通信超时时间(毫秒)。
///
int Timeout { get; }
///
/// 获取重试次数。
///
int RetryCount { get; }
}
///
/// 串口通信配置。
///
public interface ISerialPortConfig : IPlcConnectionConfig
{
string PortName { get; }
int BaudRate { get; }
int DataBits { get; }
System.IO.Ports.Parity Parity { get; }
System.IO.Ports.StopBits StopBits { get; }
}
///
/// 以太网通信配置。
///
public interface IEthernetConfig : IPlcConnectionConfig
{
string IpAddress { get; }
int Port { get; }
}
///
/// Modbus协议特定配置(可选)。
///
public interface IModbusConfig : IPlcConnectionConfig
{
byte StationId { get; } // 从站地址
// 可扩展 Modbus 相关参数
}
///
/// 三菱MC协议配置。
///
public interface IMcProtocolConfig : IPlcConnectionConfig
{
/// 网络编号(通常为0)
byte NetworkNumber { get; }
/// PC编号(通常为0xFF)
byte PcNumber { get; }
/// 目标模块IO编号(通常为0x03FF)
ushort DestinationModuleIoNumber { get; }
/// 目标模块站号(通常为0)
byte DestinationModuleStationNumber { get; }
/// CPU定时器(秒)
ushort CpuTimer { get; }
}
4. 核心PLC通信接口 IPlcCommunicator
定义统一的PLC通信操作方法,支持异步读写。
///
/// PLC通信器接口,提供连接管理和数据读写功能。
///
public interface IPlcCommunicator : IDisposable
{
///
/// 当前连接状态。
///
PlcConnectionState State { get; }
///
/// 连接配置。
///
IPlcConnectionConfig Config { get; }
///
/// 连接状态变化事件。
///
event EventHandler StateChanged;
///
/// 建立连接(异步)。
///
Task ConnectAsync(CancellationToken cancellationToken = default);
///
/// 断开连接(异步)。
///
Task DisconnectAsync(CancellationToken cancellationToken = default);
///
/// 读取单个位(线圈/触点)。
///
/// 地址,如 "M100"、"Q0.0" 等。
Task<bool> ReadBoolAsync(string address, CancellationToken cancellationToken = default);
///
/// 写入单个位。
///
Task WriteBoolAsync(string address, bool value, CancellationToken cancellationToken = default);
///
/// 读取16位整数。
///
Task<short> ReadInt16Async(string address, CancellationToken cancellationToken = default);
///
/// 写入16位整数。
///
Task WriteInt16Async(string address, short value, CancellationToken cancellationToken = default);
///
/// 读取32位整数。
///
Task<int> ReadInt32Async(string address, CancellationToken cancellationToken = default);
///
/// 写入32位整数。
///
Task WriteInt32Async(string address, int value, CancellationToken cancellationToken = default);
///
/// 读取浮点数(32位)。
///
Task<float> ReadFloatAsync(string address, CancellationToken cancellationToken = default);
///
/// 写入浮点数。
///
Task WriteFloatAsync(string address, float value, CancellationToken cancellationToken = default);
///
/// 读取字符串(指定长度)。
///
Task<string> ReadStringAsync(string address, ushort length, CancellationToken cancellationToken = default);
///
/// 写入字符串。
///
Task WriteStringAsync(string address, string value, CancellationToken cancellationToken = default);
///
/// 批量读取字节数组(适用于任意数据块)。
///
Task<byte[]> ReadBytesAsync(string address, ushort length, CancellationToken cancellationToken = default);
///
/// 批量写入字节数组。
///
Task WriteBytesAsync(string address, byte[] data, CancellationToken cancellationToken = default);
}
设计说明:地址字符串格式由具体实现解释,例如 "D100"、"M0"、"40001" 等,推荐采用协议相关的标准表示。
5. 通信结果封装(可选)
为了提供更丰富的返回值(包含错误信息等),可以定义结果类。
///
/// 表示PLC读写操作的结果。
///
/// 数据类型。
public class PlcResult<T>
{
public bool IsSuccess { get; set; }
public T Value { get; set; }
public string ErrorMessage { get; set; }
public Exception Exception { get; set; }
public static PlcResult Success(T value) => new PlcResult { IsSuccess = true, Value = value };
public static PlcResult Failure(string error, Exception ex = null) => new PlcResult { IsSuccess = false, ErrorMessage = error, Exception = ex };
}
6. 通信事件参数
///
/// PLC连接状态变化事件参数。
///
public class PlcConnectionStateChangedEventArgs : EventArgs
{
public PlcConnectionState OldState { get; }
public PlcConnectionState NewState { get; }
public string Message { get; }
public PlcConnectionStateChangedEventArgs(PlcConnectionState oldState, PlcConnectionState newState, string message = "")
{
OldState = oldState;
NewState = newState;
Message = message;
}
}
///
/// PLC数据接收事件参数(适用于订阅特定地址变化)。
///
public class PlcDataReceivedEventArgs : EventArgs
{
public string Address { get; }
public object Value { get; }
public DateTime Timestamp { get; }
public PlcDataReceivedEventArgs(string address, object value)
{
Address = address;
Value = value;
Timestamp = DateTime.Now;
}
}
7. 协议特定接口(可选扩展)
对于某些协议可能需要特殊方法,可定义子接口。
7.1 Modbus专用接口
public interface IModbusCommunicator : IPlcCommunicator
{
/// 读取线圈(功能码01)。
Task<bool[]> ReadCoilsAsync(ushort startAddress, ushort quantity, CancellationToken cancellationToken = default);
/// 读取离散输入(功能码02)。
Task<bool[]> ReadDiscreteInputsAsync(ushort startAddress, ushort quantity, CancellationToken cancellationToken = default);
/// 读取保持寄存器(功能码03)。
Task<ushort[]> ReadHoldingRegistersAsync(ushort startAddress, ushort quantity, CancellationToken cancellationToken = default);
/// 读取输入寄存器(功能码04)。
Task<ushort[]> ReadInputRegistersAsync(ushort startAddress, ushort quantity, CancellationToken cancellationToken = default);
/// 写入单个线圈(功能码05)。
Task WriteSingleCoilAsync(ushort address, bool value, CancellationToken cancellationToken = default);
/// 写入单个寄存器(功能码06)。
Task WriteSingleRegisterAsync(ushort address, ushort value, CancellationToken cancellationToken = default);
/// 写入多个线圈(功能码15)。
Task WriteMultipleCoilsAsync(ushort startAddress, bool[] values, CancellationToken cancellationToken = default);
/// 写入多个寄存器(功能码16)。
Task WriteMultipleRegistersAsync(ushort startAddress, ushort[] values, CancellationToken cancellationToken = default);
}
7.2 三菱MC协议专用接口
public interface IMcProtocolCommunicator : IPlcCommunicator
{
/// 批量读取软元件(字/双字)。
Task<byte[]> ReadDeviceBlockAsync(string device, ushort size, CancellationToken cancellationToken = default);
/// 批量写入软元件。
Task WriteDeviceBlockAsync(string device, byte[] data, CancellationToken cancellationToken = default);
/// 随机读取多个软元件。
Task<byte[]> ReadRandomAsync(string[] devices, CancellationToken cancellationToken = default);
/// 远程运行/停止PLC。
Task RemoteOperationAsync(PlcRemoteOperation operation, CancellationToken cancellationToken = default);
}
public enum PlcRemoteOperation
{
Run,
Stop,
Reset
}
8. 通信管理器接口 IPlcCommunicationManager
用于管理多个PLC连接实例,提供统一的创建、获取、移除等功能。
///
/// PLC通信管理器,负责创建和管理多个PLC通信器实例。
///
public interface IPlcCommunicationManager : IDisposable
{
///
/// 根据配置创建新的PLC通信器。
///
/// 连接配置。
/// 可选标识符,若未提供则自动生成。
/// 创建的PLC通信器实例。
IPlcCommunicator CreateCommunicator(IPlcConnectionConfig config, string id = null);
///
/// 根据标识符获取已创建的PLC通信器。
///
IPlcCommunicator GetCommunicator(string id);
///
/// 移除并释放指定PLC通信器。
///
bool RemoveCommunicator(string id);
///
/// 获取所有已创建的PLC通信器。
///
IReadOnlyList GetAllCommunicators() ;
///
/// 当任何PLC通信器的状态发生变化时触发。
///
event EventHandler CommunicatorStateChanged;
}
9. 总结
接口文档汇总 - 3.PLC通信管理
2/2
本文档定义了一套标准化的PLC通信管理接口,涵盖连接配置、核心通信方法及高级管理器。设计支持串口与以太网传输,并针对Modbus和三菱MC协议提供扩展接口。通过统一的IPlcCommunicator接口,上层应用能以相同方式操作不同品牌PLC,极大提升代码可维护性与扩展性。在WPF项目中,结合MVVM模式可轻松实现PLC状态的实时监控与交互。










