项目

一般

简介

任务支持 #2542 » SERVO42C-点动不转排查.md

孙乃宇, 2026-09-19 17:07

 

MKS SERVO42C「点动不转 / 转一下就锁死 + 电流声 + 烫手」——已解决记录

2026-09-19 · 结论:Mode 从 CR_vFOC(闭环)改为 CR_OPEN(开环)后,一切正常。
上位机控制好使、电机正常运动、电流声消失。
本文记录:已验证配置、根因链、以及"以后想用闭环该怎么查"。


一、✅ 已验证解(结论先行)

把 42C 的 Mode 从 CR_vFOC 改成 CR_OPEN。

改完现象全部消失:

症状 改 CR_OPEN 后
发脉冲电机不动 ✅ 正常运动
上位机控制无效 ✅ 好使
电流声 ✅ 消失
运动一次后就锁死 ✅ 不再出现
电机烫手 ✅ 随之解决(电流声没了 = 不再持续灌大电流)

⇒ 根因不在 config.yaml、不在接线、不在 FluidNC 侧,而在 42C 的 CR_vFOC 闭环路径本身。


二、★ 为什么 CR_OPEN 能解、CR_vFOC 不能 —— 整条因果链

三个模式的区别(手册原文)

Mode 含义 是否需要编码器
CR_OPEN 开环控制模式 不需要 ← 本次可用
CR_vFOC 矢量闭环控制模式,有编码器反馈防丢步 需要(用电角度对齐)
CR_UART 串口直接控制 Stp/Dir 完全失效

现象 → 机制对照

观察 机制
clk = 正好 3200(1mm × 3200 步/mm,分毫不差) ✅ 脉冲数量正确,Stp/Dir 接线 + Com 共地正确
MPos 0 → 1.000,2.39s 停稳 ✅ FluidNC 侧命令链 / 速度 / 限位全正常
屏幕"角度"是内部命令位置(手转轴时角度不变、err 会变 → 实测) 角度 359.9° 只说明命令走了一圈,不能证明电机转了
err 卡在 17.99(≈10 个整步)不收敛 ⚠️ 闭环在较劲:位置环追不上 ⇒ 电流顶到上限
电流声 + 烫手 ⚠️ 电流顶满的结果
第一次运动能转一圈、之后再也不响应 ⚠️ 位置环饱和 → 锁死,只有复位能清
CAL 后电流声消失、屏幕归零 ★ CAL 不走位置环(它只是强制正反转做电角度对齐)⇒ CAL 永远正常,证明不了位置环正常

⇒ 根因

CR_vFOC 闭环路径失效:驱动器收下脉冲(内部命令位置走了一圈),
但位置环无法把转子驱动到位 ⇒ 误差不收敛 ⇒ 电流灌满线圈 ⇒ 嗡响 + 发热 + 锁死。
改成开环后不再依赖反馈,脉冲直接被当作步进指令执行 ⇒ 一切正常。

⇒ 闭环为什么会失效(后续想修再看,不影响当前使用)

按可能性排序:

# 原因 怎么查
1 MotType 与电机不匹配(0.9° vs 1.8°) 菜单 MotType 应 = 1.8°;改过必须重跑 CAL
2 闭环 PID 被改坏 Kp/Ki/Kd ⚠️ 没有菜单项!只能在串口 e0 a1/a2/a3 看;恢复只有 Restore(e0 3f 1f)
3 ACC / MaxT 被改坏 ACC 有菜单项;MaxT(e0 a5)没有
4 编码器磁铁(轴向充磁 / 偏心 / 间距不在 1~2mm) 屏幕报 Magnet Loss! / Magnet Error!;或用 e0 30 手转轴看编码器值是否连续变化

若以后要回到闭环,按这个顺序做一遍:
Restore → 重新上电 → 重设 MotType=1.8° / MStep=16 / Ma=1200 / En=Hold / Mode=CR_vFOC
→ 空载重跑 CAL → 点动 1mm,验收标准见第四节。


三、★ 当前可用的 42C 参数快照(换板/复位后照着设回来)

