2、G代码基础:G代码与M代码的语法、坐标系统、单位、进给率、温度与运动命令的解析
在Klipper固件环境中,G代码(RS-274)是3D打印机最底层的控制语言。无论是切片软件生成的打印文件,还是通过终端手动发送的调试指令,最终都会以G代码行的形式被Klipper解析并转化为步进电机的脉冲、加热棒的PWM占空比以及风扇的转速。理解G代码的语法结构、坐标系统、单位制以及关键命令的语义,是编写宏指令、排查打印异常、优化运动控制参数的先决条件。本章将系统拆解G代码的核心要素,并重点说明Klipper与标准Marlin固件在解析上的细微差异。
2.1 G代码语法结构与解析规则
核心原理:词法单元与地址字
每一行G代码由若干地址字(Address Word)组成,每个地址字由一个英文字母(A-Z)后跟一个数值(可带正负号和小数点)构成。字母代表命令类型或参数类型,数值代表该参数的值。例如 G1 X10.5 Y20.3 E1.5 F1800 中,G 是准备功能(Preparatory Function),1 表示线性插补;X、Y 是目标坐标轴;E 是挤出轴;F 是进给率。Klipper 的解析器会从左到右扫描,忽略大小写,并将分号(;)之后的内容视为注释。与 Marlin 不同,Klipper 对未定义的地址字会直接报错,而不是静默忽略,这有助于提前发现切片配置错误。
判断方法:命令分类与模态/非模态
G代码命令分为模态命令(Modal)和非模态命令(Non-modal)。模态命令一旦执行,其效果会持续到被同组的另一个命令替换为止。例如 G90(定位)和 G91(相对定位)属于同一模态组,发送 G91 后,后续所有坐标解释都变为相对模式,直到发送 G90。非模态命令如 G28(回原点)只影响当前行。Klipper 的宏系统([gcode_macro])允许你自定义命令,但必须遵循同样的词法规则。在编写宏时,建议显式声明模态状态,避免依赖上一次执行留下的状态。
G0 和 G1 在运动控制上完全等价(均使用最大加速度和速度规划),但在语义上 G0 通常用于非挤出移动。切片软件有时会交替使用,Klipper 不会区分,但宏中建议保持语义清晰。
案例拆解:解析一行实际打印命令
假设切片软件输出以下命令:
G1 X127.2 Y104.8 E0.762 F2400 ; 外壁移动
解析过程如下:
- G1:线性插补,目标点为 (127.2, 104.8)。
- E0.762:挤出量增加 0.762mm(若配置了挤出机截面积,则为 0.762mm³)。
- F2400:进给率 2400 mm/min(即 40 mm/s)。
- Klipper 会将此命令加入运动队列,并根据
max_accel和max_velocity计算实际运动曲线。
若在终端手动发送 G1 X127.2 Y104.8 E0.762 F2400,但当前挤出机温度低于冷挤出保护阈值(默认 min_extrude_temp),Klipper 会拒绝执行并报错 Heater extruder not hot enough。这是常见的初学者困惑点。
常见误区与总结
- 误区:认为
G0比G1快。实际上在Klipper中两者速度规划完全一致。 - 误区:忽略注释中的分号。分号后的内容不会被解析,但若分号出现在字符串中(如
M117 Hello;World),Klipper 会截断为M117 Hello。 - 复盘:在宏中尽量使用
G90和G21开头,确保坐标和单位状态可预测。
2.2 坐标系统与单位制
核心原理:机床坐标、工作坐标与相对坐标
3D打印机的坐标系统分为三层:机床坐标系(Machine Coordinate System, MCS) 是物理原点(通常由限位开关决定);工作坐标系(Work Coordinate System, WCS) 是切片软件设定的打印起点,通过 G54 或 G92 偏移实现;相对坐标 则是以当前点为原点。Klipper 默认使用坐标(G90),但切片软件可能在首层使用 G91 进行相对移动(如 G91 G1 Z0.2 抬升0.2mm)。单位制方面,G21 设置毫米,G20 设置英寸。Klipper 的配置文件 [printer] 段中的 kinematics 选项决定了坐标如何映射到步进电机(如 cartesian、corexy、delta)。
操作流程:设置工作偏置与原点
- 开机后执行
G28回原点,建立机床坐标系。 - 若使用探针(BLTouch),执行
G29或BED_MESH_CALIBRATE生成网格补偿。 - 切片软件通常在 G 代码开头发送
G92 E0将挤出轴清零,然后G1 Z0.2 F300移动到首层高度。 - 若需手动调整Z偏移,使用
SET_GCODE_OFFSET Z=0.05或G92 Z0.1临时修改。
案例拆解:首层坐标偏移问题
某用户打印时发现模型整体向X轴正方向偏移5mm。检查切片G代码开头:
G28 ; 回原点
G1 Z5 F3000 ; 抬升
G92 E0 ; 清零挤出
G1 X5 Y5 F3000 ; 移动到起点
问题在于 G1 X5 Y5 是坐标,但用户之前手动发送过 G91 且未切换回 G90。Klipper 保留了模态状态,导致该命令被解释为相对移动。解决方法是切片软件开头强制添加 G90。此案例说明模态命令的“粘性”是排障时首要检查项。
常见误区与总结
- 误区:混淆
G92与G54。G92是临时偏移,重启后失效;G54是持久工作偏置,需在配置中定义。 - 误区:在Klipper中使用
M206(Marlin的坐标偏移)无效,应使用SET_GCODE_OFFSET。 - 总结:单位制错误会导致打印尺寸偏差10倍(毫米/英寸混淆),务必在切片机中设置公制输出。
2.3 进给率与运动命令解析
核心原理:F值的含义与运动规划
进给率 F 的单位是 mm/min(毫米/分钟),但切片软件常以 mm/s 表示速度。Klipper 内部将 F 值转换为 mm/s 用于运动规划。例如 F1800 等于 30 mm/s。运动命令 G1 会触发Klipper的轨迹前瞻(Lookahead)机制:它不会立即执行,而是进入缓冲区,由运动控制器根据 max_accel、max_velocity 和 square_corner_velocity 计算平滑的速度曲线。这意味着即使你发送 G1 F3000,实际最高速度也可能被 max_velocity 限制。
判断方法:区分速度限制与加速度限制
当打印出现“ ringing ”(振纹)时,通常不是 F 值过高,而是加速度 max_accel 设置过大。Klipper 的 TUNING_TOWER 命令可以辅助测试不同加速度。另外,G1 命令中的 F 值只影响当前运动段,若后续命令未指定 F,则沿用上一次的 F 值(模态)。在宏中,建议每次运动都显式指定 F,避免速度突变。
案例拆解:高速打印时的挤出不足
用户设置 F6000(100 mm/s)打印,但出现层间挤出不足。分析:Klipper 的 max_extrude_only_velocity 和 max_extrude_only_accel 限制了纯挤出移动的速度。若切片软件在非挤出移动(如 G0)中设置了高 F,但挤出移动(G1)的 F 值较低,则不会触发限制。然而,若用户手动发送 G1 E10 F6000,Klipper 会报错 Extrude only move too fast。解决方法是调整配置:
[extruder]
max_extrude_only_velocity: 50 # mm/s
max_extrude_only_accel: 500 # mm/s²
此案例说明,理解Klipper的运动学限制比单纯调高 F 值更重要。
常见误区与总结
- 误区:认为
F值越大越好。实际上,加速度限制和电机扭矩决定了实际可达速度。 - 误区:在宏中使用
G4 P200(暂停200ms)时,Klipper 会阻塞解析线程,但运动缓冲仍会执行完之前的命令,可能导致暂停位置不精确。 - 复盘:使用
SET_VELOCITY_LIMIT命令可在运行时动态调整速度限制,适合打印不同特征(如薄壁 vs 填充)时切换。
2.4 温度命令与等待机制
核心原理:M104/M109 vs M140/M190
温度命令分为两组:挤出机(M104 设置,M109 设置并等待)和热床(M140 设置,M190 设置并等待)。Klipper 对 M109 的处理与 Marlin 不同:Marlin 会阻塞所有命令直到温度到达,而 Klipper 的 M109 会阻塞宏解析线程,但运动队列中的命令仍会执行。这意味着如果你在宏中写 M109 S200 后立即 G1 E10,挤出命令可能先于温度到达执行,导致冷挤出。正确做法是使用 TEMPERATURE_WAIT 命令或确保宏中温度等待后无运动命令。
操作流程:安全的温度控制宏
[gcode_macro START_PRINT]
gcode:
# 设置目标温度但不等待
M104 S{params.TEMP}
M140 S{params.BED}
# 等待热床到达
M190 S{params.BED}
# 等待挤出机到达
M109 S{params.TEMP}
# 此时才允许挤出
G92 E0
G1 Z5 F300
注意:M190 在Klipper中会等待热床到达目标温度,但若目标温度低于当前温度,它会立即返回(不降温)。若需降温等待,需使用 TEMPERATURE_WAIT SENSOR=heater_bed MINIMUM=50。
案例拆解:宏中温度等待导致的热失控
用户编写宏:
M104 S210
M109 S210
G1 E5 F300
在Klipper中,M109 阻塞了解析线程,但运动队列为空,所以实际上没有命令执行。然而,如果之前有未完成的运动命令(如 G1 X100),它们会在等待期间执行。若挤出机温度未到,G1 E5 会触发冷挤出保护。更隐蔽的问题是:如果 M109 等待时间过长,加热棒持续全功率加热,可能触发 heater_timeout 保护。Klipper 默认 heater_timeout 为 30 秒,若温度在30秒内未变化,会报错。解决方法是使用 M109 S210 前先检查当前温度,或使用 SET_HEATER_TEMPERATURE 配合 TEMPERATURE_WAIT。
常见误区与总结
- 误区:在Klipper中使用
M109后立即发送G28,回原点命令会等待温度,导致打印启动缓慢。 - 误区:忽略
min_extrude_temp设置。默认值为 170°C,若打印PLA设置190°C,冷挤出保护不会触发,但若设置160°C,则必须等待。 - 总结:推荐在宏中使用
M190等待热床,使用M109等待挤出机,但务必确保等待期间无运动命令。
2.5 知识结构总览与实战复盘
| 命令类别 | 典型命令 | Klipper 特有行为 | 常见错误 |
|---|---|---|---|
| 运动 | G0, G1, G28, G29 | G0/G1 等价;G29 需配置探针 | 未指定 F 导致速度突变 |
| 坐标 | G90, G91, G92, G54 | G92 临时偏移;G54 需配置 | 模态状态未重置 |
| 单位 | G20, G21 | 默认 G21,配置中可强制 | 英寸/毫米混淆 |
| 温度 | M104, M109, M140, M190 | M109 阻塞解析但运动队列继续 | 冷挤出保护触发 |
| 风扇 | M106, M107 | M106 S0 关闭,S255 全速 | PWM 频率不匹配 |
M112(紧急停止)会立即切断步进使能,但不会关闭加热器。若发生热失控,应使用 FIRMWARE_RESTART 或物理断电。切勿在宏中依赖 M112 作为温度保护手段。
本章从语法、坐标、单位、进给率和温度五个维度拆解了G代码的核心机制。Klipper 的解析器严格且高效,但模态命令的“记忆性”和运动队列的异步执行是初学者最容易踩坑的地方。建议在编写宏时,始终以 G90 和 G21 开头,显式设置 F 值,并使用 TEMPERATURE_WAIT 替代 M109 实现更精细的温度控制。下一阶段,我们将深入 Klipper 的宏语法(gcode_macro)与变量系统,将本章的命令知识转化为可复用的自动化逻辑。