三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

WinCC组合框控件:实现PLC变量安全赋值与模式选择

WinCC组合框控件:实现PLC变量安全赋值与模式选择

1. 项目概述:为什么我们需要在WinCC中用组合框给PLC变量赋值?

在工业自动化项目的上位机监控系统开发中,我们经常会遇到一个看似简单却至关重要的需求:如何让操作员在WinCC画面上,以一种安全、直观且不易出错的方式,向PLC(可编程逻辑控制器)写入特定的设定值或模式选择。直接使用输入输出域(I/O Field)固然可以,但面对诸如“设备运行模式选择”(手动/自动/维护)、“产品配方选择”(配方A/配方B/配方C)或“预设速度档位选择”(低速/中速/高速)这类场景时,让操作员手动输入“1”、“2”、“3”这样的数字,不仅容易输错,而且极不友好。

这时,组合框(ComboBox)控件就成为了一个绝佳的解决方案。它本质上是一个下拉列表,允许我们预定义好一系列可读的文本选项(如“自动模式”、“手动模式”),当操作员选择其中一项时,WinCC会自动将该项对应的一个内部值(通常是整数)写入到关联的PLC变量中。这个“文本-数值”的映射关系,就是我们实现精准控制的关键。最近在相关技术社区和搜索热词中,诸如“wincc输入变量增加确认功能”、“wincc输入输出域怎样二次确认”等讨论非常活跃,这恰恰反映了业界对操作安全性和数据可靠性的迫切需求。而使用组合框,配合脚本进行逻辑处理,本身就是一种内置的“确认”机制,因为它从源头上限制了输入范围,避免了非法数值的输入。

这个功能广泛应用于S7-1200/1500、S7-300/400等西门子PLC系统,以及通过OPC UA等方式连接的其他品牌PLC(如三菱、欧姆龙、汇川等)项目中。掌握它,意味着你能设计出更专业、更人性化的人机界面(HMI)。

2. 核心原理与架构设计:理解“文本”与“数值”的映射桥梁

在动手配置之前,我们必须彻底理解WinCC组合框与PLC变量之间数据流转的核心原理。这不仅仅是拖拽一个控件那么简单,而是涉及HMI与控制器之间清晰的数据契约。

2.1 数据流与变量关联模型

整个过程涉及三个核心角色和两层映射关系:

  1. WinCC内部变量:这是WinCC运行系统中的数据载体,充当PLC物理变量与画面控件的“中介”。它拥有自己的名称、数据类型和当前值。
  2. 组合框控件:作为画面上的输入元素,它管理着两套数据:
    • 显示文本:用户在下拉列表中看到的选项,如“停机”、“运行”、“故障”。
    • 项目数据:每个显示文本背后对应的一个数值(通常是整数),这个值才是真正需要传递的数据。
  3. PLC变量:最终的目标,是PLC数据块(DB)或存储器(M、I、Q)中的一个具体地址,如DB10.DBW0(一个16位整数)。

其数据流如下图所示(概念模型):

操作员选择组合框选项 -> 触发事件 -> 脚本执行 -> 将`项目数据`赋值给`WinCC内部变量` -> WinCC运行系统通过配置好的通道(如S7协议)-> 将内部变量的值写入`PLC变量`地址 -> PLC程序接收并处理该值。

关键点:组合框不直接连接PLC变量。它通过事件(如选择改变)触发脚本,脚本再对WinCC内部变量进行赋值。而这个WinCC内部变量,在变量管理器中已经与PLC变量建立了连接。这是一种“事件驱动+变量绑定”的架构。

2.2 组合框的两种核心属性:ItemTextItemData

这是理解组合框编程的基石。在WinCC的VBScript或C脚本中,我们主要通过这两个属性数组来操作组合框。

  • ItemText数组:存储下拉列表中显示的所有文本字符串。索引从0开始。例如:
    • ComboBox1.ItemText(0) = “手动模式”
    • ComboBox1.ItemText(1) = “自动模式”
    • ComboBox1.ItemText(2) = “维护模式”
  • ItemData数组:存储与每个ItemText一一对应的数值型数据。这个值就是最终要写入PLC的。例如:
    • ComboBox1.ItemData(0) = 0// 对应手动模式
    • ComboBox1.ItemData(1) = 1// 对应自动模式
    • ComboBox1.ItemData(2) = 2// 对应维护模式

