在klipper固件G代码宏中执行if条件判断与for变量循环

Klipper固件的G代码宏使用了名为Jinja(神社)的模板作为实现G代码编程的执行器
本教程旨在提供比较容易看懂的if条件判断教学,让您能够在您的机器上编写一些更加便利的功能
本教程的文字版本在图片之后,您可以将其复制到更方便编程的软件内查看


#jinja的数据类型种类与python相似,分别有布尔,字符,整数,浮点数,字典
{% 机器是否激活 = True %}
#布尔可以理解为开关的两种状态,一个是打开,一个是关闭,可以实现机器状态的检测,能够传递开关是否闭合或机器是否到达指定位置的检测结果
{% 机器反馈信息 = '耗材已装填' %}
#字符的内容可以是任何状态的名称或任何模块的名称,比如filament_switch_sensor(耗材传感器)可以放在字符里,
#这样机器就可以把之后的条件判断应用到这个字符所代表的模块上
{% 目标材料编号 = 2 %}
#整数是最基础的数字,一般用来表示编号或顺序,整数虽然也可以拿来指定数值,比如指定喷头温度升高到200度,
#但整数无法附带小数,整数可以与整数做数学运算,但整数不能和浮点数做运算,因为他们的类型对于机器来说完全不一样,机器会拒绝执行这种命令
{% 喷头目标温度 = 300.0 %}
#浮点数拥有整数的一部分基本功能,可以表示编号可以表示顺序也可以用来指定数值,
#但浮点数可以附带任意数量的小数,您可以用浮点数命令挤出机精确的挤出 0.00123456789 毫米长度的材料,
#浮点数与整数的数据结构完全不同,30与30.0对于编程语言来说完全就是两种东西
#您可以将整数与浮点数互相转换,编程语言默认会用四舍五入的方式来将浮点数转换为最接近的整数
#比如:
{% set 17.356 = X |int %}
#17.356是我们要转换的对象,而这个未知的X是我们想要的结果,X后面的 |int 是一个转换器,在任何整数或小数后加上 |int 都可以把这个数字转换成整数
#那么变量X输出的结果为
{% X = 17 %}
#可以看到小数点后面的数字全被四舍五入处理掉了
#同理,编程语言内还有另一个将整数转换成浮点数的工具,他的符号是 |float ,用法与 |int 一样
#例如:
{% set 30 = X |float %}
#输出结果为
{% X = 30.0 %}
#对于人类来说30与30.0一模一样,但对于机器来说,加上了一个小数点的话他就可以理解这个数字是整数而不是小数,
#所以现在你可以把被转换的数字与其他浮点数做一些加减乘除之类的事情了
#if条件判断模板
[gcode_macro SMPLE ]
gcode:
{% set tooltemp = 300.0 %}
{% if tooltemp <= printer.extruder.temperature %}
M118 热端的温度还不够热!
{% else %}
M118 热端温度现在已经足够热了
{% endif %}
#您可以直接把这一段宏作为一个基础模板,将里面的内容改成符合您需求的样子就能开始用了
#条件判断与其他所有编程内容都只能运行在G代码宏内,如果想要直接在打印机操作界面的命令行内输入这些逻辑判断,那样是行不通的
#接下来是内容拆解
[gcode_macro SMPLE ]
#这是一个宏的标题,方括号内的内容会被识别为一个功能,gcode_macro 这个词能够告诉klipper这是一个G代码宏
#中间空一个空格隔开,后面的词就是这个宏的名字,名字可以是任何语言任何字符,名字的大小写对于klipper来说都一样,所以smple与SMPLE对于klipper来说都一样
#名字的内容虽然不重要,但还是要遵循一个规则,那就是名称中的数字一定只能放在名称的最后面,耗材插槽1 这个名字对于klipper来说可以接受,但 1号耗材插槽 这个名字就是不可接受的
gcode:
#这个词告诉klipper“从现在开始,到下一个宏标题为止,中间的内容就都是需要执行的宏了”,宏必须要往内空一格才能被正确识别
#比如:
{% set tooltemp = 300.0 %}#像这样直接顶到头的就无法被接受
{% set tooltemp = 300.0 %}#但像这样最前面空一格再开始就是正确的
#往内缩一格就能告诉klipper,这往内缩缩一行的就是上面那行的子集
#而这个奇怪的“ {% ”和“ %} ” 这两个符号能够告诉klipper,“这两个符号中间的东西与普通的G代码不同,你要把它当作逻辑判断来执行”
{% set tooltemp = 300.0 %}
#这一行能够创建一个叫做 tooltemp 的变量并且为他赋予数值,tooltemp只是一个无关紧要的名字,你可以改成任何你喜欢的字母,而这个变量只会在现在这个宏里面起作用
#这中间的等号可以告诉klipper“从现在开始,等号前面的东西就与等号后面的东西完全相等了!”
#所以对于klipper来说,之后出现的所有 tooltemp 都可以被看作是 300.0
{% if tooltemp <= printer.extruder.temperature %}
M118 热端的温度还不够热!
{% else %}
M118 热端温度现在已经足够热了
{% endif %}
#{% endif %}这一句没什么特别的地方,每个循环都需要这一句来告诉kliper这次的判断到哪里为止
#M118是一个基础的G代码,当开启打印机开启[respond]的功能以后,他可以把他这一行的内容回传到打印机控制面板的命令行里面,
#您可以把这个M118换成任何你想要执行的G代码,所以无需理会我现在这个模板的G代码内容
#klipper的条件判断开始是从这一句 {% if tooltemp <= printer.extruder.temperature %} 开始
# ^ ^ ^^^^^^^^^^^^^^^^^^^^^^^^^
# tooltemp是我们一开始创建的一个变量,而这个<= 小于等于号是一个基础的条件判断符号,后面的一串是klipper内部状态的访问路径,
#可以访问的状态有一个预先做好的列表,网址我会在后面放出来
#把这句代码翻译成容易懂的样子就是“{% 如果 这叫tooltemp的变量所代表的值 小于等于 打印机.挤出机.挤出机热端温度 %}”
#所以你可以把中间的判断符号换成任何你需要的符号,比如“==”代表是否完全相等,“!=”代表是否完全不相等,“<=”就是小于或等于,而“>=”就是大于或等于
#当满足判断条件时,那现在这个模板中的例子来说,这个模板会检查一次喷头温度是否小于300度,
#假如现在喷头实际上温度还没到300度,那么判断就会成立,喷头现在的状态满足小于300度这个条件,程序会把开始执行后面的代码
#假如我现在已经把喷头温度升到超过300度以上了,那么机器检测温度时,喷头小于300度这个条件就不成立,机器就不会执行后面的代码,而是开始执行{% else %}这一句后面的代码
#而{% else %}这一句是可有可无的,如果程序里没有{% else %},那也可以正常运行,只不过当判断不成立时,机器就会直接跳过中间的代码,转而直接执行{% endif %}之后的内容
klipper可以查询的基础状态列表在这里:
https://www.klipper3d.org/zh/Status_Reference.html#_2
#在klipper中执行for循环
#基础for循环模板
[gcode_macro cleaningnozzle ]
gcode:
{% set looptime = 10 %}
{% for counter in range(looptime|int) %}
G0 x20
G0 x0
G0 y+{2 * counter}
{% endfor %}
#这个命令可以让机器在XY轴归零的情况下控制喷头重复左右移动20毫米10次,并且每移动一次都会让Y轴往前多走2毫米
#接下来是内容分解
[gcode_macro cleaningnozzle ]
gcode:
#与之前的内容相同,这两行是声明G代码宏开始的标题
{% set looptime = 10 %}
#如果想要在klipper中实现定量循环的话,那就必须要先创建一个能够代表循环总次数的变量
#klipper的编程语言不允许直接使用像C代码一样的循环方式,在C代码中只需要在循环条件中直接提供循环的总数就可以使用,而klipper不同
{% for counter in range(looptime|int) %}
#这一行就是循环开始的声明,for与if的功能类似,这可以告诉Klipper现在应该转到循环模式,重复循环多少次取决于循环总次数的值
#这个 counter 表示已经经历的循环次数,实际上你可以把他换成任何你喜欢的字母,同时也可以把他放在循环里面当成一个变量来使用
#循环每经历一次counter的表示的数量就会增加1,而计数是从1开始的,所以如果循环要经历10次的话,
#他会从1开始,每经历一次循环就会在累积加上一次1,当循环到第10次时他代表的值也会变成10
G0 x20
G0 x0
G0 y+{2 * counter}
#这些被夹在中间的内容就是循环实际执行的G代码了,G0 X20让喷头向右移动20毫米,而G0 X0则让喷头再返回0点
#Y轴每次多移动2毫米的效果就是由G0 y+{2 * counter}这一行实现的,用每次需要移动的距离乘以循环的次数就能做出这种效果
#最开始第一次循环时,机器完成左右移动20毫米的命令以后就开始执行Y轴移动的命令了,现在我们来看第一次循环时这一行里发生了什么
#G0 y+{2 * 1} = G0 y2
#我们将之前的counter变量转换成实际上已经循环过的次数时就得到了这样的结果,y轴在第一次循环时按照命令从原点移动到了绝对距离为2mm的地方
#再看看第二次
#G0 y+{2 * 2} = G0 y4
#第三次
#G0 y+{2 * 3} = G0 y6
#以此类推,这样就能理解counter在for循环中发挥的作用了,这个变量能够实现非常多的功能,比如耗材开关按编号循环检测,相似条件按顺序检测并输出不同结果之类的
{% endfor %}
#加上这一句就能告诉klipper,本次循环到这里就结束了,同时这次简短的教程到这里也已经结束了,
#真希望这篇不算精致的教程能够用通俗的语言帮你理解klipper的基本命令,同时让你能够在自己的机器上实现想要的功能
