前言
工业自动化和智能制造快速发展,SCADA(数据采集与监控系统)与物联网(IoT)的融合已成为行业趋势。然而,对于初学者,市面上的商用SCADA系统往往功能复杂、成本高昂,且封闭性较强,难以用于教学或深入理解底层逻辑。
本文推荐一个轻量级、开源、基于 WinForm 的 SCADA+IoT 学习型程序,在帮助开发快速掌握工业通信、人机界面设计、实时数据处理等核心技能。
项目介绍
一个面向学习目的的桌面应用程序,采用 C# 语言和 .NET 平台开发,界面基于 Sunny.UI 框架,后端通过 IoTClient 库与西门子 S7 系列 PLC 进行通信。程序支持从 Excel 配置文件中读取变量定义,自动建立与 PLC 的连接,并实现周期性数据读取、断线重连、多模块页面管理等功能。整个系统结构清晰、代码规范,适合作为 SCADA 入门项目的参考模板。
项目功能
1、PLC 连接管理
支持配置 IP、端口、CPU 类型等参数,自动尝试连接西门子 PLC,并提供连接状态指示灯。
2、变量动态绑定
通过 Excel 表格定义 PLC 地址与变量名称、数据类型,程序启动时自动加载并映射。
3、实时数据轮询
后台任务以设定间隔(如 500ms)批量读取 PLC 数据,并更新本地缓存字典。
4、断线自动重连
当通信中断时,系统会按设定时间间隔尝试重新连接,保障数据连续性。
5、多模块界面
包含控制、监控、用户管理、配方设置、日志、报表、图表、系统参数等八大功能模块。
6、主题与字体自定义
支持切换 UI 主题、全局字体及字号,提升用户体验与可读性。
7、无边框窗口拖动
实现现代风格的窗口交互,支持点击标题栏任意位置拖动窗口。
项目特点
项目并非追求工业级稳定性,而是聚焦于"可学、可改、可跑"。其最大特点是配置驱动——所有 PLC 变量无需硬编码,只需维护一份 Excel 表格即可扩展监控点;
同时,模块化设计使得新增功能页面非常便捷。另外,代码中大量使用依赖注入、日志记录、异步任务等现代开发实践,便于学习理解企业级应用架构。
项目技术
1、IoTClient 库(SiemensClient,S7 协议通信)
2、SqlSugar ORM(数据持久层)
3、Sunny.UI(WinForm 界面控件库)
4、IniFile(INI 配置文件读写)
5、MiniExcel(Excel 配置解析)
6、单例模式(ISingletonSelfDependency)
7、Microsoft.Extensions.DependencyInjection(依赖注入与服务生命周期管理)
项目代码
读取PLC参数
/// <summary> /// 读取PLC参数 /// </summary> private void InitPlcClient() { var configFile = Application.StartupPath + PlcConstants.PlcVarConfigFile; if (!File.Exists(configFile)) { Globals.IniFile.Write("PLC参数", "变量表地址", Application.StartupPath + PlcConstants.PlcVarConfigFile); } // 读取表格路径 var path = Globals.IniFile.ReadString("PLC参数", "变量表地址", Application.StartupPath + PlcConstants.PlcVarConfigFile); // 导入PLC变量 var plcList = MiniExcel.Query<PlcVarConfigModel>(path).ToList(); // 配置plc客户端参数 Globals.siemensClient = new IoTClient.Clients.PLC.SiemensClient( Globals.CpuType, Globals.IpAddress, Globals.Port, Globals.Slot, Globals.Rack, Globals.ConnectTimeout); // 尝试连接PLC var connectResult = Globals.siemensClient.Open(); if (connectResult.IsSucceed) { plcIsConnected = true; led_PlcState.On = true; } else { plcIsConnected = false; led_PlcState.On = false; } for (int i = 0; i < plcList.Count; i++) { if (plcList[i].PLC地址 == null) { continue; } // 变量地址类型 PLC地址-变量类型 Globals.ReadDic.Add(plcList[i].PLC地址, Enum.Parse<DataTypeEnum>(plcList[i].变量类型, true)); // plc变量写入 名称-PLC地址 Globals.WriteDic.Add(plcList[i].名称, plcList[i].PLC地址); // PLC变量数据字典 名称-值 Globals.DataDic.Add(plcList[i].名称, "NA"); } Task.Run(async () => { while (!cts.IsCancellationRequested) { if (plcIsConnected) { var readResult = Globals.siemensClient.BatchRead(Globals.ReadDic); if (readResult.IsSucceed) { for (int i = 0; i < plcList.Count; i++) { if (plcList[i].PLC地址 == null) { continue; } Globals.DataDic[plcList[i].名称] = readResult.Value[plcList[i].PLC地址]; } } else { Globals.siemensClient.Close(); plcIsConnected = false; this.Invoke(() => { this.led_PlcState.On = false; }); } await Task.Delay(Globals.ReConnectTimeInterval); } else { // 重连 var reconnResult = Globals.siemensClient.Open(); if (reconnResult.IsSucceed) { plcIsConnected = true; this.Invoke(() => { this.led_PlcState.On = true; }); } else { plcIsConnected = false; this.Invoke(() => { this.led_PlcState.On = false; }); await Task.Delay(Globals.ReConnectTimeInterval); } } } }); }项目效果
PLC 连接成功后,状态指示灯变绿,各监控页面可实时显示设备运行参数(如温度、压力、阀门状态等)。即使模拟断开网络,系统也会在几秒内自动重连。所有数据展示均基于内存字典,响应迅速,界面流畅。
用户管理
图表模块
参数模块
项目源码
关键逻辑集中在 InitPlcClient 方法中,包括变量加载、客户端创建、连接测试及后台轮询任务。所有页面(如 PageEquipmentMonitor、PageRecipeManage 等)均通过依赖注入动态加载,便于单元测试与功能扩展。
为了防止丢失,后台回复关键字「数据采集」,即可获取完整源码地址。
总结
这个 SCADA+IoT 学习项目虽小,却涵盖了工业软件开发的核心要素:设备通信、数据建模、界面交互、异常处理与系统扩展。它不追求大而全,而是以"最小可行系统"为原则,让大家能快速上手、理解原理、动手改造。不管是作为设计原型、教材示例,还是个人技术练手项目,都具有较高的实用价值。希望它能成为大家踏入工业自动化领域的一块垫脚石。
关键词
#SCADA、#IoT、#WinForm、#PLC通信、#S7协议、#SunnyUI、#Excel配置、#实时监控、#断线重连、#依赖注入