中国自动化学会专家咨询工作委员会指定宣传媒体
文摘详情
gkongbbs

全闭环EtherCAT运动控制器运动到位判断方式详解

http://www.gkong.com 2026-06-17 11:22 深圳市正运动技术有限公司

ZMC432CL-V2全闭环EtherCAT运动控制器简介

ZMC432CL-V2高性能多轴运动控制器是一款兼容EtherCAT总线和脉冲型的独立式运动控制器,具备高速实时反馈功能,支持脉冲全闭环控制,能够实现高精度、高响应速度的运动控制。高精度定位,有效消除机械传动误差,满足高精密加工场景应用要求。

正运动ZMC432CL-V2全闭环EtherCAT运动控制器.png

ZMC432CL-V2硬件功能:

①丰富的运动控制功能:支持直线、圆弧、空间圆弧、螺旋插补等。

②硬件接口丰富:支持脉冲轴(带编码器反馈)和EtherCAT总线轴,具备24路输入和12路输出的通用IO,部分为高速IO,2路模拟量输出(DA)。

③EtherCAT刷新周期最快达250us,满足高速通信需求。

④支持4通道硬件比较输出、硬件定时器、运动中精准输出,适用于多通道视觉飞拍等场合。

⑤支持掉电检测、掉电存储,多种程序加密方式,能够有效防止系统故障,保护项目工程文件数据,并提高系统的可靠性。

⑥通过纯国产IDE开发环境RTSys进行项目开发,可实时仿真、在线跟踪以及诊断与调试,简便易用,支持多种高级上位机语言联合编程进行二次开发。

正运动ZMC432CL-V2全闭环EtherCAT运动控制器框架.webp

更多关于ZMC432CL-V2运动控制器的详情点击→步进控制的光栅尺全闭环解决方案:32轴EtherCAT总线运动控制器ZMC432CL-V2查看。

ZMC432CL-V2产品介绍视频请点击→步进控制的光栅尺全闭环解决方案:32轴EtherCAT总线运动控制器ZMC432CL-V2

为什么要进行轴运动到位判断?

在工业运动控制现场,控制器仅依靠运动指令状态判定动作结束,往往存在局限性。常规的IDLE状态只能识别指令位置是否执行完成,无法同步校验电机、编码器的实际运行位置。

尤其当电机存在运动滞后、传动间隙等问题时,会出现“指令显示停止,实际轴并未精准到位”的情况,进而导致上下工位对接异常、加工精度不足、设备联动出错等故障。

为保障设备运行精度与动作逻辑可靠,就需要结合现场工况,搭配多种方式综合判断轴是否真正运动到位。

本文将详细介绍四种到位判断方式、对应指令参数及编程实现方法,满足不同步进、伺服驱动器的使用需求。

01 正运动轴运动到位功能介绍

正运动控制器判断运动是否结束一般通过判断对应轴的运动状态指令【IDLE】值是否未为【0】:

①为【0】表示运动中。

②为【-1】表示停止。

但是【IDLE】只能判断指令位置是否到位,并不关心实际电机,或者说编码器反馈坐标是否到位。如果实际应用场景对于到位的要求比较严格,电机运动滞后严重的情况下,还需要加入电机实际位置是否到位的判断。



02 判断运动到位的四种方式
 

方式一:判断运动状态

通过指令位置的运动状态【IDLE】指令返回是否为【0】来判断运动是否结束。

这种方式用于不带编码器的步进,或没接编码器线的脉冲伺服。控制器的轴类型一般为【ATYPE】1/7纯脉冲轴,例程中以虚拟轴类型演示功能,实际应用中注意修改。

Basic指令介绍:

Basic指令介绍.webp

PC函数介绍:

方式一pc函数介绍.png

方式二:判断运动状态与反馈速度

通过指令位置的运动状态【IDLE】判断运动是否结束的同时,加上对伺服电机反馈速度的判断,当反馈速度低于一定阈值时认为电机到位。

这种方式要求脉冲伺服一定要把编码器线正常接入控制器,总线驱动器不是总线步进类型即可。

Basic指令介绍:

方式二Basic指令介绍:.webp

PC函数介绍:

方式二PC函数介绍:.webp

方式三:判断运动状态与到位标志(1)

通过指令位置的运动状态【IDLE】判断运动是否结束的同时,加上对到位标志【IN_POS】的判断,需要先映射好到位信号输入【AXISINP_IN】参数。

