跳转至

EtherCAT 伺服接入 Klipper / Kalico

三条结论

  • Klipper 主线与 Kalico 都没有原生 EtherCAT。能上机的路线只有一条:Linux 内核里跑 IgH 主站,外加一个把 Klipper toolhead 位置流翻译成 CiA402 CSP 目标位置的桥接守护进程。脉冲转换器和 LinuxCNC + lcec 混合是备选,其余路径停在实验阶段。
  • 纯总线机(伺服 + IO 板、没有物理 MCU 板)必须用 Linux host MCU 为 toolhead.mcu 提供打印时间基准,否则 [mcu] 直接 Unable to connect;这个 MCU 在没有 /dev/gpiochip 的 x86 上还要打一个 GPIO 补丁才不 segfault。
  • 软实时 IgH 在 1 kHz / 500 mm/s 量级是稳的(print_stall = 0、丢帧 0.0001% 级);推到 1000 mm/s 的瓶颈是主站周期而不是加速度。到 µs 级周期、8 kHz 伺服刷新这个量级,才需要 FPGA 硬主站——而用 USB 连硬主站会把优势全部吃掉。

从站拓扑:一块 IO 板 + 四路伺服

一个可用的最小总线拓扑(四轴机,X/Y/Z + 挤出):

slave 设备 角色 profile 周期
1 EaserCAT 3000 数字 IO 板(限位/回零/急停) cia402_mode = -1,不下发控制字 1 kHz
2 L6N COE X 轴伺服 CSP 1 kHz
3 L6N COE Y 轴伺服 CSP 1 kHz
4 L6N COE Z 轴伺服 CSP 1 kHz
5 L6N COE E 轴(挤出)伺服 CSP 1 kHz

几个值得固定下来的工程约定:

  • PDO 描述统一成四段式 0x6040:0:16:0,即 index:subindex:bits:offset。写配置时一眼能看出映射对不对,比纯十六进制偏移表好查。
  • IO 板与伺服走同一套 profile 机制,用 cia402_mode = -1 表示"这块从站不参与 CiA402 状态机",只搬 PDO、不写控制字。这样同一份代码可以同时驱动两种从站,不必为 IO 板单开分支。
  • 从站序号就是轴身份。slave_index 同时出现在 printer.cfg 轴段和主站配置里,两边错一个数字,现象是"某个轴不动/乱动"而不是报错——排查时先核对这两处。

IO 板出厂默认已经配好了限位,用 SDO 读一遍即可确认,不必从零映射:

对象 默认值 含义
0x2400 1 正限位 POT
0x2401 2 负限位 NOT
0x2402 0x16 回零 HOME
0x2403 — 预留

对应手册的 SI 功能号:正向限位 PL = 25h、反向限位 NL = 26h、HOME = 22h。回零速度要注意 IO 板是 10 ms 轮询,高速回零的触发误差约等于 10 ms × 速度,精确定位场合不可接受,回零应交给伺服自己的 DI。

生态现实:四条路,只有一条能上机

方案 集成难度 实时性 硬件成本 成熟度
EtherCAT → Step/Dir 脉冲转换器 低 中 中(每轴一个模块) 成熟
LinuxCNC + lcec 混合 中 高 低 中等
IgH 主站 + 位置流桥接 高 中高 低 已在真机跑通
Klipper MCU 层原生 EtherCAT(PRU/专用从站芯片) 极高 极高 低 未验证

调研到的硬事实:

  • mainline Klipper 官方不支持 EtherCAT,原生接口只有 step/dir、CAN、USB、串口,社区论坛口径是"别浪费时间"。
  • Kalico(原 Danger Klipper)也没有原生 EtherCAT,仓库里只有通用 servo.py。
  • GitHub 上没有成熟的 Klipper 直挂 EtherCAT 伺服公开项目。公开可见的尝试是用 Beckhoff EK1100 耦 EtherCAT 伺服搭大型机——主站装好、ethercat slaves 能看到从站,然后卡在"怎么对接 Klipper"。
  • 工业 3D 打印的 EtherCAT 案例集中在建筑/大幅面(例如专利 CN109537455A),配的是 PLC 或运动控制卡,不是 Klipper。
  • 唯一成熟对标是 LinuxCNC + linuxcnc-ethercat (lcec)。