参数 值 说明
Mode CR_OPEN ★ 本次的关键项
MotType 1.8° 待最终确认
MStep 16 与 FluidNC 侧 steps_per_mm = 3200 对应
Ma 待确认(建议 800~1200mA) ★ 开环下电流是恒定的,不受负载自动调节 ⇒ 发热只由 Ma 决定
En Hold 建议 一直使能,绕开 EN 引脚电平问题(出厂默认是 L)
Protect 建议 Enable 开环没有丢步保护,靠堵转保护兜一层(触发后屏幕 Wrong Protect Enter..,Enter 解除)
MPlyer Enable(默认) 内部 256 细分插补,低速更静

⚠️ 两件要确认的事

  1. 做一次断电重启验证:断电 → 重新上电 → 点动一次,确认 Mode 仍是 CR_OPEN 且能转
    (42C 参数应掉电保存,但值得实测一次,避免下次上电又变回去)。
  2. 跟一次温度:开环恒流,若跑一会儿还烫手 ⇒ 把 Ma 调低(800mA 起)。

四、开环(CR_OPEN)的代价 —— 要接受的取舍

项 说明
没有丢步保护 开环不看编码器,丢步不会报错。本机负载轻(纯电机 / 后续接位移台),一般可接受
电流恒定 手册原文:Ma 设的是开环模式的运行电流档位;闭环才会随负载自动调电流
没有堵转自动保护 除非开 Protect
好处 不依赖编码器/电角度对齐 ⇒ 绕开了本次的闭环故障,最简单最稳

若后续对定位精度/丢步有硬要求,再按第二节末尾的清单去修闭环。


五、验收标准(本机,随时可复测)

点动 1mm:

项目 期望
电机 肉眼可见转 1 圈(本机 1mm = 1 圈)
clk +3200(1mm × 3200 步/mm)
MPos 0.000 → 1.000,约 2.4s 停稳
声音 / 温度 无电流声;不烫手

六、已实测排除的环节(留档,别再回头查)

环节 实测 结论
config.yaml 脉冲数量 + 速度 + 接线三项全对 ✅ 不是 config 的问题
FluidNC 命令链 $J=G91 X1 F60 → MPos 0.000 → 1.000;同方向连点两次各 +1.000mm ✅ 正常
脉冲数量 42 板 clk = 正好 3200 ✅ Stp/Dir 接线 + Com 共地正确
steps_per_mm $/axes/X/steps_per_mm = 3200.000 ✅ 生效
脉冲速率 3.2kHz,手册上限 60KHz ✅ 不存在"太快跟不上"
转速量级 60mm/min = 1 圈/s = 60RPM,上限 1200RPM ✅ 不存在"转速过高"
Stp 噪声 / 接反 不点动时 clk 不变;每次点动正好 +3200 ✅ 均排除
CR_UART 菜单能跑到 CAL;当时"CR_UART 下菜单只剩 2 项"⇒ 该项判据已作废,见下方更正 ✅ 排除
驱动器使能 手拧轴有阻力;改为 CR_OPEN 后能正常驱动 ✅ 排除
驱动级 + 相线 + 编码器 + 磁铁 CAL 正反转各一圈正常 ✅ 好
CR_vFOC 闭环 误差不收敛、电流顶满、锁死、烫手 ❌ 坏 —— 本次根因

★★ 更正(2026-09-19):当时"CR_UART 下菜单只剩 2 项、此模式菜单被锁死"是误判 ——
菜单项变少的真因是当时 42C 没有识别到编码器磁铁,与 Mode 无关。
磁铁被识别到后,CR_OPEN / CR_vFOC / CR_UART 三个模式的菜单都是齐全的。
⇒ 因此也不能用"菜单项数"/"菜单里能不能跑到 CAL"来判断 Mode(原判据作废);
判断 Mode 直接进菜单看 Mode 项。详见 LO-TTA-03-整合指南.md §3.1。


七、SERVO42C 参数速查