这种方式一般针对于有到位输出功能的脉冲步进与伺服,且仅限4系列与部分其他型号支持,使用前需确认。

Basic指令介绍:

方式三basic指令介绍.webp

方式三Basic指令介绍2.webp

PC函数介绍:

到位标志与到位信号输入在上位机暂时没有直接对应的API函数,需要间接通过轴参数修改函数【ZAux_Direct_GetParam】【ZAux_Direct_SetParam】访问basic指令字符串【IN_POS】【AXISINP_IN】进行读写。

方式三pc函数介绍1.webp

方式三pc函数介绍2.webp

方式四:判断运动状态与到位标志(2)

通过指令位置的运动状态【IDLE】判断运动是否结束的同时,加上对到位标志【IN_POS】的判断,需要先设置好到位距离【IN_POS_DIST】与到位速度【IN_POS_SPEED】两个参数,由于到位信号【AXISINP_IN】指令的优先级高于到位速度与到位距离,因此还需要把【AXISINP_IN】设置为【-1】,保证取消了到位信号。

这种方式与方式二相同,同样需要驱动器为带编码器的伺服驱动器,否则到位标志【IN_POS】无法实际反应电机实际位置情况。同方式三也仅限4系列与部分其他型号支持,使用前需确认。

Basic指令介绍:

方式四basic函数介绍1.webp

方式四basic函数介绍2.webp

PC函数介绍:

与方式三相同,到位距离与到位速度也需要间接通过轴参数修改函数【ZAux_Direct_GetParam】【ZAux_Direct_SetParam】访问basic指令字符串【IN_POS_DIST】【IN_POS_SPEED】进行读写。

Basic编程使用说明:

(1)轴到位判断模式与参数设置函数。

'/************************************************************
'任务编号:        无
'函数功能:        轴到位判断设置
'Input:           
'iaxis:轴号
'imode:模式选择
'InpIn:到位输入信号
'ispeed:到位速度阈值,反馈速度小于阈值认为到位
'idist:到位距离阈值,规划位置与反馈位置差值小于阈值认为到位
'Output:          无 
'返回值:          无
'备注:            无        
'*************************************************************/
GLOBAL SUB TargetReach(iaxis,imode,InpIn,ispeed,idist)
    IF imode = 1 THEN
        '方式一:仅适用于不带编码器的步进轴
        WAIT UNTIL IDLE(iaxis)		'等待运动结束
    ELSEIF imode = 2 THEN
        '方式二:通过自定义反馈速度阈值来判断是否到位。需要伺服带编码器,也是伺服轴到位的通用方式
        WAIT UNTIL IDLE(iaxis) AND ABS(MSPEED(iaxis))<ispeed		'等待运动结束、反馈速度小于阈值条件达成
    ELSEIF imode = 3 THEN
        '方式三:通过映射到位输入信号【AXISINP_IN】与到位标志指令【IN_POS】判断是否到位,需要伺服支持到位信号输出功能,用于脉冲轴,部分低系列控制器可能不支持
        AXISINP_IN(iaxis) = InpIn		'映射输入到位信号
        WAIT UNTIL IDLE(iaxis) AND IN_POS(iaxis)		'等待运动结束、到位标志触发条件达成
    ELSEIF imode = 4 THEN
        '方式四:通过设置到位参数【IN_POS_DIST】【IN_POS_SPEED】与到位标志指令【IN_POS】判断是否到位,需要伺服带编码器,部分低系列控制器可能不支持
        AXISINP_IN(iaxis) = -1				'到位信号的优先级高于到位距离、到位速度参数,如果操作不当设置了需要取消映射
        IN_POS_SPEED(iaxis) = ispeed		'设置到位速度
        IN_POS_DIST(iaxis) = idist		'设置到位距离
        WAIT UNTIL IDLE(iaxis) AND IN_POS(iaxis)		'等待运动结束、到位标志触发条件达成
    ENDIF
ENDSUB


(2)轴到位判断函数使用示例。

GLOBAL CONST mode = 0'选择对应的测试模式
if mode=1 then
    BASE(0)
    ATYPE = 0				'设置虚拟轴类型
    UNITS = 100'设置脉冲当量
    SPEED = 100				'设置运动速度
    ACCEL = 10000'设置运动加速度
    DECEL = 10000			'设置运动减速度
    AXIS_STOPREASON = 0'清除轴历史停止原因
    MOVE(1000)				'执行运动
    TargetReach(0,mode,0,0,0)			'轴0使用方式1判断到位,当运动结束时执行后续程序
    if AXIS_STOPREASON(0)=0 then 		'判断轴0是否正常运动停止,输出异常停止错误码
        PRINT "运动到位"
    else
        ''''''''''''处理运动异常流程''''''''''''
        PRINT "轴运动异常停止,停止错误码:"+TOSTR(AXIS_STOPREASON(0),1,0)
    endif
