基于C#实现ProU winPLC的程序开发

Posted 伺服与运动控制

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于C#实现ProU winPLC的程序开发相关的知识,希望对你有一定的参考价值。

点击  关注伺服与运动控制



01
winPLC机器控制平台简介


winPLC机器控制平台是功能全面的自动化控制器,集成EtherCAT现场总线、内置64路高速IO(包括最多16路200KHz高速脉冲输出和4路200KHz AB相高速计数)、丰富的网口串口等接口配置。支持C#、C++多语言开发,实现机器的逻辑和运动控制、与周边设备通讯以及机器视觉功能。
以下将介绍如何用C#语言基于Microsoft Visual Studio开发一个winPLC通过网口(EtherCAT总线)或脉冲口的运动控制应用。从新建项目、函数讲解到最后的项目开发,让我们一起熟悉项目的开发过程吧。


02
新建C#项目,添加函数库

 
1.下载安装ProU开发环境、ProH执行环境

下载链接:
http://www.proutech.com/index.php?id=download2

基于C#实现ProU winPLC的程序开发
 
2.打开ProU、ProH,在ProU上新建一个工程。

基于C#实现ProU winPLC的程序开发

3.示例使用雷赛步进驱动器 DM3C-EC556、实点IO模块 EC4-1616A做为从站。

1)在左侧工程树上单击右键 “ECAT主站”,单击添加,在弹框列表中找到相对应的驱动器和IO模块进行添加,用户可以根据项目需要的从站数量或品牌进行添加。
 
基于C#实现ProU winPLC的程序开发

2)硬件连接通过winPLC的EtherCAT网口按照ECAT主站添加的顺序。
连接顺序:WinPLC网口➡步进驱动器 DM3C-EC556➡IO模块 EC4-1616A

基于C#实现ProU winPLC的程序开发
 
4.实时系统安装教程可参考以下在线手册:
http://www.prou.cn/manual/20ProH/02Intime.html
 
(1)实时系统安装完成后,Windows右下角任务栏有如图的圆形图标。红色表示启动、淡黄色表示未启动。

基于C#实现ProU winPLC的程序开发

5.

1)打开ProH、系统设置,密码“proutech”。

基于C#实现ProU winPLC的程序开发
 
2)驱动库选择“3.incat[总线]”

注:无硬件时可以使用“1.仿真模式”进行测试;

基于C#实现ProU winPLC的程序开发

6.打开ProH后,把ProU配置好的总线数据下载到ProH。

基于C#实现ProU winPLC的程序开发

7.ProH_CPU信息_RUN亮灯即是连接成功。如果连接失败,ERR亮灯,通过查看总线诊断 确定问题。 确认成功后,关闭ProH。

基于C#实现ProU winPLC的程序开发

8.

1)打开“D:YouKongProHYKCat库文件”文件夹(软件安装默认路径),双击“双击获取并更新文件.bat” 

基于C#实现ProU winPLC的程序开发
 
2)应用程序会自动把ProH目录需要用到的配置文件、YKCAT目录的TestYK.exe拷贝到库文件夹里面。

基于C#实现ProU winPLC的程序开发

9.

1)打开库文件夹的“YKDemo.exe”使用示例程序再次确认是否能正常连接,可以直接测试轴点动定位回原和 IO 输入输出,不需要则关闭即可。

基于C#实现ProU winPLC的程序开发
 
2)选择对应的驱动库,点击初始化。对测试轴进行点动测试。

基于C#实现ProU winPLC的程序开发

10.打开 Visual Studio 2015,新建一个 C# "Windows 窗体应用程序" 的项,命名为“YKdemo”,位置存放在D盘根目录下。

1)“文件”→“新建”→ “项目” ,启动创建项目向导。

基于C#实现ProU winPLC的程序开发

2)选择开发语言为“Visual C#”和.NET Framework 以及Windows 窗体应用程序。
 基于C#实现ProU winPLC的程序开发
 
11. 把第 8 步的 双击获取并更新文件 .bat” 文件拷 “D:YKdemoYKdemoinDebug”文件夹,再双击打开“双击获取并更新文件.bat”,把配置文件自动拷贝过来。

