C# 中使用建造者模式实现多设备 Modbus RTU 数据采集(案例版)
C# 中使用建造者模式实现多设备 Modbus RTU 数据采集
下面将展示如何使用建造者模式来实现一个支持多种 Modbus RTU 设备数据采集的系统。
1. 定义 Modbus 采集配置产品类
c#
// Modbus采集配置类
public class ModbusDeviceConfiguration
{
public string DeviceName { get; set; }
public string DeviceType { get; set; }
public byte SlaveId { get; set; }
public string ComPort { get; set; }
public int BaudRate { get; set; }
public Parity Parity { get; set; }
public int DataBits { get; set; }
public StopBits StopBits { get; set; }
public Dictionary<string, RegisterInfo> RegisterMap { get; set; }
public int PollingInterval { get; set; }
}
// 寄存器信息类
public class RegisterInfo
{
public ushort Address { get; }
public RegisterType Type { get; }
public string Description { get; }
public float ScaleFactor { get; }
public RegisterInfo(ushort address, RegisterType type, string description, float scaleFactor = 1.0f)
{
Address = address;
Type = type;
Description = description;
ScaleFactor = scaleFactor;
}
}
public enum RegisterType
{
Int16,
UInt16,
Int32,
UInt32,
Float32
}
2. 定义抽象建造者接口
c#
// Modbus设备配置建造者接口
public interface IModbusDeviceBuilder
{
void SetDeviceInfo(string deviceName, byte slaveId);
void SetCommunicationParameters(string comPort, int baudRate);
void SetRegisterMap();
void SetPollingInterval(int interval);
ModbusDeviceConfiguration GetConfiguration();
}
3. 实现具体设备建造者
3.1 电能表建造者
c#
public class PowerMeterBuilder : IModbusDeviceBuilder
{
private ModbusDeviceConfiguration _config = new ModbusDeviceConfiguration();
public void SetDeviceInfo(string deviceName, byte slaveId)
{
_config.DeviceName = deviceName;
_config.DeviceType = "电能表";
_config.SlaveId = slaveId;
}
public void SetCommunicationParameters(string comPort, int baudRate)
{
_config.ComPort = comPort;
_config.BaudRate = baudRate;
_config.Parity = Parity.Even;
_config.DataBits = 8;
_config.StopBits = StopBits.One;
}
public void SetRegisterMap()
{
_config.RegisterMap = new Dictionary<string, RegisterInfo>
{
{ "Voltage", new RegisterInfo(0x0000, RegisterType.Float32, "电压(V)", 0.1f) },
{ "Current", new RegisterInfo(0x0002, RegisterType.Float32, "电流(A)", 0.01f) },
{ "ActivePower", new RegisterInfo(0x0004, RegisterType.Float32, "有功功率(kW)", 0.1f) },
{ "Energy", new RegisterInfo(0x0008, RegisterType.Float32, "累计电能(kWh)", 1.0f) }
};
}
public void SetPollingInterval(int interval)
{
_config.PollingInterval = interval;
}
public ModbusDeviceConfiguration GetConfiguration()
{
return _config;
}
}
3.2 温度传感器建造者
c#
public class TemperatureSensorBuilder : IModbusDeviceBuilder
{
private ModbusDeviceConfiguration _config = new ModbusDeviceConfiguration();
public void SetDeviceInfo(string deviceName, byte slaveId)
{
_config.DeviceName = deviceName;
_config.DeviceType = "温度传感器";
_config.SlaveId = slaveId;
}
public void SetCommunicationParameters(string comPort, int baudRate)
{
_config.ComPort = comPort;
_config.BaudRate = 9600; // 温度传感器通常使用9600波特率
_config.Parity = Parity.None;
_config.DataBits = 8;
_config.StopBits = StopBits.One;
}
public void SetRegisterMap()
{
_config.RegisterMap = new Dictionary<string, RegisterInfo>
{
{ "Temperature", new RegisterInfo(0x0000, RegisterType.Int16, "温度(°C)", 0.1f) },
{ "Humidity", new RegisterInfo(0x0001, RegisterType.Int16, "湿度(%RH)", 0.1f) },
{ "Status", new RegisterInfo(0x0002, RegisterType.UInt16, "设备状态") }
};
}
public void SetPollingInterval(int interval)
{
_config.PollingInterval = interval;
}
public ModbusDeviceConfiguration GetConfiguration()
{
return _config;
}
}
4. 定义指挥者 (Director)
c#
public class ModbusConfigDirector
{
private IModbusDeviceBuilder _builder;
public ModbusConfigDirector(IModbusDeviceBuilder builder)
{
_builder = builder;
}
public void ConstructConfiguration(string deviceName, byte slaveId, string comPort, int baudRate)
{
_builder.SetDeviceInfo(deviceName, slaveId);
_builder.SetCommunicationParameters(comPort, baudRate);
_builder.SetRegisterMap();
_builder.SetPollingInterval(5000); // 默认5秒采集间隔
}
public ModbusDeviceConfiguration GetConfiguration()
{
return _builder.GetConfiguration();
}
}
5. Modbus 数据采集器实现
c#
public class ModbusDataCollector : IDisposable
{
private readonly ModbusDeviceConfiguration _config;
private IModbusSerialMaster _master;
private SerialPort _serialPort;
private Timer _pollingTimer;
public ModbusDataCollector(ModbusDeviceConfiguration config)
{
_config = config;
InitializeModbusMaster();
StartPolling();
}
private void InitializeModbusMaster()
{
_serialPort = new SerialPort(
_config.ComPort,
_config.BaudRate,
_config.Parity,
_config.DataBits,
_config.StopBits);
_master = ModbusSerialMaster.CreateRtu(_serialPort);
_serialPort.Open();
}
private void StartPolling()
{
_pollingTimer = new Timer(_config.PollingInterval);
_pollingTimer.Elapsed += async (sender, e) => await PollDataAsync();
_pollingTimer.AutoReset = true;
_pollingTimer.Enabled = true;
}
private async Task PollDataAsync()
{
try
{
foreach (var register in _config.RegisterMap)
{
ushort[] values = await _master.ReadHoldingRegistersAsync(
_config.SlaveId,
register.Value.Address,
1);
float scaledValue = values[0] * register.Value.ScaleFactor;
Console.WriteLine($"{DateTime.Now}: {_config.DeviceName} - {register.Value.Description}: {scaledValue}");
}
}
catch (Exception ex)
{
Console.WriteLine($"采集 {_config.DeviceName} 数据时出错: {ex.Message}");
}
}
public void Dispose()
{
_pollingTimer?.Dispose();
_master?.Dispose();
_serialPort?.Dispose();
}
}
6. 客户端使用示例
c#
class Program
{
static void Main(string[] args)
{
// 创建电能表配置
var powerMeterBuilder = new PowerMeterBuilder();
var director = new ModbusConfigDirector(powerMeterBuilder);
director.ConstructConfiguration("电表1", 1, "COM3", 9600);
var powerMeterConfig = director.GetConfiguration();
// 创建温度传感器配置
var tempSensorBuilder = new TemperatureSensorBuilder();
director = new ModbusConfigDirector(tempSensorBuilder);
director.ConstructConfiguration("温度传感器1", 2, "COM4", 9600);
var tempSensorConfig = director.GetConfiguration();
// 创建数据采集器
var collectors = new List<ModbusDataCollector>
{
new ModbusDataCollector(powerMeterConfig),
new ModbusDataCollector(tempSensorConfig)
};
Console.WriteLine("数据采集中...");
// 清理资源
foreach (var collector in collectors)
{
collector.Dispose();
}
}
}
以上案例结合实际情况稍微调整一下就可以使用,本案例主要演示建造者模式在多设备采集数据方面的应用,真正应用需要结合实际情况再做实际调整。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐

所有评论(0)