功能码 作用 取值/默认
e0 30 读编码器值(需已校准) 0~FFFF
e0 33 读输入累计脉冲数(=屏幕 clk) int32
e0 36 读位置(=屏幕 角度,实测为内部命令位置) int32
e0 39 读位置角度误差(=屏幕 err) int16,182.444 / 度
e0 3a 读 En 引脚状态 01=使能 02=未使能 00=错误
e0 3e 读堵转标志 01=堵转 02=正常
e0 3d 解除堵转状态
e0 80 00 60 校准编码器(=菜单 CAL),必须空载 成功 e0 01 e1
e0 81 电机类型 MotType 00=0.9° 01=1.8°(改后必须重校准)
e0 82 工作模式 CtrMode 00CR_OPEN 01CR_vFOC 02CR_UART
e0 83 电流档 Ma 00=0mA, 01=200mA, … 06=1200mA, 0F=3000mA
e0 84 细分 MStep 1~256(本机 = 16)
e0 85 En 有效电平 00L(出厂默认) 01H 02Hold
e0 86 旋转正方向 Dir 00CW 01CCW
e0 88 堵转保护 Protect 触发后屏幕 Wrong Protect Enter..
e0 89 内部 256 细分插补 MPlyer 默认 Enable
e0 3f 1f 恢复默认参数(需重新上电)
e0 a1 / a2 / a3 位置环 Kp / Ki / Kd(无菜单项) 默认 0x650 / 1 / 0x650
e0 a4 / a5 加速度 ACC / 最大扭矩 MaxT(MaxT 无菜单项) 默认 0x11E / 0x4B0

屏幕报错对照:Not Cal=未校准 / Phase Line Error!=电机线序错 /
Magnet Loss!=编码器磁铁缺失或轴向充磁(需径向充磁)/ Wrong Protect Enter..=堵转保护。


八、FluidNC 侧命令速查(本机 COM15 @115200)

?                     查状态(★轮询判停要取缓冲区最后一条状态行)
$I                    固件 / 板型 / 机器名
$GD                   所有 GPIO 电平(★看不到 I2SO 扩展脚)
$MD / $ME             禁用 / 使能所有电机
$Config/Dump          当前生效配置(≠ 磁盘 config.yaml)
$LocalFS/Show=/config.yaml   磁盘上真正的 config.yaml(权威值)
$axes/X/steps_per_mm  读单项设置
$J=G91 X1 F60         相对点动 1mm @F60(★本机 1mm = 电机 1 圈 = 3200 脉冲)
$ESP444=RESTART       重启(★ 串口 $ 写入全部丢失,只认 config.yaml 文件)

九、相关脚本(D:\workspace\jiahe-agg\fluidncdll\)

脚本 用途
test_enable.py 4 步现场判定:① 判使能($MD/$ME 交替、看松手弹不弹回) ② 点动看 clk 增量 ③ 同方向再点(判 Stp/Dir 接反) ④ 看角度/err
probe_ports.py 枚举串口 + 逐个探测(判断设备是否还在线)★怀疑掉线先跑这个
diag_motor.py 抓 $I / $CMD / $GD / 运动配置段
diag_jog_me.py 点动验证 MPos + 试 $MD/$ME
axis_params.py 轴参数在线读写 + 卡尺标定

⚠ 工具坑(已修):check_jogcancel.py 的 Raw 原先没设 COMMTIMEOUTS,
未设超时的串口 ReadFile 会一直阻塞到有 1 字节到达,read_for(ms) 的时限形同虚设。
设备一旦不回话脚本就卡死被 SIGTERM,而且 stdout 是空的(缓冲没 flush)——
我因此两次把 $GD 的"读不出来"误判成命令问题。
现已在 SetCommState 后补 SetCommTimeouts(ReadIntervalTimeout=10ms /
ReadTotalTimeoutConstant=25ms,读缓冲 1→4096 字节)。
另注:蓝牙调制解调器口(\Device\BthModem*)打开就卡住,探测时跳过;
Raw.read_for() 返回的已是 str,不要再 .decode()。

(4-4/7)