elseif mode=2 then
    BASE(0)
    ATYPE = 0'设置虚拟轴类型
    UNITS = 100				'设置脉冲当量
    SPEED = 100'设置运动速度
    ACCEL = 10000			'设置运动加速度
    DECEL = 10000'设置运动减速度
    AXIS_STOPREASON = 0	'清除轴历史停止原因
    MOVE(1000)				'执行运动
    TargetReach(0,mode,0,0.1,0)			'轴0使用方式2判断到位,当运动结束且反馈速度阈值低于0.1时执行后续程序
    if AXIS_STOPREASON(0)=0 then 			'判断轴0是否正常运动停止,输出异常停止错误码
        PRINT "运动到位"
    else
        ''''''''''''处理运动异常流程''''''''''''
        PRINT "轴运动异常停止,停止错误码:"+TOSTR(AXIS_STOPREASON(0),1,0)
    endif
elseif mode=3 then
    BASE(0)
    ATYPE = 0				'设置虚拟轴类型
    UNITS = 100'设置脉冲当量
    SPEED = 100				'设置运动速度
    ACCEL = 10000'设置运动加速度
    DECEL = 10000			'设置运动减速度
    INVERT_IN(1,ON)		'ZMC系列控制器默认到位输入口常闭有效,需要反转输入口逻辑,ECI系列控制器不用反转
    AXIS_STOPREASON = 0	'清除轴历史停止原因
    MOVE(1000)				'执行运动
    TargetReach(0,mode,1,0,0)				'轴0使用方式3判断到位,当运动结束且到位输入口IN1触发后执行后续程序
    if AXIS_STOPREASON(0)=0 then 			'判断轴0是否正常运动停止,输出异常停止错误码
        PRINT "运动到位"
    else
        ''''''''''''处理运动异常流程''''''''''''
        PRINT "轴运动异常停止,停止错误码:"+TOSTR(AXIS_STOPREASON(0),1,0)
    endif
elseif mode=4 then
    BASE(0)
    ATYPE = 0				'设置虚拟轴类型
    UNITS = 100'设置脉冲当量
    SPEED = 100				'设置运动速度
    ACCEL = 10000'设置运动加速度
    DECEL = 10000			'设置运动减速度
    AXIS_STOPREASON = 0'清除轴历史停止原因
    MOVE(1000)				'执行运动
    TargetReach(0,mode,0,0.1,0.1)			'轴0使用方式4判断到位,当运动结束,反馈速度阈值低于0.1且反馈位置与规划位置差值低于0.1时执行后续程序
    if AXIS_STOPREASON(0)=0 then 			'判断轴0是否正常运动停止,输出异常停止错误码
        PRINT "运动到位"
    else
        ''''''''''''处理运动异常流程''''''''''''
        PRINT "轴运动异常停止,停止错误码:"+TOSTR(AXIS_STOPREASON(0),1,0)
    endif
endif
END

C#编程使用说明:

(1)轴到位判断模式与参数设置函数。

