刚开始用CODESYS做CANopen总线伺服控制的时候,很多人都会被那一堆节点、对象字典、PDO映射搞得晕头转向。明明单个伺服用脉冲方式跑得好好的,一换成总线控制就各种报错、节点掉线、轴使能不了。我最早从汇川PLC转过来接触CODESYS时,也在这个地方卡了不少时间。后来把CANopen协议里几个关键概念和CODESYS的配置逻辑对照起来看,才慢慢捋清楚——其实CODESYS里的CANopen配置并没有想象中复杂,关键是要理解它背后的工作方式。
这篇文章我就以一套典型的“控制器+CANopen总线+伺服电机”项目为例,把整个一体化配置过程拆开揉碎了讲。从协议原理、工程配置、伺服参数设置,到轴调试和常见故障排查,全部覆盖。无论你是刚从传统脉冲控制转过来的电气工程师,还是正在做设备集成的调试人员,这篇文章都能帮你少走弯路,直接把坑填平。
1. 先把CANopen协议的核心概念捋清楚
在打开CODESYS配置界面之前,我强烈建议先花点时间理解CANopen的底层逻辑。因为你在CODESYS里做的每一个配置项,几乎都是在跟CANopen的对象字典、PDO、SDO这些东西打交道。如果不懂原理,配置界面上那一堆选项就只能是死记硬背,换一个伺服品牌就抓瞎。
1.1 对象字典:一切数据的核心中转站
CANopen协议的核心是对象字典,你可以把它想成伺服驱动器内部的一张“数据大表”。表中的每一行都有一个16位的索引号,有的还带子索引,存储着驱动器的所有运行参数。比如“控制字”通常排在0x6040,“状态字”是0x6041,“目标速度”是0x60FF,“模式选择”是0x6060。
我见过很多工程师在配置时,直接在伺服厂商的调试软件里把参数设置好,然后接到CODESYS上发现设备报错,归根结底就是没搞懂对象字典的映射关系。CODESYS通过CANopen总线去读写这些索引号,你必须确保伺服驱动器里的对象字典内容跟你在CODESYS里配置的一致,否则通信能建立但控制逻辑完全是乱的。
实际项目中,你可能需要修改某个对象字典的值,比如改变加减速时间。常见的做法有两种:一是用SDO直接写入,二是通过PDO周期下发。SDO适合不定期修改的参数,而PDO适合每个周期都要刷新的数据,比如速度指令。
1.2 NMT与节点状态机:通信的“总开关”
CANopen总线上每个节点都遵循一个统一的状态机,包括初始化、预操作、操作、停止等几个状态。NMT就是负责切换这些状态的核心报文,由主站(也就是你的CODESYS控制器)发出,控制所有从站的启停。
这里要特别注意:设备上电后默认进入的是预操作状态,在这个状态下只能进行SDO通信,不能进行PDO实时数据交换。必须由主站发送“进入操作状态”的NMT命令,从站才会开始接收PDO指令,伺服才能真正动起来。
很多刚上手的朋友在调试时遇到“总线连上了但轴就是不动”的情况,十有八九就是没看节点状态——要么还在预操作阶段,要么节点被NMT停止了。CODESYS里可以通过总线诊断窗口查看每个节点的当前状态,调试时养成定时查看的习惯,能省下大量无谓的排查时间。
1.3 PDO与SDO:两种完全不同的数据通道
SDO是一问一答的邮箱式通信,可靠但速度慢,适合传输配置参数和偶发数据。PDO则是广播式的实时数据通道,主站和从站之间可以直接映射参数,一旦建立连接就周期性地自动交换,速度快、实时性有保障,适合传输运动控制指令和状态反馈。
举个例子:你想把目标位置、目标速度、控制字这些数据在每个周期都发给伺服,就走PDO。而你只是在开机时下发一次“电子齿轮比”之类的配置参数,走SDO就够了。CODESYS的工程配置里,PDO的映射表你需要手动建立,把对象字典中的参数地址一一拖到发送或接收通道里。
一个常见的坑是PDO映射的长度和参数顺序,两边必须完全一致。比如你把控制字放在第一个字,目标速度放在第二个字,那伺服端的配置也必须按这个顺序排,错一个字节数据就全乱了。
2. 项目开始前的硬件选型与连接规划
聊完协议基础,再来讲讲实操环节中硬件层面的准备工作。很多人一上来就开软件,结果设备接不上、通讯不上,最后发现是硬件接线或者通信参数不一致的问题。
2.1 控制器与伺服驱动器的硬件连接
首先确定你的CODESYS控制器上是否有CANopen接口。常见的配置方案有三种:控制器自带CANopen接口(比如一些CODESYS软PLC或者嵌入式控制器)、通过扩展模块添加CANopen通讯卡、以及使用以太网转CANopen的网关设备。具体用哪种取决于你的硬件平台,但在CODESYS工程里配置方式大同小异。
接线方面,CANopen总线通常是CAN_H、CAN_L两线制,接线时需要特别注意终端电阻。CANopen规范要求总线的两端都接120欧姆终端电阻,否则信号反射会导致通讯不稳定,表现为偶发性通讯中断、节点掉线。早期我调试时总线上挂三个设备,只在最末端接了一个电阻,结果总是频繁掉站,后来两端都加上电阻就稳定了。另外通讯线建议使用屏蔽双绞线,屏蔽层单端接地。
波特率也是必须统一的关键参数,常见的CANopen波特率有125K、250K、500K、1M等。主站和所有从站必须设置成完全一样的波特率。有些伺服驱动器上有拨码开关直接设定波特率、站号和终端电阻,比如汇川的SV660N系列就用拨码配置,调试前先确认这些硬件设置,能省去后期大量排查时间。
2.2 伺服电机与控制器的匹配关系
在配置之前,还需要确认伺服电机和驱动器的参数匹配。额定电流、额定转速、编码器分辨率这些参数都会影响到后续的轴配置和速度单位转换。比如在CODESYS的CNC或者运动控制库中,轴的位置单位默认是用户自定义单位,你需要根据编码器分辨率来换算实际位移值与用户单位的比例。
一个很容易踩坑的地方是电子齿轮比和单位换算。伺服驱动器内部有电子齿轮比设置,而CODESYS那边也会定义用户单位,两者叠加容易造成实际移动距离和指令距离不一致。我的建议是优先用驱动器本身的电子齿轮比做精确转换,然后在CODESYS内部再做一次简单的比例换算,两边分清楚,避免在调试中混淆。
物理接线完成后,下一步就是用伺服厂商的调试软件(比如汇川的InoDriverShop、信捷的伺服调试助手)先把驱动器单独调试顺畅。确认电机能正常旋转,编码器反馈正常,限位开关逻辑正确后,再接入CODESYS总线。这一步很多人会跳过,直接在总线上调,结果一出现问题,到底是总线问题还是伺服问题都分不清。
3. CODESYS工程里CANopen从站的添加与配置过程
硬件就绪之后,进入核心环节——在CODESYS里完成整个CANopen配置流程。我以一个实际项目来演示:用汇川SV660N伺服驱动器带动一台转台设备,实现精确的位置控制。
3.1 新建工程并添加CANopen管理器
打开CODESYS,先新建一个标准项目,选择你使用的控制器型号。在左侧设备树中,右键点击“设备”,选择“添加设备”,在设备列表中找到CANopen主站相关的设备描述文件。不同控制器对应的CANopen管理器名称可能略有不同,比如有的叫“CANopen_Manager”,有的叫“CANopen Master”。
添加完成后,你会在设备树中看到CANopen管理器的条目。双击打开,配置界面上主要有通讯参数设置、启动行为设置、节点管理等几块内容。通讯参数主要是波特率匹配,启动行为中可以设置“自动启动CANopen”,这样PLC上电运行后会自动完成NMT状态切换,把总线上所有从站快速带入操作状态。
这里建议把“自动启动CANopen”开启,同时激活“检查所有节点”选项,这样系统在启动时会逐一遍历所有配置好的从站,发现异常节点会直接报错,而不是带病运行。上电后总线状态一目了然,减少调试中反复试错的成本。
3.2 导入伺服驱动的EDS文件
每一个符合CANopen协议的伺服驱动器,厂商都会提供一个EDS文件,全称是Electronic Data Sheet,电子数据表。这个文件是驱动器的“身份证”,里面完整描述了驱动器的对象字典结构、支持的PDO映射、通讯参数等所有信息。
在CODESYS的CANopen管理器节点上右键,“添加设备”,浏览找到伺服驱动器的EDS文件并导入。比如汇川SV660N的EDS文件在伺服调试软件的安装目录下就能找到,信捷、台达、松下等品牌也都类似。导入成功后,设备树中会出现对应的从站节点。
这里有个细节要留意:不同固件版本的驱动器,EDS文件可能会有差异。导入的EDS文件版本最好跟实际设备固件版本严格对应,否则可能出现某些对象字典参数无法通讯,或者PDO映射错误等怪异现象。如果出现异常,优先考虑去官网下载对应固件版本的新版EDS文件重新导入。
3.3 设置从站节点ID并建立PDO映射
导入EDS后,双击从站节点,首先要设置的是节点ID,也就是从站的站号,必须与驱动器拨码设置的一致。CANopen标准规定有效站号范围是1到127,站号0是广播地址,不允许分配给单独设备。
接下来是PDO映射设置,这是整个配置中最关键也最容易出问题的地方。CODESYS中从站配置界面通常分为发送PDO(TxPDO)和接收PDO(RxPDO)两组。RxPDO是主站发给从站的数据,比如控制字、目标速度、目标位置;TxPDO是从站发给主站的数据,比如状态字、实际位置、实际速度。
以汇川SV660N为例,常用的一组映射是:
- RxPDO1(主站到从站):控制字0x6040(16位)、目标速度0x60FF(32位)、目标位置0x607A(32位)
- TxPDO1(从站到主站):状态字0x6041(16位)、实际速度0x606C(32位)、实际位置0x6064(32位)
在CODESYS的EDS导入后,这些对象字典通常已经自动映射好了,但你需要检查一下映射项的顺序和数据长度是否与实际设备要求的格式一致。一旦建立映射后,数据会按固定的字节偏移量自动收发,不需要额外编程,就能在每个扫描周期内刷新这些数据。
4. 伺服电机的关键参数设置与控制模式选择
CODESYS侧的配置工作做完,还要确保伺服驱动器内部的参数设置与之匹配。这里涉及一些重要的功能码和参数项,你需要根据实际的运动控制模式来设定。
4.1 控制模式的选择:位置、速度还是扭矩
在CANopen协议下,伺服驱动器的控制模式由对象字典0x6060定义,常用值包括:数值1表示位置模式,数值3表示速度模式,数值4表示扭矩模式。
我早期做转台定位项目时,用的是位置模式。位置模式的特点是控制器发送目标位置和速度,伺服驱动器内部完成位置环和速度环的闭环控制,控制精度高,调试相对简单。而如果做追剪、飞锯这类需要实时调节速度的设备,可能就需要速度模式,此时关键是关注速度指令的响应实时性。
CODESYS里使用运动控制库时(比如PLCopen的MC_MoveAbsolute、MC_MoveVelocity指令),你在编程前就必须明确轴的工作模式与驱动器实际模式一致。比如程序里用了MC_MoveAbsolute,驱动器就必须工作在位置模式,否则定位逻辑会错乱。在轴配置中还可以通过MC_Power指令使能时,指定驱动器的模式参数,但这个也可以手动统一设置。
4.2 伺服驱动器功能码设置与对象字典的关系
在伺服调试软件上,你将驱动器的控制模式设定为CANopen通讯控制,还要把速度指令来源、位置指令来源这些参数切换为“网络给定”,屏蔽掉驱动器面板和端子给定。这一操作实际上就是在修改驱动器的对象字典数值,只是通过厂商的调试软件间接修改。无论是用伺服调试软件,还是用CODESYS直接通过SDO读写,最终目的都是让驱动器的内部状态与总线Master的期望一致。
关于电子齿轮比,我的建议是:如果伺服驱动器的分辨率较高(比如23位编码器,分辨率8388608),尽量在驱动器内将电子齿轮比设为1:1,即直接按编码器单位下达位置指令。然后在CODESYS侧通过MC_Home方式定义用户单位与编码器单位的换算系数。这样可以避免电子齿轮比多次折算造成的误差和调试困惑。
实际操作中,这些参数改完后,一定不要忘记在伺服调试软件里执行“参数保存”,否则断电后驱动器会恢复默认值。CANopen参数设置中,某些关键参数还需要通过SDO写入EEPROM区域才能永久保存,仅修改RAM区的数据在重启后会全部丢失。
5. 轴配置与PLCopen运动控制的程序实现
通讯参数、伺服驱动器参数都已经就绪,最后一步就是在CODESYS编程环境中建立运动控制轴,并编写控制程序。这里使用CODESYS标准的PLCopen库,工业界用得非常普遍,主流PLC品牌都有适配支持。
5.1 建立运动控制轴并与CANopen从站关联
在CODESYS的左侧设备树中,展开PLC或应用节点,右键添加“CNC轴”或“SoftMotion轴”,具体名称与安装的运动控制库有关。添加后,双击轴配置,在“驱动”或“通讯”选项卡中,选择刚才配置好的CANopen从站节点作为该轴的驱动来源。这个关联行为就是把软件轴与物理设备绑定在一起,是后续指令控制的基础。
在第2节提到的单位换算也在轴的配置界面中定义。如果你直接在驱动器端按1:1编码器单位工作,这里可以设置轴的基本单位和位置比例系数。比如编码器分辨率8388608对应转台一圈360度,那比例系数设为360/8388608,程序中的位置单位就直接是度数了。这样在编写运动程序时会非常直观,不需要再为单位问题费心思。
这里要特别强调,轴的使能逻辑一定要处理好。PLCopen要求执行运动指令之前必须先调用MC_Power,将Axis Enable置为TRUE。同时在轴配置界面中可以设置最大跟随误差,一旦实际位置和目标位置偏差超过这个值,系统会自动报错停止,这对保护设备非常有用。
5.2 编写完整的伺服控制程序
下面是我在转台定位项目中的一段核心控制程序,供大家参考。首先在全局变量区声明:
PROGRAM MAIN VAR Axis1 : AXIS_REF; Power : MC_Power; Home : MC_Home; MoveAbs : MC_MoveAbsolute; MoveVel : MC_MoveVelocity; StopAxis : MC_Stop; StatusWord : WORD; bPowerOn : BOOL := TRUE; bExecuteMove : BOOL; bHomeExecute : BOOL; rTargetPos : LREAL := 90.0; rVelocity : LREAL := 20.0; END_VAR然后在程序体中依次调用功能块:
// 使能轴 Power.Axis := Axis1; Power.Enable := bPowerOn; Power.bRegulatorOn := TRUE; Power.bDriveStart := TRUE; Power(); // 执行回零 Home.Axis := Axis1; Home.Execute := bHomeExecute; Home.Position := 0; Home(); // 绝对定位 MoveAbs.Axis := Axis1; MoveAbs.Execute := bExecuteMove; MoveAbs.Position := rTargetPos; MoveAbs.Velocity := rVelocity; MoveAbs.Acceleration := 100.0; MoveAbs.Deceleration := 100.0; MoveAbs(); // 停止 StopAxis.Axis := Axis1; StopAxis.Execute := bStopAxis; StopAxis.Deceleration := 200.0; StopAxis();从上面的程序中可以看到,PLCopen指令封装了绝大部分底层的复杂逻辑。例如MC_MoveAbsolute内部会通过PDO自动下发目标位置和速度,同时实时监测伺服状态字,若伺服报错会立刻反应到Busy和Error引脚上。你不需要自己拼帧、发送CANopen报文,但前提是你在第3节中的PDO映射配置正确。
调试时我习惯先做一个最简单的点动程序,只调用MC_MoveVelocity,让轴以恒定速度转动,观察方向是否正确、实际速度跟设定值是否一致。方向如果反了,决不在程序里加负号掩盖,而是去驱动器参数中调整电机方向,或者更换U、V、W相序,这样才能从根本上解决问题。
6. 一体化联调时的参数整定与常见问题排查
所有配置和程序都完成之后,就进入了最考验耐心的联调阶段。这里我把实际项目中踩过的一些坑和排查思路整理出来,供大家对照参考。
6.1 伺服系统整定的基本原则
在位置控制模式下,如果你发现电机运行时噪音大、跟随误差偏大、定位时有明显过冲,这时候需要做伺服增益整定。现在主流伺服驱动器都支持自动整定,比如汇川在面板上按一下就能做自动惯量识别和增益调整,然后用InoDriverShop软件也能手动细调。
自动整定省时省力,但自动整定并不等于最优。在高负载、高惯量比的场合,自动整定往往偏保守,响应速度不够快。这时候就需要手动调参:先调速度环的增益和积分时间,让速度响应快而不振荡,然后再调位置环增益。每调完一个参数都实际运行验证,主轴转动听声音是否顺畅,观察跟随误差曲线是否平稳。
我常用的经验是:位置环增益Kp从低速开始逐步增加,直到出现定位振荡,然后回调到振荡值的70%左右;速度环增益和积分时间配合调整,让系统阶跃响应没有明显超调。完成之后再反复执行几次快速定位,观察实际的定位重复精度。整个过程没有捷径,耐心调出来的设备后期才稳定。
6.2 问题排查实录:从总线到伺服再到程序的逐级定位
以下是我实际项目中遇到的几个典型问题,都很有代表性。
第一个是总线通讯异常,现象是设备运行一段时间后PLC报警“从站节点丢失”,但重新上电后又恢复正常。排查过程是这样的:先检查CANopen总线诊断界面,发现报错的节点号确实是伺服从站;然后检查现场布线,发现通讯线跟电机动力线走同一个线槽,而且距离很远,干扰严重。把通讯线单独走线、加磁环、把两个终端电阻规范配置后,问题彻底解决。这个案例提醒我,总线类通讯故障首先要怀疑物理层,而不是一开始就改软件参数。
第二个是PDO数据无效的问题。现象是程序里下发目标位置之后,伺服完全不动,而且无任何报警。检查配置后发现,RxPDO中目标位置的映射索引写错了,映射到了0x6079而不是0x607A。这个纯粹是导入EDS后手动修改映射时看走眼造成的。把映射重新修正、下载工程并复位通讯后,伺服立刻有响应。
第三个是轴使能后立即报错。这通常与驱动器模式设置、伺服使能信号来源有关。如果你在伺服调试软件里把“伺服使能”设置为“端子使能”,那么即使CODESYS通过总线发送了使能指令,驱动器也不会真正通电励磁。解决方法是把使能信号来源也切换为“通讯控制”,或者直接将驱动器的使能端子短接到24V正极。
第四个问题比较隐蔽:回零速度正常,但回零完成后定位偏差很大。排查发现是原点开关接到伺服驱动器的手动脉冲输入端口上,而不是接入控制器或驱动器的CIA402标准原点输入。这样回零完成的瞬间虽然有信号,但实际原点位置跟程序设定的坐标系存在偏差。后来把原点开关重新接到标准输入口,并设置了合适的回零高速、低速和回零方向,问题解决。回零逻辑看似简单,真正做好的企业真不多,这块值得下功夫。
6.3 联调经验总结
联调这个阶段,我个人的习惯是保持“单一变量”的测试原则。一次只改一个参数或一个环节,改完就验证,验证通过再改下一个。很多朋友出了故障后急着同时改软件程序、改伺服参数、改接线,结果最后问题解决了,但根本不知道是哪个动作起的作用,后期维护和同类项目的复制完全没有参考价值。
调试中也可以多用CODESYS自带的Trace工具,把轴的速度、位置、电流、跟随误差这些变量实时记录下来,形成趋势曲线。比如通过观察跟随误差曲线,很快就能判断出是增益不足还是机械间隙问题。这种可视化手段远比盯着PLC程序空想高效得多。
7. 这个方案还能怎么拓展
一套标准的CANopen总线伺服控制系统搭建完成之后,后续的运维和扩展其实比你想象的更灵活。
最直接的扩展是增加从站数量。一条CANopen总线上可以挂多个伺服驱动器,增加从站时只需要在CODESYS里导入对应的EDS文件、分配站号、建立PDO映射即可,不需要修改现有轴的程序结构。对于多轴联动的设备,这种组网方式比脉冲控制省掉了大量的接线和控制端子,系统整洁度和可靠性都更高。
其次可以结合CODESYS的软motion功能,实现CNC插补或者电子凸轮控制。当你拥有多台CANopen伺服时,利用SoftMotion的手轮模式和CNC功能,可以方便地实现多轴同步和轨迹插补,这在传统PLC中往往是遥不可及的。CODESYS本身就是个开放平台,接入CANopen伺服后整套运动控制架构的价值会迅速放大。
最后想提醒一点:很多朋友问我到底哪种总线控制方式更好,EtherCAT和CANopen选哪个。我的经验是——如果设备定位中低端、成本敏感、控制周期要求100ms级别,CANopen已经足够稳定靠谱。如果追切精度很高、多轴同步要求极高、控制周期要1ms以内,那直接上EtherCAT更合理。不要盲目追求技术参数,能可靠满足你设备需求的方案,就是好方案。