项目

一般

简介

行为

任务支持 #2542

已关闭

调研并实验步进电机+编码器的半闭环系统是否可行

由 曹晏彬 在 大约 2 个月 之前添加. 更新于 大约一个月 之前.

状态:
已完成
优先级:
C级
指派给:
开始日期:
2026-09-14
计划完成日期:
% 完成:

100%

预期时间:

描述

使用信浓42电机并安装磁编码器,配合可以直插MKS DLC32板卡的安装座
链接
https://item.taobao.com/item.htm?id=609741216671&mi_id=0000Na-0nzcbT-oZC23iynIpEgwplY22pRqtT6HEAyFN9ZQ&spm=tbpc.boughtlist.suborder_itempic.d609741216671.679b2e8dck0TqB
链接
https://item.taobao.com/item.htm?id=655942481011&mi_id=0000H_nkVOeHrScpBA18CGuD_gUWrPgaWxw6WSq9-HuZLK8&spm=tbpc.boughtlist.suborder_itempic.d655942481011.679b2e8dck0TqB
将整个编码器反馈视为一个电机驱动,它同样可以执行FOC算法,搭配原来的MKS DLC32+FluidNC直接执行闭环控制。


文件

FluidNC.dll (198 KB) FluidNC.dll 孙乃宇, 2026-09-19 16:36
LO-TTA-03-交付清单.md (9.1 KB) LO-TTA-03-交付清单.md 孙乃宇, 2026-09-19 17:07
LO-TTA-03-整合指南.md (31.2 KB) LO-TTA-03-整合指南.md 孙乃宇, 2026-09-19 17:07
SERVO42C-点动不转排查.md (10.8 KB) SERVO42C-点动不转排查.md 孙乃宇, 2026-09-19 17:07
config.yaml (714 Bytes) config.yaml 孙乃宇, 2026-09-19 17:08
LO-TTA-03.json (107 KB) LO-TTA-03.json 孙乃宇, 2026-09-19 17:24
clipboard-202609191726-w2bkz.png (3.14 MB) clipboard-202609191726-w2bkz.png 孙乃宇, 2026-09-19 17:26

由 曹晏彬 更新于 大约 2 个月 之前

  • 项目 从 29 变更为 软件开发组

由 孙乃宇 更新于 大约 2 个月 之前

  • 状态 从 新建 变更为 进行中

由 孙乃宇 更新于 大约一个月 之前

由 孙乃宇 更新于 大约一个月 之前

MKS SERVO42C + MKS DLC32 单轴电机整合指南(LO-TTA-03)

从接线到使用,一份可复现的完整手册。
2026-09-19 真机验收通过 · 链路:PC(USB/COM) → MKS DLC32 V2.2 → SERVO42C → 42 步进电机

本文与以下文档配套(都在 configs\ 目录):

  • SERVO42C-点动不转排查.md —— 42C 那个"点动不转"故障的完整排查与结案记录
  • LO-TTA-03-交付清单.md —— 本次整合改了什么、成果物在哪
  • config_LO-TTA-03.notes.md —— config.yaml 的逐字段说明与上传步骤
  • LO-TTA-03\config.yaml —— 待上传到设备的配置文件本体

0. 一句话概览

一块 DLC32(ESP32 主板,跑 FluidNC)接收上位机指令,产生 Stp/Dir 脉冲;
一个 SERVO42C(驱动板,装在电机后轴)把脉冲变成电机转动。上位机通过 USB 串口控制 DLC32。

┌──────────────┐  USB(CH340)   ┌─────────────────┐  Stp/Dir/En   ┌──────────────┐
│  PC 上位机    │ ────────────▶ │ MKS DLC32 V2.2  │ ────────────▶ │ MKS SERVO42C │
│ (jiahe-agg)  │  115200 8N1   │ FluidNC (GRBL)  │  12~24V 共地   │  (开环模式)   │
└──────────────┘               └─────────────────┘               └──────┬───────┘
                                                                            │ A+/A-/B+/B-
                                                                            ▼
                                                                      ┌──────────┐
                                                                      │ 42 步进电机│
                                                                      └──────────┘

软件分四层,各管各的(改一层不影响另一层):