/// /// 轴到位判断设置
/// /// 轴号/// 模式选择/// 到位输入信号/// 到位速度阈值,反馈速度小于阈值认为到位/// 到位距离阈值,规划位置与反馈位置差值小于阈值认为到位private void TargetReach(int iaxis, int imode, int InpIn, float ispeed, float idist)
{
    int Idle = -1;          //运动状态
    float Mspeed = 0;       //编码器反馈速度
    float Inpos = -1;       //到位标志状态
    switch (imode)
    {
        case 1:
            //方式一:仅适用于不带编码器的步进轴
            while (true)
            {
                zmcaux.ZAux_Direct_GetIfIdle(g_handle, testAxis, ref Idle);                 //获取轴0运动状态
                if (Idle != 0)  { break; }          //等待运动结束
                Thread.Sleep(50);
            }
            break;
        case 2:
            //方式二:通过自定义反馈速度阈值来判断是否到位。需要伺服带编码器,也是伺服轴到位的通用方式
            while (true)
            {
                zmcaux.ZAux_Direct_GetIfIdle(g_handle, testAxis, ref Idle);                 //获取轴0运动状态
                zmcaux.ZAux_Direct_GetMspeed(g_handle, testAxis, ref Mspeed);               //获取轴0反馈速度
                if ((Idle != 0) && (Math.Abs(Mspeed) < ispeed))  { break; }     //等待运动结束、反馈速度小于阈值条件达成
                Thread.Sleep(50);
            }
            break;
        case 3:
            //方式三:通过映射到位输入信号【AXISINP_IN】与到位标志指令【IN_POS】判断是否到位,需要伺服支持到位信号输出功能,用于脉冲轴,部分低系列控制器可能不支持
            zmcaux.ZAux_Direct_SetParam(g_handle, "AXISINP_IN", testAxis, InpIn);           //映射输入到位信号
            while (true)
            {
                zmcaux.ZAux_Direct_GetIfIdle(g_handle, testAxis, ref Idle);                 //获取轴0运动状态
                zmcaux.ZAux_Direct_GetParam(g_handle, "IN_POS", testAxis, ref Inpos);       //获取到位标志状态
                if ((Idle != 0) && (Inpos != 0)) { break; }             //等待运动结束、到位标志触发条件达成
                Thread.Sleep(50);
            }
            break;
        case 4:
            //方式四:通过设置到位参数【IN_POS_DIST】【IN_POS_SPEED】与到位标志指令【IN_POS】判断是否到位,需要伺服带编码器,部分低系列控制器可能不支持
            zmcaux.ZAux_Direct_SetParam(g_handle, "AXISINP_IN", testAxis, -1);                  //到位信号的优先级高于到位距离、到位速度参数,如果操作不当设置了需要取消映射
            zmcaux.ZAux_Direct_SetParam(g_handle, "IN_POS_SPEED", testAxis, ispeed);            //设置到位速度
            zmcaux.ZAux_Direct_SetParam(g_handle, "IN_POS_DIST", testAxis, idist);              //设置到位距离
            while (true)
            {
                zmcaux.ZAux_Direct_GetIfIdle(g_handle, testAxis, ref Idle);                 //获取轴0运动状态
                zmcaux.ZAux_Direct_GetParam(g_handle, "IN_POS", testAxis, ref Inpos);       //获取到位标志状态
                if ((Idle != 0) && (Inpos != 0)) { break; }             //等待运动结束、到位标志触发条件达成
                Thread.Sleep(50);
            }
            break;
        }
    }

(2)轴到位判断函数使用示例。

