Macros - Mejoras

Una de las mayores mejoras diferenciadoras de Klipper con respecto a otros firmware 3D es el uso de macros que nos permiten extender y personalizar nuestro sistema, donde el límite es casi nuestra imaginación.

Controlar, entender y ajustar nuestras macros es algo imprescindible para verdaderamente controlar y sacar provecho de Klipper.

¿Pero... que es una macro exactamente?

Básicamente, son un conjunto de comandos ejecutados “secuencialmente” que nos van a permitir realizar acciones repetitivas, Klipper usa Jinja2 como lenguaje.

Algunos empleos de macros es el START_PRINT donde definimos el proceso de puesta en marcha de nuestra máquina al iniciar una impresión. Aunque también tenemos otros como facilitarnos el PID, cambio de filamentos, etc...

Tal como hemos comentado, si queremos sacar verdaderamente provecho del empleo de Klipper, es aconsejable aprender a crear nuestras propias macros, para ello os aconsejamos el tutorial creación de macros creado por el compañero mental que es uno de los más completos y sencillo que hemos visto.

¿Como añado macros?

Sea por coger una de ejemplo o generar la nuestra propia, el utilizarlas es tan sencillo como añadirla a nuestro printer.cfg o a algún include en el mismo.

Os aconsejamos en la medida de lo posible siempre usar un include... básicamente creamos un macros.cfg a la altura de nuestro printer.cfg, puede tener el nombre que quieras y estar en otra ubicación, y lo añadimos como include en nuestro printer.cfg:

De esta forma tenemos nuestra configuración de una forma modular, más ordenada y más sencilla de leer.

Usando nuestras macros

Podemos ejecutar/lanzar nuestras macros de diferentes maneras:

  • Directamente, al poner en marcha nuestra impresora, por ejemplo, para ejecutar macros de efectos en leds, configurar estados de sensores, etc... Para ello usaremos, una vez definida nuestra macro, una macro de tipo delayed_gcode... donde básicamente indicamos al cabo de cuanto tiempo (initial_duration) lanzamos nuestro gcode/macro:

[delayed_gcode SAMPLE_MACRO_LOADSTART]
initial_duration: 1
gcode:
    SAMPLE_MACRO
  • Desde nuestra consola de Klipper:

  • Desde las secciones de Macro desde nuestra UI, en el caso de Mainsail podemos crear grupos, gestionar en que estados son visibles, etc...

Macros a fondo

Si habéis llegado hasta aquí, seguro que estás buscando como poder sacar más provecho de las macros, que como ya hemos comentado es una de las opciones más potente que contamos en Klipper.

Como ya seguro que sabéis, los ficheros de configuración de Klipper se dividen en secciones que dependiendo del tipo tienen diferentes claves/valores para poder ajustar sus valores.

En el caso de macros contamos con unas claves específicas que nos van a permitir incluir código gcode separados por línea.

Sección Macro

Para definir una macro en nuestra configuración comenzaremos añadiendo una sección [gcode_macro] donde también indicaremos el nombre de nuestra macro (NOMBRE_MACRO):

[gcode_macro NOMBRE_MACRO]
gcode:
    codigo gcode
    ...

Un tip... si ponemos un símbolo _ delante de nuestro NOMBRE_MACRO la macro aparecerá como "oculta"... podremos usarla pero no será visible desde nuestra UI. Algo muy útil para macros que sean internas y poco útiles tenerlas visibles.

Podemos lanzar nuestras macros desde la UI, desde la consola, desde el proceso de un gcode o incluso lanzarlas desde otras macros:

[gcode_macro _HOME]
gcode:
    G28 ; home all axis

[gcode_macro MI_MACRO]
gcode:
    # Home the printer first
    _HOME
    G0 X0 Y0

En el ejemplo anterior tenemos una macro MI_MACRO que al llamarla ejecutará nuestra macro _HOME, que es oculta.

Variables