基于C#实现ProU winPLC的程序开发
12. 把“D:YouKongProHYKCat”目录的 “YKLib.cs” 文件
拷贝到  “D:YouKongYKdemoYKdemo”。
 
基于C#实现ProU winPLC的程序开发

13.

1)在 Visual Studio 的"解决方案资源管理器",右键" YKdemo"选择“添加”——“现有项"。

基于C#实现ProU winPLC的程序开发

2)把"D:YKdemoYKdemo"目录的 “YKLib.cs"添加进来。
 
基于C#实现ProU winPLC的程序开发

14.将C#运动函数库添加进来,至此项目新建完成。

基于C#实现ProU winPLC的程序开发

 
0 3
查看API函数手册,了解其用法


1.API函数库在线链接,函数说明及示例。

手册链接:
http://www.prou.cn/manual/29YKCat/00Index.html

基于C#实现ProU winPLC的程序开发
 
2.新项目的配置需包含以下2条函数指令

1)配置驱动库以及网卡配置信息。

基于C#实现ProU winPLC的程序开发

基于C#实现ProU winPLC的程序开发

2)加载总线与脉冲卡信息

基于C#实现ProU winPLC的程序开发

3.通过调用YK_AxisMovAbs,对控制器进行单轴绝对运动控制。

1)axisIndex:轴号;
2)position:该轴运动的绝对距离;
3)Speed:该轴运动的定位速度;

基于C#实现ProU winPLC的程序开发

4.通过调用YK_AxisGoHome,对控制器进行单轴回原控制。

1)axisIndex:轴号;
2)highSpeed:该轴回原速度;
3)lowSpeed:该轴回原速度;

基于C#实现ProU winPLC的程序开发

5.通过调用YK_AxisLine2Abs,进行2轴绝对直线插补运动。

基于C#实现ProU winPLC的程序开发

6.YK_AxisCircleCenterAbs,进行2轴圆弧插补运动。
 
基于C#实现ProU winPLC的程序开发
基于C#实现ProU winPLC的程序开发


04
例程的讲解



1.例程以连接4个总线驱动器,执行电机往复运动动作。
 
基于C#实现ProU winPLC的程序开发

2.通过网口方式连接驱动器,对函数库类型进行初始化。

  
    
    
  
1/// <summary> 2 /// 库类型初始化 3 /// </summary> 4 /// <param name="sender"></param> 5 /// <param name="e"></param> 6 private void btnInit_Click(object sender, EventArgs e) 7 { 8 string strlibtype = cbxLibtype.SelectedItem.ToString(); 9 LibType libtype; 10 Enum.TryParse<LibType>(strlibtype, out libtype); 11 RetCode ret; 12 13 int win64; 14 if (Is64BitOS()) 15 win64 = 1; 16 else 17 win64 = 0; 18 19 String exe_path = 20System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase; 21 String p = Path.Combine(exe_path, "config.txt"); //"D:\YouKong\ProH\config.txt" 22 ret = YKCAT.YK_LibLoad(libtype, p, win64); 23 24 p = Path.Combine(exe_path, "ecat.bin"); //"D:\YouKong\ProH\data\ecat.bin" 25 String p1 = Path.Combine(exe_path, "ext_data.bin"); //“D:\YouKong\ProH\data 26ecat.bin" 27 28 ecat_bin.Text = "总线配置文件目录:" + p; 29 ext_data_din.Text = "脉冲卡配置文件目录:" + p1; 30 31 // ret = YKCAT.YK_BusConfig(p); 32 ret = YKCAT.YK_BusConfig2(p, p1); 33 InitAxis(); 34 DiosetGrid(); 35 InitVision(); 36 37 //初始化脉冲当量,完成后不能再次修改 38 for (UInt32 idx = 0; idx < mUserSys.axis.Length; idx++) 39 { 40 ret = YKCAT.YK_AxisSetEquiv(idx, mUserSys.axis[idx].PlsEquiv); 41 } 42 YKCAT.YK_RtExit(1); 43 44 isInit = true; 45 timerMonitor.Enabled = true; 46 btnInit.Enabled = false; 47 }
 
3.通过网口所控制的驱动器,轴0-3的位置和限位等信息。

  
    
    
  