层 是什么 在哪 什么时候要动
设备固件 FluidNC v4(GRBL 方言) DLC32 板内 基本不动
设备配置 config.yaml DLC32 的 LittleFS 换电机/改机械参数时
驱动层 fluidncdll.dll Industrial_ui\device\ 平台侧包装层,本次未改
厂商层 FluidNC.dll(源码 D:\workspace\FluidNC_API) 同上 本次重编过(修点动)
平台配置 LO-TTA-03.json Industrial_ui\src\json\ 新增型号时
驱动器参数 42C 的屏幕菜单 42C 板内 换驱动板/复位后

1. 硬件清单

件 型号 / 规格 说明
主板 Makerbase MKS DLC32 V2.2 ESP32,激光雕刻机控制板,固件 FluidNC v4.x
驱动器 MKS SERVO42C 闭环步进驱动板,装在电机后轴;本次按开环(CR_OPEN)使用
电机 42 步进(NEMA17),1.8° 200 步/圈
编码器磁铁 径向充磁,装在电机后轴端 42C 套装自带;装错/丢失会报 Magnet Loss!
电源 12~24V 直流(≥9V) 42C 工作范围;别把 5V 接进 V+
绝缘材料 绝缘胶带 / 绝缘垫片(或加高尼龙柱) ★ 必需:板子与电机外壳之间要隔离,否则短路(见 2.1)
USB 线 Type-C 或 Micro-USB(视板子版本) 板载 CH340,本机枚举为 COM15
无线(可选) 板内 WiFi AP,SSID FluidNC,192.168.10.123 改设备配置用;本项目走 USB 串口

2. 接线

2.1 ★★★ 第一步:把驱动板装到电机上 —— 必须做绝缘隔离

这是装机的第一个动作,别跳过。 装完再接线,顺序反了要拆。

风险(实测踩到):

  • 42C 靠**四个垫脚(铜柱)**架在电机后端面上;
  • 但电机端面上螺丝孔的位置是凹陷的 ⇒ 垫脚高度不够;
  • 结果电路板背面的针脚 / 焊点会顶到电机底部的金属外壳 ⇒ 短路
    (轻则上电不启动,重则烧板)。

做法:

  • ★ 在板子与电机外壳之间加一层绝缘隔离:绝缘胶带(Kapton / 电工胶带)、绝缘垫片、
    或换更高的尼龙柱垫高,都可以;
  • ★ 别用金属垫片 / 金属柱替代 —— 那等于没做;
  • 隔离层要平整,别挡住编码器磁铁(磁铁在轴端,见 2.6),也别把板子顶得离轴端太远;
  • 装完用万用表蜂鸣档量一下:V+、Gnd、相线等关键点对外壳不应导通;
  • 四个螺丝拧到位但别压板(压板同样会把焊点顶到外壳上)。

2.2 总览

42C 绿色端子 接到 DLC32 必要性
V+ VIN(12~24V) 必接
Gnd G 必接(电源地)
Com Vcc 建议接
Stp STP(丝印可能是 S) 必接
Dir DIR(丝印可能是 D) 必接
En EN(丝印可能是 E) 接不接都行(见 2.4)

★ DLC32 的轴端子是 4 针(G/D/S/E 一类丝印),而 42C 要接 6 根 ——
其中 Gnd 和 Com 都要落到主板的 G 上。用一个端子压两根线,或用一分二端子。
具体丝印顺序以你手上板子的实物为准,按字母含义对接即可(G=GND、S=Step、D=Dir、E=Enable)。

2.3 电源

  • V+ 接 12~24V 直流(可从主板的 VIN 取电,也可独立电源)。
  • Gnd 必须与主板共地——不共地则脉冲信号没有参考电平,表现为"发脉冲完全没反应"。
  • ⚠️ 大电流(Ma 设到 1A 以上)时建议独立电源供电、只共地,避免主板供电轨过载。
  • ⚠️ 适配器的 5V 不要接 V+(会欠压,42C 工作下限是 9V)。

2.4 脉冲信号(42C ↔ DLC32)★ 最容易出错的一段

四个坑,按顺序避开:

① Com 的极性要和主板的脉冲极性匹配

  • Com=VCC → 共阳 → 低电平有效
  • DLC32 的 STP/DIR 是 3.3V 高有效脉冲 → 所以优先接 Com=G(共阴)
  • 接反的后果:光耦长期导通,看不到有效的脉冲边沿 ⇒ 发脉冲不转
  • 手册允许 Com 接 VCC / G / 悬空三种,先试共阴