所以路径选择的判据不是"哪个先进",而是"谁负责 1 kHz 的确定性":主站必须在内核态(IgH),运动规划留在用户态(Klipper 的 Python 规划器),两者之间用环形缓冲/共享内存解耦。脉冲转换器最省事,但每轴一个模块的成本加上额外一级延迟,在大幅面多轴机上不划算。

开源硬件主站板:能用,但不该用在打印机上

市面上有现成的开源 EtherCAT 主站小板可以买,接上 USB 就能扫从站。识别特征:STM32H743(Cortex-M7 @ 480 MHz、1 MB RAM、硬件以太网 MAC + RMII PHY,常见 LAN8720,CH340 做调试串口),跑开源 SOEM 库(裸机 / FreeRTOS / RT-Thread 任选)。另有 ESP32 + W5500 的变体——SPI 接网口芯片,实时性更差一档。

这类板子与上位机架构(klippy 是 Linux 进程)不兼容,三条理由:

  1. klippy 跑在 Linux 上,H743 是 MCU,跑不了 Klipper 的运动引擎——螺杆补偿、分段 mesh、输入整形这些全部丢失;
  2. 裸机 SOEM 在 1 kHz 下确定性不错(比 ESP32 强),但运动插值只能在 MCU 里做简单梯形,做不了前瞻;
  3. 受内存限制,从站规模只能十几个,DC 精度与 x86 上的 IgH 有实质差距。

正确用途:EtherCAT 协议学习、从站调试工具(挂总线扫伺服身份)、不需要 Klipper 的单轴嵌入式设备。

扫描从站身份的最小验证(pysoem):

import pysoem
master = pysoem.Master()
master.open('enp2s0')
if master.config_init() > 0:
    for s in master.slaves:
        print(s.position, s.name, hex(s.man), hex(s.id))

输出形如 1 EtherCATServo 0x100 0x100 就说明链路和从站都活着,可以接着做 SDO 身份读取和 CSP/CSV 模式控制测试。

一个容易跑偏的排查:CH340 串口枚举正常但板子无输出,先查固件是否烧录、网口 Link 灯是否亮,别去怀疑串口驱动——这类板子出厂常常是空片。

没有物理 MCU 的机器:Linux host MCU

EtherCAT 驱动不是独立运动引擎,它挂在 Klipper 的 MCU 抽象上,需要 toolhead.mcu 提供打印时间基准。纯总线机没有物理 MCU 板,[mcu] serial: /tmp/xxx 会直接报 Unable to connect。

编译 Kalico 的 Linux host MCU:

cd ~/kalico
echo "CONFIG_MACH_LINUX=y" > .config
make olddefconfig && make -j4
sudo bash scripts/flash-linux.sh          # → /usr/local/bin/klipper_mcu

GPIO 补丁(没有 /dev/gpiochip 的 x86)

在没有 /dev/gpiochip 的机器(典型是 Intel 消费级平台)上,klipper_mcu 启动即 segfault。补丁改三处:

  • get_chip_fd() 失败返回 -1,不走 shutdown 流程;
  • gpio_out_reset / gpio_out_write / gpio_in_read 对无效 fd 静默 no-op;
  • EtherCAT 轴的 step_pin/dir_pin 只是配置占位,实际运动由桥接守护进程驱动,GPIO 层不参与。

第三条是关键认识:这些 pin 是给 Klipper 的配置解析器看的,不是给硬件看的。理解这点就不会去纠结"pin 明明电平没变,轴怎么在动"。

systemd

[Service]
Type=simple
User=kalios                  # 普通用户,避免 socket 权限问题
ExecStart=/usr/local/bin/klipper_mcu
Restart=always

用 root 跑会带来 /tmp/klipper_host_mcu 的属主问题,klippy 以普通用户连不上。

printer.cfg

[mcu]
serial: /tmp/klipper_host_mcu

[stepper_x]
step_pin: gpio0              # 占位,无实际 GPIO
dir_pin: gpio1
enable_pin: gpio2
drive_type: eth              # EtherCAT 伺服
slave_index: 2
endstop_pin: ^gpio3

drive_type: eth 把该轴从"发脉冲"切到"发目标位置";slave_index 必须与主站配置一致。

主站启动顺序

顺序错了会出现"从站看得见、轴不动",或者主站反复重载:

sudo ethercatctl stop
sudo rmmod ec_generic ec_master 2>/dev/null || true
sudo modprobe ec_master && sudo modprobe ec_generic
sudo ethercatctl start              # dmesg: Accepting ... as main device
sudo systemctl start klipper-ethercatd
  • systemd 服务里不要手动 modprobe ec_master,全部交给 ethercatctl start——它内部带 main_devices 参数做卸载重载,手动加载会让主站绑错网卡。
  • ethercatctl start 之后 dmesg 里必须有 Accepting ... as main device。没有这行,说明网卡没绑上,后面所有调试都是白费。
  • 主站进程用 SCHED_FIFO 优先级 80 绑隔离核,网卡 IRQ 也要绑到同一批核(irqaffinity),否则中断会跑到跑着 GUI/切片的核上。

一组可对照的参数:

项目 取值
内核 6.8 系 -realtime(PREEMPT_RT)
隔离核 isolcpus=10,11 + nohz_full + rcu_nocbs + irqaffinity
网卡 独立 PCIe 网卡,专供 EtherCAT,不配 IP
主站进程调度 SCHED_FIFO 80,绑 CPU 10/11
网卡 IRQ 绑 CPU 10

CiA402:位置/速度之外还能读什么

总线方案相对脉冲方案最大的增量不是"接线少",而是每一毫秒都能拿到伺服内部状态。

已接入读取的:

数据 对象 用途
位置实际值 0x6064 运动控制
速度实际值 0x606C 运动控制
扭矩实际值 0x6077 堵料/碰撞检测;int16,单位 0.1% 额定扭矩,实测可读

同族伺服支持、但需要显式加 PDO/SDO 的:

数据 对象 3D 打印里的用途
位置误差 0x60F4 丢步检测:误差突增 = 丢步/撞车
目标位置 0x60FC 与指令对比,判断桥接层是否跟丢
控制字/状态字 0x6040 / 0x6041 伺服健康状态、故障码入口
输入信号 0x60FD 限位/回零状态
电机电流 / 母线电压 厂商区 0x2xxx 功率监控
温度 厂商区 过热预警
编码器多圈位置 0x6063 断电后位置恢复
报警历史 0x1003 / 厂商区 故障诊断
滤波后实际速度 厂商区 速度环诊断

据此能做出八类优化,按价值排序:

  1. 挤出机扭矩监控 + 堵料检测(最实用):扭矩 > 阈值持续 N ms → 堵料,自动暂停;扭矩 ≈ 0 而挤出指令 > 0 → 断料/齿轮打滑。
  2. XY 碰撞检测:0x60F4 突增超阈值 → 立即停机,比限位开关更早、更灵敏。
  3. 扭矩显示界面:给现场看,是售前卖点。
  4. 压力提前(PA)闭环:扭矩近似正比于熔体压力 → 实时调挤出速度。大厂靠 loadcell 做这件事,总线方案直接从伺服读扭矩,不需额外传感器。
  5. 丢步检测与自动补偿:按层统计位置误差,累积量对应 Z 偏移。
  6. 机械健康诊断:扭矩波形频谱中,周期性波动指向丝杆弯曲/轴承磨损,高频振动指向皮带松动,堵转特征指向润滑不良。
  7. 速度环 PID 自动整定:读速度环误差自动调 Kp/Ki/Kd。
  8. 断电恢复:0x6063 多圈绝对值 → 恢复精确位置 → 续打。

一个反直觉但很关键的点:多数 CSP 配置只下发位置,不下发目标速度(Rx PDO 只有 0x6040/0x607A/0x60B8,没有 0x60FF)。好处是配置简单,坏处是伺服完全靠内部滤波消化位置流的不平滑——这正是下一节诊断的根因之一。

CSP 周期与线宽脉动:诊断流程

三步法

第一步,速度达成率。 对目标轴做递增速度测试并量实际速度:

SET_VELOCITY_LIMIT VELOCITY={vel}
G1 X±100 F{vel*60}

判据:中低速达成率 ≥ 90% 正常,< 80% 说明存在硬限制。一组实测:

目标速度 实际速度 达成率
50 mm/s 48 mm/s 96%
100 mm/s 91 mm/s 92%
200 mm/s 156 mm/s 78%
400 mm/s 256 mm/s 64%

巡航速度封顶约 270 mm/s(ACCEL = 3000)。这种"低速几乎不丢、越高速越掉"的形状,指向限幅/前瞻不足,而不是电机能力不足。

第二步,CSP 流送分析。 从 klippy.log 解析 STREAM 行,取 tp(目标位置)、tv(目标速度)、pa(实际位置),做相邻差分并统计:

指标 正常 异常
步进波动 CV < 10% > 30%
大幅跳跃(> 3σ) 0 ≥ 1
跳跃间隔 — ≈ 50 ms → trapq 速率问题
跟随误差 < 1 mm > 3 mm

实测 200 mm/s 往复:CV 正向 49.2% / 反向 38.4%,> 3σ 跳跃 31 / 30 次,跳跃间隔 ~51 ms / ~62 ms,跟随误差 3.27 mm。CV 近 50% 加 50 ms 间隔,几乎等于直接指认 trapq 失配。

第三步,根因定位。

trapq  (20 Hz,50 ms 间隔)
  ├─ t = 0~49 ms : 目标位置不变(49 个 cycle 是同一个数)
  └─ t = 50 ms   : 目标位置跳一大步 → 伺服急加速追赶 → "咔咔"响

Klipper 的 trapq 按约 20 Hz 更新位置,CSP 以 1 kHz 流送。中间 49 个周期目标位置不变、第 50 个周期跳一步,伺服为跟上这个阶跃会瞬时加大加速度。这是周期/速率不匹配,不是机械故障。

参数修正

参数 默认 建议 说明
max_delta_mm 1.0 0 关闭步进限幅,减少高频微跳
jump_resync_mm 8.0 30.0 避免高速时误触发重同步
stream_lookahead 0.020 s 0.040~0.060 s 加长前瞻,平滑轨迹
EC_SAFE_LIMITS VELOCITY 30 500 解除速度锁定
EC_SAFE_LIMITS ACCEL 500 3000 提高加速度上限

另一类根因是 position_scale 不一致:配置写 3276.8,监测 API 报 6553.6,差整两倍。表现是回零后 Klipper 认为 X = 0,监测页却显示伺服实际位置 356 mm。改这个数不会让机器动起来,但会让所有基于位置的判据全部失真——诊断前先核对它,否则后面的误差分析都是在错误尺子上量。

弧线线宽周期性脉动

更难的案例:四轴全 CSP,直线正常、弧线线宽周期性脉动,同一台机器改脉冲方式控制就正常。这类"换驱动方式就好了"的现象容易误判成 Klipper 轨迹问题,静态读代码可定位到四个叠加因素。

① DC 同步未激活(最硬)。 实际调用是:

ecrt_slave_config_dc(sl->sc, 0x0300, g_cycle_ns, 0, 0, 0);

IgH 的签名是 (sc, sync0_cycle, sync1_cycle, assign_activate, sync0_shift, sync1_shift)。这里把 768 ns 当成了 sync0 周期(应为 DP 周期 1 ms),而 assign_activate = 0 意味着 SYNC0 根本没激活。正确写法:

ecrt_slave_config_dc(sc, g_cycle_ns, g_cycle_ns, EC_DC_ACTIVATE_SYNC0, 0, 0);

DC 不激活时,各从站按自己收到帧的时刻锁存目标位置,帧到达的微小偏差直接变成位置锁存偏差。

② Rx PDO 里没有目标速度。 profile 只有 0x6040/0x607A/0x60B8,offset_target_velocity = -1,纯位置闭环。没有速度前馈,伺服只能靠内部滤波器"猜"这一毫秒该走多快,对指令平滑度和时序极度敏感。

③ 主站时间开环累加。 全局 g_seg_pt_est += cyc_s 固定加 1 ms,只有 host 时钟段到达时才用 PLL 系数 0.05 对齐。周期抖动不会被纠正,只能缓慢收敛。

④ 从站各自独立估时。 早期实现每个从站独立 pt_est,E 轴与 XY 之间存在相位差;改全局统一后有所缓解,但 ① 未改,问题仍在。

为什么直线正常、弧线暴露:直线匀速时位置随时间线性变化,采样相位差只产生恒定相位偏移,不改变速度,也不改变挤出量。弧线被离散成大量微小线段,频繁加减速和变向,从站目标位置的锁存稍不同步就转成周期性速度波动 → 挤出量与运动量失配 → 线宽脉动。线宽脉动的本质是"位置同步误差被微分成了速度误差"。

修复优先级:DC 激活 → PLL 对齐系数/批次(0.05 跟不上圆弧加减速)→ 周期与资源(1 ms 周期下用户态 RT 被切片器和浏览器抢占,系统负载 7~8 时明显;把重负载挪走,或把周期降到 500 µs)。

只读验证(不触运动):

ethercat slaves      # 每个从站的 SYNC / OP 状态
ethercat master      # DC 参考时钟与偏移

两类"假故障"

