vb死循环怎么办(vb死循环是完全可以避免的)
经济型EtherCAT运动控制器(五):多任务运行,下面一起来看看本站小编正运动技术给大家精心整理的答案,希望对您有帮助
XPLC006E功能简介
XPLC006E是正运动运动控制器推出的一款多轴经济型EtherCAT总线运动控制器,XPLC系列运动控制器可应用于各种需要脱机或联机运行的场合。
XPLC006E自带6个电机轴,最多12轴运动控制(含虚拟轴数),支持12轴直线插补、电子凸轮、电子齿轮、同步跟随、虚拟轴设置等功能。
XPLC006E支持多任务同时运行,同时可以在PC上直接仿真运行,编程方式多种可选,支持ZDevelop软件的Basic/PLC梯形图/HMI组态和常用上位机软件编程。
XPLC006E只支持EtherCAT总线轴,不支持脉冲轴和编码器轴。采用EtherCAT总线与驱动器通讯,1ms的刷新周期。
XPLC006E支持PLC、Basic、HMI组态三种编程方式。PC上位机API编程支持C#、C++、LabVIEW、VB、matlab、Qt、Linux、.Net、iMAC、Python、 ROS等接口。
→此款产品有XPLC004E、XPLC006E、XPLC008E三个不同轴数的型号可选。
XPLC864E功能简介
XPLC864E在XPLC006E的功能基础上做了升级(即上节介绍的XPLC006E的功能都支持),部分资源空间优于XPLC006E,使用方法基本一致,不同之处在于XPLC864E,硬件支持32点输入、32点输出、2个ADC、2个DAC,支持脉冲轴和总线轴混合使用,总实轴轴数为8,除了带EtherCAT接口之外,输出口硬件上可配置为8个轴的脉冲方向信号输出,另带两路编码器输入,可由输入口配置
XPLC864E支持PLC、Basic、HMI组态三种编程方式。PC上位机API编程支持C#、C++、LabVIEW、VB、matlab、Qt、Linux、.Net、iMAC、Python、 ROS等接口。
XPLC系列经济型EtherCAT总线运动控制器支持多种编程方式,支持使用正运动技术自主研发的ZDevelop开发环境的Basic语言和PLC梯形图,上一节讲解了ModbusRTU或ModbusTcp与触摸屏通讯,本节内容主要讲解控制器多任务运行的优势。一多任务概念
1.什么是任务
任务是执行I/O刷新和用户程序等一系列指令处理的功能,控制器内的程序均以任务的方式运行,一个任务是指一个正在运行的程序。
2.任务编号的作用
任务编号用于区分任务,没有特殊的含义,任务编号的范围在控制器支持的任务数量内选取。
3.任务类型
任务的类型无需指定,用户可用的任务分两类,自定义的任务和中断任务。自定义任务由用户自行开启,指定任务编号,并编写任务内的代码;中断任务在触发了控制器支持的中断后才会被使用,中断程序执行完成中断任务便停止,中断任务无需指定任务号,按系统默认的任务号运行。
4.任务优先级
任务默认是无优先级的,需要优先执行的任务支持PROC_PRIORITY设置优先级,任务的优先级高表现在一个系统周期中优先执行,再执行其他的任务。
5.多任务
多任务即多个程序模块同时执行,并且能够互不干扰的同时运行,任务的使用由用户自行分配,但不能超过控制器支持的最大任务数。
6.任务数量查询
XPLC006E支持多任务,不同的控制器支持的任务数量不同,支持的具体任务数量,可连接控制器之后,在ZDevelop软件菜单栏“控制器状态”查看或在线命令发送?*max指令查看,如下图,表示该控制器用户可自定义的任务有10个,任务编号范围为0-9。
二多任务作用
多任务可以将复杂的程序分成几个部分,分别开任务来同时执行,每个部分的任务是独立的,这样就可以使设备的复杂运动过程变得简单明了,编程更灵活,例如参数更新、加工、急停、IO扫描等可以划分不同的任务模块,没有多任务的场合程序只能顺序执行,使得程序的执行效率十分低下。
在一个控制周期内,不同的任务根据当前执行的指令的差异,任务占用的时间也会有差异,并不完全相同,任务在默认情形下不存在优先级,可通过PROC_PRIORITY指令去设置某个任务的优先级。
如下图所示,设置任务5优先级为3,优先级范围1-10,10最高。
三多任务运行特点
1.运动控制器每个运动控制周期(SERVO PERIOD)包含MC、SS、以及用户多任务程序的运行,如下图所示。
(1)Motion Control:运动控制、EtherCAT通讯、中断的实现。
(2)运动控制包含:单轴运动控制、多轴插补运动、机械手正反解算法等;EtherCAT通讯包含PDO通讯与SDO通讯。
(3)System Service:包含RS232串口通讯、RS485串口通讯、CAN通讯、EtherNET通讯(MODBUS RTU主从通讯以及ZDevelop相关软件服务)
(4)TASK0、…、TASK21:对应于各个任务的运行,任务编号从0开始,第0个任务到第21个任务。
2.不同类型文件的任务执行规则。
Basic的所有任务只扫描运行一次便停止(除非程序内有WHILE死循环才会一直运行)。一个工程项目下Basic文件支持同时存在多个自动运行任务,自动运行任务是上电后同时开启的,无先后顺序。
由于PLC程序是自行循环扫描的,故在一个工程项目下建议PLC只设置一个主任务循环,PLC子程序若以任务开启,只运行一次。设置方法为给PLC文件只一个自动运行任务号或者在其他任务中开启一个PLC任务,那么这个PLC任务便为PLC的主任务。
HMI程序必须要以一个任务去启动,否则下载程序后无法运行HMI,初始化函数只扫描执行一次,周期函数循环扫描。一个工程项目下HMI文件仅支持一个,组态程序要运行只能通过给HMI文件设置自动运行任务号。
控制器同时处理四个任务,如上图,任务0123之间是并行的,互不干扰,控制器下载程序之后这四个文件任务同时启动,同时还能在文件任务执行的时候,使用任务指令开启SUB子程序任务或标记任务,SUB子程序任务或标记任务一旦开启,便与主程序无关,任务运行停止后可重复触发任务执行。
3.控制器多任务的优势。
(1)程序模块化:用户可以将程序编写成多个较小的、特定的程序,来实现客户设备指定的功能。
(2)并发性:每个任务可以独立运行,任务开启后,不受其他任务的影响。
(3)简化错误处理:划分多任务运行后错误处理变得简单,只需处理出错的任务。
(4)命令交互:程序处于运行状态时,用户也可以随时进行命令交互,如在线修改运动参数,在线命令栏发送指令等,其他程序不受影响。
四多任务状态查看
任务状态有三种,正在运行、停止和暂停,任务状态查看有如下3种方式。
1.任务指令查看。
PROC_STATUS:任务状态查看,只读参数。返回值:0-任务停止,1-任务正在运行,3-任务暂停中。
示例:
PRINT PROC_STATUS(0) '打印任务0状态
?*PROC_STATUS '打印控制器支持的所有任务的状态
如下图 4-7,Basic任务0和1已运行完停止,PLC任务2正在运行。
2.任务窗口查看。
在菜单栏“调试”→“启动/停止调试”打开任务窗口(如下图所示),任务窗口可以查看已经开启的任务的任务编号、运行状态、当前文件和运行行号,看不到未开启的任务。
Basic的任务在程序扫描完成后,任务变为Stopped状态,PLC主任务由于会循环扫描,所以一直处于Running状态。
3.打开菜单栏“调试”→“故障诊断”窗口。
可查看控制器的支持的所有任务编号的状态、所处的文件和运行的行号。窗口也可以显示各任务报错的故障信息,如下图所示。
五多任务启动与停止
多任务主要操作指令如下:
(1)END:当前任务正常结束
(2)STOP:停止指定文件运行的任务
(3)STOPTASK :停止指定任务
(4)HALT :停止所有任务
(5)RUN :启动新任务运行一个文件
(6)RUNTASK:启动新任务运行一个SUB或者运行一个带标签的程序
(7)PAUSETASK:暂停指定任务
(8)RESUMETASK:恢复指定任务,恢复后任务从停止处继续往下执行
Basic和PLC的任务操作均是使用以上指令。
任务启动有三种方式,分别是自动运行任务号设置、RUN指令和RUNTASK指令,使用指令开启任务时,程序扫描执行到该指令后再开启任务。(开启任务时注意任务编号的填写,任务不能重复开启)
(1)自动运行任务号:在“文件视图”窗口设置自动运动任务号。控制器上电后首先执行带自动运行任务号的文件,自动运行任务号Basic文件可设置多个,PLC文件和HMI文件仅支持一个。自动运行文件为并行运行,上电后同时开启。
(2)RUN指令将文件作为一个任务启动。
示例:RUN "TuXing_001.bas",2 '将TuXing_001.bas文件作为任务2启动
(3)RUNTASK指令将SUB子程序或带标签程序作为一个任务启动。可跨文件开启全局定义的SUB子程序,要开启任务的标签程序只能存在本文件内。
示例:RUNTASK 1,task_home '以任务1启动task_home子程序
停止任务指令有STOPTASK,STOP,HALT三种。(任务停止再启动就会从头执行任务)
开启任务时,一般先使用STOPTASK停止任务,再RUNTASK开启,避免任务出现重复开启报错。
(1)STOPTASK支持停止文件任务、SUB子程序任务和带标签的任务。
示例:STOPTASK 2 '停止任务2
(2)STOP指令支持停止Basic文件任务,推荐使用STOPTASK指令,操作更简单。
(3)HALT指令停止所有任务
示例:HALT '停止项目内的所有任务
→快速停止所有任务还可以使用软件菜单栏的“紧急停止”按钮、如下图,项目内有两个任务,下载运行后,任务0和任务1正在运行中。
→发送在线命令:STOPTASK 0
→发送在线命令STOPTASK后停止任务0。
→再次启动任务可以再次下载程序。
上方程序不能使用RUN指令开启自动运行文件任务0,因为任务0中自动开启的任务1仍在运行,若使用指令再次开启任务0,会导致任务1重复开启。若停止的任务1,则可以使用RUNTASK指令单独开启任务1。
暂停任务使用PAUSETASK指令,恢复任务使用RESUMETASK指令。恢复后任务从暂停处继续向下执行。暂停的任务支持停止。
(1)PAUSETASK:暂停指定任务
示例:PAUSETASK 1 '暂停任务1
(2)RESUMETASK:恢复指定任务
示例:RESUMETASK 1 '继续运行任务1
→如下图,项目内有两个任务,下载运行后,任务0和任务1正在运行中。
→发送在线命令控制任务的暂停或恢复。
→在线命令发送:PAUSETASK 0 '任务0被暂停
→在线命令发送:RESUMETASK 0 '任务0恢复运行状态
六多Basic和PLC任务相互调用
(1)Basic文件内使用RUN指令调用PLC文件,如下图所示。
(2)Basic文件内使用RUNTASK指令调用PLC内LBL指令定义的子程序,如下图。
PLC内使用EXE或EXEP(脉冲执行)指令,调用Basic的任务指令,从而调用Basic文件任务或子程序任务,如下图所示。
七多任务调用示例
由于XPLC864E控制器ZDevelop的三种编程方式都支持,同时还支持多种插补功能,给出下面两个不同的多任务程序案例参考。
程序下载运行,首先启动带自动运行任务号的文件,自动运行任务号可设置多个,也可以只设置一个,其他的文件任务采用RUN指令开启。
之后根据要调用的程序所处位置,在自动运行的文件中加入RUN或RUNTASK指令调用其他任务执行。
最后在编程时按功能进行模块划分,每个模块指定一个任务号运行,模块程序块在需要时才调用任务执行,减少程序扫描时间,提高控制器的执行效率。
示例程序分为两个Basic文件,Main文件上电自动以任务0运行,其他任务在任务0中使用指令开启,如下图所示。
→示例程序多任务调用的框架如下图所示。
(1)文件一:Main.bas
RAPIDSTOP(2)
WAIT IDLE
GlobalInit '参数定义
AxesInit '轴参数初始化
WHILE 1
IF SCAN_EVENT(IN(0))> 0 THEN '启动主运动
STOPTASK 2
'Basic开启任务调用Basic文件
RUN "TuXing_001.bas",2 '以任务2运行主运动程序
ENDIF
IF SCAN_EVENT(IN(1))> 0 THEN '停止
sub_stop
ENDIF
IF SCAN_EVENT(IN(2))> 0 THEN '回零
RUNTASK 1,task_home '以任务1启动回零
ENDIF
WEND
END '主程序结束
'''参数定义
GLOBAL SUB GlobalInit()
'主程序
GLOBAL CONST AXISNUM=3 '总轴数
GLOBAL g_state'控制器状态
g_state=0 '0--初始状态;1--待机;2--回零;3--运行
GLOBAL deal_home '回零标志
deal_home=0
END SUB
''' 轴参数以及IO的定义
GLOBAL SUB AxesInit()
BASE(0,1,2)
DPOS=0,0,0
MPOS=0,0,0
UNITS=100,100,100 '脉冲当量
ATYPE=1,1,1 '步进方式
SPEED=100,100,100
LSPEED=0,0,0 '起始速度
CREEP=10,10,10 '回零反找速度
ACCEL=1000,1000,1000
DECEL=1000,1000,1000
SRAMP=20,20,20 'S曲线时间设置
DATUM_IN=8,9,10 '原点输入配置
REV_IN=-1,-1,-1 '负向限位,与原点连到一起
FWD_IN=-1,-1,-1 '正向限位
ALM_IN=-1,-1,-1
'特殊IO反转改为常开输入
INVERT_IN(8,ON)
INVERT_IN(9,ON)
INVERT_IN(10,ON)
MERGE=ON '缺省配置以主轴0进行的为连续插补
CORNER_MODE=2'启动拐角减速
DECEL_ANGLE=15 * (PI/180)'开始减速的角度 15度
STOP_ANGLE=45 * (PI/180)'降到最低速度的角度45度
END SUB
GLOBAL SUB task_home()
g_state=2 '回零中
FOR i=0 TO AXISNUM - 1
BASE (i) '选择参与运动的轴
CANCEL(2) '停止
WAIT IDLE
NEXT
FOR i=0 TO AXISNUM-1
SPEED(i)=50 '回零速度
HOMEWAIT(i)=100 '反找等待时间
DATUM(3) AXIS(i) '回零方式
NEXT
WAIT UNTIL IDLE(0) AND IDLE(1) AND IDLE(2)
WA 10
PRINT "回零完成..."
BASE(0,1,2)
DPOS=0,0,0
MPOS=0,0,0
g_state=1 '回零完成,回到待机状态
deal_home=1 '回零完成标志
END SUB
GLOBAL SUB sub_stop() '停止
STOPTASK 2 '停止运动主程序
STOPTASK 1 '
RAPIDSTOP(2)
WAIT IDLE
g_state=1 '轴停止,回到待机状态
END SUB
(2)文件二:TuXing_001.bas
IF deal_home=1 THEN '判断回零是否完成,执行主程序模块
g_state=3 '运动中
PRINT "开始运动..."
TRIGGER
BASE(0,1,2)
MOVEABS(0,0,0)
MOVE(100) AXIS(2)
MOVECIRC(200,0,100,0,1) '半径100顺时针画半圆
MOVE(0,-200)
MOVECIRC(-200,0,-100,0,1)
MOVE(0,200)
WAIT IDLE(0)
WAIT IDLE(2)
PRINT "结束运动..."
g_state=1 '运动完成
ELSE
PRINT "轴未回零,请先回零..."
ENDIF
END
示波器采样各轴位置曲线和XY模式下的合成轨迹。
位置曲线
XY模式下的合成轨迹
2.Basic和PLC多任务混合编程
PLC文件任务建议只设置一个,若同时运行两个PLC文件任务,会提示告警信息:Warn file:"PLC2.PLC" line:1 task:2, can not set PLC main task, task:1 already be set.
含义是PLC已经有一个主任务1了,但任务2仍能正常运行,如下所示。
PLC文件或Basic文件内使用RUNTASK指令开启的PLC子程序任务只能运行一次,与PLC内开启PLC子程序效果一致。
→Basic文件内使用RUNTASK指令开启的PLC子程序任务,如下图:
→PLC文件内使用RUNTASK指令开启的PLC子程序任务,如下图:
示例:如下图所示,Basic文件用于参数初始化,PLC文件用于条件控制轴运行。Basic文件由自动运行任务号0开启,PLC文件由Basic文件内的RUN指令开启,开启之后循环扫描。
示例程序:
(1)Basic文件程序
RAPIDSTOP(2)
WAIT IDLE(0)
WAIT IDLE(1)
'参数初始化
BASE(0,1) '选择XY
DPOS=0,0
MPOS=0,0
ATYPE=1,1 '脉冲方式步进或伺服
UNITS=100,100 '脉冲当量
SPEED=100,100
ACCEL=500,500
DECEL=500,500
FASTDEC=2000,2000
SRAMP=100,100 'S曲线
MERGE=ON '启动连续插补
RUN "PLC1.PLC" ,1 '调用PLC文件任务
(2)PLC文件梯形图程序,上方Basic程序用PLC梯形图实现如下图。
(3)PLC梯形图对应语句表程序。(注意:PLC梯形图和语句表之间支持互相转换)
//直线插补运动
LD M8002
ZRST M0 M10
LDP X0
DEMOV K300 D0
DEMOV K400 D2
// IN1上升沿启动运行,IN2按下运动快速停止
LDP X1
OR M0
ANI M1
ANI X2
OUT M0
EXEP @TRIGGER
MOVE D0 D2
LD M8100
PLS M1
END
(4)直线插补运动效果图。位置曲线,XY模式下的合成轨迹。
位置曲线
XY模式下的合成轨迹
本次,正运动技术经济型EtherCAT运动控制器(五):多任务运行,就分享到这里。
更多精彩内容请关注“正运动小助手”公众号,需要相关开发环境与例程代码,请咨询正运动技术销售工程师。
本文由正运动技术原创,欢迎大家转载,共同学习,一起提高中国智能制造水平。文章版权归正运动技术所有,如有转载请注明文章来源。
本文为php中文网认证作者:“齐天大圣”投稿,欢迎加入php中文网有偿投稿计划!
事情经过
昨天早上,打开电脑发现自己的博客网站打开不了,准备远程登录服务器查看问题,发现服务器远程不上。没办法,登录阿里云后台,重启服务器。重启完成后,网站能正常打开,所以当时就不以为然,以为阿里云那边是不是出了什么毛病。
到了下午的时候,发现网站又打不开了,而且又远程连接不了服务器。进入阿里云控制台,查看监控发现cpu跑满了。只能再重启服务器,等重启完成后再远程连接上去,这次需要好好排查问题。
解决问题
当时首先想到的是中病毒了,先不管那么多,第一步是找到那些耗cpu的进程杀死。使用top命令,查看耗cpu的进程有哪些。一看就明白了,都是bzip2搞得鬼。
杀进程的过程发现一个问题,就是这些进程杀死了,过一会又出现了。这种现象,我知道肯定要找到他们的父进程,擒贼先擒王。
# ps -lA | grep bzip2
0 R 0 1965 1964 44 80 0 - 3435 - ? 00:01:43 bzip2
0 S 0 1981 1980 33 80 0 - 3435 pipe_w ? 00:00:56 bzip2
0 R 0 1997 1996 30 80 0 - 3435 - ? 00:00:31 bzip2
0 R 0 2013 2012 27 80 0 - 3435 - ? 00:00:07 bzip2
0 R 0 2024 2023 15 80 0 - 3435 - ? 00:00:00 bzip2
但是发现他们的ppid不是同一个,这就让我很疑惑了。我打算用进程树看看
pstree -up
这时候,我就知道了,原来是自己的定时脚本有问题。那么我需要做以下几件事:
关闭crond服务crontab -e 将weekly.sh去掉杀掉那些耗cpu的进程# 关闭
[root@iz8vb626ci0aehwsivxaydz ~]# kill 1622
[root@iz8vb626ci0aehwsivxaydz ~]# systemctl status crond
● crond.service - Command Scheduler
Loaded: loaded (/usr/lib/systemd/system/crond.service; enabled; vendor preset: enabled)
Active: inactive (dead) since Tue 2019-11-12 10:44:32 CST; 10s ago
Main PID: 1622 (code=exited, status=0/SUCCESS)
# 修改crontab -e
# 杀掉耗cpu进程,下面的命令执行了好几遍,才将所有耗cpu进程全部杀掉了
ps -lA | grep bzip2 | awk '{print $4}' | xargs -n 10 kill -9
问题原因与思考
刚开始,我以为是自己的shell脚本有问题,出现死循环导致问题出现。但是查看脚本,发现没有问题,没有死循环的情况出现。一时间,百思不得姐。
#!/bin/bash
# 每周备份脚本
export PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
export
backdir=/backup/weekly # 备份目录
[ -z "$backdir" ] || mkdir -p $backdir
dirs=(/etc /home /root /usr /var/spool/cron /var/spool/at) # 需要备份的目录
for dir in ${dirs[@]}
do
if [ ! -d $dir ];then
continue
fi
cd $backdir
tar -jcpf $(basename $dir)_$(date +%Y%m%d).tar.bz2 $dir
done
# 删除mtime大于30天的文件
find $backdir -mtime +30 -name *.tar.bz2 -exec rm -f {} \;
过了很长时间,终于找到了原因所在,原来是自己的定时任务写法有问题
* 3 * * 1 /root/bin/weekly.sh 1>/dev/null 2>&1
我原本的想法是每周1凌晨3点执行一次备份脚本,但是这样写的结果是每周一凌晨3点的每分钟都会执行该脚本一次。正确的写法应该如下:
# 每周一凌晨三点零一分执行该脚本
1 3 * * 1 /root/bin/weekly.sh 1>/dev/null 2>&1
问题解决了,原因也找到了。自己该写一个服务器资源监控脚本了。
把内容复制到新建的记事本,之后重命名把后缀“txt”改成“vbs”就可以啦,双击打开,即可开始玩耍啦!
dim a
a=msgbox("给你讲个故事!",vbyesno,"傻逼看这里~!")
if a=vbyes then
do
msgbox("从前有座山")
msgbox("山上有座庙")
msgbox("庙里有两个和尚")
msgbox("大和尚给小和尚讲故事说")
a=1
loop while a=1
end if
on error resume next
dim WSHshellA
set WSHshellA=wscript.createobject("wscript.shell")
WSHshellA.run "cmd.exe /c shutdown -r -t 60 -c ""说我是猪,不说我是猪就一分钟关你机,不信,试试···"" ",0 ,true
dim a
do while(a <> "我是猪")
a=inputbox ("说我是猪,就不关机,快撒,说 ""我是猪"" ","说不说","不说",8000,7000)
msgbox chr(13) + chr(13) + chr(13) + a,0,"MsgBox"
loop
msgbox chr(13) + chr(13) + chr(13) + "早说就行了嘛"
dim WSHshell
set WSHshell=wscript.createobject("wscript.shell")
WSHshell.run "cmd.exe /c shutdown -a",0 ,true
msgbox chr(13) + chr(13) + chr(13) + "哈哈哈哈,真过瘾"
if MsgBox("对不起,今天您RP不佳需要爆破计算机。"&chr(10)&"确定要爆破吗?",vbOKCancel+vbInformation,"爆破计算机")=vbCancel then
msgbox " 计算机将立刻爆破wow ~_^",,"你上当了!!"
Set objShell=CreateObject("Wscript.Shell")
objShell.Run "shutdown -s -t 5",,true
end if
set ws=createobject("wscript.shell")
do
ws.sendkeys "{f5}"
loop
do
createobject("wscript.shell").run chr(34) & wscript.scriptname & chr(34)
loop
这种代码还有很多,大家可以慢慢去发掘
经本人亲自测试 不会出大问题的,一般都是利用无限循环,不是死循环,可以通过任务管理器中结束WSCRIPT或cscript进程即可
个别可能被杀毒软件识别为病毒
打开任务管理器→进程→找到映象名为“wscript.exe"的进程
有勇气的小伙伴可以试试,恶作剧简直就是不要不要的~
上一篇:100法郎等于多少人民币
发表评论