② En 引脚 —— 建议直接设 En=Hold 绕开它

  • GRBL 主板的 EN 脚常常悬空或常高,而 42C 出厂默认 En=L(低有效)
  • 两者一撞,驱动器一直处于"未使能" ⇒ 现象同样是"发脉冲不转,且不报错"
  • 解法:42C 菜单里把 En 设为 Hold(一直使能),此后 EN 引脚接不接都不影响

③ Mode 不能是 CR_UART

  • CR_UART 模式下 Stp/Dir 被完全忽略,脉冲接得再对也不会转
  • 本机最终用的是 CR_OPEN(详见第 3 节)

④ DLC32 侧的 step_pin / direction_pin 要与实际接线一致

  • 本机配置(config.yaml):step_pin: i2so.1 / direction_pin: i2so.2 / shared_stepper_disable_pin: i2so.0
  • i2so.* 是 DLC32 的 I2S 扩展 IO(板载 74HC595 移位寄存器),不是 ESP32 直连 GPIO
  • ⚠️ $GD(查 GPIO 电平)看不到 I2SO 扩展脚,别用它判断脉冲是否发出

2.5 电机相线

  • 42C 端子 A+ / A- / B+ / B- → 电机四根相线,按颜色/丝印对应。
  • 接错的判据:跑 CAL 校准时电机只抖动、不整圈转 ⇒ 相线线序错,改成 A+/A- 对调或 B+/B- 对调。
  • 跑 CAL 能正反转各一整圈,就证明驱动级 + 相线 + 编码器 + 磁铁整条链路都是好的。

2.6 编码器(磁铁安装)

  • 42C 板上是 MT6816(14 位磁编码器),芯片正对电机后轴端。
  • 电机后轴端要装 径向充磁的磁铁;轴向充磁会报 Magnet Loss!。
  • 磁铁与芯片间距建议 1~2mm,且尽量同心。
  • ⚠️ 本次按**开环(CR_OPEN)**使用,运行时不依赖编码器;
    但 CAL 校准仍会用到它,所以磁铁还是要装好。

2.7 USB 串口

  • 主板 → PC,板载 CH340,本机枚举为 COM15,参数 115200 8N1。
  • 该串口既是"控制通道"(平台走它),也是"调试通道"(串口助手发 $ 命令)。
  • ★ 开关串口不会复位主板(实测重连后 MPos 保留)⇒ 平台可以放心重连。

2.8 上电前检查清单

  • ★ 驱动板与电机外壳之间已做绝缘隔离,并已用万用表确认关键点对外壳不导通(见 2.1)
  • V+ = 12~24V(不是 5V)
  • 42C Gnd 与主板 G 共地
  • Com 接 G(共阴)
  • Stp/Dir 已接到对应端子(丝印确认过)
  • 电机四根相线接好
  • 编码器磁铁已装、径向充磁、间距 1~2mm
  • 42C 菜单 Mode 已确认为 CR_OPEN(不是 CR_vFOC,更不是 CR_UART)

3. 42C 驱动器配置

3.1 ★ 菜单项变少 = 没识别到编码器磁铁(不是 Mode 的差别)

★★ 更正(2026-09-19):早前记录的"某模式下菜单被锁死、只剩两项",
真因是当时 42C 没有识别到编码器磁铁,与 Mode 无关。
磁铁被识别到之后,CR_OPEN / CR_vFOC / CR_UART 三个模式的菜单都是齐全的。

状态 屏幕菜单长相
已识别到编码器磁铁 ★ 三个模式的菜单都齐全 —— MotType / Mode / MStep / Ma / En / Dir / CAL / UartBaud / UartAddr / Protect / MPlyer / ACC 等都在
未识别到编码器磁铁 菜单项明显变少(曾观察到只剩 MotType + Mode)⇒ 去查磁铁,别去改 Mode

⇒ 现场判据:菜单项少 ⇒ 先确认磁铁有没有被识别到(安装要求见 2.6):

  1. 屏幕是否报 Magnet Loss! / Magnet Error!;
  2. 磁铁是否径向充磁、是否同心、与芯片间距 1~2mm;
  3. 用串口 e0 30 手转电机轴,看编码器值是否在 0~FFFF 间连续变化
    (恒 0 / 不动 ⇒ 磁铁问题坐实)。

