本文主要是介绍codesys【虚轴】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
虚轴:
Act 回馈
Offset 末端设置SM_Drive_Virtual_1.fActPosition '电机反馈位置'
SM_Drive_Virtual_1.fLastActVelocity '电机反馈速度'
SM_Drive_Virtual_1.fLastPositionOffset '刀具末端位置偏置'SM_Drive_Virtual_1.fSetPosition '设置虚轴位置 LF' 危
SM3_Basic.AXIS_REF_VIRTUAL_SM3
AXIS_REF_SM3【父类】
【虚轴】是codesys的标准参考轴。
就跟房子的单位【平方】一样。手轮/计数io/【自由编码器】--------|-----【虚轴】【凸轮】-----|--【自由编码器】【虚轴】-------------| |--【虚轴】【实轴ECAT】---------| |--【实轴ECAT】【实轴CAN】----------| |--【实轴CAN】【位置控制驱动器】----| |--【位置控制驱动器】【虚轴】》齿轮比,凸轮等》【虚轴】
【虚轴】》【实轴】 //这个一般用于一拖多
【虚轴】》【脉冲轴】 //这个要看固件功能SMC_AXIS_STATE (ENUM) 状态:
power_off 0 PLCopen calls this state: “Disabled”
errorstop 1
stopping 2
standstill 3 '准备'
discrete_motion 4
continuous_motion 5
synchronized_motion 6
homing 7
成员:
SM_Drive_Virtual_1.fLastActPosition 最后电机反馈位置 12.3456
SM_Drive_Virtual_1.fLastPositionOffset 【刀具末端位置偏移】【父1215参数】
SM_Drive_Virtual.fLastActVelocity 最后电机反馈速度 0.00
修改虚轴坐标:
SM_Drive_Virtual_1.AXIS_REF_SM3.fActPosition
概述:codesys里有3个轴:
自由编码器 SM3_Basic.FREE_ENCODER_REF【位置】.diEncoderPosition禾川编码器 hsi_cnt.diCurCountValue; //编码器位置
虚轴 SM3_Basic.AXIS_REF_VIRTUAL_SM3【位置】.fLastActPosition 'fActPosition'【速度】.fLastActVelocity
实轴ECAT SM3_Drive_ETC_DS402_CyclicSync.AXIS_REF_ETC_DS402_CS;【位置】.fLastActPosition fActPosition【速度】.fLastActVelocity实轴CAN _3SCOS.CANRemoteDevice
流程:【高速输入:采集AB脉冲】带》【自由编码器】带》【虚轴】带》【实轴】
1虚轴:
用法和实轴一样。一般用于,一拖多。【手轮/高速输入/自由编码器】--------|-----【虚轴】-----|--【自由编码器】【虚轴】-------------| |--【虚轴】【实轴ECAT】---------| |--【实轴ECAT】【实轴CAN】----------| |--【实轴CAN】【位置控制驱动器】----| |--【位置控制驱动器】
2编码器带虚轴:
3虚轴带实轴:
GearIn和JOG必须在ecat线程内运行。【因为采集周期】
【1】计数io---位置:
【计数采集》自由编码器》虚轴》实轴】
采集的值由硬件完成,所以放哪个线程内不会影响采集精度。
// QQ750273008 // 禾川Q---高速计数器
// 硬件引脚:【A】【B】【Z】【锁存】 // Falling下降沿
// 功能:【比较】【脉冲密度】【锁存】【重载】 //[Z]引脚用于重载值刷新
// 输出:【密度值】【当前计数值】【锁存值】【计数器状态字】
hsi_cnt(
//【1】通道wDriveID:= 0, //【WORD】通道0~7,hsi_cnt到【hsi_cnt_7】//【2】计数总开关bCounterEnable:= 1 , //【BOOL】计数器功能使能位,高电平有效 diCntMinValue:= -10000, //【DINT】 【当前计数值最小值 】diCntMaxValue:= 10000, //【DINT】 【当前计数值最大值 】// 计数模式wCountMode:= 2#0000,//【模式0】 //【WORD】计数模式与计数极性设置, bit[3] : 计数极性配置 ,bit[2:0] : 计数模式配置 //[0]AB脉冲1倍速【A高电平时:B上升沿加,B下降沿减】//[1]AB脉冲2倍速//[2]AB脉冲4倍速//[3]【B脉冲加,A脉冲减 】 // 1相位2输入脚【上升沿】//[4]B脉冲,【引脚A低加高减】 // 1相位1硬件模式输入脚【B负责脉冲,A负责加减方向】//[5]B脉冲,【bSoftDirection标志位,低加高减】 // 1相位1软件模式输入脚bSoftDirection:= , //【BOOL】计数模式[5]时有效,低加高减//【3】比较值事件 bEventEnable:=0 , //【BOOL】比较事件触发使能位,高电平有效 【产品打包计数】diEventCmpValue:= , //【DINT】比较值【比较计数值】,diEventCmpValue==diCurCountValue时, 将触发计数器比较一致事件//【4】脉冲密度bDspdEnable:=1 , //【BOOL】脉冲密度使能位,高电平有效,,,脉冲密度测量,单位时间设置【单位ms】 wMeasureUnitTime:=1000 , //【WORD】脉冲密度测量,单位时间设置【单位ms】 // 单位时间内,获取脉冲数量//【5】锁存引脚 【和】Z脉冲脚bLatchEnable:=1 , //【BOOL】锁存开关,高电平有效,硬件脚触发,标记计数位置wHardTrgMethod:=2#00010001 , //【WORD】硬件触发端子,bit[6:4]: Latch【锁存端子】检查设置 ,bit[2:0]: 【Z相端子】检查设置// [0]边沿检测失能 【关闭】// [1]上升沿触发有效 【0001】// [2]下降沿触发有效 【0010】// [3]升降沿触发有效 //【注:】Z脉冲用于刷新重载值bSoftPreTrg:= , //【BOOL】触发【重载】 当该位由0->1时,diSoftPreValue将被写入到diCurCountValue//【重载值】:填编码器圈脉冲 // [0]校零,解决脉冲干扰diSoftPreValue:=0 , //【DINT】计数【重载值】 ,当前计数预置值,Z相或【bSoftPreTrg】预置触发后, 该数值将被写入diCurCountValue BZport_sel:= 6, //【BYTE】 Z相端子选择 // 0 : X0将被选择作为Z相端子// 1 : X1将被选择作为Z相端子// ........// 15 : X15将被选择作为Z相端子Blatch_sel:= 7, //【BYTE】 锁存端子选择 // 0 : X0将被选择作为【锁存】端子// 1 : X1将被选择作为【锁存】端子// ........// 15 : X15将被选择作为【锁存】端子 // 16为其他端子//【6】备用 wCmpoutCtrlword:= , //【WORD】 // 预留,v103版本支持
//【7】状态字 wStatus_clr:= , //【WORD】状态位清除字// bit0 预留// bit1 预留 // bit2 锁存完成标记清除 // bit3 硬件预置数触发完成标记清除 // bit4 软件预置数触发完成标记清除 // bit5 计数器下溢标记清除 // bit6 计数器上溢标记清除// bit7 预留// bit8 比较中断触发标记清除 // bit9 脉冲密度测量完成标记清除 // bTabCmpEnable:= , //【BOOL】wStartNum:= , //【WORD】wEndNum:= , //【WORD】//========================================
// C1脉冲密度:DINT;
// C2当前计数值:DINT;
// C3锁存值:DINT;
// C4计数器状态字:WORD;diDspdFreqValue=> C1脉冲密度, //【DINT】 脉冲密度测量值 diCurCountValue=> C2当前计数值 , //【DINT】 当前计数值diLatchData=> C3锁存值, //【DINT】 锁存值 wCounterStatus=> C4计数器状态字); //【WORD】 计数器状态字 //bit0: 计数器工作状态 //bit1: 预留//bit2: 锁存完成标记//bit3: 硬件预置数触发完成 //bit4: 软件预置数触发完成 //bit5: 计数器下溢标记 //bit6: 计数器上溢标记 //bit7: 当前计数方向 //bit8: 比较中断触发标记 //bit9: 脉冲密度测量完成标记 //SMC_FreeEncoder.diEncoderPosition:=hsi_cnt.diCurCountValue; //编码器位置 //SMC_FreeEncoder.diEncoderPosition:=GVL.电位器1;// IoConfig_Globals.hsi_cnt.bSoftPreTrg ; // 编码器手动校零【 := True 】 // 解决编码器干扰
【2】位置---自由编码器:
SMC_FreeEncoder.diEncoderPosition:=hsi_cnt.diCurCountValue; //编码器位置
【增量】比【应用单元】1000 : 5 // 作用是给编码器赋值1000,编码器导程是5mm【模数】这个不起作用,只是用于可视化,转多少mm后,电机转一圈。默认360mm后转一圈。
【3】自由编码器---虚轴:
虚轴【JOG】等函数,不能放在ecat线程内????? '放在MainTask'
同样只有【模数】这一个选项,用于导程mm虚轴的作用是【一拖多】
【4】虚轴---实轴Ecat:
每秒转速 := 每分钟转速 x 导程5 ÷ 60秒
125对应1500转 500对应6000转
SMC_TrackAxis '跟随'
MC_CamIn '电子凸轮'
MC_GearIn '电子齿轮'没加ecat总线时,【JOG】【POWER】函数在main线程内。
加了ecat后,【JOG】只能在ecat线程内运行Master/Slave '主/从 轴'
MC_CamIn (FB) '电子凸轮'
MC_CamOut (FB)
MC_GearIn (FB) '电子齿轮'
MC_GearInPos (FB) 指定位置切入同步
MC_GearOut (FB)
MC_Phasing (FB) 修改主从轴【相位】Direct '直接'
SMC_FollowPosition (FB)
SMC_FollowPositionVelocity (FB)
SMC_FollowSetValues (FB)
SMC_FollowVelocity (FB)
SMC_SetTorque (FB)
SMC_TrackAxis (FB)
SMC_TrackSetValues (FB)Direct Axis Control '直接轴控制'
SMC_ControlAxisByPos (FB) 位置
SMC_ControlAxisByPosVel (FB) 位置速度
SMC_ControlAxisByVel (FB) 速度
【5】位置---脉冲轴
编码器采集【位置】带【脉冲轴】无法实现,可变齿轮。解决思路是:
【编码器】【自由编码器】【虚轴】{齿轮比}【虚轴】【脉冲轴】
【6】虚轴带---can轴:
回零后,再按下stop
先按stop后,再按【点动】
变量:
FUNCTION_BLOCK FB_CAN轴VAR_IN_OUTcan轴输入: _3SCOS.CANRemoteDevice;//ecat实轴输入:SM3_Drive_ETC_DS402_CyclicSync.AXIS_REF_ETC_DS402_CS;//axis: _3SCOS.CANRemoteDevice;// //编码器轴:SM3_Basic.FREE_ENCODER_REF;
END_VARVAR_INPUTf_齿轮比:REAL:=10000;// 齿轮比【圈脉冲】u1_电源:BOOL:=FALSE;// h6040u1_点正:BOOL:=FALSE;u1_点反:BOOL:=FALSE;u1_停止:BOOL:=FALSE;u1_复位:BOOL:=FALSE;u1_回零:BOOL:=FALSE;lf_零点偏置:LREAL:=1234;u1_速度模式:BOOL:=FALSE;u1_绝对模式:BOOL:=FALSE;u1_相对模式:BOOL:=FALSE;f_速度:REAL:=10;// h6081f_加速度:REAL:=10;// h6083f_减速度:REAL:=10;// h6084f_目标速度:REAL:=10;// h60FFf_绝对坐标:REAL:=5;// h607Af_相对坐标:REAL:=5;// h607A//=====================================
// g6041:UINT:=16#250;//状态字
// g6061:SINT;//模式
// g6064:DINT;//位置
// g606C:DINT;//速度
// g6077:UINT;//力矩END_VARVAR_OUTPUT//=============================================b伺服通信状态 :BOOL;e轴运行状态 :SMC_AXIS_STATE;e轴故障代码 :MC_ERROR_CO;f轴当前位置 :LREAL;f轴当前速度 :lREAL;f轴当前转矩 :REAL;END_VARVAR//=======================x6041:UINT;// 状态字x6061:SINT;// 模式x6064:DINT;// 电机位置x606C:DINT;// 电机速度x6077:INT;// 电机力矩y6040:UINT;//控制字y6060:SINT;//模式y6081:UDINT;//速度y6083:UDINT;//加速y6084:UDINT;//减速y607A:DINT;//绝对坐标y60FF:DINT;//模式:速度y6071:INT;//模式:力矩y607C:DINT;//原点【偏置】
//=====================================//AXIS: _3SCOS.CANRemoteDevice;// :=ADR(DMA882_CAN); Axis1: AXIS_REF_CO ; // 局部变量
//==============================================MC_Power_CO :MC_Power_CO;MC_Home_CO :MC_Home_CO;MC_Reset_CO :MC_Reset_CO;MC_Stop_CO :MC_Stop_CO;MC_MoveVelocity_CO :MC_MoveVelocity_CO;//【速度模式】MC_MoveAbsolute_CO :MC_MoveAbsolute_CO;//【绝对定位】MC_MoveRelative_CO :MC_MoveRelative_CO;//【相对定位】MC_Jog_CO :MC_Jog_CO;//【点动】TON_0: ton;//【刷新定位】u16线程count: UINT;
END_VAR
程序:
u16线程count:=u16线程count+1;
axis1.pDevice:= ADR(can轴输入); //axis1.pDevice:= ADR(axis);
axis1.In.wStatusWord:=x6041; // 状态字
axis1.In.sActMode:=x6061; // 模式
axis1.In.dActPosition:=x6064;// 电机位置
axis1.In.dActVelocity:=x606C;// 电机速度
axis1.In.dActTorque:=x6077; // 电机力矩// 修改0x6041默认值0x0250
// IF gvl.h6041 = 16#0200
// OR gvl.h6041 = 16#8270
// OR gvl.h6041 = 16#0270//axis1.In.wStatusWordIF Axis1.In.wStatusWord =16#200 //【雷赛】默认0x0200,要改成 0x0250
OR (Axis1.In.wStatusWord AND 16#0F) =16#00 // 8670,【xxx0】
THENAxis1.In.wStatusWord := 16#250;
END_IFA00_功能块调用();y6040:=axis1.Out.wControlWord;y6060:=axis1.Out.sSetMode;y6083:=axis1.Out.dProfileAcc;y6084:=axis1.Out.dProfileDec;y607A:=axis1.Out.dTargetPos;y6081:=axis1.Out.dProfileVel;y60ff:=axis1.Out.dTargetVel;y6071:=axis1.Out.dTargetTor;//【力矩】y607C:=axis1.Out.dHomeOffset;// 原点偏置// 显示结果
b伺服通信状态 :=Axis1.bCommunication; //---读取从站通信状态
e轴运行状态 :=Axis1.nAxisState; //---读取轴运行状态
e轴故障代码 :=Axis1.eErrorID[0]; //---读取当前的轴故障代码
f轴当前位置 :=Axis1.fActPosition; //---读取伺服 反馈位置
f轴当前速度 :=Axis1.fActVelocity; //---读取伺服 反馈速度
f轴当前转矩 :=Axis1.fActTorque; //---读取伺服 反馈转矩
这篇关于codesys【虚轴】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!