Intouch 本身不是一种编程语言。

- Intouch:是一款非常知名的工业自动化软件,由美国 Wonderware 公司(现为施耐德电气旗下品牌)开发,它的全称是 InTouch Human Machine Interface (HMI) / Supervisory Control and Data Acquisition (SCADA) 系统。
- C语言:是一种通用的、高级的编程语言,以其高效、灵活和底层操作能力而闻名。
"Intouch C语言" 这个说法,通常指的是 在 Intouch 软件环境中,如何使用 C语言 来进行扩展和开发,你可以把 Intouch 看作是一个功能强大的“框架”或“平台”,而 C语言 则是你用来定制和增强这个平台功能的“工具”之一。
下面我将从几个方面详细解释它们之间的关系以及如何结合使用。
为什么要在 Intouch 中使用 C语言?
Intouch 本身提供了强大的图形化界面编辑功能(拖拽、绘制动画连接)和内置的脚本语言(如 QuickScript),可以完成绝大多数工业监控任务,但在某些特定场景下,这些内置功能可能无法满足需求,这时就需要使用 C语言来扩展 Intouch 的能力,主要应用场景包括:
-
高性能计算和复杂算法:
(图片来源网络,侵删)- 当你需要执行非常复杂的数学运算(如 FFT 快速傅里叶变换、高级滤波算法、PID 控制算法的精确实现)时,C语言的高效性能远超 Intouch 的内置脚本。
- 对一个高速传感器数据进行实时滤波处理。
-
与硬件或特殊协议的直接通信:
- Intouch 通过 I/O Server(I/O服务器)与PLC、DCS等设备通信,如果遇到以下情况,就需要 C语言:
- 没有现成的 I/O Server:对于一些非常老旧或小众的设备,可能没有现成的驱动程序。
- 需要自定义通信协议:设备使用的是非标准的、私有的通信协议。
- 需要处理底层串口/网络通信:直接操作串口(RS232/RS485)或进行复杂的网络 socket 编程。
- Intouch 通过 I/O Server(I/O服务器)与PLC、DCS等设备通信,如果遇到以下情况,就需要 C语言:
-
实现高级功能或集成外部系统:
- 与第三方库集成:调用用 C语言编写的 DLL(动态链接库)文件,以实现 Intouch 本身不具备的功能,例如人脸识别、图像处理、调用特定的硬件SDK等。
- 后台服务任务:创建一个独立于 Intouch 界面的后台服务程序,用于执行周期性的任务,如数据归档、文件备份等,并通过某种方式(如内存映射、共享内存、TCP/IP)与 Intouch 交换数据。
-
提高执行效率:
对于需要被频繁调用的函数(每一秒都要执行上百次的单位转换或逻辑判断),将其编译成 C/C++ 的 DLL,其执行速度会比 Intouch 的 QuickScript 快几个数量级。
(图片来源网络,侵删)
如何在 Intouch 中使用 C语言?
主要有两种方式,最常用的是第一种。
创建并调用 C/C++ 动态链接库 (DLL)
这是最核心、最标准的方法,其基本流程是:
Step 1: 编写 C/C++ 源代码
创建一个 C 语言源文件(myutils.c),编写你需要的功能函数。关键点:这个函数必须遵循特定的调用约定(通常是 __stdcall),以便 Intouch 能够正确调用。
// myutils.c
#include <windows.h> // 包含 Windows API 头文件
// __stdcall 是 Intouch 调用 DLL 函数的标准约定
// __declspec(dllexport) 告诉编译器这个函数需要导出,供外部程序调用
double __declspec(dllexport) __stdcall CalculateAverage(double* pData, int iCount)
{
double sum = 0.0;
for (int i = 0; i < iCount; i++)
{
sum += pData[i];
}
return (iCount > 0) ? (sum / iCount) : 0.0;
}
// 另一个示例:从DLL中返回一个字符串
// 注意:字符串内存必须由DLL管理,或者使用固定的静态缓冲区
char* __declspec(dllexport) __stdcall GetStatusMessage()
{
static char message[256] = "System Status: OK"; // 使用静态变量
return message;
}
Step 2: 编译生成 DLL 文件
使用 Visual Studio、MinGW 或其他 C/C++ 编译器,将上面的源代码编译成一个 DLL 文件(myutils.dll),在 Visual Studio 中,需要创建一个 "动态链接库(DLL)" 项目。
Step 3: 在 Intouch 中配置和使用
-
添加 DLL:
- 在 Intouch 开发环境中,打开 "Specialty Tags"(特殊标签)或 "Access Names"(访问名)。
- 创建一个 "Access Name",类型选择 "Fast Access to DLL"。
- 在 "Program Name" 字段中,输入你的 DLL 文件的完整路径,
C:\MyProject\myutils.dll。
-
定义 I/O Item (I/O项):
- 在该 "Access Name" 下,创建一个 "I/O Item"。
- Item Name: 输入你在 C 函数中定义的函数名,
CalculateAverage。 - Data Type: 选择与函数返回值和参数类型匹配的 Intouch 数据类型,对于上面的
CalculateAverage,返回值是Double,参数是一个Double数组和一个Integer。
-
在 QuickScript 或动画连接中调用:
- 你可以在 Intouch 的任何地方(如按钮的
Clicked事件、动画连接的Expression中)像使用普通变量一样调用这个函数。 - 在一个按钮的
Clicked事件中写入 QuickScript:
// 假设你有一个名为 "ArrayTag" 的数组标签,长度为 10 // 调用 DLL 函数 double avg = CalculateAverage(ArrayTag, 10); // 将结果存入另一个标签 "AverageValue" AverageValue = avg; // 调用获取字符串的函数 string status = GetStatusMessage(); StatusMessage = status;
- 你可以在 Intouch 的任何地方(如按钮的
使用 C++ 开发 I/O Server
对于复杂的硬件通信,更专业的方法是使用 C++ 开发一个自定义的 I/O Server,这个 Server 作为一个独立的 Windows 服务运行,负责与硬件设备通信,然后将数据通过标准的 I/O Server 接口(如 SuiteLink 协议)提供给 Intouch。
- 优点:性能高、稳定、不占用 Intouch 主线程资源,结构清晰。
- 缺点:开发复杂度更高,需要深入理解 I/O Server 开发规范(如 Wonderware 的 I/O Server Toolkit)。
一个完整的示例:计算数组平均值
目标:Intouch 中有一个名为 TemperatureArray[10] 的数组,我们想通过一个按钮点击事件,计算它的平均值,并将结果显示在 AvgTemp 标签中。
C 代码 (calc_avg.c)
#include <windows.h>
// 导出函数,供 Intouch 调用
// 参数1: double数组指针 (In)
// 参数2: 数组元素个数 (In)
// 返回值: 计算出的平均值 (Out)
double __declspec(dllexport) __stdcall GetArrayAverage(double* pArray, int iSize)
{
if (iSize <= 0) return 0.0;
double dSum = 0.0;
for (int i = 0; i < iSize; i++)
{
dSum += pArray[i];
}
return dSum / iSize;
}
编译为 DLL
使用 VS 编译生成 calc_avg.dll,并放到一个固定路径,如 C:\IntouchDLL\。
Intouch 配置
-
创建 Access Name:
- Name:
MyDLLAccess - Program Name:
C:\IntouchDLL\calc_avg.dll - 其他默认。
- Name:
-
创建 I/O Item:
- 在
MyDLLAccess下,创建一个 I/O Item。 - Item Name:
GetArrayAverage(必须和C函数名完全一样) - Data Type:
F8(对应 Double) - 其他默认。
- 在
-
创建标签:
TemperatureArray[10]: 一个包含10个元素的F8数组标签。AvgTemp: 一个F8标签,用于存储平均值。
-
编写 QuickScript:
- 选中一个按钮,打开其
Clicked事件,输入以下脚本:
// 调用我们创建的I/O Item,就像使用一个函数一样 // Intouch会自动将TemperatureArray的地址和长度(10)作为参数传递给DLL AvgTemp = GetArrayAverage;
- 选中一个按钮,打开其
运行效果
当运行程序并点击按钮时,AvgTemp 标签的值就会被更新为 TemperatureArray 数组的平均值。
注意事项与最佳实践
- 数据类型匹配:Intouch 和 C语言的数据类型(如
int,double,char*)必须精确对应,否则会导致数据错乱或程序崩溃。 - 内存管理:
- 避免内存泄漏:在 DLL 中动态分配的内存(
malloc,new),除非有明确的机制释放,否则很容易造成内存泄漏。 - 字符串处理:从 DLL 返回字符串时,最佳实践是使用静态缓冲区(如示例中的
static char),或者让调用方(Intouch)提供一个缓冲区作为参数传入。
- 避免内存泄漏:在 DLL 中动态分配的内存(
- 错误处理:DLL 函数应该具备一定的健壮性,处理无效输入(如空指针、负数长度)等情况,并返回一个安全的默认值。
- 性能瓶颈:频繁地在 Intouch 和 DLL 之间传递大量数据(每次循环都传递一个很大的数组)可能会成为新的性能瓶颈,尽量传递处理后的结果或索引。
- 调试:调试 DLL 中的代码比调试普通脚本复杂,通常需要将 Visual Studio 的附加到
InTouch.exe进程上进行调试。
| 特性 | Intouch 内置脚本 | C/C++ DLL 扩展 |
|---|---|---|
| 语言 | 类 Basic 的脚本语言 | C/C++ |
| 性能 | 较慢,适合逻辑控制 | 极高,适合计算和通信 |
| 开发复杂度 | 低,图形化,易于上手 | 高,需要编译器和编程知识 |
| 主要用途 | 界面逻辑、数据记录、简单计算 | 复杂算法、硬件通信、系统集成、性能优化 |
| 集成方式 | 直接在事件或表达式中调用 | 通过 I/O Name 和 I/O Item 间接调用 |
"Intouch C语言" 是指利用 C/C++ 编写的 DLL 来增强 Intouch SCADA 系统功能的一种高级开发技术,它是一种“点金术”,让你能够突破 Intouch 原生功能的限制,解决更复杂、更底层的工业自动化问题。
