Grbl v1.1 激光模式(Laser Mode)完全指南:$32 设置、M3/M4 功率控制原理与安全操作
Grbl v1.1 激光模式(Laser Mode)完全指南:$32 设置、M3/M4 功率控制原理与安全操作
Grbl 在 v1.1 版本中引入的激光模式(Laser Mode),通过复用主轴 PWM 输出(Uno D11 引脚)实现 0–5V 线性激光功率控制,并在连续运动段之间不再因 S 主轴速度变化而停机,从而避免烧灼痕迹与切割不均匀。本文以 doc/markdown/laser_mode.md 为主线,结合 grbl/spindle_control.c、grbl/gcode.c、grbl/stepper.c 等源码,讲解 $32 开关、M3 恒功率与 M4 动态功率两种模式的运行差异、强制同步停机条件、G0/G1/G38 交互行为,以及面向 CAM 与 G 代码生成器的编程建议,帮助你安全、精准地驱动激光切割与雕刻。
免责声明: 激光属于极其危险的设备,可瞬间引发火灾并永久损伤视力。使用前请务必完整阅读并理解你所用激光器的全部相关文档。按 GPL 许可约定,Grbl 项目不对固件可能造成的任何损坏或问题负责。
1. 激光模式概述:为什么激光不能像主轴那样"停一下再走"
默认 Grbl 对主轴的控制逻辑是:每当出现 M3、M4、M5 主轴状态变化或 Sxxx 主轴速度变化,Grbl 都会先让运动完全停止,等待主轴调速完成,再继续执行后续运动——这是铣床主轴的标准操作流程,因为电机需要时间升速/降速。
但对激光器而言,若每一次功率变化都伴随启停,会在工件上留下烧灼(scorching)和切割/雕刻不均匀的痕迹。激光模式的核心目标有两个:
- 尽可能避免非必要停机:在连续运动指令之间更新激光功率时保持连续运动;
- 新增动态激光功率模式:根据当前实际速度相对编程进给率(programmed rate)的比例自动缩放功率,即使机器正在加速、减速甚至低速运行,也能保证单位长度上的激光能量一致,从而在低加速度机器上也能得到干净利落的效果。
1.1 启用/禁用:$32 设置
激光模式的开关就是 Grbl 的 $32 设置(对应 grbl/settings.h 中的 BITFLAG_LASER_MODE,默认值 0,见 grbl/defaults.h):
- 启用:发送
$32=1 - 禁用:发送
$32=0
在 grbl/settings.c 中,设置项 32 的处理逻辑为:当编译时启用了 VARIABLE_SPINDLE(即 PWM 变速主轴)时,$32=1 会置位 settings.flags 中的 BITFLAG_LASER_MODE 位;反之若固件未编译 VARIABLE_SPINDLE,则直接返回错误码 STATUS_SETTING_DISABLED_LASER——对应 doc/markdown/interface.md 错误表里的 error:17 "Laser mode disabled. Requires PWM output."。也就是说,激光模式必须依赖硬件 PWM 输出,这是固件层面的硬性前提。
警告: 如果你从激光模式切回铣削主轴,必须发送 $32=0 禁用激光模式。铣削需要主轴先达到正确转速才能安全切削,否则容易断刀并飞溅金属碎屑。禁用激光模式后,Grbl 会在任何主轴速度或状态变化时短暂停顿,给主轴升速时间。
2. 激光模式运行原理:PWM 输出与功率映射
2.1 0–5V 电压线性控制
启用激光模式后,Grbl 通过 D11 引脚(SPINDLE PWM) 输出 0–5V 电压来控制激光功率:
- 0V 视为关闭;
- 5V 为全功率;
- 中间电压假定与激光功率线性对应,例如 2.5V ≈ 50% 功率。
在 grbl/cpu_map.h 中可以看到这套 PWM 的底层配置:ATmega328P 的 8 位快速 PWM(Fast PWM)模式下,SPINDLE_PWM_MAX_VALUE 固定为 255,SPINDLE_PWM_MIN_VALUE 默认为 1(必须大于 0),SPINDLE_PWM_OFF_VALUE 为 0,功率范围 SPINDLE_PWM_RANGE = 254。SPINDLE_PWM_BIT 定义为 3,对应 Uno 数字引脚 11。
功率换算发生在 grbl/spindle_control.c 的 spindle_compute_pwm_value():它以 $30(rpm_max)和 $31(rpm_min)为上下界做线性映射,pwm_gradient = SPINDLE_PWM_RANGE/(rpm_max - rpm_min),中间值按 pwm_value = floor((rpm-rpm_min)*pwm_gradient) + SPINDLE_PWM_MIN_VALUE 计算。这意味着在激光模式下,G 代码中的 S 值经过 $30/$31 两个设置映射为 PWM 占空比,S0 映射为关闭,S 等于 rpm_max 时映射为全功率。
2.2 PWM 频率:默认 1kHz,可在 cpu_map.h 修改
默认主轴 PWM 频率为约 1kHz(精确值为 0.98kHz,即 16MHz 主频经 1/64 预分频得到),这是大多数 Grbl 兼容激光系统推荐的频率。如需其他频率,可修改 grbl/cpu_map.h 中的 SPINDLE_TCCRB_INIT_MASK 预分频配置:
// #define SPINDLE_TCCRB_INIT_MASK (1<<CS20) // Disable prescaler -> 62.5kHz
// #define SPINDLE_TCCRB_INIT_MASK (1<<CS21) // 1/8 prescaler -> 7.8kHz (Used in v0.9)
// #define SPINDLE_TCCRB_INIT_MASK ((1<<CS21) | (1<<CS20)) // 1/32 prescaler -> 1.96kHz
#define SPINDLE_TCCRB_INIT_MASK (1<<CS22) // 1/64 prescaler -> 0.98kHz (J-tech laser)
注释中可以看到,1/8 预分频对应 7.8kHz(v0.9 曾使用),1/64 预分频对应约 1kHz,即当前默认值。
2.3 非线性功率模型的编译选项
原文档提到"存在一个编译期选项,可将线性模型平移为从非零电压起始"。在 grbl/config.h 中对应 ENABLE_PIECEWISE_LINEAR_SPINDLE 选项:它把主轴 PWM/速度映射改为分段线性曲线,用于转速-电压关系不线性的主轴/激光系统。该选项需要配合仓库 doc/script/fit_nonlinear_spindle.py 脚本采集主轴数据并拟合出分段系数,在 grbl/spindle_control.c 中对应 ENABLE_PIECEWISE_LINEAR_SPINDLE 分支(N_PIECES、RPM_LINE_Ax、RPM_LINE_Bx 等分段拟合参数)。
3. 两种激光模式:M3 恒功率与 M4 动态功率
激光通过 M3(主轴顺时针,恒功率)与 M4(主轴逆时针,动态功率)两个命令开启,两者对同一 PWM 硬件而言代表两种不同的功率控制策略。
3.1 M3 恒定激光功率模式
- 无论机器是运动、加速还是静止,激光功率始终保持在程序设定的值。对编程良好的 G 代码而言,这能在较难加工的材料上获得更一致的切割效果,对激光状态的控制也更直接。
- 为避免烧灼,使用
M3恒功率模式时,建议在目标切割线段的起点和终点附加引入/引出运动(lead-in / lead-out),为机器加速和减速留出空间,避免功率已在目标值而速度尚未跟上导致烧灼。 - 注意:
M3也可以用来在聚焦对位时保持激光常亮。
3.2 M4 动态激光功率模式
- 动态模式根据当前速度相对编程进给率的比例,自动调节激光功率,保证切割路径上激光能量一致,即使机器静止或正在加速也是如此。这对多种 CAM 生成的雕刻/切割任务都很实用,通常运行更快,很可能就是你需要用的那一种。
- 局限性:Grbl 假设激光功率与速度、材料呈线性关系,但现实往往并非如此——不同功率下激光的切割表现不同,某些材料在特定速度/功率组合下无法切透。因此动态模式未必适合所有场景,换新材料或新机器前务必先做测试件。
- 安全特性:
M4模式下机器不运动时激光自动关闭,只有运动时才点亮。这意味着如果中途停下忘记关闭,M4不会像M3那样在桌面上烧穿一个洞——这也是动态模式更安全的根本原因。
源码印证:在 grbl/spindle_control.c 的 spindle_set_state() 中可以看到,当 BITFLAG_LASER_MODE 置位且状态为 SPINDLE_ENABLE_CCW(即 M4)时,代码强制将 rpm 设为 0(注释标注为 TODO,未来可能需要映射到 rpm_min*(100/MAX_SPINDLE_SPEED_OVERRIDE))。这意味着 M4 使能指令本身不点亮激光,点亮与否完全交由运动过程决定。相应地,在 grbl/stepper.c 的步进段预备逻辑中,只有当 pl_block->condition 含 PL_COND_FLAG_SPINDLE_CCW 时,才会预计算 inv_rate = 1.0/programmed_rate 并将 is_pwm_rate_adjusted 置真——这正是 M4 动态功率"按速度实时缩放 PWM"的底层实现:每个步进段内根据当前实际速度更新 PWM 输出,且动态功率运动段总是以激光关闭状态结束(源码注释:"PWM rate adjusted motions will always complete a motion with the spindle off")。
4. 启用激光模式后的运行行为变化
以下行为变化请仔细阅读并充分理解——没有什么比车库里的火灾更糟糕。
4.1 连续运动段之间不停机更新功率
启用激光模式后,Grbl 在连续的运动指令之间遇到新的 S 主轴速度(即激光功率)时,会持续运动,并在每个运动中瞬时更新 PWM 引脚,不会停止。例如下面这组 G 代码,在激光模式启用时每行之间不会停顿,而在禁用时会停顿:
G1 X10 S100 F50
G1 X0 S90
G2 X0 I5 S80
在 grbl/gcode.c 的执行阶段,GC_PARSER_LASER_ISMOTION 标志位决定了 S 变化是否需要调用 spindle_sync()(强制同步/停机):只要当前行包含轴字且处于运动模式,功率变化就随运动即时生效而无需停机;只有非运动行才走 spindle_sync() 同步路径。
4.2 激光模式强制停机的几种情形
为保证与 G 代码程序的同步,Grbl 会在少数情形下强制执行激光模式运动停机:
- 任何
M3、M4、M5主轴状态变化; - 仅
M3且没有编程运动时:S主轴速度变化; - 仅
M3且没有编程运动时:G1/G2/G3激光点亮状态切换为G0/G80激光关闭状态; - 注意:
M4除主轴状态变化外不会为任何其他原因停机。
这些条件在 grbl/gcode.c 中通过 GC_PARSER_LASER_DISABLE 与 GC_PARSER_LASER_FORCE_SYNC 两个解析器标志实现:当运动模式不属于 G1(MOTION_MODE_LINEAR)、G2/G3(圆弧)时置 GC_PARSER_LASER_DISABLE;在 M3 恒功率模式下,非运动行在点亮/关闭状态之间切换时置 GC_PARSER_LASER_FORCE_SYNC,强制走 spindle_sync() 同步。此外 grbl/motion_control.c 的 mc_line() 中还有一个补充逻辑:当规划器返回空块(如重合坐标、零长度运动)且处于 M3 激光模式时,会调用 spindle_sync() 确保激光状态被正确设置。
4.3 激光只在 G1/G2/G3 运动模式下点亮
激光只在 G1、G2 或 G3 运动模式下才会点亮:
G0快速定位或G38.x探测循环永远不会点亮激光,并且总是关闭激光,但会照常更新运行中的模态状态。当模态切回G1/G2/G3时,Grbl 会立即按当前运行状态点亮激光。- 务必记住:
G0是上电和复位后的默认运动模式。手动点亮激光前,必须先切换为G1/G2/G3。这是严格的安全措施。 - 示例:
G0 M3 S1000不会点亮激光,但会把激光模态状态设置为M3使能、功率S1000;紧接着的G1命令会立即以M3、S1000执行。
这一行为对应 grbl/gcode.c 中的实现:激光模式下,任何非 G1/G2/G3 运动都会把 pl_data->spindle_speed 保持为零(GC_PARSER_LASER_DISABLE 时"Pass zero spindle speed for all restricted laser motions"),从而使规划器中的受限运动不带功率执行。
4.4 点动(Jog)时保持激光状态
如果希望在点动过程中让激光点亮,需要先启用有效的运动模式和主轴状态(如先执行一次 G1 M3 S...),之后发出的点动运动会继承并维持之前的激光状态。请谨慎使用:这个能力主要服务于"以极低功率点亮激光点,点动定位工件起始位置"的场景。在 grbl/gcode.c 的 jog 分支中可以看到,点动命令初始化规划数据时直接沿用了当前主轴与冷却模态状态(pl_data->spindle_speed = gc_state.spindle_speed),印证了点动继承激光状态的设计。
4.5 S0 零功率即时关断
S0(零主轴速度)会关闭激光。在有效的激光运动指令中编程 S0,Grbl 会在不停止运动的情况下即时关断激光,并持续到后续运动把功率设回大于 0 为止。
- 在
M3恒功率模式下,这是在G1激光运动与G0快速运动之间连续切换且无需停机的好方法:在G0运动前先编程一段短的G1 S0运动,随后紧接一段G1 Sxxx恢复切割。 - 源码层面,grbl/spindle_control.c 中
rpm == 0.0时返回SPINDLE_PWM_OFF_VALUE(0),spindle_set_speed()随之禁用 PWM 输出(输出为零电压);若同时编译启用了SPINDLE_ENABLE_OFF_WITH_ZERO_SPEED(grbl/config.h 中的选项,默认禁用),还会在零速时调用spindle_stop()关闭使能引脚。
5. CAM / G 代码生成器开发笔记
原文档的 CAM 开发章节尚标记为 TODO,但已有若干明确建议,并结合上述运行规则整理如下:
5.1 M3 恒功率模式下尽量避免强制同步
使用 M3 恒功率模式时,工作中尽量避免强制同步(force-sync)条件:
- 本质上,每次主轴速度变化都必须伴随一个有效的运动指令。任意运动都可以,因为 Grbl 会根据模态状态自动点亮/关闭激光。
- 避免在工件加工中途发送没有轴字的
G0和G1命令——这正是第 4.2 节所述"无运动行 + 功率变化 → 强制停机"的触发条件。
5.2 两种"不改变主轴状态地开关激光"的写法
要保证全程运动平滑,应在不使用 M3/M4/M5 主轴状态命令的情况下开关激光,有两种方法:
-
编程零主轴速度
S0:S0是合法 G 代码,它关断主轴/激光但不改变主轴状态。激光模式下 Grbl 会平滑地穿越连续运动并关断激光;反之,用大于零的S即可重新点亮。注意:M3恒功率模式要求任何S速度变化都必须伴随一个运动指令才能保持连续运动,而M4动态功率模式不需要。 -
在点亮运动之间编程无功率运动:如果在光栅(raster)任务的各区域之间移动且无需点亮激光,可在其间编程一段
G0快速运动。G0会强制自动关闭激光;最后一次编程的S速度不会改变,因此之后执行有效的点亮运动(如G1)时,会立即以最后编程的S功率重新点亮激光。
5.3 配套的辅助安全选项
在 grbl/config.h 中还有两个与激光安全直接相关的编译期选项,建议 CAM 开发者与用户知悉:
DISABLE_LASER_DURING_HOLD(默认启用):进给保持(feed hold)停机后立即调用主轴停止覆盖(spindle stop override)自动关闭激光,避免激光在停止状态意外持续点亮引发火灾;若确有需要,可通过关闭主轴停止覆盖重新点亮。grbl/protocol.c 的暂停/保持恢复逻辑中可以看到,进入 HOLD 状态时若BITFLAG_LASER_MODE置位即设置EXEC_SPINDLE_OVR_STOP标志;而在恢复(cycle start)时,若处于激光模式会忽略主轴升速延时,直接设置STEP_CONTROL_UPDATE_SPINDLE_PWM让激光随运动重启。SPINDLE_ENABLE_OFF_WITH_ZERO_SPEED(默认禁用):零速时同时关闭主轴使能引脚,需与USE_SPINDLE_DIR_AS_ENABLE_PIN配合(grbl/grbl.h 中有编译期断言约束),常用于把方向引脚复用为使能引脚的主轴/激光驱动板。
6. 相关资源与进一步阅读
- 激光模式官方说明(本文主线):doc/markdown/laser_mode.md
- 系统命令与设置总览:doc/markdown/commands.md
- 串口交互、状态报告与错误码(含 error:17 定义):doc/markdown/interface.md
- 设置项与错误/告警码 CSV 解析表:doc/csv/setting_codes_en_US.csv、doc/csv/error_codes_en_US.csv
- 激光功率相关源码:grbl/spindle_control.c(PWM 换算与
M4零功率)、grbl/stepper.c(M4动态功率实时更新)、grbl/gcode.c(激光模式解析器标志与同步逻辑)、grbl/protocol.c(进给保持关断激光)、grbl/cpu_map.h(D11 PWM 引脚与频率配置)、grbl/config.h(DISABLE_LASER_DURING_HOLD等安全选项) - 非线性主轴/激光功率拟合脚本:doc/script/fit_nonlinear_spindle.py
无论选择 M3 恒功率还是 M4 动态功率,请始终遵循"先做测试件、再跑正式任务"的原则,并确保机器具备急停与安全防护。激光模式下 Grbl 会尽量避免停机以保证切割质量,但这也意味着功率控制完全依赖程序正确性——正确理解上文的同步规则与安全选项,是安全使用激光模式的前提。