任务支持 #2542 » SERVO42C-点动不转排查.md
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 细分插补,低速更静 |
⚠️ 两件要确认的事
-
做一次断电重启验证:断电 → 重新上电 → 点动一次,确认
Mode仍是CR_OPEN且能转
(42C 参数应掉电保存,但值得实测一次,避免下次上电又变回去)。 -
跟一次温度:开环恒流,若跑一会儿还烫手 ⇒ 把
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()。