Part 1: Basic Programming Concepts
Klipper macros are quite powerful, but at the same time can be limited in their
scope. The idea for macros is to be able to make some basic decisions and act
on them by substituting various values with other values. To understand macros,
though, we must first understand some programming basics
What is a function?
A function is a bit of code that produces output based on the input. Typically
decisions are made inside of a function via expressions that determine what the
function should do. Functions can also be called methods, routines, procedures.
They all do basically the same thing: Take a block of code and give it a name
so it can be reused to produce output based on input.
What is a literal?
A literal is a value that is effectively hard coded and cannot be changed
throughout the execution of a program. For instance, a integer value of 42
is a
literal. The value of 42
is literally 42
.
What is a comment?
The intended use of a comment is for the person writing code to leave
notes for themselves or anyone else should they come back and try to understand
the code later. Comments are denoted by a special character or set of characters
specific to each programming language. In the case of Klipper config files and
macros, there are two such characters used to denote a comment. #
and ;
. When
Either of these appear on a line, anything after them will be ignored.
#Move the toolhead to the middle of the bed
G1 X150 Y150
#Move the toolhead up slightly
G1 Z1
Comments can also be beneficial for debugging or changing code around. If you
have a bit of code that might not be working right or you want try to make it
do something else, but don’t want to delete the original bit in case it doesn’t
work, you can “comment out” that bit of code
#Move the toolhead to the middle of the bed
#G1 X150 Y150
#Move the toolhead up slightly
G1 Z1
In the example above, the newly commented line will be ignored when it comes
time to execute the macro.
What is a variable?
A variable is a value that can change throughout the execution of a program.
Variables are typically represented by names or letters. The name is associated
with a value because the value can change. When the variable name is referenced
during the execution of a block of code, the name is substituted for the
value of the variable at the time the expression is executed. So if we take
our literal 42
and assign it to a variable called e
whenever e
is
referenced, the value 42
will be used.
What is an assignment?
Giving a value to a variable is done by assignment. This can be a literal value, the
value of another variable, or the result of an expression. An assignment is done by
setting the variable equal to a value. In Jinja2 syntax, this is done with
{ set x = 42 }
What is an expression?
An expression is a programming command that does something. A simple example
would be a gcode command. M105
is a gcode expression that reports the various
temperatures. A variable assignment is also an expression. A comparison of
two values is an expression. In the simplest terms, an expression is a bit of code
that produces a result or value.
What is an object?
An object is a collection of variables, states, functions, and possibly more
objects. Objects are used to organize and access entities in a program. For
instance, in Klipper macros, there is a printer
object which has another
“fan” object attached to it. The fan has a “speed” variable which is used
to both get and set the fan speed. To get the fan speed, one would use
printer.fan.speed
What is a parameter?
A parameter is a value that is used as the input for the execution of a
function. In gcode, the function would be the gcode command and the
parameters would be the axis positions and speeds.
G1 X100 Y24 Z1 F2000
In other programming languages like python, functions are represented by a name
and the parameters are enclosed in parenthesis after the name.
action_respond_info("String Literal")
What is a conditional?
Similarly, expressions can also evaluate two things. Conditionals answer a
Yes
or No
, True
or False
, 1
or 0
question by evaluating one variable or literal
against another variable or literal. This is “boolean” logic and it is at the
core of all programming.
Is 15 equal to 12?
False
Is EXTRUDER_TEMP > 100?
True
Similarly, functions can return a value after they execute and that value can
be compared in an expression as well.
There say you have a function called EXTRUDER_PERCENT_TO_TARGET()
and it takes
two parameters. It returns the percentage of the CURRENT_TEMP
to the TARGET_TEMP
Is EXTRUDER_PERCENT_TO_TARGET( CURRENT_TEMP, TARGET_TEMP ) > 70? False
What is a macro?
A macro is a stored set of commands that can be called from a single
gcode command. Macros can call other macros or even themselves. Macros can
be treated like functions. For all intents and purposes, a klipper macro is
a function.
What is a Jinja?
Jinja is an engine for python (Klipper’s primary language) that can
take a block of text and read programming elements out of it. In the case of
gcode macros those programming elements are applied as a command template.
A command template could be looked at like a paragraph of fill in the blanks.
Like Mad Libs meets Choose Your Own Adventure. When the gcode macro is called,
the entirety of the command template is read in and evaluated. The gcode that
is expressed back to klipper is the result of whatever decisions were made
inside of that macro.
What is delayed gcode?
Delayed gcode is a macro that cannot be called directly, but is instead called
and executed from a timer at a set interval. Delayed gcode can run once or
repeatedly