//C#开发轴到位判断使用示例:
private int caseTest()
{
    float Stopreason = 0;
    if (mode == 1)
    {
        //设置测试运动轴运动参数
        zmcaux.ZAux_Direct_SetAtype(g_handle, testAxis, 0);                 //设置虚拟轴类型
        zmcaux.ZAux_Direct_SetUnits(g_handle, testAxis, 100);               //设置脉冲当量
        zmcaux.ZAux_Direct_SetSpeed(g_handle, testAxis, 100);               //设置运动速度
        zmcaux.ZAux_Direct_SetAccel(g_handle, testAxis, 1000);              //设置运动加速度
        zmcaux.ZAux_Direct_SetDecel(g_handle, testAxis, 1000);              //设置运动减速度
        zmcaux.ZAux_Direct_SetParam(g_handle, "AXIS_STOPREASON", testAxis, 0);      //清除轴历史停止原因
        zmcaux.ZAux_Direct_Single_Move(g_handle, testAxis, 1000);        //执行运动
        TargetReach(testAxis, mode, 0, 0, 0);              //轴0使用方式1判断到位,当运动结束时执行后续程序
        zmcaux.ZAux_Direct_GetParam(g_handle, "AXIS_STOPREASON", testAxis, ref Stopreason);     //获取到位后的停止原因,0为正常停止
    }
    else if (mode == 2)
    {
        //设置测试运动轴运动参数
        zmcaux.ZAux_Direct_SetAtype(g_handle, testAxis, 0);                 //设置虚拟轴类型
        zmcaux.ZAux_Direct_SetUnits(g_handle, testAxis, 100);               //设置脉冲当量
        zmcaux.ZAux_Direct_SetSpeed(g_handle, testAxis, 100);               //设置运动速度
        zmcaux.ZAux_Direct_SetAccel(g_handle, testAxis, 1000);              //设置运动加速度
        zmcaux.ZAux_Direct_SetDecel(g_handle, testAxis, 1000);              //设置运动减速度
        zmcaux.ZAux_Direct_SetParam(g_handle, "AXIS_STOPREASON", testAxis, 0);      //清除轴历史停止原因
        zmcaux.ZAux_Direct_Single_Move(g_handle, testAxis, 1000);        //执行运动
        TargetReach(testAxis, mode, 0, 00.1f, 0);              //轴0使用方式2判断到位,当运动结束且反馈速度阈值低于0.1时执行后续程序
        zmcaux.ZAux_Direct_GetParam(g_handle, "AXIS_STOPREASON", testAxis, ref Stopreason);     //获取到位后的停止原因,0为正常停止
    }
    else if (mode == 3)
    {
        //设置测试运动轴运动参数
        zmcaux.ZAux_Direct_SetAtype(g_handle, testAxis, 0);                 //设置虚拟轴类型
        zmcaux.ZAux_Direct_SetUnits(g_handle, testAxis, 100);               //设置脉冲当量
        zmcaux.ZAux_Direct_SetSpeed(g_handle, testAxis, 100);               //设置运动速度
        zmcaux.ZAux_Direct_SetAccel(g_handle, testAxis, 1000);              //设置运动加速度
        zmcaux.ZAux_Direct_SetDecel(g_handle, testAxis, 1000);              //设置运动减速度
        zmcaux.ZAux_Direct_SetParam(g_handle, "AXIS_STOPREASON", testAxis, 0);      //清除轴历史停止原因
        zmcaux.ZAux_Direct_Single_Move(g_handle, testAxis, 1000);        //执行运动
        TargetReach(testAxis, mode, 1, 0, 0);              //轴0使用方式3判断到位,当运动结束且到位输入口IN1触发后执行后续程序
        zmcaux.ZAux_Direct_GetParam(g_handle, "AXIS_STOPREASON", testAxis, ref Stopreason);     //获取到位后的停止原因,0为正常停止
    }
    else if (mode == 4)
    {
        //设置测试运动轴运动参数
        zmcaux.ZAux_Direct_SetAtype(g_handle, testAxis, 0);                 //设置虚拟轴类型
        zmcaux.ZAux_Direct_SetUnits(g_handle, testAxis, 100);               //设置脉冲当量
        zmcaux.ZAux_Direct_SetSpeed(g_handle, testAxis, 100);               //设置运动速度
        zmcaux.ZAux_Direct_SetAccel(g_handle, testAxis, 1000);              //设置运动加速度
        zmcaux.ZAux_Direct_SetDecel(g_handle, testAxis, 1000);              //设置运动减速度
        zmcaux.ZAux_Direct_SetParam(g_handle, "AXIS_STOPREASON", testAxis, 0);      //清除轴历史停止原因
        zmcaux.ZAux_Direct_Single_Move(g_handle, testAxis, 1000);        //执行运动
        TargetReach(testAxis, mode, 0, 0.1f, 0.1f);              //轴0使用方式4判断到位,当运动结束,反馈速度阈值低于0.1且反馈位置与规划位置差值低于0.1时执行后续程序
        zmcaux.ZAux_Direct_GetParam(g_handle, "AXIS_STOPREASON", testAxis, ref Stopreason);     //获取到位后的停止原因,0为正常停止
    }
    //判断轴0是否正常运动停止,输出异常停止错误码
    if (Stopreason != 0)       
    {
        //轴运动异常停止,异常停止报错码:Stopreason
        return Convert.ToInt32(Stopreason);
    }
    else return 0;
}

完整代码获取地址

例程二维码.webp

本次,正运动技术全闭环EtherCAT运动控制器运动到位判断方式详解,就分享到这里。

更多精彩内容请关注“正运动小助手”公众号,需要相关开发环境与例程代码,请咨询正运动技术销售工程师:400-089-8936。

二维码.webp

正运动技术专注于运动控制技术研究和通用运动控制软硬件产品的研发,是国家级高新技术企业。正运动技术汇集了来自华为、中兴等公司的优秀人才,在坚持自主创新的同时,积极联合各大高校协同运动控制基础技术的研究。主要业务有:运动控制卡_运动控制器_EtherCAT运动控制卡_EtherCAT控制器_运动控制系统_视觉控制器__运动控制PLC_运动控制_机器人控制器_视觉定位_XPCIe/XPCI系列运动控制卡等等。

版权所有 工控网 Copyright©2026 Gkong.com, All Rights Reserved