Part 3: Parameters and Basic Conditionals
If the axes aren’t homed or the nozzle is not to temp, it will fail like
anything else because of safety checks.
What if we wanted to incorporate some of that into my start_print macro? We
would need to get values from the slicer, such as extruder and bed temperature
back to our macro somehow.
We can use parameters for this.
To add a parameter for a macro, all we have to do is reference it. Within
Jinja2 templates, programmatic actions need to be encapsulated within curly
braces. In this case, we are simply substituting the name of the parameter
for it’s value. Parameters passed to a gcode macro are contained within the params collection. Due to how parameters are handled in the gcode parser, they must be capitalized when referencing them in a macro.
[gcode_macro start_print]
gcode:
M109 S{ params.TOOL_TEMP } # Heat the tool to temperature and wait
G92 E0 # Reset Extruder
G1 Z2.0 F3000 # Move Z Axis to travel height
G1 X0.1 Y20 Z0.2 F5000.0 # Move to start position
G1 X0.1 Y200.0 Z0.2 F1500.0 E15 # Draw the first line
G1 X0.4 Y200.0 Z0.2 F5000.0 # Move to side a little
G1 X0.4 Y20 Z0.3 F1500.0 E30 # Draw the second line
G92 E0 # Reset Extruder
G1 Z2.0 F3000 # Move Z Axis up to travel height
From now on, whenever start_print is called, { params.TOOL_TEMP } will be replaced
with whatever value the tool_temp parameter is assigned.
start_print tool_temp=200
If our slicer supports variables in its gcode templates like Slic3r variants,
for instance, we could substitute the 200 for whatever that variable is in the
slicer. So in the start gcode, we could put something like
start_print tool_temp=[first_layer_temperature]
when the gcode file is written out, the slicer substitutes the variable
[first_layer_temperature] for the temperature that was specified in the slicer
settings for that particular filament. This would produce gcode in the output
file similar to
start_print tool_temp=200
When the macro is called, the 200 is being assigned to the tool_temp,
parameter. When the tool_temp variable is referenced, it is substituted
for 200.
M109 S200 # Heat the tool to temperature and wait
This still doesn’t solve the problem of axes that aren’t homed. We could just
call G28 at the start of the macro, but that would result in the axes homing
again even if they are already homed. With macros, we can actually check to
see if we need to home by using a conditional and referencing the toolhead
object.
In Jinja2, a conditional is prefixed with {% followed by the type of conditional
to use followed by the expression to be evaluated closed with %} In this case,
we would want to use an if statement. An if statement is a conditional
that compares two things and results in a true or “false” answer. If the
resulting answer is true then the code in the if statement is executed,
if it is false then the code is ignored or the else is executed. More on that later.
Klipper has certain “virtual” objects exposed to the macro ecosystem so that
this sort of thing can be accomplished. In our macro example here, we are
looking to figure out which axes are currently homed. To get there we need to
reference the printer object. The printer object has a field called
homed_axes which is a string of characters that represent each axis that
is currently homed. So XY would mean both X and Y are homed, but Z is not.
The printer.homed_axes object will always contain the axes in the order of XYZ
so to check to see if all 3 axes are homed, we merely need to make sure the
value of printer.homed_axes is equal to XYZ. Since we want to perform an
action if they are not homed we need to use the not equal comparision
operator, != .
In plain English, we are trying to say “If all 3 axes are not homed, home them”
In Jinja2, we express that as
{% if printer.homed_axes != 'XYZ' %}
G28 #Home All Axes
{% endif %}
The condition is typed on the first line encased in the curly braces with
percent signs. The code to execute is on the next line. Finally, the {% endif %}
tag is added to close the statement. Anything in between the if and endif is
executed if the if statement evaluates true.
So when the macro is called, if one or more of the printer’s axes are not homed,
G28 will be called to home them.
[gcode_macro start_print]
gcode:
M109 S{params.TOOL_TEMP} # Heat the tool to temperature and wait
{% if printer.homed_axes != 'XYZ' %}
G28 #Home All Axes
{% endif %}
G92 E0 # Reset Extruder
G1 Z2.0 F3000 # Move Z Axis to travel height
G1 X0.1 Y20 Z0.2 F5000.0 # Move to start position
G1 X0.1 Y200.0 Z0.2 F1500.0 E15 # Draw the first line
G1 X0.4 Y200.0 Z0.2 F5000.0 # Move to side a little
G1 X0.4 Y20 Z0.3 F1500.0 E30 # Draw the second line
G92 E0 # Reset Extruder
G1 Z2.0 F3000 # Move Z Axis up to travel height