当用户在画面上选择“自动模式”时,组合框的.Value属性获取到的是其索引(这里是1)。而我们通过脚本,需要取出这个索引对应的ItemData值(这里是1),然后将其赋给内部变量。

注意:很多初学者会误以为直接操作.Text属性或.Value属性就能完成赋值,这是错误的。.Text属性只是当前显示的文本,而.Value是当前选中的索引号。我们必须通过索引号去ItemData数组中取出对应的数值。

2.3 方案选型:静态配置 vs. 动态脚本

如何填充组合框的列表?这里有两种主流方法,适用于不同场景:

  • 静态配置(设计时填充):在WinCC图形编辑器的组合框属性中,直接输入“文本/数值对”。这种方法简单直观,适用于选项固定不变且数量较少的场景,如固定的几种模式。优点是无需脚本,配置简单。缺点是灵活性差,选项变更需要修改画面并下载。
  • 动态脚本(运行时填充):通过VBScript或C脚本,在画面打开时(或某个按钮事件中)动态地向ItemTextItemData数组赋值。这种方法功能强大,适用于:
    • 选项来源于数据库(如从SQL Server读取产品配方列表)。
    • 选项需要根据其他条件动态变化(如根据当前工位加载不同的设备列表)。
    • 选项较多,便于集中管理。优点是高度灵活,可维护性强。缺点是需要编写脚本,对开发者有一定要求。

对于大多数需要与PLC交互的工业场景,尤其是选项具有明确业务含义和对应控制代码时,我强烈推荐使用动态脚本方式。它不仅更专业,也为后续的功能扩展(如与数据库联动)留下了空间。

3. 完整实操流程:从零构建一个模式选择功能

下面,我们以一个最经典的案例——“设备运行模式选择”为例,使用S7-1200 PLC和WinCC Professional/Advanced,详细演示从变量创建到画面功能实现的完整步骤。假设PLC中有一个DB块DB101,其中DB101.DBW0(Int类型)用于存储运行模式(0=手动,1=自动,2=维护)。

3.1 第一步:在TIA Portal中创建PLC变量与DB块

  1. 打开TIA Portal项目,进入PLC设备视图。
  2. 添加全局数据块:在“程序块”文件夹下,添加一个新块,类型选择“全局数据块”,命名为DB_DeviceCtrl
  3. 定义变量:在打开的数据块中,定义变量:
    Name DataType Address Comment iOpMode Int 0.0 // 操作模式:0-手动,1-自动,2-维护
  4. 设置PLC变量:在“PLC变量”表中,确保这个数据块中的变量可以被访问。通常,全局DB块中的变量会自动生成对应的PLC变量,其地址如%DB101.DBW0

3.2 第二步:在WinCC中创建连接与内部变量

  1. 在TIA Portal中进入WinCC设备视图,打开HMI变量表。
  2. 创建连接:如果尚未创建,在“连接”中新建一个指向S7-1200 PLC的HMI连接,正确设置IP地址、机架/插槽号。
  3. 创建内部变量并连接PLC变量
    • 在HMI变量表中,新建一个变量,命名为HMI_OpMode
    • 数据类型选择“Int”(与PLC变量一致)。
    • 在“连接”项,选择刚才建立的HMI连接。
    • 在“地址”项,点击浏览按钮,找到PLC中的变量DB_DeviceCtrl.iOpMode。此时,WinCC内部变量HMI_OpMode就与PLC变量DB101.DBW0建立了绑定关系。HMI_OpMode值的变化会自动同步到PLC。

3.3 第三步:画面组态与组合框配置

  1. 打开画面编辑器,从工具箱的“控件”中拖拽一个“组合框”到画面上。
  2. 重命名对象:在属性窗口的“属性 > 常规”中,将组合框的名称改为一个有意义的名称,如Combo_OpMode
  3. (可选)静态配置预览:在“属性 > 属性 > 其他”中,你可以看到“项目”集合。点击“...”可以打开编辑器,手动添加几行文本和值,这可以帮助你在设计时预览效果。但我们最终会使用脚本,所以这里可以保持为空或随意填写。

3.4 第四步:编写VBScript脚本实现动态功能

这是最核心的一步。我们将编写两个脚本:一个用于初始化填充列表,一个用于处理选择改变事件。

