
如果你正在开发工业自动化设备特别是物料分拣、包装或传送系统那么“如何让多个电机协同工作”这个问题一定困扰过你。传统的脉冲方向控制一个电机就需要一个控制器线缆复杂同步精度差距离稍远信号就衰减。而当你听说CANopen总线可以“一根线”控制多个设备时又会立刻被其复杂的协议栈、抽象的“对象字典”和繁琐的配置劝退。“沈阳广成CANopen步进”这个组合恰恰瞄准了这个痛点。它不是一个新协议而是一个将成熟的CANopen总线协议与步进电机驱动深度集成的成熟工业解决方案。本文要解决的不是泛泛地介绍CANopen而是回答一个具体问题一个自动化工程师或嵌入式开发者如何利用像沈阳广成这样的成熟CANopen步进驱动器快速、可靠地搭建一套分布式运动控制系统并完成像“自动化分拣”这样的典型任务我的核心判断是对于中小型自动化项目采用集成CANopen协议的步进驱动器如沈阳广成GCAN系列其价值不在于协议本身有多先进而在于它极大地降低了分布式运动控制的工程化门槛和后期维护成本。你无需从零实现CANopen协议栈只需关注上层的应用逻辑——如何定义分拣动作、如何协调多个轴——底层的通信、同步、错误处理都由驱动器固件完成了。接下来我将以“自动化分拣”为场景带你从原理到实操完整走通基于CANopen步进驱动器的开发流程。你会看到如何配置一个驱动器、如何通过SDO快速修改参数、如何利用PDO实现实时控制、以及如何编写一个简单的分拣控制程序。无论你用的是STM32还是其他主控这套思路都是通用的。1. 为什么CANopen步进是自动化分拣的优选方案在探讨具体技术前我们先厘清需求。一个典型的自动化分拣系统核心动作是传感器检测到物料到位 → 控制器计算物料属性和目标位置 → 控制多个电机执行抓取、移动、放置等动作。这对控制系统提出了几个关键要求多轴协调需要多个电机步进或伺服同时或顺序动作动作之间可能有严格的时序关系。实时性从传感器信号到电机响应的延迟必须足够小以保证分拣节拍。可靠性工业现场环境复杂通信需要抗干扰系统需要便于诊断和恢复。布线简洁设备可能分布在不同位置减少线缆能降低成本和故障率。传统的“脉冲方向”控制方式每个电机需要独立的控制信号线至少2根和电源线。当轴数增多时控制柜接线会变得异常复杂且长距离传输脉冲信号容易受到干扰。而基于RS-485的Modbus等方式实时性又往往达不到高速分拣的要求。CANopen总线方案的优势正在于此一根总线多个设备所有CANopen节点驱动器、IO模块、传感器等都挂载在一条双绞线上极大简化布线。硬实时通信CAN总线本身具备优先级仲裁机制高优先级的报文如急停能立即获得总线使用权保证关键指令的实时性。标准化与互操作性CANopen定义了标准的设备模型如CiA 402驱动与运动控制设备行规、通信对象SDO PDO和状态机。这意味着你为沈阳广成驱动器写的控制程序稍作调整也能用于其他符合CiA 402标准的CANopen伺服驱动器提升了系统的可扩展性和供应商选择性。强大的网络管理可以一键命令所有节点进入预操作、操作或停止状态便于系统整体控制与诊断。对于“沈阳广成CANopen步进”这类产品它把CANopen从协议变成了“即插即用”的硬件功能。你购买的不只是一个步进驱动器更是一个已经实现了标准CANopen协议栈和CiA 402运动控制行规的智能节点。你的开发重点从“如何让电机转起来”变成了“如何让电机按我的业务流程精准地转起来”。2. CANopen核心概念快速理解对象字典、SDO与PDO要操作CANopen设备必须理解三个核心概念对象字典、SDO和PDO。这是与设备对话的“语言规则”。2.1 对象字典设备的“参数说明书”你可以把每个CANopen设备如步进驱动器想象成一个拥有大量内部参数的盒子。这些参数包括电机电流、细分设置、加速度、目标位置、实际位置、错误代码等等。对象字典就是一个为所有这些参数编制的标准化索引目录。每个参数被称为一个“对象”它有一个16位的索引Index和一个8位的子索引Subindex。例如控制字Controlword的索引通常是0x6040目标位置Target Position是0x607A。通过索引和子索引我们可以唯一地读写任何一个参数。沈阳广成的CANopen步进驱动器其对象字典是预先定义好的并遵循CiA 402标准。你不需要创建它只需要学会查询和修改它。2.2 SDO参数配置的“专用通道”SDOService Data Object 服务数据对象用于非实时、点对点的参数配置。比如你需要在设备启动前设置电机的最大转速0x6080或回零模式0x6098。这个过程不要求极高的速度但要求准确可靠。SDO通信像是一次“问答”。主站你的控制器发送一个包含索引、子索引和数据的请求报文从站驱动器回复一个确认报文。它适合初始化配置和偶尔的参数修改。2.3 PDO实时控制的“高速广播”PDOProcess Data Object 过程数据对象用于实时、周期性的数据交换。这是运动控制的核心。例如主站需要每1ms就发送一次目标位置和控制字同时接收驱动器的实际位置和状态字。PDO的特点是“生产/消费”模型。一个设备“生产”某个数据如状态字并把它映射到一个PDO上然后周期性地发送出去其他需要这个数据的设备“消费”它。PDO的传输是广播式的没有确认速度极快。在分拣控制中控制字Controlword和目标位置Target Position通常通过PDO发送给驱动器状态字Statusword和实际位置Actual Position通过PDO从驱动器接收。这是实现实时位置控制的关键。3. 硬件准备与网络搭建假设我们要构建一个简单的两轴分拣系统X轴负责水平移动Y轴负责抓取升降。我们需要以下硬件主控制器1个可以是带CAN接口的STM32开发板如STM32F103/F407/F429系列、树莓派 CAN扩展板或任何支持CAN的工控机/PLC。本文以STM32F407为例。CANopen步进驱动器2个这里以沈阳广成GCAN系列CANopen步进驱动器为例。步进电机2个42或57步进电机与驱动器匹配。CAN总线网络CAN电缆屏蔽双绞线推荐。终端电阻在总线物理两端第一个和最后一个节点处的CAN_H和CAN_L之间各接一个120Ω的终端电阻用于阻抗匹配消除信号反射。电源为控制器、驱动器和电机提供合适的直流电源。网络连接示意图[STM32主站] ---CAN总线--- [驱动器1 (节点ID1)] ---CAN总线--- [驱动器2 (节点ID2)] | | | 终端电阻 电机X轴 电机Y轴关键设置步骤设置节点ID每个CANopen设备必须有唯一的节点ID1-127。通常通过驱动器上的拨码开关或软件设置。我们将X轴驱动器设为节点1Y轴设为节点2。配置波特率所有节点主站和从站的CAN通信波特率必须一致。常用速率有125Kbps 250Kbps 500Kbps 1Mbps。工业现场常用500Kbps在通信速度和抗干扰性之间取得平衡。需要在主站程序和驱动器中分别设置。连接与上电确保接线正确CAN_H接CAN_H CAN_L接CAN_L终端电阻已加然后上电。4. 驱动器基础配置通过SDO上电后驱动器通常处于“预操作状态”。我们需要通过SDO对其进行初始化配置。这些配置通常在系统启动时执行一次。以下是一个通过CAN总线发送SDO报文来配置驱动器的示例流程。我们使用一个简化的函数sdo_write来示意。// 假设CAN发送函数将数据打包成CAN帧发送 // can_send(uint32_t id, uint8_t* data, uint8_t len); // COB-ID规则客户端发送SDO的COB-ID 0x600 节点ID // SDO写参数函数加速段下载标准方式 // index: 对象字典索引如0x6080 // subindex: 子索引通常为0x00 // value: 要写入的32位值 // node_id: 从站节点ID void sdo_write_parameter(uint16_t index, uint8_t subindex, int32_t value, uint8_t node_id) { uint8_t data[8]; uint32_t cob_id 0x600 node_id; // 客户端发送SDO的COB-ID // 构建SDO“加速段下载”请求报文 data[0] 0x23; // 命令字0x2表示写0x3表示数据为32位 data[1] (uint8_t)(index 0xFF); // 索引低字节 data[2] (uint8_t)(index 8); // 索引高字节 data[3] subindex; // 子索引 // 数据小端格式 data[4] (uint8_t)(value 0xFF); data[5] (uint8_t)((value 8) 0xFF); data[6] (uint8_t)((value 16) 0xFF); data[7] (uint8_t)((value 24) 0xFF); can_send(cob_id, data, 8); // 在实际应用中需要等待并处理从站的回复报文COB-ID 0x580node_id }关键配置示例在系统初始化时调用以下配置函数void drive_init_config(uint8_t node_id) { // 1. 设置工作模式轮廓位置模式CiA 402模式PP // 对象字典索引 0x6060 子索引 0x00 值 1 代表轮廓位置模式 sdo_write_parameter(0x6060, 0x00, 1, node_id); delay_ms(10); // 2. 设置轮廓速度Profile Velocity // 对象字典索引 0x6081 单位取决于驱动器设置可能是脉冲/秒或转/分 // 假设设置为1000转/分具体值需参考驱动器手册换算 sdo_write_parameter(0x6081, 0x00, 1000, node_id); delay_ms(10); // 3. 设置轮廓加速度Profile Acceleration // 对象字典索引 0x6083 sdo_write_parameter(0x6083, 0x00, 5000, node_id); // 示例值 delay_ms(10); // 4. 设置轮廓减速度Profile Deceleration // 对象字典索引 0x6084 sdo_write_parameter(0x6084, 0x00, 5000, node_id); // 示例值 delay_ms(10); // 5. 使能驱动器通过控制字但通常先发送“启动”命令到状态机 // 首先发送“Shutdown”命令 (控制字 0x6040 0x06) // 然后发送“Switch On”命令 (0x07) // 最后发送“Enable Operation”命令 (0x0F) // 更常见的做法是通过PDO发送控制字见下一章节。 }注意这些SDO写操作需要根据驱动器的具体对象字典定义来调整。务必查阅沈阳广成对应型号驱动器的CANopen通信手册确认每个对象索引的含义、数据类型和单位。5. PDO映射与实时控制程序实现配置完成后驱动器进入“操作状态”。此时实时控制应通过PDO进行。我们需要配置PDO的映射关系并编写周期性的控制程序。5.1 PDO通信参数配置PDO的通信参数如COB-ID、传输类型、禁止时间等和映射参数哪些对象字典项被映射到PDO数据中本身也是对象字典中的参数可以通过SDO配置。一个常见的简化方法是使用驱动器的出厂默认PDO映射。许多驱动器包括沈阳广成的某些型号出厂时已经将最常用的对象如控制字、目标位置、状态字、实际位置映射到了TPDO1和RPDO1上。你需要确认这一点。如果默认映射不符合要求你需要手动配置。例如将“控制字(0x6040)”和“目标位置(0x607A)”映射到发送给驱动器的RPDO1// 配置RPDO1的COB-ID (对象字典 0x1400子索引 0x01) // COB-ID 0x200 节点ID 这是RPDO1的标准标识符 sdo_write_parameter(0x1400, 0x01, 0x80000200 node_id, node_id); delay_ms(10); // 配置RPDO1的传输类型 (对象字典 0x1400子索引 0x02) // 传输类型 0xFF: 事件驱动异步传输 // 传输类型 0xFE: 由设备子协议定义 // 传输类型 1-240: 同步周期数每收到N个SYNC报文发送一次 // 这里设为0xFF异步由主站触发 sdo_write_parameter(0x1400, 0x02, 0xFF, node_id); delay_ms(10); // 配置RPDO1的映射参数先禁止映射 (对象字典 0x1600子索引 0x00 0) sdo_write_parameter(0x1600, 0x00, 0, node_id); delay_ms(10); // 映射第一个对象控制字 (0x6040 子索引0 长度16位0x10) sdo_write_parameter(0x1600, 0x01, 0x60400010, node_id); delay_ms(10); // 映射第二个对象目标位置 (0x607A 子索引0 长度32位0x20) sdo_write_parameter(0x1600, 0x02, 0x607A0020, node_id); delay_ms(10); // 设置映射条目数量为2 (对象字典 0x1600子索引 0x00 2) sdo_write_parameter(0x1600, 0x00, 2, node_id); delay_ms(10);配置完成后需要让驱动器重新应用PDO映射通常通过重启通信或发送特定SDO命令实现。5.2 编写实时控制逻辑假设PDO已正确映射。我们的主控制程序需要周期性地例如每1ms执行以下任务读取传感器如光电开关状态。根据分拣逻辑计算X轴和Y轴的下一个目标位置。通过RPDO将控制字和目标位置发送给对应的驱动器。通过TPDO接收驱动器的状态字和实际位置进行监控和错误处理。下面是一个简化的主程序控制循环框架#include “can.h” // 你的CAN驱动 #include “timer.h” // 用于定时 // 定义驱动器节点ID #define NODE_ID_X_AXIS 1 #define NODE_ID_Y_AXIS 2 // 定义PDO的COB-ID (根据配置或标准) #define RPDO1_X_AXIS (0x200 NODE_ID_X_AXIS) // 发送给X轴的控制数据 #define RPDO1_Y_AXIS (0x200 NODE_ID_Y_AXIS) // 发送给Y轴的控制数据 #define TPDO1_X_AXIS (0x180 NODE_ID_X_AXIS) // 接收来自X轴的状态数据 #define TPDO1_Y_AXIS (0x180 NODE_ID_Y_AXIS) // 接收来自Y轴的状态数据 // 控制字命令宏CiA 402状态机 #define CMD_SHUTDOWN 0x06 #define CMD_SWITCH_ON 0x07 #define CMD_ENABLE_OP 0x0F #define CMD_ABS_POS_START 0x001F // 绝对定位启动控制字0x1F // 全局变量存储各轴的目标位置和控制状态 typedef struct { int32_t target_position; uint16_t controlword; int32_t actual_position; // 从TPDO更新 uint16_t statusword; // 从TPDO更新 uint8_t is_homed; uint8_t is_enabled; } Axis_t; Axis_t axis_x axis_y; // 初始化轴状态 void axis_init() { axis_x.target_position 0; axis_x.controlword CMD_SHUTDOWN; axis_x.is_homed 0; axis_x.is_enabled 0; // 同理初始化 axis_y } // 通过RPDO1发送控制数据给指定轴 void send_rpdo1_to_axis(Axis_t* axis uint32_t cob_id) { uint8_t data[8]; // 数据按映射顺序排列控制字(16bit) 目标位置(32bit) data[0] (uint8_t)(axis-controlword 0xFF); data[1] (uint8_t)((axis-controlword 8) 0xFF); data[2] (uint8_t)(axis-target_position 0xFF); data[3] (uint8_t)((axis-target_position 8) 0xFF); data[4] (uint8_t)((axis-target_position 16) 0xFF); data[5] (uint8_t)((axis-target_position 24) 0xFF); data[6] 0; // 填充字节如果PDO映射了更多数据 data[7] 0; can_send(cob_id data 8); // 发送8字节CAN帧 } // CAN接收中断服务程序示例 // 这里处理接收到的TPDO更新轴状态 void CAN_RX_IRQHandler(uint32_t can_id uint8_t* data) { switch(can_id) { case TPDO1_X_AXIS: // 假设映射状态字(16bit) 实际位置(32bit) axis_x.statusword data[0] | (data[1] 8); axis_x.actual_position (int32_t)(data[2] | (data[3] 8) | (data[4] 16) | (data[5] 24)); // 检查状态字中的错误位、到位信号等 if (axis_x.statusword 0x0800) { // 检查“到位”位bit11 // X轴已到达目标位置 } break; case TPDO1_Y_AXIS: // 同理更新Y轴状态 break; default: // 处理其他CAN ID如SDO响应 break; } } // 驱动器使能序列通过PDO发送控制字实现状态机转换 void enable_drive(Axis_t* axis uint32_t rpdo_cob_id) { axis-controlword CMD_SHUTDOWN; send_rpdo1_to_axis(axis rpdo_cob_id); delay_ms(50); axis-controlword CMD_SWITCH_ON; send_rpdo1_to_axis(axis rpdo_cob_id); delay_ms(50); axis-controlword CMD_ENABLE_OP; send_rpdo1_to_axis(axis rpdo_cob_id); delay_ms(50); axis-is_enabled 1; } // 主控制任务在1ms定时器中断或高优先级任务中调用 void control_task_1ms() { // 1. 状态检查与错误处理基于statusword if (!axis_x.is_enabled) { enable_drive(axis_x RPDO1_X_AXIS); } // 同理检查Y轴 // 2. 分拣逻辑简化示例 static uint32_t pick_place_phase 0; static uint32_t phase_timer 0; switch(pick_place_phase) { case 0: // 等待物料 if (sensor_material_detected()) { axis_x.target_position 10000; // X轴移动到拾取位 axis_x.controlword CMD_ABS_POS_START; // 启动绝对定位 pick_place_phase 1; phase_timer 0; } break; case 1: // X轴移动到位 if (axis_x.statusword 0x0800) { // 检查到位信号 axis_y.target_position -5000; // Y轴下降抓取 axis_y.controlword CMD_ABS_POS_START; pick_place_phase 2; phase_timer 0; } break; case 2: // Y轴下降到位执行抓取 if (axis_y.statusword 0x0800) { gripper_close(); // 控制夹爪闭合 delay_ms(100); // 等待抓稳 axis_y.target_position 0; // Y轴上升 axis_y.controlword CMD_ABS_POS_START; pick_place_phase 3; phase_timer 0; } break; case 3: // Y轴上升到位X轴移动到放置位 if (axis_y.statusword 0x0800) { axis_x.target_position 50000; // X轴移动到放置位 axis_x.controlword CMD_ABS_POS_START; pick_place_phase 4; phase_timer 0; } break; case 4: // X轴移动到位Y轴下降放置 if (axis_x.statusword 0x0800) { axis_y.target_position -5000; // Y轴再次下降 axis_y.controlword CMD_ABS_POS_START; pick_place_phase 5; phase_timer 0; } break; case 5: // Y轴下降到位释放物料 if (axis_y.statusword 0x0800) { gripper_open(); // 夹爪打开 delay_ms(100); axis_y.target_position 0; // Y轴归位 axis_y.controlword CMD_ABS_POS_START; pick_place_phase 0; // 回到等待状态 phase_timer 0; } break; default: pick_place_phase 0; break; } // 3. 发送PDO控制指令 send_rpdo1_to_axis(axis_x RPDO1_X_AXIS); send_rpdo1_to_axis(axis_y RPDO1_Y_AXIS); // 4. 超时处理可选 if (phase_timer 5000) { // 5秒超时 // 触发错误处理停止所有轴 axis_x.controlword 0x00; // 急停或关闭命令 axis_y.controlword 0x00; send_rpdo1_to_axis(axis_x RPDO1_X_AXIS); send_rpdo1_to_axis(axis_y RPDO1_Y_AXIS); pick_place_phase 0; phase_timer 0; // 记录错误日志 } }6. 运行、调试与效果验证将上述代码整合到你的STM32工程中编译下载。上电后按以下步骤验证硬件检查确认CAN总线终端电阻已接节点ID设置正确波特率一致。初始化监听使用CAN分析仪如PCAN-USB GCAN-USBCAN等或支持CAN的调试软件监听总线报文。上电后你应该能看到驱动器发送的“心跳”报文通常是NMT节点保护或心跳报文COB-ID0x700节点ID。SDO配置验证主程序启动后CAN分析仪应能捕捉到主站发送给驱动器的SDO配置报文COB-ID0x600节点ID以及驱动器的回复COB-ID0x580节点ID。回复报文的数据字节0若为0x60表示SDO写成功。状态机转换观察主站通过PDO发送的控制字序列0x06 - 0x07 - 0x0F以及驱动器状态字的变化。当状态字的bit0“准备上电”和bit3“操作使能”为1时表示驱动器已使能。运动测试触发你的分拣逻辑例如模拟传感器信号观察主站是否发送包含新目标位置和控制字0x1F的PDO报文。同时监听驱动器返回的TPDO检查状态字中的“到位”位bit11是否在电机到达目标位置后置1。实际动作观察X轴和Y轴电机是否按预期顺序运动完成拾取、移动、放置的循环。成功标志电机能够按照预设的顺序和位置平滑运动。CAN总线通信稳定无大量错误帧。系统能够连续运行多个周期无异常。通过状态字能准确监控各轴状态使能、到位、错误等。7. 常见问题与排查思路在集成CANopen步进系统时以下问题是高频雷区问题现象可能原因排查方式解决方案电机不使能状态字无变化1. CAN通信未建立。2. 控制字序列发送错误或时序不对。3. 驱动器有硬件错误如过流。1. 用CAN分析仪检查是否有报文收发。2. 检查发送的控制字值是否正确。3. 查看驱动器状态字或LED指示灯。1. 检查接线、终端电阻、波特率、节点ID。2. 严格按照Shutdown(0x06)-Switch On(0x07)-Enable Op(0x0F)顺序发送并留足状态转换时间几十毫秒。3. 排查电机接线、电源电压、电流设置。电机使能后啸叫或振动但不运动1. 目标位置未更新或与控制字不匹配。2. 工作模式设置错误非PP模式。3. 轮廓速度/加速度设置为0。1. 检查PDO发送的数据中目标位置是否有效。2. 通过SDO读取0x6060确认模式。3. 读取0x60810x60830x6084等参数。1. 确保在发送0x1F启动命令前目标位置已通过PDO更新。2. 通过SDO将0x6060设为1PP模式。3. 设置合理的速度、加速度参数。电机运动方向与预期相反电机接线相序或驱动器方向逻辑设置问题。通过SDO发送一个小的正数目标位置观察电机转向。1. 交换电机A A-或B B-中的一组线。2. 或通过驱动器对象字典如极性参数修改方向。CAN总线通信错误帧多1. 波特率不匹配。2. 终端电阻缺失或错误。3. 线路干扰或过长。使用CAN分析仪查看错误帧计数和类型。1. 确认所有节点波特率绝对一致。2. 确保总线两端有且仅有2个120Ω终端电阻。3. 使用屏蔽双绞线远离强电干扰源。只能控制一个电机第二个无反应1. 第二个驱动器的节点ID设置错误或冲突。2. 主站程序未正确区分两个节点的COB-ID。3. 第二个驱动器未成功初始化。1. 检查第二个驱动器的拨码开关。2. 监听总线看主站是否向第二个节点的COB-ID发送了报文。3. 检查第二个驱动器的SDO配置回复。1. 确保节点ID唯一。2. 在主站程序中为每个轴使用正确的节点ID计算COB-ID。3. 分别对两个驱动器进行完整的SDO初始化流程。位置控制不精准有累积误差1. 步进电机开环控制固有的丢步问题。2. 机械传动存在间隙。观察多次往返后实际位置与目标位置的偏差是否固定。1.考虑闭环步进方案这是“张大头42步进闭环”等方案的价值所在。它通过编码器反馈构成位置环从根本上消除丢步。2. 机械上使用消隙齿轮或双螺母丝杠。8. 最佳实践与工程建议将原型系统转化为稳定可靠的工业应用还需要注意以下几点启动与初始化序列化不要同时初始化所有节点。建议采用顺序初始化发送NMT启动命令让所有节点进入预操作状态 - 逐个节点进行SDO参数配置 - 逐个节点使能发送控制字序列。这有助于隔离问题。心跳与节点监护在生产系统中务必启用心跳Heartbeat或节点监护Node Guarding功能。主站可以定期检查从站是否在线一旦从站故障或掉线主站可以进入安全状态如停止所有轴。错误处理与恢复在控制循环中持续监控驱动器的状态字Statusword。如果检测到错误位如bit3“故障”应立即停止发送运动指令并通过SDO读取具体的错误代码对象通常是0x603F来诊断原因然后根据错误代码执行复位或清除错误操作。参数存储通过SDO配置的参数通常存储在驱动器的RAM中掉电丢失。如果参数需要永久保存查阅手册看是否支持通过SDO写入“保存参数”命令对象字典中常有0x1010“存储参数”等。使用成熟的协议栈对于复杂的多轴系统或需要支持更多CANopen服务如SDO块传输、时间戳、同步报文SYNC的项目建议在控制器端使用成熟的、经过验证的CANopen协议栈如CANopenNode CanFestival等而不是完全从零实现。这能大幅提升开发效率和系统稳定性。文档与版本管理为每个驱动器型号建立其对象字典的配置文档。记录所有通过SDO修改过的参数索引、值和含义。这将为后续维护、调试和产品升级节省大量时间。接地与屏蔽工业现场干扰强烈。务必做好CAN屏蔽线的单点接地驱动器、电机和控制器电源的接地要可靠以最大限度减少通信干扰和误动作。通过沈阳广成这类集成CANopen的步进驱动器你获得了一个符合工业标准、稳定可靠的执行单元。你的工作重心得以从底层通信协议解放出来聚焦于上层的应用逻辑和系统集成。这套基于CANopen的分布式控制架构不仅适用于分拣同样适用于雕刻机、点胶机、装配线等任何需要多轴协调运动的场景。