1 /// <summary> 2 /// 状态刷新 3 /// </summary> 4 private void StatusShow() 5 { 6 //总线状态 7 EcatSts busSts; 8 YKCAT.YK_BusGetStatus(out busSts); 9 labelBusSts.Text = EcatMsg.ParseMsg(busSts); 10 11 //数字输入信号 12 Byte inVale = 0; 13 int count = mUserSys.InputGroup; 14 if (count > dataGridViewInput.RowCount) 15 { 16 count = dataGridViewInput.RowCount; 17 } 18 for (int row = 0; row < count; row++) 19 { 20 YKCAT.YK_DiGetByte((UInt32)row, out inVale); 21 for (int bit = 0; bit < 8; bit++) 22 { 23 if (0 == (inVale & (1 << bit))) 24 { 25 dataGridViewInput[bit, row].Style = styleOff; 26 } 27 else 28 { 29 dataGridViewInput[bit, row].Style = styleOn; 30 } 31 } 32 } 33 34 //数字输出信号 35 Byte outVale = 0; 36 count = mUserSys.OutGroup; 37 if (count > dataGridViewOutput.RowCount) 38 { 39 count = dataGridViewOutput.RowCount; 40 } 41 for (int row = 0; row < count; row++) 42 { 43 YKCAT.YK_DoGetByte((UInt32)row, out outVale); 44 for (int bit = 0; bit < 8; bit++) 45 { 46 if (0 == (outVale & (1 << bit))) 47 { 48 dataGridViewOutput[bit, row].Style = styleOff; 49 } 50 else 51 { 52 dataGridViewOutput[bit, row].Style = styleOn; 53 } 54 } 55 } 56 57 //轴输入信号 58 UInt32 axisSts = 0; 59 if(dataGridViewAxis.RowCount != (int)mUserSys.AxisNum) 60 dataGridViewAxis.RowCount = (int)mUserSys.AxisNum; 61 for (int idx = 0; idx < mUserSys.AxisNum; idx++) 62 { 63 YKCAT.YK_AxisGetStatus((UInt32)idx, out axisSts); 64 int offset = 2; 65 if (0 == (axisSts & (1 << (int)AxisSts.BUSY))) 66 dataGridViewAxis[offset, idx].Style = styleOff; 67 else 68 dataGridViewAxis[offset, idx].Style = styleOn; 69 offset++; 70 71 if (0 == (axisSts & (1 << (int)AxisSts.POT))) 72 dataGridViewAxis[offset, idx].Style = styleOff; 73 else 74 dataGridViewAxis[offset, idx].Style = styleOn; 75 offset++; 76 77 if (0 == (axisSts & (1 << (int)AxisSts.NOT))) 78 dataGridViewAxis[offset, idx].Style = styleOff; 79 else 80 dataGridViewAxis[offset, idx].Style = styleOn; 81 offset++; 82 83 if (0 == (axisSts & (1 << (int)AxisSts.HOME))) 84 dataGridViewAxis[offset, idx].Style = styleOff; 85 else 86 dataGridViewAxis[offset, idx].Style = styleOn; 87 offset++; 88 89 if (0 == (axisSts & (1 << (int)AxisSts.WARN))) 90 dataGridViewAxis[offset, idx].Style = styleOff; 91 else 92 dataGridViewAxis[offset, idx].Style = styleOn; 93 94 offset++; 95 } 96 97 //轴当前位置 98 double axisPos = 0; 99 for (int idx = 0; idx < mUserSys.AxisNum; idx++) 100 { 101 YKCAT.YK_AxisGetPosCmd((UInt32)idx, out axisPos); 102 dataGridViewAxis[0, idx].Value = ((int)axisPos).ToString(); 103 104 YKCAT.YK_AxisGetPosRt((UInt32)idx, out axisPos); 105 dataGridViewAxis[1, idx].Value = ((int)axisPos).ToString(); 106 } 107 }

4.通过启动按钮的事件处理函数来启动单轴往复运动。

  
    
    
  