8612 / Er1B0 单周期 TP 跳变。 现象是"首次打印正常,二次打印必 fault",故障位置固定。根因不在速度达成率,而在状态复位不完整:打印中复位后 Klipper 重新武装 sync_count_offset 并 CLEAR,桥接层 seg_clear() 清了 have_host_tp,却没有重置 tp_last,残留 2.5 亿 counts(≈ 376 mm)。重武装时用队列头(未来时刻)的时间戳去锚定,锚定检查因 have_host_tp = false 被跳过,于是一步锚到未来位置,目标位置突变,护栏 vmax × dt × 1.2 太松没拦住,报 Er1B0 并进入 fail-closed 级联 CLEAR 三次。

日志特征很好认:pt=266.411(残留时钟)+ d=-252248297(-376 mm)+ 打印中全轴 seg_clear 连续三次。修法三条:seg_clear 时把 tp_last 重置到 PA;锚定兜底改用 seg_tp(PA);重武装改用 estimated_print_time(monotonic())。

教训值得单列:护栏基准(tp_last)与锚定检查(have_host_tp)是两个独立状态,clear 时必须一起重置,否则陈旧基准继续参与限幅,形成"看起来有护栏、实际全部放行"。

丢帧率的脏数据。 报 0.0298%(Lost 2001 / Tx 671 万)不一定是真丢帧。核实下来是统计窗口落在最脏时段:某轴 count_offset 失配导致"积分突变"日志 63034 条 / 3 分钟,journald 磁盘 IO 饱和,偶发拖垮 RT 周期。判据是规律性——每 3 秒丢一帧是周期性 IO 刷新的节奏,不是随机调度抖动;再取 60 秒双快照比对帧数零变化,说明主站已停,丢帧发生在刷屏时段而非打印时段。

结论:丢帧率必须先确认窗口干净(无日志洪水、无异常刷屏),否则 0.03% 这个量级的数字全是假象;真实值要用干净打印窗口的前后增量对比。

长期方案:把 50 ms 台阶从根上消掉

参数调优只能压平台阶,压不掉它。两条根治路线:

  • stepper_sync_manager:新版 Klipper 提供的高频位置内插机制,本质是把 trapq 的粗粒度位置在 MCU/驱动侧做原生插值,从根上消除 50 ms 跳变。先确认版本是否带这个模块:
grep -r "stepper_sync_manager" klippy/

有则升级 klipper-ethercat 组件后启用;这需要动组件版本,不能只改配置。 - CSP 层插值/平滑:无法升级时的退路——在桥接层加一阶低通,或用最近 2~3 个 trapq 采样点做线性外推,把中间的空档 cycle 填满。代价是引入一点相位滞后(半个采样周期量级),在圆弧上表现为跟随误差略增,但比"每 50 ms 一次阶跃"好得多。

判断该走哪条:如果跳跃间隔稳定在 50 ms 且 CV > 30%,走路线一;如果已经做了内插但 CV 仍在 10~20%,说明瓶颈转移到 DC/PLL,回去查第六节 ①。

能不能到 1000 mm/s

先把账算清楚。

项 当前 目标 差距
max_velocity 500 mm/s 1000 mm/s ×2
主站周期 1000 µs (1 kHz) 500 µs (2 kHz) 建议 ×2
伺服刷新 1 kHz 2 kHz+ ×2
max_accel 20000 5000 即够 不是瓶颈

关键换算:

  • 位置增量:1 ms × 1000 mm/s = 每周期 1 mm。20 位编码器约 3277 counts/mm → 每周期下发 3277 counts。切到 2 kHz 后每周期 0.5 mm ≈ 1638 counts,增量减半,插值更平滑。
  • 加速度:0.2 s 加到 1000 mm/s 需要 5000 mm/s²,现有 max_accel = 20000 有四倍余量。
  • 所以瓶颈是主站周期,不是速度值本身。1 ms 周期下每周期 1 mm 的台阶已接近伺服速度环能平稳消化的上限。

链路各段余量:

运动规划(Klipper, Python)  →  ecrtd(C)  →  IgH(内核)  →  伺服
      1 kHz 无压力              CPU 11%      PREEMPT_RT

连续运行数天的实测指标:

指标 实测
print_stall 0(规划端从不卡顿)
mcu_task_stddev 0.0001(0.1 ms 级抖动)
丢帧率 446 / 4500 万帧 = 0.001%;另一台 58 / 5900 万 = 0.0001%
主站进程占用 12 MB 内存 / 10.8% 单核
网络重传 数千帧中 9 次