★ 所以不要用"菜单项数"去判断当前 Mode(它反映的是磁铁识别状态)。
看 Mode 就直接进菜单找 Mode 那一项。
★ 本次整合同样要求 Mode 最终落在 CR_OPEN,理由见 3.3。

3.2 本机参数快照(换板 / 复位后照此设回)

参数 值 说明
Mode CR_OPEN ★ 本次整合最关键的一项
MotType 1.8° 由"3200 脉冲 = 1 圈"反推自洽
MStep 16 与 FluidNC 侧 steps_per_mm = 3200 对应
Ma 800~1200mA ★ 开环下电流恒定,发热只由它决定
En Hold 一直使能,绕开 EN 引脚电平问题(出厂默认 L)
Protect Enable 开环没有丢步保护,靠堵转保护兜一层
MPlyer Enable(默认) 内部 256 细分插补,低速更静
UartBaud 38400(本项目不用串口控制,可不管) 出厂默认 Disable

3.3 ★★★ 为什么必须用 CR_OPEN 而不是 CR_vFOC

这是本次整合踩得最深的一个坑,结论先行:

把 Mode 从 CR_vFOC(闭环)改成 CR_OPEN(开环),故障全部消失。

改之前的表现(四个症状会同时出现):

症状 说明
发脉冲电机不动,但 42C 屏幕数字在变 驱动器收下了脉冲,但没把它变成运动
改完 CR_OPEN 之前,运动一次就锁死 位置环饱和,只有复位能清
明显电流声 + 电机烫手 闭环在"较劲",电流顶到上限
上位机控制完全无效 脉冲进了驱动器,但没出力

根因链:CR_vFOC 的位置环失效 ⇒ 误差不收敛(屏幕 err 卡在 17.99 不动)
⇒ 电流灌满线圈 ⇒ 嗡响 + 发热 + 锁死。开环不依赖反馈,脉冲直接被当作步进指令执行,所以正常。

★ 一个极具迷惑性的判据:CAL 校准永远正常(正反转各一圈),
这让"驱动器是好的"看起来成立。但 CAL 不走位置环(它只是强制正反转做电角度对齐),
所以 CAL 正常证明不了位置环正常。 详见 SERVO42C-点动不转排查.md。

开环的代价(要接受的取舍):

项 说明
没有丢步保护 开环不看编码器,丢步不会报错
电流恒定 Ma 设的就是运行电流,不会随负载自动降
没有堵转自动保护 除非开 Protect
✅ 好处 不依赖编码器/电角度对齐,绕开了本次故障,最简单最稳

若将来对定位精度/丢步有硬要求,再按 SERVO42C-点动不转排查.md 第二节去修闭环
(顺序:Restore → 重新上电 → 重设参数 → 空载重跑 CAL → 验收)。

3.4 ★ 屏幕三行读数的真实含义(别读错)

42C 主界面显示三个数:

显示 真实含义 怎么用
角度(如 359.9°) ★ 驱动器的内部「命令位置」,不是电机真实转角 手转电机轴时它不变 —— 所以它变了只说明"命令走完了",不能证明电机转了
err(如 17.99) 位置角度误差,单位 182.444 / 度 ★ 只有它能反映闭环好坏:卡住不收敛 = 闭环在较劲
clk(如 3.2K) 输入累计脉冲数,由 Stp 引脚直接累加 ★ 与电机是否出力无关;正好 +3200 就证明脉冲通路完全正确

★ 实测验证方法:上电后用手转电机轴 —— 如果 角度 不变而 err 变了,就印证了上表。
★ 另一个关键点:clk 在看脉冲,角度 在看命令,只有 err 才在看在闭环。


4. DLC32 设备侧配置(config.yaml)

4.1 完整文件(待上传的那份)

board: MKS DLC32 (Single Axis)
name: LO-TTA-03
stepping:
  engine: I2S_STATIC
  idle_ms: 255
  pulse_us: 4
  dir_delay_us: 0
  disable_delay_us: 0
  segments: 12

axes:
  shared_stepper_disable_pin: i2so.0
  shared_stepper_reset_pin: NO_PIN
  x:
    steps_per_mm: 3200
    max_rate_mm_per_min: 60.0
    acceleration_mm_per_sec2: 3.0
    max_travel_mm: 1000.0
    soft_limits: false
    motor0:
      stepstick:
        step_pin: i2so.1
        direction_pin: i2so.2