脚本1:画面打开时初始化组合框列表

  1. 选中画面,在属性窗口中找到“事件 > 加载”。
  2. 点击右侧的闪电图标,选择“VBScript...”,打开脚本编辑器。
  3. 输入以下代码:
    Sub OnLoad() Dim objCombo ' 获取画面上的组合框对象 Set objCombo = ScreenItems("Combo_OpMode") ' 先清空现有列表(防止重复添加) objCombo.Clear ' 动态添加选项:ItemText(索引) = "显示文本", ItemData(索引) = 对应数值 objCombo.AddItem "手动模式" objCombo.ItemData(objCombo.ListCount - 1) = 0 ' 最后一项的索引是 ListCount-1 objCombo.AddItem "自动模式" objCombo.ItemData(objCombo.ListCount - 1) = 1 objCombo.AddItem "维护模式" objCombo.ItemData(objCombo.ListCount - 1) = 2 ' (可选)读取PLC当前模式,并设置组合框的初始选中项 Dim currentMode currentMode = HMIRuntime.Tags("HMI_OpMode").Read ' 根据值找到对应的索引并选中 For i = 0 To objCombo.ListCount - 1 If objCombo.ItemData(i) = currentMode Then objCombo.ListIndex = i Exit For End If Next End Sub
    代码解读
    • ScreenItems(“Combo_OpMode”)用于获取画面上的控件对象。
    • .AddItem方法用于添加显示文本,同时列表项数量(ListCount)会增加。
    • 添加文本后,立即通过.ItemData(索引)为其赋予对应的数值。objCombo.ListCount - 1总能指向刚刚添加的那一项的索引。
    • 初始化时读取PLC当前值并设置选中项,是一个非常好的实践,能确保画面状态与设备实际状态一致。

脚本2:选择改变时写入变量

  1. 选中组合框控件Combo_OpMode
  2. 在属性窗口中找到“事件 > 属性 > 更改”。
  3. 点击右侧的闪电图标,选择“VBScript...”。
  4. 输入以下代码:
    Sub OnChange() Dim objCombo, selectedValue Set objCombo = ScreenItems("Combo_OpMode") ' 获取当前选中项对应的ItemData值 If objCombo.ListIndex >= 0 Then ' 确保有选中项 selectedValue = objCombo.ItemData(objCombo.ListIndex) ' 将值写入WinCC内部变量,进而写入PLC HMIRuntime.Tags("HMI_OpMode").Write selectedValue ' (可选)添加操作日志或提示信息,增强可追溯性 HMIRuntime.Trace "操作员将运行模式改为: " & objCombo.Text & " (值: " & selectedValue & ")" & vbCrLf End If End Sub
    代码解读
    • objCombo.ListIndex是当前选中项的索引。
    • objCombo.ItemData(objCombo.ListIndex)是关键,它通过索引取出我们要写入PLC的整数值。
    • HMIRuntime.Tags(“HMI_OpMode”).Write是执行写入操作的标准方法。
    • 添加Trace输出是调试和记录用户操作的好习惯,信息会输出到WinCC Runtime的诊断窗口。

3.5 第五步:测试与模拟运行

  1. PLC程序模拟:在TIA Portal中,启动PLC仿真(PLCSIM),将程序下载到仿真PLC。
  2. WinCC运行系统模拟:在WinCC画面编辑器,点击“在线模拟”按钮。此时会启动WinCC Runtime。
  3. 功能测试
    • 画面打开后,观察组合框是否正确显示了“手动模式”、“自动模式”、“维护模式”三个选项。
    • 观察组合框的初始选中项是否与PLC仿真器中DB101.DBW0的当前值对应。
    • 在运行画面中,点击组合框选择不同的模式。
    • 切换到TIA Portal的监控表,在线查看DB101.DBW0的值是否随着你的选择而立即变为0, 1, 2。
    • 同时,在WinCC Runtime的诊断窗口(或通过“系统信息”控件)查看是否有我们编写的Trace日志输出。

4. 高级技巧与深度优化:让功能更稳健、更专业

基础功能实现后,我们可以从工业应用的可靠性、安全性和可维护性角度,进行一系列优化。

4.1 增强操作安全性与确认机制

直接写入模式可能会因误操作导致生产问题。我们可以引入二次确认,这是搜索热词中高频出现的需求。

方案:通过弹出对话框确认修改组合框的“更改”事件脚本,不直接写入,而是先弹出确认框。