También podemos tener variables en nuestras macros que nos va a permitir una enorme flexibilidad y opciones de crear funciones/macros realmente complejas.

Podemos definir nuestras macros en la propia macro al inicio usando variable_NOMBRE (usa minúsculas idealmente):

[gcode_macro MI_MACRO]
variable_mi_variable: 0
gcode:
    M117 mi_variable is equal to {mi_variable}

En el ejemplo anterior crearemos una variable mi_variable con un valor 0 y al lanzar nuestra macro MI_MACRO lanzaremos un mensaje (M117) mostrando el valor de nuestra variable.

Otra función interesante es que podemos acceder a estas variables desde otras macros:

[gcode_macro MI_MACRO2]
gcode:
    {% set macro_var = printer["gcode_macro MI_MACRO"] %}
    M117 mi_variable from MI_MACRO is set to {macro_var.mi_variable}

Además de poderlas usar en otras macros podemos ajustar su valor con SET_GCODE_VARIABLE:

[gcode_macro MI_MACRO3]
gcode:
    SET_GCODE_VARIABLE MACRO=MI_MACRO2 VARIABLE=mi_variable VALUE=10

Otra forma de usar variables son las variables internas o temporales que podemos crear dentro del propio gcode de nuestra macro:

[gcode_macro MI_MACRO]
gcode:
    {% set mi_variable = printer.toolhead.axis_maximum.x %}
    G0 X{mi_variable}

En el ejemplo anterior hemos generado una variable y le asignamos un valor de nuestra configuración de impresora, el tamaño máximo de nuestro eje X, para mover nuestro eje X a su máximo… con este código podemos hacer una macro que sea dinámica y adaptable a cualquier máquina dado que cogerá valores de nuestra configuración de forma dinámica.

Las variables pueden ser de varios tipos, los cuales podemos definir:

[gcode_macro MI_MACRO]
gcode:
    {% set mi_variable_int = params.INT_VALUE|int %}
    {% set mi_variable_float = params.FLOAT_VALUE|float %}
    {% set mi_variable_list = params.LIST_VALUE|split(",") %}

Además, podemos indicarle un valor por defecto en el caso de que esta variable pueda ser dinámica:

[gcode_macro MI_MACRO]
gcode:
    {% set mi_variable_int = params.INT_VALUE|default(5)|int %}
    {% set mi_variable_float = params.FLOAT_VALUE|default(2.5)|float %}

Parámetros

Aunque podríamos considerar muy similares a las variables del punto anterior, los parámetros son variables que nos pueden ser proporcionados al ejecutar una macro.

[gcode_macro MI_MACRO]
gcode:
    {% set mi_variable = params.PARAMS1 %}

Esta macro nos permitirá que cuando la llamemos poder pasarle el valor que asignaremos a mi_variable :

MI_MACRO PARAMS1=<value>

Macros dinámicas

Podemos añadir condiciones lógicas en nuestras macros que nos permitan que estas sean dinámicas con condiciones para poder lanzar comandos o procesos dependiendo de estas condiciones.

[gcode_macro MI_MACRO]
gcode:
    M109 S200
    {% for i in range(5) %}
        {% if printer.extruder.temperature < 100 %}
            M117 HEATING...
        {% else %}
            M117 Done.
        {% endif %}
    {% endfor %}

En el ejemplo anterior veremos que introducimos un comando (M109) para calentar nuestro extrusor sin parar la ejecución de nuestra macro y tenemos un bucle que nos irá avisando de que está calentando o no dependiendo de la temperatura y el rango que pongamos.

En la anterior macro hemos introducido también dos conceptos interesantes:

  • loops (for, endfor), normalmente las macros se evalúan de forma lineal, aunque con la inclusión de loops podemos hacer qué determinadas partes se ejecuten en bucle

  • condiciones (if, elif, else, endif), nos permiten ejecutar partes de nuestras macros dependiendo de valores/estados que nos interesen, permitiendo gran flexibilidad en nuestras macros

Última actualización