1 //自动运动2 public void AxisAuto(object axis)3 {4 UInt32 axisIdx = (UInt32)axis;56 while (true)7 {8 if (1 == mUserSys.axis[axisIdx].exitAuto)9 break;1011 YKCAT.YK_AxisMovAbs(axisIdx, mUserSys.axis[axisIdx].AbsValue1, mUserSys.axis[axisIdx].RunSpeed);12 getAxisStatusWait(axisIdx);1314 if (1 == mUserSys.axis[axisIdx].exitAuto)15 break;1617 YKCAT.YK_AxisMovAbs(axisIdx, mUserSys.axis[axisIdx].AbsValue2, mUserSys.axis[axisIdx].RunSpeed);18 getAxisStatusWait(axisIdx);19 }20 }2122 Thread[] thAutoAxis = new Thread[128];23 private void buttonAutoStart_Click(object sender, EventArgs e)24 {25 if (!CheckTips())26 return;2728 UInt32 axis = (UInt32)comboBoxAxisSel.SelectedIndex;29 if (1 == mUserSys.axis[axis].phaseAuto)30 return;3132 mUserSys.axis[axis].phaseAuto = 1;33 mUserSys.axis[axis].exitAuto = 0;3435 mUserSys.axis[axis].thAuto = new Thread(new ParameterizedThreadStart(AxisAuto));36 mUserSys.axis[axis].thAuto.IsBackground = true;37 mUserSys.axis[axis].thAuto.Start(axis);38 }3940 private void buttonAutoStop_Click(object sender, EventArgs e)41 {42 if (!CheckTips())43 return;4445 UInt32 axis = (UInt32)comboBoxAxisSel.SelectedIndex;46 if (1 != mUserSys.axis[axis].phaseAuto)47 return;4849 mUserSys.axis[axis].phaseAuto = 0;50 mUserSys.axis[axis].exitAuto = 1;51 }5253 private void buttonRstWarn_Click(object sender, EventArgs e)54 {55 if (CheckTips())56 {57 UInt32 axis = 0;5859 if (!UInt32.TryParse(comboBoxAxisSel.Text, out axis))60 return;6162 YKCAT.YK_AxisRstWarn(axis);63 }64 }6566 private void buttonHome_Click(object sender, EventArgs e)67 {68 UInt32 axis = 0;6970 axis = (UInt32)comboBoxAxisSel.SelectedIndex;71 int speedH = mUserSys.axis[axis].RunSpeed;72 int speedL = mUserSys.axis[axis].RunSpeed / 4;7374 int mode = mUserSys.axis[axis].HomeMode;75 InitAxis(axis);76 YKCAT.YK_AxisGoHome(axis, (UInt32)mode, speedH, speedL);77 }

5.通过停止按钮的事件处理函数来停止插补运动。

  
    
    
  
0 private void buttonAutoStop_Click(object sender, EventArgs e) 1 { 2 if (!CheckTips()) 3 return; 4 5 UInt32 axis = (UInt32)comboBoxAxisSel.SelectedIndex; 6 if (1 != mUserSys.axis[axis].phaseAuto) 7 return; 8 9 mUserSys.axis[axis].phaseAuto = 0; 10 mUserSys.axis[axis].exitAuto = 1; 11          }

6. 编译程序例程。

基于C#实现ProU winPLC的程序开发

7.运行单轴往复运动自动程序。

基于C#实现ProU winPLC的程序开发

以上是使用YKCAT函数库操作winPLC上的网口或者脉冲口实现运动控制的应用案例。大家可以到我们官网下载软件、例程进行学习测试。

基于C#实现ProU winPLC的程序开发


- END -

热门文章


基于C#实现ProU winPLC的程序开发

基于C#实现ProU winPLC的程序开发

基于C#实现ProU winPLC的程序开发


基于C#实现ProU winPLC的程序开发


以上是关于基于C#实现ProU winPLC的程序开发的主要内容,如果未能解决你的问题,请参考以下文章

C#开发的OpenRA的纹理图片显示到顶点缓冲区

C#开发的OpenRA的纹理图片显示到顶点缓冲区

C#基于UDP实现简单客户端和服务器消息发送和接收

基于C#和Blazor开发的前后端分离框架

20210311 全网唯一,物联网MQTT协议报文结构分析以及基于C#代码的报文组装实现

完全开源基于插件的开发框架(使用DEV实现Ribbon界面)