# Configuración Klipper en laminadores

**Klipper** es un firmware de impresoras 3D increíblemente flexible que podemos configurar basándonos en ficheros de configuración.

## Generación de Gcode

Los laminadores disponen de una opción para indicar el tipo de gcode (**G-Code flavor**) que queremos generar.

Normalmente, estos usan por defecto **Marlin** que funciona bien con Klipper al igual que **Smoothieware**.

Nuestro laminador favorito, **SuperSlicer o Bambu Studio/OrcaSlicer** (PrusaSlicer lo tendrá disponible a partir de la versión 2.6) tiene una opción específica para **Klipper** que podemos encontrar en el perfil de impresora **General/Firmware**:

![](/files/t7loWPCW9xoyBJI9aIXd)

{% hint style="success" %}
A continuación tenéis links a grupos de laminadores en Telegram por si necesitáis más información:

* **Bambu Studio/OrcaSlicer** -> <https://t.me/bambulabs_studio>
* **SuperSlicer** -> <https://t.me/superslicer>
* **PrusaSlicer** -> <https://t.me/prusaslicer>
  {% endhint %}

{% hint style="danger" %}
Laminadores como **Cura necesitan de ciertos ajustes para evitar que generen ciertos gcodes que pueden no llevarse bien con Klipper**, de igual forma l**aminadores con G-Code flavor Marlin2 pueden ocasionar problemas similares**

