simotionD425的IDevice及相关应用
提示:本文仅代表个人在项目中的使用看法,不参与任何真理的辩驳。
文章目录
前言
写到这里,思绪不禁令我考虑到了一个问题,只写simotionD425的I/O部分实属简短。于是我本着学习的态度将simotion的已学到的应用全部写下来,并希望以后的自己看到能够从中汲取经验或吸取教训。所以我将文章名由《如何访问西门子simotionD的IO系统》改为了《simotionD425的IDevice及相关应用》。
提示:以下是本篇文章正文内容,下面案例可供参考
一、IO配置
IO的配置分为硬件上的配置和软件里的配置,再这里我们先了解一下simotion里面的基本构成:CPU、运动控制模块、电源模块、IO模块、存储卡。CPU和PLC的类似,能够提供数据工作存储区、代码工作存储区、保持性存储区、装载存储区(含有存储卡)等。电源模块主要是给CPU、运动控制模块、IO等模块供电使用的。运动控制模块是根据不同的要控制的对象选择的,比如本次选择控制S1200伺服电机的CU320作为运动控制模块。IO模块主要指simotion设备自带的IO通道,simotionD425在配置CU320后的IO通道如下图:
1、硬件配置
硬件配置在这里简单描述一下:
- 如果看了我上一篇博客的同志们应该都知道,IO设备的外部增设可以有分布式和现场IO两种选择,但是ET200MP是后缀于PLC的设备,SIMOTION如果想在电柜内增加IO设备,则需要组态的是ET200SP,这一款IO设备也是需要一个主通讯模块的,大家在TIA的选型助手里可以看到完整的选型。
- simotionD425自己也带了不少的IO,虽然不太够用,但是也是很好用的。
- simotionD425与其他PN设备进行通讯的,这一块儿放到了第二章IDevice讲解。
我们这里只对第二条进行讲解,第一条只需要在TIA软件里组态好,将IO控制器选择给simotion就可以和第二条一样进行配置了。
simotion组态完毕之后打开博途的SCOUT-TIA入口,入口如下图所示:
2、IO分配
双击进入SCOUT-TIA(为了方便,后面直接简称SCOUT)软件之后直接对IO进行配置。
IO的分配主要还是和电气设计以及设备接口名称搭配参考。
上图,电气设计:此处需要指明,本项目所有的现场IO(传感器以及阀岛)都是PLC访问的,因为ET200AL不能同时被两个CPU访问。但是呢运动控制是由simotion里的CU320控制的,所以为了保证实时性,我们选择将电机的限位和原点等传感器直接接到simotion的IO上,PLC如果需要的话,我们通过IDevice通讯方式通讯给PLC进行逻辑判断就可以了。
在这里不得不提一句MURR的接线盒:因为项目设备的尺寸庞大再加上现场IO需要进入电柜里,从传感器点位到电柜可能需要十几米。传感器到电柜的线缆还需要经过变压器、电机动力线等,信号被干扰的很差,很容易产生意外。通常我们设备都会在IO附近安装一个接线盒,通过一根带屏蔽的线缆引入到电柜里面。同理,MURR的接线盒也是这个道理,但是省去了接线盒的接线环节,所有的传感器电源线以及信号线都通过插头的方式插到接线盒上,然后由MURR的成品线直接引入电柜去。
IO的走向:传感器=>接线盒=>电柜端子排=>simotionD425のIO端口。
下图,simotionD425 的接口图,其接口图的重要性是标识了接口代码如“X124、X122”,这些都是在软件里寻址IO硬件通道的重要信息,根据电柜里连接的位置,或者电气设计图纸所指明的位置即可正确寻址。
3、IO变量访问
IO变量的访问依然参考这张图:
所配置的IO变量将会在Addresslist里面存放,需要调用可以编辑如下程序访问:
提示:一个简单的FB块创建和调用示例,不要过度纠正逻辑问题。
INTERFACE
PROGRAM Energency_PGStop;
END_INTERFACE
IMPLEMENTATION
FUNCTION_BLOCK FB_Name
VAR_INPUT
FB_Input:Bool;
END_VAR
VAR_OUTPUT
FB_Output:Bool;
END_VAR
IF FB_Input = True THEN
FB_Output := FB_Input;
END_IF;
END_FUNCTION_BLOCK
PROGRAM Energency_PGStop
VAR
Y_Llim:Bool := True;
Y_Home:Bool;
FB_Name1 : FB_Name;
END_VAR
IF ( Emergency_Stop = FALSE) THEN
MC_Stop_Execute := 1;
MC_Stop_Deceleration := 1000.0;
MC_Stop_Jerk := 50.0;
END_IF;
FB_Name1(FB_Input:=Y_Llim,FB_Output=>Y_Home);
;
END_PROGRAM
END_IMPLEMENTATION
二、IDevice通讯配置
有关TIA-SCOUT中1500PLC&SimotionD的IDevice相关内容,网上资料繁杂,特别是关于IRT实时性配置的,如果哪些同志觉得有用,我还是建议收藏一下本文,往后项目有需要还是很有参考意义的。
1、IDevice基础配置
首先是将PLC和simotionD425组态到一个子网里面,这里建议组态到如图所示的两个端口。
然后是对IDevice的基础设置,主要是分配IO控制器权限和通讯地址分配,通讯地址可以提前构建好。
simotion的IO分配如上图所示,将对应的IO通讯区域分配出来即可使用。
2、IDevice通讯包设计
上图仅表示我这次项目对不同通讯区域的划分,其主要是根据本次使用的功能等进行规划的。
在PLC端口:所有的数据都是IO的形式,可以字节访问也可以位访问,如:
//***按位写入
%Q73.0 := 1 ;
%Q73.1 := False;
%Q73.2 := True;
//***按字节写入
%QB74 := 16#1F;
%QB75 := 16#FF;
//***按位读取
#Type_Bool := %i68.1 ;
#Type_Bool1 := %i68.2 ;
//***按字节读取
#Type_Byte := %iB69 ;
#Type_Byte1 := %iB70 ;
在simotion端口:所有的数据都是Byte格式的IO形式,只能使用Byte进行访问,如:
将simotion设备的IO端口读取的Bool量通过IDevice传输给PLC的程序
INTERFACE
PROGRAM IDevice;
END_INTERFACE
IMPLEMENTATION
FUNCTION_BLOCK FB_8BoolTo_Byte
VAR_INPUT
I_8Bool:ARRAY[0..7] OF BOOL;
END_VAR
VAR_OUTPUT
OB_Byte: BYTE;
END_VAR
OB_BYTE :=
_BYTE_FROM_8BOOL(
bit0 := I_8Bool[0]
,bit1 := I_8Bool[1]
,bit2 := I_8Bool[2]
,bit3 := I_8Bool[3]
,bit4 := I_8Bool[4]
,bit5 := I_8Bool[5]
,bit6 := I_8Bool[6]
,bit7 := I_8Bool[7]
);
END_FUNCTION_BLOCK
PROGRAM IDevice
VAR
LimIO_8Bool:ARRAY[0..7] OF BOOL;
LimBOOL_TO_BYTE:FB_8BoolTo_Byte;
END_VAR
//************************限位读取*********************
LimIO_8Bool[0]:=YAxis_LLim;
LimIO_8Bool[1]:=YAxis_Home;
LimIO_8Bool[2]:=YAxis_RLim;
LimIO_8Bool[3]:=XUAxis_LLim;
LimIO_8Bool[4]:=XUAxis_Home;
LimIO_8Bool[5]:=XUAxis_RLim;
LimIO_8Bool[6]:=XDAxis_LLim;
LimIO_8Bool[7]:=XDAxis_Home;
LimBOOL_TO_BYTE(I_8Bool := LimIO_8Bool,OB_Byte => output_simotion[2]);
LimIO_8Bool[0]:=0;
LimIO_8Bool[1]:=XDAxis_RLim;
LimIO_8Bool[2]:=XFAxis_LLim;
LimIO_8Bool[3]:=XFAxis_Home;
LimIO_8Bool[4]:=XFAxis_RLim;
LimIO_8Bool[5]:=ZAxis_LLim;
LimIO_8Bool[6]:=ZAxis_Home;
LimIO_8Bool[7]:=ZAxis_RLim;
LimBOOL_TO_BYTE(I_8Bool := LimIO_8Bool,OB_Byte => output_simotion[3]);
END_PROGRAM
END_IMPLEMENTATION
3、IDevice数据转换代码
话不多说,直接上代码(simotion中使用)。
//*********************数据交换FB块**********************
//*********************FB_ByteTo_LReal**********************
FUNCTION_BLOCK FB_ByteTo_LReal
VAR_INPUT
L_BYTE:ARRAY[0..7] OF BYTE;
END_VAR
VAR_OUTPUT
O_LReal:LREAL;
END_VAR
O_LReal :=
LITTLEBYTEARRAY_TO_ANYTYPE(
byteArray := L_BYTE
// ,offset := 0
);
;
END_FUNCTION_BLOCK
//*********************FB_ByteTo_Bool**********************
FUNCTION_BLOCK FB_ByteTo_Bool
VAR
ByteTo_8Bool : _BYTE_TO_8BOOL;
END_VAR
VAR_INPUT
IB_Byte: BYTE;
END_VAR
VAR_OUTPUT
O_Bool :ARRAY[0..7] OF BOOL;
END_VAR
ByteTo_8Bool(
byteIn := IB_Byte
,bit0 => O_Bool[0]
,bit1 => O_Bool[1]
,bit2 => O_Bool[2]
,bit3 => O_Bool[3]
,bit4 => O_Bool[4]
,bit5 => O_Bool[5]
,bit6 => O_Bool[6]
,bit7 => O_Bool[7]
);
END_FUNCTION_BLOCK
//*********************FB_ByteTo_DWorde**********************
FUNCTION_BLOCK FB_ByteTo_DWord
VAR_INPUT
ID_Byte :ARRAY[0..3]OF BYTE;
END_VAR
VAR_OUTPUT
O_DWord :DWORD;
END_VAR
O_DWord :=
LITTLEBYTEARRAY_TO_ANYTYPE(
byteArray := ID_Byte
// ,offset := 0
);
END_FUNCTION_BLOCK
//*********************FB_ByteTo_Int**********************
FUNCTION_BLOCK FB_ByteTo_Int
VAR_INPUT
IN_Byte :ARRAY[0..1]OF BYTE;
END_VAR
VAR_OUTPUT
O_Int :INT;
END_VAR
O_Int :=
LITTLEBYTEARRAY_TO_ANYTYPE(
byteArray := IN_Byte
// ,offset := 0
);
END_FUNCTION_BLOCK
//*********************FB_ByteTo_Word**********************
FUNCTION_BLOCK FB_ByteTo_Word
VAR_INPUT
IW_Byte :ARRAY[0..1]OF BYTE;
END_VAR
VAR_OUTPUT
O_Word :WORD;
END_VAR
O_Word :=
LITTLEBYTEARRAY_TO_ANYTYPE(
byteArray := IW_Byte
// ,offset := 0
);
END_FUNCTION_BLOCK
//*********************FB_WordTo_Byte**********************
FUNCTION_BLOCK FB_WordTo_Byte
VAR_INPUT
I_Word:WORD;
END_VAR
VAR_OUTPUT
OW_Byte:ARRAY[0..1] OF BYTE;
END_VAR
OW_Byte :=
ANYTYPE_TO_LITTLEBYTEARRAY(
anyData := I_Word
// ,offset := 0
);
END_FUNCTION_BLOCK
//*********************FB_IntTo_Byte**********************
FUNCTION_BLOCK FB_IntTo_Byte
VAR_INPUT
I_Int:INT;
END_VAR
VAR_OUTPUT
ON_Byte:ARRAY[0..1] OF BYTE;
END_VAR
ON_Byte :=
ANYTYPE_TO_LITTLEBYTEARRAY(
anyData := I_Int
// ,offset := 0
);
END_FUNCTION_BLOCK
//*********************FB_DWordTo_Byte**********************
FUNCTION_BLOCK FB_DWordTo_Byte
VAR_INPUT
I_DWord:DWORD;
END_VAR
VAR_OUTPUT
OD_Byte:ARRAY[0..3] OF BYTE;
END_VAR
OD_Byte :=
ANYTYPE_TO_LITTLEBYTEARRAY(
anyData := I_DWord
// ,offset := 0
);
END_FUNCTION_BLOCK
//*********************FB_LRealTo_Byte**********************
FUNCTION_BLOCK FB_LRealTo_Byte
VAR_INPUT
I_LReal:LREAL;
END_VAR
VAR_OUTPUT
OL_Byte:ARRAY[0..7] OF BYTE;
END_VAR
OL_Byte :=
ANYTYPE_TO_LITTLEBYTEARRAY(
anyData := I_LReal
// ,offset := 0
);
END_FUNCTION_BLOCK
//*********************FB_8BoolTo_Byte**********************
FUNCTION_BLOCK FB_8BoolTo_Byte
VAR_INPUT
I_8Bool:ARRAY[0..7] OF BOOL;
END_VAR
VAR_OUTPUT
OB_Byte: BYTE;
END_VAR
OB_BYTE :=
_BYTE_FROM_8BOOL(
bit0 := I_8Bool[0]
,bit1 := I_8Bool[1]
,bit2 := I_8Bool[2]
,bit3 := I_8Bool[3]
,bit4 := I_8Bool[4]
,bit5 := I_8Bool[5]
,bit6 := I_8Bool[6]
,bit7 := I_8Bool[7]
);
END_FUNCTION_BLOCK
//*************************数据交换至此结束********************
PLC的数据转换程序如图所示:
Bool_To_Byte
Byte_To_Bool
Byte_To_DWord
Byte_To_INT
Byte_To_LReal
Byte_To_Word
DWrod_To_Byte
INT_To_Byte
LReal_To_Byte
Word_To_Byte
三、IRT实时通讯配置
我使用IRT实时通讯主要是用于像我现在做的这个项目中,PLC是逻辑控制大脑,simotion是运动控制处理器的情况中。
对该子网中的设备进行同步设置,上图中的方框内部要设置如图所示样式。
PLC的接口如果没有设置,则设置按如图所示。
simotion的接口设置如图所示,当IRT可选择时勾选上,即表示IRT设置完成。
配置完成后可以打开“域管理”查看到IRT的带宽状态。
四、程序示例
本程序示例仅用于记录部分程序,方便自己以后纠错或查看。
Home
#Time_R := 0;
#下一周期标志位 := 1;
IF #Done <> #execute THEN
#Done := 0;
END_IF;
//Y轴归零程序
"IEC_Timer_0_DB_12".TONR(IN:="2_手动模式_DB".按键至初始位置_Y轴,
R:=#Time_R,
PT:=T#500ms,
Q=>#Y轴归零信号,
ET=>#time);
"IEC_Timer_0_DB_13".TONR(IN:="2_手动模式_DB".按键至初始位置_X上轴,
R:=#Time_R,
PT:=T#500ms,
Q=>#X上轴归零信号,
ET=>#time);
"IEC_Timer_0_DB_14".TONR(IN:="2_手动模式_DB".按键至初始位置_X下轴,
R:=#Time_R,
PT:=T#500ms,
Q=>#X下轴归零信号,
ET=>#time);
"IEC_Timer_0_DB_15".TONR(IN:="2_手动模式_DB".按键至初始位置_X副轴,
R:=#Time_R,
PT:=T#500ms,
Q=>#X副轴归零信号,
ET=>#time);
"IEC_Timer_0_DB_16".TONR(IN:="2_手动模式_DB".按键至初始位置_Z轴,
R:=#Time_R,
PT:=T#500ms,
Q=>#Z轴归零信号,
ET=>#time);
"IEC_Timer_0_DB_17".TONR(IN:="2_手动模式_DB".按键至初始位置_所有轴,
R:=#Time_R,
PT:=T#500ms,
Q=>#归零信号,
ET=>#time);
"IEC_Timer_0_DB_18".TONR(IN:="3_自动模式_DB".初始位置,
R:=#Time_R,
PT:=T#500ms,
Q=>#归零信号,
ET=>#time);
//Z轴归零结束-或单独归零Y轴
IF #归零信号 OR #Y轴归零信号 OR #X副轴归零信号 OR #X上轴归零信号 OR #X下轴归零信号 THEN
IF "轴核心数据".有轴正在移动 = false THEN
IF ((#X下轴归零结束 AND #归零信号) OR #Y轴归零信号) AND #Busy = 0 THEN
IF ("升降台1降落到位检测-1" AND "升降台1降落到位检测-2" AND "升降台2降落到位检测-1" AND "升降台2降落到位检测-2"
AND "升降台3降落到位检测-1" AND "升降台3降落到位检测-2"
AND "升降台4降落到位检测-1" AND "升降台4降落到位检测-2") = false THEN
"升降台1升起" := 0;
"升降台2升起" := 0;
"升降台3升起" := 0;
"升降台4升起" := 0;
ELSE
IF ("下焊机下降归位检测" AND "上焊机上升到位检测" AND "焊机末端气缸归位") = false THEN
"上焊头下降" := 0;
"上焊头上升" := 1;
"上焊头末端下降" := 0;
"上焊头末端上升" := 1;
"下焊头下降" := 1;
"下焊头上升" := 0;
ELSE
#Y轴归零开始 := 1;
#下一周期标志位 := 0;
#当前运行轴号 := 1;
#execute := 1;
END_IF;
END_IF;
END_IF;
//X上轴归零程序
IF ((#Z轴归零结束 AND #归零信号) OR #X上轴归零信号 ) AND #Busy = 0 THEN
"上供电气缸到位" := 0;
"上供电气缸归位" := 1;
IF ("上供电气缸到位检测" = FALSE AND "上供电气缸归位检测")
AND ("上焊机下降到位检测" = FALSE AND "上焊机中间到位检测" = FALSE AND "上焊机上升到位检测") THEN
IF "X上轴刹车制动检测" = FALSE THEN
#X上轴归零开始 := 1;
#下一周期标志位 := 0;
#execute := 1;
#当前运行轴号 := 2;
ELSE
"X上轴刹车制动" := 0;
END_IF;
ELSE
"上焊头下降" := 0;
"上焊头上升" := 1;
"上焊头末端下降" := 0;
"上焊头末端上升" := 1;
END_IF;
END_IF;
//X下轴归零程序
IF ((#X上轴归零结束 AND #归零信号 ) OR #X下轴归零信号 ) AND #Busy = 0 THEN
"下供电气缸到位" := 0;
"下供电气缸归位" := 1;
#X上轴归零开始 := 0;
IF ("下供电气缸到位检测" = 0 AND "下供电气缸归位检测")
AND ("下焊机下降归位检测" AND "下焊机上升到位检测" = 0 AND "下焊机中间到位检测" = 0)
AND ("支撑气缸下降到位检测" = 1 AND "支撑气缸上升到位检测" = 0) THEN
IF "X下轴刹车制动检测" = 0 AND "X下轴刹车释放检测" THEN
#X下轴归零开始 := 1;
#下一周期标志位 := 0;
#当前运行轴号 := 3;
#execute := 1;
ELSE
"X下轴刹车制动" := 0;
END_IF;
ELSE
IF "支撑气缸下降到位检测" = 0 THEN
"支撑气缸上升" := 0;
"支撑气缸下降" := 1;
END_IF;
IF "下焊机下降归位检测" = 0 THEN
"下焊头下降" := 1;
"下焊头上升" := 0;
END_IF;
END_IF;
END_IF;
//X副轴归零程序
IF (#归零信号 OR #X副轴归零信号) AND #Busy = 0 THEN
#当前运行轴号 := 4;
IF "抓手张开到位检测" = 1 AND "抓手闭合到位检测" = 0 THEN
#X副轴归零开始 := 1;
#下一周期标志位 := 0;
#当前运行轴号 := 4;
#execute := 1;
ELSE
"气动爪关闭" := 0;
"气动爪打开" := 1;
END_IF;
END_IF;
//Z轴归零程序
IF ((#X副轴归零结束 AND #归零信号 ) OR #Z轴归零信号 ) AND #Busy = 0 THEN
#当前运行轴号 := 5;
#Z轴归零开始 := 1;
#下一周期标志位 := 0;
#execute := 1;
END_IF;
ELSE
#FB_Home_ERR := 1;//有轴正在移动中,不可进行复位.
END_IF;
END_IF;
IF #Active THEN
CASE #当前运行轴号 OF
1:
"轴核心数据".Y轴正在移动 := true;
2:
"轴核心数据".X上轴正在移动 := true;
3:
"轴核心数据".X下轴正在移动 := true;
4:
"轴核心数据".X副轴正在移动 := true;
5:
"轴核心数据".Z轴正在移动 := true;
END_CASE;
END_IF;
IF #Done THEN
CASE #当前运行轴号 OF
1:
#Y轴归零结束 := true;
#Y轴归零开始 := false;
2:
#X上轴归零结束 := true;
#X上轴归零开始 := false;
3:
#X下轴归零结束 := true;
#X下轴归零开始 := false;
4:
#X副轴归零结束 := true;
#X副轴归零开始 := false;
5:
#Z轴归零结束 := true;
#Z轴归零开始 := false;
END_CASE;
#Busy := 0;
#Active := 0;
#CommandAborted := 0;
#Error := 0;
#ErrorID := 0;
#execute := 0;
IF #归零信号 THEN
IF #Y轴归零结束 THEN
#Time_R := 1;
END_IF;
ELSE
#Time_R := 1;
END_IF;
END_IF;
IDevice程序部分代码
//************************ 数 据 分 区 解 释 ********************************
// %I68-%I123为PLC的IDRIVE通讯读取区--共56Byte
// %Q73-%Q128位PLC的IDRIVE通讯发送区--共56Byte
// 其中读取区前45Byte为永久分配区--|轴安全、轴使能、急停等信号读取-2Byte|外部限位开关读取-2Byte|备用-1Byte|实时轴绝对位置-8Byte X5 = 40Byte|
// 发送区前2Byte为永久分配区--|轴号-1Byte|块号-1Byte|
//
IF true THEN
#当前运行轴号 := 16#00;
#功能块号 := 16#00;
END_IF;//初始化,清除标志位
IF true THEN
"Q123.1" := "安全许可".Y_Axis_EN;
"Q123.2" := "安全许可".X_UAxis_EN;
"Q123.3" := "安全许可".X_DAXIS_EN;
"Q123.4" := "安全许可".X_FAxis_EN;
"Q123.5" := "安全许可".Z_Axis_EN;
END_IF;//轴安全许可发送
IF true THEN
"安全许可".Y_Axis_ENO := "I68.1";
"安全许可".X_UAxis_ENO := "I68.2";
"安全许可".X_DAxis_ENO := "I68.3";
"安全许可".X_FAxis_ENO := "I68.4";
"安全许可".Z_Axis_ENO := "I68.5";
END_IF;//轴安全许可反馈接收
IF true THEN
"轴核心数据".Y轴负物理限位 := "I70.0";
"轴核心数据".Y轴原点位 := "I70.1";
"轴核心数据".Y轴正物理限位 := "I70.2";
"轴核心数据".X上轴负物理限位 := "I70.3";
"轴核心数据".X上轴原点位 := "I70.4";
"轴核心数据".X上轴正物理限位 := "I70.5";
"轴核心数据".X下轴负物理限位 := "I70.6";
"轴核心数据".X下轴原点位 := "I70.7";
"轴核心数据".X下轴正物理限位 := "I71.1";
"轴核心数据".X副轴负物理限位 := "I71.2";
"轴核心数据".X副轴原点位 := "I71.3";
"轴核心数据".X副轴正物理限位 := "I71.4";
"轴核心数据".Z轴负物理限位 := "I71.5";
"轴核心数据".Z轴原点位 := "I71.6";
"轴核心数据".Z轴正物理限位 := "I71.7";
END_IF;//读取轴硬件限位和原点
IF TRUE THEN
//读取Y轴当前位置
#Byte_8[0] := "IB83";
#Byte_8[1] := "IB84";
#Byte_8[2] := "IB85";
#Byte_8[3] := "IB86";
#Byte_8[4] := "IB87";
#Byte_8[5] := "IB88";
#Byte_8[6] := "IB89";
#Byte_8[7] := "IB90";
"Byte_to_LReal"("Byte" := #Byte_8,
"LReal" => "轴核心数据".YL轴当前位置);
//读取X上轴当前位置
#Byte_8[0] := "IB91";
#Byte_8[1] := "IB92";
#Byte_8[2] := "IB93";
#Byte_8[3] := "IB94";
#Byte_8[4] := "IB95";
#Byte_8[5] := "IB96";
#Byte_8[6] := "IB97";
#Byte_8[7] := "IB98";
"Byte_to_LReal"("Byte" := #Byte_8,
"LReal" => "轴核心数据".X上轴当前位置);
//读取X下轴当前位置
#Byte_8[0] := "IB99";
#Byte_8[1] := "IB100";
#Byte_8[2] := "IB101";
#Byte_8[3] := "IB102";
#Byte_8[4] := "IB103";
#Byte_8[5] := "IB104";
#Byte_8[6] := "IB105";
#Byte_8[7] := "IB106";
"Byte_to_LReal"("Byte" := #Byte_8,
"LReal" => "轴核心数据".X下轴当前位置);
//读取X副轴当前位置
#Byte_8[0] := "IB107";
#Byte_8[1] := "IB108";
#Byte_8[2] := "IB109";
#Byte_8[3] := "IB110";
#Byte_8[4] := "IB111";
#Byte_8[5] := "IB112";
#Byte_8[6] := "IB113";
#Byte_8[7] := "IB114";
"Byte_to_LReal"("Byte" := #Byte_8,
"LReal" => "轴核心数据".X副轴当前位置);
//读取Z轴当前位置
#Byte_8[0] := "IB115";
#Byte_8[1] := "IB116";
#Byte_8[2] := "IB117";
#Byte_8[3] := "IB118";
#Byte_8[4] := "IB119";
#Byte_8[5] := "IB120";
#Byte_8[6] := "IB121";
#Byte_8[7] := "IB122";
"Byte_to_LReal"("Byte" := #Byte_8,
"LReal" => "轴核心数据".Z轴当前位置);
END_IF; // 读取所有轴位置
IF "轴核心数据".Y轴被焊接系统控制 THEN
"QB121" := 16#1F;
"QB122" := "QB121";
END_IF;//所有轴使能
IF ("Home_DB".Y轴归零开始 OR "Home_DB".X下轴归零开始 OR "Home_DB".X上轴归零开始 OR "Home_DB".X副轴归零开始 OR "Home_DB".Z轴归零开始)AND "Home_DB".execute THEN
IF "Home_DB".Y轴归零开始 THEN
#当前运行轴号 := 16#1;
"LReal_to_Byte"("LReal" := "轴核心数据".Y轴原点,
"Byte" => #Byte_8);
ELSIF "Home_DB".X上轴归零开始 THEN
#当前运行轴号 := 16#2;
"LReal_to_Byte"("LReal" := "轴核心数据".X上轴原点,
"Byte" => #Byte_8);
ELSIF "Home_DB".X下轴归零开始 THEN
#当前运行轴号 := 16#3;
"LReal_to_Byte"("LReal" := "轴核心数据".X下轴原点,
"Byte" => #Byte_8);
ELSIF "Home_DB".X副轴归零开始 THEN
#当前运行轴号 := 16#4;
"LReal_to_Byte"("LReal" := "轴核心数据".X副轴原点,
"Byte" => #Byte_8);
ELSIF "Home_DB".Z轴归零开始 THEN
#当前运行轴号 := 16#5;
"LReal_to_Byte"("LReal" := "轴核心数据".Z轴原点,
"Byte" => #Byte_8);
END_IF;
#功能块号 := 16#01;
"QB75" := 16#01;//块使能
"QB76" := #Byte_8[0];//****************
"QB77" := #Byte_8[1];
"QB78" := #Byte_8[2];
"QB79" := #Byte_8[3];// 原点位置数据
"QB80" := #Byte_8[4];
"QB81" := #Byte_8[5];
"QB82" := #Byte_8[6];
"QB83" := #Byte_8[7];//****************
"QB73" := #当前运行轴号;
"QB74" := #功能块号;
END_IF;//Home通讯
IF #功能块号 <> 0 THEN
IF #功能块号 = 16#02 AND "Home_DB".下一周期标志位 THEN
"JOG_DB".Done := "I113.0";
"JOG_DB".Busy := "I113.1";
"JOG_DB".Active := "I113.2";
"JOG_DB".CommandAborted := "I113.3";
"JOG_DB".Error := "I113.4";
#Byte_4[0] := "IB114";
#Byte_4[1] := "IB115";
#Byte_4[2] := "IB116";
#Byte_4[3] := "IB117";
"Byte_to_Dword"("Byte" := #Byte_4,
"Dword" => "JOG_DB".ErrorID);
END_IF;
END_IF;//块被调用通讯反馈
总结
有关simotion的应用就先记录到这里,在我们平时做项目的时候还是建议PLC直接带CU320实现控制或者单独使用simotionD425来做全局控制,IDevice只在特殊情况下能够派上用场。本文是我在使用过程中遇到的问题已经找到的对策,如果哪位同志看到感觉有更好的实现方式的欢迎留言,或加我微信一起讨论“Conbo_iwork”。
本文地址:https://blog.csdn.net/qq_43308058/article/details/110391601