start:
  must_home: false
  check_limits: true
arc_tolerance_mm: 0.002
junction_deviation_mm: 0.01
verbose_errors: true
report_inches: false
use_line_numbers: false
planner_blocks: 16

i2so:
  bck_pin: gpio.16
  data_pin: gpio.21
  ws_pin: gpio.17

4.2 关键字段

字段 值 怎么定
name LO-TTA-03 机器名,$I 会回显 [MSG:Machine: LO-TTA-03]
steps_per_mm 3200 = 一圈脉冲数 ÷ 导程(mm) × 传动比 = (200×16) ÷ 1 × 1
max_rate_mm_per_min 60.0 = 1mm/s。★ jog 的 F 会被它钳位(实测 SPAxisSpeed 恒为 1.000)
acceleration_mm_per_sec2 3.0 越大越干脆;太大会丢步。本机 3 意味着加速到 1mm/s 要 0.33s
max_travel_mm 1000.0 ★ 软限位关闭时它只是声明值,拦不住运动
soft_limits false 见第 9 节"已知局限"
start.must_home false 本机没有限位开关、也不回零

★ steps_per_mm = 3200 的推导:42C 实测 MStep = 16,1.8° 电机
⇒ 一圈脉冲 = 200 × 16 = 3200;当前裸电机、导程按 1mm、传动比 1 ⇒ 3200 ÷ 1 × 1 = 3200。

★ 由此得到一个不用卡尺的验证法:3200 步/mm 且 3200 脉冲/圈 ⇒ 1mm = 电机转 1 圈。
所以发"走 10mm",电机应该正好转 10 圈,数圈数即可。

4.3 ★★★ 上传方法(唯一持久路径)

核心事实:串口 $ 写入不持久,只有改文件才作数。

实测证据($ESP444=RESTART 重启验证):

写入方式 立即生效 重启后
$axes/X/steps_per_mm=3200 ✅ 回读 3200 ❌ 回到 6400
$Name=LO-TTA-03 ✅ $I 立刻报新名 ❌ 回到旧名
$110=3200(Grbl 编号) ❌ 报 error:162 Read-only setting,是只读视图
$Config/Save 等 6 个候选 ❌ 全部 error:3 Invalid $ statement,根本没有"保存"命令
改 config.yaml 文件 + 重启 ✅ ✅ 唯一持久路径

上传步骤(WiFi WebUI):

  1. 电脑连上这块 DLC32 的热点:SSID FluidNC(设备 IP 192.168.10.123)
  2. 浏览器打开 http://192.168.10.123/
  3. 顶部标签切到 FluidNC(面板标题 FluidNC Settings)
  4. 工具栏点 Manage local files → 弹窗 FluidNC Local Filesystem
  5. ★ 上传 configs\LO-TTA-03\config.yaml 到 /
    —— 文件名必须就叫 config.yaml!
    WebUI 上传是用本地文件名当设备端路径的,传 config_LO-TTA-03.yaml
    只会多出一个新文件,不会覆盖开机读的那份,你会以为"改了没生效"
  6. 工具栏点 Restart FluidNC 重启

不想用 WiFi:固件也有整套文件 API,串口就能做:
$LocalFS/List / $LocalFS/Show=/config.yaml / $LocalFS/Backup =path / $Xmodem/Send

复核(三者应一致,且再重启一次确认不回退):

$I                              → 看 [MSG:Machine: LO-TTA-03]
$LocalFS/Show=/config.yaml      → 看磁盘文件原文(权威值)
$axes/X/steps_per_mm            → 看生效值(应为 3200.000)

5. 平台侧配置

5.1 LO-TTA-03.json

位置:D:\workspace\Industrial_ui\src\json\LO-TTA-03.json

以 LO-TTA-01.json 为底稿,实测只有 10 处差异:

# 位置 旧值 → 新值
1 queryJson.SPQuery lobll75 → fluidnc ★★★ 最关键
2–8 checkJson[*].model ×7 LO-ALN100-2 → LO-TTA-03
9 attribute[1].value(开环步数) 4000 → 3200
10 attribute[6].value(细分) "20" → "16"

★ 第 1 条是本质区别:SPQuery 是"用哪个设备驱动"的键,与 DLL 目录名一一对应:

SPQuery 实际加载
fluidnc fluidncdll.dll(+ 厂商层 FluidNC.dll)
lobll75 Lobll75dll.dll
mcc mccdll.dll
cam camdll.dll
weightcell WeightCellDll.dll

⇒ LO-TTA-01 走 Lobll75dll;LO-TTA-03 改走 fluidncdll。
这就是"本次没有新增 DLL 模块、复用 fluidncdll"的物证。

5.2 让型号出现在前端下拉列表

前端下拉读的是登录用户目录下 info.json 的 configData[]。
新型号要能被选中,需把它登记进去(脚本:Industrial_ui\register_tta03.py,幂等、自动备份)。

⚠️ 服务端同步资源时可能覆盖 info.json,届时重跑该脚本。
⚠️ 前端需重启应用才能看到新下拉项。

5.3 DLL 层:版本与位置(四处,务必对齐)

位置 作用 应是什么
D:\workspace\FluidNC_API\bin\x64\Release\FluidNC.dll 编译产物(源头) 9f9575a4(202752B)
D:\workspace\Industrial_ui\device\ 平台运行目录 FluidNC.dll=9f9575a4,fluidncdll.dll=5b10aee3
D:\workspace\Industrial_ui\needCopyDependence\device\ ★ 打包源(vue.config.js 里 from: "needCopyDependence/") 同上,发版前必须同步
D:\workspace\Industrial_ui\dist_electron\win-unpacked\device\ 上次打包输出 重新打包会自动覆盖,不用手工维护

★ 这两个 DLL 必须成对更新:fluidncdll.dll 是平台按 SPQuery 加载的入口,
它隐式链接 FluidNC.dll(协议层)。只换一个会让入口指向不匹配的依赖。

★ 换运行目录里的 DLL 时:必须先停平台(DLL 被进程锁定,否则复制会失败)。
打包源目录可以随时改。

★ 发布链路的关键:vue.config.js 会把 needCopyDependence\ 整目录复制进安装包。
本机跑得再好,这个目录是旧的,客户装完就是坏的——现场极难查。


6. 使用

6.1 开机顺序

  1. 上电(42C 和 DLC32 通常同一路电源,一起上电)
  2. 42C 屏幕显示 0 / 0.0 / 0 三行初值,无报错
  3. PC 上启动平台(lier-ws-proveder.exe)
  4. 平台里打开设备

6.2 平台侧打开设备(测试脚本路线)

cd D:\workspace\jiahe-agg\fluidncdll
python test_fluidnc.py --refresh     # SPRefrensh=1,热重载 device/ 目录
python test_fluidnc.py --open        # SPOpen "com15-fluidnc"
python test_fluidnc.py --probe       # 打印原始广播帧,核对字段
python test_fluidnc.py               # 只读监控

★ 顺序很重要:先 --refresh 再 --open。 直接 SPOpen 曾出现"成功但几秒后平台自行关闭设备",
补一次 SPRefrensh 后广播稳定。

★ 平台进程要用后台常驻方式启动;& 挂在前台 shell 里会随 shell 退出被杀。
停进程:MSYS_NO_PATHCONV=1 taskkill /F /IM lier-ws-proveder.exe

其他可用动作:

python test_fluidnc.py --rel 2        # 相对定位 +2mm
python test_fluidnc.py --abs 0.5      # 绝对定位到 0.5mm
python test_fluidnc.py --stop         # 缓停
python test_fluidnc.py --estop        # 急停
python test_fluidnc.py --setpos 0     # 置位
python verify_jog_fix.py + 6 1        # 点动 6s @1mm/s(按帧记录,判速率/连续性)
python verify_stop_ab.py 2.5 1        # 缓停 vs 急停 A/B 对照

6.3 指令映射表(平台积木块 → 底层动作)

平台动作 normal_data.name 落到 GRBL
急停 SingleEmergencyStop velocityStop(0x85) + $ES
缓停 SingleStop velocityStop(0x85) + !
调整位置(置位) Reset $MPos=x<值>
点动 / 定速 SingleToSpeed 长 $J + 0x85 停止(见第 9 节)
相对定位 SingleToPosition + ModeType=1 $J=G91 X<d> F<feed>
绝对定位 SingleToPosition + ModeType=2 $J=G90 X<t> F<feed>
回零 ToHome $H