Sub OnChange() Dim objCombo, selectedValue, newText Set objCombo = ScreenItems("Combo_OpMode") If objCombo.ListIndex >= 0 Then selectedValue = objCombo.ItemData(objCombo.ListIndex) newText = objCombo.Text ' 弹出确认对话框 Dim result result = MsgBox("确定要将运行模式切换为【" & newText & "】吗?", vbYesNo + vbQuestion, "模式切换确认") If result = vbYes Then HMIRuntime.Tags("HMI_OpMode").Write selectedValue HMIRuntime.Trace "确认:运行模式已改为 " & newText & vbCrLf Else ' 用户取消,需要将组合框显示回之前的值 Dim currentMode currentMode = HMIRuntime.Tags("HMI_OpMode").Read For i = 0 To objCombo.ListCount - 1 If objCombo.ItemData(i) = currentMode Then objCombo.ListIndex = i Exit For End If Next HMIRuntime.Trace "取消:运行模式切换已取消。" & vbCrLf End If End If End Sub

注意MsgBox在Runtime中会阻塞画面线程。对于不允许阻塞的关键过程,可以考虑使用非阻塞的自定义确认画面,通过画面窗口(Picture Window)或弹出画面来实现。

4.2 实现数据与逻辑分离:从数据库或文件加载列表

当选项非常多(如成百上千个产品配方)或需要频繁变更时,将列表数据存储在外部(如SQL Server数据库、CSV文件)是更优解。

示例:从CSV文件加载假设有一个ModeList.csv文件,内容为:

显示文本,对应值 手动模式,0 自动模式,1 维护模式,2 快速模式,10

修改画面“加载”事件的脚本:

Sub OnLoad() Dim objCombo, fso, file, line, parts Set objCombo = ScreenItems("Combo_OpMode") Set fso = CreateObject("Scripting.FileSystemObject") objCombo.Clear ' 假设CSV文件位于项目目录下(实际路径需根据部署环境调整) Dim filePath filePath = HMIRuntime.ActiveProject.Path & "\ModeList.csv" If fso.FileExists(filePath) Then Set file = fso.OpenTextFile(filePath, 1) ' 1 for reading file.SkipLine ' 跳过标题行 Do While file.AtEndOfStream <> True line = file.ReadLine parts = Split(line, ",") If UBound(parts) >= 1 Then objCombo.AddItem Trim(parts(0)) objCombo.ItemData(objCombo.ListCount - 1) = CInt(Trim(parts(1))) End If Loop file.Close Else ' 文件不存在,使用默认值 objCombo.AddItem "文件加载失败-手动" objCombo.ItemData(0) = 0 End If ' ... (后续读取PLC当前值并设置选中项的代码不变) End Sub

优势:修改配方或模式时,只需更新CSV文件并重启Runtime或触发重载脚本,无需修改和下载画面程序。

4.3 状态反馈与互锁控制

在工业现场,不是任何时候都允许切换模式的。例如,设备正在高速运行中,不允许切换到“手动模式”。我们需要在画面上给出明确的反馈。

方案:根据PLC状态禁用组合框或过滤选项

  1. 全局禁用:在画面“加载”事件和监视PLC状态的周期脚本中,判断设备状态。
    ' 假设有一个PLC变量 HMI_DeviceRunning 表示设备是否运行(1运行,0停止) Dim isRunning isRunning = HMIRuntime.Tags("HMI_DeviceRunning").Read If isRunning = 1 Then objCombo.Enabled = False ' 禁用组合框 objCombo.BackColor = RGB(240,240,240) ' 灰色背景提示禁用 Else objCombo.Enabled = True objCombo.BackColor = RGB(255,255,255) ' 白色背景 End If
  2. 动态过滤选项:更精细的控制。在填充列表时,根据条件跳过某些选项。
    objCombo.Clear ' 只有设备停止时,才显示“维护模式” If isRunning = 0 Then objCombo.AddItem “维护模式” objCombo.ItemData(objCombo.ListCount - 1) = 2 End If objCombo.AddItem “手动模式” objCombo.ItemData(objCombo.ListCount - 1) = 0 objCombo.AddItem “自动模式” objCombo.ItemData(objCombo.ListCount - 1) = 1

5. 常见问题排查与实战经验分享

即使按照步骤操作,在实际项目中仍会遇到各种问题。下面是我总结的常见“坑点”和解决方法。

5.1 问题速查表