**Volviendo a Cura, os aconsejamos utilizar el script del compañero** [**Pedro Lamas**](https://ko-fi.com/pedrolamas) **donde con su**[ **post-processing script** ](https://github.com/pedrolamas/klipper-preprocessor)**podemos añadir cualquier ajuste para mejorar el funcionamiento con Klipper.**
{% endhint %}

<details>

<summary>Importante!!!...<strong>Bambu Studio/OrcaSlicer... ARC en Klipper</strong></summary>

**Bambu Studio/OrcaSlicer** (fork del primero con opciones interesantes añadidas):

**Bambu Studio utiliza ARC**, significa que usa los gcodes G2/G3, por defecto en algunos perfiles y que funcione correctamente necesitaremos activar el soporte ARC en nuestro Klipper.

**¿Que hace ARC?**\
Básicamente **ARC transforma un círculo o una curva como un solo comando (G2/G3) matemático en una trazada en arco**, el firmware lo interpola en tiempo real a trazadas.\
Sin ARC un circulo o una curva se convierten en muchos G1 que son trazadas rectas para construir ese circulo o curva.

**¿En que mejora el uso de ARC?**\
El uso de **ARC suele repercutir en unas curvas más suaves, con movimientos continuos y no "poligonales". Esto suele generar menos artefactos en este tipo de trazadas.**

**¿En que afecta ARC a nivel de firmware?**\
El uso de **ARC genera menos líneas gcode cuando se tienen muchas trazadas curvas, por lo cual el proceso del fichero por parte del firmware es más fácil** en especial cuando usamos combinaciones Marlin/Octoprint que al igual que Klipper utiliza una arquitectura host/cliente.\
Pero por otro lado y **por como funciona Klipper genera más carga de cálculos en el host ya que debe calcular en tiempo real la trayectoria del arco y generar las trazadas**.\
Si disponemos de **un host potente y una electrónica capaz podemos decir que ARC puede ser beneficioso**, también **va a depender de ciertas configuraciones como velocidades/aceleraciones/pasos de los motores/CAN que van a generar carga extra!!!**\
⚠️ Si tenemos <mark style="color:red;">**hosts con potencia limitada, montamos canales de conexion más pesadas como CAN, unimos ARC a la ecuación junto con altas velocidades/aceleraciones/pasos de motores... creamos la tormenta perfecta para saturar nuestro sistema y disparar errores como el famoso "Timer too close" que tenéis más información en la guía de Troubleshooting.**</mark>

Lo ideal es crear un nuevo fichero de configuración, bambu\_studio.cfg por ejemplo, y añadirlo como include en nuestro printer.cfg.

{% code title="bambu\_studio.cfg" %}

```django
[gcode_arcs]
resolution: 0.1

[gcode_macro m201]
gcode:
  {% if 'X' in params or 'Y' in params %}
    {% set accel = (params.X|default(params.Y)|float,
                    params.Y|default(params.X)|float)|min %}
      SET_VELOCITY_LIMIT ACCEL={accel} ACCEL_TO_DECEL={accel * 0.5}
  {% else %}
    SET_VELOCITY_LIMIT
  {% endif %}

[gcode_macro m203]
gcode:
  {% if 'X' in params or 'Y' in params %}
    {% set speed = (params.X|default(params.Y)|float,
                       params.Y|default(params.X)|float)|min %}
    SET_VELOCITY_LIMIT VELOCITY={speed}
  {% else %}
    SET_VELOCITY_LIMIT
  {% endif %}

[gcode_macro M205]
gcode:
  {% if 'X' in params or 'Y' in params %}
    {% set corner_speed = (params.X|default(params.Y)|float,
                       params.Y|default(params.X)|float)|min %}
    SET_VELOCITY_LIMIT SQUARE_CORNER_VELOCITY={corner_speed}
  {% else %}
    SET_VELOCITY_LIMIT
  {% endif %}

[gcode_macro M900]
gcode:
      SET_PRESSURE_ADVANCE ADVANCE={params.K}

```

{% endcode %}

Tenéis un ejemplo de nuestro compañero Laureano a modo de ejemplo también:

<https://gist.github.com/LauOtero/9a5d392c374791fe4faace74c3a9979e>

En el caso **que no queráis usar ARC** porque vuestra máquina no lo soporte o simplemente porque no le veis beneficio **aseguraos que las siguientes funciones están deshabilitadas**:

* **Arc fitting**
* **Z-hop type : Spiral lift**

![](/files/lO6Yyql6AyoU23tB3Rql) ![](/files/JLw4d5OktPFBfnwUI7cd)

</details>

## Gcode de inicio y fin

Los laminadores suelen contar con gcodes de inicio y de final que se encargan de realizar los procesos pre y post-impresión que pueden impactar en la calidad de nuestra impresión.

Dado que en Klipper podemos configurar nuestras propias macros, algo que suele ser muy útil es la creación de macros para el inicio de impresión (START\_*PRINT) y final de impresión (END*\_PRINT).

Os vamos a sugerir como poder personalizar vuestros gcodes pre y post usando las macros de Klipper que os van a permitir:

{% hint style="success" %}
**Si buscas un sistema más completo, avanzado y personalizable a los scripts básicos que te sugerimos a continuación te aconsejamos que revises nuestro**[ **bundle para Klipper modular aquí**](/klipper/mejoras/3dwork-klipper-bundle.md)**.**
{% endhint %}

### START\_PRINT

* Recuperar automáticamente el tamaño de impresión, diámetro del filamento y nozzle
* Purga de línea inteligente
* Temperaturas de precalentado
* Hacer el proceso de homing, [z-tilt](/klipper/empezamos/nivelacion-gantry-z-tilt.md) y [nivelado](/klipper/empezamos/malla-nivelacion-de-cama-klipper.md)
* Temperaturas de impresión

{% hint style="success" %}
**IMPORTANTE!!!**

**Configuración Linea Purga Inteligente.**

* Puede ser necesario que **vuestra sección \[extruder]** se indique el <mark style="color:green;">**max\_extrude\_cross\_section**</mark>... un valor de 5 debería de ser suficiente generalmente:

{% code title="printer.cfg" %}

```django
[extruder]
...
max_extrude_cross_section: 5
```

{% endcode %}

{% hint style="info" %}
Sin este ajuste, Klipper puede lanzar el error **`Move exceeds maximum extrusion`** al ejecutar la línea de purga o la macro START\_PRINT, ya que la cantidad de filamento extruida es desproporcionada respecto al desplazamiento. Consulta [cómo diagnosticar y resolver este error](https://klipper.3dwork.io/klipper/troubleshooting#error-move-exceeds-maximum-extrusion) en la guía de troubleshooting.
{% endhint %}

* Otro ajuste necesario para **vuestra sección \[extruder]** se indique el [<mark style="color:green;">**max\_extrude\_only\_distance**</mark>](https://www.klipper3d.org/Config_Reference.html#extruder)... el valor aconsejable suele ser >101 (en caso de no estar definido usa 50) para por ejemplo permitir los tests típicos de calibración del extrusor.\
  Deberías ajustar el valor en base a lo comentado anteriormente del test o la configuración de tu **variable\_line\_length** y/o **variable\_purge\_amount**.

<mark style="color:orange;">**Los siguientes ajustes se han de realizar en la macro START\_PRINT en la sección inicial donde se encuentran las variables de configuración:**</mark>

* Mediante <mark style="color:green;">**variable\_adaptive\_enable**</mark> , con valor True nuestra línea de purga va a ser dinámica en base al tamaño de nuestra pieza a imprimir en el caso de False realizará una gota de purgado
* En <mark style="color:green;">**variable\_flow\_rate**</mark> podemos ajustar el [máximo flow rate](https://github.com/alienboyxp/gitbook_es_klipper_3dwork_io/blob/main/broken/pages/-MTqPy_NKPC-R-jkDi7M/README.md#15.-ajuste-de-extrusion-volumetrica-opcional) de nuestro extrusor. El valor de 12mm3/s suele ser válido para sistemas de extrusión normales y 24 para alto flujo
* <mark style="color:green;">**variable\_line\_length**</mark> donde indicaremos el tamaño deseado en mm de nuestra línea de purga... un valor de 1/5 de nuestro eje X suele ser lo indicado
* <mark style="color:green;">**variable\_purge\_amount**</mark> la cantidad de filamento en mm que queremos purgar
* <mark style="color:green;">**variable\_x\_default**</mark>, y mismo parámetro para y, serán las coordenadas donde queremos que comience nuestra línea de purga. En el caso de tener activada la línea de purga automática no se tiene en cuenta

También contamos con la macro **SETUP\_START\_PRINT** que desde la UI podemos ajustar estos parámetros.
{% endhint %}

{% hint style="success" %}
**IMPORTANTE!!!**

**Configuración Nivelación.**

En el ejemplo **START\_PRINT incluido en esta guía facilita el proceso de nivelación pudiendo adaptarse a diferentes usos:**\ <mark style="color:orange;">**Los siguientes ajustes se han de realizar en la macro START\_PRINT en la sección inicial donde se encuentran las variables de configuración:**</mark>

* <mark style="color:green;">**`variable_calibrate_z_tilt`**</mark> **si contamos doble Z con z-tilt** **podremos hacer un nivelado** [**Z-tilt**](/klipper/empezamos/nivelacion-gantry-z-tilt.md) **(True)** o **no (False)**.
* <mark style="color:green;">**`variable_calibrate_bed_mesh`**</mark> para indicar **si queremos hacer una malla al inicio de cada impresión (True)** o **si queremos aprovechar un mallado ya guardado (False)**.

También podemos añadir la siguiente macro para que haga el proceso de igual forma que se hacía antes del cambio en Klipper.

```django
[delayed_gcode bed_mesh_init]
initial_duration: .01
gcode: 
  BED_MESH_PROFILE LOAD=default
```

{% endhint %}

{% hint style="warning" %}
En el ejemplo <mark style="color:red;">**START\_PRINT incluido en esta guía usaremos notificaciones para indicar en que paso estamos durante el proceso de inicio de impresión por lo que necesitamos que tu**</mark><mark style="color:red;">**&#x20;**</mark><mark style="color:red;">**`printer.cfg`**</mark><mark style="color:red;">**&#x20;**</mark><mark style="color:red;">**o includes del mismo tengan la sección \[respond]**</mark>

{% code title="printer.cfg" %}

```django
[respond]
```

{% endcode %}
{% endhint %}

{% embed url="<https://gist.github.com/alienboyxp/fe225e1667da13557c270b7e5b73db10>" %}
<https://gist.github.com/alienboyxp/fe225e1667da13557c270b7e5b73db10>
{% endembed %}

### END\_PRINT

* Ejecutar una retracción del filamento
* Presentar la impresión para poder retirarla de forma sencilla
* Apagado de los motores

{% embed url="<https://gist.github.com/alienboyxp/1fe5c57b40c09a9d0095d027ffc0f5d7>" %}
<https://gist.github.com/alienboyxp/1fe5c57b40c09a9d0095d027ffc0f5d7>
{% endembed %}

### Configurando nuestro laminador para usar las macros START\_PRINT y END\_PRINT

Para ejecutar estas macros en nuestro laminador:

{% hint style="success" %}
**Estas configuraciones suelen encontrarse dentro de las opciones dentro de la configuración de impresora. Revisa en el caso de tu laminador donde ajustar**
{% endhint %}

* **gcode de inicio START\_PRINT**, usando placeholders para pasar los valores de temperatura de filamento y cama de forma dinámica:

{% tabs %}
{% tab title="Bambu Studio/OrcaSlicer" %}

```gcode
M190 S0 ; Prevents prusaslicer engine from prepending m190 to the gcode ruining our macro
M109 S0 ; Prevents prusaslicer engine from prepending m109 to the gcode ruining our macro
SET_PRINT_STATS_INFO TOTAL_LAYER=[total_layer_count] ; Provide layer information
START_PRINT EXTRUDER_TEMP=[nozzle_temperature_initial_layer] BED_TEMP=[first_layer_bed_temperature] CHAMBER=[chamber_temperature] PRINT_MIN={first_layer_print_min[0]},{first_layer_print_min[1]} PRINT_MAX={first_layer_print_max[0]},{first_layer_print_max[1]}
```

<figure><img src="/files/Jf2UIjIeZEGdALVnVqw0" alt=""><figcaption></figcaption></figure>
{% endtab %}

{% tab title="PrusaSlicer-SuperSlicer" %}
**PrusaSlicer**

```gcode
M190 S0 ; Prevents prusaslicer from prepending m190 to the gcode ruining our macro
M109 S0 ; Prevents prusaslicer from prepending m109 to the gcode ruining our macro
SET_PRINT_STATS_INFO TOTAL_LAYER=[total_layer_count] ; Provide layer information
START_PRINT EXTRUDER_TEMP=[first_layer_temperature[initial_extruder]] BED_TEMP=[first_layer_bed_temperature] PRINT_MIN={first_layer_print_min[0]},{first_layer_print_min[1]} PRINT_MAX={first_layer_print_max[0]},{first_layer_print_max[1]}
```

**SuperSlicer** - contamos con la opción de poder ajustar la temperatura de cerramiento (CHAMBER)

```gcode
M190 S0 ; Prevents prusaslicer from prepending m190 to the gcode ruining our macro
M109 S0 ; Prevents prusaslicer from prepending m109 to the gcode ruining our macro
SET_PRINT_STATS_INFO TOTAL_LAYER=[total_layer_count] ; Provide layer information
START_PRINT EXTRUDER_TEMP=[first_layer_temperature[initial_extruder]] BED_TEMP=[first_layer_bed_temperature] CHAMBER=[chamber_temperature] PRINT_MIN={first_layer_print_min[0]},{first_layer_print_min[1]} PRINT_MAX={first_layer_print_max[0]},{first_layer_print_max[1]}
```

![Ejemplo para PrusaSlicer/SuperSlicer](/files/pjTjXA4em3dU4zXV4zO8)
{% endtab %}

{% tab title="Cura" %}

```gcode
START_PRINT EXTRUDER_TEMP={material_print_temperature_layer_0} BED_TEMP={material_bed_temperature_layer_0} PRINT_MIN=%MINX%,%MINY% PRINT_MAX=%MAXX%,%MAXY%
```

{% hint style="warning" %}
Deberemos de instalar el plugin [**Post Process Plugin (by frankbags)**](https://gist.github.com/frankbags/c85d37d9faff7bce67b6d18ec4e716ff) desde el menú ***Help/Show*** configuration Folder... copiaremos el script del link anterior dentro de la carpeta script.\
Reiniciamos Cura e iremos a ***Extensions/Post processing/Modify G-Code*** y seleccionaremos ***Mesh Print Size***.
{% endhint %}
{% endtab %}

{% tab title="IdeaMaker" %}

```gcode
START_PRINT EXTRUDER_TEMP={temperature_extruder1} BED_TEMP={temperature_heatbed}
```

{% endtab %}

{% tab title="Simplify3D" %}

```gcode
START_PRINT EXTRUDER_TEMP=[extruder0_temperature] BED_TEMP=[bed0_temperature]
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
Los **placeholders son unos "alias" o variables que usan los laminadores para que a la hora de generar el gcode sustituyen por los valores configurados en el perfil** de impresión.

En los siguientes links podéis encontrar un listado de estos para: [**PrusaSlicer**](https://help.prusa3d.com/es/article/lista-de-placeholders_205643), [**SuperSlicer**](https://github.com/supermerill/SuperSlicer/wiki/Macro-&-Variable-list) (además de los del anterior), [**Bambu Studio**](https://wiki.bambulab.com/en/software/bambu-studio/placeholder-list) y [**Cura**](http://files.fieldofview.com/cura/Replacement_Patterns.html).

El uso de estos permiten que nuestras macros sean dinámicas.
{% endhint %}

* **gcode de final END\_PRINT**, en este caso al no usar placeholders es común a todos los laminadores

```gcode
END_PRINT
```

## Subir gcodes desde el laminador

Podemos subir nuestros gcodes directamente desde el laminador, algo que es muy cómodo. Moonraker emula la API de Octoprint, algo muy útil para hacerlo compatible con cualquier herramienta que use Octoprint.

Para habilitar la emulación Octoprint tendremos que añadir al ficher de configuración de Moonraker lo siguiente:

```cpp
[octoprint_compat]
```

{% tabs %}
{% tab title="PrusaSlicer/SuperSlicer (< v2.3.0)" %}
Habilitaremos el **modo experto** y cambiaremos las opciones en **Printer Settings / General** como podemos ver en la siguiente captura.

<figure><img src="/files/4mp16Ss5rzJPj9MnqnUZ" alt=""><figcaption></figcaption></figure>

{% hint style="warning" %}
**Os recordamos que lo hemos de configurar desde una "Impresora Física"**
{% endhint %}
{% endtab %}

{% tab title="Cura" %}
Instalaremos la **extensión OctoPrint-Connection desde el Marketplace**. Iremos a **Settings > Printer > Manage Printers** y buscaremos el botón **Connect OctoPrint** y añadiremos nuestra impresora tal como vemos en la siguiente captura, **podemos poner cualquier cosa en API Key**.

<figure><img src="/files/zzecLOE3hW7KvYcKeJwo" alt=""><figcaption></figcaption></figure>
{% endtab %}
{% endtabs %}

## Thumbnails

Podemos generar previews de nuestras piezas que podemos visualizar en nuestra UI de Klipper para identificar mejor la pieza.

![](/files/wUKlCI7kovv1iehomXjH)

{% tabs %}
{% tab title="OrcaSlicer" %}
OrcaSlicer suele funcionar directamente, tenemos las opciones para ajustar la generación en las opciones avanzadas del perfil de impresión:\
![](/files/gih4c7aIMy92fLweW9HO)
{% endtab %}

{% tab title="PrusaSlicer (< v2.3.0)" %}
Cambiaremos al **modo Experto** y en **General / Firmware** pondremos **32x32,400x300** en **G-code thumbnails**:

![](/files/rpOtELBo8PSWIYAxEaEH)

{% embed url="<https://youtu.be/4nFqfq8kikU>" %}
{% endtab %}

{% tab title="Superslicer (< v2.2.54.0)" %}
Cambiaremos al **modo Experto** y en **Printer Settings :**

![](/files/4arjrOQudnJEYGKLzjMk)

{% embed url="<https://youtu.be/xdOM5Uco9hM>" %}
{% endtab %}

{% tab title="Cura" %}
Instalaremos el plugin/extensión Cura2Moonraker y podemos seguir esta [**guía**](https://github.com/emtrax-ltd/Cura2MoonrakerPlugin)

![](/files/NKokhaNIAGdFeM1gVi1V)
{% endtab %}

{% tab title="IdeaMaker (< v4.2.1)" %}
Para que podamos disponer del progreso de capas en nuestra UI es aconsejable configurar correctamente nuestro laminador:

Para habilitar la previsualización abriremos **Advanced** en **Printer Settings**, habilitaremos la opción **Gcode Thumbnails for Pctoprint and Mainsail** y en **Resolution** pondremos **400x400**:

![](/files/apmbYZE2VHQt0D324YSu)
{% endtab %}
{% endtabs %}

## Progreso de capas

Para poder disponer del progreso de capas en nuestra UI de Klipper:

{% tabs %}
{% tab title="OrcaSlicer" %}
Para poder obtener más información detallada sobre el progreso de la impresión podemos mejorar desde el laminador de la siguiente manera:

* En las opciones de la impresora iremos a `Machine G-code`

<figure><img src="/files/sKgxMf7h7IrcTau9HJjB" alt=""><figcaption></figcaption></figure>

* Añadiremos lo siguiente en `Layer Change Gcode`

```
M117 Layer {layer_num+1}/[total_layer_count] : {filament_settings_id[0]}
SET_PRINT_STATS_INFO CURRENT_LAYER={layer_num + 1}
```

{% endtab %}

{% tab title="PrusaSlicer/SuperSlicer" %}

* Iremos a `Printer Settings` > `Custom Gcode` > `Start Gcode`

`SET_PRINT_STATS_INFO TOTAL_LAYER=[total_layer_count]`

* Iremos a `Printer Settings` > `Custom Gcode` > `After layer change Gcode` y añadiremos el siguiente gcode :

```gcode
SET_PRINT_STATS_INFO CURRENT_LAYER={layer_num + 1}
M117 Layer {layer_num+1}/[total_layer_count] : {filament_settings_id[0]}
```

<figure><img src="/files/kHZwiZDYPyJijy3kOO5G" alt=""><figcaption></figcaption></figure>
{% endtab %}

{% tab title="Cura" %}
En el caso de cura, la forma más rápida y sencilla, instalaremos la extensión `Display Filename and Layer on LCD`

También podremos además usar la extensión `Post processing` para ello:

* Abriremos el menu de extensiones y utilizaremos `Post processing`, haremos click en `Modify G-Code`
* Pulsaremos `Add Script` y seleccionamos `Search and Replace`
* En `Search` buscaremos por:

`;(LAYER|LAYER_COUNT):(\d+)`

* En `Replace` pondremos:

`;\1:\2\n_CURA_SET_PRINT_STATS_INFO \1=\2`

* Marcaremos `Use Regular Expresions` y cerramos

En nuestra configuración de Klipper añadiremos esta macro:

```
[gcode_macro _CURA_SET_PRINT_STATS_INFO]
gcode:
  {% if params.LAYER_COUNT is defined %}
    SET_PRINT_STATS_INFO TOTAL_LAYER={params.LAYER_COUNT}
  {% endif %}
  {% if params.LAYER is defined %}
    SET_PRINT_STATS_INFO CURRENT_LAYER={(params.LAYER | int) + 1}
  {% endif %}
```

{% endtab %}
{% endtabs %}

{% hint style="warning" %}
Nuestra UI de Klipper puede usar diferentes metodos para el cálculo del tiempo estimado de acabado (estimación y ETA). Normalmente podremos seleccionar el método que más nos guste o se ajuste a nuestra máquina en la configuración del UI y podremos, normalmente, seleccionar entre el fichero, filamento o el slicer:

![](/files/uuqV2IpVt3hyBnCX8xG1)\
En el caso de seleccionar varios hará una media de ellos.
{% endhint %}

En el caso que usemos KlipperScreen podemos mejorar la información mostrada sobre las capas ajustando:

## Coasting y Advanced extruder pressure

Estas opciones habilitadas puede provocar calidad pobre de nuestras impresiones y lo aconsejable es la utilización de [**Pressure Advance**](/klipper/empezamos/pressure-advance.md).

Por otro lado, las funciones que suelen ir bien es emplear los valores de retracciones desde el laminador, las opciones de wipe o wipe on retract.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://klipper.3dwork.io/klipper/empezamos/configuracion-klipper-en-laminadores.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