单位约定:JSON 的 Speed 是 mm/s(DLL 里 ×60 变成 GRBL 的 F/mm-min);Distance 是 mm。

★ 点动积木块里虽然带 Distance 字段,但底层不读它 ——
点动是"按住走、松开停",靠同一积木块的 stop.actions[0] = SingleStop 收尾。
不要试图用 Distance 限制点动行程,它没有作用。


7. 验收标准

7.1 三步验收(本机,随时可复测)

① 单点动 1mm

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

② 连走 10mm:$J=G91 X10 F60 → MPos 增量 +10.000mm,用时约 10.7s(≈1.02mm/s,与 F60 吻合)。

③ 平台层点动:verify_jog_fix.py + 6 1 → 位移 +6.100mm 左右,逐帧位移连续单调、无反向跳变。

7.2 两个不用卡尺的判据

  • 数圈数:设 3200 步/mm 时 1mm = 1 圈 ⇒ 走 10mm 电机转 10 圈
  • 看 clk:走 1mm 必然 +3200,分毫不差就说明脉冲通路完全正确

★ ⚠️ MPos 读数自洽不能证明物理位移:MPos = steps ÷ steps_per_mm 用同一个常数反算,
"相对定位 +2.000 精确"是恒等式,不是验证。要证明物理位移只能用卡尺或数圈数。


8. 故障排查速查

症状 最可能的原因 怎么处置
发脉冲电机不动,但 42C 屏幕数字在变 ① Mode 是 CR_vFOC(闭环坏)
② En 未使能
③ Mode 是 CR_UART
改 CR_OPEN(优先);En 设 Hold;确认不是 CR_UART
屏幕数字根本不变 脉冲没进来:Stp/Dir 接错、没共地、Com 极性反 查接线;Com 接 G(共阴)
电机只抖动不转 相线线序错 A+/A- 或 B+/B- 对调
屏幕报 Magnet Loss! 编码器磁铁缺失 / 轴向充磁 换径向充磁磁铁,间距 1~2mm
屏幕报 Phase Line Error! 电机线序错 检查相线
屏幕报 Not Cal 未校准 空载跑 CAL
屏幕报 Wrong Protect Enter.. 堵转保护触发 按 Enter 解除;检查是否卡住
电流声大 + 烫手 闭环在较劲(err 不收敛) 改 CR_OPEN;开环下若还烫 ⇒ 降 Ma
转一次就锁死 位置环饱和 改 CR_OPEN;或复位
改的配置重启后失效 只用了串口 $ 写入(只改 RAM) 必须改 config.yaml 文件并重启
平台报 -2147483387 / -3000453,广播 axis_stutus: [] 平台已判定设备断开并关闭 重跑 --refresh + --open 恢复
串口发 $ 命令毫无响应 串口被占用 / 设备离线 先跑 probe_ports.py 确认在线

★ 怀疑设备是否在线,先跑 probe_ports.py(枚举注册表串口并逐个探测)。
★ 蓝牙调制解调器口(\Device\BthModem*)打开就会卡住,探测时要跳过。


9. 已知局限与取舍(用之前要知道)

9.1 长按点动超过 20 秒,会有一个"接缝"

修好后的点动方案是发一条长 $J(≈20 秒行程)+ 实时字节 0x85 停止,
跑完一段会续接下一段。段与段之间必然有个过渡:

指标 实测(45 秒点动)
总位移 +44.250mm(期望 45.000,缺口 0.75mm ≈ 2 次接缝)
接缝处速度 从 1.000 掉到 0.450(45%)
接缝持续 ≈1.0 秒

成因:① 上一段 $J 自然减速跑完 → ② 平台状态缓存(≤100ms 滞后)报 IDLE
→ ③ 新段 $J 重新加速(accel=3mm/s²,到 1mm/s 要 0.33s)。

  • 短按(< 20 秒)完全碰不到,日常"按住找位置"无影响
  • ⚠️ 相对/绝对定位不走这条路,是单条 $J,没有接缝问题
  • 若确实需要长时间连续恒速且不能有速度波动,可考虑把
    FluidNC_API\src\VelocityController.cpp 里的 HOLD_SEC(现 20s)调大后重编
    —— 但它是安全上限(防上位机崩了无界走),调大要配合限位保护

9.2 开环没有丢步保护