改法:

# ethercat_bus.cfg
cycle_us = 500
# printer.cfg
max_velocity: 1000

改完重启 klipper-ethercatd。但先验证三件事:

  1. 伺服支持 2 kHz 周期——查手册 DC 同步范围(多数 1~4 kHz),按型号确认,不要默认。
  2. ecrtd 在 2 kHz 的 CPU——1 kHz 用 11%,2 kHz 约 20~25%,工控机/ARM 板都扛得住,但要给切片和 UI 留余量。
  3. 机械刚性——颗粒机/大流量机质量大、惯性大,1000 mm/s 可能机械先抖。空跑测试(不装料)看伺服跟不跟得上、有无同步错误;ethercat master 的帧率应从 1000/s 变成 2000/s。

软实时 vs FPGA 硬主站

方案 1 kHz 空闲抖动 压力下抖动 周期能力
FPGA 硬主站(网口/PCIe 直连) < 3.6 µs 14~15 µs µs 级
IgH 软件主站 + RT 内核 均值 < 20 µs ~100 µs 1 kHz 稳定

短板要说清楚:

短板 受限场景
抖动 10~100 µs(硬主站是 ns 级) 精密多轴插补(机床、机器人)不行
125 µs 以下周期不稳 8 kHz+ 伺服刷新的极端场景

反过来,软实时在 3D 打印赛道有硬优势:Klipper 全家桶(断电续打、调平、输入整形、Mainsail/摄像头/远程)直接可用;配置改一行重启秒级生效,而 Zynq 改一版 PL 要重新综合(小时级);SSH + 日志 + ethercat master 就能调试,不需要 JTAG 和示波器。

USB 是硬主站的天花板。 USB High-Speed 帧周期固定 125 µs,FPGA 再快,数据也要每 125 µs 过一个 USB 帧;USB 是主机轮询协议,延迟 = 帧周期 + 驱动排队 + 调度抖动,叠加后比原生 PCIe/网卡差一个数量级。USB 连接的硬主站,实时性大概率不如 IgH + RT 内核 + 直连网卡。

提升实时性的收益排序:

方案 提升 成本
IgH + 直连网卡 + RT 内核(现状) 基准 0
IgH + 专用网卡 + isolcpus/IRQ 绑核 +20~30% 一块网卡
Xenomai 双内核(IgH 原生支持) ~2× 0
FPGA 硬主站 + PCIe 直连 5~10× 数千元
FPGA 硬主站 + USB 持平或更差 数千元,不推荐

补充一条:消费级网卡(如 Intel 82574L + ec_e1000e)没有硬件时间戳,换 I210 + ec_igb 只能优化软实时,真硬实时仍要 FPGA/Zynq。

边界结论:1~4 ms 周期、1000 mm/s、颗粒/大流量打印,软实时够用且功能完整;要 µs 级周期、多轴高精插补(雕刻、机器人、机床),才上 FPGA + PCIe。

诊断判据总表

现象 首选判据 常见根因
轴不动、无报错 ethercat slaves 是否进 OP;两侧 slave_index 是否一致 从站未进 OP / 序号写错
[mcu] Unable to connect klipper_mcu 是否在跑;socket 属主 未编 host MCU / 用 root 跑
klipper_mcu 启动即崩 有无 /dev/gpiochip 缺 GPIO 补丁
主站绑错网卡 dmesg 有无 Accepting ... as main device 手动 modprobe 抢占
高速掉速、低速正常 速度达成率曲线 安全限幅、前瞻不足
"咔咔"声 + CV > 30% + 跳跃间隔 ≈ 50 ms STREAM 解析的跳跃间隔 trapq 20 Hz 与 CSP 1 kHz 失配
弧线线宽周期性脉动、直线正常 ethercat master 的 DC 状态 DC 未激活 / 缺 0x60FF / PLL 太慢
回零后位置凭空偏移整倍数 position_scale 与监测 API 的 scale 对比 换算系数差 2×
二次打印必 fault(Er1B0 / 8612) 日志 pt= 残留 + d= 大幅负跳变 seg_clear 未重置 tp_last
丢帧率 0.0x% 丢帧是否规律(每 3 s 一帧)、窗口内有无日志洪水 IO 刷屏拖垮 RT,脏数据
扭矩读数恒定或为 0 0x6077 是否在 Tx PDO 里 PDO 未映射,不是伺服坏了

相关阅读