news 2026/9/15 21:59:52

Klipper 使用 PWM 工具控制激光器与主轴:pwm_tool 配置、M3/M4/M5 宏与 LaserWeb 集成实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Klipper 使用 PWM 工具控制激光器与主轴:pwm_tool 配置、M3/M4/M5 宏与 LaserWeb 集成实战

Klipper 使用 PWM 工具控制激光器与主轴:pwm_tool 配置、M3/M4/M5 宏与 LaserWeb 集成实战

【免费下载链接】klipperKlipper is a 3d-printer firmware项目地址: https://gitcode.com/GitHub_Trending/kl/klipper

导读

本文基于 Klipper 官方文档 docs/Using_PWM_Tools.md 与仓库中的示例配置 config/sample-pwm-tool.cfg,系统讲解如何复用打印头风扇的 PWM 输出来驱动激光器(laser)或主轴(spindle)。你将掌握[pwm_tool]配置段的全部参数含义、M3/M4/M5 宏的实现原理、安全超时的正确设置方法,以及如何在 LaserWeb 等 CAM 工具中无缝集成——最终获得一套可直接复制运行、可安全切换工具头的 PWM 工具控制方案。

工作原理:把风扇 PWM 输出改造成工具控制口

Klipper 打印头风扇原本由 PWM 信号驱动,其输出本质是一路可高速更新的脉宽调制信号。借助这一特性,可以将打印头的风扇 PWM 输出"挪用"为激光器或主轴的控制信号——这在更换式打印头(switchable print heads)场景下尤为实用,例如 E3D toolchanger 或各类 DIY 换头方案。

CNC/CAM 领域通常约定用M3~M5三个 G-code 命令控制主轴与激光器:

命令含义参数
M3 S<value>主轴顺时针旋转(Spindle speed CW)S取值 0~255
M4 S<value>主轴逆时针旋转(Spindle speed CCW)S取值 0~255
M5停止主轴(Spindle stop)无参数,输出回到 shutdown value

S参数的 0~255 是经典 CNC 的 8 位占空比标度,Klipper 侧通过宏把它归一化映射到 0.0~1.0 的 PWM 占空比(详见下文"M3/M4/M5 宏"一节)。LaserWeb 等工具默认就能以M3 $INTENSITY的形式发送这些命令,因此无需改造切片或 CAM 软件即可接入 Klipper。

安全警告:驱动激光器必须遵守的底线

使用 PWM 工具驱动激光器时,请务必把能想到的安全措施全部落实到位,这一点在原文档中被着重强调:

  • 二极管激光器通常是反相的(inverted)。这意味着当 MCU 重启、固件尚未完成初始化时,PWM 引脚处于未定义/默认状态,激光器可能会在 MCU 重新启动的短暂时间内以满功率开启。这是硬件级风险,必须通过外围电路(如常闭联锁继电器)加以兜底。
  • 激光通电期间应始终佩戴与激光波长匹配的专用护目镜
  • 不需要使用激光时,请直接断开激光器电源
  • 必须配置安全超时(safety timeout):当主机或 MCU 发生错误时,工具要能自动停止,避免长时间空烧。

安全超时正是[pwm_tool]maximum_mcu_duration参数的职责,下文会详细展开。

一个隐含但重要的细节:原文档与示例配置反复强调"homing 时工具需要处于默认速度"。因为在归零过程中 Klipper 会执行运动同步,若此时工具占空比非默认值,超时机制可能被误触发或导致意外的 PWM 输出,配置时务必结合下面的超时参数一起考虑。

配置[pwm_tool]:从风扇引脚到可控工具

完整的可运行配置见仓库 config/sample-pwm-tool.cfg,其核心是[pwm_tool]配置段:

[pwm_tool TOOL] pin: !ar9 # 使用你风扇的引脚编号(此处为示例) hardware_pwm: True cycle_time: 0.001 shutdown_value: 0 maximum_mcu_duration: 5 # Default: 0 (disabled) # Amount of time in which the host has to acknowledge # a non-shutdown output value. # Suggested value is around 5 seconds. # Use a value that does not burn up your stock. # Please note that during homing, your tool # needs to be in default speed.

[pwm_tool]配置段在 docs/Config_Reference.md(第 3716 行起)中有官方说明,各参数含义与默认值整理如下:

参数默认值说明
pin必填要配置为输出的引脚,使用你风扇原来的引脚编号;!前缀表示反相。示例中!ar9是 BigTreeTech 类主板上的 AR9 引脚(反相)
maximum_mcu_duration0(禁用)MCU 在没有收到主机确认的情况下,最多允许持续输出非 shutdown 值多长时间。若主机无法跟上更新节奏,MCU 将进入 shutdown 并把所有引脚置为各自的 shutdown 值。建议值约 5 秒,具体以不会烧毁你的工件(stock)为准
value0MCU 配置期间引脚初始值(0~1 或 0~scale
shutdown_value0MCU shutdown 事件发生时引脚应置为的值(0~1 或 0~scale)。激光器场景建议设为 0(关闭)
cycle_time0.100 秒每个 PWM 周期的时间(秒)。软件 PWM 建议 10 毫秒或更长;使用硬件 PWM 时实际周期受硬件实现约束,可能与请求值明显不同
hardware_pwmFalse是否使用硬件 PWM 而非软件 PWM
scale1用于改变value/shutdown_value的解析标度,配置为 PWM 引脚控制步进电压参考等场景时可设为等效电流值

其中cycle_time: 0.001表示 1 kHz 的 PWM 频率,适合激光器等需要较高调制频率的工具。

版本注意:3 秒上限变更

根据 docs/Config_Changes.md 中20250428条目的记录:[pwm_tool]及类似 PWM 配置段的cycle_time最大值从 5 秒缩减为3 秒maximum_mcu_duration的上限同样被限制为3 秒。因此在新版本上配置时,maximum_mcu_duration: 5这类取值需要改为不超过 3 秒的值。

为什么需要maximum_mcu_duration

其底层逻辑是"看门狗式"的:正常情况下主机周期性下发新的 PWM 值(例如通过运动队列的刷新回调),MCU 收到后即视为"确认"。若主机卡死、串口中断或发生错误导致长时间没有新指令,MCU 会在超时后将引脚强制置为shutdown_value——对激光器而言就是立刻关断,避免持续高功率输出引发事故。这一点在 pwm_tool.py 中通过_gen_intermediate_updates_flush_notification机制实现(详见"源码级原理"一节)。

M3/M4/M5 宏:把 0~255 映射成 PWM 占空比

[pwm_tool]本身只提供一个SET_PIN运行时命令,真正的 M3/M4/M5 是通过[gcode_macro]实现的。示例配置中的宏如下:

[gcode_macro M3] gcode: {% set S = params.S|default(0.0)|float %} SET_PIN PIN=TOOL VALUE={S / 255.0} [gcode_macro M4] gcode: {% set S = params.S|default(0.0)|float %} SET_PIN PIN=TOOL VALUE={S / 255.0} [gcode_macro M5] gcode: SET_PIN PIN=TOOL VALUE=0

要点解析:

  • S参数通过 Jinja2 模板读取,params.S|default(0.0)|float保证了未传S时安全回退为 0;
  • 关键映射是VALUE={S / 255.0}:把 CNC 惯用的 0~255 标度换算为 Klipper PWM 的 0.0~1.0 占空比。例如M3 S128会执行SET_PIN PIN=TOOL VALUE=0.502
  • M5直接SET_PIN PIN=TOOL VALUE=0,把输出置回关闭状态。

SET_PIN的语义在 docs/G-Codes.md(第 1071 行起)中有明确定义:PWM 引脚时VALUE应取值 0.0~1.0,若配置了scale则取 0~scaleSET_PIN是面向运动队列的异步命令——它会注册一个 lookahead 回调,在对应的打印时间点才真正改变引脚电平,从而与运动轨迹精确同步,这一点在源码cmd_SET_PIN中可以看到(toolhead.register_lookahead_callback(...))。

LaserWeb 集成配置

LaserWeb 是常见的激光雕刻 CAM 前端。原文档给出了一套经过验证的配置,完整照录如下:

GCODE START: M5 ; Disable Laser G21 ; Set units to mm G90 ; Absolute positioning G0 Z0 F7000 ; Set Non-Cutting speed GCODE END: M5 ; Disable Laser G91 ; relative G0 Z+20 F4000 ; G90 ; absolute GCODE HOMING: M5 ; Disable Laser G28 ; Home all axis TOOL ON: M3 $INTENSITY TOOL OFF: M5 ; Disable Laser LASER INTENSITY: S

要点解读:

  • 开始/结束/归零时一律先M5:确保激光在作业前后始终处于关闭状态,属于安全惯例;
  • TOOL ON 使用M3 $INTENSITY:LaserWeb 会把当前强度值以S参数形式填充进命令,正好落入上面宏的S/255.0映射;
  • LASER INTENSITY 填S:告诉 LaserWeb 强度参数名是S,与 M3/M4 宏的解析方式对应。

可选增强:LCD 菜单控制

示例配置还附带了一段可选的 LCD 菜单控制,便于在打印机屏幕上直接开关工具和调节速度:

[menu __main __control __toolonoff] type: input enable: {'pwm_tool TOOL' in printer} name: Fan: {'ON ' if menu.input else 'OFF'} input: {printer['pwm_tool TOOL'].value} input_min: 0 input_max: 1 input_step: 1 gcode: M3 S{255 if menu.input else 0} [menu __main __control __toolspeed] type: input enable: {'pwm_tool TOOL' in printer} name: Tool speed: {'%3d' % (menu.input*100)}% input: {printer['pwm_tool TOOL'].value} input_min: 0 input_max: 1 input_step: 0.01 gcode: M3 S{'%d' % (menu.input*255)}

这里通过printer['pwm_tool TOOL'].value实时读取当前占空比——value状态字段在 docs/Status_Reference.md(第 390 行起)中有定义,表示引脚当前被SET_PIN设置的值。菜单项最终仍复用 M3 宏(S{255 if menu.input else 0}S{'%d' % (menu.input*255)}),保证 0~255 标度的一致性。

源码级原理:pwm_tool在 Klipper 中如何工作

核心实现在 klippy/extras/pwm_tool.py 中,模块类MCU_queued_pwm承担了全部底层逻辑。PrinterOutputPin.load_config_prefix是配置入口,通过ppins.lookup_pin()解析引脚,然后根据hardware_pwm分支走两套完全不同的 MCU 命令序列:

硬件 PWM 分支:向 MCU 下发config_pwm_out(含cycle_ticks、起始值、default_valuemax_duration),随后用queue_pwm_out排入队列;PWM_MAX常量由 MCU 固件提供(如 Atmel 系列的定时器计数上限),占空比换算为value * PWM_MAX的计数值。

软件 PWM 分支:向 MCU 下发config_digital_outset_digital_out_pwm_cycle,以 GPIO 翻转加周期计数实现软件 PWM。这里有一个硬性约束:软件 PWM 模式下shutdown_value只能是 0.0 或 1.0,否则_build_config会直接抛出配置错误"shutdown value must be 0.0 or 1.0 on soft pwm"

其他值得注意的实现细节:

  • 同步队列(syncemitter)MCU_queued_pwmmotion_queuing分配一个 syncemitter(alloc_stepcompress=False),PWM 更新通过syncemitter_queue_msg注入运动队列,与步进指令共享时间基准,从而保证占空比切换与打印头运动在时序上严格对齐;
  • 超时续命机制_gen_intermediate_updates会在当前值非默认值时,以duration_ticks为间隔周期性地重发当前值,相当于持续"喂狗";一旦主机停止确认,MCU 侧max_duration即触发 shutdown。这与配置中的maximum_mcu_duration一一对应;
  • 启动值约束_build_config中若设置了max_duration且起始值与 shutdown 值不同,会报错"Pin with max duration must have start value equal to shutdown value"——这正是示例配置中valueshutdown_value都为 0 的原因。

测试用例佐证

仓库测试 test/klippy/pwm.cfg 与 test/klippy/pwm.test 覆盖了pwm_tool的基本行为:测试配置声明了[pwm_tool test_pwm_tool](引脚 PH4),测试脚本依次执行SET_PIN PIN=test_pwm_tool VALUE=0/0.5/0.5/0.25/1,验证重复设置、半占空比与满占空比切换均能正确通过运动队列下发。这套测试同时覆盖硬件 PWM 与软件 PWM 两种分支,可作为修改配置后回归验证的参考。

排查与使用建议

  • 激光"失控常亮":优先检查shutdown_value是否配置为 0,以及maximum_mcu_duration是否按版本上限正确设置;同时确认二极管激光器的反相特性是否已用!引脚前缀或外围电路处理;
  • 软 PWM 配置报错:报错shutdown value must be 0.0 or 1.0 on soft pwm时,要么把shutdown_value改为 0 或 1,要么开启hardware_pwm: True
  • 超时误触发:若打印过程中工具提前关闭,可适当增大maximum_mcu_duration(不超过 3 秒上限),并确保归零/换刀等操作期间工具处于默认占空比;
  • 更换主板pin需按新主板风扇引脚改写,可参考 config/example-extras.cfg 中其它输出引脚配置段的写法保持一致风格。

总结

通过[pwm_tool]+ 三个[gcode_macro]宏,Klipper 可以把一路风扇 PWM 输出变成完全可控、带安全超时的激光器/主轴驱动口:M3/M4 S0-255控制占空比、M5安全关断,LaserWeb 开箱即用;maximum_mcu_duration提供主机失联时的硬件级兜底;源码中的 syncemitter 机制保证 PWM 切换与运动时序精确同步。从 config/sample-pwm-tool.cfg 出发,结合本文的参数说明与安全注意点,即可在自己的打印机上安全、可靠地启用 PWM 工具控制。

【免费下载链接】klipperKlipper is a 3d-printer firmware项目地址: https://gitcode.com/GitHub_Trending/kl/klipper

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/15 21:59:41

数据工程版本控制全攻略:代码、数据与Schema管理实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/15 21:57:07

HOG+SVM目标检测原理与手写实现指南

1. 这不是“过时技术”&#xff0c;而是你真正理解目标检测的起点HOGSVM 这个组合&#xff0c;现在一提起来&#xff0c;很多人第一反应是“老古董”“早就被YOLO和RetinaNet淘汰了”。但我在带新人做计算机视觉项目时&#xff0c;坚持让他们先手写一遍 HOG 特征提取 SVM 训练…

作者头像 李华
网站建设 2026/9/15 21:55:44

恒捷家电商城SpringBoot毕业设计项目完整拆解与避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/15 21:55:03

GD32H759 + RT-Thread 以太网驱动移植实战:从 DMA 描述符到 PHY 调试

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华