CR_OPEN 不看编码器,丢步不会报错。负载轻(纯电机/后续接位移台)一般可接受;
要硬保证就开 Protect 堵转保护,或回去修闭环。

9.3 软限位关闭 = 没有软件保护

本机 soft_limits: false,且 must_home: false、没有限位开关、不回零
⇒ MPos 只是"上电以来"的相对坐标,soft_limits: true 也不是可靠保护(MPos 本身可能是任意值)。

实际可行的保护手段:

  • 小行程轴把 MAX_CHUNK_MM(现 3000)调小
  • max_travel_mm 填真实行程
  • 操作上留足余量

9.4 速度被 max_rate 钳位

max_rate_mm_per_min = 60 ⇒ 无论指令给多少 mm/s,实测速率上限就是 1mm/s
(SPAxisSpeed 恒为 1.000)。判速率要拿 SPAxisSpeed 实测值当基准,
别拿指令速度当期望值,否则会把设备限速误判成驱动故障。

9.5 平台广播的位置有约 0.9s 滞后

把"下发停止指令那一刻读到的位置"当基准去量过冲,会把滞后算成过冲。
过冲/拖尾只用"起始 → 停稳的总位移"来量。


10. 附:命令与参数速查

10.1 FluidNC 串口命令(COM15 @115200)

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

10.2 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 80 00 60 校准编码器(=菜单 CAL),必须空载
e0 81 电机类型 MotType 00=0.9° 01=1.8°(改后必须重校准)
e0 82 工作模式 CtrMode 00CR_OPEN 01CR_vFOC 02CR_UART
e0 83 电流档 Ma 06=1200mA 0F=3000mA
e0 84 细分 MStep 1~256(本机 = 16)
e0 85 En 有效电平 00L 01H 02Hold
e0 88 堵转保护 Protect
e0 3f 1f 恢复默认参数(需重新上电)
e0 a1/a2/a3 位置环 Kp / Ki / Kd(无菜单项)
e0 a4/a5 加速度 ACC / 最大扭矩 MaxT(MaxT 无菜单项)

★ 42C 串口是板上 4pin 3V3/G/T/R(不是右边绿色端子),接线要交叉 + 共地:
TXD→R、RXD→T、GND→G、3V3 不接。8N1,关流控。
★ 出厂默认 UartBaud=Disable ⇒ 板子对串口全程静默,必须先设波特率。

10.3 常用测试脚本(D:\workspace\jiahe-agg\fluidncdll\)

脚本 用途
test_fluidnc.py 平台 WS 客户端:--refresh / --open / --probe / --rel / --abs / --stop / --estop / --setpos / --jog
verify_jog_fix.py ★ 按广播帧采样,判点动速率/连续性/是否掉线
verify_stop_ab.py ★ 缓停 vs 急停 A/B 对照
probe_ports.py ★ 枚举串口并逐个探测(怀疑掉线先跑这个)
test_enable.py 4 步现场判定:判使能 → clk 增量 → 判 Stp/Dir 接反 → 看角度/err
axis_params.py 轴参数在线读写 + 卡尺标定(calib 10 <实测mm> --apply)
check_jogcancel.py 裸串口校验「长 $J + 0x85」方案(不占平台)
dump_config.py COM15 抓 $Config/Dump + 关键 $$

★ 裸串口脚本一律复用 check_jogcancel.py 里的 Raw 类(ctypes 直调 kernel32,不需要 pyserial)。
★ Raw 必须设 COMMTIMEOUTS,否则 ReadFile 在没有数据时会无限阻塞,
read_for(ms) 的时限形同虚设(已修:ReadIntervalTimeout=10ms + ReadTotalTimeoutConstant=25ms)。
★ Raw.read_for() 直接返回 str,不要再 .decode()。


变更记录

日期 内容
2026-09-19 首版。42C 改 CR_OPEN 结案;FluidNC.dll 点动修复(长 $J + 0x85);LO-TTA-03.json 新增;config.yaml 就绪待上传;打包源 DLL 同步完成
2026-09-19 修订:3.1 重写 —— 菜单项变少的真因是未识别到编码器磁铁(与 Mode 无关;识别到后三个模式菜单都齐全);新增 2.1 驱动板安装绝缘隔离(原 2.1~2.7 顺延为 2.2~2.8,同步修正交叉引用与检查清单)
行为

导出 Atom PDF