问题现象可能原因排查步骤与解决方案
组合框下拉列表为空1. 初始化脚本未执行或报错。
2. 脚本中对象名称错误。
3.AddItem方法未成功执行。
1. 在画面“加载”事件脚本开始处添加HMIRuntime.Trace “OnLoad Script Start”确认脚本执行。
2. 检查ScreenItems(“Combo_OpMode”)中的控件名是否与画面对象名称完全一致(区分大小写)。
3. 检查脚本语法,确保AddItem语句在Clear之后。
选择组合框选项后,PLC变量值无变化1. 组合框“更改”事件脚本未触发或报错。
2. 写入的变量名错误或未连接。
3. 取出的ItemData值错误。
4. 通信连接故障。
1. 在“更改”事件脚本首行添加Trace输出。
2. 确认HMIRuntime.Tags(“HMI_OpMode”)变量名正确,且在变量管理器中已正确连接到PLC地址。
3. 使用Trace输出objCombo.ListIndexselectedValue,检查数值是否正确。
4. 检查WinCC连接状态指示灯,在诊断中查看通信错误。
组合框显示的值与PLC实际值不同步1. 画面初始化时未从PLC读取初始值。
2. PLC变量被其他程序(如PLC自身逻辑、其他画面)修改,但组合框未更新显示。
1. 确保画面“加载”脚本中包含“读取PLC变量并设置选中项”的逻辑(见3.4节)。
2.实现双向同步:为WinCC内部变量HMI_OpMode添加“数值更改”事件脚本,当PLC主动改变该变量时,触发脚本去更新组合框的ListIndex
运行时弹出脚本错误对话框1. 对象未定义(未找到控件或变量)。
2. 类型不匹配(如将字符串赋给数值变量)。
3. 数组越界(访问了不存在的ItemData索引)。
1. 仔细检查所有对象名称的拼写。
2. 使用CInt(),CStr()等函数进行显式类型转换。
3. 在访问ItemData(i)前,确保i的值在0ListCount-1之间。使用If objCombo.ListCount > 0 Then进行判断。
组合框样式异常或位置错乱1. 画面分辨率与设计分辨率不一致。
2. 控件属性(如字体、大小)被脚本意外修改。
1. 在图形编辑器的“项目属性”中设置好参考分辨率,并使用“缩放”属性(如“缩放模式”设为“按比例缩放”)。
2. 避免在运行时脚本中修改控件的Left,Top,Width,Height等布局属性,除非必要。

5.2 独家避坑技巧与心得

  1. 命名规范是生命线:给WinCC内部变量、画面控件、脚本中的对象名建立一套清晰的命名规范。例如,变量用Var_前缀,控件用Ctl_或类型前缀如Cbo_,Btn_。这能极大减少因拼写错误导致的调试时间。
  2. 善用Trace功能进行调试:在脚本的关键节点(如开始、结束、赋值前后)使用HMIRuntime.Trace输出变量值、执行状态。这是诊断WinCC运行时脚本问题最直接有效的手段,远比盲目猜测强。
  3. 始终考虑异常处理:工业现场环境复杂,通信可能中断。在读写Tag的脚本中,加入简单的错误处理。
    On Error Resume Next ‘ 忽略单句错误继续执行(慎用) HMIRuntime.Tags(“HMI_OpMode”).Write selectedValue If Err.Number <> 0 Then HMIRuntime.Trace “写入变量失败!错误: ” & Err.Description & vbCrLf Err.Clear End If On Error Goto 0 ‘ 恢复默认错误处理
  4. 性能考量:避免在高速周期触发的脚本(如全局脚本的定时器)中进行复杂的组合框操作或频繁读写变量。对于列表项很多的情况,初始化(OnLoad)时加载一次即可,不要在其他事件中重复加载。
  5. 版本与兼容性:注意TIA Portal和WinCC的版本。不同版本间,VBScript的对象模型或方法可能有细微差别。在升级项目时,务必对脚本功能进行充分测试。例如,早期WinCC Flexible中的某些方法在WinCC Advanced/Professional中可能已变更。
  6. 关于“确认功能”的平衡:虽然二次确认提升了安全性,但过度使用(尤其是阻塞式的MsgBox)会严重影响操作效率。对于高风险操作(如模式切换、急停复位)使用确认,对于常规参数微调则可以不用。也可以设计一个全局的“操作确认开关”,让用户自行决定是否启用二次确认。

通过以上从原理到实践,再到高级优化和问题排查的完整阐述,你应该能够独立设计并实现一个健壮、专业且用户友好的WinCC组合框变量赋值功能了。这个功能的精髓在于理解“事件-脚本-变量”这条数据链,并围绕它构建起安全、可靠的控制逻辑。在实际项目中多思考、多测试,这些代码片段和思路就能组合成满足各种复杂需求的解决方案。

← 返回列表