用 VB.Net 开发 CX1000 的 HMI 第二部分和 TwinCAT PLC 通讯 一 TwinCAT 动态库 TwinCAT.Ads.dll The TwinCAT.Ads.dll 是一个.NET 类库, 它提供和 ADS 设备通讯的类 如果 TwinCAT PLC 运行在 IPC 上, 则需要添加的类库是路径 \TwinCAT\ADS Api\.NET\v1.1.4322 下的 TwinCAT.Ads.dll 如果 TwinCAT PLC 运行在 CX1000 上, 则根据 CX1000 的操作系统不同添加的通讯类库也不同, 对于 WinCE.Net 则添加的类库是 \TwinCAT\ADS Api\CompactFramework\v1.0.5000 下的 TwinCAT.Ads.dll, 对于 WinXPe 则添加的类库也是路径 \TwinCAT\ADS Api\.NET\v1.1.4322 下的 TwinCAT.Ads.dll 1.VB.Net 项目中添加 TwinCAT.Ads.dll 在 VB.Net 开发环境中, 选择菜单 项目 -> 添加引用 (R), 打开 添加引用 对话框 在对话框中点击 浏览 按钮选择相应路径下的 TwinCAT.Ads.dll, 选择完毕后点击 确定 按钮则可添加到项目中
添加 TwinCAT.Ads.dll 后, 在解决方案资源管理器中可以看到 TwinCAT.Ads 如下图 二 工程开发用 VB.Net 开发运行在 CX1000 上的 HMI,CX1000 操作系统是 Windows CE.Net 4.2 1. 创建新项目打开 Microsoft Visual Studio.NET 2003 开发环境, 点击菜单 文件 -> 新建 -> 项目, 打开 新建项目 对话框
项目类型选择 Visual Basic 项目, 模板选择 智能设备应用程序, 对该项目命名并选择保存路径后按 确定 按钮, 进入下面的对话框 平台选择 Windows CE, 项目类型选择 Windows 应用程序, 然后点击 确定 按钮, 则打开 VB.Net 的开发环境
2. 添加 TwinCAT.Ads.dll 添加...\TwinCAT\ADS Api\CompactFramework\v1.0.5000 下的 TwinCAT.Ads.dll 3. 建立和 ADS 设备的通讯连接 TcAdsClient tcclient= new TcAdsClient(); tcclient.connect("192.168.1.217.1.1",801); 其中,192.168.1.217.1.1 是 CX1000 的 AMS NetID 数据的传输通过 AdsStream 类, 向 TwinCAT PLC 写数据通过 System.IO.BinaryWriter, 读数据则通过 System.IO.BinaryReader 为了建立 ADS 通讯, 在程序中还需要加入下面语句 : Imports TwinCAT.Ads Imports System.IO 4. 界面设计该项目周期性地读取 PLC 程序的 3 个布尔量 (b1,b2,b3) 和 3 整型变量 (i1, i2,i3), 在 HMI 界面上,Data1 Data2 和 Data3 下方的 3 个 TextBox 控件用来显示来自 PLC 的 3 个整数,3 个圆形指示灯用来表征来自 PLC 的 3 个布尔量, 若读取的布尔量是 True, 则相应指示灯的颜色是绿色的, 若读取的布尔量是 False, 则相应指示灯的颜色是红色的 3 个按钮 Light1 On/Off, Light2 On/Off, Light3 On/Off 可以修改 3 个布尔量的值 例如 Light1, 若当前 PLC 中的布尔量 b1 是 True, 则按下按钮 Light1 On/Off 后, 将 PLC 中的布尔量 b1 写成 False, 否则, 将 b1 写成 True 项目中的 Timer1 控件用来周期性地读取 PLC 的 3 个布尔量和 3 整型变量 按钮 Start Read 的功能是启动 Timer1 按钮 Stop Read 的功能是停止 Timer1
先把 PLC 程序下载到 CX1000 中, 使其运行起来 然后把编译的 VB.Net 程序全部拷贝到 CX1000 中, 运行文件夹 bin 中 Debug 下的可执行文件 CXTest 即可 附 : VB.Net 程序如下 : Imports TwinCAT.Ads Imports System.IO Dim hvar1, hvar2 As Integer Dim hb1, hb2, hb3 As Integer Dim tcclient As TcAdsClient Dim istream As New AdsStream(3 * 2) Dim ibinread As New BinaryReader(iStream) Dim bstream As New AdsStream(3) Dim bbinread As New BinaryReader(bStream) Dim b(3) As Boolean Private Sub btnstartread_click(byval sender As System.Object, ByVal e As System.EventArgs) Handles btnstartread.click Timer1.Enabled = True btnstartread.enabled = False btnstopread.enabled = True Private Sub btnstopread_click(byval sender As System.Object, ByVal e As System.EventArgs) Handles btnstopread.click Timer1.Enabled = False
btnstartread.enabled = True btnstopread.enabled = False Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick tcclient.read(hvar1, istream) tcclient.read(hvar2, bstream) istream.position = 0 Dim i As Integer txtdata1.text = ibinread.readint16().tostring() txtdata2.text = ibinread.readint16().tostring() txtdata3.text = ibinread.readint16().tostring() bstream.position = 0 For i = 0 To 2 b(i) = bbinread.readboolean() Next i '=================Light 1=========================== If b(0) = True Then Dim mybrush As New SolidBrush(Color.Green) g.fillellipse(mybrush, 46, 126, 40, 40) Dim mybrush As New SolidBrush(Color.Red) g.fillellipse(mybrush, 46, 126, 40, 40) '=================Light 2=========================== If b(1) = True Then Dim mybrush As New SolidBrush(Color.Green) g.fillellipse(mybrush, 189, 126, 40, 40)
Dim mybrush As New SolidBrush(Color.Red) g.fillellipse(mybrush, 189, 126, 40, 40) '=================Light 3=========================== If b(2) = True Then Dim mybrush As New SolidBrush(Color.Green) g.fillellipse(mybrush, 332, 126, 40, 40) Dim mybrush As New SolidBrush(Color.Red) g.fillellipse(mybrush, 332, 126, 40, 40) Catch err As Exception MessageBox.Show(err.Message) Private Sub btnlight1_click(byval sender As System.Object, ByVal e As System.EventArgs) Handles btnlight1.click If b(0) = True Then tcclient.writeany(hb1, False) tcclient.writeany(hb1, True)
Private Sub btnlight2_click(byval sender As System.Object, ByVal e As System.EventArgs) Handles btnlight2.click If b(1) = True Then tcclient.writeany(hb2, False) tcclient.writeany(hb2, True) Private Sub btnlight3_click(byval sender As System.Object, ByVal e As System.EventArgs) Handles btnlight3.click If b(1) = True Then tcclient.writeany(hb2, False) tcclient.writeany(hb2, True) Private Sub frmcx_load(byval sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load '=========== 建立通讯连接 ======= tcclient = New TcAdsClient tcclient.connect("192.168.1.217.1.1",801)
hvar1 = tcclient.createvariablehandle("main.ivar") hvar2 = tcclient.createvariablehandle("main.bvar") hb1 = tcclient.createvariablehandle("main.bvar[0]") hb2 = tcclient.createvariablehandle("main.bvar[1]") hb3 = tcclient.createvariablehandle("main.bvar[2]") Catch err As Exception MessageBox.Show(err.Message) Timer1.Interval = 500 btnstartread.enabled = True btnstopread.enabled = False Private Sub frmcx_paint(byval sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint '=========== 初始化指示灯的颜色为红色 ====================================== Dim mybrush As New SolidBrush(Color.Red) g.fillellipse(mybrush, 46, 126, 40, 40) g.fillellipse(mybrush, 189, 126, 40, 40) g.fillellipse(mybrush, 332, 126, 40, 40) End Class PLC 程序如下 : PROGRAM MAIN VAR ivar : ARRAY [0..2] OF INT; bvar : ARRAY [0..2] OF BOOL ; Index: BYTE; END_VAR FOR Index := 0 TO 9 DO ivar[index] := 10+ INDEX; END_FOR bvar[0]:=true; bvar[2]:=true;