作者:单威
发布平台:CSDN
标签:HMI开发、PLC通讯、C#、工业自动化、Modbus、实时监控、远程控制
一、前言
随着工业自动化的不断推进,HMI(人机界面)系统已成为工控系统中不可或缺的一部分。一个高效的HMI不仅要实时监控设备运行状态,还需要支持历史数据分析、图表展示以及远程操作控制功能。
在实际项目中,使用C#开发工业HMI系统具备众多优势——语言成熟、开发效率高、生态丰富,尤其适合Windows平台的工业软件开发。
本篇文章将以实际应用为导向,带你一步步构建一个具备以下功能的工业HMI系统:
- 📡 与PLC(如西门子、施耐德、三菱)进行实时数据通讯
- 📊 实现设备状态的图形化实时监控
- 🧠 可视化的历史数据图表展示
- 📥 支持远程操作指令下发(写入PLC)
二、系统架构总览
本系统采用三层架构设计:
┌────────────┐
│ 用户界面 │ ←—— WinForms / WPF / Avalonia UI
└────────────┘
↑
┌────────────┐
│ 数据逻辑层 │ ←—— 实时通讯、指令控制、历史记录
└────────────┘
↑
┌────────────┐
│ 通讯协议层 │ ←—— Modbus TCP、S7、OPC UA
└────────────┘
三、PLC 通讯实现(Modbus TCP 示例)
在工业自动化中,Modbus TCP是最常见的通讯协议之一,支持大多数PLC(施耐德、三菱、欧姆龙、国产PLC等)。
1. 引用库推荐
使用开源库 NModbus 可大幅简化PLC通讯开发。
安装方式(NuGet):
Install-Package NModbus4
2. 连接PLC并读取寄存器数据
示例:连接PLC并读取40001地址的寄存器(保持寄存器)
using Modbus.Device;
using System.Net.Sockets;
public class PlcModbusClient
{
private TcpClient client;
private ModbusIpMaster master;
public void Connect(string ip, int port = 502)
{
client = new TcpClient(ip, port);
master = ModbusIpMaster.CreateIp(client);
}
public ushort ReadRegister(ushort address)
{
var result = master.ReadHoldingRegisters(address, 1);
return result[0];
}
public void WriteRegister(ushort address, ushort value)
{
master.WriteSingleRegister(address, value);
}
public void Disconnect()
{
client?.Close();
}
}
四、实时监控界面设计(WinForms/WPF)
1. 实时刷新机制
使用定时器(System.Timers.Timer
)每隔 500ms 读取PLC数据并更新UI:
private System.Timers.Timer dataTimer;
private void StartMonitoring()
{
dataTimer = new System.Timers.Timer(500); // 500ms 刷新一次
dataTimer.Elapsed += (s, e) =>
{
var value = plc.ReadRegister(40001);
this.Invoke(() => txtTemperature.Text = value.ToString());
};
dataTimer.Start();
}
2. 图形显示建议
可使用:
Chart
控件(WinForms 原生)- LiveCharts(更高级、支持动态曲线)
- SciChart、OxyPlot(专业图表库)
简单动态曲线图示例(LiveCharts):
SeriesCollection series = new SeriesCollection
{
new LineSeries
{
Title = "温度",
Values = new ChartValues<double> {}
}
};
public void AddTemperaturePoint(double value)
{
series[0].Values.Add(value);
if (series[0].Values.Count > 100)
series[0].Values.RemoveAt(0);
}
五、远程操作功能实现
除了读取PLC数据,很多HMI系统还需要远程控制功能,例如:远程启动/停止设备、设置参数等。
1. 示例:启动电机
// 写线圈:地址00001,写入true
plc.WriteCoil(0, true); // 0 => 00001
2. 控制按钮事件绑定
private void btnStart_Click(object sender, EventArgs e)
{
plc.WriteCoil(0, true); // 启动指令
}
private void btnStop_Click(object sender, EventArgs e)
{
plc.WriteCoil(0, false); // 停止指令
}
六、历史数据记录与图表分析
工业场景常常需要:
- 数据趋势分析
- 报表导出
- 故障记录等
1. 数据落地(写入SQLite)
使用轻量级数据库 SQLite 记录历史数据:
using System.Data.SQLite;
public void LogTemperature(double value)
{
string sql = "INSERT INTO TemperatureLog (Time, Value) VALUES (@time, @val)";
using (var conn = new SQLiteConnection("Data Source=data.db"))
{
conn.Open();
using (var cmd = new SQLiteCommand(sql, conn))
{
cmd.Parameters.AddWithValue("@time", DateTime.Now);
cmd.Parameters.AddWithValue("@val", value);
cmd.ExecuteNonQuery();
}
}
}
2. 展示趋势图
从数据库读取最近100条温度值并绑定至图表。
public List<double> GetLatestTemperatures()
{
var result = new List<double>();
using (var conn = new SQLiteConnection("Data Source=data.db"))
{
conn.Open();
var cmd = new SQLiteCommand("SELECT Value FROM TemperatureLog ORDER BY Time DESC LIMIT 100", conn);
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
result.Add(reader.GetDouble(0));
}
}
}
return result;
}
七、网络部署与远程操作
1. 本地部署架构
使用Windows服务或桌面应用部署至工业现场终端,使用局域网访问PLC。
2. 支持远程访问方式
- 通过 Socket/WCF/MQTT 将数据上报至服务器
- 支持通过Web UI 或移动端进行远程下发指令
建议远程控制功能务必增加权限校验与通信加密(如SSL)。
八、性能优化建议
- ✅ 通讯线程独立,UI更新使用
Invoke
- ✅ 异常捕获与自动重连机制
- ✅ 图表刷新频率不要过高(建议1秒一次)
- ✅ 长连接维持稳定性(心跳机制)
九、结语与拓展方向
本文完整介绍了如何使用 C# 实现一个具备PLC实时通讯、图表可视化与远程操作能力的工业 HMI 系统。无论你是初入工业软件开发,还是希望将传统SCADA系统功能轻量化自研,本指南都希望为你提供方向。
🔧 后续可扩展方向:
- OPC UA / S7 协议支持
- 报警机制(声光报警、邮件通知)
- 云端数据同步与Web展示(结合 MQTT + Web API)
- 使用 MAUI/Avalonia 开发跨平台 HMI