# 3DWork.io - Klipper

[![](https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FvJoBFZltsRTZLqf0j497%2Fimage.png?alt=media\&token=3a8d094d-7608-4ad2-a7ef-0cb0e7869624) - English](https://klipper-3dwork-io.translate.goog/?_x_tr_sl=es&_x_tr_tl=en&_x_tr_hl=es&_x_tr_pto=wapp)

{% hint style="info" %}
El contenido de estas guías es gracias a la experiencia obtenida ayudando a compañeros de los diferentes grupos de nuestras redes sociales así como información o guías que creemos interesantes para nuestro hobby.

⚠️ **No nos hacemos responsables de cualquier daño que se pueda ocasionar en vuestras impresoras al aplicar cualquier sugerencia/solución a un problema/necesidad expuesto en las guías. Cada uno es responsable de sus máquinas.**

⚠️ **Si en algún punto hemos usado contenido de terceros y no hacemos referencia directa no es nuestra intención hacer nuestro el trabajo de otros si no que simplemente se nos ha olvidado hacerlo.**
{% endhint %}

<table data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th><th data-hidden data-card-cover data-type="files"></th></tr></thead><tbody><tr><td><strong>KLIPPER</strong> - Guías de instalación, configuración y mejoras relacionadas con este firmware de impresoras 3D</td><td></td><td></td><td><a href="/klipper/klipper-1">Klipper</a></td><td><a href="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/8vvQysyeYt9HAp4fYGaC/Klipper-logo_svg.svg.png">Klipper-logo_svg.svg.png</a></td></tr></tbody></table>


# Klipper

[**Klipper**](https://www.klipper3d.org/) es un firmware open-source creado por [**Kevin O'Connor**](https://www.patreon.com/koconnor) en 2016. A diferencia de Marlin —que corre completamente en la electrónica de la impresora—, Klipper divide el trabajo entre **dos piezas de hardware**: un ordenador host (habitualmente una Raspberry Pi u otro SBC con Linux) que se encarga de todo el procesado, y la electrónica de la impresora que actúa como gestor de motores y sensores.

El resultado: puedes sacarle todo el partido a electrónicas lentas y baratas, aplicar cambios de configuración sin recompilar nada y tener funciones avanzadas que en Marlin son imposibles o muy limitadas. Si ya tienes claro que quieres instalarlo, ve directamente a la [**guía de instalación**](/klipper/instalacion).

{% embed url="<https://t.me/Klipper_Firmware_ES>" %}
Grupo de Telegram en español para dudas y soporte de Klipper
{% endembed %}

## ¿Qué necesito saber antes de instalar Klipper?

Klipper no es difícil, pero sí requiere un mínimo de base técnica. Si vienes de Marlin con poca experiencia, prepárate para aprender algunas cosas nuevas. Si ya tienes soltura con ordenadores y sistemas Linux, la curva de aprendizaje es más suave de lo que parece.

**Conocimientos mínimos necesarios:**

* **SSH y terminal Linux**: tendrás que conectarte por SSH a tu Raspberry Pi para instalar componentes, revisar logs y lanzar comandos. No necesitas ser administrador de sistemas, pero sí saber abrir un terminal, moverte por directorios (`cd`, `ls`) y editar ficheros (`nano` o similar).
* **Edición de ficheros de texto**: la configuración de Klipper son ficheros `.cfg`. Tienes que sentirte cómodo abriéndolos, editándolos y guardándolos. No hay compilador: editas, guardas, reinicias Klipper y los cambios están activos.
* **Lectura de mensajes de error**: Klipper es muy explícito en sus errores. Cuando algo falla, el mensaje en Mainsail/Fluidd indica exactamente qué fichero y qué línea tiene el problema. Saber leer esos mensajes sin entrar en pánico es la habilidad más valiosa.
* **Paciencia en la puesta en marcha**: la primera instalación lleva tiempo. Es normal. Una vez tienes la máquina funcionando, los cambios futuros son rápidos.

**No necesitas:**

* Saber programar ni Python
* Compilar código (salvo el firmware inicial de la MCU, que se hace con un par de comandos guiados)
* Experiencia previa con Linux avanzado

{% hint style="success" %}
Si ya has usado OctoPrint con Marlin, tienes la mitad del camino hecho. La lógica de tener un host que controla la impresora te resultará familiar. El proceso de instalación está detallado paso a paso en la [guía de instalación](/klipper/instalacion).
{% endhint %}

## Cómo funciona Klipper — Arquitectura

En un ecosistema Klipper conviven varios componentes que trabajan juntos:

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/lXNdQfE3e6TsrNaHB5xR/image.png" alt=""><figcaption></figcaption></figure>

* **Host Klipper (Klippy)**: el programa principal que corre en el SBC. Lee los ficheros `.cfg`, procesa los G-codes durante la impresión y toma todas las decisiones de movimiento. Al correr en un procesador potente, puede hacer cálculos en tiempo real que una MCU de impresora no podría.
* **MCU Klipper**: la electrónica de la impresora. Con Klipper, la MCU ya no "piensa" — solo recibe órdenes del host (mover este motor X pasos, leer este sensor, activar este calentador) y las ejecuta. Esto es lo que permite usar electrónicas antiguas y lentas con excelentes resultados.
* **Moonraker**: la API que hace de puente entre Klipper y el resto del mundo. Las interfaces web, las aplicaciones móviles y las integraciones externas hablan con Moonraker, que traduce esas peticiones a comandos para Klipper.
* **Interfaz web** (Mainsail, Fluidd): el panel de control visual. Desde aquí monitorizas temperaturas, lanzas impresiones, ejecutas macros y ajustas la configuración. Son accesibles desde cualquier navegador de tu red local.
* **KlipperScreen** (opcional): una interfaz táctil para pantallas conectadas directamente al SBC. Ideal si quieres controlar la impresora sin abrir el ordenador.

{% hint style="info" %}
Una de las grandes ventajas de esta arquitectura es que puedes actualizar Klipper en segundos desde la propia interfaz web, sin tocar la electrónica. Los cambios de configuración se aplican con un simple reinicio del servicio, no con una recompilación y flasheo.
{% endhint %}

## El ecosistema actual

Klipper ha crecido mucho desde sus inicios. Hoy tienes varias opciones para instalarlo y gestionarlo.

### Distribuciones listas para usar

La forma más rápida de empezar: imagen lista para grabar en tu tarjeta SD con todo preinstalado. Consulta la [guía de instalación](/klipper/instalacion) para el proceso detallado de cada una.

| Distribución   | Descripción                                                                                                                                            |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **MainsailOS** | La más usada. Raspberry Pi con Klipper + Moonraker + Mainsail preinstalados. Lista en minutos. Recomendada para empezar.                               |
| **FluiddPI**   | Igual que MainsailOS pero con Fluidd como interfaz.                                                                                                    |
| **RatOS**      | Orientada a impresoras RatRig pero compatible con muchas otras. Incluye configuraciones base muy completas y un sistema de overrides muy bien pensado. |

### Instalador manual

| Herramienta | Descripción                                                                                                                                                                                                                                                  |
| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **KIAUH**   | Script interactivo en bash que instala y gestiona todos los componentes de Klipper. La opción más flexible si no usas Raspberry Pi o quieres control total sobre la instalación. Ver [guía de instalación con KIAUH](/klipper/instalacion#instalando-kiauh). |

### Variantes de Klipper

| Variante                       | Descripción                                                                                                                                                                                                                                                                               |
| ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Klipper oficial**            | La versión estándar mantenida por Kevin O'Connor y la comunidad. La referencia, la más estable.                                                                                                                                                                                           |
| **Kalico** (ex Danger Klipper) | Fork con funciones experimentales que aún no están en el oficial: mejoras en Input Shaper, gestión de temperatura avanzada, `minimum_cruise_ratio` (incorporado ya en el oficial), y otras optimizaciones. Adecuado para usuarios que quieren lo último aunque no esté 100% estabilizado. |

### Interfaces disponibles

| Interfaz           | Tipo            | Descripción                                                                        |
| ------------------ | --------------- | ---------------------------------------------------------------------------------- |
| **Mainsail**       | Web             | La más completa y popular. Gestión avanzada de macros, historial, actualizaciones. |
| **Fluidd**         | Web             | Más ligera, muy limpia visualmente. Buena opción en hardware con poca RAM.         |
| **KlipperScreen**  | Pantalla táctil | Para pantallas conectadas directamente al SBC.                                     |
| **OctoEverywhere** | Acceso remoto   | Acceso seguro desde fuera de tu red sin abrir puertos.                             |
| **Mobileraker**    | App móvil       | Control desde Android/iOS.                                                         |

## Klipper vs Marlin — Comparativa actualizada (2025)

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/MXSVpEFyxojqIHsdJ8TE/image.png" alt=""><figcaption></figcaption></figure>

|                                 | **Klipper**                                                                                                                                                                  | **Marlin**                                                                                                            |
| ------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| **Arquitectura**                | Host (SBC Linux) + MCU como esclavo. Todo el procesado en el host.                                                                                                           | Firmware compilado íntegramente en la MCU de la electrónica.                                                          |
| **Configuración**               | Ficheros `.cfg` de texto plano. Cambios sin recompilar: editas, reinicias servicio, listo.                                                                                   | Requiere recompilar y reflashear la electrónica para cambiar funciones o parámetros de firmware.                      |
| **Velocidad de impresión**      | Muy alta. El procesado en el host elimina los cuellos de botella de la MCU. Con Input Shaper calibrado, 300-500 mm/s es realista en máquinas preparadas.                     | Buena en electrónicas modernas de 32 bits. Limitada por la capacidad de cálculo de la MCU.                            |
| **Input Shaping**               | Muy maduro. Calibración con acelerómetro (ADXL345, LIS2DW12). Klipper 0.13: **sweeping resonance testing** (barre frecuencias en movimiento continuo, más rápido y preciso). | Disponible desde Marlin 2.1.2. Funcional pero menos flexible. También requiere acelerómetro para calibración precisa. |
| **Pressure / Linear Advance**   | Pressure Advance muy preciso. Proceso de calibración ágil mediante macros.                                                                                                   | Linear Advance. Compatible con muchas electrónicas y bien documentado.                                                |
| **Mallado de cama**             | Mallado adaptativo nativo (Klipper 0.12+). Sondea solo el área que ocupa la pieza. Compatible con BLTouch, sensores inductivos, Eddy, etc.                                   | Bilineal con parámetros de área (`L/R/F/B`) o UBL para mallas guardadas. Funcional pero menos integrado.              |
| **Macros**                      | Sistema de macros muy potente (Jinja2). Puedes crear flujos complejos: inicio automático, calibración, cambio de filamento, notificaciones, etc.                             | G-code scripts básicos. Menos flexibles.                                                                              |
| **Soporte multiMCU**            | Soporte nativo. Puedes conectar varias placas a un mismo Klipper: MCU principal + toolhead CAN + host como MCU.                                                              | No soportado.                                                                                                         |
| **CANbus**                      | Soporte nativo y maduro. Toolheads como EBB36, EBB42, SB2209, SB2240.                                                                                                        | No soportado.                                                                                                         |
| **Pantalla LCD**                | Soporte limitado para LCDs en la MCU. KlipperScreen resuelve esto para pantallas en el SBC.                                                                                  | Soporte amplio y maduro para pantallas LCD estándar RepRap.                                                           |
| **Instalación**                 | Requiere configurar un SBC adicional. Las distribuciones (MainsailOS, FluiddPI) y la [guía de instalación](/klipper/instalacion) simplifican mucho el proceso.               | Compilar y flashear. Sencillo con VSCode + PlatformIO. Sin hardware adicional.                                        |
| **Compatibilidad electrónicas** | Muy amplia y creciendo. Prácticamente todas las placas modernas están soportadas.                                                                                            | La más amplia del mercado, incluyendo electrónicas antiguas de 8 bits.                                                |
| **Comunidad y documentación**   | Documentación oficial excelente. Comunidad muy activa en Discord, Telegram y grupos específicos de máquinas.                                                                 | Documentación extensísima. La base de usuarios más grande del mundo.                                                  |

{% hint style="info" %}
**Estado en 2025**: Marlin ha cerrado distancias. La versión 2.1.2+ incluye Input Shaping con acelerómetro y el G29 Bilineal acepta parámetros de área para mallado adaptativo básico. Sigue siendo la mejor opción para impresoras de entrada/media gama con electrónicas sencillas, sin querer complicarse.

Klipper sigue siendo la referencia para máquinas de alto rendimiento, setups personalizados y cualquiera que quiera exprimir al máximo su impresora. La brecha de rendimiento se nota especialmente a partir de 150 mm/s.
{% endhint %}

## Novedades recientes en Klipper

### Klipper 0.13.0 — Abril 2025

La versión más reciente con mejoras importantes:

* **Sweeping resonance testing**: el nuevo método de calibración de Input Shaper barre las frecuencias mientras la máquina se mueve de forma continua, en lugar de vibrar a frecuencias fijas. Resultado: calibración más rápida y lecturas más precisas, especialmente en máquinas con múltiples picos de resonancia o cinemáticas complejas.
* **`minimum_cruise_ratio`** reemplaza a `max_accel_to_decel`: control más intuitivo de la velocidad de crucero en movimientos cortos. El valor recomendado es `0.5` (50% de la velocidad máxima para tramos de crucero muy cortos). Si migras de una versión anterior, elimina `max_accel_to_decel` de tu config y añade `minimum_cruise_ratio: 0.5`.
* **Mallado adaptativo nativo**: `BED_MESH_CALIBRATE ADAPTIVE=1` ya no requiere KAMP. Klipper calcula automáticamente el área de la pieza y sondea solo esa zona, directamente desde el slicer.
* **Soporte RP2350**: el nuevo chip de Raspberry Pi (Pi Pico 2) ya está soportado.
* **RP2040 a 200 MHz**: las placas basadas en RP2040 (como BTT SKR Pico) pueden correr a mayor frecuencia, mejorando la resolución de pasos.

### Klipper 0.12.0 — Noviembre 2023

* **Modos IDEX COPY y MIRROR**: impresión dual con dos cabezales en paralelo (copiar la pieza) o en espejo, para setups IDEX.
* **Soporte TMC2240**: drivers de alto rendimiento para setups exigentes con motores de mayor par.
* **Axis Twist Compensation**: corrección de torsión del eje X o Y para impresoras con gantries con ligera torsión mecánica.

## Hardware necesario

### El host (SBC)

| Hardware                            | Valoración                                                                                                                   |
| ----------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| **Raspberry Pi 3B+**                | Mínimo recomendado. Funciona bien para la mayoría de impresoras.                                                             |
| **Raspberry Pi 4 (2 GB+)**          | La opción más cómoda. Sobrada para cualquier setup. Recomendada si quieres correr cámara, timelapse y servicios adicionales. |
| **Raspberry Pi 5**                  | Más que suficiente. Especialmente útil para setups exigentes o múltiples instancias Klipper.                                 |
| **BTT Pi / Mellow FLY-Pi**          | Alternativas más económicas al Raspberry Pi con soporte oficial de Klipper. Buena opción si hay falta de stock.              |
| **Orange Pi / Rock Pi / similares** | Compatible via KIAUH. Más económicos, soporte de la comunidad (no oficial).                                                  |
| **PC o portátil viejo**             | Perfectamente válido si tiene Linux. Consume más energía pero funciona.                                                      |

{% hint style="warning" %}
La versión de Raspberry Pi 4 con **1 GB de RAM** puede quedarse justa si corres Klipper + cámara + timelapse de forma simultánea. La versión de 2 GB o superior es más cómoda.
{% endhint %}

### La electrónica (MCU)

Prácticamente cualquier placa de impresora 3D moderna funciona con Klipper. Algunas de las más habituales:

* **BTT**: Octopus, Octopus Pro, Manta M8P/M5P, SKR series, Kraken
* **Fysetc**: Spider, S6
* **MKS**: Robin Nano, Skipr
* **Creality**: electrónicas de Ender 3 S1, Neo, algunas directamente, otras con adaptaciones
* **Placas de 8 bits** (RAMPS, Melzi...): funcionan, pero la velocidad de comunicación limita la frecuencia de pasos máxima. Úsalas solo si no tienes otra opción.

Para la lista completa de electrónicas soportadas, consulta la [documentación oficial de Klipper](https://www.klipper3d.org/Overview.html).

## ¿Es Klipper para mí?

**Klipper encaja bien si:**

* Quieres imprimir rápido (150+ mm/s con calidad) sin sacrificar acabado
* Tienes o quieres montar una impresora tipo Voron, RatRig, Vzbot u otra CoreXY de alto rendimiento
* Quieres calibración automática avanzada (Input Shaper con acelerómetro, mallado adaptativo, Pressure Advance automatizado con macros)
* Disfrutas trastear, personalizar y entender cómo funciona tu máquina por dentro
* Tu electrónica es antigua o limitada y quieres exprimir al máximo la impresora sin cambiar la placa
* Quieres un sistema de macros potente para automatizar procesos: inicio, purga, cambio de filamento, notificaciones, etc.
* Tienes una impresora multimaterial, IDEX o configuración especial que Marlin no soporta bien

**Marlin puede ser mejor opción si:**

* Tienes una impresora cerrada o semi-cerrada donde no quieres meterte en profundidad
* Tu impresora es básica (Ender 3, Artillery, etc.) y ya funciona bien sin modificaciones
* No te apetece aprender Linux ni SSH
* Quieres algo que funcione sin necesidad de ajustar nada, que "simplemente funcione"
* No quieres instalar hardware adicional (el SBC)

{% hint style="success" %}
**La experiencia habitual**: muchos usuarios de Marlin que dan el salto a Klipper reconocen que la puesta en marcha inicial les costó más de lo esperado, pero que a las pocas semanas ya no querrían volver. La clave está en la paciencia inicial y en tener claro que la curva de aprendizaje al principio es empinada pero corta.
{% endhint %}

## Por dónde empezar

Si has decidido instalar Klipper, el camino más directo es:

1. **Instalar MainsailOS** en tu Raspberry Pi → sigue la [**guía de instalación**](/klipper/instalacion), en 15 minutos tienes el host listo
2. **Compilar y flashear el firmware** en tu electrónica → específico para tu placa, detallado en la guía
3. **Configurar el `printer.cfg`** con los parámetros de tu impresora
4. **Calibrar** paso a paso: PID, extrusor, nivelación, Input Shaper, Pressure Advance

{% content-ref url="/pages/-MXbzxFcjgWJXG3b4v51" %}
[Instalación](/klipper/instalacion)
{% endcontent-ref %}

{% content-ref url="/pages/-M\_\_AtRY62iB7N60gJTS" %}
[Configuración](/klipper/empezamos)
{% endcontent-ref %}

Si tienes dudas durante el proceso, el grupo de Telegram en español es el sitio más rápido para resolverlas:

{% embed url="<https://t.me/Klipper_Firmware_ES>" %}


# Instalación

***

## Instalación

{% hint style="info" %}
**English**: Use your browser's built-in translation — Chrome and Edge detect the language automatically and offer to translate the page.
{% endhint %}

### ¿Qué necesitamos?

* **Raspberry Pi o cualquier host que pueda correr Linux**, normalmente se aconseja Raspberry Pi dado que la mayoría de distribuciones y herramientas son totalmente compatibles con ellas y en otros dispositivos se ha de realizar una instalación manual e incluso adaptar algunas partes.

{% hint style="success" %}
Si elegimos instalar nuestro host Klipper en una Raspberry Pi, es aconsejable al menos una Raspberry Pi 3B/Zero W 2 o superior.

También es importante que el cargador que alimente esta sea el oficial o uno adecuado para alimentar estos tipos de dispositivos.

Otras alternativas populares y completamente compatibles con MainsailOS/Klipper:

* **BTT Pi / CB2** — placas SBC de Bigtreetech, muy comunes en impresoras BTT y Voron
* **Mellow FLY-Pi / Gemini** — alternativas de Mellow con buena compatibilidad
* **Orange Pi Zero 2W / 3 LTS** — opción económica con imágenes Armbian compatibles

En todos estos casos los requerimientos de hardware son similares: mínimo 1 GB RAM, almacenamiento eMMC o SD de buena calidad.
{% endhint %}

* **SD**, aconsejable que sea rápida y con espacio suficiente para almacenar el sistema y archivos gcode normalmente entre 16-64Gb que sea de Class 10 (velocidad).
* **Cable conexión entre nuestra Pi y nuestra electrónica/impresora**, ya sea USB que es lo más normal o vamos a conectar usando USART u otro tipo de conexión como CAN disponer del cable correspondiente en cada caso.\
  Es importante que este cable sea de la mayor calidad y que este quede correctamente conectado/fijado entre dispositivos para evitar que las vibraciones o movimientos de nuestra máquina puedan afectar a la conexión.

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FuK9y7dfVBAiM67eNULFk%2Fimage.png?alt=media&amp;token=61fc6a73-1cb0-4774-96cf-8d4bd9de7e29" alt=""><figcaption></figcaption></figure>

### Guías para hosts alternativos

Además de Raspberry Pi, Klipper puede instalarse en otros dispositivos. Tenemos guías específicas para:

<table data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Klipper en Android</strong><br>Recicla un teléfono o tablet Android como host Klipper con Linux Deploy o UserLAnd.</td><td></td><td><a href="/klipper/instalacion/klipper-en-android">Klipper en Android</a></td></tr><tr><td><strong>Raspberry Pad 5</strong><br>Guía específica para el kit todo-en-uno de BTT con pantalla integrada.</td><td></td><td><a href="/klipper/instalacion/klipper-en-raspberry-pad-5">Klipper en Raspberry Pad 5</a></td></tr><tr><td><strong>Orange Pi Zero Plus</strong><br>Alternativa económica con Orange Pi Zero Plus como host Klipper.</td><td></td><td><a href="/klipper/instalacion/klipper-en-orange-pi-zero-plus">Klipper en Orange Pi Zero Plus</a></td></tr><tr><td><strong>PC con Windows (WSL)</strong><br>Instala Klipper usando el Subsistema de Windows para Linux.</td><td></td><td><a href="/klipper/instalacion/klipper-en-pc-con-windows-usando-wsl">Klipper en PC con Windows (Usando WSL)</a></td></tr><tr><td><strong>Múltiples instancias</strong><br>Corre varias impresoras desde un mismo host Klipper.</td><td></td><td><a href="/klipper/instalacion/multiples-instancias-klipper">Múltiples instancias Klipper</a></td></tr><tr><td><strong>Guías específicas por impresora</strong><br>Instalación Klipper para Creality (Sonic Pad), Artillery y otros modelos.</td><td></td><td><a href="/klipper/instalacion/guias-instalacion-especificas-impresora-electronica">Guías Instalación específicas impresora/electrónica</a></td></tr></tbody></table>

### **Antes de comenzar!!!**

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/X80gAmPPLStcEvFTI7hx/image.png)

Por favor entiende que instalar **Klipper** en tu impresora require de cierta experiencia con impresoras 3d, hardware y software. Puede no ser una tarea trivial para gente que se acaba de iniciar en el mundo 3D o que no dispone de unos mínimos conocimientos ya que puedes romper tu impresora o pi durante el proceso

Lee antes la guía completa y entiende todos los pasos que explicamos. Si tienes cualquier duda del proceso por favor te aconsejamos unirte al grupo de Telegram <https://t.me/Klipper_Firmware_ES> donde seguro te echaran una mano.

{% hint style="danger" %}
**No nos hacemos cargo de cualquier daño, problema o fallo que se pueda ocasionar siguiendo estas guías, todos los pasos han sido probados o son las instrucciones de los propios fabricantes/desarrolladores y no deberían de ocasionar fallos.**

**Se intentan mantener al día pero puede darse el caso que, por actualizaciones, estos pasos puedan variar sin previo aviso.**

**Estás haciendo estos cambio bajo tu propia responsabilidad!!!**
{% endhint %}

### Instalando Klipper usando imágenes preconfiguradas para Raspberry Pi

Aunque os mostraremos como instalar el sistema usando un sistema base de Raspberry también **disponemos de distribuciones de Klipper con todo preinstalado que suele ser la alternativa más sencilla y rápida para tener nuestro Klipper montado en especial para usuarios sin experiencia en Linux o Klipper**.

Principalmente contamos con varias distribuciones: **MainsailOS** especialmente indicada para usuarios que comienzan con Klipper, **FluiddOS** como alternativa a MainsailOS con interfaz Fluidd, y **RatOS** para usuarios más experimentados que quieran sacar provecho de su configuración modular y macros avanzadas.

{% hint style="info" %}
Os aconsejamos instalar como complemente a cualquier distribución/imagen de Klipper que os sugerimos a continuación que os [**instaléis Kiauh**](#instalando-kiauh) ya que añade una serie de ayudas extras interesantes.
{% endhint %}

<table data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-cover data-type="files"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>MainsailOS</strong>: La distribución Klipper con todos los componentes preinstalados lo cual nos ahorra bastante tiempo.<br>Especialmente indicado si tenemos una Raspberry Pi o Orange Pi.</td><td></td><td></td><td><a href="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FwdLNlnN97Ed8169wtanz%2Fmainailos-sdcard-logo.png?alt=media&amp;token=a6b79ce0-f3d9-428b-95dc-89dd86f43a16">mainailos-sdcard-logo.png</a></td><td><a href="#mainsailos">#mainsailos</a></td></tr><tr><td><strong>RatOS:</strong> Otra distribución de Klipper basada en MainsailOS y que además soporta hosts, aparte de los soportados por MainsailOS, CB1 de Bigtreetech.<br>Destaca sobre MainsailOS por su soporte nativo a impresoras Ratrig, Voron y Prusa con sus configuraciones modulares.<br>Además, cuenta con extensiones y macros muy potentes instaladas.</td><td></td><td></td><td><a href="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FHbwQ1VB99KIJYJHBi8qN%2Fimage.png?alt=media&amp;token=6fecf929-4de4-4129-888b-a26b9689201b">image.png</a></td><td><a href="#ratos">#ratos</a></td></tr><tr><td><strong>Kiauh</strong>: es un grandísimo avance para Klipper. Kiauh permite mediante unos sencillos menus instalar Klipper y sus principales componentes de una forma sencilla.<br>En este caso podremos instalar y gestionar Klipper en cualquier tipo de host.</td><td></td><td></td><td><a href="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2F29QNibFvOMTj0vMwBLjq%2Fimage.png?alt=media&amp;token=d03732bd-3cb4-4e93-9305-25436835d2b5">image.png</a></td><td><a href="#kiauh-instalando-klipper-de-forma-manual-asistida">#kiauh-instalando-klipper-de-forma-manual-asistida</a></td></tr></tbody></table>

{% tabs %}
{% tab title="MainsailOS" %}

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FWYnU9jPXQbs2D6MxNxPv%2Fimage.png?alt=media&amp;token=eab30777-1958-4dc7-8cd5-5b29457caf11" alt="" width="188"><figcaption></figcaption></figure>

Una de las opciones es usar la distribución de Mainsail llamada **MainsailOS**:

1. **Descargaremos** la última versión de **MainsailOS** desde [**aquí**](https://github.com/mainsail-crew/MainsailOS/releases) **desde el apartado Assets que deberemos desplegar o hacer mostrar todos los que existen**. Disponemos de soporte para basados en Raspberry y Armbian (OrangePi) que podemos identificar por el nombre fácilmente.\
   ![](https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2Fdkf8s0jLzByicXFFyCCk%2Fimage.png?alt=media\&token=537e76f8-1353-4da4-9e1d-76d1c37e4c5b)

{% hint style="info" %}
**DESCARGA DE LA IMAGEN DESDE RASPBERRY PI IMAGER DIRECTAMENTE:**\
En el caso que utilicemos [**Raspberry Pi Imager**](https://www.raspberrypi.com/software/) directamente desde sus opciones podremos elegir que se descargue MainsailOS desde la opción `CHOOSE OS`:

<img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FoHZ5z7v3AxPkfI5rktuY%2Fimage.png?alt=media&amp;token=72e8f4ae-2936-4419-8cec-9f8eccc83355" alt="" data-size="original">
{% endhint %}

{% hint style="warning" %}
**La selección de la imagen de Raspberry Pi OS 32b o 64b dependerá que nuestra Pi la soporte:**

<img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/ylgfMdhUk4KlhrRLCncr/image.png" alt="" data-size="original">

Normalmente la instalación de la versión 32b suele ser más segura aunque actualmente los diferentes componentes de Klipper así como sus dependencias (Python) soportan sin problema entornos de 32/64b.

Identificaremos entre 32b o 64b para SBC Raspberry por el nombre del fichero:

<img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FSp6jXwd1oKdJ7xpLJZ0E%2Fimage.png?alt=media&amp;token=0c5c77c2-2b12-4d6e-b50a-91123299983b" alt="" data-size="original">

Aparecen varios ficheros a descargar, el correcto (fijarse en el tamaño) suele ser el acabado en .img.xz:

<img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2Fz31WuH8r2Nwws8ZLuyUE%2Fimage.png?alt=media&amp;token=41ff20b7-5043-4e09-bb01-12364b3b5c05" alt="" data-size="original">
{% endhint %}

1. Descomprimiremos el zip donde obtendremos un .img
2. Utilizando [**BalenaEtcher**](https://www.balena.io/etcher/) o [**Raspberry Pi Imager**](https://www.raspberrypi.com/software/) escribiremos .img a nuestra SD (8GB o mayor además de idealmente que sea una SD de alta velocidad)

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FUHmSbwnQMJHlKhbueOEA%2Fchrome-capture-2024-3-18.gif?alt=media&amp;token=372c820a-dd75-48f0-af3b-8240ba4c007f" alt=""><figcaption></figcaption></figure>

{% hint style="danger" %}
**ESTE PROCESO BORRARÁ TODO EL CONTENIDO DE NUESTRA SD.**
{% endhint %}

* Colocaremos la SD en nuestro host y alimentaremos para que arranque.

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FXLZbLR3TjMAVmGMKN2K2%2Fchrome-capture-2024-3-182.gif?alt=media&amp;token=1c9f1c95-5f19-4366-a957-9bd64e6de848" alt=""><figcaption></figcaption></figure>

* Si usamos wifi, y no hicimos la configuración de esta en el caso de usar Raspberry Pi Imager, editaremos el fichero *mainsailos-wpa-supplicant.txt* donde añadiremos la información de nuestra red wifi.
* Una vez todo iniciado comprobaremos que podemos acceder al interfaz web de Klipper, cuando [encontremos la IP asignada de nuestra red a nuestro host](/klipper/empezamos/puesta-en-marcha-inicial#conexion-al-interfaz-web-de-klipper), ya podremos conectar nuestra impresora a nuestro host.

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2F43AGieFKzFS2F6WygL8W%2Fchrome-capture-2024-3-183.gif?alt=media&amp;token=3daab8e0-5083-4f03-ad97-95427a2cb883" alt=""><figcaption></figcaption></figure>

{% hint style="success" %}
**Una vez tengamos instalado nuestro Klipper os sugerimos continuar con la** [**guía de primeros pasos en Klipper**](/klipper/empezamos/puesta-en-marcha-inicial) **donde veremos como conectarnos al interfaz web, SSH, primeras comprobaciones y ajustes, etc...fácilmente**
{% endhint %}
{% endtab %}

{% tab title="FluiddOS" %}

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/cn1b31Dv4YfG6WKT7YWl/image.png" alt="" width="188"><figcaption></figcaption></figure>

**FluiddOS** es la distribución oficial de Fluidd, con todos los componentes de Klipper preinstalados y la interfaz Fluidd como front-end. Es una excelente alternativa a MainsailOS para quienes prefieran Fluidd.

1. Descarga la última versión desde [**aquí**](https://github.com/fluidd-core/FluiddPI/releases) desde el apartado Assets. Hay versiones para Raspberry Pi y Armbian (Orange Pi).
2. Descomprime el .img.xz
3. Escribe la imagen con [**Raspberry Pi Imager**](https://www.raspberrypi.com/software/) o [**BalenaEtcher**](https://www.balena.io/etcher/) en tu SD (mínimo 8 GB, Class 10 o superior)

{% hint style="danger" %}
**ESTE PROCESO BORRARÁ TODO EL CONTENIDO DE NUESTRA SD.**
{% endhint %}

* Coloca la SD en el host y alimenta para que arranque.
* Si usas wifi, edita el fichero *fluiddpi-wpa-supplicant.txt* con los datos de tu red antes del primer arranque.
* Una vez iniciado, accede al interfaz web cuando encuentres la IP del host en tu red.

{% hint style="success" %}
**Una vez tengamos instalado nuestro Klipper os sugerimos continuar con la** [**guía de primeros pasos en Klipper**](/klipper/empezamos/puesta-en-marcha-inicial) **donde veremos como conectarnos al interfaz web, SSH, primeras comprobaciones y ajustes, etc...**
{% endhint %}
{% endtab %}

{% tab title="RatOS" %}

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FHbwQ1VB99KIJYJHBi8qN%2Fimage.png?alt=media&amp;token=6fecf929-4de4-4129-888b-a26b9689201b" alt=""><figcaption></figcaption></figure>

Al igual que Mainsail **RatOS** de Ratrig también ha creado una distribución con todo instalado para sus máquinas basado en Mainsail y que sin duda aún sin tener una Ratrig, también tiene soporte por defecto para máquinas Voron y Prusa, las macros que incluyen puede ser una gran base para nuestro Klipper.

1. Descargaremos la última versión de RatOS desde [**aquí**](https://github.com/Rat-OS/RatOS/releases) **desde el apartado Assets que deberemos desplegar o hacer mostrar todos los que existen**. Disponemos de soporte para basados en Raspberry y CB1 (Bigtreetech) que podemos identificar por el nombre facilmente.\
   ![](https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2Fdk6j9hqxB3DApJTrZk06%2Fimage.png?alt=media\&token=5d5016a5-1e31-40a2-bdc3-cfedf3c6345f)
2. Descomprimiremos el zip donde obtendremos un .img
3. Utilizando [**BalenaEtcher**](https://www.balena.io/etcher/) o [**Raspberry Pi Imager**](https://www.raspberrypi.com/software/) escribiremos .img a nuestra SD (8GB o mayor además de idealmente que sea una SD de alta velocidad)

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FUHmSbwnQMJHlKhbueOEA%2Fchrome-capture-2024-3-18.gif?alt=media&amp;token=372c820a-dd75-48f0-af3b-8240ba4c007f" alt=""><figcaption></figcaption></figure>

{% hint style="danger" %}
**ESTE PROCESO BORRARÁ TODO EL CONTENIDO DE NUESTRA SD.**
{% endhint %}

* Colocaremos la SD en nuestro host y alimentaremos para que arranque.

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FXLZbLR3TjMAVmGMKN2K2%2Fchrome-capture-2024-3-182.gif?alt=media&amp;token=1c9f1c95-5f19-4366-a957-9bd64e6de848" alt=""><figcaption></figcaption></figure>

* RatOS crea un **punto de acceso wifi llamado RatOS** al que podremos conectarnos para realizar la configuración una vez conectados [http://RatOS.local/configure](http://ratos.local/configure) o <http://192.168.50.1/configure> para configurar los parámetros de nuestra wifi.
* Una vez todo iniciado comprobaremos que podemos acceder al interfaz web de Klipper, cuando [encontremos la IP asignada de nuestra red a nuestro host](/klipper/empezamos/puesta-en-marcha-inicial#conexion-al-interfaz-web-de-klipper), ya podremos conectar nuestra impresora a nuestro host.

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2F43AGieFKzFS2F6WygL8W%2Fchrome-capture-2024-3-183.gif?alt=media&amp;token=3daab8e0-5083-4f03-ad97-95427a2cb883" alt=""><figcaption></figcaption></figure>

{% hint style="success" %}
**Una vez tengamos instalado nuestro Klipper os sugerimos continuar con la** [**guía de primeros pasos en Klipper**](/klipper/empezamos/puesta-en-marcha-inicial) **donde veremos como conectarnos al interfaz web, SSH, primeras comprobaciones y ajustes, etc...**
{% endhint %}
{% endtab %}

{% tab title="Kiauh" %}
Kiauh : Instalando Klipper de forma manual asistida

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2F29QNibFvOMTj0vMwBLjq%2Fimage.png?alt=media&amp;token=d03732bd-3cb4-4e93-9305-25436835d2b5" alt=""><figcaption></figcaption></figure>

**Kiauh** es un grandísimo avance para Klipper. Kiauh permite mediante unos sencillos menus instalar Klipper y sus principales componentes de una forma sencilla:

* Instalación de Klipper
* Instalar Moonraker (API que permite interactuar con Klipper por terceros como Mailsail, Fluidd o KlipperScreen)
* Instalación de diferentes interfaces web como Mainsail, Fluidd, Duet Web Control o Octoprint
* Instalar KlipperScreen (un fork de OctoScreen para Klipper)
* Actualizar todos los componentes (Octoprint de ser instalado se gestionará directamente desde el mismo)
* Eliminar cualquier componente
* Hacer un backup del sistema
* Preparar el firmware Klipper para nuestra MCU (placa de la impresora)
* Detectar el serial donde comunicar con nuestras MCU

Puedes encontrar un listado completo de las características [aquí](https://github.com/th33xitus/kiauh/blob/master/docs/features.md).

**Kiauh se hace una herramienta indispensable en el caso que optemos por una distribución Linux que no cuente preinstalados los componentes Klipper.**

#### Preparación de nuestro host Klipper

{% hint style="danger" %}
**ESTE PASO ES NECESARIO SI NO HEMOS OPTADO POR UTILIZAR UNA DISTRIBUCIÓN CON TODO INSTALADO COMO LAS ANTERIORES SUGERIDAS.**

**ESTE PROCESO NO ES ACONSEJABLE PARA USUARIOS SIN UN MINIMO EXPERIENCIA EN LINUX O KLIPPER.**
{% endhint %}

Para poder instalar Klipper debemos preparar nuestro host Klipper. Esta guía no va a entrar en detalle este paso tan solo haremos un listado rápido de los pasos a seguir basados en un host como Raspberry Pi:

* Descargaremos una imagen de [Raspberry Pi OS Lite](https://www.raspberrypi.org/documentation/installation/installing-images/README.md) y la "quemaremos" en nuestra SD usando [**BalenaEtcher**](https://www.balena.io/etcher/) o [**Raspberry Pi Imager**](https://www.raspberrypi.com/software/).\
  En el caso que no uses una Pi usaremos la imagen del sistema más adecuado a nuestro host

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FUHmSbwnQMJHlKhbueOEA%2Fchrome-capture-2024-3-18.gif?alt=media&amp;token=372c820a-dd75-48f0-af3b-8240ba4c007f" alt=""><figcaption></figcaption></figure>

* Colocaremos la SD en nuestro host y alimentaremos para que arranque.

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FXLZbLR3TjMAVmGMKN2K2%2Fchrome-capture-2024-3-182.gif?alt=media&amp;token=1c9f1c95-5f19-4366-a957-9bd64e6de848" alt=""><figcaption></figcaption></figure>

* Verificaremos que nuestro host Klipper arranca y podemos conectarnos por red wifi o cable
* Habilitaremos SSH y verificaremos que podemos conectar por SSH
* En el caso que nuestro host Klipper sea una Pi:
  1. Ejecutaremos `sudo raspi-config`
     1. Haremos un reset del password por defecto
     2. configuraremos el hostname si queremos
* Ejecutaremos `sudo apt-get update` y `sudo apt-get upgrade` para actualizar nuestra pi

{% hint style="warning" %}
**La selección de la imagen de Raspberry Pi OS 32b o 64b dependerá que nuestra Pi la soporte:**

<img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/ylgfMdhUk4KlhrRLCncr/image.png" alt="" data-size="original">

**Normalmente la instalación de la versión 32b suele ser más segura aunque actualmente los diferentes componentes de Klipper así como sus dependencias (Python) soportan sin problema entornos de 32/64b**
{% endhint %}

#### Instalando Kiauh

Ahora que ya tenemos el sistema base en nuestro host Klipper, esta actualizado y podemos conectarnos por SSH a ella comenzaremos a instalar Kiauh

```bash
sudo apt-get update && sudo apt-get install git -y
cd ~ && git clone https://github.com/dw-0/kiauh.git
./kiauh/kiauh.sh
```

{% hint style="info" %}
Con estos comandos hacemos...

* Instalamos git para la gestión de repositorios
* Clonamos el repositorio de Kiauh
* Permitimos que los scripts descargados puedan ser ejecutados
* Ejecutamos Kiauh

Si necesitamos volver a lanzar Kiauh en el futuro podemos ir a `home/pi/kiauh (o el path de instalación elegido) y ejecutar ./kiauh.sh`
{% endhint %}

Una vez hemos realizado el proceso completo y lanzamos Kiauh deberíamos ver un menú como este:

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/CHFeM3sxP2336IUFL32S/image.png)

{% hint style="success" %}
**En el caso que vengas de la instalación de una distribución con todo pre-instalado como MainsailOS/RatOS/FluiddOS no es necesario que realices los siguientes pasos de instalación de otros componentes de Klipper ya que estos ya estarán instalados**.
{% endhint %}

#### Instalando Klipper y Moonraker

Para nuestra guía vamos a usar Klipper que es el core del sistema y Moonraker que va a crear una API para poder gestionar la comunicación entre Klipper.

De las opciones del menú elegiremos la opción 1 para acceder al menú de instalación

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/83nv20ZWO2487QUiblco/image.png)

Volveremos a elegir la opción 1 y comenzaremos el proceso de instalación:

* Eligiremos compilar nuestro firmware
* Por ahora no elegiremos actualizar nuestra MCU

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/m9kNBxIDWDpJhlrw7Ecy/image.png)

#### Instalando un interfaz para acceder a Klipper

Existen diferentes formas de gestionar Klipper, recomendamos el uso de Mainsail o Fluidd, es posible usar Octoprint también pero creemos que no es la mejor opción salvo casos puntuales ya que es más de uso general y Mainsail/Klipper son desarrollos específicos para Klipper.

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/cn1b31Dv4YfG6WKT7YWl/image.png)

La instalación es bastante sencilla y similar a la que realizamos en el punto anterior tan solo seleccionando el interfaz que más nos guste y seguir el asistente/indicaciones.

Es importante comentar que podemos instalar diferentes interfaces siempre y cuando usemos un puerto diferente para cada uno, aquí Kiauh también nos ayuda.

Otra función muy interesante, en este caso de Mainsail, es que podemos usar el interfaz online y dar de alta nuestra impresora sin necesitar nada instalado aunque en ocasiones podemos perder alguna funcionalidad.

{% embed url="<http://my.mainsail.xyz>" %}

{% hint style="info" %}
Para permitir que [my.mainsail.xyz](http://my.mainsail.xyz/) acceda a nuestra instalación local tenemos que permitir en nuestro moonraker.conf añadiendo o revisando que tengamos el siguiente codigo:

```
[authorization]
cors_domains:
    https://my.mainsail.xyz
    http://my.mainsail.xyz
    http://*.local
trusted_clients:
 10.0.0.0/8
 127.0.0.0/8
 169.254.0.0/16
 172.16.0.0/12
 192.168.0.0/16
 FE80::/10
 ::1/128
```

{% endhint %}
{% endtab %}
{% endtabs %}

### Firmware Klipper manualmente

Una vez ya tenemos nuestro OS instalado y con Klipper, Moonraker y la interfaz que más nos guste instalada, es hora de pasar a crear nuestro firmware Klipper.

Ya que hemos Klipper este nos va a permitir de una forma muy sencilla a los diferentes pasos para realizar el proceso.

#### Creando el firmware

{% tabs %}
{% tab title="Manualmente" %}
Para poder generar nuestro firmware Klipper manualmente:

* Nos aseguraremos que tenemos instala la utilidad make

```bash
sudo apt install make
```

* Una vez instalado make nos iremos a la carpeta klipper y lanzaremos el configurador para nuestro firmware

```bash
 cd ~/klipper
 make clean
 make menuconfig
```

* Configuraremos las opciones necesarias para nuestra electrónica, usando la tecla Q para salir del configurador y Y para guardar los cambios. Ej. SKR Mini E3 v3 aunque más abajo tenéis más ejemplos

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/EX343NdOwcHObMH7Bsve/image.png" alt=""><figcaption></figcaption></figure>

* Una vez ya tenemos la configuración de nuestra electrónica lista lanzaremos el proceso make para que se compile nuestro firmware:

```bash
make
```

* Aplicaremos el firmware creado dependiendo de nuestra electrónica. En electrónicas modernas de 32b se suele copiar el firmware generado (por ejemplo con Filezilla y generando una conexión SFTP) .../out/klipper.bin a nuestro ordenador y de ahí a la SD con el nombre que sea necesario para nuestra electronica... para electrónicas SKR suele ser firmware.bin y para ver que se aplicó correctamente debería de cambiar a firmware.cur.

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/JqIyCfMY9o7Ti1HZgSSM/image.png" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
En determinados casos podremos actualizar la electrónica directamente por USB/USART:

Lanzaremos el comando ls para listar nuestra electrónica:

***ls /dev/serial/by-id/\****

Deberiamos obtener algo como...

***/dev/serial/by-id/usb-1a86\_USB2.0-Serial-if00-port0***

Y utilizaremos ese identificador serial o serial ID para lanzar el comando flash:

***sudo service klipper stop***

***make flash FLASH\_DEVICE=/dev/serial/by-id/usb-1a86\_USB2.0-Serial-if00-port0***

***sudo service klipper start***
{% endhint %}
{% endtab %}

{% tab title="Kiauh" %}
Accederemos a **Kiauh** desde SSH

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/MfvaN25PB3sPIpjIqWGw/image.png)

Elegiremos la opción más adecuada para nuestra placa ya que en ocasiones nos interesará solamente hacer el Build del firmware para después extraerlo, Flash to aplicarlo a nuestra placa si es compatible con el proceso o Build + Flash que realizaría todo el proceso.

{% hint style="warning" %}
**IMPORTANTE!!!**\
**En el caso de realizar el proceso Build + Flash tenemos que tener en cuenta el método de actualización de nuestra electrónica ya que Kiauh no es siempre compatible o puede dar problemas.**
{% endhint %}
{% endtab %}

{% tab title="Bundle Klipper 3Dwork" %}
Disponemos de un bundle de Klipper creado por nosotros y basado en RatOS para que el acceso a macros avanzadas y a configuraciones custom sea más sencillo.

Dentro de estas funciones se dispone de unas macros que permiten compilar firmware Klipper para las electrónicas soportadas de uns forma sencilla.

Si quieres más información la tienes en el [siguiente enlace](/klipper/mejoras/3dwork-klipper-bundle#macros-de-configuracion-de-maquina).
{% endtab %}

{% tab title="Creality Sonic Pad" %}
{% hint style="warning" %}
**El Creality Sonic Pad fue descontinuado por Creality en 2024 y ya no tiene soporte oficial activo. No lo recomendamos para nuevas instalaciones. Si ya dispones de uno, aquí tienes cómo generar firmware desde él.**
{% endhint %}

Aunque no es un dispositivo que solamos aconsejar, te invitamos a [leer esta información](/klipper/troubleshooting#creality-sonic-pad) que te puede ser interesante, os vamos a dar unas indicaciones para poder generar el firmware Klipper desde este dispositivo para poder añadir impresoras no soportadas por defecto.

**Herramientas:**

* Cliente SSH siempre aconsejamos [**Terminus**](https://termius.com/download/) por ser multiplataforma, sencillo y no tiene coste para el uso de administrar tus máquinas con Klipper. También dispones de otras como [**Putty**](https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html).\
  Tenéis más información sobre [qué es SSH aquí](/klipper/empezamos/puesta-en-marcha-inicial#conexion-a-ssh).
* Utilidad sFTP para transferir ficheros desde la Sonic Pad, os aconsejamos [WinSCP](https://winscp.net/eng/download.php) o [Cyberduck](https://cyberduck.io/)
* Acceso root a la Sonic Pad... dentro de los menús de esta... `Setup > Advanced Options > Root Access`

**Pasos a seguir:**

* Abriremos nuestro cliente SSH (PuTTy) y pondremos la IP así como el nombre y usuario que obtuvimos en la Sonic Pad al activar el acceso root

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FlPXlrCBmlQj599Z1taEn%2Fimage.png?alt=media&amp;token=0742490e-ee78-4cf0-8552-be125a4783ba" alt=""><figcaption></figcaption></figure>

* Escribiremos `cd /usr/share/klipper`

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FuJeUNgG5dpMJ4n1uzS6u%2Fimage.png?alt=media&amp;token=e6103913-77ea-4bbc-af2e-f043abf6de8a" alt=""><figcaption></figcaption></figure>

* Lanzaremos el comando `make clean` para limpiar cualquier configuración previa.

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FhdQHElCm6tUh5PqjhoM9%2Fimage.png?alt=media&amp;token=f8b82dc7-5017-453f-b857-60404e145716" alt=""><figcaption></figcaption></figure>

* Ahora un `make menuconfig`

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FpHCIH0btOnnmKww7bMzS%2Fimage.png?alt=media&amp;token=831ee778-758c-4c68-83f5-c53944468815" alt=""><figcaption></figcaption></figure>

* Tendremos un menú donde tendremos que elegir las opciones para nuestra electrónica, normalmente encontramos los parámetros básicos en los cfg de ejemplo que tenemos en el [repositorio de Klipper en Github](https://github.com/Klipper3d/klipper/tree/master/config), en la parte inicial de los mismos

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FqXGvu70AuPbq7cMvRnhH%2Fimage.png?alt=media&amp;token=471ee72b-743a-4ece-a225-2449eb436928" alt=""><figcaption></figcaption></figure>

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2F4SEftU2KJX49uVhpJQgq%2Fimage.png?alt=media&amp;token=08fa8fe6-1567-4424-a98f-6f340eb6d3c2" alt=""><figcaption><p>Las opciones y nombres de la captura pueden variar dependiendo de la versión de firmware</p></figcaption></figure>

* Una vez tengamos las opciones pulsaremos `Q` para salir y `Y` para guardar los cambios
* Ejecutaremos el comando `make`

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FkWLeufLRESBjAnq3KJrV%2Fimage.png?alt=media&amp;token=ebf385d7-0b08-47d7-846e-ebaff0018155" alt=""><figcaption></figcaption></figure>

* Esperaremos unos minutos a que el firmware se acabe de generar, este quedará dentro del directorio/path `/out/klipper.bin`... la extensión puede depender del modelo de electrónica que hayamos seleccionado

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2F8zMq1XiBzPReYr2LyPxa%2Fimage.png?alt=media&amp;token=4b647dd8-87b5-46ac-ae66-f73c8009daea" alt=""><figcaption></figcaption></figure>

* Ahora con el firmware Klipper creado y con el cliente sFTP, WinSCP por ejemplo, utilizando la IP y el usuario/contraseña que usamos para entrar en nuestra Sonic Pad por SSH nos conectaremos a esta e iremos al directorio/path `/usr/share/klipper/out/` y descargaremos el firmware a nuestro ordenador
* Seguiremos las instrucciones del fabricante de nuestra electrónica para aplicar el firmware a ella.
  * en electrónicas de 32b normalmente renombraremos el firmware de klipper.bin a firmware.bin, algunas electrónicas pueden requerir otro nombre o que este no coincida con el último aplicado, colocaremos el fichero en una microSD (con formato FAT32/4096 e idealmente <2GB) y reiniciaremos la electrónica
  * en electrónicas de 8b normalmente aplicaremos por USB el firmware desde un laminador como PrusaSlicer o Cura
* Si se aplicó todo correctamente podremos pasar al paso siguiente, [verificar la conexión](#verificando-la-conexion) entre nuestra Sonic Pad y nuestra electrónica/MCU
* Recuerda que para añadir impresoras de terceros has de poner el nuevo printer.cfg en un USB (con formato FAT32/4096) en el conector USB2 (abajo izquierda) y la impresora conectada en el USB1 ajustando el printer.cfg
  {% endtab %}
  {% endtabs %}

Os facilitamos la configuración para las electrónicas que hemos probado:

{% tabs %}
{% tab title="Klipper Oficial" %}
El [repositorio oficial de Klipper](https://github.com/Klipper3d/klipper/tree/master/config) incluye configuraciones para una amplia variedad de electrónicas y modelos de impresora. Entre ellos encontraréis:

* **BTT/SKR**: `generic-bigtreetech-*.cfg` — SKR Mini E3, SKR Pico, Octopus, Manta, EBB CAN...
* **FYSETC**: `generic-fysetc-*.cfg` — Spider, Cheetah, S6...
* **MKS**: `generic-mks-*.cfg` — Robin Nano, Monster8, Rumba32...
* **Creality**: `printer-creality-*.cfg` — Ender 3 y variantes, CR-10, Ender 5, CR-6 SE...
* **Elegoo**: `printer-elegoo-neptune2-2021.cfg`, `printer-elegoo-neptune3-pro-2023.cfg`
* **Anycubic**: `printer-anycubic-*.cfg` — Kobra Go, Kobra Plus, Vyper, i3 Mega, 4Max...
  {% endtab %}

{% tab title="BTT / SKR" %}
BigTreeTech incluye las configuraciones de sus electrónicas directamente en el repositorio oficial de Klipper con el prefijo `generic-bigtreetech-`:

* [SKR Mini E3 v3](https://github.com/Klipper3d/klipper/blob/master/config/generic-bigtreetech-skr-mini-e3-v3.0.cfg)
* [SKR v1.4](https://github.com/Klipper3d/klipper/blob/master/config/generic-bigtreetech-skr-v1.4.cfg)
* [Octopus Pro](https://github.com/Klipper3d/klipper/blob/master/config/generic-bigtreetech-octopus.cfg)
* [Manta M8P v1.1](https://github.com/Klipper3d/klipper/blob/master/config/generic-bigtreetech-manta-m8p-v1.1.cfg)
* [EBB CAN v1.2](https://github.com/Klipper3d/klipper/blob/master/config/sample-bigtreetech-ebb-canbus-v1.2.cfg)

Listado completo en el [repositorio de Klipper](https://github.com/Klipper3d/klipper/tree/master/config) filtrando por `bigtreetech`.

#### SKR Octopus PRO — menuconfig

Elegiremos las siguientes opciones dependiendo del procesador/version de nuestra Octopus:

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/cZrYAeGtevAMk269lYnm/image.png)

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/u6Ge6s1lV9Nl8ck3LJes/image.png)

#### SKR MINI E3 V3 — menuconfig

Elegiremos las siguientes opciones dependiendo del procesador/version de nuestra Mini E3 v3:

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/EX343NdOwcHObMH7Bsve/image.png)

Una vez tengamos todas las opciones ajustadas pulsaremos ***q*** para salir y "***Yes***" para almacenar la configuración, si lanzamos el proceso desde Kiauh nos realizará directamente el comando ***make***.

Una vez terminado el compilado del firmware podremos encontrar el binario ***klipper.bin*** en el directorio ***/home/pi/klipper/out*** el cual podremos aplicar directamente por DFU o usando la SD tal como tenemos en [**nuestra guía**](broken://pages/-MjAhH5k3yBW1g-2ESN8#generacion-firmware-klipper).
{% endtab %}

{% tab title="FYSETC" %}

* [Spider](https://github.com/Klipper3d/klipper/blob/master/config/generic-fysetc-spider.cfg)
* [S6 v2](https://github.com/Klipper3d/klipper/blob/master/config/generic-fysetc-s6-v2.cfg)
* [Cheetah v2.0](https://github.com/Klipper3d/klipper/blob/master/config/generic-fysetc-cheetah-v2.0.cfg)
* [F6](https://github.com/Klipper3d/klipper/blob/master/config/generic-fysetc-f6.cfg)

#### FYSETC Spider — menuconfig

Elegiremos las siguientes opciones dependiendo del procesador/version de nuestra Spider:

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/FfGUYA7W3LV3bqhLdXAb/image.png)

{% hint style="info" %}
**Si tu Spider es posterior al 23/6/2021 elige como Bootloader offset 32KiB bootloader.**

**Si tu Spider es anterior al 23/6/2021 elige como Bootloader offset 64KiB bootloader.**
{% endhint %}

Una vez tengamos todas las opciones ajustadas pulsaremos ***q*** para salir y "***Yes***" para almacenar la configuracion, si lanzamos el proceso desde Kiauh nos realizará directamente el comando ***make***.

Una vez terminado el compilado del firmware podremos encontrar el binario ***klipper.bin*** en el directorio ***/home/pi/klipper/out*** el cual podremos aplicar directamente por DFU o usando la SD tal como tenemos en [**nuestra guía**](broken://pages/-MbekXV_N0G4WCu3EAW6).
{% endtab %}

{% tab title="MKS" %}
MKS mantiene un repositorio oficial con configuraciones Klipper para todas sus electrónicas:

[github.com/makerbase-mks/Klipper-for-MKS-Boards](https://github.com/makerbase-mks/Klipper-for-MKS-Boards)

Algunas electrónicas MKS también están incluidas en el repositorio oficial de Klipper (`generic-mks-*.cfg`): Robin Nano v1/v2/v3, Monster8, Rumba32, SGENL.
{% endtab %}

{% tab title="Creality" %}
Creality dispone de un repositorio oficial con configuraciones Klipper para sus impresoras compatibles con el **Sonic Pad**:

[github.com/CrealityOfficial/Creality\_Sonic\_Pad/tree/main/printer\_configrations](https://github.com/CrealityOfficial/Creality_Sonic_Pad/tree/main/printer_configrations)

Incluye configuraciones para: Ender 3 (y todas sus variantes), Ender 5, CR-10, CR-6 SE, Ender 3 S1, CR-30, Sermoon y más modelos.

Para las impresoras de la **serie K1** (K1, K1 Max, K1C, K1 SE), Creality mantiene su propio fork de Klipper:

[github.com/CrealityOfficial/K1\_Series\_Klipper](https://github.com/CrealityOfficial/K1_Series_Klipper)

{% hint style="info" %}
Los modelos clásicos de Creality (Ender 3, CR-10, etc.) también están incluidos en el repositorio oficial de Klipper con el prefijo `printer-creality-*.cfg`.
{% endhint %}
{% endtab %}

{% tab title="Anycubic" %}
Varios modelos de Anycubic están incluidos directamente en el **repositorio oficial de Klipper**:

* [Kobra Go (2022)](https://github.com/Klipper3d/klipper/blob/master/config/printer-anycubic-kobra-go-2022.cfg)
* [Kobra Plus (2022)](https://github.com/Klipper3d/klipper/blob/master/config/printer-anycubic-kobra-plus-2022.cfg)
* [Vyper (2021)](https://github.com/Klipper3d/klipper/blob/master/config/printer-anycubic-vyper-2021.cfg)
* [i3 Mega (2017)](https://github.com/Klipper3d/klipper/blob/master/config/printer-anycubic-i3-mega-2017.cfg)
* [4Max Pro 2.0 (2021)](https://github.com/Klipper3d/klipper/blob/master/config/printer-anycubic-4maxpro-2.0-2021.cfg)

Para la **Kobra 3** y modelos más recientes con Klipper nativo de Anycubic, mantienen un fork específico de su MCU:

[github.com/ANYCUBIC-3D/K3-klipper-mcu](https://github.com/ANYCUBIC-3D/K3-klipper-mcu)
{% endtab %}

{% tab title="Elegoo" %}
Los modelos **Neptune 2** y **Neptune 3 Pro** están incluidos en el **repositorio oficial de Klipper**:

* [Neptune 2 (2021)](https://github.com/Klipper3d/klipper/blob/master/config/printer-elegoo-neptune2-2021.cfg)
* [Neptune 3 Pro (2023)](https://github.com/Klipper3d/klipper/blob/master/config/printer-elegoo-neptune3-pro-2023.cfg)

Para las impresoras **Neptune 4** y variantes (con Klipper integrado de fábrica), Elegoo distribuye las configuraciones junto con el firmware oficial disponible en su [página de descargas](https://www.elegoo.com/pages/download).
{% endtab %}
{% endtabs %}

{% hint style="info" %}
📖 **Reviews de electrónica en 3dwork.io:** ¿Tienes una de estas placas y quieres saber más?

* [BTT Octopus: Análisis y guía Klipper](https://3dwork.io/btt-octopus/)
* [BTT Manta M8P/M5P/M4P: Análisis y guía Klipper](https://3dwork.io/manta-m8p-m5p-m4p-e3ez-analisis-y-guia-completa/)
* [BTT SKR v1.4 / v1.4 Turbo + TMC2209: Guía completa](https://3dwork.io/guia-completa-skr-v1-4-y-tmc2209/)
* [BTT SKR Mini E3 V3: Análisis y guía](https://3dwork.io/btt-skr-mini-e3-v3-2/)
  {% endhint %}

{% hint style="success" %}
3Dwork Klipper Bundle:

Desde 3Dwork mantenemos un[ **bundle para Klipper**](/klipper/mejoras/3dwork-klipper-bundle) que incluye macros, configuraciones de máquinas, etc... entre ellas damos soporte a diferentes electrónicas que utilizando una [macro podemos compilar](/klipper/mejoras/3dwork-klipper-bundle#impresoras-y-electronicas) nuestro firmware Klipper de una forma totalmente automatizada y sencilla.
{% endhint %}

### Firmware Klipper pre-generado desde Auto Builder 3Dwork

También contamos con un sistema de auto builder de firmware Klipper basado en nuestro bundle que compila, para las electrónicas soportadas, para diferentes electrónicas de forma diaria.

{% hint style="danger" %} <mark style="color:red;">**EL USO DE ESTOS FIRMWARE KLIPPER PRE-GENERADOS SON BAJO VUESTRA PROPIA RESPONSABILIDAD!!!**</mark>\ <mark style="color:red;">**Siempre aconsejamos que cada usuario cree por si mismo su firmware desde su host Klipper.**</mark>
{% endhint %}

Del siguiente listado haremos click en nuestra electrónica y nos descargaremos el firmware Klipper compilado a aplicar en nuestra electrónica siguiendo las instrucciones del fabricante!!!

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FjY5GhfxJUmgLysxG17ix%2Fimage.png?alt=media&amp;token=36d34d73-6016-4f93-b32c-afde779bd102" alt=""><figcaption></figcaption></figure>

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

### Katapult — Actualización de firmware sin SD

**Katapult** (antes CanBoot) es un bootloader para microcontroladores que permite actualizar el firmware Klipper directamente desde el host **sin necesidad de extraer la SD ni usar DFU**. Es especialmente útil para electrónicas con conexión CAN bus o USB.

{% hint style="success" %}
Katapult es el método recomendado para mantener actualizado el firmware en electrónicas modernas BTT, Mellow y similares. Una vez instalado, basta con ejecutar un script desde el host para actualizar.
{% endhint %}

#### ¿Cuándo usar Katapult?

* Electrónicas conectadas por **CAN bus** (EBB, U2C, etc.) — es prácticamente obligatorio
* Cualquier electrónica donde quieras evitar sacar la SD para cada actualización
* Setups con múltiples MCUs (placa principal + cabezal CAN)

#### Instalación básica

```bash
cd ~
git clone https://github.com/Arksine/katapult
cd katapult
make menuconfig   # configura para tu MCU específica
make
```

Después de compilar, el bootloader se aplica por DFU una única vez. Las actualizaciones posteriores se hacen desde el host:

```bash
python3 ~/katapult/scripts/flashtool.py -i can0 -u <uuid> -f ~/klipper/out/klipper.bin
```

{% hint style="info" %}
Consulta la [documentación oficial de Katapult](https://github.com/Arksine/katapult) y las guías específicas de tu electrónica para los parámetros correctos de `menuconfig`. Los ajustes varían según el modelo y la frecuencia del cristal.
{% endhint %}

### Verificando la conexión

Ahora que tenemos nuestro firmware Klipper en nuestra electrónica procederemos a verificar que tenemos comunicación con ella, un paso previo y necesario antes de continuar con la configuración de Klipper.

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/GjGbPBX7d9poorNfnqWs/image.png)

Elegiremos el tipo de conexión entre nuestra electrónica y la Pi, normalmente y aconsejable USB:

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/35QNJmmaAp6ueTbfs1wZ/image.png)

{% hint style="info" %}
**En el caso que usemos Klipper por los pines GPIO deberemos habilitar la comunicación serial en nuestra pi, para simplificar el proceso teneis aqui unos comandos para que sea más sencillo:**

**sudo raspi-config nonint do\_serial 2**

**echo dtoverlay=pi3-disable-bt | sudo tee -a /boot/config.txt**

**sudo reboot**
{% endhint %}

En el caso que no detecte nuestra electrónica deberemos verificar el proceso de aplicar el firmware Klipper o el cableado:

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/CFgBXu8w8LhfUDiNXnKA/image.png)

En el este correcto nos listará un dispositivo, es importante anotarse este ya que lo necesitaremos más adelante:

![Deberemos copiar lo marcado para usarlo en los ficheros de configuración de Klipper](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/doV7PrklaMgf0jkuD0RE/image.png)

{% hint style="info" %}
En el caso que no realicemos el proceso desde Kiauh podemos usar el comando ***ls /dev/serial/by-id*** para listar los dispositivos conectados.
{% endhint %}

{% hint style="info" %}
**Conexión por CAN bus**: Si tu electrónica usa CAN en lugar de USB, el dispositivo no aparecerá en `/dev/serial/by-id`. Para verificar la conexión CAN:

```bash
~/klippy-env/bin/python ~/klipper/scripts/canbus_query.py can0
```

Esto listará los UUIDs de todos los dispositivos CAN detectados en la red. Apunta el UUID de tu electrónica, lo necesitarás en la sección `[mcu]` de `printer.cfg`:

```ini
[mcu]
canbus_uuid: XXXXXXXXXXXXXXXX
```

{% endhint %}


# Múltiples instancias Klipper

Una de las ventajas de la arquitectura de Klipper es que el host puede controlar varias impresoras al mismo tiempo. Cada impresora necesita su propia instancia de Klipper y Moonraker, pero todas comparten el mismo SBC, la misma red y pueden gestionarse desde una sola interfaz web.

Esta guía cubre el proceso completo: instalación, gestión de serial USB, configuración de interfaces y las preguntas más frecuentes.

{% hint style="warning" %}
**Antes de empezar — consideraciones importantes**

* Cuantas más instancias corran en el mismo host, más recursos consumes. Un problema de hardware (sobrecalentamiento, corte de luz, SD corrupta) afectará a **todas** las impresoras simultáneamente.
* El host necesita estar correctamente dimensionado. Una Raspberry Pi 3B+ puede gestionar 2 impresoras sencillas, pero 3 o más instancias activas con cámara y timelapse requieren al menos una Raspberry Pi 4 con 2 GB de RAM o superior.
* Si las impresoras son críticas o para producción, valora tener hosts separados.
  {% endhint %}

## Requisitos previos

* KIAUH instalado y funcionando en tu host. Si aún no lo tienes, sigue la [guía de instalación](https://github.com/alienboyxp/gitbook_es_klipper_3dwork_io/blob/main/klipper/README.md#instalando-kiauh).
* Punto de partida limpio: instalación recién hecha, o instalación existente **completamente actualizada** con todas las instancias funcionando.
* Python 3.8 o superior (KIAUH v6+ lo requiere y lo verifica automáticamente).

{% hint style="info" %}
**KIAUH v6** (lanzado en octubre 2025) es una reescritura completa del instalador en Python. Si tienes una versión anterior basada en bash, actualiza con:

```bash
cd ~/kiauh && git pull
```

El proceso de instalación de múltiples instancias es funcionalmente el mismo, aunque la interfaz de menús puede verse diferente a las capturas de esta guía.
{% endhint %}

## Nomenclatura — nombres de instancia

Cuando KIAUH instala varias instancias, te permite elegir entre dos modos:

* **Nombres por defecto (numérico)**: las instancias se llaman `printer`, `printer_2`, `printer_3`... Los directorios de datos serán `~/printer_data/`, `~/printer_2_data/`...
* **Nombres personalizados**: puedes poner nombres descriptivos como `voron`, `ender3`, `artillery`. Los directorios serán `~/voron_data/`, `~/ender3_data/`...

**Recomendación: usa nombres personalizados siempre que puedas.** Hace que todo sea mucho más fácil de identificar: servicios, logs, configuraciones y URLs tienen el nombre de la impresora.

## Estructura de directorios

Tras instalar múltiples instancias con KIAUH, cada instancia tiene su propio directorio de datos con esta estructura:

```
~/voron_data/
├── config/          ← aquí van los .cfg (printer.cfg, moonraker.conf...)
├── gcodes/          ← archivos de impresión subidos
├── logs/            ← klippy.log, moonraker.log...
├── comms/           ← sockets de comunicación interna
├── database/        ← base de datos de Moonraker (historial, etc.)
└── systemd/         ← referencias a servicios systemd

~/ender3_data/
├── config/
├── gcodes/
├── logs/
├── comms/
└── database/
```

Cada instancia es completamente independiente en cuanto a datos, configuraciones y logs.

## Puertos asignados por instancia

KIAUH asigna los puertos automáticamente según el orden de instalación:

| Instancia    | Moonraker API | Interfaz web (Nginx) |
| ------------ | ------------- | -------------------- |
| 1ª instancia | 7125          | 80                   |
| 2ª instancia | 7126          | 81                   |
| 3ª instancia | 7127          | 82                   |
| 4ª instancia | 7128          | 83                   |

Para acceder a la segunda impresora desde el navegador: `http://IP_DEL_HOST:81`

{% hint style="info" %}
Para ver los puertos activos en cualquier momento, desde SSH:

```bash
sudo ss -lntp | grep -E "7125|7126|7127|7128|:80|:81|:82"
```

O con más detalle:

```bash
sudo netstat -ltnp
```

{% endhint %}

## Servicios systemd

Cada instancia crea sus propios servicios de sistema. Con nombres personalizados:

```bash
# Klipper
klipper-voron.service
klipper-ender3.service

# Moonraker
moonraker-voron.service
moonraker-ender3.service
```

Con nombres por defecto:

```bash
klipper.service          # primera instancia
klipper-2.service        # segunda instancia
moonraker.service
moonraker-2.service
```

### Comandos útiles para gestionar instancias individualmente

```bash
# Ver estado
sudo systemctl status klipper-voron.service
sudo systemctl status moonraker-voron.service

# Reiniciar una instancia específica
sudo systemctl restart klipper-voron.service
sudo systemctl restart moonraker-voron.service

# Parar una instancia (sin afectar a las demás)
sudo systemctl stop klipper-ender3.service

# Ver logs en tiempo real de una instancia
journalctl -fu klipper-voron.service
journalctl -fu moonraker-ender3.service
```

***

## Instalación paso a paso con KIAUH

### Paso 1 — Instalar varias instancias de Klipper

Lanza KIAUH desde SSH:

```bash
./kiauh/kiauh.sh
```

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/eTYlFmyLT6nraOUbrGxM/image.png" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
En el menú inicial, KIAUH muestra el número de instancias instaladas y la versión de cada componente.
{% endhint %}

* Selecciona **#1 Install**

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/ZcpEllUgNntgRN3HYYo3/image.png" alt=""><figcaption></figcaption></figure>

* Selecciona **#1 Klipper**
  * Elige la versión de Python (selecciona **Python 3**, que es la única opción válida actualmente)
  * Indica el **número de instancias** que quieres instalar
  * KIAUH te preguntará si quieres **personalizar los nombres** — di que sí y pon nombres descriptivos

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/MAnJazVRDXmrjeehUJMv/image.png" alt=""><figcaption></figcaption></figure>

Klipper se descarga e instala para cada instancia. Al terminar vuelves al menú principal.

### Paso 2 — Instalar varias instancias de Moonraker

* Selecciona de nuevo **#1 Install**
* Selecciona **#2 Moonraker**
  * KIAUH te preguntará el número de instancias. Debe coincidir con el de Klipper (el menú ya te muestra las instancias existentes como referencia).

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/7uJCzZoPDO2q6tThpPLr/image.png" alt=""><figcaption></figcaption></figure>

Al terminar, KIAUH muestra las IPs y puertos asignados a cada instancia de Moonraker:

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/S4aFT2ZCmeDfeA7skHbl/image.png" alt=""><figcaption></figcaption></figure>

Anota estos datos — los necesitarás para configurar las interfaces web.

### Paso 3 — Instalar la interfaz web

Tienes dos opciones:

**Opción A — Una interfaz compartida (recomendada)**

Instala Mainsail o Fluidd una sola vez. Desde esa interfaz puedes gestionar todas las impresoras añadiéndolas como impresoras adicionales (ver sección de gestión más abajo). Es la opción más limpia y consume menos recursos.

**Opción B — Una interfaz por instancia**

Instala Mainsail o Fluidd tantas veces como instancias, cada una en su propio puerto. Útil si diferentes personas deben controlar impresoras distintas de forma independiente.

Para instalar una segunda interfaz: selecciona **#1 Install → #3 Mainsail** (o Fluidd) y repite el proceso.

***

## El problema del serial USB con electrónicas idénticas

Esta es la pregunta más frecuente cuando se configuran múltiples instancias: **si tengo dos impresoras con la misma placa (por ejemplo, dos Ender 3 con placa Creality original), ¿cómo las diferencio?**

El problema está en el chip USB. Muchas placas económicas usan chips CH340 que no tienen un número de serie único grabado. Cuando Klipper busca la MCU por `by-id`, ambas placas tienen el mismo identificador y no sabe a cuál conectarse.

Tienes tres soluciones:

### Solución 1 — Serial by-path (más sencilla)

En lugar de usar el ID del dispositivo, usas el **puerto USB físico** del host. El sistema operativo asigna un path diferente a cada puerto, independientemente del dispositivo conectado.

```bash
# Ver los paths disponibles
ls /dev/serial/by-path/*
```

Ejemplo de resultado:

```
/dev/serial/by-path/platform-fd500000.pcie-pci-0000:01:00.0-usb-0:1.1:1.0-port0
/dev/serial/by-path/platform-fd500000.pcie-pci-0000:01:00.0-usb-0:1.2:1.0-port0
```

En el `printer.cfg` de cada impresora:

```ini
# printer.cfg — impresora 1 (conectada al puerto USB físico 1)
[mcu]
serial: /dev/serial/by-path/platform-fd500000.pcie-pci-0000:01:00.0-usb-0:1.1:1.0-port0

# printer.cfg — impresora 2 (conectada al puerto USB físico 2)
[mcu]
serial: /dev/serial/by-path/platform-fd500000.pcie-pci-0000:01:00.0-usb-0:1.2:1.0-port0
```

{% hint style="warning" %}
**Importante con by-path**: cada impresora debe estar **siempre conectada al mismo puerto USB físico** del host. Si cambias el cable a otro puerto, el path cambia y Klipper no encontrará la MCU. Márcalos con cinta adhesiva o etiquetas para no confundirlos.
{% endhint %}

### Solución 2 — ID USB personalizado en el firmware (más robusta)

Cuando compilas el firmware Klipper para tu MCU, puedes establecer un número de serie USB único para cada placa. Así aunque ambas tengan el mismo chip CH340, Klipper las distingue por el ID personalizado.

En el proceso de compilación del firmware (`make menuconfig`), busca la sección **USB ids** y establece un valor único por impresora:

![](https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FC6yjs32hDpgI9WLyisf9%2Ftelegram-cloud-photo-size-4-5902074441494544581-y.jpg?alt=media\&token=e89874b1-655f-4fbb-8895-a71966b64067) ![](https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2F0844WrM5nFvAW1o8LcRY%2Ftelegram-cloud-photo-size-4-5902074441494544582-y.jpg?alt=media\&token=67dee153-ddca-4de9-93d1-3462d28310ca)

Tras flashear cada MCU con su firmware personalizado, `ls /dev/serial/by-id/*` mostrará identificadores diferentes y podrás usar `by-id` con normalidad.

{% hint style="warning" %}
Debes repetir este paso cada vez que recompiles el firmware de la MCU. Si compartes el mismo binario entre dos placas idénticas, volverán a tener el mismo ID.
{% endhint %}

***

## Gestión desde las interfaces web

### Mainsail — gestionar múltiples impresoras

Mainsail puede gestionar todas las instancias desde una sola ventana del navegador. Añade cada impresora así:

* Ve a **Configuración** (icono de engranajes) → **Printers**

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/S29ZKFZLCJx1aCVA3vtW/image.png" alt=""><figcaption></figcaption></figure>

* Pulsa **ADD PRINTER** e introduce la IP y puerto de Moonraker de cada instancia:

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/Hazhd5ZXQWDQafNEkErY/image.png" alt=""><figcaption></figcaption></figure>

| Instancia   | Host     | Puerto |
| ----------- | -------- | ------ |
| Impresora 1 | IP\_HOST | 7125   |
| Impresora 2 | IP\_HOST | 7126   |
| Impresora 3 | IP\_HOST | 7127   |

Una vez añadidas, puedes cambiar entre impresoras desde la barra superior de Mainsail sin cambiar de URL. También puedes acceder a cada una directamente desde `http://IP_HOST:80`, `http://IP_HOST:81`, etc.

### Fluidd — gestionar múltiples impresoras

Fluidd funciona de forma similar a Mainsail. Ve a **Configuración → Impresoras** y añade cada instancia con su IP y puerto de Moonraker.

También puedes acceder a cada instancia directamente por su puerto Nginx (`http://IP_HOST:80`, `:81`, `:82`...).

### KlipperScreen — múltiples impresoras en pantalla táctil

KlipperScreen puede mostrar y gestionar varias impresoras desde una única pantalla. Edita el fichero `KlipperScreen.conf` y añade una sección `[printer ...]` por cada impresora:

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/whWVYJfymrl2na840LN5/image.png" alt=""><figcaption></figcaption></figure>

```ini
# KlipperScreen.conf

[printer Voron 2.4]
moonraker_host: 127.0.0.1
moonraker_port: 7125
# moonraker_api_key: False   # Solo si usas API key

[printer Ender 3]
moonraker_host: 127.0.0.1
moonraker_port: 7126

[printer Artillery Sidewinder]
moonraker_host: 127.0.0.1
moonraker_port: 7127
```

Si las impresoras están en **hosts diferentes**, pon la IP correspondiente en `moonraker_host`.

En KlipperScreen aparecerá un selector en la pantalla de inicio para elegir con qué impresora operar.

***

## Configuración de printer.cfg y moonraker.conf

### printer.cfg

Cada instancia tiene su propio `printer.cfg` en `~/NOMBRE_data/config/printer.cfg`. No hay nada especial respecto a una instalación única — simplemente configura cada uno para su impresora.

{% hint style="success" %}
Para impresoras idénticas (misma electrónica, mismo hardware), puedes usar **includes compartidos** para la configuración común y sobreescribir solo lo que cambia (serial USB, offsets, nombre):

```ini
# ~/voron_data/config/printer.cfg
[include ../shared/voron_base.cfg]   # Configuración común
[mcu]
serial: /dev/serial/by-path/...      # Serial específico de esta unidad
```

Pon los ficheros compartidos en un directorio accesible por ambas instancias, por ejemplo `~/shared_configs/`.
{% endhint %}

### moonraker.conf

El fichero `moonraker.conf` de cada instancia es generado automáticamente por KIAUH con el puerto correcto. Raramente necesitas editarlo, pero es útil entender los parámetros clave:

```ini
# ~/voron_data/config/moonraker.conf

[server]
host: 0.0.0.0
port: 7125          # Puerto de esta instancia (7126 para la segunda, etc.)
klippy_uds_address: ~/voron_data/comms/klippy.sock

[authorization]
trusted_clients:
    10.0.0.0/8
    127.0.0.0/8
    169.254.0.0/16
    172.16.0.0/12
    192.168.0.0/16
    ::1/128
    FE80::/10
    ::1

cors_domains:
    *.local
    *.lan
    *://app.fluidd.xyz
    *://my.mainsail.xyz
```

{% hint style="info" %}
El parámetro `klippy_uds_address` es el socket Unix que conecta Moonraker con Klipper. Cada instancia tiene el suyo propio en su directorio `comms/`. KIAUH lo configura correctamente de forma automática — no lo cambies.
{% endhint %}

### Update Manager en Moonraker

Para que Mainsail/Fluidd muestre las actualizaciones disponibles de cada instancia correctamente, el `moonraker.conf` de cada instancia debe tener su propia sección `[update_manager]`:

```ini
# moonraker.conf — sección de actualizaciones

[update_manager]
# Para Klipper
[update_manager klipper]
type: git_repo
path: ~/klipper
origin: https://github.com/Klipper3d/klipper.git
managed_services: klipper-voron   # Nombre del servicio de esta instancia

# Para Moonraker
[update_manager moonraker]
type: git_repo
path: ~/moonraker
origin: https://github.com/Arksine/moonraker.git
managed_services: moonraker-voron

# Para Mainsail
[update_manager mainsail]
type: web
channel: stable
repo: mainsail-crew/mainsail
path: ~/mainsail
```

{% hint style="warning" %}
Adapta `managed_services` al nombre real de tu servicio systemd. Si tus instancias se llaman `voron` y `ender3`, los servicios serán `klipper-voron` y `klipper-ender3`. Si usas nombres por defecto, será `klipper` y `klipper-2`.

Comprueba los nombres exactos con:

```bash
sudo systemctl list-units | grep klipper
sudo systemctl list-units | grep moonraker
```

{% endhint %}

***

## Añadir una instancia adicional a una instalación existente

Si ya tienes una instancia funcionando y quieres añadir una segunda sin reinstalar todo:

* Lanza KIAUH y selecciona **#1 Install → #1 Klipper**
* KIAUH detecta que ya tienes instancias instaladas y te ofrece **añadir una nueva** sin tocar las existentes
* Indica el número total de instancias que quieres tener (existentes + nuevas)
* Repite el proceso para Moonraker

{% hint style="success" %}
KIAUH v6 gestiona esto de forma muy cómoda: detecta automáticamente las instancias existentes y solo instala lo que falta, manteniendo las configuraciones actuales intactas.
{% endhint %}

***

## Cámaras con Crowsnest

Crowsnest gestiona las cámaras USB y las expone como streams MJPEG o HLS accesibles desde Mainsail/Fluidd.

**Recomendación para múltiples impresoras**: usa **una sola instancia de Crowsnest** gestionando todas las cámaras. Es más sencillo de mantener y Crowsnest puede manejar varias cámaras sin problema.

En tu `crowsnest.conf` (en `~/printer_data/config/crowsnest.conf` de la primera instancia):

```ini
[crowsnest]
log_path: ~/printer_data/logs/crowsnest.log
log_level: verbose

# Cámara para impresora 1
[cam voron]
mode: camera-streamer
enable_rtsp: false
rtsp_port: 8554
port: 8080                              # Puerto del stream de esta cámara
device: /dev/video0
resolution: 1280x720
max_fps: 30

# Cámara para impresora 2
[cam ender3]
mode: camera-streamer
enable_rtsp: false
rtsp_port: 8555
port: 8081                              # Puerto diferente para la segunda cámara
device: /dev/video2
resolution: 1280x720
max_fps: 30
```

En el `moonraker.conf` de cada instancia, referencia el stream correcto:

```ini
# moonraker.conf de la instancia Voron
[webcam voron_cam]
stream_url: http://127.0.0.1:8080/?action=stream
snapshot_url: http://127.0.0.1:8080/?action=snapshot

# moonraker.conf de la instancia Ender3
[webcam ender3_cam]
stream_url: http://127.0.0.1:8081/?action=stream
snapshot_url: http://127.0.0.1:8081/?action=snapshot
```

### Si necesitas instancias separadas de Crowsnest

Si prefieres instancias independientes (por ejemplo, para que el fallo de una no afecte a las demás), el proceso es manual ya que Crowsnest no tiene soporte nativo multi-instancia en su instalador:

```bash
cd ~/crowsnest
make config
```

El asistente te preguntará el directorio de datos para esta instancia. Repite tantas veces como necesites, luego:

```bash
sudo make install
```

Reinicia el host al terminar y añade la entrada de Update Manager en el `moonraker.conf` correspondiente.

***

## Dimensionamiento del host

Una guía orientativa para no quedarse corto:

| Número de instancias | Hardware mínimo            | Hardware recomendado     |
| -------------------- | -------------------------- | ------------------------ |
| 2 impresoras         | Raspberry Pi 3B+, 1 GB RAM | Raspberry Pi 4, 2 GB RAM |
| 3-4 impresoras       | Raspberry Pi 4, 2 GB RAM   | Raspberry Pi 4, 4 GB RAM |
| 5+ impresoras        | Raspberry Pi 4/5, 4 GB RAM | Raspberry Pi 5, 8 GB RAM |

Estos valores asumen impresoras en operación normal. Si añades **cámaras con timelapse**, **Input Shaper en curso** o **compilación de firmware** simultánea, multiplica los requisitos.

Puedes monitorizar la carga del sistema con:

```bash
# Carga de CPU y memoria en tiempo real
htop

# Carga de CPU promedio
uptime

# Uso de memoria
free -h

# Temperatura (en Raspberry Pi)
vcgencmd measure_temp
```

{% hint style="warning" %}
Si el host supera el 80% de CPU de forma sostenida durante una impresión, aumentas el riesgo de que Klipper pierda el timing de pasos y la impresión falle o se descalibre. Monitoriza antes de poner impresoras en producción.
{% endhint %}

***

## Acceso remoto con múltiples instancias

Si usas **OctoEverywhere** o **Obico** para acceso remoto, cada instancia de Moonraker requiere su propio registro. El proceso es el mismo que con una sola instancia, pero repitiendo el emparejamiento para cada puerto.

Para **OctoEverywhere**:

* Ve a `http://IP_HOST:80` (instancia 1) y sigue el proceso de enlace
* Ve a `http://IP_HOST:81` (instancia 2) y repite

Cada instancia tendrá su propio enlace de acceso remoto independiente.

***

## Troubleshooting — Problemas frecuentes

### Klipper no arranca en una instancia

```bash
# Ver el log de errores de la instancia
journalctl -fu klipper-voron.service
# o directamente
tail -f ~/voron_data/logs/klippy.log
```

Los errores más comunes son:

* **Serial no encontrado**: el cable USB no está conectado, el path `by-path` cambió porque se conectó a otro puerto, o el ID `by-id` es incorrecto.
* **Error de configuración**: algún parámetro de `printer.cfg` tiene un error de sintaxis. El log lo indica con el fichero y la línea exacta.
* **Puerto ocupado**: otro proceso ya usa el socket de comunicación. Reinicia ambos servicios (klipper y moonraker) de esa instancia.

### Confundo qué serial pertenece a qué impresora

Con `by-path`, identifica cada puerto físico USB del host y etiquétalo. Para `by-id` con firmware personalizado, documenta qué ID pusiste en cada placa.

Un truco: desconecta todas las placas excepto una y lanza `ls /dev/serial/by-id/*` — solo aparecerá la que dejaste conectada. Repite para cada una.

### Moonraker no conecta con Klipper en una instancia

Verifica que el socket `klippy_uds_address` en `moonraker.conf` apunta al directorio correcto de esa instancia:

```bash
# Debe existir este fichero cuando Klipper está corriendo
ls ~/voron_data/comms/klippy.sock
```

Si no existe pero Klipper está corriendo, hay un problema en la ruta configurada. Revisa `moonraker.conf` de esa instancia.

### Una interfaz web muestra la impresora equivocada

Comprueba a qué puerto Moonraker estás conectando. La instancia 1 usa `7125`, la 2 usa `7126`. En Mainsail/Fluidd, ve a la configuración de impresoras y verifica que cada entrada apunta al puerto correcto.

### Tras actualizar Klipper, solo se actualiza una instancia

Verifica que el `managed_services` en la sección `[update_manager]` de cada `moonraker.conf` tiene el nombre correcto del servicio systemd de esa instancia.

### Los logs crecen mucho con varias instancias

Moonraker gestiona la rotación de logs automáticamente. Si los logs son excesivamente grandes, puedes reducir el nivel de verbosidad en el `moonraker.conf`:

```ini
[server]
log_level: warning   # en lugar de info o debug
```

***

## Checklist de verificación final

Antes de dar por buena la instalación múltiple, verifica:

* [ ] Cada instancia de Klipper tiene su propio servicio systemd activo (`sudo systemctl status klipper-NOMBRE.service`)
* [ ] Cada instancia de Moonraker está corriendo en su puerto correcto (`sudo ss -lntp | grep 712`)
* [ ] Cada `printer.cfg` usa el serial correcto para su MCU (verificado con `QUERY_ENDSTOPS` o `M115`)
* [ ] La interfaz web puede acceder a cada instancia por separado
* [ ] Las cámaras muestran la imagen de la impresora correcta
* [ ] El Update Manager en Moonraker lista correctamente los componentes de cada instancia
* [ ] Has probado un print de prueba corto en cada impresora antes de poner en producción


# Klipper en Raspberry Pad 5

La **Raspberry Pad 5** de **Bigtreetech** parece a simple vista una pantalla táctil de 5 pulgadas... nada más lejos de la realidad.

## Raspberry Pad 5

{% embed url="<https://youtu.be/0glRpsoWSQI>" %}

Por la parte trasera vemos que cuenta con un módulo **Raspberry Pi Compute Module 4**, o CM4 de aquí adelante, que **permite conectar directamente módulos MCU con formato CM4**. Además, también contamos con un arsenal de conexiones como puerto **HDMI con soporte 2K**, un **GPIO**, puerto **USB-C**, conectores **USB 2.0**, interfaz **CSI** e incluso un conector Ethernet **RJ-45** para conexión a nuestras redes por cable.

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/lAqhZS77FPowMO1zb1Tp/image.png" alt=""><figcaption></figcaption></figure>

{% hint style="warning" %}
**La Raspberry Pad 5 no incluye el módulo CM4 el cual ha de comprarse aparte.**

**El módulo CB1 de Bigreetech, equivalente a CM4, no es compatible en este caso con la Raspberry Pad 5.**

**Tampoco lleva incluída la batería RTC (Real Time Clock) de 3v CR1200.**
{% endhint %}

En cuanto a la parte gráfica de la pantalla, **contamos con un panel IPS con hasta cinco capturas de pulsaciones simultáneas** y una **resolución de 800x480 píxeles**. También es de agradecer disponer de tres pulsadores para controlar el brillo y el giro de la pantalla.

La **Raspberry Pad 5** puede ser aliado para muchos de vuestros proyectos. En nuestro caso nos vamos a centrar en su uso como host **Klipper** para nuestras impresoras.

Anteriormente os hemos contado que la **Raspberry Pad 5** cuenta con un conector para la conexión de un módulo **CM4**, pero… que es exactamente un **CM4**?

Básicamente, un módulo **CM4** es una pequeña placa que incorpora un **ARM Cortex-A72**, el mismo usado por una Raspberry Pi 4. Estos módulos están fabricados para, como en nuestro caso con la **Raspberry Pad 5**, otra controladora que le facilite interfaces o funciones como USB, salidas de video, etc.

Teniendo en cuenta las limitaciones y precio de **Raspberry Pi**, el empleo de estos módulos **CM4** junto con nuestra **Raspberry Pad 5** nos va a permitir tener, para nuestro caso, un host **Klipper** potente gracias al **CM4** y capaz en opciones gracias a la parte **Raspberry Pad 5** de conexiones y pantalla.

## Preparando nuestra Raspberry Pad 5

Ahora que tenemos toda la información de nuestra **Raspberry Pad 5** es hora de comenzar a prepararla para instalar **Klipper**.

El primer paso a realizar es la instalación del módulo **CM4** el cual, junto con los tornillos suministrados, anclaremos en el zócalo **CM4** de nuestra **Raspberry Pad 5**.

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/mFoyBKw1XXaYUcNH7C1j/image.png" alt=""><figcaption></figcaption></figure>

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

**el módulo CM4 ha de ser instalado correctamente, tal como vemos en la imagen antrior la serigrafía Made in UK tiene que quedar en el lado de los conectores USB del Pad 5.**
{% endhint %}

Siguiendo con el módulo **CM4** es importante identificar que tipo de módulo vamos a usar, básicamente tenemos 4 combinaciones con diferentes configuraciones.

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/qGUcHb2j859BB85E2GpS/image.png" alt=""><figcaption></figcaption></figure>

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/FAU46ikFGxZCR6895FUa/image.png" alt=""><figcaption></figcaption></figure>

Por un lado tenemos que identificar si nuestro **CM4** es la **versión con eMMC o Lite**, ya que va a afectar en la forma de instalar nuestro **Klipper**.

## Instalando Klipper

A continuación os detallamos el proceso para instalar Klipper tanto en módulos CM4 Lite como en módulos con eMMC. En nuestro caso utilizamos nuestra distribución favorita MainsailOS.

### Para módulos CM4 Lite (sin eMMC)

Si nuestro módulo es un CM4 Lite, sin eMMC, deberemos instalar nuestra imagen de MainsailOS usando nuestra SD:

* Insertaremos nuestra SD en nuestro ordenador, os aconsejamos una SD de al menos 16Gb-32Gb y que tenga una velocidad de lecturas/escrituras lo mejor posible para una mejor experiencia.
* Abriremos nuestro **Raspberry Pi Imager**, si no lo tenéis instalados podéis descargarlo desde [aquí](https://www.raspberrypi.com/software/)
* El primer paso será seleccionar el OS a instalar donde elegiremos **Other specific-purpose Os -> 3D printing -> MainsailOS** y seleccionaremos la versión que mejor se adapte a nuestras necesidades:

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/1ZjwMMdIR5PFh2ZGXCAL/image.png" alt=""><figcaption></figcaption></figure>

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/kdiA3S5rS8jSyoKGIoGz/image.png" alt=""><figcaption></figcaption></figure>

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/IQ9MYmL93Z8KLTRJzwXF/image.png" alt=""><figcaption></figcaption></figure>

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/M2fuwMUBE9nwlaWVrrgN/image.png" alt=""><figcaption></figcaption></figure>

* Una vez seleccionado nuestro OS el siguiente paso será **escoger nuestra unidad SD**
* Antes de proceder a aplicar la imagen del OS a nuestra SD, y para ahorraros pasos posteriormente, **os aconsejamos ajustar las opciones avanzadas como habilitar SSH o configuración WiFi usando el icono del engranaje**

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/dgQVICuyZ7slwQEnRI2k/image.png" alt=""><figcaption></figcaption></figure>

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/fssr4NUi49keYaJWgICo/image.png" alt=""><figcaption></figcaption></figure>

* Con todo bien ajustado procederemos a escribir en nuestra SD MainsailOS

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/aRz8APTbxujH2cAadjfg/image.png" alt=""><figcaption></figcaption></figure>

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/UW1T5PEHSKnws1au0c9I/image.png" alt=""><figcaption></figcaption></figure>

* Una vez finalizado el proceso insertaremos la SD en el zócalo de nuestra Raspberry Pad 5

{% hint style="info" %}
La Raspberry Pad 5 cuenta con 3 leds para los diagnósticos del sistema que nos pueden a ayudar a identificar problemas:

* ROJO, nos indica el estado de la alimentación
* AZUL, muestra que nuestro módulo CM4 está alimentado
* VERDE, el OS de nuestro módulo CM4 está ejecutándose
  {% endhint %}

En el caso que falle el proceso de configuración WiFi podemos volver a poner la SD en nuestro ordenador y ajustar el fichero wpa\_supplicant... a continuación tenéis un generador de configuraciones para verificar que lo hacéis de forma correcta.

{% embed url="<https://codepen.io/LilTrublMakr/full/yRGPrv>" %}

### Para módulos CM4 eMMC

En el caso que nuestro módulo **CM4** cuente con eMMC deberemos de realizar la instalación de una forma diferente a la anterior siguiendo estos pasos:

{% hint style="warning" %}
Instalar el OS para Klipper en la SD no nos va a funcionar si nuestro módulo CM4 cuenta con eMMC.
{% endhint %}

* Descargaremos Raspberry Pi Imager
* También la utilidad **RPIboot** ([Windows](https://github.com/raspberrypi/usbboot/blob/master/win32/rpiboot_setup.exe)/[Mac\&Linux](https://github.com/raspberrypi/usbboot#building)) de Raspberry

{% hint style="info" %}
Si usamos Mac o Linux va a ser un poco más laborioso el usar RPIboot ya que tendremos que compilarla, desde el link anterior para las versiones [Mac\&Linux](https://github.com/raspberrypi/usbboot#building) tenemos más detallados los pasos:

* En el caso de Linux y desde su terminal:

```bash
sudo apt install git libusb-1.0-0-dev pkg-config
git clone --depth=1 https://github.com/raspberrypi/usbboot
cd usbboot
make
sudo ./rpiboot
```

* En el caso de Mac

```bash
git clone --depth=1 https://github.com/raspberrypi/usbboot
cd usbboot
brew install libusb
brew install pkg-config
make
sudo ./rpiboot
```

{% endhint %}

* Ajustaremos los **switches USBOTG y el BOOT en las posiciones tal como veis en la siguiente imagen** para **entrar en modo BOOT nuestro módulo CM4**:

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/bdygfPzsPUlZS1u1nhLM/image.png" alt=""><figcaption></figcaption></figure>

* **Lanzaremos RPIboot** y **conectaremos nuestra Raspberry Pad 5 mediante USB C**. Si todo ha ido correctamente nos **montará nuestro módulo CM4 como una unidad de nuestro ordenador**
* Abriremos **Raspberry Pi Imager** y realizaremos el mismo proceso para aplicar la imagen en la SD pero en este caso elegimos nuestra **Raspberry Pad 5**
* Una vez finalizado el proceso de instalación **desconectaremos el cable USB C a nuestra Raspberry Pad 5**
* Cambiaremos los **switches USBOTG y el BOOT en las posiciones originales**

## **Ajustes MainsailOS**

{% hint style="warning" %}
IMPORTANTE!!!

Nos hemos de asegurar que a partir de este paso nuestra Raspberry Pad 5 está conectada a una fuente de alimentación correcta porque podemos encontrarnos con problemas relacionados como lentitud, reinicios o falta de conectividad WiFi.
{% endhint %}

* **Conectaremos de nuevo el cable USB C de carga** y usaremos nuestra aplicación [**Fing**](https://www.fing.com/) desde nuestro teléfono, o cualquier otra que nos permita encontrar los equipos conectados en nuestra red, para detectar la IP asignada a nuestra **Raspberry Pad 5** y poder conectarnos por SSH
* Lo primero será instalar los drivers necesarios para que funcione la pantalla:

```bash
sudo wget https://datasheets.raspberrypi.com/cmio/dt-blob-disp1-cam1.bin -O /boot/dt-blob.bin
```

{% hint style="warning" %}
En el caso que queramos volver a usar la conexión HDMI deberemos eliminar el fichero /boot/dt-blob.bin
{% endhint %}

* Nuestra **Raspberry Pad 5 viene equipada con un hub USB 2.0 pero por defecto el OS de los módulos CM4 puede llevarlo desactivado**. Para habilitarlo pondremos en modo BOOT nuestro módulo CM4 como realizamos previamente o colocaremos la SD en nuestro ordenador para editar el fichero config.txt añadiendo al final:

{% code title="config.txt" %}

```bash
dtoverlay=dwc2,dr_mode=host
```

{% endcode %}

* **Instalaremos KlipperScreen** desde nuestro terminal SSH si no lo lleva nuestra distribución de MainsailOS

```bash
cd ~/
git clone https://github.com/jordanruthe/KlipperScreen.git
cd ~/KlipperScreen
./scripts/KlipperScreen-install.sh
```

{% hint style="success" %}
Os aconsejamos añadir esta sección al final de vuestro moonraker.conf:

```django
[update_manager KlipperScreen]
type: git_repo
path: ~/KlipperScreen
origin: https://github.com/jordanruthe/KlipperScreen.git
env: ~/.KlipperScreen-env/bin/python
requirements: scripts/KlipperScreen-requirements.txt
install_script: scripts/KlipperScreen-install.sh
managed_services: KlipperScreen
```

{% endhint %}

Si todo ha ido bien ya podremos acceder al interfaz web de Klipper desde nuestro navegador desde cualquier dispositivo de tu red y acceso mediante KlipperScreen usando vuestra pantalla.

Los siguientes pasos será crear tu printer.cfg, crear y aplicar el firmware Klipper a tu electrónica si no lo tiene todavía y encontrar el serial\_ide para nuestro printer.cfg.


# Klipper en Orange Pi Zero Plus

Klipper es un sistema extremadamente flexible que puede correr un múltiples dispositivos y uno de ellos pueden ser una Orange Pi Zero Plus.

## Orange Pi Zero Plus

La Orange Pi Zero Plus es un SBC (Single Board Computer) que pese a que en su nombre parezca equivaler a una Raspberry Pi Zero no lo es dado que usa un diseño y medidas totalmente diferente además de diferencias a nivel de electrónica como su MCU.

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/dwXfQjcv51SuG0umrccd/image.png" alt=""><figcaption></figcaption></figure>

En todo caso y dada la versatilidad de Klipper puede ser una alternativa al uso de Raspberry Pi. A continuación podéis encontrar sus especificaciones:

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/PDO0PogJ1BaiRpYTXVCB/image.png" alt=""><figcaption></figcaption></figure>

## Instalación del OS Armbian

La Orange Pi Zero Plus dispone de su propia distribución del sistema operativo llamado [Armbian y que podéis descargar desde aquí](https://www.armbian.com/orange-pi-zero-plus/). En todo caso en nuestro ejemplo [usamos una variante de este (Jammy) que podéis descargar su última versión desde aquí](https://redirect.armbian.com/orangepizeroplus/Jammy_current).

Una vez que ya tenemos descargada nuestra imagen y usando [Raspberry Pi Imager](https://www.raspberrypi.com/software/) la aplicaremos a nuestra SD:

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/0Izl0S1KTG7zHhv5rB3B/image.png" alt=""><figcaption></figcaption></figure>

Al cabo de unos minutos y si todo ha ido correctamente ya tendremos nuestra SD preparada con el OS. Procederemos a instalar la SD en el lector de nuestra Orange Pi Zero Plus y la alimentaremos desde un cable USB desde nuestro ordenador para que arranque.

Pasados unos minutos nuestro ordenador debería disponer de un nuevo puerto COM:

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/znb7jldeLRGIfoJDyVBA/image.png" alt=""><figcaption></figcaption></figure>

Ahora abriremos [**PuTTY**](https://www.putty.org/) o cualquier otro cliente terminal y configuraremos una nueva conexión Serial usando el COM detectado anteriormente:

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/0o30SeGNTopd8ooQweb9/image.png" alt=""><figcaption></figcaption></figure>

Una vez conectados lo primero que nos solicitará será la **configuración del password del usuario root** y seguidamente el **sistema de comandos que elegiremos BASH y posteriormente configurar un usario, en nuestro caso es importante que se llame pi, y el password del usuario pi**:

{% hint style="warning" %}
**Es importante que creemos un usuario pi ya que de no hacerlo algunos procesos que seguiremos más adelante pueden no funcionar correctamente.**
{% endhint %}

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/YBWjK9lRX0uZwPHLOJi5/image.png" alt=""><figcaption></figcaption></figure>

El siguiente paso será un asistente para la configuración de nuestra red tanto cableada como WiFi:

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/DQsgjYypyqOEZzXnnrvF/image.png" alt=""><figcaption></figcaption></figure>

Como último paso tendremos que seleccionar nuestra configuración de idioma:

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/Qfml3Szv1JV7kVn3ne6K/image.png" alt=""><figcaption></figcaption></figure>

## Instalando Klipper en nuestra Orange Pi Zero Plus

Ahora que ya tenemos el sistema base en nuestra Orange Pi Zero Plus comenzaremos a instalar Kiauh:

```
sudo apt-get install git -y
su pi
cd ~
git clone https://github.com/th33xitus/kiauh.git
cd kiauh
chmod +x kiauh.sh scripts/*
./kiauh.sh
```

{% hint style="info" %}
Con estos comandos hacemos...

* Instalamos git para la gestión de repositorios
* Cambiaremos el usuario de root a pi
* Clonamos el repositorio de Kiauh
* Permitimos que los scripts descargados puedan ser ejecutados
* Ejecutamos Kiauh

Si necesitamos volver a lanzar Kiauh en el futuro podemos ir a `home/pi/kiauh (o el path de instalación elegido) y ejecutar ./kiauh.sh`
{% endhint %}

Una vez hemos realizado el proceso completo y lanzamos Kiauh deveriamos ver un menú como este:

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/CHFeM3sxP2336IUFL32S/image.png)

### Instalando Klipper y Moonraker

Para nuestra guía vamos a usar Klipper que es el core del sistema y Moonraker que va a crear una API para poder gestionar la comunicación entre Klipper.

De las opciones del menú elegiremos la opción 1 para acceder al menú de instalación

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/83nv20ZWO2487QUiblco/image.png)

Volveremos a elegir la opción 1 y comenzaremos el proceso de instalación:

* Eligiremos compilar nuestro firmware
* Por ahora no elegiremos actualizar nuestra MCU

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/m9kNBxIDWDpJhlrw7Ecy/image.png)

### Instalando un interfaz para acceder a Klipper

Existen diferentes formas de gestionar Klipper, recomendamos el uso de Mainsail o Fluidd, es posible usar Octoprint también pero creemos que no es la mejor opción salvo casos puntuales ya que es más de uso general y Mainsail/Klipper son desarrollos específicos para Klipper.

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/cn1b31Dv4YfG6WKT7YWl/image.png)

La instalación es bastante sencilla y similar a la que realizamos en el punto anterior tan solo seleccionando el interfaz que más nos guste y seguir el asistente/indicaciones.

Es importante comentar que podemos instalar diferentes interfaces siempre y cuando usemos un puerto diferente para cada uno, aquí Kiauh también nos ayuda.

Para acceder a nuestra interfaz verificaremos su IP además de que se conectó nuestra Orange correctamente a nuestra red usando el comando ifconfig:

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/9xIXYi1HGttdWqP597Xd/image.png" alt=""><figcaption></figcaption></figure>

Ahora que ya tenemos identificada nuestra IP iremos a nuestro navegador y accederemos a nuestra UI:

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/6nAbmpFdTQB0psjEZvLq/image.png" alt=""><figcaption></figcaption></figure>

Ahora como siguiente paso deberíamos obtener el serial-id de nuestra electrónica y generar el firmware Klipper para poder aplicarlo y controlar la electrónica, tenéis información del proceso [**aquí**](/klipper/instalacion#creando-nuestro-firmware-klipper).


# Klipper en PC con Windows (Usando WSL)

Con está guía obtendrás una instalación de Klipper que funciona en un PC con Windows 10 o 11, utilizando la herramienta del Subsistema de Windows para Linux (WSL).

{% hint style="danger" %}
*Este método requiere que WSL se ejecute en un PC (Windows 10 o 11) todo el tiempo que está imprimiendo, **NO** se puede apagar.*
{% endhint %}

### Lista de materiales

* Paciencia
* Cable USB para conectar la MCU al PC

### Instalación de WSL <a href="#refheading___toc670_2080801950" id="refheading___toc670_2080801950"></a>

Antes de nada, voy a responder a la gran pregunta, Qué es WSL?.

Es e*l Subsistema de Windows para Linux que permite a los desarrolladores ejecutar un entorno Linux, incluida la mayoría de las herramientas, utilidades y aplicaciones de línea de comandos, directamente en Windows, sin modificaciones, sin la sobrecarga de una máquina virtual tradicional o una configuración de arranque dual.*

Para la mayoría de las personas esto no le será útil, pero no está de mas aclararlo. La instalación de WSL es muy sencilla. La documentación se puede consultar [aquí,](https://docs.microsoft.com/es-es/windows/wsl/install) pero continua leyendo para conocer los pasos básicos para iniciar la instalación.

<div align="left"><figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FaOcIUWBSc685sfpwsN45%2Fimage.png?alt=media&amp;token=9a928bb5-122c-4509-8b8e-2fbc31540ee0" alt=""><figcaption><p>Realize una búsqueda escribieno: símbolo del sistema</p></figcaption></figure></div>

En el símbolo del sistema como administrador, ejecute el siguiente comando:

```powershell
wsl --install
```

WSL comienza a instalarse, tenga paciencia, puede tardar bastante tiempo, ya que se tiene que descarga e instalar Ubuntu. En la tienda de Microsoft hay otro sistemas operativos de Linux disponibles y utilidades para facilitar el uso de WSL.

<div align="left"><figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FF2wi1ARDJy51OEkoFvXP%2Fimage.png?alt=media&amp;token=05c07c71-232f-488d-815b-9b31ff6c5b9d" alt=""><figcaption></figcaption></figure></div>

Una vez completado, nos informa que los cambios no se aplicarán hasta que se haya reiniciado. Continúe y reinicie su PC. Cuando se inicie la instalación debería continuar automáticamente y se abrirá una ventana de Ubuntu. Introduzca un nombre de usuario y contraseña.

{% hint style="warning" %}
Tenga presente el usuario y contraseña, habrá que utilizarlo más adelante.
{% endhint %}

<div align="left"><figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2F3ixb4mkl3LX7qWamlBJ8%2Fimage.png?alt=media&amp;token=327b6c3a-07bc-4702-9824-1f05a16ac3ff" alt=""><figcaption></figcaption></figure></div>

Debería de aparecer una bienvenida en la interfaz de línea de comandos de Ubuntu.

<div align="left"><figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2Fqv2F8BWFNLhCJXGOLOIK%2Fimage.png?alt=media&amp;token=658eafc6-a33e-41b6-9bd5-d2762629521d" alt=""><figcaption></figcaption></figure></div>

Abra una ventana del símbolo del sistema y actualice WSL antes de continuar. Cierre WSL y vuelva a ponerlo en marcha (Ubuntu debería aparecer como cualquier otro programa en su menú) para que los cambios surtan efecto.

```powershell
wsl --update
wsl --shutdown
```

<div align="left"><figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FzOnqZ77oV3rY7mI5Q2Kv%2Fimage.png?alt=media&amp;token=243561dd-5125-4932-a262-7a05266e313a" alt=""><figcaption></figcaption></figure></div>

### Preparando el sistema para compartir los puertos de comunicación. <a href="#refheading___toc672_2080801950" id="refheading___toc672_2080801950"></a>

Desafortunadamente, WSL no tiene acceso automático a dispositivos USB o puertos de comunicación en serie. Por suerte, alguien ha [agregado una herramienta](https://github.com/dorssel/usbipd-win/wiki/WSL-support#usbip-client-tools) que incluye está caracteristica.

{% hint style="info" %}
Consulte el enlace anterior para verificar nuevas funciones y configuraciones.
{% endhint %}

En el símbolo del sistema, escriba el siguiente comando para instalar **usbipd** (ejecútelo como administrador)

```powershell
winget install usbipd
```

<div align="left"><figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FMkhPM5vyhpD4pBrgXNSc%2Fimage.png?alt=media&amp;token=050176a7-00b8-454a-b97b-bc8eebe50827" alt=""><figcaption></figcaption></figure></div>

Conecte la mcu(placa base) de la impresora a su PC. Comprueba que puedes ver el puerto COM en el administrador de dispositivos. En la imagen es el COM8.

<div align="left"><figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FrTPbiMnT5UfPWN62koZl%2Fimage.png?alt=media&amp;token=ded1934f-2483-4b33-9ea2-764e5ff6af66" alt=""><figcaption></figcaption></figure></div>

Ejecute el siguiente comando y tome nota del BUSID de su mcu. en la imagen es '1-12'.

`usbipd list`

<div align="left"><figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FuTiV8xLcYZNOYIx30glX%2Fimage.png?alt=media&amp;token=8333e6bf-fa17-4374-9c27-2090d5b3f2b4" alt=""><figcaption></figcaption></figure></div>

Dependiendo de su configuración y de si ha usado o no WSL anteriormente y/o Docker, es posible que deba configurar Ubuntu como predeterminado.\
Ejecute el siguiente comando para verificarlo. Si no es el predeterminado, utilice la segunda línea para activarlo como predeterminado.

{% hint style="warning" %}
Puede ejecutar el primer comando para comprobar que ahora es el predeterminado.
{% endhint %}

```bash
wsl --list
wsl --setdefault Ubuntu
wsl --list
```

<div align="left"><figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FHvJXJ780W17TMZUo7psS%2Fimage.png?alt=media&amp;token=135c34d4-f4e9-4e5f-8cf0-9e7eaf80eae3" alt=""><figcaption></figcaption></figure></div>

```bash
sudo apt install linux-tools-virtual hwdata
sudo update-alternatives --install /usr/local/bin/usbip usbip `ls /usr/lib/linux-tools/*/usbip | tail -n1` 20
```

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FOuAitoCvQA9K0XhAGivC%2Fimage.png?alt=media&amp;token=06e4a145-4174-48fb-9709-fe56a1b4bb95" alt=""><figcaption></figcaption></figure>

Necesitamos conectar el dispositivo USB a WSL. Vamos a ejecutar el siguiente comando en el símbolo del sistema de windows. El dispositivo debería haber desaparecido de su lista de dispositivos.

```powershell
usbipd wsl attach --busid=1-12
```

<div align="left"><figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FDaeidrCBbdNL3bbi2JHl%2Fimage.png?alt=media&amp;token=7e76d95f-5440-4a2f-b482-239ae8de3147" alt=""><figcaption></figcaption></figure></div>

Comprueba que no está visible en WSL.

Ejecute el siguiente comando en Ubuntu.

Puede ver los resultados de ejecutar este comando antes y después de conectar el dispositivo USB a continuación.

Nos aparece un dispositivo STM32 que puedo indentificar que es mi mcu, ya que es el procesador que utiliza.

```bash
lsusb
```

<div align="left"><figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FLMT5WirDNGIMSBbiLq7r%2Fimage.png?alt=media&amp;token=a828db40-d50a-4190-b759-305cebfdb62d" alt=""><figcaption></figcaption></figure></div>

Dentro de Ubuntu, ejecute los siguientes dos comandos. Se le pedirá la contraseña de sudo. Escriba la contraseña que estableció cuando creó su usuario al principio. Presione Y cuando se le solicite continuar con la instalación.

### Configurando Ubuntu <a href="#refheading___toc674_2080801950" id="refheading___toc674_2080801950"></a>

Instala las herramientas de red, ya que más adelante las usaremos para obtener la dirección IP.

```bash
sudo apt install net-tools
```

Ahora, necesitamos tener una versión que soporte la activación de Systemd, porque se utiliza con la mayoría de los servicios (Klipper, Moonraker, etc.) en segundo plano.

**Cómo habilitar Systemd en Ubuntu/WSL**

WSL admite Systemd, pero hay que comprobar la versión que tengamos instalada.

* Los nuevos usuarios de WSL con Windows 11 22H2 o posterior recibirán automáticamente la versión de la aplicación de WSL cuando se ejecuten `wsl --install`, a menos que se agregue específicamente la opción `--inbox`.
* Los usuarios de Windows 10 necesitan [KB5020030 ](https://support.microsoft.com/en-gb/topic/november-15-2022-kb5020030-os-builds-19042-2311-19043-2311-19044-2311-and-19045-2311-preview-237a9048-f853-4e29-a3a2-62efdbea95e2)o posterior. Tenga en cuenta que aún no está claro en el momento de esta actualización si funcionarán las versiones anteriores de Windows 10. Personalmente, solo he podido validarlo en Windows 10 22H2 hasta ahora.

Con la versión de Windows necesaria puede instalar o actualizar a la versión 1.0.0 (o posterior) de la aplicación WSL mediante varios métodos:

* A través de Microsoft Store (como "Subsistema de Windows para Linux").
* O desde la [página del proyecto ](https://github.com/microsoft/WSL/releases)en el repositorio de GitHub. Para instalar una versión manualmente:
  1. Reinicie (para asegurarse de que WSL no esté en uso). Un simple `wsl --shutdown` *puede* funcionar, pero a menudo no lo hará.
  2. Descargue la versión 1.0.0 (o posterior) desde el enlace de arriba.
  3. Inicie un PowerShell de administrador y:

```powershell
           Add-AppxPackage < <path>/Microsoft.WSL_1.0.3.0_x64_ARM64.msixbundle
           wsl --version # muestra la versión.
```

Para habilitar, inicie su distribución de Ubuntu (u otra Systemd) bajo WSL (normalmente`wsl`).

```bash
sudo -e /etc/wsl.conf
```

Agregue lo siguiente:

```
[boot]
systemd=true
```

Salga de Ubuntu y de nuevo:

```bash
wsl --shutdown
```

Luego reinicie Ubuntu.

```bash
sudo systemctl status
```

... debería mostrar sus servicios Systemd.

### Instalación de Klipper <a href="#refheading___toc676_2080801950" id="refheading___toc676_2080801950"></a>

Ahora es la parte fácil. Es hora de instalar Klipper usando [KIAUH](https://github.com/th33xitus/kiauh) como estamos acostumbrados.

Ejecute los siguientes comandos en Ubuntu:

```
cd ~
git clone https://github.com/th33xitus/kiauh.git
```

<div align="left"><figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FptEJBCXhHLWkKBWS6QqH%2Fimage.png?alt=media&amp;token=0de2f36e-aa37-4f18-9931-7b73625be1eb" alt=""><figcaption></figcaption></figure></div>

A continuación, inicie KIAUH e instale los componentes en el siguiente orden:

1. Klipper
2. Moonraker
3. Mainsail o Fluidd.

Para obtener la dirección IP del dispositivo, ejecute el siguiente comando: (Busque la línea `inet debajo de eth0`)

```bash
/sbin/ifconfig
```

<div align="left"><figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2Fz3xE4PGt5katKoWm7ElV%2Fimage.png?alt=media&amp;token=f4eff3a7-2465-42a5-881a-b8219f02edfe" alt=""><figcaption></figcaption></figure></div>

Escriba la ip en su navegador web y listo, ¡klipper tendría que dar señales de vida!

<div align="left"><figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FPHWZRbnb8P57kKlPDTAq%2Fimage.png?alt=media&amp;token=3c78a341-cfe8-442e-9dbb-319cb5edb425" alt=""><figcaption></figcaption></figure></div>

Ahora solo falta confgurar nuestra mcu como estamos acostumbrados, ya vemos el error que nos muestra la interface web, necesitamos configurar el printer.cfg. Sin embargo, debemos asegurarnos de que la MCU está conectada al puerto USB, para ello, en el símbolo del sistema de windows, ejecute el siguiente comando (añadiendo el código que identifica su mcu, recuerda que lo hemos buscamos anteriormente)

```powershell
usbipd wsl attach --busid=1-12 
```

En Ubuntu, ejecute el siguiente comando para obtener el ID del dispositivo. Pegue esta ID en su archivo printer.cfg (usando la interfaz de usuario de mainsail o fluidd) y Klipper ya estaría funcional.

```bash
ls /dev/serial/by-id/*
```

<div align="left"><figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2F5CSOHgGpc9sxjxs31sk8%2Fimage.png?alt=media&amp;token=9ef31e5c-83fc-44a4-93fa-934f4d5abd37" alt=""><figcaption></figcaption></figure></div>

<div align="left"><figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2Ft0V1G4EURV47JxurEmQE%2Fimage.png?alt=media&amp;token=d142d846-acb1-4029-b9a4-2626f7be9aea" alt=""><figcaption></figcaption></figure></div>

<div align="left"><figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FmVg4z4kytE52yRalMDZr%2Fimage.png?alt=media&amp;token=6cea13b9-3fac-4441-b936-9f4edde28213" alt=""><figcaption></figcaption></figure></div>

\
Ahora solo queda realizar la configuración especifica para su impresora.<br>


# Klipper en Android

Convierte tu teléfono o tablet Android antiguo en el host de Klipper para tu impresora 3D. Guía completa de instalación con Linux Deploy (root) y UserLAnd (sin root), conexión OTG y configuración paso

Una de las opciones más interesantes para reciclar hardware es usar un teléfono o tablet Android como host de Klipper, sustituyendo a la Raspberry Pi. Los dispositivos Android modernos cuentan con procesadores ARM de alto rendimiento, varios GB de RAM y almacenamiento interno suficiente para correr Klipper, Moonraker y Mainsail/Fluidd sin problemas.

{% hint style="success" %}
**¿Por qué Android?**

* Reutilizas un móvil o tablet que tienes en un cajón
* Suelen tener más potencia que una Raspberry Pi Zero o Pi 3
* Pantalla integrada opcional con KlipperScreen
* Conectividad WiFi y Bluetooth de serie
  {% endhint %}

{% embed url="<https://www.youtube.com/watch?v=K6o8XyquIxQ>" %}
Tutorial en español — Instalación de Klipper en Android
{% endembed %}

## Requisitos

### Hardware

* **Teléfono o tablet Android** — mínimo 2 GB de RAM (recomendado 3+ GB), 8+ GB de almacenamiento libre
* **Android 8.0 o superior** (recomendado Android 10+)
* **Cable USB OTG** (o adaptador OTG) para conectar la MCU de la impresora
* **Cable USB-C Y (datos + carga)** o placa que alimente el teléfono — necesario para usar OTG y cargar a la vez

{% hint style="warning" %}
**USB OTG + carga simultánea** es el mayor escollo en esta instalación. No todos los dispositivos lo soportan de forma nativa. Las opciones son:

1. Usar una placa impresora que pueda alimentar el dispositivo por USB (ej. BTT Octopus Pro con 5V en el puerto USB)
2. Usar un hub USB OTG con entrada de alimentación independiente
3. Retirar la batería del teléfono y alimentar directamente (avanzado, bajo tu responsabilidad)
   {% endhint %}

### Software y métodos disponibles

| Método                 | Root necesario       | Dificultad | Rendimiento | Notas                            |
| ---------------------- | -------------------- | ---------- | ----------- | -------------------------------- |
| **Linux Deploy**       | Sí (Magisk)          | Media      | Alto        | Método más estable y documentado |
| **UserLAnd**           | No                   | Baja       | Medio       | Más sencillo, algo más lento     |
| **KlipperPhonesLinux** | No (flashing nativo) | Muy alta   | Muy alto    | Solo modelos específicos Xiaomi  |

***

## Método 1 — Linux Deploy (recomendado, requiere root)

Linux Deploy crea un contenedor Debian completo dentro de Android aprovechando el entorno chroot. Es el método más estable y con mejor rendimiento.

{% embed url="<https://www.youtube.com/watch?v=B5gGMIXwDuo>" %}
Run Klipper, Moonraker y Fluidd en Android con Linux Deploy
{% endembed %}

### Paso 1 — Rootear el dispositivo

{% hint style="danger" %}
Rootear un dispositivo puede anular su garantía y, si se hace incorrectamente, puede dejarlo inutilizable ("brickear"). Asegúrate de encontrar el procedimiento específico para tu modelo antes de continuar.
{% endhint %}

El método más recomendado actualmente es **Magisk**:

1. Descarga la imagen de stock de tu dispositivo desde el sitio oficial del fabricante
2. Extrae el `boot.img` de la imagen
3. Parchea el `boot.img` con la app **Magisk** (disponible en [github.com/topjohnwu/Magisk](https://github.com/topjohnwu/Magisk))
4. Flashea el `boot.img` parcheado con `fastboot`
5. Verifica el root instalando **Root Checker** desde la Play Store

### Paso 2 — Instalar apps necesarias

Instala desde la Play Store o F-Droid:

* [**Linux Deploy**](https://play.google.com/store/apps/details?id=ru.meefik.linuxdeploy) — el contenedor Debian
* [**BusyBox**](https://play.google.com/store/apps/details?id=ru.meefik.busybox) — utilidades necesarias para Linux Deploy
* [**JuiceSSH**](https://play.google.com/store/apps/details?id=com.sonelli.juicessh) o similar — cliente SSH para conectarte al contenedor

### Paso 3 — Configurar SELinux en modo permisivo

Para que Linux Deploy pueda montar el contenedor correctamente, SELinux debe estar en modo permisivo:

1. Instala **SELinuxModeChanger** (búscalo en GitHub o F-Droid)
2. Cambia el modo de `Enforcing` a `Permissive`
3. Reinicia el dispositivo

{% hint style="info" %}
En algunos dispositivos también es necesario añadir la siguiente ruta al PATH en la configuración de Linux Deploy: `/data/user/0/ru.meefik.linuxdeploy/files:/system/xbin`
{% endhint %}

### Paso 4 — Crear el contenedor Debian en Linux Deploy

Abre Linux Deploy y configura el contenedor con los siguientes ajustes:

```
Bootstrap:
  Distro:          Debian (Bookworm / Bullseye)
  Architecture:    arm64 (o armhf en dispositivos más antiguos de 32 bits)
  Installation:    Directory
  Path:            /data/local/debian

Init:
  Enable:          yes
  Init system:     sysv

SSH:
  Enable:          yes
  Port:            22

GUI (solo si quieres KlipperScreen):
  Enable:          yes
  Graphics:        X11
  Desktop:         XTerm
```

Pulsa **INSTALL** y espera a que finalice la instalación (puede tardar varios minutos).

### Paso 5 — Arrancar el contenedor y conectar por SSH

1. Pulsa **START** en Linux Deploy
2. Conéctate por SSH desde JuiceSSH o desde otro dispositivo en tu red:

```bash
ssh android@<IP_DEL_TELEFONO>
# Contraseña por defecto: android
```

3. Una vez dentro, actualiza el sistema:

```bash
sudo apt update && sudo apt upgrade -y
```

### Paso 6 — Instalar Klipper con KIAUH

```bash
sudo apt install git -y
cd ~
git clone https://github.com/dw-0/kiauh.git
./kiauh/kiauh.sh
```

En el menú de KIAUH selecciona e instala en este orden:

1. `1) Install` → `1) Klipper`
2. `1) Install` → `2) Moonraker`
3. `1) Install` → `3) Mainsail` (o `4) Fluidd`)
4. (Opcional) `1) Install` → `5) KlipperScreen` — tarda bastante, puede fallar en versiones antiguas de Debian

{% hint style="warning" %}
Si la instalación de KlipperScreen falla por la versión de Python, instala Python 3.11 desde source antes de continuar:

```bash
sudo apt install -y build-essential libssl-dev libffi-dev python3-dev
# Instalar Python 3.11 desde los repositorios de Debian Bookworm
sudo apt install python3.11 python3.11-venv
```

{% endhint %}

### Paso 7 — Corregir los paths de socket (si hay problemas)

En algunos casos Klipper y Moonraker no se comunican bien por los paths de socket por defecto. Comprueba y ajusta si es necesario:

En `/etc/default/klipper`:

```bash
KLIPPY_SOCKET=/home/android/printer_data/comms/klippy.sock
```

En `~/printer_data/config/moonraker.conf`:

```ini
klippy_uds_address: /home/android/printer_data/comms/klippy.sock
```

En `/etc/default/moonraker`:

```bash
MOONRAKER_SOCKET=/home/android/printer_data/comms/moonraker.sock
```

Reinicia los servicios tras los cambios:

```bash
sudo service klipper restart
sudo service moonraker restart
```

***

## Método 2 — UserLAnd (sin root)

UserLAnd es una app que permite ejecutar un entorno Linux completo sin necesidad de root. El rendimiento es algo inferior al método con Linux Deploy pero es mucho más accesible.

### Instalación

1. Descarga [**UserLAnd**](https://play.google.com/store/apps/details?id=tech.ula) desde la Play Store
2. Crea una nueva sesión → Elige **Ubuntu** o **Debian**
3. Selecciona conexión **SSH**
4. Espera a que el sistema base se instale (primera vez tarda varios minutos)
5. Conéctate por SSH con las credenciales que elegiste

### Instalar Klipper con KIAUH

El proceso es idéntico al Método 1 desde el Paso 6. UserLAnd ya proporciona un entorno Debian/Ubuntu completo.

{% hint style="info" %}
UserLAnd **no necesita root** pero puede tener problemas accediendo directamente a `/dev/ttyACM0` o `/dev/ttyUSB0`. Si la impresora no se detecta, consulta el apartado de [Conexión de la impresora](#conexion-de-la-impresora-por-usb-otg) más abajo.
{% endhint %}

***

## Método 3 — KlipperPhonesLinux (avanzado, modelos específicos)

Este proyecto convierte el teléfono en un host Linux nativo (sin Android, directamente Debian), ofreciendo el máximo rendimiento. Solo está disponible para **modelos específicos de Xiaomi** (Redmi 3, Note 3, etc.).

{% hint style="warning" %}
Este método **borra completamente Android** del dispositivo y requiere flashear un kernel Linux nativo. Es el más complejo y está limitado a unos pocos modelos concretos.

Más información en: [github.com/umeiko/KlipperPhonesLinux](https://github.com/umeiko/KlipperPhonesLinux)
{% endhint %}

***

## Conexión de la impresora por USB OTG

### Detectar el puerto serial de la MCU

Con el cable OTG conectado y la impresora encendida, ejecuta dentro del contenedor:

```bash
ls /dev/ttyACM* /dev/ttyUSB* 2>/dev/null
```

La MCU debería aparecer como `/dev/ttyACM0` o `/dev/ttyUSB0`. Si no aparece, el driver del chip USB puede no estar incluido en el kernel del teléfono.

### Si la MCU no se detecta (driver CH34x)

Muchas placas usan el chip USB-serial **CH34x**, que algunos kernels Android no incluyen. Solución con la app **Octo4a**:

1. Instala [Octo4a](https://github.com/feelfreelinux/octo4a) desde GitHub (no publicar en Play Store)
2. Ábrela y espera a que detecte la impresora (incluye driver CH34x propio)
3. No es necesario usar OctoPrint dentro de Octo4a — solo la necesitas para el driver
4. El serial pipe se expone en: `/data/data/com.octo4a/files`
5. Monta esa ruta en Linux Deploy:

```
MOUNTS → Enable: yes
  Source: /data/data/com.octo4a/files
  Target: /home/android/octo4a
```

6. En `printer.cfg`, usa:

```ini
[mcu]
serial: /home/android/octo4a/serialpipe
```

### Dar permisos al puerto serial

```bash
sudo chmod 777 /dev/ttyACM0
# o
sudo chmod 777 /dev/ttyUSB0
```

Para que el permiso sea permanente añade esta línea a `/etc/rc.local`:

```bash
chmod 777 /dev/ttyACM0
```

***

## Configuración del printer.cfg

Una vez localizado el serial, edita tu `printer.cfg` con el serial correcto. Puedes obtenerlo con:

```bash
ls /dev/serial/by-id/
```

Y añadirlo en la sección `[mcu]`:

```ini
[mcu]
serial: /dev/serial/by-id/usb-Klipper_stm32f103xe_xxxxxxxx-if00
```

Para obtener una configuración base de tu electrónica consulta el [repositorio oficial de Klipper](https://github.com/Klipper3d/klipper/tree/master/config) o los repositorios específicos de cada marca que tenemos en la [guía de instalación](https://klipper.3dwork.io/klipper/instalacion).

***

## Acceso a la interfaz web

Una vez Klipper y Moonraker estén corriendo, accede a Mainsail o Fluidd desde cualquier navegador en tu red local:

```
http://<IP_DEL_TELEFONO>
```

{% hint style="success" %}
Para encontrar la IP de tu teléfono dentro del contenedor ejecuta:

```bash
hostname -I
```

{% endhint %}

***

## Inicio automático al arrancar Linux Deploy

Para que el contenedor y los servicios arranquen solos cuando enciendas el teléfono:

1. En Linux Deploy, activa **Autostart** en los ajustes
2. Activa también **Run on startup** para que Linux Deploy inicie el contenedor al arrancar Android

***

## Solución de problemas frecuentes

| Problema                        | Causa probable                   | Solución                                                                   |
| ------------------------------- | -------------------------------- | -------------------------------------------------------------------------- |
| El contenedor no monta          | SELinux en modo `Enforcing`      | Cambiar a `Permissive` con SELinuxModeChanger                              |
| `/dev/ttyACM0` no aparece       | Driver CH34x no disponible       | Usar Octo4a para exponer el serial pipe                                    |
| Klipper y Moonraker no conectan | Path de socket incorrecto        | Verificar y ajustar los paths en los ficheros `default` y `moonraker.conf` |
| OTG + carga no funciona         | Hardware no compatible           | Usar hub USB OTG con alimentación externa o placa que alimente el USB      |
| KlipperScreen falla al instalar | Versión Python demasiado antigua | Instalar Python 3.11 desde source o usar Debian Bookworm                   |
| El contenedor es muy lento      | Poca RAM o dispositivo de 32b    | Usar dispositivo con ≥3 GB RAM y arquitectura arm64                        |

***

## Comparativa con otros hosts

| Host                       | Precio orientativo | Root/Complejidad     | Rendimiento | Notas                        |
| -------------------------- | ------------------ | -------------------- | ----------- | ---------------------------- |
| **Android (Linux Deploy)** | 0 € (reutilizas)   | Alta (requiere root) | Alto        | Ideal para reciclar hardware |
| **Raspberry Pi Zero 2W**   | \~20 €             | Baja                 | Medio       | Bajo consumo, compacto       |
| **Raspberry Pi 4 2GB**     | \~45 €             | Baja                 | Alto        | Estándar de referencia       |
| **Orange Pi Zero 2W**      | \~20 €             | Media                | Medio-Alto  | Buena alternativa económica  |
| PC con Windows (WSL)       | 0 €                | Baja-Media           | Muy alto    | PC siempre encendido         |

{% hint style="info" %}
Tenemos guías específicas para otros hosts alternativos en la [sección de instalación](https://klipper.3dwork.io/klipper/instalacion).
{% endhint %}

***

## Recursos adicionales

* [github.com/d4rk50ul1/klipper-on-android](https://github.com/d4rk50ul1/klipper-on-android) — scripts de automatización para Linux Deploy
* [github.com/umeiko/KlipperPhonesLinux](https://github.com/umeiko/KlipperPhonesLinux) — Linux nativo en móviles Xiaomi específicos
* [KlipperScreen en Android (WiFi)](https://klipper.3dwork.io/klipper/mejoras/klipperscreen-mejoras/klipperscreen-android-wifi) — usar el teléfono como pantalla táctil de KlipperScreen desde otro host
* [Grupo Telegram Klipper ES](https://t.me/Klipper_Firmware_ES) — comunidad de ayuda en español


# Duet 2 Wifi - Klipper

Las electrónicas Duet son muy buenas, sobre todo en entornos de producción porque son muy robustas. Originalmente, usan RRF que es un gran firmware 3D pero sinceramente nunca nos hemos llevado muy bien con él y en especial desde que Klipper empezó a dar sus primeros pasos.

Vamos a explicar el proceso a seguir para aplicar el firmware Klipper a nuestra Duet en especial teniendo en cuenta algunos aspectos importantes.

{% hint style="danger" %} <mark style="color:red;">**IMPORTANTE!!**</mark>

**El proceso de aplicar un firmware a una electrónica es un paso crítico que de fallar o realizarse de forma incorrecta puede dejar dañada nuestra electrónica y puede requerir de herramientas adicionales para recuperarla o incluso dejar inservible de darse el caso.**

**Los siguientes pasos si los realizas son bajo tu propia responsabilidad!!!**
{% endhint %}

## Klipper... ojo con el sistema que utilizamos en nustro host

MainsailOS es una de las distribuciones, para Raspberry, más utilizadas y actualizadas ya que tenemos todo pre-instalado... por contra y en el caso de Duet puede dar problemas si utilizamos una distribución de MainsailOS basada en Debian 11. Podemos averiguar que usamos mediante el comando lsb\_release

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FcHrH1G8IBLiRRMEJGpim%2Fimage.png?alt=media&amp;token=8d0a9f71-c21f-4ec1-9425-3f0e995f6485" alt=""><figcaption></figcaption></figure>

Aunque puede ser un poco laborioso, en el caso que el escenario anterior sea el vuestro, os aconsejamos utilizar dos imágenes... una con MainsailOS actualizado y otra u otro dispositivo host utilizando una version OS que no esté afectada por el fallo anterior.

Podemos utilizar una distribución de Rasbian Lite antigua basada en buster, realizaremos la instalación de Kiauh y desde el instalar Kiauh. Desde el propio Kiauh pudemos hacer el proceso de creación y aplicar el firmware y debería funcionar.

* Descargaremos una imagen de Raspian LITE 10 BUSTER (legacy) que podréis encontrar [aquí](https://support.pishop.us/article/137-official-links-to-raspberry-pi-os-buster) y la aplicaremos en una SD nueva para continuar manteniendo nuestro MainsailOS actualizado.\
  Asegúrate que habilitas la opción de SSH al quemar la imagen a la SD desde RaspiImager además de los datos de tu WiFi de ser necesario.
* Abriremos Terminus o Putty, cliente SSH para conectarnos al host con la imagen Raspbian Buster, recuerda encontrar la IP de tu host para ello.
* Desde el terminal SSH e **instalaremos Git:**

```bash
sudo apt update
sudo apt -get install git -y
```

* **Instalaremos y lanzamos** [**Kiauh**](https://github.com/dw-0/kiauh):

```bash
cd ~
git clone 
https://github.com/th33xitus/kiauh.git
./kiauh/kiauh.sh
```

* Dentro de Kiauh **instalaremos una instancia de Klipper y Moonraker** y ya podemos salir de Kiauh. Cin esto ya tenemos una versión actaulizada y mínima de Klipper en una versión antigua no afectada por el problema con Duet.

## Creando el firmware Klipper

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

**Antes de seguir este proceso os aconsejamos revisar el anterior con detalle!!!**
{% endhint %}

Vamos al paso sencillo que es crear el firmware para nuestra Duet utilizando el comando `make menuconfig` desde SSH, recuerda entrar en el directorio `klipper` antes, utilizando las siguientes opciones:

```bash
cd klipper
make menuconfig
```

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FoJHvgo6E09VKQuuzSP2y%2Fimage.png?alt=media&amp;token=2e8e164b-03d8-4742-82d0-1dad1913aeba" alt=""><figcaption></figcaption></figure>

Guardaremos y saldremos.

El siguiente paso es generar el firmware con la configuración anterior utilizando el comando `make`

## Aplicando el firmware a nuestra Duet

El siguiente paso, el complicado, es el de aplicar el firmware creado anteriormente en nuestra Duet. Os aconsejamos[ **revisar le guía de Duet** ](https://docs.duet3d.com/en/User_manual/RepRapFirmware/Updating_firmware#all-other-duet-boards)para más detalle del proceso.

En concreto nos fijaremos en los pasos para preparar nuestra Duet para ponerla en `flash mode`, **previamente deberemos haber hecho el proceso de borrado de firmware**.

También tenemos el proceso en otra guía que hicimos hace tiempo sobre la BLV que podéis ver en el siguiente link:

{% embed url="<https://labs.3dwork.io/reviews-guias/impresoras-3d/fdm/blv-cube-kit-fysetc#klipper>" %}

Básicamente deberemos de:

{% hint style="warning" %} <mark style="color:orange;">**IMPORTANTE!!! Conexión Raspberry/Duet**</mark>

**Dado que normalmente las Duet no tienen un jumper de alimentación USB es importante que tapemos el pin 5v del conector USB para evitar retroalimentación**

**Este pin ha de quedar sin tapar cuando realicemos el proceso de actualización de firmware cuando la Duet no tenga alimentación de la fuente.**

<img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2Fm346EqqblhaG0VINVrog%2Fimage.png?alt=media&amp;token=8e942a67-7c47-4a06-afbc-85998d42df58" alt="" data-size="original">
{% endhint %}

* Hacer un **borrado del firmware**, haremos un `factory reset` de nuestra placa, para ello con la placa apagada colocaremos un jumper en los pines de borrado (Erase pins en la imagen de abajo.\
  A continuación conectaremos el cable USB para alimentar nuestra placa.\
  Una vez el **led DIAG se encienda, quitaremos el jumper** y tendremos nuestra placa sin ningún firmware instalado
* Pulsaremos el botón RESET (Reset button) para poner en modo DFU

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FVtpl6Bu87byPkOoN8ySg%2Fimage.png?alt=media&amp;token=7c6d221a-d623-4e6b-9beb-6feb7a702ecb" alt=""><figcaption></figcaption></figure>

* Obtendremos el USB ID mediante el comando ls /dev/serial/by-id/\* que copiaremos.
* Pararemos el servicio Klipper por seguridad **`sudo service klipper stop`**
* Lanzaremos el comando para aplicar el firmware creado reemplazando el /dev/serial/by-id/xxxx por el obtenido en pasos anteriores **`make flash FLASH_DEVICE=/dev/serial/by-id/xxxx`**
* Si aparece algo como lo siguiente ya tenemos Klipper en nuestra Duet!!!

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2F2stNHeTUrbwgYjZDuUW2%2Fimage.png?alt=media&amp;token=4123767b-f4bd-45dc-9142-2c7d0b59888f" alt=""><figcaption></figcaption></figure>

* Volveremos a iniciar el servicio Klipper con **`sudo service klipper start`.**

**Ahora con nuestro firmware Klipper aplicado podemos volver a nuestro MainsailOS y desde el interfaz web comentazar a ajustar nuestro printer.cfg y verificar que todo funcione correctamente.**

## printer.cfg

Ahora que ya tenemos nuestro firmware Klipper aplicado y el USB ID que obtuvimos con el ls en el paso anterior ya podemos montar nuestro printer.cfg, podemos utilizar el ejemplo proporcionado por Klipper en su Github.

{% embed url="<https://github.com/Klipper3d/klipper/blob/master/config/generic-duet2.cfg>" %}

A continuación un ejemplo de printer.cfg y uno de macros:

{% embed url="<https://gist.github.com/blackfyre/1a1701bd3ef765b8d16dbe637719c873#file-printer-cfg>" %}

{% embed url="<https://gist.github.com/blackfyre/1a1701bd3ef765b8d16dbe637719c873#file-printer_with_macros-cfg>" %}

#### Ajustes opcionales

A continuación os sugerimos algunos ajustes de Klipper interesantes para nuestra BLV:

* Configuración de la gestión de apagado/encendido

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/gwRUOabHwR8LGaO5EYqE/image.png)

* Usar nuestra pantalla PanelDue, conectando la pantalla a nuestra Pi por GPIO... más detalle [**aquí**](https://docs.duet3d.com/en/User_manual/RepRapFirmware/Updating_PanelDue)<br>
  * Deberemos actualizar nuestro `config.txt` mediante ***`sudo nano /boot/config.txt`*** añadiendo al final ***`dtoverlay=pi3-miniuart-bt`*** presionaremos ***`CTRL+X`*** para guardar los cambios seguido de ***`ENTER`***\
    ![](https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FoLxhHjL0iAb8SfvVcClD%2Fimage.png?alt=media\&token=c387a549-900e-4fdd-888c-6660ca2c953f)
  * Por otro lado tendremos que actualizar nuestro `cmdline.txt` lanzando &#x73;***`udo nano /boot/cmdline.txt`*** eliminando o comentando ***`console=serial0,115200`*** presionaremos ***`CTRL+X`*** para guardar los cambios seguido de ***`ENTER`***\
    ![](https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FVwxevgy2f4ti7aLBTqQw%2Fimage.png?alt=media\&token=50b3c5d9-fb05-4986-b2dc-e7866d492561)
  * Ejecutaremos la utilidad `raspi-config` mediante ***`sudo raspi-config`*** e iremos a la opción ***`3 Interface Options > P6 Serial Port > No > Yes`*** y reiniciaremos nuestra Pi
  * Nos aseguraremos que nuestro ***PanelDue está configurado en 115200***
  * Por último deberemos de realizar algunas ***modificaciones en el fichero moonraker.cfg*** de nuestro Klipper, [**aquí**](https://github.com/Arksine/moonraker/blob/master/docs/configuration.md#paneldue) tenéis más detalles de los cambios.

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/qzwgdk48Ri9oTPc3zp5W/image.png)

Tenéis un video de Nero3D para más referencias.

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

También tenéis el siguiente PDF muy bueno aunque algo antiguo sobre el proceso.

{% file src="/files/CpeDi3nkRwVBwAnMm686" %}


# Guías Instalación específicas impresora/electrónica

{% hint style="info" %}
**English**: Use your browser's built-in translation — Chrome and Edge detect the language automatically and offer to translate the page.
{% endhint %}


# Anycubic - Klipper

Guías de instalación de Klipper en impresoras Anycubic

Selecciona tu modelo de Anycubic para acceder a la guía de instalación específica:

## Modelos Disponibles

### [Kobra 2 Neo](/klipper/instalacion/guias-instalacion-especificas-impresora-electronica/anycubic-klipper/kobra-2-neo)

La Kobra 2 Neo monta de fábrica una electrónica GigaDevice GD32F303, compatible con Klipper usando el target de compilación STM32F103. Esta guía cubre la migración completa a Klipper, incluyendo:

* Compilación del firmware (klipper.bin) con las opciones correctas de menuconfig
* Procedimiento de flasheo mediante tarjeta microSD
* printer.cfg de referencia de la comunidad
* Calibración del Z-offset con la sonda (probe) como endstop virtual
* Limitaciones conocidas: la pantalla/panel de control de fábrica deja de funcionar

**Audiencia:** Usuarios con Kobra 2 Neo que desean migrar a Klipper

***

## Documentación Relacionada

* [**Guías de Instalación Específicas**](/klipper/instalacion) - Otras impresoras y electrónicas
* [**Primeros Pasos con Klipper**](/klipper/empezamos) - Configuración general
* [**Troubleshooting**](/klipper/troubleshooting) - Resolución de problemas

***

**Última actualización:** 2026-08-17 **Autor:** HAL (Technical Writer - 3Dwork.io)


# Kobra 2 Neo

La Kobra 2 Neo viene de serie con firmware propio de Anycubic (basado en Marlin) y una electrónica **GigaDevice GD32F303**, un chip compatible con Klipper usando el target de compilación **STM32F103**. Esto permite instalar Klipper sobre la propia placa de fábrica, sin necesidad de sustituir la electrónica.

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

* Tras flashear Klipper, **la pantalla/panel de control de fábrica deja de funcionar**. La unidad de control se comunica por SPI, un protocolo que Klipper todavía no soporta en esta placa, así que a partir de ese momento el control pasa a hacerse por Mainsail/Fluidd/OctoPrint desde otro dispositivo (más abajo tenéis alternativas si queréis un panel físico).
* **Los siguientes procedimientos requieren de unos mínimos conocimientos**, os aconsejamos informaros bien antes ya que <mark style="color:red;">**cualquier problema o fallo al aplicar este procedimiento es vuestra responsabilidad y puede eliminar la garantía con Anycubic**</mark>.
* Siempre podéis volver al firmware de fábrica reflasheándolo de la misma forma, así que si tenéis dudas podéis probar Klipper con la tranquilidad de que el proceso es reversible.
  {% endhint %}

Antes de empezar es necesario que dispongáis de un **host** (un dispositivo aparte que ejecute Klipper, Moonraker y el frontend) que se conecte a la impresora por USB-C. No tiene por qué ser una Raspberry Pi: sirve prácticamente cualquier equipo capaz de correr Linux, incluso un portátil viejo sin pantalla que vayáis a controlar en remoto desde el navegador.

Para instalar el host y el software (Moonraker, Mainsail/Fluidd, KlipperScreen, etc.) os recomendamos seguir [**nuestra guía de instalación de Klipper**](/klipper/instalacion), que cubre tanto las imágenes preconfiguradas (MainsailOS, FluiddOS, RatOS) como la instalación manual, además de Kiauh como complemento para gestionar componentes adicionales.

## Generar y aplicar el firmware Klipper a nuestra Kobra 2 Neo

{% hint style="warning" %}
**Los siguientes procedimientos requieren de unos mínimos conocimientos, os aconsejamos antes informaros bien ya que�**<mark style="color:red;">**cualquier problema o fallo al aplicar este procedimiento es vuestra responsabilidad y pueda eliminar la garantía con Anycubic**</mark>**.**
{% endhint %}

Conectaremos por SSH a nuestro host y lanzaremos los siguientes comandos para configurar la compilación:

```bash
cd ~/klipper/
make menuconfig
```

En el menú de configuración ajustaremos las siguientes opciones, específicas para la electrónica de la Kobra 2 Neo:

* **Micro-controller Architecture:** STMicroelectronics STM32
* **Processor model:** STM32F103
* **Bootloader offset:** 36KiB
* **Communication interface:** Serial (on USART2 PA3/PA2)
* **Baud rate for serial port:** 115200 (o 250000, ver aviso debajo)

<figure><img src="https://1coderookie.github.io/Kobra2NeoInsights/assets/images/K2Neo_bin-cfg.jpg" alt="Opciones de menuconfig para compilar Klipper para la Kobra 2 Neo"><figcaption></figcaption></figure>

{% hint style="info" %}
Esta placa **no tiene una opción de "Communication interface: USB" independiente** en el menuconfig: tanto si conectáis por el puerto USB-C de la impresora como si cableáis directamente a los pines serie, Klipper se comunica siempre a través del mismo **USART2 (pines PA3/PA2)** — es el único interfaz de comunicación disponible para esta electrónica. Lo único que cambia entre un método y otro es el **baud rate**: 115200 si conectáis por el puerto serie "en crudo", o 250000 si conectáis por el USB-C de la impresora (como en la captura de arriba). Sea cual sea el que uséis, ajustad ese mismo valor en la línea `baud:` de la sección `[mcu]` de vuestro `printer.cfg`.
{% endhint %}

Guardaremos los cambios (**Q** para salir, **Y** para guardar) y lanzaremos la compilación:

```bash
make
```

Al terminar, tendremos el fichero `klipper.bin` listo. El método de flasheo de la Kobra 2 Neo es distinto al de otras electrónicas que se flashean por USB/DFU: aquí se hace mediante **tarjeta microSD**, igual que con el firmware de fábrica:

1. Renombrad el `klipper.bin` compilado a `firmware.bin`.
2. Copiadlo a la raíz de una tarjeta microSD (no en una subcarpeta). Os aconsejamos vaciar la tarjeta de otros ficheros antes de copiarlo.
3. Con la impresora apagada, insertad la tarjeta y encended la impresora.
4. La pantalla mostrará el mensaje **"Firmware update. Please wait"** y se quedará así, sin avanzar. Es normal: esperad entre **5 y 10 minutos** para dar tiempo a que el proceso termine internamente aunque la pantalla no lo refleje.
5. Apagad la impresora, retirad la tarjeta y conectad el host por **USB-C**.
6. Encended de nuevo la impresora y conectad desde Mainsail/Fluidd/OctoPrint.

{% hint style="warning" %}
Si al conectar veis un error de que no se puede establecer conexión con el MCU, probad a pulsar "Restart Firmware" desde la interfaz o apagar y encender la impresora de nuevo.
{% endhint %}

## Obtener un printer.cfg para nuestra Kobra 2 Neo

En la comunidad no existe (todavía) un `printer.cfg` oficial de Klipper para este modelo, pero contamos con varias configuraciones de referencia aportadas por la comunidad:

| Fuente                        | printer.cfg                                                                                                                                 |
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| Klipper4Kobra2series (AJolly) | [printer.cfg](https://github.com/1coderookie/Klipper4Kobra2series/blob/main/Kobra2Neo/cfg/k2neo_Xenyonmedia_v201.cfg) NO OFICIAL KLIPPER!!! |
| cheadrian/kobra2neo-klipper   | [Repositorio completo](https://github.com/cheadrian/kobra2neo-klipper) NO OFICIAL KLIPPER!!!                                                |

{% hint style="warning" %}
Este fichero contiene líneas `[include additional.cfg]`. **Si el fichero incluido no existe, Klipper no arrancará y dará error.** Revisad todos los `[include ...]` del printer.cfg antes de usarlo: o bien creáis los ficheros referenciados, o comentáis esas líneas anteponiendo `#` (por ejemplo `#[include additional.cfg]`) hasta que los necesitéis.
{% endhint %}

Si preferís partir de macros propias en lugar de las de terceros, en nuestro [3Dwork Klipper Bundle](/klipper/mejoras/3dwork-klipper-bundle) tenéis un paquete de macros y configuraciones mantenido por nosotros. Y en general, para entender qué son y cómo aprovechar al máximo las macros de Klipper (como el propio `START_PRINT` que usaremos a continuación), tenéis nuestra sección de [Macros - Mejoras](/klipper/mejoras/macros-mejoras).

{% hint style="info" %}
**Recursos adicionales de la comunidad**

El repositorio [cheadrian/kobra2neo-klipper](https://github.com/cheadrian/kobra2neo-klipper) va un paso más allá del printer.cfg: incluye firmware Klipper precompilado, perfiles para OrcaSlicer, diagramas de cableado de la Raspberry Pi, un modelo 3D para imprimir un soporte para la Pi, e instrucciones específicas para instalar **KlipperScreen** en esta impresora.

También hay hilos activos en la comunidad con configuraciones ya calibradas (Input Shaping y Pressure Advance incluidos) que sirven como buen punto de partida antes de calibrar los vuestros propios:

* [Anycubic kobra 2 neo v0.7.3.5 configs + OrcaSlicer profiles](https://klipper.discourse.group/t/anycubic-kobra-2-neo-v0-7-3-5-configs-orcaslicer-profiles/13009) (Klipper Discourse)
* [Kobra 2 Neo running Klipper (with config and guide)](https://www.reddit.com/r/anycubic/comments/1987n78/kobra_2_neo_running_klipper_with_config_and_guide) (r/anycubic)

Recordad que los valores de Input Shaping y Pressure Advance dependen de cada unidad concreta (mecánica, resonancias propias, extrusor): usad estos configs como referencia de partida, no como valores definitivos, y calibrad los vuestros con [`SHAPER_CALIBRATE`](https://www.klipper3d.org/Resonance_Compensation.html#resonance-compensation) y [`PRESSURE_ADVANCE`](https://www.klipper3d.org/Pressure_Advance.html) en vuestra propia máquina.
{% endhint %}

Una vez nuestro Klipper conecte con la electrónica, os aconsejamos seguir nuestra [guía de primeros pasos](/klipper/empezamos/puesta-en-marcha-inicial) para finalizar el proceso de configuración y ajustes, y en particular revisar las [comprobaciones de configuración oficiales](https://www.klipper3d.org/Config_checks.html) antes de imprimir nada.

### Calibración del Z-offset (la sonda hace de endstop virtual)

La Kobra 2 Neo no tiene un final de carrera físico en el eje Z: usa la propia sonda (probe) como **endstop virtual**. Antes de lanzar vuestra primera impresión es imprescindible calibrar el offset con el comando [`PROBE_CALIBRATE`](https://www.klipper3d.org/Probe_Calibrate.html#calibrating-probe-z-offset). Tenéis el proceso explicado paso a paso, con más detalle del que damos aquí, en nuestra [guía de sensor de nivelación](https://github.com/alienboyxp/gitbook_es_klipper_3dwork_io/tree/main/klipper/empezamos/sensor-nivelacion.md).

{% hint style="warning" %}
Al ejecutar `PROBE_CALIBRATE`, primero moveréis la sonda al centro de la cama indicando las coordenadas X/Y y lanzando la calibración. El cabezal bajará hasta que la sonda detecte la superficie y, justo en ese momento, **se desplazará lateralmente para situar la boquilla sobre el punto detectado**. Esperad a que este movimiento termine por completo antes de ajustar la altura; si tocáis el ajuste mientras el cabezal aún se está desplazando, el offset quedará mal calculado.
{% endhint %}

Al terminar, aceptad el valor y enviad también un `SAVE_CONFIG` para que quede guardado.

Aprovechad que acabáis de calibrar la impresora para dejar también un backup de vuestro `printer.cfg`: si más adelante una actualización o un error humano lo estropea, no tendréis que repetir todo este proceso desde cero. Os explicamos cómo hacerlo en nuestra [guía de backup de Klipper](/klipper/mejoras/backup-klipper).

### Nivelación automática (ABL) y Bed Mesh

Antes de lanzar la malla automática, aseguraos de que la cama está bien nivelada mecánicamente con los tornillos de ajuste (`BED_SCREWS_ADJUST` o `SCREWS_TILT_CALCULATE`): la malla compensa pequeñas variaciones, pero no corrige una cama descuadrada de fábrica. Tenéis el proceso detallado en nuestra [guía de nivelación manual de cama](/klipper/empezamos/nivelacion-cama-manual).

Tras ejecutar una secuencia de ABL, los resultados **no se guardan automáticamente**: hay que guardarlos explícitamente (con el nombre que prefiráis, o como "default").

Para que la malla se aplique realmente al imprimir, hay que añadir el comando `BED_MESH_PROFILE LOAD=default` (o el nombre que hayáis usado) a la macro `START_PRINT` de vuestro printer.cfg, **justo después del último `G28`** (home) de la macro. Explicamos este proceso con más detalle, incluyendo cómo configurar los puntos de sondeo, en nuestra [guía de malla de nivelación de cama](/klipper/empezamos/malla-nivelacion-de-cama-klipper).

## Funciones destacadas de Klipper en esta impresora

* **Pressure Advance**: la Kobra 2 Neo monta drivers TMC2208 que con el firmware de fábrica no permiten aprovechar bien el "Linear Advance" de Marlin. Con Klipper, Pressure Advance sí funciona correctamente y mejora notablemente la sobre/sub-extrusión en esquinas. Tenéis la guía completa de calibración en nuestro [artículo sobre Pressure Advance](/klipper/empezamos/pressure-advance) (también disponible en la [documentación oficial](https://www.klipper3d.org/Pressure_Advance.html)).
* **Input Shaping**: compensación de resonancias para reducir ringing/ghosting, especialmente útil a velocidades altas. Se puede calibrar manualmente o con un sensor ADXL345 (recomendado). Tenéis el proceso paso a paso en nuestra [guía de Input Shaper](/klipper/empezamos/input-shaper) (o en la [documentación oficial](https://www.klipper3d.org/Resonance_Compensation.html#resonance-compensation)).
* **G-Code Flavour**: recordad cambiar el "G-Code Flavour" a "Klipper" en vuestro slicer (en PrusaSlicer: *Printer Settings → General → Firmware*, con el modo "Expert" activado) para poder usar los G-codes extendidos de Klipper. Repasamos esto y más ajustes recomendados de laminador en nuestra [guía de configuración de Klipper en laminadores](/klipper/empezamos/configuracion-klipper-en-laminadores).

## Panel de control: qué pasa con la pantalla de fábrica

Como comentábamos al inicio, la pantalla/panel de control de fábrica **deja de responder** tras instalar Klipper. Vuestras opciones para controlar la impresora son:

* **Mainsail/Fluidd desde el navegador**, accediendo por ejemplo a `mainsail.local` desde el móvil, tablet u ordenador. Una vez lo tengáis funcionando, en nuestra sección de [Mainsail - Mejoras](/klipper/mejoras/mainsail-mejoras) y [Moonraker - Mejoras](/klipper/mejoras/moonraker-mejoras) tenéis trucos adicionales para sacarle más partido (como notificaciones vía Telegram).
* **KlipperScreen** en un móvil o tablet antiguo, o en una pantalla táctil conectada al propio host (por ejemplo, a una Raspberry Pi por HDMI). Es una manera cómoda de tener un panel físico junto a la impresora si no queréis depender solo del navegador. Tenéis el paso a paso completo para convertir un móvil Android antiguo en pantalla de control (por WiFi, sin cables) en nuestra [guía de KlipperScreen en Android](/klipper/mejoras/klipperscreen-mejoras/klipperscreen-android-wifi). Una vez montado, tenéis más ideas para personalizarlo en nuestra [guía de pantallas compatibles](/klipper/mejoras/klipperscreen-mejoras/klipperscreen-guia-de-pantallas) y en cómo [poner un vídeo con vuestro logo en el arranque](/klipper/mejoras/klipperscreen-mejoras/klipperscreen-personaliza-arranque-con-un-video-con-tu-logo).

{% hint style="warning" %}
**¿Se puede recuperar la pantalla de fábrica?** Para la **Kobra Neo/Go originales** (sin el "2"), electrónica **Huada HC32F460**, sí existe un proyecto de la comunidad ([jokubasver/Anycubic-Kobra-Go-Neo-LCD-Driver](https://github.com/jokubasver/Anycubic-Kobra-Go-Neo-LCD-Driver)) que permite recablear esa pantalla SPI directamente a los GPIO de una Raspberry Pi y mostrar KlipperScreen en modo solo-lectura (sin táctil, aunque hay un [driver de mando por encoder rotatorio](https://github.com/SomeSpaceNerd/KlipperScreen-Encoder-Driver) como complemento).

**Esto NO aplica a la Kobra 2 Neo** de esta guía: es una electrónica distinta (GD32F303, no HC32F460) y no hay confirmación de que use el mismo panel ni el mismo pinout SPI. De hecho, en el propio foro de Klipper la gente confunde ambos modelos con frecuencia. A día de hoy no hemos encontrado ningún proyecto equivalente verificado específicamente para la Kobra 2 Neo — si alguien de la comunidad lo consigue, avisadnos y actualizamos la guía.
{% endhint %}

***

Esta guía está basada en la documentación de la comunidad recopilada en [Kobra2Neo Insights](https://1coderookie.github.io/Kobra2NeoInsights/firmware/fw_klipper/), adaptada y traducida para 3Dwork.

## Documentación Relacionada

* [**Anycubic - Klipper**](/klipper/instalacion/guias-instalacion-especificas-impresora-electronica/anycubic-klipper) - Otros modelos Anycubic
* [**Primeros Pasos con Klipper**](/klipper/empezamos) - Configuración general
* [**Nivelación manual de cama**](/klipper/empezamos/nivelacion-cama-manual) - Ajuste mecánico previo a la malla
* [**Malla de nivelación de cama**](/klipper/empezamos/malla-nivelacion-de-cama-klipper) - Bed mesh en detalle
* [**Pressure Advance**](/klipper/empezamos/pressure-advance) - Calibración paso a paso
* [**Input Shaper**](/klipper/empezamos/input-shaper) - Compensación de resonancias
* [**Configuración Klipper en laminadores**](/klipper/empezamos/configuracion-klipper-en-laminadores) - Ajustes de slicer
* [**Macros - Mejoras**](/klipper/mejoras/macros-mejoras) - Personaliza y extiende tu printer.cfg
* [**3Dwork Klipper Bundle**](/klipper/mejoras/3dwork-klipper-bundle) - Paquete de macros propio
* [**Mainsail - Mejoras**](/klipper/mejoras/mainsail-mejoras) / [**Moonraker - Mejoras**](/klipper/mejoras/moonraker-mejoras) - Trucos adicionales para el frontend
* [**KlipperScreen en Android**](/klipper/mejoras/klipperscreen-mejoras/klipperscreen-android-wifi) - Panel de control con un móvil
* [**Backup Klipper**](/klipper/mejoras/backup-klipper) - No perdáis vuestra calibración
* [**Troubleshooting**](/klipper/troubleshooting) - Resolución de problemas

***

**Última actualización:** 2026-08-17 **Autor:** HAL (Technical Writer - 3Dwork.io)


# Creality - Klipper

{% hint style="info" %}
**English**: Use your browser's built-in translation — Chrome and Edge detect the language automatically and offer to translate the page.
{% endhint %}


# Creality Sonic Pad - Klipper Oficial, custom firmware

Como muchas veces hemos comentado, la Creality Sonic Pad utiliza un firmware personalizado por Creality y que por desgracia no está actualizado por lo que la compatibilidad y acceso a según que opciones de Klipper no son posibles.

**Pero, ¿por qué es importante utilizar un firmware custom, no de Creality, para poder disponer de una versión Klipper oficial y actualizada?**

La versión stock del sistema operativo de la Creality Sonic Pad utilizan una distribución llamada Tina, una versión a su vez que es un fork de OpenWRT hecha por Allwinner para sus procesadores, que es el que justamente monta la Creality Sonic Pad.

Creality ha personalizado esta distribución para instalar los componentes de Klipper como es el core de Klipper, Moonraker y Klipper Screen y personalizarlos para su ecosistema pero, por otro lado, esta customizacion se basa en versiones antiguas de Klipper por lo que perdemos ciertas funciones y compatibilidad.

Aquí es donde entra en juego la comunidad y el proyecto para crear una distribución para la Creality Sonic Pad con un Debian y Klipper oficial preinstalado además de compatible con herramientas como Kiauh para poder instalar o actualizar los componentes de Klipper o relacionados.

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

Para poder adaptar nuestra Sonic Pad a este nuevo firmware custom vamos a tener que descargar un nuevo firmware/imagen/distribución, aplicarlo a nuestro Sonic Pad y realizar configuraciones de nuestro entorno de la forma tradicional... esto es sin alguno de los asistentes que Creality incluye en su firmware stock.

**Por eso es importante recordar que para realizar este proceso has de tener unos minimos conocimientos de Linux, informática ademas de manejo de Klipper y sus ajustes.**

**Por otro lado indicar que este proceso puede dejar inservible vuestro Sonic Pad y que al final es vuestra responsabilidad realizar el proceso y cualquier problema que pueda venir de utilizarlo.**
{% endhint %}

## Instalación custom firmware (Debian) en la Creality Sonic Pad

A continuación os vamos a describir los pasos del proceso, de todas formas os facilitamos el siguiente video que puede facilitar entender el proceso.

{% embed url="<https://www.youtube.com/watch?v=W4cSQND8eSM>" %}

{% hint style="info" %}
**Links importantes que pueden ser de utilidad durante el proceso:**

* [**Creality Original Firmware**](https://www.creality.com/pages/download-creality-sonic-pad), aquí tenéis disponibles para descarga los firmwares originales de Creality para la Sonic Pad
* [**SonicPad Debian Firmware**](https://github.com/Jpe230/SonicPad-Debian/releases), página con las versiones/releases en Github
* [**PhoenixSuit Tool**](https://github.com/CrealityOfficial/Creality_Sonic_Pad_Firmware), descarga de la herramienta para aplicar firmware a nuestra Sonic Pad
  {% endhint %}

### Descarga del custom firmware (Debian) para la Creality Sonic Pad

Disponemos de los ficheros a descargar desde el apartado [Releases](https://github.com/Jpe230/SonicPad-Debian/releases) del proyecto [Sonic Pad Debian](https://github.com/Jpe230/SonicPad-Debian) del compañero Jpe230. Hemos de descargar el zip y todos los zxx que estén en el apartado Assets de cada release:

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FqwuR2g6IsVuxDVyy7zoz%2Fimage.png?alt=media&amp;token=7e981bc9-f6fa-43c3-b495-74a2f56e359a" alt=""><figcaption></figcaption></figure>

Una vez descargados los descomprimimos y nos dejará un fichero con la imagen con extensión `.img`.

### Descarga de PhoenixSuit

El siguiente paso será la descarga de PhoenixSuit que podremos encontrar en la carpeta [tools](https://github.com/CrealityOfficial/Creality_Sonic_Pad_Firmware/tree/main/tools) dentro del repositorio oficial de [Creality Sonic Pad](https://github.com/CrealityOfficial/Creality_Sonic_Pad_Firmware/tree/main/tools) donde encontraremos versiones para Windows y MacOS.

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2Fxd0yU9MWExWoq0DGpoj5%2Fimage.png?alt=media&amp;token=64f2a359-e669-422d-9779-f7e70e8503f9" alt=""><figcaption></figcaption></figure>

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FBnGw2eaR8jTXror68oed%2Fimage.png?alt=media&amp;token=4c38d4e7-4a6b-4991-8d53-ba41a3a067ed" alt=""><figcaption></figcaption></figure>

Una vez descargado lo descomprimimos en nuestro ordenador y abriremos la aplicación cargando la imagen descargada en el punto anterior:

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FVCANbDDJktLgKCdyMaOv%2Fimage.png?alt=media&amp;token=b6a9faf3-5724-43b1-9bfc-669f7db5cc77" alt=""><figcaption></figcaption></figure>

### Creality Sonic Pad en modo BOOT

A continuación conectaremos el cable USB (USB-A macho a USB-A macho!!!) entre nuestro ordenador y nuestra Creality Sonic Pad... es importante hacerlo en el puerto USB con la etiqueta CAM!!!

Pulsaremos con un clip o una llave Allen del diámetro adecuado el pulsador FEL que podéis ver en la imagen a continuación al mismo tiempo que encendemos la Sonic Pad.

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FxTIWM99BdPoTfYBmlRhQ%2Fimage.png?alt=media&amp;token=1204efdc-1787-4208-914b-158e609eb9f6" alt=""><figcaption></figcaption></figure>

Si todo ha ido bien nuestra Creality Sonic Pad estará en modo BOOT, la pantalla no mostrará imagen durante este modo.

### Instalación de drivers Sonic Pad

Con la Creality Sonic Pad en modo BOOT y con el cable USB-Am/Am conectados nuestro ordenador deberá detectar un nuevo dispositivo del que probablemente no tengamos drivers, estos drivers los podemos encontrar en el PhoenixSuit descomprimido en la carpeta Drivers.

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FyQ5LAWDHBQLwztqss2nH%2Fimage.png?alt=media&amp;token=2fe6ef67-6a4e-4f5a-b687-4a3faa5c8171" alt=""><figcaption><p>Ejemplo Windows del administrador de dispositivos y la deteccion de un dispositivo desconocido al conectar la Sonic Pad</p></figcaption></figure>

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FW24GNmcL4PUcJ6sC9xfv%2Fimage.png?alt=media&amp;token=1e7b4a80-f1a5-48e4-9df0-b2663e0f275e" alt=""><figcaption><p>Instalación Windows de drivers</p></figcaption></figure>

### Aplicar custom firmware (Debian) a nuestra Sonic Pad

Una vez tengamos los drivers instalados PhoenixSuit podrá aplicar el firmware custom a ella, como primer paso nos va a pedir que formateemos el dispositivo:

{% hint style="danger" %}
**Este proceso va a borrar completamente el contenido de nuestro Sonic Pad por lo que os aconsejamos disponer de un backup de vuestras configuraciones previas.**

**Este proceso es crítico, cualquier problema durante el mismo podría dañar la Sonic Pad y dejarla inservible.**
{% endhint %}

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2F7xDiSukryllfGQcZIAZT%2Fimage.png?alt=media&amp;token=162e6293-6e58-479d-b0c8-1e36baf00a47" alt=""><figcaption></figcaption></figure>

Una vez finalizado el proceso ya tendremos todo instalado, apagaremos la Sonic Pad y volveremos a encenderla normalmente asegurándonos que retiraremos el cable entre esta y el ordenador.

Si todo ha ido bien al encenderla veremos el logo rojo de Debian, el primer arranque puede tardar unos minutos.

## Primeros pasos con custom firmware (Debian) para Sonic Pad

Ahora que ya tenemos un sistema "libre" además de la IP podemos comenzar a por conectarnos a el por SSH para realizar algunas acciones.

### Conectar a la WiFi

El primer paso, si no conectamos por cable a nuestra red, será configurar la WiFi utilizando la pantalla de la Sonic Pad donde veremos el interfaz, puro, de KlipperScreen. Iremos a Menu -> Network donde veremos las redes WiFi disponibles y podemos conectarnos a una además de ver la IP asignada una vez conectados.

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FU1dJtjP3Wdjhw0HEMOM9%2Fimage.png?alt=media&amp;token=30053a76-9fa0-4443-9993-c2503e5a8599" alt=""><figcaption></figcaption></figure>

### Conectar por SSH

Aunque tenemos más información sobre esto en nuestra [guia de primeros pasos ](/klipper/empezamos/puesta-en-marcha-inicial#conexion-a-ssh)os vamos a describir brevemente el proceso.

Lo primero es importante disponer de la IP de red asignada a nuestra Sonic Pad tal como vimos en el paso anterior, esta IP la utilizaremos para configurar el acceso desde nuestro cliente SSH os aconsejamos [**Terminus**](https://termius.com/download/) por ser multiplataforma, sencillo y no tiene coste para el uso de administrar tus máquinas con Klipper. También dispones de otras como [**Putty**](https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html).

Igualmente importante recordar el usuario/password que podemos utilizar, os aconsejamos utilizar sonic:

| Usuario | Password |
| ------- | -------- |
| root    | toor     |
| sonic   | pad      |

{% hint style="info" %}
Si tenemos nuestra Sonic Pad en un entorno con acceso de red compartido os aconsejamos cambiar estos passwords por unos propios por seguridad con el comando:

`sudo passwd root` -> si queremos cambiarlo para el usuario root

`sudo passwd sonic` -> en el caso del usuario sonic
{% endhint %}

También os aconsejamos actualizar el sistema mediante el comando `sudo apt-get update && sudo apt-get upgrade` para asegurarnos que tenemos todo actualizado.

### Kiauh

En esta distribución contamos con Kiauh que es un script que desde SSH y mediante sencillos menús nos va a permitir instalar, actualizar y eliminar componentes relacionados con Klipper.

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2Foq4BfhzXKKGiMZ3Ua2cX%2Fimage.png?alt=media&amp;token=63a3ccdf-feb0-41d0-9b07-233733796891" alt=""><figcaption></figcaption></figure>

Podremos lanzar Kiauh desde la línea de comandos de SSH lanzando `~/kiauh/kiauh.sh` (el path completo por información es `/home/sonic/kiauh/kiauh.sh`)

Toda la información de nuestra instancia de Klipper en nuestra nueva Sonic Pad custom la vamos a encontrar en el path `/home/sonic/printer_data/config`

{% hint style="warning" %}
**CONSEJOS SOBRE APAGADO DE LA SONIC PAD:**

**Para evitar problemas con el sistema os aconsejamos SIEMPRE realizar un apagado correcto de la Sonic Pad, apagar el sistema utilizando el botón de apagado/encendido es contraproducente.**

**El apagado correcto podremos realizarlo desde el interfaz web o Klipperscreen que disponen de opciones para ello apagando el sistema de la forma correcta.**
{% endhint %}

### Ajuste de zona horaria

Otro ajuste recomendable es el de la zona horaria para que la información de tiempos sea siempre correcta con nuestra localización.

Para ello:

* Podemos listar todas las zonas horarias con `timedatectl list-timezones | more`
* Para ajustar nuestra Sonic Pad a una zona horaria lo haremos con `timedatectl set-timezone 'Europe/Madrid'`
* Verificaremos que todo está correcto con `timedatectl` y reiniciaremos el sistema para que se apliquen los cambios

### Acelerómetro

Para aprovechar las capacidades de Klipper con su[ Input Shaper](/klipper/empezamos/input-shaper), os aconsejamos leer la guía del link, y el acelerómetro que podemos instalar en nuestra Sonic Pad os vamos a explicar el proceso para poder hacer funcionar este en nuestro custom firmware.

* Primero nos aseguramos que nuestro sistema esté completamente actualizado lanzando el siguiente comando desde nuestra linea de comandos SSH:

```bash
sudo apt update
```

* Instalaremos las dependencias para poder utilizar el acelerómetro y sus componentes

```bash
 sudo apt install binutils-arm-none-eabi libnewlib-arm-none-eabi libstdc++-arm-none-eabi-newlib gcc-arm-none-eabi
```

* Instalaremos los componentes para realizar los cálculos Input Shaper

```bash
sudo apt install python3-numpy python3-matplotlib libatlas-base-dev
```

* Añadiremos el componente numpy a nuestro entorno python virtual Klipper

```bash
~/klippy-env/bin/pip install -v nump
```

* Nos aseguramos que nuestro servicio Klipper MCU arranque al inicio

```bash
sudo cp ~klipper/scripts/klipper-mcu.service /etc/system/system/
```

* Aplicaremos el firmware Klipper a nuestra MCU Sonic Pad para tener acceso a sus pines/componentes (como en este caso el acelerómetro)

```bash
cd ~/klipper
make clean
make menuconfig # select "linux process"
make flash
```

* Ahora que ya hemos habilitado nuestra Sonic Pad como segunda MCU hemos de habilitar el acceso por parte de Klipper, añadiremos lo siguiente a nuestro `printer.cfg`

```django
[mcu rpi]
serial: /tmp/klipper_host_mcu

[adxl345]
cs_pin: rpi:None
spi_speed: 2000000
spi_bus: spidev2.0

[resonance_tester]
accel_chip: adxl345
accel_per_hz: 70
probe_points:
      117.5,117.5,10
```

Con esto ya tenemos listo nuestra Sonic Pad para utilizar su acelerómetro. Os aconsejamos revisar nuestra [**guía Input Shaper** ](/klipper/empezamos/input-shaper)para ver los siguientes pasos y ajustes.

***

#### Resolución de problemas - Errores al aplicar el firmware Klipper a la Sonic Pad para añadirla como segunda MCU

En algunos casos se pueden ver errores como el siguiente (unsupported locale setting) durante el proceso:

```bash
sonic@SonicPad:~/klipper$ make menuconfig #
Loaded configuration '/home/sonic/klipper/.config'
Traceback (most recent call last):
  File "/home/sonic/klipper/lib/kconfiglib/menuconfig.py", line 3281, in <module>
    _main()
  File "/home/sonic/klipper/lib/kconfiglib/menuconfig.py", line 661, in _main
    menuconfig(standard_kconfig(__doc__))
  File "/home/sonic/klipper/lib/kconfiglib/menuconfig.py", line 705, in menuconfig
    locale.setlocale(locale.LC_ALL, "")
  File "/usr/lib/python3.9/locale.py", line 610, in setlocale
    return _setlocale(category, locale)
locale.Error: unsupported locale setting
make: *** [Makefile:116: menuconfig] Error 1
```

Ejecutaremos los siguientes comandos para ajustar el locale en "en\_US UTF8"

```bash
export LC_ALL="en_US.UTF-8"
export LC_CTYPE="en_US.UTF-8"
sudo dpkg-reconfigure locales
```

#### Resolución de problemas - Durante el proceso de cálculo de resonancias se queda en "Wait for calculations"

Normalmente en estos casos puede ser por incompatibilidades entre la versión instalada de numpy y nuestro sistema, usando una versión anterior o actualizando esta suele ser la solución.

Para utilizar una versión anterior, donde podremos especificar la versión a usar:

```bash
~/klippy-env/bin/pip install -v numpy==1.25.2
```

### Añadir soporte USB para gcodes

Al realizar los cambios anteriores perdemos algunas de las funcionalidades que Creality integra en su firmware como es que podamos usar un USB para pasar los gcodes a nuestra máquina, algo que con Klipper no suele ser necesario salvo en determinados usos específicos por requerimiento... como por ejemplo tener la máquina en un entorno sin acceso a red.

* El primer paso, para simplificar el proceso, es darle un nombre estándar a nuestro USB... pongamos para la guía que le llamamos USB

{% hint style="warning" %}
Es importante recordar que Linux es sensible a mayúsculas y minúsculas por lo que el nombre que le des a tu USB ha de ser exactamente igual al que uses en los siguiente pasos.
{% endhint %}

* Editaremos la configuración de fstab que es el demonio que se encarga de montar unidades, esto lo haremos mediante el siguiente comando desde SSH `sudo nano /etc/fstab` (en la [guía de primeros pasos](/klipper/empezamos/puesta-en-marcha-inicial#conexion-a-ssh) tienes información de nano que es un editor de textos en línea de comandos para Linux) y añadiremos al final lo siguiente:

```bash
/dev/disk/by-label/USB  /home/sonic/printer_data/gcodes/USB    auto    defaults,uid=sonic      0       0
```

* Crearemos un punto de montaje para ello con `mkdir ~/printer_data/gcodes/USB`
* Montaremos todos los recursos `sudo mount -a`


# Artillery - Klipper

Guías de instalación de Klipper en impresoras Artillery

Selecciona tu modelo de Artillery para acceder a la guía de instalación específica:

## Modelos Disponibles

### [Sidewinder X2](/klipper/instalacion/guias-instalacion-especificas-impresora-electronica/artillery-klipper/sw-x2)

Las Artillery SW X2 vienen con firmware Marlin 2.x y electrónica Ruby. Esta guía cubre la migración completa a Klipper, incluyendo:

* Compilación de firmware para STM32F401
* Procedimiento de flasheo por USB (modo DFU)
* Configuración inicial de printer.cfg
* Referencias a configuraciones oficiales de Klipper

**Audiencia:** Usuarios con SW X2 que desean migrar a Klipper

***

### [Sidewinder X4 Pro / X4 Plus](/klipper/instalacion/guias-instalacion-especificas-impresora-electronica/artillery-klipper/sw-x4-pro-plus)

Guía completa de instalación y configuración de Klipper en la serie X4 Pro/Plus con STM32F407. Cubre:

* Especificaciones técnicas y pinout
* Primeros pasos (SSH, puertos COM/USB)
* Instalación desde cero
* Configuración avanzada (Z offset, bed mesh, PID, etc.)
* Mods recomendados
* Mantenimiento (backup firmware, actualizaciones, unbrick)

**Audiencia:** Usuarios con X4 Pro/Plus, desde principiantes hasta avanzados

***

## Documentación Relacionada

* [**Guías de Instalación Específicas**](/klipper/instalacion) - Otras impresoras y electrónicas
* [**Primeros Pasos con Klipper**](/klipper/empezamos) - Configuración general
* [**Troubleshooting**](/klipper/troubleshooting) - Resolución de problemas

***

**Última actualización:** 2026-05-05 **Autor:** HAL (Technical Writer - 3Dwork.io)


# Sidewinder X2

Las Artillery SW X2 vienen de serie con firmware Marlin 2.x y, teniendo en cuenta la potencia de la electrónica Ruby que monta y el soporte de Artillery, es muy aconsejable pasarlas al sistema Klipper.

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

* **Klipper a día de hoy no soporta el uso de pantallas serial de forma directa como las que montan estas Artillery por lo que�**<mark style="color:red;">**se aconseja la desconexión de la pantalla a la electrónica**</mark>**.**
* **Los siguientes procedimientos requieren de unos mínimos conocimientos, os aconsejamos antes informaros bien ya que�**<mark style="color:red;">**cualquier problema o fallo al aplicar este procedimiento es vuestra responsabilidad y pueda eliminar la garantía con Artillery**</mark>**.**
  {% endhint %}

Antes de empezar es necesario que dispongáis un host con Klipper instalado, no vamos a explicar este proceso ya que va a depender de gustos personales o necesidades específicas. Tenéis nuestra [guía de instalación aquí](/klipper/instalacion/guias-instalacion-especificas-impresora-electronica).

En nuestro caso os aconsejamos el uso de una Raspberry Pi o Bigtreetech Pi/Pad5/Pad7 con módulo CB1 y una usar una imagen de sistema con Klipper instalado como MainsailOS/RatOS dependiendo de vuestro host y conocimientos.

## Generar y aplicar el firmware Klipper a nuestra Ruby

{% hint style="warning" %}
**Los siguientes procedimientos requieren de unos mínimos conocimientos, os aconsejamos antes informaros bien ya que�**<mark style="color:red;">**cualquier problema o fallo al aplicar este procedimiento es vuestra responsabilidad y pueda eliminar la garantía con Artillery**</mark>**.**
{% endhint %}

El primer paso para poder aplicar el firmware Klipper en nuestra Artillery Ruby v1.x es poner esta en modo DFU.

Aunque se puede hacer lanzando comandos gcode (M997) os aconsejamos realizar el proceso mediante un jumper, con la impresora/electrónica completamente apagada sin alimentación, en la electrónica entre los pines BOOT y 3.3v tal como podéis ver en la siguiente captura.

Una vez ya tenemos el jumper el siguiente paso será [conectar por SSH](https://github.com/alienboyxp/gitbook_es_klipper_3dwork_io/blob/main/klipper/instalacion/empezamos/puesta-en-marcha-inicial.md#conexion-a-ssh) a nuestro host y lanzaremos los siguientes comandos:

```bash
cd ~/klipper/
make menuconfig
```

Nos aparecerá un menu para ajustar las opciones para compilar nuestro firmware Klipper, para ajustarlo a una Artillery Ruby:

* Ajustaremos **STMicroelectronics STM32** como **Micro-controller Architecture**
* En **Processor model** seleccionaremos **STM32F401**
* En **Bootloader** pondremos **No bootloader**
* Tan solo nos queda pulsar **Q para salir** y **Y para guardar cambios**

El siguiente paso será lanzar el comando para compilar el firmware:

```bash
make
```

Una vez finalizada la compilación del firmware conectaremos por USB nuestra Artillery Ruby a nuestro host y lanzaremos el siguiente comando para encontrar el serial id de esta:

```bash
ls /dev/serial/by-id/*
```

Deberíamos obtener algo como esto:

```bash
usb-Klipper_stm32f401xc_4F006F000351383532393535-if00
```

En el caso que no obtengamos el serial id os aconsejamos revisar la [guía de troubleshooting/resolución de problemas ](https://github.com/alienboyxp/gitbook_es_klipper_3dwork_io/blob/main/klipper/instalacion/troubleshooting.md)que os puede ser de ayuda para identificar el problema.

Pararemos el servicio Klipper por seguridad:

```bash
sudo service klipper stop
```

A continuación, y de nuevo asegurando que la Ruby se encuentra en modo DFU (jumper), conectada por USB y tenemos el serial id... lanzaremos el siguiente comando para aplicar el firmware a nuestra Ruby:

```bash
make flash FLASH_DEVICE=/dev/serial/by-id/usb-Klipper_stm32f401xc_4F006F000351383532393535-if00
```

Si todo ha ido bien podremos retirar el cable USB y el jumper.

Arrancaremos el servicio Klipper:

```bash
sudo service klipper start
```

¡Ya tenemos todo listo!!!

## Obtener un printer.cfg para nuestra Artillery

El siguiente paso, tal como tenéis en la [guía de primeros pasos](https://github.com/alienboyxp/gitbook_es_klipper_3dwork_io/blob/main/klipper/instalacion/empezamos/puesta-en-marcha-inicial.md), sería la de poner nuestro printer.cfg con las configuraciones de nuestra impresora/electrónica y ajustaremos en este el serial id.

A modo de ejemplo, os facilitamos los de Artillery que tenemos en el Github de Klipper y otros alternativos a usar bajo vuestra propia responsabilidad:

| Modelo                                                      |                                                                                                                                                                  |
| ----------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Artillery Sidewinder X2 (2022)                              | [printer.cfg](https://github.com/Klipper3d/klipper/blob/master/config/printer-artillery-sidewinder-x2-2022.cfg)                                                  |
| Artillery Genius Pro                                        |                                                                                                                                                                  |
| Artillery Sidewinder X1 (Stock)                             | [printer.cfg](https://github.com/Clank50AE/Clanks-Klipper-Configs/blob/master/SideWinder%20X1%20Stock.cfg) NO OFICIAL KLIPPER!!!                                 |
| Artillery Sidewinder X1 (Stock + Bltouch)                   | [printer.cfg](https://github.com/Clank50AE/Clanks-Klipper-Configs/blob/master/SideWinder%20X1%20BLTouch.cfg) NO OFICIAL KLIPPER!!!                               |
| Artillery Sidewinder X1 (SKR 1.4 Turbo + TMC2209 + Bltouch) | [printer.cfg](https://github.com/Clank50AE/Clanks-Klipper-Configs/blob/master/Sidewinder%20X1%20SKR%201_4%20Turbo%20TMC2209%20BLTouch.cfg) NO OFICIAL KLIPPER!!! |
| Artillery Genius (Stock)                                    | [printer.cfg](https://github.com/Clank50AE/Clanks-Klipper-Configs/blob/master/Genius%20Stock.cfg) NO OFICIAL KLIPPER!!!                                          |
| Artillery Genius (Stock + Bltouch)                          | [printer.cfg](https://github.com/Clank50AE/Clanks-Klipper-Configs/blob/master/Genius%20BLTouch.cfg) NO OFICIAL KLIPPER!!!                                        |
| Artillery Genius (SKR 1.4 Turbo + TMC2209 + Bltouch)        | [printer.cfg](https://github.com/Clank50AE/Clanks-Klipper-Configs/blob/master/Genius%20SKR%201_4%20Turbo%20TMC2209%20BLTouch.cfg) NO OFICIAL KLIPPER!!!          |

Una vez nuestro Klipper conecte con la electrónica, os aconsejamos seguir nuestra [guía de primeros pasos](https://github.com/alienboyxp/gitbook_es_klipper_3dwork_io/blob/main/klipper/instalacion/empezamos/puesta-en-marcha-inicial.md) para finalizar el proceso de configuración y ajustes.


# Sidewinder X4 Pro / X4 Plus

Guía completa de instalación y configuración de Klipper en Artillery Sidewinder X4 Pro/Plus

## Introducción

La **Artillery Sidewinder X4 Pro** y **X4 Plus** son impresoras 3D FDM con un **sistema completo Linux + Klipper integrado** directamente en la mainboard. No necesitas Raspberry Pi separada — todo funciona dentro de la impresora.

Esta guía es para **todos los niveles**: si nunca usaste SSH o Linux, no te preocupes. Explicaremos cada concepto paso a paso.

{% hint style="info" %}
**Lo mejor:** La mainboard Artillery STM32F407 ejecuta un pequeño sistema Linux + Klipper. Es como tener una computadora dentro de tu impresora.
{% endhint %}

> **Versión firmware base:** Artillery SW4-Pro firmware 1.5.3
>
> **Compatibilidad:** X4 Pro | X4 Plus

***

## Especificaciones Técnicas

### Mainboard & Sistema Integrado

| Componente              | Especificación                                  |
| ----------------------- | ----------------------------------------------- |
| **Mainboard**           | Artillery Custom (STM32F407 + Linux SoC)        |
| **MCU Principal**       | STM32F407 (32-bit ARM Cortex-M4, 168 MHz)       |
| **Almacenamiento**      | eMMC 8GB estándar (upgrading a 32GB disponible) |
| **Red**                 | WiFi 2.4GHz + Ethernet (RJ45)                   |
| **Pantalla**            | 4.3" LCD táctil integrada                       |
| **Sistema Operativo**   | Linux minimalista (Buildroot) + Klipper         |
| **Usuario SSH default** | `mks` / contraseña `makerbase`                  |

### ¿Qué significa todo esto?

* **STM32F407:** Microcontrolador potente (168 MHz) que controla motores y sensores
* **eMMC 8GB:** Almacenamiento rápido donde vive Linux y Klipper (como SSD pero integrado)
* **WiFi nativo:** Puedes acceder a tu impresora desde cualquier dispositivo en la red
* **Sistema Linux:** Corre un pequeño SO que ejecuta Klipper
* **Usuario SSH:** Acceso remoto por terminal (como controlar impresora por línea de comandos)

### Hardware de Impresión

* **Estructura:** Marco aluminio reforzado (resistente, no se dobla)
* **Plataforma:** 220 x 220 x 250mm (tamaño respetable para gama media)
* **Velocidad:** Hasta 200 mm/s de serie (con Klipper puedes alcanzar 250+ mm/s) — ver [Velocidad Máxima](/klipper/empezamos/velocidad-maxima)
* **Extrusor:** Direct Drive (filamento no pasa por tubo, control preciso)
* **Cama:** PEI + resistencia cerámica (calienta rápido, adhesión excelente)

***

## Pinout Mainboard MCU

### Diagrama Pinout Visual

![Artillery Mainboard STM32F407 Pinout](https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2Fgit-blob-2af333a471f5b329f96abc2779ba4be1a8c2af55%2Fmainboard-pinout.webp?alt=media) *Diagrama de pines de la mainboard Artillery. Estos pines controlan todos los componentes (motores, calentadores, ventiladores).*

### Pines Críticos Explicados

Cada pin STM32F407 controla una función específica:

| Función               | Pins      | ¿Qué hace?                                  |
| --------------------- | --------- | ------------------------------------------- |
| **Motor X**           | PA0-PA3   | Mueve carro izquierda/derecha               |
| **Motor Y**           | PA4-PA7   | Mueve cama adelante/atrás                   |
| **Motor Z**           | PB0-PB3   | Mueve cabezal arriba/abajo                  |
| **Extrusor**          | PB4-PB7   | Empuja filamento hacia boquilla             |
| **Calentador Hotend** | PC0       | Calienta la boquilla (donde sale filamento) |
| **Calentador Cama**   | PC1       | Calienta la plataforma de impresión         |
| **Sensor Hotend**     | PA0 (ADC) | Mide temperatura de boquilla                |
| **Sensor Cama**       | PA1 (ADC) | Mide temperatura de cama                    |
| **Ventilador Hotend** | PC2       | Enfría el hotend (crítico para calidad)     |
| **Ventilador Cama**   | PC3       | Enfría la cama entre impresiones            |

***

## Primeros Pasos: Acceso a Fluidd

Fluidd es la **interfaz web de Klipper**. Es donde controlas todo tu impresora desde el navegador. Acceder a Fluidd es lo PRIMERO que debes hacer.

### Paso 1: Conectar a WiFi

Tu impresora necesita estar en tu red WiFi para que puedas acceder desde tu PC.

**En la pantalla táctil integrada de la impresora:**

1. **Enciende la impresora**
2. En la pantalla, toca **\[Menu]** (puede variar según revisión)
3. Navega a **\[Network]** o **\[Net]** o **\[WiFi]**
4. Selecciona tu red WiFi de la lista
5. Ingresa la contraseña WiFi
6. Espera a conectar (verás un ícono WiFi en la pantalla)

{% hint style="info" %}
**Si tu impresora tiene puerto Ethernet (RJ45):** Puedes conectar un cable de red directamente — es más rápido y estable que WiFi. Salta el paso WiFi.
{% endhint %}

### Paso 2: Encontrar la Dirección IP

Tu impresora ahora tiene una **dirección IP** (como su "dirección en internet" en tu red local). Necesitas esta dirección para acceder desde tu PC.

**En la misma pantalla de Network:**

Deberías ver algo como:

```
IP Address: 192.168.1.171
```

Anota este número. Es ÚNICO de tu impresora.

{% hint style="warning" %}
Si no ves la IP en la pantalla, busca en tu router (router admin page, típicamente 192.168.1.1) y busca "Artillery" en dispositivos conectados.
{% endhint %}

### Paso 3: Abrir Fluidd en el Navegador

Ahora es lo emocionante: abre tu navegador favorito (Chrome, Firefox, Safari) en tu PC y escribe:

```
http://192.168.1.171
```

(Reemplaza 171 con tu IP real)

Presiona Enter y **¡Fluidd aparecerá!** Verás:

* **Dashboard:** Temperatura en tiempo real, estado de impresión
* **Control:** Botones para mover ejes, controlar extrusor
* **Files:** Cargar archivos .gcode para imprimir
* **Config:** Editor para cambiar configuración
* **Temperature:** Gráficos de temperatura
* **History:** Registro de impresiones

{% hint style="success" %}
Si Fluidd abre en **chino**, haz clic en el ícono ⚙️ (engranaje) en la esquina superior derecha y selecciona tu idioma.
{% endhint %}

### Paso 4: Verificar que todo Funciona

En el **Dashboard de Fluidd**, deberías ver:

```
MCU: connected ✓
Temperature: hotend XX°C, bed XX°C
```

Si dice "connected", ¡perfectamente! Tu mainboard habla con Klipper.

Si dice "disconnected", hay un problema (veremos soluciones abajo).

***

## Configuración Básica de Printer

Ahora que accediste a Fluidd, necesitas configurar cómo funciona tu impresora. Esto se hace editando el archivo `printer.cfg`.

{% hint style="info" %}
**Primera vez con Klipper?** Lee [Primeros pasos con Klipper](/klipper/empezamos/puesta-en-marcha-inicial) para una introducción completa al ecosistema.
{% endhint %}

### ¿Qué es printer.cfg?

Es un archivo de **configuración de texto** que le dice a Klipper exactamente:

* Dónde están tus motores (en qué pines)
* Cuántos pasos son un milímetro
* Temperaturas máximas permitidas
* Dónde están los sensores
* Cómo funciona cada componente

Sin este archivo, Klipper no sabe nada de tu máquina.

### Acceder a printer.cfg en Fluidd

1. En Fluidd, ve a **Config** (arriba)
2. Haz clic en **printer.cfg**
3. Se abre el editor de texto

### Configuración Base para X4 Pro/Plus

Si tu printer.cfg está vacío o corrupto, **reemplázalo completamente** con esto:

```ini
# Artillery Sidewinder X4 Pro/Plus - Configuración Base Klipper

[printer]
kinematics: cartesian
max_velocity: 200
max_accel: 3000
max_z_velocity: 40
max_z_accel: 1000

# ========================================
# MOTORES STEPPERS (controlan movimiento)
# ========================================

# Eje X (movimiento izquierda-derecha)
[stepper_x]
step_pin: PA0
dir_pin: PA1
enable_pin: !PA2
microsteps: 16
rotation_distance: 40
endstop_pin: ^PA14
position_endstop: 0
position_max: 220
homing_speed: 50

# Eje Y (movimiento adelante-atrás)
[stepper_y]
step_pin: PA4
dir_pin: PA5
enable_pin: !PA6
microsteps: 16
rotation_distance: 40
endstop_pin: ^PA15
position_endstop: 0
position_max: 220
homing_speed: 50

# Eje Z (movimiento arriba-abajo)
[stepper_z]
step_pin: PB0
dir_pin: PB1
enable_pin: !PB2
microsteps: 16
rotation_distance: 8
endstop_pin: ^PB6
position_endstop: 0
position_max: 250
homing_speed: 10

# ========================================
# EXTRUSOR (empuja filamento)
# ========================================

[extruder]
step_pin: PB4
dir_pin: PB5
enable_pin: !PB6
microsteps: 16
rotation_distance: 4.5
nozzle_diameter: 0.4
filament_diameter: 1.75
heater_pin: PC0
sensor_type: Generic 3950
sensor_pin: PA0
control: pid
pid_Kp: 22.2
pid_Ki: 1.08
pid_Kd: 114
min_extrude_temp: 170

# ========================================
# CAMA CALIENTE (plataforma)
# ========================================

[heater_bed]
heater_pin: PC1
sensor_type: Generic 3950
sensor_pin: PA1
control: pid
pid_Kp: 54.27
pid_Ki: 0.77
pid_Kd: 959
min_temp: 0
max_temp: 130

# ========================================
# VENTILADORES
# ========================================

[fan]
pin: PC2
max_power: 1.0
kick_start_time: 0.1
off_below: 0.1

# ========================================
# PANTALLA LCD (opcional)
# ========================================

[display]
lcd_type: st7920
rs_pin: PD10
e_pin: PD11
d4_pin: PD12
d5_pin: PD13
d6_pin: PD14
d7_pin: PD15
encoder_pins: ^PD6,^PD7
click_pin: ^!PD8
```

**Después de pegar:**

1. Haz clic en **Save** (arriba a la derecha)
2. En Fluidd, ve a **Control** → presiona **Firmware Restart**
3. Espera 30 segundos a que reinicie

**Deberías ver temperatura en el dashboard.**

{% hint style="warning" %}
**Nota importante:** Estos valores son referencias. Después necesitarás:

* [Calibrar extrusor (E-steps)](/klipper/empezamos/calibracion-extrusor-e-steps)
* [Ajustar temperaturas (PID)](/klipper/empezamos/pid)
* [Nivelar cama](/klipper/empezamos/nivelacion-cama-manual)

Eso lo cubrimos en la siguiente sección.
{% endhint %}

***

## Configuración de Printer (Calibración y Tunning)

Una vez que printer.cfg funciona básicamente, vamos a afinar TODO para impresiones perfectas.

### Z Offset (Altura de Boquilla)

**¿Qué es?** La distancia exacta entre la boquilla y la cama cuando Z=0.

**¿Por qué importa?** Si está mal:

* Muy alto → filamento no toca la cama (no pega)
* Muy bajo → boquilla roza la cama (daña impresora)

**Más detalles:** Ver [Nivelación manual de cama](/klipper/empezamos/nivelacion-cama-manual) para técnicas avanzadas.

**Calibración Manual:**

En Fluidd → **Control**:

1. Presiona **\[Home All]** (pone impresora en origen)
2. En **Move**, baja **Z** manualmente hasta que:
   * Puedas pasar un **papel de 0.1mm** bajo la boquilla
   * Sientas **fricción** (resistencia del papel)
3. Anota el valor Z que ves (ej: -0.15)

En Fluidd → **Config** → **printer.cfg**, añade al final:

```ini
[gcode_macro HOME_Z]
gcode:
  SET_GCODE_OFFSET Z=-0.15
```

(Reemplaza -0.15 con tu valor)

Luego presiona **Save & Restart**.

### Bed Level (Nivelado Manual de Cama)

**¿Qué es?** Ajustar los 4 tornillos bajo la cama para que esté plana.

**¿Por qué?** Si está torcida:

* Un lado toca la boquilla, el otro no
* Impresiones con calidad desigual

📚 **Guía completa:** [Nivelación manual de cama](/klipper/empezamos/nivelacion-cama-manual)

**Proceso:**

En Fluidd → **Control**:

```bash
# Home solo X e Y (no Z aún)
G28 X Y

# Ir a esquina 1 (frontal-izquierda)
G0 X30 Y30 F6000
```

Ahora **ajusta el tornillo bajo esa esquina** hasta que el papel tenga fricción.

**Repite en las otras 3 esquinas:**

```bash
G0 X190 Y30 F6000   # Frontal-derecha
G0 X190 Y190 F6000  # Trasera-derecha
G0 X30 Y190 F6000   # Trasera-izquierda
```

Ajusta cada tornillo **lentamente**. Esto toma 20-30 minutos en la primera vez.

### Bed Mesh (Compensación Automática)

**¿Qué es?** Si tu cama tiene pequeñas ondulaciones, Klipper las compensa automáticamente.

📚 **Profundizar:** [Malla nivelación de cama](/klipper/empezamos/malla-nivelacion-de-cama-klipper)

**En printer.cfg**, añade:

```ini
[bed_mesh]
speed: 120
horizontal_move_z: 5
mesh_min: 10, 10
mesh_max: 210, 210
probe_count: 5, 5
algorithm: bicubic
fade_start: 1
fade_end: 10
fade_target: 0
```

**Para generar el mesh:**

En Fluidd → **Control**, en terminal ejecuta:

```bash
BED_MESH_CALIBRATE
```

Espera 3-5 minutos (la boquilla se moverá midiendo altura en cada punto).

Luego:

```bash
SAVE_CONFIG
```

Klipper guardará el mapa de tu cama.

### Calibración PID (Control de Temperatura)

**¿Qué es PID?** Sistema automático que Klipper usa para mantener temperatura exacta.

**Sin PID:** Temperatura sube/baja inconsistentemente **Con PID calibrado:** Temperatura perfecta siempre

📚 **Aprende más:** [Guía completa PID](/klipper/empezamos/pid)

**Para el Hotend (a 200°C):**

En Fluidd → **Control**, terminal:

```bash
PID_CALIBRATE HEATER=extruder TARGET=200
```

Espera 10 minutos. Verás que se caliente, se enfríe, se caliente... Klipper está aprendiendo.

Al final:

```
PID parameters: pid_Kp=X pid_Ki=Y pid_Kd=Z
```

**Para la Cama (a 60°C):**

```bash
PID_CALIBRATE HEATER=heater_bed TARGET=60
```

Espera 15 minutos.

**Al terminar ambas:**

```bash
SAVE_CONFIG
```

Los valores se guardan automáticamente en printer.cfg.

### Tensión de Correas

**¿Qué es?** Las correas que mueven X e Y deben tener tensión correcta.

**Método simple:**

Presiona la correa en el medio entre dos puntos. Deberías sentir una **resistencia moderada** que corresponde a \~110-130 Hz (frecuencia de vibración).

* Si está muy floja → afloja el estribo de la correa
* Si está muy tensa → aprieta el estribo

Después de ajustar, imprime una pieza pequeña y mira si está recta.

### Fan Noise (Ventiladores Silenciosos)

Por defecto, ventiladores pueden ser ruidosos. Aquí los controlamos:

```ini
[fan]
pin: PC2
max_power: 1.0
kick_start_time: 0.1
off_below: 0.1
cycle_time: 0.010

[controller_fan mainboard_fan]
pin: PC3
max_power: 1.0
kick_start_time: 0.1
fan_speed: 0.5
idle_timeout: 30
heater: extruder, heater_bed
stepper: stepper_x, stepper_y, stepper_z, extruder
```

Esto hace que:

* Fan parte cooling se apaga cuando no se necesita
* Fan mainboard se adapta a carga de trabajo
* Resultado: mucho más silencio

***

## Sugerencias de Mods

### Refrigeración de Steppers

**Qué:** Disipadores de aluminio en motores **Por qué:** Motores más fríos = más potencia disponible **Costo:** \~10€ **Tiempo:** 15 minutos

Se pegan con adhesivo térmico. Especialmente útil si imprimes largas horas.

### Cable Management

**Qué:** Organizar cables con espirales de nylon **Por qué:** Mejor airflow, menos ruido, más profesional **Costo:** \~5€ **Tiempo:** 30 minutos

Mantén cables USB y potencia separados de motores.

### Upgrade de Cama

**Opciones:**

* **PEI magnetizada:** Cambios de plataforma ultrarápidos
* **Textil (Ultem):** Adhesión excelente sin pegamento

**Costo:** 30-50€ **Beneficio:** Nunca más limpieza de pegamento

### Input Shaper (Avanzado)

**Qué:** Acelerómetro ADXL345 que Klipper usa para calibrar vibraciones **Beneficio:** Impresiones más nítidas, sin artefactos **Costo:** 20€ **Dificultad:** Media (requiere soldadura)

📚 **Guía detallada:** [Input Shaper](/klipper/empezamos/input-shaper)

***

## OS Updates y Mantenimiento

### Acceso SSH: Cómo Conectarse Remotamente

**¿Qué es SSH?** Una forma segura de conectarte a la impresora **por terminal** (línea de comandos) desde tu PC.

Fluidd es interfaz gráfica. SSH es poder escribir comandos directamente.

**Pasos para conectar:**

#### En Windows:

1. **Descarga PuTTY:** <https://www.putty.org/>
2. **Abre PuTTY**
3. En **Host Name**, escribe tu IP: `192.168.1.171`
4. En **Port**, asegúrate que dice `22`
5. Haz clic en **Open**
6. Verás una pregunta sobre la clave del servidor → presiona **Yes**
7. En el prompt, escribe:

   ```
   login as: mks
   password: makerbase
   ```

#### En Mac/Linux:

```bash
ssh mks@192.168.1.171
# Contraseña: makerbase
```

**Ahora estás dentro de la impresora por terminal.** Puedes escribir comandos.

Verás algo como:

```
mks@printer:~ $
```

Esto significa que estás conectado y puedes escribir comandos.

### Actualizar Firmware MCU (Klipper)

**¿Cuándo hacer esto?**

* Quieres nuevas características de Klipper
* Bugs fixes de seguridad
* Mejor rendimiento

**¿Qué pasa?** Compilamos Klipper en la mainboard y flasheamos el firmware STM32.

#### Paso 1: Hacer Backup (CRÍTICO)

Siempre haz backup antes de cambios:

```bash
# Conectado vía SSH

# Entrar como super-usuario (root)
sudo -i

# Cambiar a directorio de Klipper
cd /home/mks/klipper

# Hacer backup del firmware actual
stm32flash -r ~/backup-firmware-original.bin /dev/ttyS0
```

Esto guarda tu firmware original. Si algo sale mal, puedes restaurar.

**Transfiere este archivo a tu PC vía SCP (copia segura):**

```bash
# En tu PC (no en la impresora)
scp mks@192.168.1.171:~/backup-firmware-original.bin ~/

# Pedirá contraseña: makerbase
```

Ahora tienes backup en tu PC. Guardalo en lugar seguro.

#### Paso 2: Compilar Nuevo Firmware

**Vía SSH en la impresora:**

```bash
cd /home/mks/klipper

# Limpiar compilaciones previas
make clean

# Abrir menú de configuración
make menuconfig
```

**En el menú, selecciona:**

```
Microcontroller Architecture: STMicroelectronics STM32
Processor model: stm32f407
Clock reference: 8 MHz crystal
Communication interface: PA11/PA12
```

Presiona **Q** para salir, **Y** para guardar.

```bash
# Compilar (tarda 2-5 minutos)
make
```

Espera a ver:

```
Build complete
```

#### Paso 3: Flashear Firmware a Mainboard

**Lo crítico:** Poner mainboard en modo bootloader antes de flashear.

```bash
# Aún conectado vía SSH, ejecuta:
sudo -i

# Activar modo bootloader
echo 0 > /sys/class/gpio/gpio86/value
echo 0 > /sys/class/gpio/gpio83/value

# Instalar dfu-util si no está
apt install dfu-util

# Flashear
dfu-util -a 0 -i 0 -s 0x08000000:0x10000 -D /home/mks/klipper.bin

# Espera a ver: "File downloaded successfully"
```

#### Paso 4: Reiniciar y Verificar

```bash
# Salir de SSH
exit
```

Desconecta SSH y en Fluidd:

1. Ve a **Control**
2. Presiona **Firmware Restart**
3. Espera 30 segundos

En el dashboard deberías ver temperatura nuevamente. ✓ ¡Éxito!

### Backup y Restauración de eMMC

**¿Por qué?** Si algo se daña, puedes restaurar todo rápidamente.

**Hacer backup completo:**

```bash
# Vía SSH
sudo -i

# Verificar espacio (necesitas ~8GB libres)
df -h

# Hacer backup
dd if=/dev/mmcblk0 of=/home/mks/emmc-backup.img bs=1M

# Transferir a tu PC
# (En tu PC)
scp mks@192.168.1.171:/home/mks/emmc-backup.img ~/
```

**Restaurar desde backup (si impresora muere):**

```bash
# Vía SSH
dd if=/home/mks/emmc-backup.img of=/dev/mmcblk0 bs=1M
```

### Migrar a eMMC 32GB

Si necesitas más espacio (8GB → 32GB):

1. **Descargar imagen 32GB** desde SourceForge wiki
2. **Hacer backup actual** (ver arriba)
3. **Preparar nuevo módulo eMMC**
4. **Escribir imagen en nuevo módulo** con herramienta USB (Balena Etcher)
5. **Instalar nuevo módulo** en impresora
6. **Verificar:** `df -h` debería mostrar \~30GB

### Actualizar Linux en la Impresora

Mantener seguridad y rendimiento al día:

```bash
# Vía SSH
sudo -i

# Actualizar lista de paquetes
apt update

# Instalar actualizaciones
apt upgrade -y

# Reiniciar
reboot
```

***

## Troubleshooting

📚 **Para problemas no listados aquí:** Consulta [Klipper Troubleshooting](/klipper/troubleshooting)

### Fluidd no carga

**Checklist:**

1. ¿Impresora encendida?
2. ¿Conectada a WiFi? (verifica en pantalla LCD)
3. ¿IP correcta? (mira en Network)
4. ¿Escribiste `http://` no `https://`?

**Solución:** Reinicia impresora completamente.

### Temperatura no se actualiza

**Checklist:**

1. ¿Sensores conectados?
2. ¿`sensor_type: Generic 3950` en printer.cfg?
3. ¿Pines PA0 y PA1 en printer.cfg?

**Solución:** Verifica cables de temperatura en mainboard.

### Motor no se mueve

**Checklist:**

1. ¿Pines en printer.cfg correctos?
2. ¿Cable motor conectado?
3. ¿Motor hace ruido al presionar Home?

**Solución:** Verifica conexión de motor en mainboard.

### MCU disconnected

**Problema:** Klipper no se comunica con mainboard.

**Soluciones:**

1. Reinicia Klipper: **Firmware Restart** en Fluidd
2. Reconstruye: `make clean && make` vía SSH
3. Reflashea firmware si arriba no funciona

***

## Referencias

### Wikis y Documentación Externa

* **SourceForge Wiki Artillery:** <https://sourceforge.net/p/artillery-sw-x4-klipper-images/wiki/>
* **Documentación Klipper oficial:** <https://www.klipper3d.org/>
* **Fluidd Access:** <https://sourceforge.net/p/artillery-sw-x4-klipper-images/wiki/Fluidd%20Access/>
* **SSH Access:** <https://sourceforge.net/p/artillery-sw-x4-klipper-images/wiki/SSH%20Access/>
* **Klipper Update Guide:** <https://sourceforge.net/p/artillery-sw-x4-klipper-images/wiki/Klipper%20Update/>

### Guías Complementarias en 3Dwork.io

Después de dominar esta guía, estas guías te ayudarán a optimizar tu impresora:

* [Pressure Advance](/klipper/empezamos/pressure-advance) — Control de presión de filamento
* [Configuración Klipper en laminadores](/klipper/empezamos/configuracion-klipper-en-laminadores) — Integración con Cura, PrusaSlicer, etc.
* [SKEW: Compensación chasis/cinemática](/klipper/empezamos/skew-compensacion-chasis-cinematica) — Corrección de distorsión
* [Ajustes avanzados TMC (VFA)](/klipper/empezamos/ajustes-avanzados-tmc-vfa) — Optimización de drivers de motor
* [Backup Klipper](/klipper/mejoras/backup-klipper) — Salvaguardar tu configuración

***

**Última actualización:** 2026-05-05 **Autor:** HAL (Technical Writer - 3Dwork.io)

{% hint style="success" %}
¡Ya tienes Klipper completamente configurado! Ahora toca experimentar, imprimir y disfrutar de impresiones más rápidas y silenciosas.
{% endhint %}


# Configuración

{% hint style="info" %}
**English**: Use your browser's built-in translation — Chrome and Edge detect the language automatically and offer to translate the page.
{% endhint %}


# Primeros pasos con Klipper

Guía completa de puesta en marcha inicial con Klipper: conexión al interfaz web, configuración del printer.cfg, tests de motores, homing, PID, nivelación y calibración paso a paso.

En esta guía intentaremos aconsejaros los diferentes pasos iniciales usando Klipper para poner nuestra máquina en marcha.

Para realizar los pasos explicados en esta guía anteriormente vuestra máquina tiene que ser funcional a nivel mecánica/electrónica,[ **instalamos Klipper en vuestro host**](/klipper/instalacion), se [**creó/aplicó el firmware Klipper a vuestra electrónica**](/klipper/instalacion#creando-nuestro-firmware-klipper) y obtuvimos nuestra [**cadena de conexión serial**](/klipper/instalacion#verificando-la-conexion) para nuestra electrónica... si alguno no lo tienes puedes seguir los links.

{% hint style="success" %}
**Resumen del proceso — ¿por dónde empiezo?**

Si acabas de instalar Klipper y no sabes por dónde empezar, sigue este orden:

1. [Conectar al interfaz web](#conexion-al-interfaz-web-de-klipper) (Mainsail/Fluidd)
2. [Editar el `printer.cfg`](#printer.cfg-...-configuraciones-klipper-para-nuestra-maquina)
3. [Verificar termistores y calentadores](#sensor-temperaturas)
4. [Verificar motores con `STEPPER_BUZZ`](#motores)
5. [Verificar endstops con `QUERY_ENDSTOPS`](#endstops)
6. [Primer homing](#homing) con `G28`
7. [Nivelación de cama](#nivelacion-cama)
8. [Ajuste del PID](#pid)
9. [Z-Offset](#z-offset)
10. [Calibrar e-steps / `rotation_distance`](#e-steps-rotation_distance)
11. [Configurar el laminador](#slicer-laminador) con START\_PRINT / END\_PRINT
12. [Input Shaper](#input-shaper)
    {% endhint %}

## Conexión al interfaz web de Klipper

Una vez tenemos nuestro Klipper instalado y este conectado a nuestra red podremos acceder al interfaz web de control.

Para ello, sabiendo la IP de nuestra red asignada a nuestro Klipper, abriremos nuestro navegador favorito y pondremos <http://IP\\_HOST> (donde IP\_HOST será la IP de nuestra red asignada a nuestro Klipper) y podremos ver el interfaz web para la gestión remota de este:

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FzxUKRxjUYwJW0iT30KS0%2Fimage.png?alt=media&amp;token=559ff48a-030d-4d7e-ae21-7d83f60e02d3" alt=""><figcaption></figcaption></figure>

En ocasiones si se hace una instalación personalizada de estos interfaces estos se montan en un puerto quedando la URL de acceso de la siguiente forma: <http://IP\\_HOST:puerto> (donde puerto es el número que se usó o se facilitó durante la instalación personalizada.

{% hint style="info" %}
**Conocer la IP de acceso a nuestro host Klipper:**\
[**Fing**](https://www.fing.com/) que es una aplicación multiplataforma que nos escaneará y listará todos los dispositivos de nuestra red. Con ella podremos encontrar nuestro host Klipper buscando por su nombre (mainsailos, ratos, etc...)\
![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/2wXnevDIMuKoLZ4cTgG2/image.png)\
\
En el caso de que no encontremos la IP tenemos diferentes opciones a revisar:

* conectaremos la SD de nuevo a nuestro ordenador y revisaremos el fichero que utilice para configurar nuestra Wifi (normalmente wpa-suplicant pero revisa cual usa tu sistema operativo de tu host) en busca de cualquier fallo al añadir nuestros datos WiFi.\
  En el caso de sistemas MainsailOS ya sea Raspberry o Armbian podemos encontrar información [aquí](https://docs-os.mainsail.xyz/faq/change-wifi-credentials)
* Conectar fisicamente un cable de red de nuestro router a nuestro host nos puede ayudar si tenemos problemas con nuestra WiFi o reconfigurarla ya sea:
  * ajustando manualmente el fichero wpa-suplicant
  * si tienes una Raspberry Pi ejecutando el comando `raspi-config` que contamos con un apartado para configurar la Wifi
  * si tienes una Orange Pi tienes un comando similar al anterior `armbian-config` donde tienes configuraciones avanzadas
* Si nuestro host es RatOS, sobre Raspberry o CB1, si no conecta a ninguna red montará un punto de acceso Wifi al cual nos podremos conectar y configurar nuestros datos Wifi, tienes más información en la [documentción de RatOS](https://os.ratrig.com/docs/installation/#wifi-or-ethernet)

También poder conectar un teclado y pantalla al host puede ayudarnos a ver las razones por lo que no es capaz de conectar.
{% endhint %}

{% hint style="warning" %}
**Nuestro host no conecta a nuestra red:**

Es un problema que puede surgir os damos algunas sugerencias de que mirar.

* Si conectamos por WiFi tenemos que tener algunos aspectos en cuenta:
  * Algunos hosts no se llevan bien con redes mesh y algunas de sus funciones
  * Al igual que el punto anterior en ocasiones el host solamente puede utilizar redes 2.4GHz y usando WPA-Personal + WPA 2 como método de autenticación
* En el caso de conectar por cable de red asegurarse que el cable hace link con nuestro hub/router y verificar que la configuración de red para nuestra red sea la correcta si forzamos una IP en el interfaz o usamos DHCP

Por otro lado, si necesitáis más información podéis conectar a vuestro host utilizando un cable y SSH, una pantalla o un teclado con los siguientes comandos:

* `dmesg` nos va a listar el estado de los diferentes componentes en el arranque del sistema

<img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2Fw6QYEtboJedz0kBQZCUK%2Fimage.png?alt=media&amp;token=f273903a-cac4-45f7-a25f-b527651bd386" alt="" data-size="original">

* `ifconfig,` nos va a proporcionar información de nuestra conexión e interfaces

<img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FgFRJYhv3TEbEQB3uVoqG%2Fimage.png?alt=media&amp;token=7f87442d-648f-4565-9e74-dc20908f0186" alt="" data-size="original">

* `sudo iw dev`, nos va a proporcionar información del estado de nuestros interfaces de red

<img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FzAX52WP9BKoVXDZ3S0Xy%2Fimage.png?alt=media&amp;token=e5d26b3e-bcce-4573-9d81-ae7946d47c1a" alt="" data-size="original">

* `sudo iw list`, nos va a proporcionar una información de tallada de nuestros interfaces

<img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FGC1rbVUmOZU9eOHuciuu%2Fimage.png?alt=media&amp;token=8f100d91-7a15-4b32-957e-338b2e89cf1b" alt="" data-size="original">
{% endhint %}

## Conexión a SSH

Dependiendo del método elegido para instalar Klipper o si creamos manualmente el firmware Klipper para nuestra MCU (electrónica de la impresora) probablemente vimos que algunos de estos pasos se hacían por "línea de comandos" utilizando SSH para conectarnos a nuestro host (dispositivo donde instalamos Klipper).

Si no ha sido el caso tarde o temprano, más bien esto último, vas a necesitar lanzar comandos en el terminal de Klipper (Linux) dado que algunos procesos van a requerir ser lanzados desde línea de comandos

{% hint style="info" %}
¿Que es SSH?

SSH (Secure SHell) es un protocolo de administración remota con el que podemos conectarnos a nuestro host de una forma segura para poder enviar comandos al sistema operativo de esto.
{% endhint %}

Para conectarnos por SSH a nuestro host deberemos tener en cuenta:

{% hint style="warning" %}
Es importante que revises tu host para habilitar el servicio SSH para que puedas utilizarlo, normalmente las distribuciones de Klipper como MainsailOS o RatOS ya lo llevan habilitado... si usas otros revisa su documentación para habilitarlo.
{% endhint %}

* disponer de un cliente SSH en o los equipos (ordenadores, tables, teléfonos...) desde donde queramos administrar. En nuestro caso siempre aconsejamos [**Terminus**](https://termius.com/download/) por ser multiplataforma, sencillo y no tiene coste para el uso de administrar tus máquinas con Klipper. También dispones de otras como [**Putty**](https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html).

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/fMDnervamorB8sYJk6F6/image.png" alt=""><figcaption></figcaption></figure>

* lo segundo a tener en cuenta es conocer la IP de acceso a nuestro host Klipper que ya vimos en el paso anterior
* por último para poder conectar necesitamos conocer el usuario/contraseña que nos va a permitir conectar con nuestro host.\
  A continuación os facilitamos algunos de los usuarios/password por defecto usados en diferentes distribuciones:

|                                | Distribución        | Usuario/Password    |
| ------------------------------ | ------------------- | ------------------- |
| **MainsailOS**                 | Raspberry Pi        | pi/raspberry        |
|                                | Orange Pi (Armbian) | pi/armbian          |
| **FluiddOS**                   | Raspberry Pi        | pi/raspberry        |
| **RatOS**                      | Raspberry Pi        | pi/raspberry        |
| **Bigtreetech CB1/CB2**        | CB1 / CB2           | biqu/biqu           |
| **KIAUH (instalación manual)** | Cualquier Linux     | usuario del sistema |

Si ya tenemos todo lo anterior ya estaremos listos para conectar y verificar nuestra conexión SSH a nuestro host.

{% hint style="success" %}
Os facilitamos algunos comandos útiles:

* `ls`, permite listar los ficheros de un path o directorio. Podemos añadir parámetros como `ls -l` que nos darán más informacion como el tamaño o permisos.
* `df` o `du`, permite mostrar la información de uso de nuestro sistema de archivos tenemos opciones como `df -h` para mostrar el espacio de una forma mas entendible, `df -a` nos muestra todo el sistema de ficheros. Muy útil cuando queremos ver el espacio disponible o ver donde se nos va el espacio utilizado.
* `cd` , nos va a permitir cambiar de path o directorio `cd <nombre_directorio>` (podemos comenzar a poner las primeras letras y pulsar el tabulador para ver opciones que coincidan con lo introducido). También podemos volver a un path o directori padre del que nos encontremos con `cd ..`
* `cp y mv` , el primero permite hacer una copia o duplicado de un fichero `cp <nombre original> <nuevo_nombre>`. Con el comando mv podemos mover el fichero pudiendo cambiar el path/directorio y el nombre.
* `nano` , es un editor simple de ficheros `nano <nombre_fichero>`. Una vez dentro de el podemos usar `ctrl-x` para salir (si modificamos el fichero nos preguntará si queremos guardar los cambios antes de salir) o `ctrl-o` para guardar el fichero... podemos ver más en la parte inferior del editor.
* `sudo` , por defecto en Linux el usuario no tiene permisos de super administrador o root así que para lanzar según que comandos es necesario lanzarlo, es aconsejable ponerlo antes del comando a lanzar en lugar de solo.
* `tail` , nos permite mostrar las últimas lineas de un fichero lo que es ideal para ver logs `tail <nombre_fichero>`
* `chmod`, nos permite modificar los permisos de lectura/escritura/ejecución de un archivo o directorio. Linux cada archivo/directorio esta asociado a tres clases de usuarios propietario/grupo/otros. Ejemplo `chmod 777 printer.cfg` con esto permitimos acceso total acualquier usuario/grupo
* `chown`, permite cambiar la propiedad de un archivo/directorio/link simbólico a un usuario específico `chown pi printer.cfg` cambiaria la propiedad de `printer.cfg` al usuario pi.

Si queréis tener más datos de otros comandos Linux os aconsejamos revisar el siguiente link con [los 40 comandos básicos de Linux que todo usuario debe saber](https://www.hostinger.es/tutoriales/linux-comandos).
{% endhint %}

## printer.cfg ... configuraciones Klipper para nuestra máquina

A día de hoy Klipper cuenta con muchos ejemplos de configuración de impresoras y electrónicas que nos pueden ayudar a disponer de una configuración base para comenzar.

Podéis revisar estos [**ejemplos aquí desde su Github**](https://github.com/Klipper3d/klipper/tree/master/config) o por otro lado podréis acceder a ellos usando el interfaz de Klipper (Mainsail, Fluidd u otro) en el apartado de ajuste de configuraciones de máquina accediendo al **directorio /config**.

La forma más sencilla de manejar nuestro printer.cfg es usando la propia UI:

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/hJSk7sPomv4HUNRMcjTJ/image.png" alt=""><figcaption></figcaption></figure>

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/BZo5G4BMs63Asc62FnuJ/image.png" alt=""><figcaption><p>Ejemplo de acceso a los cfg usando Mainsail</p></figcaption></figure>

Os facilitamos a continuación los repositorios y fuentes oficiales donde encontrar configuraciones de ejemplo según tu electrónica o marca de impresora:

{% tabs %}
{% tab title="Klipper Oficial" %}
El [repositorio oficial de Klipper](https://github.com/Klipper3d/klipper/tree/master/config) incluye configuraciones para una amplia variedad de electrónicas y modelos de impresora. Entre ellos encontraréis:

* **BTT/SKR**: `generic-bigtreetech-*.cfg` — SKR Mini E3, SKR Pico, Octopus, Manta, EBB CAN...
* **FYSETC**: `generic-fysetc-*.cfg` — Spider, Cheetah, S6...
* **MKS**: `generic-mks-*.cfg` — Robin Nano, Monster8, Rumba32...
* **Creality**: `printer-creality-*.cfg` — Ender 3 y variantes, CR-10, Ender 5, CR-6 SE...
* **Elegoo**: `printer-elegoo-neptune2-2021.cfg`, `printer-elegoo-neptune3-pro-2023.cfg`
* **Anycubic**: `printer-anycubic-*.cfg` — Kobra Go, Kobra Plus, Vyper, i3 Mega, 4Max...
  {% endtab %}

{% tab title="BTT / SKR" %}
BigTreeTech incluye las configuraciones de sus electrónicas directamente en el repositorio oficial de Klipper con el prefijo `generic-bigtreetech-`:

* [SKR Mini E3 v3](https://github.com/Klipper3d/klipper/blob/master/config/generic-bigtreetech-skr-mini-e3-v3.0.cfg)
* [SKR v1.4](https://github.com/Klipper3d/klipper/blob/master/config/generic-bigtreetech-skr-v1.4.cfg)
* [Octopus Pro](https://github.com/Klipper3d/klipper/blob/master/config/generic-bigtreetech-octopus.cfg)
* [Manta M8P v1.1](https://github.com/Klipper3d/klipper/blob/master/config/generic-bigtreetech-manta-m8p-v1.1.cfg)
* [EBB CAN v1.2](https://github.com/Klipper3d/klipper/blob/master/config/sample-bigtreetech-ebb-canbus-v1.2.cfg)

Listado completo en el [repositorio de Klipper](https://github.com/Klipper3d/klipper/tree/master/config) filtrando por `bigtreetech`.
{% endtab %}

{% tab title="FYSETC" %}
FYSETC incluye sus configuraciones en el repositorio oficial de Klipper con el prefijo `generic-fysetc-`:

* [Spider](https://github.com/Klipper3d/klipper/blob/master/config/generic-fysetc-spider.cfg)
* [S6 v2](https://github.com/Klipper3d/klipper/blob/master/config/generic-fysetc-s6-v2.cfg)
* [Cheetah v2.0](https://github.com/Klipper3d/klipper/blob/master/config/generic-fysetc-cheetah-v2.0.cfg)
* [F6](https://github.com/Klipper3d/klipper/blob/master/config/generic-fysetc-f6.cfg)
  {% endtab %}

{% tab title="MKS" %}
MKS mantiene un repositorio oficial con configuraciones Klipper para todas sus electrónicas:

[github.com/makerbase-mks/Klipper-for-MKS-Boards](https://github.com/makerbase-mks/Klipper-for-MKS-Boards)

Algunas electrónicas MKS también están incluidas en el repositorio oficial de Klipper (`generic-mks-*.cfg`): Robin Nano v1/v2/v3, Monster8, Rumba32, SGENL.
{% endtab %}

{% tab title="Creality" %}
Creality dispone de un repositorio oficial con configuraciones Klipper para sus impresoras compatibles con el **Sonic Pad**:

[github.com/CrealityOfficial/Creality\_Sonic\_Pad/tree/main/printer\_configrations](https://github.com/CrealityOfficial/Creality_Sonic_Pad/tree/main/printer_configrations)

Incluye configuraciones para: Ender 3 (y todas sus variantes), Ender 5, CR-10, CR-6 SE, Ender 3 S1, CR-30, Sermoon y más modelos.

Para las impresoras de la **serie K1** (K1, K1 Max, K1C, K1 SE), Creality mantiene su propio fork de Klipper:

[github.com/CrealityOfficial/K1\_Series\_Klipper](https://github.com/CrealityOfficial/K1_Series_Klipper)

{% hint style="info" %}
Los modelos clásicos de Creality (Ender 3, CR-10, etc.) también están incluidos en el repositorio oficial de Klipper con el prefijo `printer-creality-*.cfg`.
{% endhint %}
{% endtab %}

{% tab title="Anycubic" %}
Varios modelos de Anycubic están incluidos directamente en el **repositorio oficial de Klipper**:

* [Kobra Go (2022)](https://github.com/Klipper3d/klipper/blob/master/config/printer-anycubic-kobra-go-2022.cfg)
* [Kobra Plus (2022)](https://github.com/Klipper3d/klipper/blob/master/config/printer-anycubic-kobra-plus-2022.cfg)
* [Vyper (2021)](https://github.com/Klipper3d/klipper/blob/master/config/printer-anycubic-vyper-2021.cfg)
* [i3 Mega (2017)](https://github.com/Klipper3d/klipper/blob/master/config/printer-anycubic-i3-mega-2017.cfg)
* [4Max Pro 2.0 (2021)](https://github.com/Klipper3d/klipper/blob/master/config/printer-anycubic-4maxpro-2.0-2021.cfg)

Para la **Kobra 3** y modelos más recientes con Klipper nativo de Anycubic, mantienen un fork específico de su MCU:

[github.com/ANYCUBIC-3D/K3-klipper-mcu](https://github.com/ANYCUBIC-3D/K3-klipper-mcu)
{% endtab %}

{% tab title="Elegoo" %}
Los modelos **Neptune 2** y **Neptune 3 Pro** están incluidos en el **repositorio oficial de Klipper**:

* [Neptune 2 (2021)](https://github.com/Klipper3d/klipper/blob/master/config/printer-elegoo-neptune2-2021.cfg)
* [Neptune 3 Pro (2023)](https://github.com/Klipper3d/klipper/blob/master/config/printer-elegoo-neptune3-pro-2023.cfg)

Para las impresoras **Neptune 4** y variantes (con Klipper integrado de fábrica), Elegoo distribuye las configuraciones junto con el firmware oficial disponible en su [página de descargas](https://www.elegoo.com/pages/download).
{% endtab %}
{% endtabs %}

Una vez localizado el o los ejemplos que necesitemos los copiaremos en nuestro printer.cfg asegurándonos que tenemos [**el serial id correcto para nuestra/s MCUs que encontramos durante la instalación de Klipper**](/klipper/instalacion#verificando-la-conexion).

{% hint style="info" %}
**BACKUP/COPIA de seguridad de vuestras configuraciones!!!**\
Os sugerimos lo primero de todo antes de comenzar con pruebas o cambios en vuestros ficheros de configuración tener un backup de estos ficheros, podéis usar [**nuestra macro de backup a Github** ](/klipper/mejoras/backup-klipper)que además de crearos un backup de forma sencilla podréis comparar entre ellos para ver las diferencias.
{% endhint %}

{% hint style="warning" %}
**Procesado del printer.cfg por parte de Klipper!!!**

Klipper procesa la configuración de una forma secuencial, esto quiere decir que si tenemos una sección o parámetros de esta en varios sitios de nuestra configuración la configuración efectiva para Klipper será la última que procese.

Si tenéis una configuración modular o un printer.cfg muy extenso, aconsejable siempre modularizarlo, siempre se pueden crear conflictos de configuraciones así que en caso que algo no funcione como deseamos siempre revisar el log de Klipper donde se podrá encontrar la configuración efectiva que este ha procesado y será un claro indicativo que puede que tengamos duplicada esa sección o parámetro.
{% endhint %}

{% hint style="danger" %}
**Zonas del printer.cfg donde colocar las configuraciones y donde no!!!**

Al usar determinadas funciones o asistentes/macros de Klipper que guardan información de configuración de máquina de forma automática nos podemos encontrar hacia el final de nuestro printer.cfg con estos datos.

<mark style="color:red;">**Es importante que NO pongamos ninguna configuración nuestra dentro o por debajo de la zona**</mark> \ <mark style="color:red;">**#\*# <---------------------- SAVE\_CONFIG ---------------------->**</mark>
{% endhint %}

### Secciones a revisar de tu printer.cfg

Si usamos un printer.cfg de algún ejemplo debemos de prestar especial atención a las siguientes secciones antes de continuar con las comprobaciones iniciales:

* cadena de conexión o serial id de nuestra MCU, asegurándonos que tenemos [**el serial id correcto para nuestra/s MCUs que encontramos durante la instalación de Klipper**](/klipper/instalacion#verificando-la-conexion)
* tipo de termistores definidos para nuestro hotend y cama
* configuración de nuestros drivers/steppers, en especial:
  * posición de los endstops
  * posición máxima del area de impresión
  * tipo de driver
* nivelacion de cama que trataremos con más detalle más adelante
* posición y configuración de nuestro sensor de nivelación o z endstop

En caso de errores de Klipper a la hora de procesar nuestra configuración os aconsejamos revisar la [guía de troubleshooting/resolución de problemas](/klipper/troubleshooting#klipper) ya que os pueden aportar ideas para resolver la mayoría de estos.

#### Definiciones de nuestra impresora

En la sección \[printer] de nuestro printer.cfg deberemos definir los parámetros que defined nuestro tipo de impresora como por ejemplo:

* cinemática que usa nuestra impresora
* velocidad máxima
* aceleraciones máximas

```django
// Ejemplo de configuración de impresora corexy
[printer]
kinematics: corexy
max_velocity: 350
max_accel: 3000
max_z_velocity: 50
max_z_accel: 350
square_corner_velocity: 10.0
minimum_cruise_ratio: 0.5  # Reemplaza al deprecated max_accel_to_decel
```

{% hint style="info" %}
La configuración anterior es de ejemplo, si no tenéis una referencia para vuestra máquina es aconsejable comenzar con valores conservadores que podemos obtener de las especificaciones del fabricante o de Marlin.

**Nota:** `max_accel_to_decel` fue eliminado en versiones recientes de Klipper. Si aparece en configuraciones antiguas, sustitúyelo por `minimum_cruise_ratio: 0.5`. Los valores óptimos de `max_accel` deberían venir del resultado de [Input Shaper](/klipper/empezamos/input-shaper).
{% endhint %}

#### Otras secciones importantes

Vamos a revisar otras secciones importantes para asegurarnos que estas están correctamente configuradas:

* secciones \[steppe&#x72;*...] deberemos tener por lo menos position\_endstop y position*\_max que se ajusten a nuestra impresora

{% hint style="info" %}
**IMPORTANTE!!! Ajustes de los límites de impresión.**\
En el caso que nuestro **home deje la punta del nozzle fuera de la cama** deberemos jugar con el **position\_*****endstop** y **position\_min** (o max dependiendo de la máquina).*

Como ejemplo imaginemos que tenemos una maquina donde tenemos nuestros endstops/home en las coordenadas XY -5 (usando como referencia X0Y0 que es el inicio de la cama).

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/6RaxbSI3ANm5WQHa1dOk/telegram-cloud-photo-size-4-5850399413623699100-y.jpg)<br>

En este caso lo que haremos será:

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

```django
[stepper_x] 
...
position_endstop: -5 # Ajustamos la distancia antes calculada desde el inicio de cama 
position_min: -5 # Ajustamos al mismo valor que el parametro anterior
...
```

{% endcode %}

Realizaremos el mismo proceso en el eje Y.

En **el caso que realicemos el proceso de homing en max** es similar pero ajustando el valor de **position\_endstop** a la coordenada adecuada, usando en este caso **position\_max** para asegurarnos que llega, y usando **homing\_positive\_dir a true** para indicar que el movimiento de home se hará a coordenadas positivas:

```django
[stepper_x] 
...
position_endstop: 350 # Ajustamos la distancia antes calculada desde el inicio de cama 
position_max: 350 # Ajustamos al mismo valor que el parametro anterior
homing_positive_dir: true
#   If true, homing will cause the stepper to move in a positive
#   direction (away from zero); if false, home towards zero. It is
#   better to use the default than to specify this parameter. The
#   default is true if position_endstop is near position_max and false
#   if near position_min.
...
```

{% endhint %}

* en \[tmcXXXX steppe&#x72;*...] donde XXXX será e tipo de drivers por ejemplo \[TMC2208 stepper\_x] indicará que nuestro eje X usará un TMC2208*

{% hint style="danger" %}
Tal como indica la propia [documentación de Klipper](https://www.klipper3d.org/TMC_Drivers.html) algunas de las propiedades de estas secciones es aconsejables eliminarlas, si has extraído un ejemplo de configuración de Klipper de terceros y basado en configuraciones antiguas es aconsejable revisarlo:

* **interpolate: True**, aunque es una función interesante que el propio driver permita seleccionar dinámica mente el valor de micropasos dependiendo de las necesidades en la práctica esto puede repercutir en pérdida de precisión de ahí que sea **aconsejable cambiarlo a interpolate: False**

* **hold\_current**, otra función que **se aconseja deshabilitar/borrar** es la de definir un valor de corriente cuando los motores están en modo descanso. Estos cambios de corrientes pueden provocar imprecisiones en su posicionamiento en determinados casos
  {% endhint %}

* *\[stepper\_z] deberiamos definir position\_\_max, en algunos casos podemos tener varios Z que iremos añadiendo con Z1 Z2 Z3*

* *\[extruder] es la seción de nuestro extrusor y deberemos prestar atención al tipo de termistor definido en sensor\_\_type*

* *\[heater\_\_bed] lo mismo que hicimos para el extrusor, revisaremos que el tipo de termistor es el correcto*

## Comprobaciones iniciales

Una vez ya tenemos nuestro printer.cfg listo revisaremos que al recargar nuestra configuración no nos de ningún error y procederemos a realizar unos tests básicos.

Para ello usaremos principalmente la consola:

![Consola en Mainssail](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/8Dyfw6rXZ5TNOl6r3Byb/image.png)

Controles de movimientos:

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/urGjM1mBhTGcxLct2oBW/image.png)

Y otras herramientas que nos facilita el interfaz de Klipper para gestionar nuestra máquina.

### Sensor temperaturas

La primera comprobación que debemos realizar es verificar que nuestros termistores están reportando temperatura de forma correcta y estable:

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/mVHXoHrEHgcdrNoKYXA1/image.png)

En el apartado de temperaturas de nuestro interfaz Klipper verificaremos que las temperaturas del nozzle y cama están presentes y no fluctúan de forma anormal.

Si vemos que la temperatura comienza a subir nada más encender la impresora procederemos a apagar de forma inmediata la impresora y a revisar el estado de cableado y del MOSFET de nuestra placa.

En el caso de ver lecturas de temperaturas que fluctúan o no son precisas deberemos revisar:

* el **cableado y estado de nuestro termistor en el caso de fluctuaciones extrañas en las lecturas**, sobretodo con la máquina en movimiento
* que en nuestro printer.cfg hemos definido correctamente **sensor\_type** que coincida con el tipo/modelo de termistor instalado, normalmente **cuando tengamos lecturas extrañas** tanto por altas como por bajas
* también e nuestro printer.cfg **el sensor\_pin y revisar que el termistor esta en el conector correcto en el caso de no tener lecturas**

### Calentadores <a href="#verify-heaters" id="verify-heaters"></a>

Una vez que ya tenemos correctamente nuestras lecturas de temperatura el siguiente paso será verificar que nuestros calentadores funcionan correctamente.

Para ello y desde la parte de temperaturas que ya vimos en el paso anterior:

* En la columna Target de nuestro Extruder le pediremos que caliente a 60 grados nuestro extrusor, en unos segundos deberíamos de ver que la gráfica y lecturas de temperatura comienzan a ascender. Una vez llegue a la temperatura y después de unos segundos manteniendola podemos seleccionar en Target Off
* Realizaremos el mismo proceso para Heater Bed

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/QavBSUUkVCWkDaHios8t/image.png)

En siguientes pasos veremos como realizar un [**ajuste del PID**](/klipper/empezamos/pid) antes de intentar hacer ningún test de impresión.

### Motores

Este test nos permitirá identificar si nuestros motores están conectados a nuestra placa/drivers y que están en la ubicación correcta.

Usaremos el comando **STEPPER\_BUZZ STEPPER=stepper\_x** desde la consola donde el valor de **STEPPER** es el eje que queremos verificar.

{% hint style="info" %}
A continuación os mostramos los valores que normalmente podemos usar en STEPPER, aunque depende de vuestra configuración pueden variar:

* stepper\_x
* stepper\_y
* stepper\_z
* stepper\_z1
* stepper\_z2
* stepper\_z3
* extruder
  {% endhint %}

El comando **STEPPER\_BUZZ lanzado sobre uno de los ejes realizará un movimiento oscilante que nos ayudará a identificar que motor** está asignado/conectado al eje que queramos comprobar.

Este movimiento se iniciara hacia coordenadas positivas (1mm y en el caso que nuestro endstop se encuentre en MIN/0) y volverá a su posición anterior durante 10 veces.

En el caso que no obtengamos ningún movimiento o este no sea en el sentido deseado:

* asegurarnos que el **valor de STEPPER es el adecuado para nuestra configuración**
* **verificar que los valores enable\_pin y step\_pin** son los correctos para el pin de nuestra electrónica que controle el driver/motor que falle
* si al encender la máquina y sin hacer nada intentamos mover los ejes de forma manual no nos deja porque los motores están activados, o la inversa... si vamos a realizar un movimiento de estos y entonces si que quedan libres pudiendo mover el eje con la mano, probablemente deberemos modificar la lógica de enable\_pin añadiendo o eliminando ! al inicio de la definición.
* en el caso que el movimiento no sea hacia cordenadas positivas deberemos verificar **dir\_pin** y **añadiremos o eliminaremos ! al inicio de la definición del pin para invertir el giro del motor**
* en el caso que veamos que el movimiento es significativamente mayor o menor a 1 mm deberemos r**evisar la configuración de nuestro rotation\_distance**

{% hint style="success" %}
En cuanto a **rotation\_distance** os aconsejamos que os paséis por la [**guía de calibración FDM**](https://labs.3dwork.io/guias-impresion-3d/calibracion_3d), en concreto por el apartado de [**pasos ejes**](https://labs.3dwork.io/guias-impresion-3d/calibracion_3d#7.-pasos-ejes) ya que contiene información muy interesante de como funciona rotation distance e incluso como compensar de forma adecuada nuestras impresiones dimensionalmente en nuestra impresora cartesiana/CoreXY y Delta.
{% endhint %}

{% hint style="danger" %}
Otro aspecto importante es el de ajustar el run\_current de nuestros motores, aquí tenéis una [**guia y calculadora**](https://labs.3dwork.io/guias-impresion-3d/calibracion_3d#id-1.-ajuste-vref-corriente-motores) para ello.

En cualquier caso os indicamos una forma de calcularlo:

* Revisaremos las características de nuestro motor y nos fijaremos en el **valor limite de pico de corriente** del mismo
* Multiplicaremos este valor por 0.707 para determinar el valor máximo de corriente RMS el cual redondearemos en .1.

Por ejemplo usando un motor LDO 42STH130-1684 que su datasheet indica un pico de corriente de 1.68A calcularemos que su run*current es... 1.68\*0.707=1.1877, lo redondearemos a 1.1A que será el valor que usaremos como run\_current: 1.1*

*<mark style="color:red;">**Es importante, dado que en muchas ocasiones estos datos del motor no suelen ser fiables del todo, realizar el cálculo de este valor usando un % de seguridad.**</mark>*\
*<mark style="color:red;">**Entre un 80-90% del valor A puede ser un buen punto de partida para después ajustarlo durante el uso:**</mark>*\
*<mark style="color:red;">**- en el caso de temperaturas excesivamente altas en el motor (bajar el % de seguridad para hacer el cálculo)**</mark>*\
*<mark style="color:red;">**- si observamos pérdida de pasos (subir el % de seguridad para hacer el cálculo).**</mark>*

También, si usamos un fichero de configuración de ejemplo y si este es antiguo, **es importante eliminar cualquier ajuste the hold\_current dado que no es aconsejable su uso.**

**Es importante tambien saber las limitaciones de nuestros drivers en la entrega sostenida de corriente, por ejemplo la máxima capacidad de un TMC2209 es de unos 1.2A.**

Una vez ajustados es importante verificar:

* los **motores pierden pasos, iremos subiendo el valor en 0.1 hasta encontrar el valor óptimo**
* los **motores se calientan en exceso, bajaremos el valor en 0.1 hasta encontrar el valor óptimo**
  {% endhint %}

Os incluimos también la calculadora de nuestros compañero Laureano con diferentes fórmulas que nos ayudarán a ajustar nuestros motores que podéis acceder desde [**aquí**](https://docs.google.com/spreadsheets/d/10JsYHwciYY5oBSxUKwOrY3GGbE0gYVUdTp7ke4r-oUo/edit?usp=sharing) que os puede ser de ayuda para convertir steps de Marlin a Klipper.

En todo caso tal como os aconsejábamos arriba es mejor ir a la [**guía de calibración FDM**](https://labs.3dwork.io/guias-impresion-3d/calibracion_3d), en concreto por el apartado de [**pasos ejes**](https://labs.3dwork.io/guias-impresion-3d/calibracion_3d#7.-pasos-ejes) ya que contiene información muy interesante de como funciona rotation distance e incluso como compensar de forma adecuada nuestras impresiones dimensionalmente en nuestra impresora cartesiana/CoreXY y Delta.

{% embed url="<https://docs.google.com/spreadsheets/d/10JsYHwciYY5oBSxUKwOrY3GGbE0gYVUdTp7ke4r-oUo/edit?usp=sharing>" %}

Para verificar que nuestros pasos sean correctos podemos utilizar la macro [SET\_KINEMATIC\_POSITION](https://www.klipper3d.org/G-Codes.html#set_kinematic_position) que se utiliza para diagnóstico/debug en este tipo de situaciones.

El proceso sería el siguiente y os aconsejamos el uso de una regla:

{% hint style="danger" %}
**IMPORTANTE!!! aunque ya verificamos motores y finales de carrera es más que aconsejable que estemos delante de la máquina para poder apagarla de emergencia en caso de que algo salga mal durante el proceso.**
{% endhint %}

* colocaremos manualmente nuestro cabezal de impresión en la mitad de recorrido de todos los ejes.
* lanzaremos el comando SET\_KINEMATIC\_POSITION X=xxx Y=yyy Z=zzz donde ajustaremos los valores xxx yyy zzz a la mitad del valor del área de impresión que soporte nuestra impresora
* verificaremos cada eje desde la consola primero indicando que los movimientos serán relativos al punto actual usando G91 para después ordenar un movimiento de, por ejemplo, 100mm con un G1 X100 F300 donde el valor de X serán los mm a mover el eje X y el F el feedrate en mm/min... realizaremos lo mismo para el restos de ejes : G1 Y100 F300 o G1 Z50 F300 (en el caso de Z os aconsejamos reducir el movimiento para evitar sustos)
* con una regla por ejemplo, del tamaño adecuado a los movimientos de test a realizar, mediremos desde el origen del movimiento hasta el final para asegurarnos que están correctos... tampoco es imprescindible que lleguen hasta la micra ya que más adelante ajustaremos fino esto pero si que no veamos que las distancias son sustancialmente menores/mayores a lo solicitado
* para evitar cualquier problema del este proceso de check es más que aconsejable, y lo tenéis más adelante en el proceso de homing, hacer un homing de todos los ejes o apagar la impresora totalmente o lanzar gcodes M84/M18 para deshabilitar los motores

En el caso que la dirección o distancia no sean adecuadas revisar de nuevo lo comentado al inicio de esta sección del ajuste de dirección y rotation distance de nuestros ejes de movimiento.

{% hint style="info" %}
Otro método alternativo pero también más peligroso tenerlo activo es el uso de la función FORCE\_MOVE que nos va a permitir mover los ejes sin realizar un homing:

```django
[force_move]
enable_force_move: True
```

{% endhint %}

### Endstops

El <mark style="color:red;">**siguente paso imprescindible/básico es la comprobación de nuestros finales de carrera**</mark>, en este caso para aquellas máquinas que usen sensores físicos, este procedimiento no nos será de ayuda en el caso de usar sensorless.

{% tabs %}
{% tab title="Endstops - Tradicionales" %}
Desde la consola enviaremos el comando **QUERY\_ENDSTOPS** y deberemos de ver una respuesta como:

```
Send: QUERY_ENDSTOPS
Recv: x:open y:open z:open
```

Dejaremos pulsados todos nuestros finales de carrera y volveremos a lanzar el comando con ellos pulsados:

```
Send: QUERY_ENDSTOPS
Recv: x:triggered y:triggered z:triggered
```

En el caso que tengamos problemas con los estados reportados:

* **en el caso que sin el endstop activado nos devuelva el estado triggered y con el pulsado open**, **invertiremos la lógica de Klipper para ese endstop añadiendo o quitando !** delante del pin asignado

```
endstop_pin: P1.28 -> endstop_pin: !P1.28
```

* **en el caso que no cambie su estado al ser pulsado deberemos revisar el cableado, el puerto que hemos usado en placa y la definición del endstop sean correctas**

{% hint style="warning" %}
Los fiales de carrera o endstops usan un pin de entrada input normalmente. Este tipo de pines pueden ser del tipo pull-up o pull-down.

Aunque normalmente la mayoría de nuestras impresoras usan pull-up dependiendo de nuestra electrónica o endstops para estos pines deberemos de indicar si es **pull-up ^** o **pull-down \~**.

**En ocasiones no definir esto de forma correcta puede inplicar que todo este bien pero el estado del endstop no cambie correctamente al estar este activado o no.**
{% endhint %}
{% endtab %}

{% tab title="Endstops - Sensorless" %}
**Sensorless**

Algo que viene siendo muy común y aconsejable es el uso de sensorless si disponemos de una electrónica que lo soporte dado que funciona muy bien, si lo configuramos correctamente, y nos ayuda a aligerar el número de cables y componentes en nuestra máquina.

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

**La función sensorless solamente es aconsejable usarla en ejes X e Y**.
{% endhint %}

Vamos a describir a grandes rasgos las cosas a tener en cuenta para configurar sensorless en Klipper y no morir en el intento :smile:

* Asegurarnos que **a nivel hardware/electrónica tenemos todo de forma correcta**:
  * La funcionalidad sensorless suele venir implementada en drivers TMC pero **recuerda que no todos los TMC cuentan con ella**, revisa las características de tus drivers antes.
  * Para que funcione correctamente **tu placa ha de disponer en su zócalo de drivers de un pin llamado DIAG**. Aunque en algunos tipos de drivers avanzados no es necesario.
  * Los **drivers han de estar en modo UART o SPI configurados siempre** dependiendo del modelo usará un tipo de comunicación para habilitar esta función
  * Normalmente **deberemos poner un jumper en la electrónica para que un driver funcione en sensorless**, revisa las características de tu electrónica.\
    De no tenerlo revisa las opciones para puentear con cable el pin DIAG con el pin endstop correspondiente. O si como es el caso de las electrónicas SKR 1.4 ya viene por defecto conectado internamente, algo que puede crear problemas en ejes que no se use sensorless y se requiere en ocasiones "mutilar" el pin DIAG del driver ya sea cortando o desoldando este para que no conecte a la eléctronica y cree interferencias.
  * Asegurate que **los endstops o finales de carrera fisicos**, si los tenias y en los ejes donde uses sensorless, **esten desconectados totalmente de la electrónica ya que van a afectar al funcionamiento de sensorless.**
* Configuración de steppers en **Klipper** deberemos tener en cuenta lo siguiente:
  * Asegurarte que tus drivers están en UART/SPI
  * Asegurarte que **diag\_pin** está definido en el pin o alias correcto, normalmente suele ser el endstop de ese eje
  * Ajustar la sensibilidad mediante el valor **`driver_SGTHRS`**, revisa el cuadro y descripción que puedes encontrar a continuación.\
    El **valor de sensibilidad va a depender de cada máquina y deberás encontrar el valor correcto** para tu caso.\
    Estos valores van desde el **valor más bajo donde no detectará ningún cambio en la corriente, por lo que chocará sin parar**, hasta el **valor máximo en el cual cualquier variación en el consumo de corriente, provocada por cualquier mínima resistencia al movimiento**, disparará la señal de final de carrera.\
    Comenzaremos por lanzar un home en el eje X ya sea desde la interfaz web, el menú de nuestra pantalla o desde la consola (`G28 X0` o `G28 Y0` en el caso del eje Y). Asegurandonos antes que se encuentra a cierta distancia de los limites del recorrido para que el proceso no falle.\ <mark style="color:orange;">**Antes de realizar este proceso por favor termina de leer toda esta sección ya que hay ciertas dependencias o ajustes/configuraciones a tener en cuenta antes.**</mark>\ <mark style="color:red;">**Deberemos estar muy atentos por si el ajuste de la sensibilidad no es la adecuada y tenemos que apagar la corriente de la impresora!!!**</mark>

    Nos podremos encontrar con dos situaciones:

    * Que se **pare al mover unos mm** realizando el proceso de homing, en ese caso **reduciremos la sensibilidad** y volveremos a realizar el proceso.
    * Que **no pare o que lo haga dando un golpe fuerte**, en este caso **aumentaremos la sensibilidad** y volveremos a realizar el proceso.

    Podremos ajustar este valor utilizando la macro `SET_TMC_FIELD` indicando en `VALUE` el valor a utilizar de sensibilidad y en `STEPPER` el id/nombre del eje:\
    \- (TMC2209/TMC2226) `SET_TMC_FIELD STEPPER=stepper_x FIELD=SGTHRS VALUE=255`\
    \- (TMC2240, TMC21x, TMC51x,TMC26x) `SET_TMC_FIELD STEPPER=stepper_x FIELD=sgt VALUE=-64`\
    Es aconsejable que los ajustes los hagamos de 10-5 unidades en cada ajuste para encontrar el punto correcto para nuestra máquina.\
    Una vez encontrado el valor haremos lo mismo con el eje Y.
  * Asegurarte que en la sección stepper de tu eje tengas **homing\_*****retract\_*****dist** a 0

```django
[stepper_x]
...
homing_retract_dist: 0 ## TMC SENSORLESS

[tmc2209 stepper_x]
uart_pin: PC11
tx_pin: PC10
uart_address: 0
diag_pin: ^x_diag_pin ## Definiremos el pin del endstop/sensorless
driver_SGTHRS: 14 ## Ajustaremos la sensibilidad
```

{% hint style="info" %}
**SOBRE DEFINICIÓN Y AJUSTE DE SENSIBILIDAD DEPENDIENDO DEL TIPO DE DRIVER:**

Dependiendo del tipo de driver se define la sensibilidad utilizando driver\_SGTHRS o driver\_SGT además que el rango de ajuste puede variar:

* **TMC2209/TMC2226 donde el valor más bajo de driver\_SGTHRS es 0 y el más alto es 255**
* **Otros TMC, TMC2240/TMC2130/TMC2160/TMC2660/TMC5130/TMC5160, donde el valor más bajo de driver\_SGT es +63 y el más alto -64**

<img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FTIEHxJkdrb4mvPEda798%2Fimage.png?alt=media&amp;token=e13a0d4a-fc4a-4ead-b9c4-2867b81cba65" alt="" data-size="original">
{% endhint %}

* Otro apartado importante es el proceso de homing, el cual lo ideal es hacer un **homing\_override** incluyendo la reducción del voltaje en los motores para que mejore el funcionamiento de sensorless (podéis encontrar un ejemplo muy completo aquí)

{% hint style="warning" %}
Si usamos home\_*override y tenemos/usamos z\_safe\_homing Klipper nos mostrará un error de incompatibilidad, lo ideal es comentar o borrar z\_safe\_homing y asegurarnos que nuestro* home\_*override realiza el homing de Z en una posición segura.*

*En el ejemplo de* home\_*override de la parte de abajo podéis ver como realiza este en el centro de nuestra cama.*
{% endhint %}

```django
[homing_override]
    ...
    SET_TMC_CURRENT STEPPER=stepper_x CURRENT=0.5
    SET_TMC_CURRENT STEPPER=stepper_y CURRENT=0.5
    G28
```

* También dentro de nuestro homing\_*override es importante ajustar las aceleraciones ya que pueden crear falsos positivos...*

  * *en el proceso de homing\_override bajaremos las aceleraciones al inicio y volveremos a dejarlas por defecto una vez finalizado el proceso usando el comando **M204 Sxxxx***<br>
  * *También es muy aconsejable realizar una pequeña pausa de 2 segundos entre los movimientos de homing para asegurarnos que el proceso funciona bien usando el comando G4 P2000*

  *En el siguiente ejemplo podemos ver un homing para sensorless de forma completa y correcta en los pasos.*

{% hint style="warning" %}
En el ejemplo de macro **home\_override incluída en esta guía usaremos notificaciones para indicar en que paso estamos durante el proceso de homing sensorless. Necesitamos que tu printer.cfg o includes del mismo tengan la sección \[respond]:**

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

```django
[respond]
```

{% endcode %}
{% endhint %}

```django
[homing_override]
axes: x,y
gcode:
    # ========================
    # INITIAL SETUP BEFORE HOMING
    # ========================
    M400            # Wait for all previous movements to finish
    G90             # Set absolute positioning mode
    G0 Z10 F600     # Move Z-axis up by 10mm to avoid collisions
    M204 S1000      # Set acceleration to 1000 mm/s² for homing

    # ========================
    # CHECK HOMING STATUS
    # ========================
    {% set x_homed = 'x' in printer.toolhead.homed_axes %}
    {% set y_homed = 'y' in printer.toolhead.homed_axes %}
    
    # Display the status of X and Y homing
    M117 X Homed: {x_homed} | Y Homed: {y_homed}
    RESPOND PREFIX="Homing Status: " MSG="X Homed: {x_homed} | Y Homed: {y_homed}"
    G4 P2000  # Pause 2 seconds to allow reading the status

    # ========================
    # REDUCE STEPPER CURRENT FOR SAFE HOMING
    # ========================
    M117 Reducing Stepper Current for Homing...
    RESPOND PREFIX="Homing Status: " MSG="Reducing stepper current for homing"
    SET_TMC_CURRENT STEPPER=stepper_x CURRENT=0.5
    SET_TMC_CURRENT STEPPER=stepper_y CURRENT=0.5

    # ========================
    # HOME X AXIS (IF NOT ALREADY HOMED)
    # ========================
    {% if not x_homed %}
        M117 Homing X Axis...
        RESPOND PREFIX="Homing Status: " MSG="Homing X Axis..."
        G4 P2000  # Pause 2 seconds before homing
        G28 X
        G0 X{printer.toolhead.axis_maximum.x / 2} F9000  # Move X to its midpoint
    {% else %}
        M117 X Already Homed
        RESPOND PREFIX="Homing Status: " MSG="X Already Homed"
    {% endif %}

    # ========================
    # HOME Y AXIS (IF NOT ALREADY HOMED)
    # ========================
    {% if not y_homed %}
        M117 Homing Y Axis...
        RESPOND PREFIX="Homing Status: " MSG="Homing Y Axis..."
        G4 P2000  # Pause 2 seconds before homing
        G28 Y
        G0 Y{printer.toolhead.axis_maximum.y / 2} F9000  # Move Y to its midpoint
    {% else %}
        M117 Y Already Homed
        RESPOND PREFIX="Homing Status: " MSG="Y Already Homed"
    {% endif %}

    # ========================
    # RESTORE STEPPER CURRENT AFTER HOMING
    # ========================
    M117 Restoring Stepper Current...
    RESPOND PREFIX="Homing Status: " MSG="Restoring stepper current"
    
    # Restore current for TMC2209
    SET_TMC_CURRENT STEPPER=stepper_x CURRENT={printer.configfile.config["tmc2209 stepper_x"].run_current}
    SET_TMC_CURRENT STEPPER=stepper_y CURRENT={printer.configfile.config["tmc2209 stepper_y"].run_current}
    
    # Uncomment for TMC2130
    # SET_TMC_CURRENT STEPPER=stepper_x CURRENT={printer.configfile.config["tmc2130 stepper_x"].run_current}
    # SET_TMC_CURRENT STEPPER=stepper_y CURRENT={printer.configfile.config["tmc2130 stepper_y"].run_current}
    
    # Uncomment for TMC5160
    # SET_TMC_CURRENT STEPPER=stepper_x CURRENT={printer.configfile.config["tmc5160 stepper_x"].run_current}
    # SET_TMC_CURRENT STEPPER=stepper_y CURRENT={printer.configfile.config["tmc5160 stepper_y"].run_current}

    # ========================
    # FINAL Z MOVE & RESET ACCELERATION
    # ========================
    G0 Z10 F600  # Move Z up by 10mm after homing
    M204 S{printer.configfile.config.printer.max_accel}  # Restore max acceleration

    M117 Homing Completed!
    RESPOND PREFIX="Homing Status: " MSG="Homing Completed!"

```

* Nos aseguraremos de **indicar que nuestros drivers X Y usen el virtual endstop sensorless**

```django
[stepper_x]
rotation_distance: 40
...
endstop_pin: tmc2209_stepper_x:virtual_endstop
```

* Por último el otro factor importante es ajustar la velocidad de homing en la definición de nuestros steppers, debemos encontrar una velocidad media que permita detectar sin reducir el rango de sensibilidad.\
  Una velocidad de homing aconsejada es usar el valor de rotation\_distance dividido entre 2:

```django
[stepper_x]
rotation_distance: 40
...
endstop_pin: tmc2209_stepper_x:virtual_endstop
homing_retract_dist: 0 ## TMC SENSORLESS
homing_speed: 20 ## TMC SENSORLESS

[tmc2209 stepper_x]
uart_pin: PC11
tx_pin: PC10
uart_address: 0
diag_pin: ^x_diag_pin ## Definiremos el pin del endstop/sensorless
driver_SGTHRS: 14 ## Ajustaremos la sensibilidad
```

{% endtab %}

{% tab title="Endstop - Sensor Nivelación Z (probe/bltouch)" %}
**Sensor de nivelación (PROBE)**

Antes de proceder con ninguno de estos tests [<mark style="color:green;">**es aconsejable revisar la guía de sensores de nivelación Klipper**</mark>](/klipper/empezamos/sensor-nivelacion) donde encontraréis información más detallada sobre estos.

Con el cabezal de impresora en el centro de la cama usaremos el comando **QUERY\_PROBE** en este caso para verificar el estado de nuestro sensor, aplicaremos las mismas soluciones dependiendo de la repuesta de estado que usamos en el punto anterior.

**Prueba de precisión del sensor de nivelación (PROBE)**

Con la cama y el hotend fríos (por ahora) podemos realizar un test de precisión lanzando el comando **PROBE\_ACCURACY**.

Este test va a realizar 10 lecturas para comprobar la desviación de cada una de esas lecturas:

```
Send: PROBE_ACCURACY
Recv: // PROBE_ACCURACY at X:125.000 Y:125.000 Z:7.173 (samples=10 retract=2.000 speed=2.0
Send: M105
Recv: // probe at 125.000,125.000 is z=4.975000
Recv: // probe at 125.000,125.000 is z=4.960000
Recv: // probe at 125.000,125.000 is z=4.955000
Recv: // probe at 125.000,125.000 is z=4.952500
Recv: // probe at 125.000,125.000 is z=4.950000
Recv: // probe at 125.000,125.000 is z=4.947500
Recv: // probe at 125.000,125.000 is z=4.942500
Recv: // probe at 125.000,125.000 is z=4.937500
Recv: // probe at 125.000,125.000 is z=4.937500
Recv: // probe at 125.000,125.000 is z=4.932500
Recv: // probe accuracy results: maximum 4.975000, minimum 4.932500, range 0.042500, average 4.949000, median 4.948750,
standard deviation 0.011948
```

{% endtab %}
{% endtabs %}

Otro tema importante en referencia a los endstops es la correcta definición para indicar a Klipper donde se encuentran para realizar el proceso de homing correctamente.

Cada eje (X,Y,Z) en Klipper tiene una posición mínima (position\_min) y posición máxima (position\_max), además para cada uno de ellos tenemos que definir una posición del endstop (position\_endstop) ya sea físico o virtual para definir el punto de referencia (home) para a partir de ahí ubicar la posición de la máquina.

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FvXOPV5GN8Q5hb9p9i6Dq%2Fimage.png?alt=media&amp;token=1e48659e-fa31-4001-8681-92a521294ac3" alt=""><figcaption></figcaption></figure>

{% tabs %}
{% tab title="Homing en MIN" %}
Suele ser lo más común y es hacer el homing en las coordenadas 0:

```
[stepper_x]
endstop_pin: ^!PC0
position_endstop: 0
position_max: 220
homing_speed: 50
```

En este caso:

* El eje X tiene su **endstop al inicio del recorrido (izquierda)**.
* Cuando hace `G28 X`, va hacia el lado negativo hasta pulsar el switch.
* Luego, la posición 0 se define ahí.
* Puede moverse desde `0` hasta `220 mm`.
  {% endtab %}

{% tab title="Homing en MAX" %}
Determinadas impresoras hacen el homing en la posicion máxima del recorrido de la máquina:

```
[stepper_y]
endstop_pin: ^!PC1
position_endstop: 250
position_min: 0
position_max: 250
homing_positive_dir: true
```

En este caso:

* El endstop está **en el extremo máximo del recorrido** (250 mm).
* Al hacer `G28 Y`, el eje se mueve **en dirección positiva**.
* Cuando toca el endstop, se fija la posición `Y=250`.
* El área de trabajo válida va de `0` a `250`.
  {% endtab %}
  {% endtabs %}

**Cómo sabe Klipper hacia donde moverse?**

* Si **`position_endstop` = 0 o menor que `position_max/2`** → se asume que el endstop está en el **mínimo**, y Klipper se moverá en dirección **negativa**.
* Si **`position_endstop` = igual a `position_max`** → el homing se hará en dirección **positiva**, a menos que lo fuerces con `homing_positive_dir: true`.

**Errores comunes al definir los endstops o dirección de movimientos:**

* ❌ Homing en dirección equivocada → usar `!` delante de `dir_pin` o cambiar `homing_positive_dir`.
* ❌ Posiciones negativas después del homing → `position_endstop` mal definido.
* ❌ Movimiento fuera del área → límites `position_min` / `position_max` incorrectos.

## TESTS BÁSICOS

Ahora que ya tenemos nuestra máquina y configuración de Klipper correctamente ajustada para por lo menos poder usar su cinemática y sistema de extrusión os aconsejamos realizar los siguientes pasos:

### HOMING

Una vez verificado que nuestros motores van en las direcciones correctas y los finales de carrera (endstops) funcionan correctamente ya podemos iniciar con más seguridad el proceso de homing.

Simplificando, el homing es el proceso por el cual nuestra máquina permite ubicar el punto de origen de sus coordenadas para a partir de este poder realizar los movimientos dentro de su área de movimiento o impresión.

Básicamente el proceso mueve los motores para encontrar el punto de activación de los finales de carrera en cada eje y a partir de ahí ya poder establecer su ubicación y límites de movimiento definidos en nuestra configuración.

Para verificar el proceso de home en cada eje:

{% hint style="danger" %}
**IMPORTANTE!!! aunque ya verificamos motores y finales de carrera es más que aconsejable que estemos delante de la máquina para poder apagarla de emergencia en caso de que algo salga mal durante el proceso.**
{% endhint %}

* Comenzaremos haciendo el home del eje X, podemos hacer esto de diferentes formas ya sea mediante el interfaz web (siguiente captura), desde la pantalla de la impresora/host, o desde la propia consola lanzando el comando `G28 X`

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FBghSqOzN0ornuFSVG8pf%2Fimage.png?alt=media&amp;token=7930dafa-29ec-4a94-b93f-5761a0622d7a" alt=""><figcaption></figcaption></figure>

* Haremos lo mismo para nuestro eje Y, desde el interfaz web, pantalla o desde consola con `G28 Y`
* Por último haremos lo mismo con el eje Z, desde el interfaz web, pantalla o desde la consola con `G28 Z`

En el caso que algo no funcione según lo esperado es aconsejable volver a revisar el apartado de comprobación de motores y endstops de nuevo para verificar que no se nos pasó nada por alto.

### NIVELACIÓN CAMA

Antes de comenzar a fundir filamento, es aconsejable asegurarnos que nuestro área de impresión esté lista para poder imprimir cualquier test necesario para el ajuste de la máquina.

<div data-full-width="true"><figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/3aolSaTrOJBaPV7fCoYX/image.png" alt=""><figcaption></figcaption></figure></div>

Para ello os aconsejamos seguir las siguientes guías específicas, en el caso que apliquen a nuestra máquina, para tener nuestra cama correctamente nivelada:

* [**Nivelado manual**](/klipper/empezamos/nivelacion-cama-manual), disponemos de diferentes asistentes en Klipper para ayudarnos en el ajuste manual (típicas ruedas de ajuste) ya sea con o sin sensor... este último siempre es aconsejable ya que además de facilitar el proceso lo hará más preciso.
* [**Nivelación del gantry (o z-tilt)**](/klipper/empezamos/nivelacion-gantry-z-tilt), en el caso que nuestra máquina disponga de 2 o más motores (en drivers independientes) en nuestro eje Z podemos usar esta función que nos va a permitir alinear correctamente nuestro gantry de una forma automatizada y precisa.
* [**Mallado de cama**](/klipper/empezamos/malla-nivelacion-de-cama-klipper), podremos generar una tabla o malla de desfases en nuestra cama para que el sistema pueda compensar desviaciones de nuestra mecánica o cinemática... de nuevo, aunque se puede hacer un mallado de forma manual, es aconsejable el uso de un sensor de nivelación. Desde Klipper 0.12 también está disponible el **mallado adaptativo** que solo malla el área real de la pieza con `BED_MESH_CALIBRATE ADAPTIVE=1` (requiere `[exclude_object]` habilitado)

### PID

El PID, Proportional Integral Derivative, es un algoritmo que nos va a permitir que el proceso de calentado de nuestra cama o hotend sea consistente (suele afectar a la calidad de impresión) y más eficiente.

<div data-full-width="true"><figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/UFXKO8ecUaWLhHetYHb3/image.png" alt=""><figcaption><p>Ejemplo de gráfica de temperaturas Klipper con un PID incorrecto y corregido.</p></figcaption></figure></div>

El [**ajuste del PID**](/klipper/empezamos/pid) se realiza de uns forma sencilla mediante macros de sistema, que podemos incluir en propias tal como veréis en la guía sugerida para automatizar el proceso, y realiza unos tests usando la temperatura del material que normalmente usemos.\
Por ejemplo si normalmente usamos PLA a 210º (hotend) y 45º (cama) usaremos estos valores para realizar el proceso de ajuste del PID. En el caso que usemos diferentes materiales podemos usar una temperatura en medio del rango de dichos materiales o realizar los tests en el peor de los casos con el material que use más altas temperaturas.

### **Z-OFFSET**

En el **caso que usemos un sensor nivelación** en nuestra máquina es importante, además de su [**configuración de sensor de nivelación en Klipper que podéis encontrar en la siguiente guía**](/klipper/empezamos/sensor-nivelacion), el ajuste de su z-offset.

El z-offset es la distancia entre el nozzle y el punto en que se activa el sensor, en la siguiente imágen tenéis un ejemplo, y es crucial ajustar este z-offset de forma correcta dado que la calidad y fiabilidad de vuestras impresiones van a depender del correcto ajuste... así que te aconsejamos que realices el proceso sin prisas!!

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/Zo7Wv41WfN51Feqknl3q/image.png" alt=""><figcaption></figcaption></figure>

Podéis encontrar el proceso de[ **ajuste de z-offset en la siguiente guía**](/klipper/empezamos/sensor-nivelacion#ajuste-del-z-offset-usando-papel-o-galga).

### E-STEPS (rotation\_distance)

El siguiente paso aconsejable es ajustar nuestra configuración de Klipper para encontrar el valor apropiado de rotation\_distance para nuestra máquina y filamento, que en ocasiones pueden diferir bastante con lo que tengamos en las configuraciones de ejemplo de Klipper o terceros.

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/cYMHydzZMkUyVOZ3ryhq/image.png" alt=""><figcaption></figcaption></figure>

Podéis encontrar el proceso con detalle en la siguiente [**guía de ajuste de e-steps**](/klipper/empezamos/calibracion-extrusor-e-steps). No os preocupéis en el caso que uséis diferentes tipos de filamentos, normalmente ajustaremos los e-steps para el material que uséis normalmente y para el resto lo podéis ajustar con [**test de flujo**](https://labs.3dwork.io/guias-impresion-3d/calibracion_3d#5.-ajuste-flujo-flow) en cada uno de ellos y ajustarlo en vuestro laminador.

### SLICER (laminador)

Antes de comenzar a realizar tests que requieran generar piezas de tests usando un laminador es **importante seleccionar aquel que se adecue a nuestras necesidades/conocimientos, idealmente que disponga de soporte Klipper nativo y si este dispone de tests de calibración integrados mejor**.

Nuestro laminador favorito actualmente es **OrcaSlicer** ya que incorpora soporte a Klipper, incluye funciones y mejoras de otros laminadores (como **Bambu Studio** del cual es un fork **basado en PrusaSlicer pero con un cambio de interfaz y flujo de trabajo que nos encanta**, **SuperSlicer** el cual **parece que su desarrollo a día de hoy está parado pero que por su número de ajustes en el laminado y generador de tests de calibración era una delicia**, **PrusaSlicer** que continúa **siendo un referente hoy en día en cuanto a funciones y soporte**, y por último **Cura** que a día de hoy **pese a tener grandes funciones su soporte para Klipper requiere de ciertos ajustes extras**).

Os aconsejamos revisar nuestra [**guía de laminadores**](/klipper/empezamos/configuracion-klipper-en-laminadores) ya que a parte de configurar correctamente ciertos parámetros es muy importante como adaptar este a las macros de Klipper en especial para el START y END scripts.

#### START\_PRINT y END\_PRINT — el paso que más bloquea a principiantes

Klipper no ejecuta el G-code de inicio que genera tu laminador directamente. En su lugar, el laminador llama a una macro `START_PRINT` que tú defines en Klipper, y esta macro gestiona el calentado, homing, nivelación, etc. Esto aporta mucha flexibilidad pero requiere que **laminador y `printer.cfg` estén sincronizados**.

**En el laminador** (ejemplo OrcaSlicer, campo "Machine start G-code"):

```gcode
START_PRINT BED_TEMP=[bed_temperature_initial_layer_single] EXTRUDER_TEMP=[nozzle_temperature_initial_layer]
```

**En tu `printer.cfg`** (o archivo de macros incluido), una macro mínima de ejemplo:

```jinja
[gcode_macro START_PRINT]
gcode:
    {% set BED_TEMP = params.BED_TEMP|default(60)|float %}
    {% set EXTRUDER_TEMP = params.EXTRUDER_TEMP|default(200)|float %}
    G90                         ; coordenadas absolutas
    M83                         ; extrusor en modo relativo
    M140 S{BED_TEMP}            ; calentar cama (sin esperar)
    M104 S{EXTRUDER_TEMP}       ; calentar hotend (sin esperar)
    G28                         ; homing de todos los ejes
    M190 S{BED_TEMP}            ; esperar temperatura cama
    M109 S{EXTRUDER_TEMP}       ; esperar temperatura hotend
    BED_MESH_CALIBRATE          ; mallado (si tienes sensor de nivelación)
    G1 Z5 F3000                 ; subir Z antes de imprimir

[gcode_macro END_PRINT]
gcode:
    G91
    G1 E-2 F300                 ; retracción
    G1 Z10 F3000
    G90
    G1 X0 Y{printer.toolhead.axis_maximum.y} F3000
    M104 S0
    M140 S0
    M84
```

{% hint style="info" %}
Si usas el [3DWork Klipper Bundle](/klipper/mejoras/3dwork-klipper-bundle) ya incluye `START_PRINT` y `END_PRINT` completos con soporte para mallado adaptativo, purgado, etc. No necesitas crearlos desde cero.

Para una explicación detallada de cómo configurar el START\_PRINT en los principales laminadores (OrcaSlicer, Cura, PrusaSlicer), consulta la [**guía de configuración de laminadores con Klipper**](/klipper/empezamos/configuracion-klipper-en-laminadores).
{% endhint %}

### INPUT SHAPER

Con Klipper podemos llegar, normalmente, a imprimir a más velocidad y aceleraciones que con otros sistemas/firmwares 3D lo cual puede provocar llevar a límite a nuestra máquina afectando en la calidad de nuestras impresiones creando un efecto de olas también llamado ghosting.

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/7VoyYjZ1tKOHnY94jWHN/image.png" alt=""><figcaption></figcaption></figure>

Klipper cuenta con Input Shaper como función para eliminar/disminuir/minimizar este efecto que tenéis [**explicado con más detalle aquí**](/klipper/empezamos/input-shaper).

El proceso de Input Shaper podremos realizarlo de varias formas:

* [**automático usando un acelerómetro**](/klipper/empezamos/input-shaper)... lo más aconsejable, cómodo y preciso
* [**de forma manual**](/klipper/empezamos/input-shaper#manual)... calculando de forma manual el efecto de las vibraciones en una pieza de test

**Dado que es un ajuste clave para la calidad final de nuestras piezas os aconsejamos realizar con paciencia el proceso!!!**

### **SKEW**

La corrección skew nos va a permitir compensar un descuadre provocado por nuestra mecánica o chasis que pueden original piezas geométricamente imperfectas.

{% hint style="success" %}
Dado que son descuadres mecánicos normalmente por un ensamblado de la máquina incorrecto o por falta de un correcto mantenimiento os aconsejamos siempre intentar corregir estos físicamente y solo recurrir a la corrección por software en última instancia.
{% endhint %}

La corrección skew por el sistema va a hacer que este realice pequeños ajustes en los movimientos de nuestro cabezal para asegurar que compensa esos desfases de nuestra mecánica.

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FyQ5iCkVk2A7TAFovfZ76%2Fimage.png?alt=media&amp;token=7345eec5-8c2d-4798-a10f-fcdfdac6f8bb" alt=""><figcaption></figcaption></figure>

El test básicamente consta de la impresión de una pieza de test y añadir configuración en nuestro fichero printer.cfg de Klipper tal como tenéis explicado en nuestra [**guía de corrección de skew para Klipper**](/klipper/empezamos/skew-compensacion-chasis-cinematica) utilizando un método simple para máquinas cartesianas.

Además disponemos de otro más completo, compatible con Marlin y compatible con máquinas delta, en nuestra [**guia de calibración FDM**](https://labs.3dwork.io/guias-impresion-3d/calibracion_3d#id-7.-pasos-ejes-movimiento).

## TESTS FILAMENTOS

Una vez ya tenemos realizados los tests básicos es importante conocer aquellos ajustes que son específicos según el filamento que usemos en nuestra máquina y que van a requerir de unos tests específicos:

### TORRE TEMPERATURA

Cada material y tipo pueden y van a tener unas propiedades diferentes siendo una de ellas la temperatura óptima de fusión. A esta van a influir otros aspectos como nuestro tipo de hotend, las condiciones ambientales y de estado del filamento... etc.

Para encontrar el valor óptimo para nuestra máquina, material y condiciones de impresión normalmente realizaremos un test de temperaturas para encontrar la ideal para nuestro caso.

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/XxCpVfgTN3DyyQ15x7zi/image.png" alt=""><figcaption></figcaption></figure>

Podéis encontrar la [**guía para realizar una torre de temperatura aquí**](https://labs.3dwork.io/guias-impresion-3d/calibracion_3d#6.-torre-de-temperatura). Estos tests también nos permiten ver como afecta la temperatura en puentes, voladizos, retracciones, etc...

### PRESSURE ADVANCE (PA)

Otro ajuste que depende del tipo de filamento es el Pressure Advance o PA. El PA permite controlar el flujo de extrusión para disminuir los artefactos en determinados movimientos como cambios de dirección o aceleraciones.

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/Kz9swuV81dEBGzfVeSgj/image.png" alt=""><figcaption></figcaption></figure>

Para realizar los tests puedes seguir la siguiente [**guía de PA aquí**](/klipper/empezamos/pressure-advance).

### EXTRUSION MULTIPLIER (flujo)

En pasos anteriores cuando os comentamos el ajuste de los e-steps de vuestra máquina ya os adelantamos que dependiendo del tipo de filamento puede ser necesario ajustar el EM (Extrusion Multiplier) de este en nuestro laminador.

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/JnrjroPoopXfwx2bIcPR/image.png" alt=""><figcaption></figcaption></figure>

Para realizar el test de EM os aconsejamos seguir la siguiente [**guía**](https://labs.3dwork.io/guias-impresion-3d/calibracion_3d#5.-ajuste-flujo-flow) donde tenéis más detalle del proceso.

## MEJORAS KLIPPER

Klipper es un firmware que por su arquitectura es modular y permite que tanto sus componentes tradicionales puedan incorporar mejoras como que se puedan añadir mejoras de terceros. A continuación os sugerimos algunas interesantes.

### 3DWORK KLIPPER BUNDLE

Desde **3Dwork** hemos recopilado y ajustando un conjunto de macros, configuraciones de máquinas y electrónicas, así como otras herramientas para una gestión sencilla y potente de Klipper.

Gran parte de este paquete está basado en [**RatOS**](https://os.ratrig.com/) mejorando las partes que creemos interesantes, así como otras aportaciones de la comunidad.

Si queréis más información de sus funciones y como instalarlo pasaros por la siguiente [**guía**](/klipper/mejoras/3dwork-klipper-bundle).

### M600 (cambio filamentos)

Dado que en Klipper muchas de las funciones especiales como un cambio de filamentos se realizan mediante macros y, aunque puedes encontrar diferentes opciones en Internet, os [**sugerimos revisar la que solemos utilizar en nuestras máquinas**](#m600-cambio-filamentos) y sugerimos en nuestros canales de Telegram.

{% hint style="warning" %}
Dado que ahora nos centramos en el [3Dwork Klipper Bundle](/klipper/mejoras/3dwork-klipper-bundle) que incluye M600 y muchas más macros interesantes te aconsejamos usar las de este.
{% endhint %}

### LAYER PAUSE (macro para pausado avanzado)

Al igual que el M600 podemos crear macros que permitan realizar una pausa en una capa de forma programada si se nos olvidó realizar ese ajuste en nuestro laminador.

Si os parece de utilidad podéis encontrar información de como implementarla [**aqui**](/klipper/mejoras/macros-mejoras/pausado-en-capa).

### EXCLUDE OBJECTS

Una función muy útil para nuestro Klipper es Exclude Objects, con ella podemos cancelar/omitir un objeto de nuestra impresión en caso de que tenga algún problema, ponga en peligro el conjunto de la impresión o que lo incluyésemos por equivocación.

En la siguiente [**guía sobre Exclude Objects**](/klipper/mejoras/mainsail-mejoras/exclude-objects) podéis encontrar información para habilitarlo en vuestras máquinas.

La configuración mínima en `printer.cfg` es una sola línea:

```ini
[exclude_object]
```

Y en el laminador: activar "Label objects" (OrcaSlicer) o "Generate object labels" (Cura). Esta sección también es necesaria para usar el mallado adaptativo (`BED_MESH_CALIBRATE ADAPTIVE=1`).

### MALLADO CAMA INTELIGENTE

Un excelente añadido si contamos con sensor de nivelación que nos va a permitir poder realizar una malla de nivelación del área de la pieza que imprimamos haciendo esto que nuestros ajustes de desfases en nuestra cama sean más precisos.

Podéis encontrar más información [**aqui**](/klipper/mejoras/macros-mejoras/mallado-de-cama-inteligente).

### TELEGRAM (control remoto)

En Klipper contamos con diferentes integraciones para poder controlarlo desde fuera de nuestra red. En nuestro caso por su simplicidad y utilizar nuestro IM favorito (Telegram) solemos usar este.

Podéis encontrar más información [**aqui**](/klipper/mejoras/moonraker-mejoras/moonraker-telegram).

## TESTS AVANZADOS

Si hemos llegado a este paso nuestra máquina probablemente esté ajustada lo suficiente como para comenzar a imprimir con una buena calidad... pero seguro que podemos sacarle un punto extra para aprovecharla!!!

### MAX SPEED (velocidad máxima)

Gracias a las bondades de Klipper podemos realizar fácilmente tests donde podremos encontrar la velocidad máxima de nuestra máquina.

Estos tests constan de dos partes:

* [**tests de cinemática**](/klipper/mejoras/macros-mejoras/test-de-cinematica)... donde encontraremos la máxima velocidad de movimientos sin pérdida de pasos
* [**tests de extrusión volumétrica**](https://labs.3dwork.io/guias-impresion-3d/calibracion_3d#15.-ajuste-de-extrusion-volumetrica-opcional)... donde encontraremos la máxima velocidad de extrusión de nuestro sistema y filamento

### TMC TUNNING

Este es un **ajuste para usuarios muy avanzados** pero que puede mejorar el rendimiento de la máquina significativamente en ocasiones y reducir algunos tipos de artefactos como el VFA.

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/AomT4umAUekHLOlbyVZB/image.png" alt=""><figcaption></figcaption></figure>

Básicamente mediante unos cálculos por nuestro tipo de motores y drivers vamos a poder ajustar las opciones avanzadas de drivers TMC para que estos rindan de una forma más óptima.

Podéis encontrar más información en la [**guía de ajustes avanzados TMC**](/klipper/empezamos/ajustes-avanzados-tmc-vfa).

### FIRMWARE RETRACTION (retracciones por firmware)

Klipper cuenta con opciones de ajuste de retracciones por firmware que podemos ajustar durante una impresión y que podéis configurar siguiendo la siguiente [**guía**](/klipper/empezamos/retracciones-en-firmware).

Aunque poder controla las retracciones desde el firmware puede tener algunos puntos positivos dado que en un momento dado podremos realizar el ajuste fino, probablemente **la gestión de estas desde el laminador va a aportar más opciones y ajustes aún perdiendo ese ajuste "en caliente".**

**Aconsejamos el usar el proceso clásico de ajuste de retracciones por el laminador tal y como tenéis en la** [**guía de calibración FDM**](https://labs.3dwork.io/guias-impresion-3d/calibracion_3d)**.**


# PID

{% hint style="danger" %}
Hemos cambiado este proceso para incluirlo en la[ **Guía Calibración de Impresoras 3D FDM/Filamento**](https://labs.3dwork.io/guias-impresion-3d/calibracion_3d#3.-ajuste-pid-mpc)
{% endhint %}

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/IbeUkZoWKHb48whblXkm/image.png)

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/DMM1Tqfct9th3yV9Wjtx/image.png)


# Calibración extrusor (e-steps)

La **calibración de e-steps** (pasos del extrusor) es uno de los ajustes base más importantes de cualquier impresora FDM. Define cuántos pasos de motor corresponden exactamente a 1 mm de filamento extruido. Si este valor no es correcto, la impresora extruirá sistemáticamente más o menos material del necesario, y ningún ajuste posterior —multiplicador de flujo, retracción, Pressure Advance— compensará ese error desde la raíz.

## ¿Cuándo necesitas recalibrarlo?

* Al montar un extrusor nuevo o cambiar el motor
* Al actualizar firmware o cambiar de placa
* En impresoras nuevas de las que no conoces la configuración previa
* Si hay sub-extrusión o sobre-extrusión constante que no mejora ajustando el flujo

## El proceso en resumen

El procedimiento es muy directo: marcas 100 mm en el filamento desde la entrada del extrusor, le pides que extruda esa cantidad desde la consola y mides cuánto ha extruido realmente. Con esa diferencia calculas el valor correcto:

```
Nuevo e-steps = (e-steps actual × 100) / mm extruidos realmente
```

Por ejemplo: si tienes configurados 415 steps/mm y la impresora solo extruye 95 mm en lugar de 100:

```
Nuevo e-steps = (415 × 100) / 95 = 436,8 steps/mm
```

{% hint style="info" %}
El proceso completo —con los comandos exactos para Klipper y Marlin, ajustes en el firmware y comprobación final— está documentado en la **Guía de Calibración FDM**, junto al resto de ajustes base en el orden correcto para realizarlos:

[**Guía Calibración de Impresoras 3D FDM → Sección 2. Pasos extrusor**](https://labs.3dwork.io/guias-impresion-3d/calibracion_3d#id-2.-pasos-extrusor)
{% endhint %}

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/URPRd7eS5KQrhkhiPhJk/image.png" alt=""><figcaption></figcaption></figure>


# Nivelación manual de cama

Como paso previo a otros tests debemos asegurarnos que nuestra cama o base de impresión esté completamente nivelada.

Para ello usaremos las funciones **BED\_SCREWS\_ADJUST** o **SCREWS\_TILT\_CALCULATE** de Klipper dependiendo de si contamos o no con sensor de nivelación.

Podéis encontrar la documentación oficial de Klipper:

{% embed url="<https://www.klipper3d.org/Manual_Level.html>" %}

## Definición de puntos de ajuste

Para poder realizar una nivelación manual con los tornillos de ajuste de nuestra base de impresión, lo primero que deberemos hacer es definir los puntos donde emplazar nuestro hotend o sensor coincidiendo con nuestros puntos de anclaje para nuestra cama.

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/Ct3ya17hbASoru2VBbSr/image.png" alt=""><figcaption><p>Mediremos, con una regla por ejemplo, las distancias entre nuestro punto X0Y0 a los puntos de anclaje de nuestra cama para añadirlos a nuestra configuración. En el caso de que usemos sensor es este el que idealmente y siempre que sea posible ha de quedar en las coordenadas de los puntos de anclaje.</p></figcaption></figure>

Procederemos este ajuste creando una **nueva sección en nuestro pinter.cfg** (o en alguno de sus includes si nuestra configuración es modular) **\[bed\_screws] o \[screws\_tilt\_adjust] dependiendo del sistema elegido**.

{% tabs %}
{% tab title="Ejemplo" %}
**Nivelación manual BED\_SCREWS\_ADJUST**, <mark style="color:red;">importante calcular las coordenada para que el nozzle esté en la posición más cercana al punto de anclaje</mark>:

```django
[bed_screws]
screw1: 70,47
screw1_name: Front left screw
screw2: 70,213
screw2_name: Rear left screw
screw3: 235,47
screw3_name: Front right screw
screw4: 235,213
screw4_name: Rear right screw
```

Podeis encontrar un asistente para poder generar la configuración \[bed\_screws] de una forma sencilla con la [**siguiente calculadora**](https://3dwork.io/tools/#bedleveling):\
![](https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FPOzh7WRaChLOX6YXwjLU%2Fimage.png?alt=media\&token=f409d24c-7832-40ec-ac1b-43e831ee0753)

Es una herramienta muy visual pero en cualquier caso podemos optar por importar nuestro printer.cfg desde donde obtendremos valores de referencia o añadirlos manualmente (dimensiones de la cama, offsets de la sonda si procede, coordenadas de los tornillos de ajuste manual en la cama y el tipo de rosca que usan... con esto daremos a Calcular y obtendremos la configuración sugerida para incluir en nuestro printer.cfg ya sea utilizando bed\_screws (nivelacion manual con papel) o screws\_tilt\_adjust (nivelación manual asistida con sensor si disponemos en nuestra máquina):

\
![](https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FYVXs6k2gYJuvwCkRhIpO%2Fimage.png?alt=media\&token=357f883f-291f-41f6-96d3-af13457b4c67)

**Nivelación asistida por sensor SCREWS\_TILT\_CALCULATE**, <mark style="color:red;">importante calcular las coordenada para que el sensor esté en la posición más cercana al punto de anclaje:</mark>

```django
# Ejemplo Ender 3
[screws_tilt_adjust]
screw1: 117,117
screw1_name: Central screw
screw2: 50,50
screw2_name: Front left screw
screw3: 50,215
screw3_name: Rear left screw
screw4: 215,50
screw4_name: Front right screw
screw5: 215,215
screw5_name: Rear right screw
horizontal_move_z: 10
speed: 150
screw_thread: CW-M3
```

{% hint style="success" %}
En el caso de usar **SCREWS\_*****TILT\_*****CALCULATE es importante:**

* **Definir como screw1 un punto central de nuestra cama al tomar este asistente de nivelación este como el punto de referencia**, de esta forma podremos obtener una nivelación óptima siempre y cuando nuestra cama no se encuentre combada.
* **horizontal\_move\_z será la altura a la que nuestro eje Z se coloque al realizar los traslados** de un punto a otro de sondeo
* **speed** la velocidad en los movimientos de traslado
* **screw\_thread**, quizás el más importante, donde **indicaremos la dirección CW o CCW para indicar la reducción de distancia entre nuestra cama y nozzle** por defecto CW pero si nuestro sistema funciona a la inversa deberemos ajustarlo... **y la métrica de nuestro tornillo** de ajuste siendo M3, M4 o M5 los valores aceptados.\
  Opciones posibles: CW-M3, CCW-M3, CW-M4, CCW-M4, CW-M5, CCW-M5
  {% endhint %}
  {% endtab %}

{% tab title="Definición \[bed\_screws]" %}
A continuación podéis ver todas las opciones de esta sección, podéis ver la [**versión actualizada desde la documentación de Klipper**](https://www.klipper3d.org/Config_Reference.html#bed_screws):

```
[bed_screws]
#screw1:
#   The X, Y coordinate of the first bed leveling screw. This is a
#   position to command the nozzle to that is directly above the bed
#   screw (or as close as possible while still being above the bed).
#   This parameter must be provided.
#screw1_name:
#   An arbitrary name for the given screw. This name is displayed when
#   the helper script runs. The default is to use a name based upon
#   the screw XY location.
#screw1_fine_adjust:
#   An X, Y coordinate to command the nozzle to so that one can fine
#   tune the bed leveling screw. The default is to not perform fine
#   adjustments on the bed screw.
#screw2:
#screw2_name:
#screw2_fine_adjust:
#...
#   Additional bed leveling screws. At least three screws must be
#   defined.
#horizontal_move_z: 5
#   The height (in mm) that the head should be commanded to move to
#   when moving from one screw location to the next. The default is 5.
#probe_height: 0
#   The height of the probe (in mm) after adjusting for the thermal
#   expansion of bed and nozzle. The default is zero.
#speed: 50
#   The speed (in mm/s) of non-probing moves during the calibration.
#   The default is 50.
#probe_speed: 5
#   The speed (in mm/s) when moving from a horizontal_move_z position
#   to a probe_height position. The default is 5.
```

{% endtab %}

{% tab title="Definición \[screws\_tilt\_adjust]" %}
A continuación podéis ver todas las opciones de esta sección, podéis ver la [**versión actualizada desde la documentación de Klipper**](https://www.klipper3d.org/Config_Reference.html#screws_tilt_adjust):

```django
[screws_tilt_adjust]
#screw1:
#   The (X, Y) coordinate of the first bed leveling screw. This is a
#   position to command the nozzle to so that the probe is directly
#   above the bed screw (or as close as possible while still being
#   above the bed). This is the base screw used in calculations. This
#   parameter must be provided.
#screw1_name:
#   An arbitrary name for the given screw. This name is displayed when
#   the helper script runs. The default is to use a name based upon
#   the screw XY location.
#screw2:
#screw2_name:
#...
#   Additional bed leveling screws. At least two screws must be
#   defined.
#speed: 50
#   The speed (in mm/s) of non-probing moves during the calibration.
#   The default is 50.
#horizontal_move_z: 5
#   The height (in mm) that the head should be commanded to move to
#   just prior to starting a probe operation. The default is 5.
#screw_thread: CW-M3
#   The type of screw used for bed level, M3, M4 or M5 and the
#   direction of the knob used to level the bed, clockwise decrease
#   counter-clockwise decrease.
#   Accepted values: CW-M3, CCW-M3, CW-M4, CCW-M4, CW-M5, CCW-M5.
#   Default value is CW-M3, most printers use an M3 screw and
#   turning the knob clockwise decrease distance.
```

{% endtab %}
{% endtabs %}

{% hint style="warning" %}
**Deberemos definir estos puntos dependiendo de nuestra máquina, la ubicación de los tornillos de ajuste de nuestra cama y el tamaño de nuestro hotend asegurando que mecánicamente es viable la ubicación del punto de sondeo.**
{% endhint %}

## Nivelación Manual

Una vez realizado el cambio en nuestra configuración y validada que no de problemas, comenzaremos con el proceso que podemos hacer desde la ventana terminal/consola:

```
# Hacemos un home de todos los ejes
G28
# Lanzamos el asistente de nivelación de cama
BED_SCREWS_ADJUST
```

* La máquina moverá el cabezal de impresión al primer punto de sondeo y con el típico papel ajustaremos el tornillo/rueda a nuestro gusto.
* Si **hemos tenido que ajustar el tornillo más de 1/8 de giro de tornillo** usaremos en el terminal/consola el **comando ADJUSTED y si no hemos necesitado apenas ajuste ACCEPT**.
* **Cuando terminemos el asistente o ciclo de nivelación finalizaremos con ABORT…** ¡Y ya podremos continuar con los siguientes pasos en nuestra calibración!!!

Una vez hayamos efectuado ambos procesos ejecutaremos Z\_ENDSTOP\_CALIBRATE que llevara nuestro nozzle a la posición Z =0 correcta.

## Nivelación manual cama con sensor

En el caso de que dispongamos un sensor de nivelación, podemos utilizarlo para simplificar y hacer más fiable la nivelación manual de nuestra cama.

**Klipper** nos facilita dos macros que nos van a ayudar en la nivelación asistida de nuestra cama, os aconsejamos emplear **SCREWS\_*****TILT\_*****CALCULATE**

### **SCREWS\_*****TILT\_*****CALCULATE**

```
# Hacemos un home de todos los ejes
G28
# Lanzamos el asistente de nivelación de cama con sensor de nivelacion
SCREWS_TILT_CALCULATE
```

* <mark style="color:red;">**Lanzaremos un comando G28 para hacer un home!!!**</mark>
* **Lanzaremos el comando SCREWS\_*****TILT\_*****CALCULATE** desde nuestra consola que efectúa un sondeo con el sensor de los puntos de lecturas definidos en la sección *\[screws\_tilt\_adjust]* de nuestro printer.cfg que ya definimos al inicio de la guía.

{% hint style="success" %}
Es aconsejable realizar este proceso con la cama a temperatura de impresión. En el caso del nozzle entre 140-170 grados **si contamos con un sensor inductivo o similar que normalmente se ven afectados por la temperatura**.
{% endhint %}

{% hint style="info" %}
El comando **SCREWS\_*****TILT\_*****CALCULATE** dispone de un parámetro llamado DIRECTION, con este parámetro podemos indicar si nuestro sistema de ajuste no puede o esta en su máximo en una de nuestras direcciones haciendo imposible el ajuste sugerido.

Por ejemplo si nuestro sistema de ajuste está al máximo en CW en algún punto lanzaremos el comando indicando que nuestra dirección de ajuste sea CCW:

**SCREWS\_*****TILT\_*****CALCULATE** **DIRECTION=CCW**
{% endhint %}

* Una vez **hechas las lecturas en esos puntos nos recomendará el ajuste manual en los tornillos de ajuste de nuestra cama**.\
  Las **correcciones nos las propone usando el sistema de agujas del reloj**, indicando las **horas:minutos a efectuar en el giro**... además del **sentido de este, siendo CW en el sentido de las agujas del reloj y CCW en contra**.

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/b3V5tZT9Wste9PVQS1jJ/image.png" alt=""><figcaption><p>Captura de SCREWS_TILT_ADJUST una forma sencilla de ajuste manual asistida por el sensor si disponemos.</p></figcaption></figure>

* Es recomendable lanzar el comando **SCREWS\_*****TILT\_*****CALCULATE varias veces hasta que el ajuste a realizar sea mínimo o inexistente**


# Sensor nivelación

{% hint style="info" %}
**English**: Use your browser's built-in translation — Chrome and Edge detect the language automatically and offer to translate the page.
{% endhint %}

Un sensor de nivelación es uno de los mejores upgrades que podemos hacer a nuestra impresora 3D que simplificará el proceso de nivelación y mejorará la calidad de nuestras primeras capas las cuales suelen ser de las más críticas.

Aunque la instalación y configuración de un sensor de nivelación, en este ejemplo un [**BLTouch**](#anadiendo-un-sensor-bltouch-en-klipper) o [**inductivo**](#anadiendo-un-sensor-inductivo-en-klipper), no es extremadamente complicada si que va a requerir de ciertos cambios a nivel de cableado, montaje, configuración de firmware y calibración.

## Tipos de sensores — ¿Cuál elegir?

En los últimos años la oferta de sensores ha crecido enormemente. Desde los clásicos BLTouch hasta los nuevos sensores de corrientes de Foucault que escanean la cama en segundos. Esta tabla te ayuda a orientarte:

| Sensor                           | Tipo de detección         | Precisión | Velocidad mallado | Funciona en vidrio | Z-Offset auto | Precio aprox.  |
| -------------------------------- | ------------------------- | --------- | ----------------- | ------------------ | ------------- | -------------- |
| BLTouch / CRTouch                | Pin mecánico              | ★★★★☆     | ★★☆☆☆             | Sí                 | No            | \~15-30 €      |
| Inductivo / PINDAv2              | Campo magnético           | ★★★☆☆     | ★★★☆☆             | No (solo metal)    | No            | \~5-15 €       |
| BIQU MicroProbe                  | Pin mecánico              | ★★★★☆     | ★★☆☆☆             | Sí                 | No            | \~15-20 €      |
| BTT Eddy / Beacon / Cartographer | Corrientes Eddy (scanner) | ★★★★★     | ★★★★★             | No (solo metal)    | Parcial¹      | \~25-45 €      |
| Voron TAP / sonda boquilla       | Nozzle directo            | ★★★★★     | ★★★☆☆             | Sí                 | Sí            | \~5-15 € (DIY) |

¹ Beacon Contact y Cartographer Survey Touch pueden hacer tap del nozzle para calibrar el Z-Offset automáticamente combinando ambos mundos.

{% hint style="success" %}
**¿Qué elijo?**

* **Empezando con Klipper o impresora de escritorio**: BLTouch o CRTouch — son fáciles, están muy documentados y funcionan con casi todo.
* **Voron, impresora de alta velocidad o quieres el mallado más rápido posible**: BTT Eddy, Beacon o Cartographer — escanean 400 puntos en menos de 20 segundos.
* **Cambias el nozzle con frecuencia o quieres olvidarte del Z-Offset para siempre**: Voron TAP o sonda por boquilla.
  {% endhint %}

{% hint style="info" %}
📖 **Guía completa en 3dwork.io:** [Instalar y configurar BLTouch / CRTouch en Marlin y Klipper](https://3dwork.io/configurar-bltouch-en-marlin/) — instalación, conexión por electrónica, configuración Marlin y Klipper, calibración Z-Offset y resolución de problemas.
{% endhint %}

{% tabs %}
{% tab title="BlTouch" %}

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/1P9DPmOjQRZ3lBzocD1q/image.png" alt=""><figcaption></figcaption></figure>

Un BlTouch es un sensor de nivelación que tiene un sensor de efecto Hall, determina la proximidad basándose en campos magnéticos, además incluye una bobina que permite un control del pin de sondeo y en su instalación en la máquina hemos de asegurarnos que el pin (recogido) se encuentre entre 2.3 y 4.3 mm de la punta del nozzle.

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/kV4wzqC4E9oAu1SbBWZh/telegram-cloud-photo-size-4-5940708853438069620-x.jpg" alt=""><figcaption></figcaption></figure>

En algunos modelos o fabricantes podemos encontrar que sustituyen el sensor hall por uno óptico.

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/Vtcm7H9E7iJ1x2pYO6DD/telegram-cloud-photo-size-4-6030764215872107933-y.jpg" alt=""><figcaption></figcaption></figure>

Para configurar nuestro sensor [**BLTouch conectado**](broken://pages/-MUSiB7abOquXYI2Bb4U) a nuestra electrónica de la impresora seguiremos los siguientes pasos:

* Abriremos nuestro printer.cfg, lo ideal es hacerlo desde la UI que usemos normalmente ya sea Mainsail o Fluidd
* Añadiremos una sección nueva llamada **\[bltouch]** siempre por encima de la sección de SAVE\_CONFIG donde se guardan todos los valores de ajuste de los diferentes asistentes como PID, mallado, etc...\
  A continuación puedes ver un ejemplo:

```django
[bltouch]
sensor_pin: ^bltouch_sensor_pin
control_pin: bltouch_control_pin
speed: 7
pin_move_time: 0.675

pin_up_reports_not_triggered: True
pin_up_touch_mode_reports_triggered: True
x_offset: -28
y_offset: -13

samples: 3
sample_retract_dist: 10
samples_result: median
samples_tolerance: 0.02
samples_tolerance_retries: 5
```

{% hint style="info" %}
En la sección \[bltouch] podemos encontrar ([**más información detallada en la documentación de Klipper**](https://www.klipper3d.org/Config_Reference.html#bltouch)):

* **sensor\_pin**: donde indicaremos el pin de la parte endstop de nuestro sensor
* **control\_pin**: en este caso indicaremos el pin del servo
* **speed**: la velocidad del eje Z al realizar el sondeo
* **pin\_*****move*****\_time**: el tiempo de espera para realizar un despliegue o recogida del pin de sondeo
* **samples**: el número de veces que queremos que se sondeen cada punto, en inductivos es aconsejable dependiendo del tipo de sensor realizar más de un sondeo
* **sample\_retract\_dist**: en el caso que usemos multi-probing (multiples sondeos por punto) indicara la distancia de retracción de Z para estos sondeos y deberemos ajustar esta para que nuestro sensor cambie de estado antes de realizar el siguiente sondeo
* **samples\_result**: tipo de media de lectura de valores en multi-probing
* **samples\_tolerance\_retries** *: indicaremos cuantos reintentos queremos realizar en un sondeo en el caso que su desviación sea superior al valor en **samples\_tolerances***
* **x y offsets**: son los offsets del sensor con respecto a nuestro nozzle

<img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/Z2LjF3hx1HGBFQMcPLRU/image.png" alt="" data-size="original"><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/Ygm6cho7yp4mZ47LK7d7/image.png" alt="" data-size="original">

<img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/yg4AmgExi5X8FYNxZYKZ/image.png" alt="" data-size="original">
{% endhint %}

* Deberemos añadir nuestra sección `[bed_mesh]` y ajustarla para nuestra máquina, tenéis [información aquí](/klipper/empezamos/malla-nivelacion-de-cama-klipper).
* También es más que aconsejable añadir la sección `[safe_z_home]` para ubicar el sensor en una posición segura para realizar el proceso de homing... tenéis más [información aquí](#safe-z-homing).
* La última parte a modificar será **\[stepper\_z]** que ya debería de existir, en este caso tendremos que asegurarnos que el **endstop\_pin** es **endstop\_pin: probe:z\_virtual\_endstop**

```django
[stepper_z]
...
endstop_pin: probe:z_virtual_endstop
...
```

* Usaremos la opción SAVE para guardar los cambios en nuestra configuración

#### Dónde conseguir el BLTouch / CRTouch

{% tabs %}
{% tab title="BLTouch (AntClabs original)" %}
{% embed url="<https://s.click.aliexpress.com/e/182731559?productUrl=https://www.aliexpress.com/item/32777786433.html>" %}
{% endtab %}

{% tab title="CRTouch (Creality)" %}
{% embed url="<https://s.click.aliexpress.com/e/182731559?productUrl=https://www.aliexpress.com/item/1005003129968663.html>" %}
{% endtab %}
{% endtabs %}

{% hint style="info" %}
Si utilizas los links de compra, el precio del producto será el mismo que si accedes de manera habitual, pero a 3DWork le quedará una pequeña comisión. Algo que nos ayudará a soportar el proyecto y continuar generando contenido.
{% endhint %}

#### Comprobaciones previas Bltouch

Una vez que tenemos toda la configuración añadida deberemos de verificar que todo funciona correctamente antes de realizar ningún home.

* **Al encender la impresora el BLTouch debería de hacer el proceso de self-test. Este proceso despliega y recoge el pin varias veces y el sensor queda en color rojo.**\
  En el caso que el led se quede parpadeando o el pin no llegue a desplegar/recoger deberías de revisar en detalle el cableado y configuración.

{% hint style="info" %}
Antes de nada, su sensor se queda parpadeando en rojo al iniciar la máquina? que puede causar este error...

**Si nuestro BLTouch parpadea rápidamente en rojo (mismo tiempo encendido y apagado...50%) significa que nuestro sensor está en fallo, indicando un fallo durante el proceso de self-test... como por ejemplo un problema de cableado, configuración, obstrucción o fallo servo del pin, etc...**

**Por otro lado, un patrón de parpadeo más lento (más tiempo de encendido que apagado...80%) es un signo que puedes tener un problema de cableado incorrecto o dañado en 5v o GND.**

* **BLTouch parpadeando rápido con patrón 50% on/off,** indica un fallo durante el self-test... os sugerimos algunas cosas a revisar:
  * El pin se queda obstruido o no se mueve con normalidad, puede ser por diferentes razones como un incorrecto ajuste de altura del pin central, dañada la parte servo o por factores externos como suciedad
  * El sensor se encontraba muy cerca de la cama y no permitió el correcto despliegue del pin golpeando esta antes de poder activar su señal de check
  * Velocidad de homing en Z muy lenta o rápida
  * Problemas con la configuración de tu firmware
  * Tu sensor está dañado
* **BLTouch parpadeando lentamente con patrón 80% on/off**, indica un fallo en la alimentación del sensor:
  * Lo más normal suele ser tener invertidos los cables de alimentación 5v y GND
  * Cableado dañado o problemas de contacto en este
* BLTouch con el led rojo encendido sin ningún patron de parpadeo, indica que nuestro sensor está funcionando normalmente.

**Tenéis más información de estos errores en el** [**manual del BLTouch**](https://www.antclabs.com/bltouch-v3)**.**
{% endhint %}

{% hint style="warning" %}
En el caso de usar BLTouch clones tenemos que jugar con los valores pin\_*up de igual forma que puede que no funcionen muy bien con la macro QUERY\_*&#x50;ROBE.

**Si al realizar el QUERY\_PROBE nos encontramos con el error "BLTouch failed to verify sensor state" será necesario ajustar pin\_up\_touch\_mode\_reports\_triggered a False.**

Si **al realizar los tests de prueba del pin para su despliegue o recogida no funciona bien es posible que necesitemos pin\_up\_reports\_not\_triggered a False**, normalmente el pin no funciona y el estado cambio de open a triggered cuando no debiera.
{% endhint %}

{% hint style="warning" %}
Los fiales de carrera o endstops usan un pin de entrada input normalmente. Este tipo de pines pueden ser del tipo pull-up o pull-down.

Aunque normalmente la mayoría de nuestras impresoras usan pull-up dependiendo de nuestra electrónica o endstops para estos pines deberemos de indicar si es **pull-up ^** o **pull-down \~**.

**Es importante el orden de valores** \[^\~] \[!] pin\_name

**En ocasiones no definir esto de forma correcta puede inplicar que todo este bien pero el estado del endstop no cambie correctamente al estar este activado o no.**
{% endhint %}

* Ejecutaremos el comando **BLTOUCH\_DEBUG COMMAND=pin\_down** desde el terminal. **Este comando despliega el pin del sensor y el led rojo debería apagarse.**\
  En el caso que el led se quede parpadeando o el pin no llegue a desplegar/recoger deberías de revisar en detalle el cableado y configuración.
* Ejecutaremos el comando **BLTOUCH\_DEBUG COMMAND=pin\_up** desde el terminal. **Este comando recogerá el pin del sensor y el led debería de quedar en rojo.**\
  En el caso que el led se quede parpadeando o el pin no llegue a desplegar/recoger deberías de revisar en detalle el cableado y configuración.
* Una vez verificada la parte servo de nuestro sensor comprobaremos la parte endstop lanzando el siguiente comando que desplegará el pin **BLTOUCH\_DEBUG COMMAND=pin\_down**
* Seguidamente ejecutaremos el comando **BLTOUCH\_DEBUG COMMAND=touch\_mode**
* Para comprobar el estado del endstop lanzaremos **QUERY\_PROBE** que debería retornarnos **probe:open**
* Manualmente subiremos el pin de nuestro sensor y volveremos a lanzar **QUERY\_PROBE** que debería retornarnos **probe:TRIGGERED**
* Si todo ha funcionado correctamente nuestro sensor parece bien instalado!!! lanzaremos el comando **BLTOUCH\_DEBUG COMMAND=pin\_up**
* Ahora vamos a comprobar un homing lanzando el comando **G28, idealmente te aconsejaría mover el eje Z a la mitad de su recorrido antes**
* Tan pronto como se inicie el proceso de homing para el eje Z se debería desplegar el pin y comenzar el movimiento hacia nuestra cama, para prevenir cualquier fallo os aconsejamos que de forma manual hagáis que el pin se active lo cual debería de parar el movimiento de homing simulando que se hizo correctamente.
* Si todo ha ido según lo esperado lanzaremos, esta vez sin intervención manual, un homing con **G28** de nuevo

Parece que todo esta correcto así que os sugerimos continuar hacia el [**ajuste del Z-Offset y nivelación de cama**](/klipper/empezamos/nivelacion-cama-manual).
{% endtab %}

{% tab title="Inductivo" %}

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/SvTQMOvgIJ95sdmcAKeJ/image.png" alt=""><figcaption><p>Esquema pines sensor PINDAv2 (compatible, 3 pines, con SuperPinda)</p></figcaption></figure>

Para configurar nuestro sensor [inductivo](broken://pages/-MbGuFV0A6O3PdCXdje6) conectado a nuestra eléctronica seguiremos los siguientes pasos

* Abriremos nuestro printer.cfg, lo ideal es hacerlo desde la UI que usemos normalmente ya sea Mainsail o Fluidd
* Añadiremos una sección nueva llamada **\[probe]** siempre por encima de la sección de SAVE\_CONFIG donde se guardan todos los valores de ajuste de los diferentes asistentes como PID, mallado, etc...\
  A continuación puedes ver un ejemplo:

```django
[probe]
pin: ^!probe_pin 
x_offset: -29.8
y_offset: -13.5
speed: 5
lift_speed: 5.0

samples: 3
sample_retract_dist: 2
samples_result: median
samples_tolerance: 0.02
samples_tolerance_retries: 5
```

{% hint style="info" %}
En la sección \[probe] podemos encontrar ([**más información detallada en la documentación de Klipper**](https://www.klipper3d.org/Config_Reference.html#probe))::

* **pin**: donde indicaremos el pin de señal de la parte endstop de nuestro sensor
  * ^ del ejemplo indica que nuestro pin de la electrónica es pull-up, en ocasiones si vemos que el estado de nuestro sensor cambia de estado pero no vuelve a cambiar puede ser por no estar correctamente definido como **pull-up ^** o **pull-down \~**
  * **! indica que la lógica de la señal del sensor se invierta** y se usa para ajustar que el estado del endstop sea OPEN sin activar y TRIGGERED en estado activado
  * **Es importante el orden de valores** \[^\~] \[!] pin\_name
* **x e y\_offset**: son los offsets del sensor con respecto a nuestro nozzle

<img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/Z2LjF3hx1HGBFQMcPLRU/image.png" alt="" data-size="original"><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/Ygm6cho7yp4mZ47LK7d7/image.png" alt="" data-size="original">
{% endhint %}

* **speed**: la velocidad del eje Z al realizar el sondeo
* **lift\_speed**: la velocidad a usar en multi-probing
* **samples**: el número de veces que queremos que se sondeen cada punto, en inductivos es aconsejable dependiendo del tipo de sensor realizar más de un sondeo
* **sample\_retract\_dist**: en el caso que usemos multi-probing (multiples sondeos por punto) indicara la distancia de retracción de Z para estos sondeos y deberemos ajustar esta para que nuestro sensor cambie de estado antes de realizar el siguiente sondeo
* **samples\_result**: tipo de media de lectura de valores en multi-probing
* **samples\_tolerance\_retries** *: indicaremos cuantos reintentos queremos realizar en un sondeo en el caso que su desviación sea superior al valor en **samples\_tolerances***

{% hint style="warning" %}
Los fiales de carrera o endstops usan un pin de entrada input normalmente. Este tipo de pines pueden ser del tipo pull-up o pull-down.

Aunque normalmente la mayoría de nuestras impresoras usan pull-up dependiendo de nuestra electrónica o endstops para estos pines deberemos de indicar si es **pull-up ^** o **pull-down \~**.

**Es importante el orden de valores** \[^\~] \[!] pin\_name

**En ocasiones no definir esto de forma correcta puede inplicar que todo este bien pero el estado del endstop no cambie correctamente al estar este activado o no.**
{% endhint %}

*
* Deberemos añadir nuestra sección `[bed_mesh]` y ajustarla para nuestra máquina, tenéis [información aquí](/klipper/empezamos/malla-nivelacion-de-cama-klipper).
* También es más que aconsejable añadir la sección `[safe_z_home]` para ubicar el sensor en una posición segura para realizar el proceso de homing... tenéis más [información aquí](#safe-z-homing).
* Dependiendo del tipo de sensor puede ser necesario definir nuestro position\_min en stepper\_z para que permita llegar a la distanci ZOffset que necesite
* La última parte a modificar será **\[stepper\_z]** que ya debería de existir, en este caso tendremos que asegurarnos que el **endstop\_pin** es **endstop\_pin: probe:z\_virtual\_endstop**

```django
[stepper_z]
...
endstop_pin: probe:z_virtual_endstop
...
```

* Usaremos la opción SAVE para guardar los cambios en nuestra configuración

#### Dónde conseguir un sensor inductivo

{% tabs %}
{% tab title="Sensor inductivo PINDAv2" %}
{% embed url="<https://s.click.aliexpress.com/e/182731559?productUrl=https://www.aliexpress.com/item/32919682669.html>" %}
{% endtab %}

{% tab title="Sensor inductivo genérico 3D printer" %}
{% embed url="<https://s.click.aliexpress.com/e/182731559?productUrl=https://www.aliexpress.com/item/1005004378719628.html>" %}
{% endtab %}
{% endtabs %}

{% hint style="info" %}
Si utilizas los links de compra, el precio del producto será el mismo que si accedes de manera habitual, pero a 3DWork le quedará una pequeña comisión. Algo que nos ayudará a soportar el proyecto y continuar generando contenido.
{% endhint %}

#### Comprobaciones previas inductivos/capacitativos

Una vez que tenemos toda la configuración añadida deberemos de verificar que todo funciona correctamente antes de realizar ningún home.

* Nos aseguraremos que el sensor no esté activado, normalmente dispone de un led que indica el estado de dección, y lanzaremos el comando en la consola **`QUERY_PROBE`** que deberia retornar el estado **`probe:open`**
* Activaremos de forma manual el sensor aproximando un objeto metálico para que el sensor se active, lanzaremos el comando **`QUERY_PROBE`** de nuevo y debería darnos **`probe:TRIGGERED`**

**¿Que pasa si no nos funciona según lo indicado?**

* En el caso que la respuesta obtenida sea la inversa usaremos el modificador !, o lo quitaremos en la definición del pin en la sección probe tal como vimos anteriormente
* En el caso que veamos que no cambia el estado:
  * verificaremos que el sensor esta cableado correctamente
  * que la definición de la configuración de pines del probe es la correcta con respecto a donde esté conectado
  * podremos intentar cambiar entre pull-up pull-down en la definción del pin tal como os comentamos anteriormente
    {% endtab %}

{% tab title="BIQU MicroProbe (Stowable)" %}
Este BIQU MicroProbe es un sensor similar a los tradicionales Bltouch con algunos aspectos interesantes a tener en cuenta.

En cuanto a sus características:

* Tamaño reducido por lo que es fácil integrar en cualquier cabezal
* Peso reducido que va a evitar vibraciones extras a la hora de imprimir
* Instalación sencilla y similar a un Bltouch
* Buena precisión y fiabilidad
* Podemos reemplazar el pin en caso de que se dañe
* Compatible con un amplio rango de impresoras/electrónicas
* Precio

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/wnJwWZUgMgFMoEi2VEkj/image.png" alt=""><figcaption><p>Diagrama de rol de conexiones.</p></figcaption></figure>

Tenéis información detallada en la guía específica de este sensor:

{% content-ref url="/pages/mtqS9eZi6TzOWtXs0jGs" %}
[BIQU MicroProbe](/klipper/empezamos/sensor-nivelacion/biqu-microprobe)
{% endcontent-ref %}
{% endtab %}

{% tab title="BTT Eddy (Scanner)" %}
El BTT Eddy es un sensor de nivelación por escaneo de la superficie, este tipo de sensores pueden escanear tu cama en unos pocos segundos con una alta precisión.

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FYPjuA24PkQhBLT9YKGEj%2Fimage.png?alt=media&amp;token=46c75662-6061-4d33-8b65-1a26e57b57ca" alt="" width="153"><figcaption></figcaption></figure>

Entre sus ventajas podemos destacar:

* **nivelación de alta velocidad**, completa un nivelado de cama en unos pocos segundos (alrededor de 20s para una cama de tamaño medio)
* **alta precisión**, con lecturas de 0.0005 mm de precisión
* **tamaño compacto y bajo peso**, con sus 6g y su pequeño tamaño es integrable en casi cualquier cabezal de impresión no afectando en el aumento de masa que pueda afectar las inercias y vibraciones durante nuestras impresiones. Especialmente pensado para su instalación en cabezales Voron
* **compensación de temperatura**, integra la función de compensación de temperatura de Klipper para una precisión perfecta

Dado los pasos extra y cambios para ajustar este sensor en Klipper contamos una guía espcífica para el:

#### Dónde conseguir el BTT Eddy

{% tabs %}
{% tab title="BTT Eddy USB / Coil" %}
{% embed url="<https://s.click.aliexpress.com/e/182731559?productUrl=https://www.aliexpress.com/item/1005006855438646.html>" %}
{% endtab %}

{% tab title="BTT Eddy Duo" %}
{% embed url="<https://s.click.aliexpress.com/e/182731559?productUrl=https://www.aliexpress.com/item/1005006344907714.html>" %}
{% endtab %}
{% endtabs %}

{% hint style="info" %}
Si utilizas los links de compra, el precio del producto será el mismo que si accedes de manera habitual, pero a 3DWork le quedará una pequeña comisión. Algo que nos ayudará a soportar el proyecto y continuar generando contenido.
{% endhint %}

[Bigtreetech Eddy](/klipper/empezamos/sensor-nivelacion/bigtreetech-eddy)
{% endtab %}

{% tab title="Beacon / Cartographer (Scanner)" %}
Los sensores de tipo scanner basados en corrientes de Foucault son actualmente los más avanzados disponibles para Klipper. **Beacon** y **Cartographer** son los más populares en la comunidad Voron. Ambos usan el mismo principio físico (el chip LDC1612 mide la resonancia de una bobina LC sobre la superficie metálica de la cama), pero cada uno tiene su propio plugin y proceso de calibración.

Entre sus ventajas:

* **Escaneo ultrarrápido**: un mallado de 20×20 puntos en menos de 20 segundos sin parar en cada punto
* **Alta precisión**: resolución de hasta 0.0005 mm
* **ADXL345 integrado** (Cartographer V3/V4, Beacon RevH): input shaper sin hardware adicional
* **Modo Contact** (Beacon Contact / Cartographer Survey Touch): el sensor puede tocar el nozzle para calibrar el Z-Offset automáticamente
* **Peso ultra reducido** (\~4-6 g): sin impacto en las inercias del cabezal

{% hint style="warning" %}
Estos sensores **solo funcionan sobre superficies metálicas**. No funcionan sobre vidrio, PEI liso o cualquier material no conductor. La mayoría de camas magnéticas PEI sobre acero funcionan perfectamente.
{% endhint %}

#### Instalación del plugin

Tanto Beacon como Cartographer requieren instalar su propio plugin de Klipper independiente. Sigue la guía oficial de instalación del fabricante antes de configurar el `printer.cfg`:

* [Documentación oficial Beacon](https://docs.beacon3d.com)
* [Documentación oficial Cartographer](https://docs.cartographer3d.com)

#### Configuración básica en `printer.cfg`

Los bloques mínimos que debes tener en tu configuración son:

```ini
# mcu del sensor (serial o canbus_uuid según tu conexión)
[mcu beacon]          # o [mcu cartographer]
serial: /dev/serial/by-id/usb-Beacon_...
# canbus_uuid: XXXXXXXXXXXXXXXX

# Sección del sensor (sustituye [beacon] por [cartographer] según corresponda)
[beacon]
mcu: beacon
x_offset: 0          # Offset XY respecto al nozzle (mide el tuyo)
y_offset: 0
speed: 5
lift_speed: 5
```

```ini
[stepper_z]
endstop_pin: probe:z_virtual_endstop
homing_retract_dist: 0   # ← OBLIGATORIO con sensores scanner
```

```ini
[safe_z_home]
home_xy_position: 150, 150   # Centro de tu cama
z_hop: 3

[bed_mesh]
zero_reference_position: 150, 150   # El mismo punto que home_xy_position
speed: 300
horizontal_move_z: 3
mesh_min: 10, 10
mesh_max: 290, 290
probe_count: 20, 20
mesh_pps: 0, 0    # Con scanners no necesitas interpolación adicional
```

{% hint style="danger" %}
**`homing_retract_dist: 0`** es **obligatorio** con sensores scanner. Si lo dejas con el valor por defecto (5 mm), obtendrás errores o resultados inconsistentes en el homing de Z.
{% endhint %}

{% hint style="info" %}
**`zero_reference_position`** indica a Klipper qué punto del mallado usar como referencia Z=0. Debe coincidir con la posición de homing (centro de la cama). Sin este parámetro, el Z-Offset puede variar entre impresiones de forma imprevisible.
{% endhint %}
{% endtab %}

{% tab title="Sonda por boquilla (TAP)" %}
La sonda por boquilla elimina el concepto de Z-Offset: como el nozzle es la propia sonda, el sistema sabe exactamente dónde está la punta con respecto a la cama. Esta tecnología está popularizada por el **Voron TAP**, y también la usan **Bambu Lab** y **Prusa MK4** en sus sistemas.

**Ventajas:**

* **Z-Offset automático**: cambias el nozzle y no necesitas recalibrar nada
* **Funciona en cualquier superficie**: vidrio, PEI, aluminio, acero, lo que sea
* **Offset XY = 0**: el punto de sondeo es exactamente donde imprime, sin cálculos
* **Muy preciso**: señal directa, sin tolerancias mecánicas de un pin externo

**Desventajas:**

* El nozzle debe estar **perfectamente limpio** antes de sondear — cualquier blob de filamento endurecido desplaza la lectura
* Instalación más compleja: carril de deslizamiento, imanes, sensor óptico o Hall
* Requiere imprimir a temperatura de impresión durante el sondeo (para que el filamento sea blando)

#### Configuración en Klipper (Voron TAP)

El TAP se configura como un `[probe]` estándar, con offset XY = 0:

```ini
[probe]
pin: ^toolhead:PROBE_PIN   # Adapta al pin de tu electrónica
x_offset: 0
y_offset: 0
speed: 5
lift_speed: 10
samples: 3
sample_retract_dist: 3
samples_result: median
samples_tolerance: 0.006
samples_tolerance_retries: 3
```

```ini
[stepper_z]
endstop_pin: probe:z_virtual_endstop

[safe_z_home]
home_xy_position: 150, 150   # Centro de tu cama
z_hop: 10

[bed_mesh]
zero_reference_position: 150, 150   # Centro de tu cama
```

{% hint style="warning" %}
Antes de sondear con TAP, asegúrate de que el nozzle está a temperatura de impresión y **limpio**. Un nozzle con restos de filamento endurecido puede dar lecturas erróneas de hasta 0.2–0.5 mm.
{% endhint %}

Para el montaje físico y más detalles, consulta la [documentación oficial de Voron Design](https://vorondesign.com/voron_tap).
{% endtab %}
{% endtabs %}

<details>

<summary>Conectando nuestro BlTouch directamente a nuestra Raspberry Pi</summary>

En algunas electrónicas antiguas con poca disponibilidad de pines expuestos o compatibles podemos encontrarnos con que añadir un sensor BlTouch es complicado o imposible. En este caso, y si nuestro host es una Raspberry Pi, podremos aprovechar su GPIO para instalar nuestro tan útil sensor de nivelación.

* El primer paso es asegurarnos que nuestra Raspberry puede ser usada por Klipper como MCU [**siguiendo este procedimiento**](/klipper/mejoras/raspberry-como-segunda-mcu). Al final si todo ha ido correctamente dispondremos en nuestro printer.cfg con una sección para nuestra rpi como MCU:

<pre class="language-django" data-title="printer.cfg"><code class="lang-django"><strong>[mcu rpi]
</strong>serial: /tmp/klipper_host_mcu
</code></pre>

* El siguiente paso será adaptar el cableado al siguiente esquema (es necesario disponer de conectores Dupont o similares para adaptar estas conexiones) os aconsejamos tener a mano el [esquema GPIO](https://pinout.xyz/):
  * blanco -> GPIO0
  * negro -> GND justo al lado del GPIO0
  * amarillo -> GPIO27
  * marrón -> GND
  * rojo -> 3.3v (**ojo, algunos sensores requieren 5v**)

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/CK84ucmIAaziJE3DGuBa/image.png)

* Una vez todo conectado, volveremos a nuestro printer.cfg para crear/ajustar nuestra sección \[bltouch]:

```
[bltouch]
sensor_pin: ^rpi:gpio0
#   Pin connected to the BLTouch sensor pin. Most BLTouch devices
#   require a pullup on the sensor pin (prefix the pin name with "^").
#   This parameter must be provided.
control_pin: rpi:gpio27
#   Pin connected to the BLTouch control pin. This parameter must be
#   provided.
z_offset: 0.2
#pin_up_touch_mode_reports_triggered: False
#probe_with_touch_mode: True 
```

* el resto de pasos deberían de ser iguales

</details>

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

**normalmente cuando activamos un sensor de nivelación este marca nuestra coordenada 0 de Z por encima de la altura física, esta diferencia la encontraremos con el proceso de** [**ajuste del z-offset**](#ajuste-del-z-offset-usando-papel-o-galga) **explicado más abajo.**

**Para evitar&#x20;**<mark style="color:red;">**errores de movimientos fuera de rango**</mark>**&#x20;en el proceso de z-offset u otras nivelaciones hemos de ajustar el position\_min de nuestro stepper\_z a un valor adecuado y con cierto margen para que nos permita esos movimientos.**

```django
[stepper_z]
...
position_min: -5
...
```

{% endhint %}

## Safe Z Homing

Una configuración común para todos los sensores de nivelación suele ser el safe\_z\_home. Esta configuración nos ayuda a definir unas coordenadas seguras para que nuestro sensor pueda hacer el homing correctamente. Normalmente lo haremos en el centro de nuestra área de impresión.

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FsPTXda6s9l17LdwoWmtC%2Fimage.png?alt=media&amp;token=a491ac62-1466-460e-9eba-1d1543fceae5" alt=""><figcaption></figcaption></figure>

Dentro de nuestro **`printer.cfg` crearemos**, si no la tenemos ya, la s**ección `[`**`safe_z_home`**`]`** a continuación os vamos a mostrar un ejemplo:

```
[safe_z_home]
home_xy_position: 125, 125
z_hop: 10
z_hop_speed: 25
speed: 20
```

{% hint style="info" %}
En la sección **\[safe\_z\_home]** podemos encontrar:

* **home\_xy\_position**: el cual indica la **coordenada donde nuestro eje Z realizará el proceso de homing**. Por seguridad esta coordenada **se aconsaja que sea el centro de la nuestra cama**.\
  Recuerda que las coordenadas en Klipper siempre usan la refencia del nozzle por lo que si quieres dejar tu sensor en el centro de tu cama deberás de calcular esas coordenadas teniendo en cuenta los offsets de tu sensor.\
  En el caso que nuestro sensor tenga estos offsets X-20Y20 y una cama de 235x235mm la coordenada seria...\
  X= (235mm/2)+20 (tamaño total de X dividido entre 2 para encontrar el centro y sumamos el offset de nuestro sensor en X al ser este un valor negativo)=X97\
  Y= (235mm/2)-20 (tamaño total de Y dividido entre 2 para encontrar el centro y, en este caso, restamos el offset de nuestro sensor en Y al ser un valor positivo)=Y147
* **speed**: la **velocidad a la que se moverán los ejes XY a la coordenada indicada**
* **z\_hop**: la **distancia que se alzará el eje Z** antes de realizar el proceso de homing
  {% endhint %}

Podéis encontrar la documentación oficial de **Klipper sobre el Safe Z Home**:

{% embed url="<https://www.klipper3d.org/Config_Reference.html?h=pixel#safe_z_home>" %}

## Test de precisión

Una vez tengamos correctamente configurado nuestro sensor de nivelación es aconsejable realizar un test de precisión.

Realizamos el proceso de home para que nuestro cabezal de impresión quede en el medio de nuestra cama y desde el terminal lanzamos la macro PROBE\_ACCURACY

```bash
Recv: // probe accuracy: at X:0.000 Y:0.000 Z:10.000
Recv: // and read 10 times with speed of 5 mm/s
Recv: // probe at -0.003,0.005 is z=2.506948
Recv: // probe at -0.003,0.005 is z=2.519448
Recv: // probe at -0.003,0.005 is z=2.519448
Recv: // probe at -0.003,0.005 is z=2.506948
Recv: // probe at -0.003,0.005 is z=2.519448
Recv: // probe at -0.003,0.005 is z=2.519448
Recv: // probe at -0.003,0.005 is z=2.506948
Recv: // probe at -0.003,0.005 is z=2.506948
Recv: // probe at -0.003,0.005 is z=2.519448
Recv: // probe at -0.003,0.005 is z=2.506948
Recv: // probe accuracy results: maximum 2.519448, minimum 2.506948, range 0.012500, average 2.513198, median 2.513198, standard deviation 0.006250

```

{% hint style="warning" %}
El resultado ideal sería que el valor máximo y mínimo fueran idénticos. En la realidad pueden variar de un paso 0.005mm o rotation\_distance/(full\_steps\_per\_rotation\*microsteps). En el ejemplo anterior el paso de Z es de 0.0125mm.

En el caso que nuestra mediana sea superior a 0.025mm deberiamos de revisar y ajustar nuestra configuración o sensor. Usaremos la macro [PROBE\_ACCURACY](https://www.klipper3d.org/G-Codes.html#probe_accuracy) para testear los diferentes parámetros y ver como afectan a la precisión.
{% endhint %}

Una vez encontrados los valores óptimos se aconseja realizar el proceso de [**Z-Offset y el mallado de la cama que podeis encontrar en esta guía**](/klipper/empezamos/malla-nivelacion-de-cama-klipper).

## Ajuste del Z-Offset (usando papel o galga)

{% hint style="warning" %}
**Pasos previos!!!**

* Es necesario haber [**realizado un PID**](/klipper/empezamos/pid) de nuestro hotend y cama previo a la realización de estos pasos.

* Realizar un pre-calentado de cama y hotend en la temperatura que normalmente imprimais durante unos 5-15m

* Tener realizado la prueba del punto anterior de nivelación de la cama ya sea manual o asistida con sensor

* Disponer de un folio o galga de 0.1
  {% endhint %}

* Realizaremos un homing:
  * en el caso que tengamos una máquina con 2 o 3 motores independientes en Z realizaremos primero un ***Z\_TILT\_ADJUST*** (nivelación del gantry) y a continuación un ***G28*** (homing de todos los ejes)
  * en el caso que tengamos una máquina con 4 motores independientes en Z realizaremos primero un ***QUAD\_GANTRY\_LEVEL*** (nivelación del gantry) y a continuación un ***G28*** (homing de todos los ejes)
  * si tu máquina no concuerda con ninguno de los casos anteriores realiza directamente un G28 (homing de todos los ejes)

* Moveremos nuestro hotend al centro de la cama si no tenemos activo el safe\_homing

* Limpiaremos cualquier malla de nivelación de nuestra cama con un ***BED\_MESH\_CLEAR***

* Dependiendo del final de carrera que usemos en nuestra máquina:
  * si tenemos un final de carrera mecánico usaremos ***Z\_ENDSTOP\_CALIBRATE***... por ejemplo máquinas como las Voron V0, Trident, V2.x o BLV
  * si usamos nuestro sensor de nivelación como final de carrera usaremos ***PROBE\_CALIBRATE***

* Mediante comandos iremos bajando lentamente el nozzle hacia la cama usando **TESTZ Z=-1** hasta que estemos cerca para en ese momento realizar movimientos más pequeños usando **TESTZ Z=-.01** o incluso menos hasta que nuestro nozzle roce con el papel. Podemos alternar el **TESTZ** con valores positivos/negativos y mayores/menores hasta que tengamos nivelado a nuestro gusto en ese momento lanzaremos un ***ACCEPT*** y un ***SAVE\_CONFIG*** para guardar la configuración.

{% hint style="danger" %}
**En el caso que usemos una configuración modular en la que nuestro z*****offset no se encuentre directamente en nuestro printer.cfg puede dar errores al hacer el SAVE\_CONFIG.***

***En estos casos puedes añadir, solamente la primera vez seria necesario, la sección bltouch y el valor de z\_offset después de SAVE\_CONFIG:***

\#\*# <---------------------- SAVE\_CONFIG ---------------------->

\#\*# DO NOT EDIT THIS BLOCK OR BELOW. The contents are auto-generated.

***En el caso de un sensor bltouch***

\#\*#

\#\*# \[bltouch]

\#\*# z\_offset = 0.685

\#\*#

**En el caso de un probe normal**

\#\*#

\#\*# \[probe]

\#\*# z\_offset = 0.320

\#\*#
{% endhint %}

{% hint style="danger" %}
**Os recordamos que Klipper usa valores positivos para su ZOffset para aquellos que vengáis de Marlin.**
{% endhint %}

{% hint style="info" %}
Klipper normalmente asume que este proceso se realizó en frío, en nuestro caso al hacerlo en caliente normalmente se aconseja realizar un TEST Z=-0.1 o -0.5 antes de guardar los cambios.

De todas formas normalmente es acabar realizando este test con un test de calibración de primeras capas y el [**ajuste fino de la altura en Z o babystepping**](#undefined).
{% endhint %}

* Ahora que ya tenemos nuestro Z-Offset ajustado lo ideal seria hacer una malla de nuestra cama si disponemos de sensor

{% hint style="info" %}
Si disponemos de una pantalla nativa de nuestra impresora configurada o tenemos KlipperScreen podremos tener un asistente para el proceso.

<img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/MrKaU6I4Js3itCnKMfDA/telegram-cloud-photo-size-4-5787361130648287521-x.jpg" alt="" data-size="original">
{% endhint %}

### Ajuste fino del Z-Offset

Es muy probable que después del proceso anterior no acaben de quedar nuestras primeras capas en ese caso lo ideal es realizar un ajuste fino de nuestro Z-Offset durante una impresión de test.

#### Usando nues UI (Mainsail/Fluidd)

Dentro de nuestro interfaz Mainsail/Fluidd, normalmente en la sección toolhead, usaremos los controles de babystepping para ajustar en tiempo real la altura de primera capa a nuestro gusto.

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/4Mkw59thEkg9CTFdImlp/image.png" alt=""><figcaption></figcaption></figure>

#### Usando una pantalla

Dentro del menu Tune podremos encontrar los controles para ajustarlo.

#### Guardando el nuevo valor de Z-Offset

Ahora que ya tenemos el ajuste fino del Z-Offset deberemos guardarlo en nuestro printer.cfg:

* En el caso que usemos un endstop físico para ajustar el valor ***position\_endstop** lanzaremos el comando **Z\_OFFSET\_ENDSTOP** seguido de **SAVE\_CONFIG***... **ojo que estor reiniciará tu impresora!!!**
* En el caso que usemos un sensor como final de carrera en Z y para ajustar el valor ***z\_offset** lanzaremos el comando **Z\_OFFSET\_APPLY\_PROBE*** seguido de ***SAVE\_CONFIG***... **ojo que estor reiniciará tu impresora!!!**

## **Compensación en caso de eje torcido**

En ocasiones nos podemos encontrar que después de ajustar y nivelar nuestra cama de forma manual, tener unas lecturas precisas del sensor o incluso realizar multiprobing para mejorar las lecturas... el resultado no es el correcto.

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2F3I1OJd5iGqL9WuArQBU3%2Fimage.png?alt=media&amp;token=2915b574-eb8c-4926-b7c7-dd850a0e2157" alt=""><figcaption></figcaption></figure>

**Nuestro eje X/Y puede estar torzido,** una situación que no es extraña en muchas ocasiones es que nuestro eje X esté torcido y dado que normalmente los sensores de nivelación se colocan alejados del eje y con respecto al nozzle (que este si que suele estar bastante más cercano al eje, el ángulo puede llegar a provocar problemas serios a la hora de realizar nuestro mallado.\
![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/LllKfoMdav0Jiw3jA9zL/telegram-cloud-photo-size-4-5798463668353088688-y.jpg)\
En el anterior dibujo podéis ver como puede impactar a la fiabilidad de las lecturas del sensor el tener este tipo de problemas en el que observamos que en determinadas áreas de nuestra área de impresión no podemos obtener unas correcciones buenas acabando en unas malas primeras capas.\
Aunque os vamos a explicar las opciones disponibles en Klipper para minimizar/compensar estos fallos mecánicos es **siempre aconsejable que antes intentemos arreglar el problema mecanicamente intentando ajustar nuestro chasis y cinemática lo máximo posible**.

{% hint style="warning" %}
Klipper y su compensación de eje torcido no es compatible con todos los tipos de sensores de nivelación.
{% endhint %}

Para activar la compensación de ejes tocidos, a partir de ahora `axis_twist_compensation` realizaremos los siguientes pasos:

* Activaremos `[`[`axis_twist_compensation`](https://www.klipper3d.org/Config_Reference.html#axis_twist_compensation)`]` en nuestro printer.cfg para habilitar el módulo de compensación e idealmente ajustar sus opciones de ser necesario.
* Desde la consola lanzaremos la macro de sistema `AXIS_TWIST_COMPENSATION_CALIBRATE` que lanzará un asistente para medir el Z Offset en diferentes puntos de nuestra cama, inicialmente utiliza 3 puntos pero podemos realizar más añadiendo el parámetro `SAMPLE_COUNT=` y el número de puntos al lanzar la macro anterior
* Realizaremos el proceso de [ajuste del Z Offset ](#ajuste-del-z-offset-usando-papel-o-galga)normal explicado en puntos anteriores
* Realizaremos los ajustes de nivelado manual asistido por sensor o [screws\_tilt\_adjust](/klipper/empezamos/nivelacion-cama-manual), [z-tilt](/klipper/empezamos/nivelacion-gantry-z-tilt) en el caso que los tengamos habilitados para asegurarnos que tenemos todo ajustado correctamente
* Haremos un home de todos los ejes y haremos un [mallado de nuestra cama](/klipper/empezamos/malla-nivelacion-de-cama-klipper)
* Realizaremos un test de impresión de primeras capas y haremos los [ajustes finos de Z Offset](#ajuste-fino-del-z-offset) durante este.

{% hint style="info" %}
Si necesitas más información sobre las configuraciones del módulo axis\_twist\_compensation puedes encontrarlas en la [documentación oficial de Klipper](https://www.klipper3d.org/Config_Reference.html#axis_twist_compensation).

Para los comandos relacionados con axis\_twist\_compensation puedes encontrarlos también en la [documentación oficial de Klipper](https://www.klipper3d.org/G-Codes.html#axis_twist_compensation).
{% endhint %}


# Bigtreetech Eddy

El BTT Eddy es un sensor de nivelación por escaneo de la superficie basado en corrientes de Eddy (inductivo). Este tipo de sensores pueden escanear tu cama en unos pocos segundos con una alta precisión, sin contacto físico y sin pin de toque.

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FYPjuA24PkQhBLT9YKGEj%2Fimage.png?alt=media&amp;token=46c75662-6061-4d33-8b65-1a26e57b57ca" alt="" width="153"><figcaption></figcaption></figure>

Entre sus ventajas destacan:

* **Nivelación de alta velocidad**: completa un nivelado en unos 20 segundos para una cama de tamaño medio, y menos con la cama pequeña.
* **Alta precisión**: lecturas con resolución de 0.0005 mm.
* **Tamaño compacto y bajo peso**: 6 g, integrable en casi cualquier cabezal sin afectar a inercias ni vibraciones.
* **Compensación de temperatura**: integra la función de compensación térmica de Klipper para mantener la precisión cuando la cama calienta.
* **Escaneo continuo**: con `METHOD=rapid_scan` el cabezal no se detiene en cada punto, el sondeo se hace en movimiento. Es especialmente rápido con el BTT Eddy.

{% hint style="danger" %}
**Limitación importante**

**Por el principio de funcionamiento, el BTT Eddy solo es compatible con superficies metálicas conductivas y con campo magnético uniforme.**

Puede dar problemas con camas que tengan zonas de nivelación aisladas, imanes para fijar el fleje o PEI, o superficies no conductoras.
{% endhint %}

{% hint style="info" %}
**Klipper oficial, no el fork de BTT**

Desde hace tiempo ya no es necesario usar el fork de Klipper de Bigtreetech. Esta guía está escrita para **Klipper oficial**. Si usas el fork de BTT, migra a la versión oficial — lo más fácil es reinstalar desde [KIAUH](https://github.com/dw-0/kiauh).
{% endhint %}

## Versiones del BTT Eddy

Existen tres versiones del sensor con diferencias importantes según el setup:

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FOROfWXyJDocUIlRXHQ8p%2Fimage.png?alt=media&amp;token=b7e53dd9-325f-47d9-b411-9c7ae8ccea3f" alt=""><figcaption></figcaption></figure>

| Versión           | Conexión       | Sensor temperatura | Cuándo usarla                                                                                       |
| ----------------- | -------------- | ------------------ | --------------------------------------------------------------------------------------------------- |
| **BTT Eddy**      | USB            | Sí                 | La opción habitual y recomendada. Se gestiona como una MCU independiente en Klipper.                |
| **BTT Eddy Coil** | I2C (EBB36/42) | No                 | Para toolheads tipo EBB36/EBB42. Simplifica el cableado pero pierde la compensación de temperatura. |
| **BTT Eddy CAN**  | CANbus         | Sí                 | Para setups con bus CAN directo al host, electrónica o toolhead.                                    |

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FjVfLNgcRjfILBak5v3dl%2Fimage.png?alt=media&amp;token=0eae2d11-b4b7-4efb-a842-77ecf8fd8d54" alt=""><figcaption></figcaption></figure>

{% tabs %}
{% tab title="BTT Eddy USB con Manta M8P v2.0" %}

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FrRHCaj5u6NGV3IipbaBU%2Fimage.png?alt=media&amp;token=0d8156d1-b3d6-4d8b-868d-ef0b7e9faa4d" alt=""><figcaption></figcaption></figure>
{% endtab %}

{% tab title="BTT Eddy USB con Manta M5P" %}

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2F1RMuVQjzi4STrS2q63OG%2Fimage.png?alt=media&amp;token=6eea971e-6276-4393-9b5b-c9b908be0e38" alt=""><figcaption></figcaption></figure>
{% endtab %}

{% tab title="BTT Eddy Coil con EBB36 v1.2" %}

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FZ3vUqz5ibSoPFYdj6ITb%2Fimage.png?alt=media&amp;token=cca1d4d3-702d-4be8-a6b6-84661dae5ee2" alt=""><figcaption></figcaption></figure>
{% endtab %}

{% tab title="BTT Eddy Coil con EBB42 v1.2" %}

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2Fpd16KrzyU6e8vTd4D11H%2Fimage.png?alt=media&amp;token=1402d3b7-90db-4291-8285-8e5541a84974" alt=""><figcaption></figcaption></figure>
{% endtab %}
{% endtabs %}

## Instalación del sensor

Algunos consejos antes de montar el sensor:

* Montarlo en el cabezal con **2-3 mm entre la superficie de medición del Eddy y la punta del nozzle** (2.5 mm es el valor óptimo).
* En la versión USB, evitar que el cable pase junto a cables de motores u otras fuentes de ruido eléctrico. Usa un cable de calidad, apantallado y flexible.
* Mantener la parte electrónica del sensor alejada de fuentes de calor como el hotend.

## Compilación del firmware

{% hint style="warning" %}
El BTT Eddy solo es compatible con instalaciones de Klipper que usen **Python 3**. Si ves errores del tipo `Internal error during connect: split() takes no keyword arguments`, tu Klipper está en Python 2 — reinstala desde [KIAUH](https://github.com/dw-0/kiauh).
{% endhint %}

{% tabs %}
{% tab title="USB" %}
Desde SSH:

```bash
cd ~/klipper
make menuconfig
```

Selecciona estos valores en el menú:

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2F4fKshuVh3slPjiMOabwx%2Fimage.png?alt=media&amp;token=79180440-2299-40ad-b407-cb14f6f00da0" alt=""><figcaption></figcaption></figure>

Pulsa `Q` y `Yes` para guardar, luego:

```bash
make
```

Con el sensor desconectado, mantén pulsado el botón **BOOT** y conecta el cable USB al host. Suelta BOOT una vez conectado.

Verifica que aparece en el sistema:

```bash
lsusb
```

Deberías ver algo como:

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2Ff2He4kjOvW8njcUp52Pn%2Fimage.png?alt=media&amp;token=8733f764-0a73-4464-8b6c-bc8eb485c33c" alt=""><figcaption></figcaption></figure>

Flashea el firmware (ajusta el ID al que veas en `lsusb`):

```bash
cd ~/klipper
make flash FLASH_DEVICE=2e8a:0003
```

Una vez finalizado, obtén el serial ID del sensor:

```bash
ls /dev/serial/by-id/*
```

Anota el ID — lo usarás en la sección `[mcu eddy]` del `printer.cfg`.
{% endtab %}

{% tab title="Coil (I2C)" %}
La versión BTT Eddy Coil se conecta al toolhead o host mediante I2C. Hay que aplicar el firmware al host EBB al que se conecta y configurarlo específicamente para I2C. Consulta la [documentación oficial de BTT](https://github.com/bigtreetech/Eddy) para los pasos específicos de tu toolhead.
{% endtab %}
{% endtabs %}

## Configuración Klipper

Elige el fichero de ejemplo según tu setup:

* **BTT Eddy como probe + z-endstop separado** → [sample-bigtreetech-eddy.cfg](https://github.com/bigtreetech/Eddy/blob/master/sample-bigtreetech-eddy.cfg)
* **BTT Eddy como probe y z-endstop** (lo más habitual) → [sample-bigtreetech-eddy-homing.cfg](https://github.com/bigtreetech/Eddy/blob/master/sample-bigtreetech-eddy-homing.cfg)
* **BTT Eddy como probe, z-endstop y con z-offset dinámico** → [sample-bigtreetech-eddy-zoffbeta.cfg](https://github.com/bigtreetech/Eddy/blob/master/sample-bigtreetech-eddy-zoffbeta.cfg)

{% hint style="success" %}
**Recomendación: usar include**

Lo más limpio es copiar la configuración de ejemplo en un fichero `eddy.cfg` y añadirlo como include en tu `printer.cfg`:

```ini
[include eddy.cfg]
```

Ponlo siempre encima de la línea `#*# <--- SAVE_CONFIG --->`. Si tienes un KNOMI, pon el include del Eddy **debajo** del KNOMI para que las macros se carguen en el orden correcto.
{% endhint %}

### Si usas el BTT Eddy como z-endstop (recomendado)

En la sección `[stepper_z]` de tu `printer.cfg`:

```ini
[stepper_z]
endstop_pin: probe:z_virtual_endstop
# Comenta o elimina la línea position_endstop
```

{% hint style="warning" %}
Si tienes un **BTT KNOMI**, algunas macros entrarán en conflicto. Comenta en el cfg del KNOMI las macros que se solapen con las del Eddy.
{% endhint %}

### Ajustes a personalizar en el cfg del Eddy

Una vez copiado el fichero de ejemplo, personaliza:

* **Serial del BTT Eddy** (versión USB): el ID que obtuviste con `ls /dev/serial/by-id/*`.
* **Offsets XY del sensor**: la distancia en X e Y desde el nozzle al punto de medición del Eddy.

{% hint style="info" %}
**Cómo medir los offsets XY**

El punto de medición del sensor está marcado en la PCB:

<img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2Fnap3zkmKE7IJJf1H1oYQ%2Fimage.png?alt=media&amp;token=ea1a2e85-18e1-4800-8e6b-b0c13a3ece89" alt="" data-size="original">

**Método manual**: mide con una regla la distancia desde el nozzle al punto de medición del sensor en X e Y.

**Método preciso** (requiere la máquina funcional con homing en XY):

1. Haz home en XY: `G28 XY`
2. Coloca el cabezal en el centro de la cama
3. Lanza `PROBE` desde la consola (pega un trozo de cinta en la cama para marcar el punto de sondeo)
4. Lanza `GET_POSITION` y anota la posición
5. Mueve el nozzle encima del punto marcado con los controles manuales
6. Lanza `GET_POSITION` de nuevo y calcula la diferencia — esos son los offsets

Aplica los valores en tu cfg y haz `RESTART`.
{% endhint %}

* **`mesh_min` y `mesh_max`**: los límites del área de mallado. Consulta la [guía de sensores de nivelación](/klipper/empezamos/sensor-nivelacion) para calcularlos correctamente según el offset de tu sensor.
* **`home_xy_position`**: la posición XY donde el Eddy hará el homing Z. Explicado en la [guía de sensores → safe\_z\_home](/klipper/empezamos/sensor-nivelacion#safe-z-homing).

## Calibración BTT Eddy

### 1. Calibración DRIVE\_CURRENT

Controla la intensidad del campo magnético que genera el sensor. Hay que calibrarla una vez (o cada vez que cambies la altura de montaje del sensor).

* Haz home en XY: `G28 XY`
* Mueve el cabezal al centro de la cama a 20 mm de altura

{% hint style="warning" %}
Si usas el Eddy como z-endstop y no puedes hacer un home completo aún, usa `SET_KINEMATIC_POSITION Z=0` para forzar la posición y poder mover el eje Z:

```gcode
G28 XY
SET_KINEMATIC_POSITION Z=0
G1 Z20 F1500
```

{% endhint %}

* Lanza la calibración:

```gcode
LDC_CALIBRATE_DRIVE_CURRENT CHIP=btt_eddy
```

* Guarda el resultado:

```gcode
SAVE_CONFIG
```

### 2. Calibración de mapeo de lecturas (correlación sensor → altura Z)

Este proceso establece la relación entre las lecturas del sensor y la posición real del nozzle. Hay que repetirlo si cambias la altura de montaje del sensor.

{% hint style="info" %}
**Dos comandos disponibles**

* `PROBE_EDDY_CURRENT_CALIBRATE_AUTO CHIP=btt_eddy` — variante histórica usada por la guía oficial de BTT, hace el proceso completo en automático.
* `PROBE_EDDY_CURRENT_CALIBRATE CHIP=btt_eddy` — el comando estándar de Klipper. Hace exactamente lo mismo: tras el test del papel, mueve el cabezal y ejecuta una serie de movimientos para correlacionar las lecturas del sensor con posiciones Z.

Cualquiera de los dos vale. En esta guía usamos el segundo, que es el documentado oficialmente en Klipper.
{% endhint %}

* Lanza:

```gcode
PROBE_EDDY_CURRENT_CALIBRATE CHIP=btt_eddy
```

* Aparecerá el asistente para bajar el nozzle con un papel hasta tocar la cama (el procedimiento clásico del papel).
* Acepta con `ACCEPT` cuando el papel haga la resistencia justa.
* El proceso continúa automáticamente y tarda aproximadamente dos minutos. Klipper publicará en consola las medidas de ruido y la frecuencia leída a cada altura Z.
* Al terminar, guarda:

```gcode
SAVE_CONFIG
```

{% hint style="warning" %}
**Calibra y sondea siempre a la misma temperatura**

La frecuencia que mide la bobina del Eddy depende ligeramente de la temperatura del propio sensor y de la cama. Si calibras en frío y luego sondeas con la cama a 60 °C, las lecturas se desplazan unas micras. Por eso el siguiente paso (compensación de temperatura) es **muy recomendable** en cualquier impresora donde no calibres siempre a la misma temperatura.
{% endhint %}

#### Habilitar el rapid scan (proving)

`PROBE_EDDY_CURRENT_CALIBRATE` solo calibra la relación lectura-altura para el sondeo estándar. Para usar `METHOD=rapid_scan` con precisión, Klipper hace una calibración adicional —llamada coloquialmente "proving"— que se ejecuta la **primera vez** que lanzas un mallado con escaneo rápido:

```gcode
G28
BED_MESH_CALIBRATE METHOD=rapid_scan
SAVE_CONFIG
```

Si la cama no está suficientemente paralela a los raíles XY, el modo rapid scan puede no ser fiable y Klipper lo avisará por consola. En ese caso usa primero `METHOD=scan` o haz un Z-tilt / QGL más fino.

### 3. Calibración de malla

Con el sensor ya calibrado, haz el mallado de cama:

```gcode
G28
BED_MESH_CALIBRATE METHOD=rapid_scan
SAVE_CONFIG
```

{% hint style="info" %}
**Parámetros avanzados de escaneo**

`BED_MESH_CALIBRATE` con el BTT Eddy soporta opciones adicionales:

* `METHOD=rapid_scan` — escaneo continuo sin parar en cada punto (el más rápido, recomendado para uso diario)
* `METHOD=scan` — escaneo con pausa en cada punto para múltiples lecturas (más lento, más preciso)
* `SCAN_MODE=detailed` o `SCAN_MODE=rapid` — submode del método `scan`
* `SCAN_SPEED=[velocidad]` — velocidad durante el escaneo continuo
* `ADAPTIVE=1` — mallado adaptativo nativo de Klipper: sondea solo el área que ocupa la pieza actual. No necesitas KAMP para esto.

Ejemplo de uso con mallado adaptativo:

```gcode
BED_MESH_CALIBRATE METHOD=rapid_scan ADAPTIVE=1
```

Añade esto a tu macro de inicio para sondear solo el área necesaria en cada impresión.
{% endhint %}

### 4. Compensación de temperatura (solo versión USB)

{% hint style="warning" %}
La compensación de temperatura solo está disponible en la versión USB, que incluye sensor de temperatura integrado en la bobina.
{% endhint %}

Este proceso crea un perfil de corrección para compensar la deriva térmica del sensor conforme calienta la cama y el propio cabezal. Sin él, las lecturas del Eddy varían con la temperatura y la primera capa se desplaza unas centésimas entre impresiones en frío y en caliente.

#### Sección `[temperature_probe]` en printer.cfg

A partir de Klipper 0.13 el procedimiento se ha estandarizado a través del módulo `[temperature_probe]`, que se vincula automáticamente con la sección `[probe_eddy_current]` si comparten el mismo nombre.

```ini
[probe_eddy_current btt_eddy]
# ...config existente del Eddy...

[temperature_probe btt_eddy]
sensor_type: temperature_mcu
sensor_mcu: eddy
min_temp: 0
max_temp: 105
# Parámetros del proceso de calibración térmica
calibration_position: 175, 175, 1     # XY de sondeo + Z para sondeo manual
calibration_bed_temp: 90              # temperatura máxima segura de la cama durante la calibración
calibration_extruder_temp: 150        # temperatura del hotend para evitar contracción del nozzle
extruder_heating_z: 50                # altura Z donde se calienta el hotend (separado de la cama)
max_validation_temp: 70               # 100-120 si tu impresora es cerrada
```

{% hint style="info" %}
**¿Por qué los parámetros `calibration_*`?**

* `calibration_bed_temp`: tras la primera muestra Klipper enciende la cama y va tomando muestras conforme sube la temperatura. Al terminar, la apaga.
* `calibration_extruder_temp`: si está definido, Klipper calienta primero el hotend hasta esa temperatura para que el nozzle ya esté dilatado durante el primer sondeo manual. Evita errores de varias centésimas por la dilatación del filamento entre frío y caliente.
* `extruder_heating_z`: Z al que se sitúa el cabezal mientras calienta el hotend, lo suficientemente lejos de la cama para no calentar la bobina del Eddy con el calor radiado del nozzle.
* `max_validation_temp`: temperatura máxima usada al final del proceso para validar la curva de compensación. En impresoras cerradas tipo Voron / Bambu hay que subirla a 100-120, ya que el aire interno alcanza temperaturas más altas.
  {% endhint %}

#### Procedimiento

Con la sección `[temperature_probe]` añadida, reinicia Klipper y lanza:

```gcode
G28
G0 Z5
SET_IDLE_TIMEOUT TIMEOUT=36000
TEMPERATURE_PROBE_CALIBRATE PROBE=btt_eddy TARGET=80
```

`TARGET` es la temperatura **máxima de la bobina del Eddy** a la que quieres llegar — no la temperatura de cama. En la práctica con cama a 90-100 °C la bobina del Eddy estabiliza alrededor de 50-70 °C.

Klipper irá tomando muestras cada **2 °C de subida** (configurable con `STEP=4` en el propio comando para muestrear cada 4 °C y acelerar el proceso). En cada muestra pide hacer el test del papel; acepta con `ACCEPT`. **Cuidado de no quemarte durante el proceso.**

Comandos auxiliares durante la calibración:

* `TEMPERATURE_PROBE_NEXT` — forzar el siguiente paso antes de llegar a la temperatura objetivo.
* `TEMPERATURE_PROBE_COMPLETE` — finalizar el proceso antes de llegar a TARGET con los datos recogidos hasta ahora.
* `ABORT` — cancelar sin guardar nada.

Al terminar, guarda con `SAVE_CONFIG`. Klipper escribirá los coeficientes de la curva de compensación al final del printer.cfg dentro del bloque `#*# <--- SAVE_CONFIG --->`.

{% hint style="success" %}
**Cómo verificar que ha quedado bien**

Tras `SAVE_CONFIG` puedes comprobar que la compensación funciona con la cama fría y luego con la cama caliente: lanza `PROBE` y mira el valor reportado. Sin compensación, la diferencia frío-caliente suele rondar 50-100 µm; con compensación, debería estar por debajo de 20 µm.
{% endhint %}

### 5. Ajuste del Z-Offset

{% hint style="warning" %}
Este paso solo aplica si usas el BTT Eddy como z-endstop.
{% endhint %}

{% hint style="info" %}
**El z-offset del Eddy funciona diferente al de un sensor tradicional**

En un sensor clásico (BLTouch, inductivo...), el z-offset es la distancia entre el punto de activación del sensor y la punta del nozzle — es fijo y depende del montaje.

En el Eddy no hay "punto de activación" — el sensor envía telemetría continua que Klipper traduce a distancias. Durante la calibración le dices al sistema que, para las lecturas obtenidas con el nozzle tocando la cama (test del papel), eso es z=0.

Por eso el parámetro `z_offset` en la config del Eddy no indica la distancia sensor-nozzle, sino la altura de sondeo por encima de la cama (normalmente 2.5 mm). Ajustar la primera capa se hace con `PROBE_CALIBRATE` como en cualquier otro sensor.
{% endhint %}

Para ajustar z=0 con el Eddy como z-endstop:

```gcode
G28
PROBE_EDDY_CURRENT_CALIBRATE_AUTO CHIP=btt_eddy
```

Sigue el asistente para ajustar el nozzle con el papel. Al finalizar, `SAVE_CONFIG`.

## Video Tutorial

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

## Troubleshooting

### `Error during homing probe: Eddy current sensor error`

Indica lecturas fuera de rango del sensor. Causas habituales:

* El sensor no está a la altura correcta (debe estar 2-3 mm sobre el nozzle, óptimo 2.5 mm).
* Siempre que cambies la altura de montaje, **borra toda la calibración y repítela desde el principio**.
* Si persiste, prueba a poner `reg_drive_current: 16` manualmente en la sección del Eddy.

### `Probe Triggered Before Movement`

Sucede cuando lanzas `PROBE` dos veces seguidas sin subir el cabezal entre medidas. Sube Z unos milímetros entre comandos `PROBE`.

### Pausas o saltos durante el mallado

Causas posibles:

* Macro `BED_MESH_CALIBRATE` mal configurada — asegúrate de usar `METHOD=rapid_scan`
* KAMP instalado y en conflicto — ver sección KAMP más abajo

### `gcode command <XX> already registered`

Una macro del Eddy está siendo sobreescrita por otra configuración (KAMP, KNOMI, u otro include). Revisa el orden de los includes en tu `printer.cfg` y elimina macros duplicadas.

### Problemas de z-offset

Lee [este documento de BTT](https://gist.github.com/bigtreetech/484380b26be613b9139bc537510393df) sobre cómo funciona el z-offset en el Eddy. El comportamiento es diferente al de un sensor tradicional — entenderlo evita muchas confusiones.

### KNOMI — conflicto de macros

Si tienes KNOMI, comenta en su cfg las macros que entren en conflicto con el Eddy. Además, en el cfg de ejemplo del Eddy descomenta las macros específicas para KNOMI.

### KAMP — ya no es necesario

KAMP (Klipper-Adaptive-Meshing-Purging) fue muy útil antes de que Klipper integrara el mallado adaptativo nativo. Hoy en día:

* Klipper 0.12+ tiene mallado adaptativo nativo (`ADAPTIVE=1` en `BED_MESH_CALIBRATE`)
* El escaneo con BTT Eddy es tan rápido que sondear toda la cama tampoco penaliza mucho
* Las macros de KAMP pueden entrar en conflicto con las del Eddy

**Recomendación**: elimina KAMP o al menos comenta la línea `[include ./KAMP/adaptive_meshing.cfg]` en `KAMP_SETTINGS.cfg` y usa `ADAPTIVE=1` directamente.


# BIQU MicroProbe

El BIQU MicroProbe es un sensor de nivelación con pin retráctil, similar en concepto al BLTouch pero con un funcionamiento electrónico diferente y algunas ventajas interesantes respecto a él.

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/wnJwWZUgMgFMoEi2VEkj/image.png" alt=""><figcaption><p>Diagrama de conexiones del BIQU MicroProbe</p></figcaption></figure>

**Características principales:**

* Tamaño reducido e integrable en casi cualquier cabezal
* Peso reducido — minimiza el impacto en inercias y vibraciones
* Instalación similar a un BLTouch
* Buena precisión y fiabilidad
* Pin de contacto reemplazable
* Compatible con una amplia variedad de impresoras y electrónicas
* Precio competitivo

## Dónde comprarlo

{% tabs %}
{% tab title="AliExpress" %}
{% embed url="<https://s.click.aliexpress.com/e/182731559?productUrl=https://www.aliexpress.com/item/1005006314165426.html>" %}
{% endtab %}
{% endtabs %}

{% hint style="info" %}
} Si utilizas los links de compra, el precio del producto será el mismo que si accedes de manera habitual, pero a 3DWork le quedará una pequeña comisión. Algo que nos ayudará a soportar el proyecto y continuar generando contenido.
{% endhint %}

{% hint style="warning" %}
**Diferencias importantes respecto al BLTouch**

<img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FAG8TD608M4pkxTCVg46Y%2Fimage.png?alt=media&amp;token=51a1cff5-a93f-48c2-ad75-87cea577133f" alt="" data-size="original">

**V1 vs V2**: existen dos versiones con polaridad de señal invertida.

* **V1**: trigger en **HIGH** — pin de señal sin modificador (`^PIN`)
* **V2**: trigger en **LOW** — pin de señal con modificador negado (`^!PIN`)

**La V2 necesita una señal pull-up fuerte**. En algunas electrónicas puede dar problemas con ciertos pines que no tienen pull-up externo suficiente. Si el sensor no responde correctamente, prueba con otro pin o añade una resistencia pull-up externa.

Verifica la versión de tu sensor antes de copiar ninguna configuración.
{% endhint %}

## Compilación y flasheo del firmware

El MicroProbe no requiere flasheo de firmware adicional. Se conecta directamente a la electrónica de la impresora como un sensor de probe estándar.

## Configuración Klipper

La configuración del MicroProbe usa la sección `[probe]` estándar de Klipper con el añadido de un pin de servo para controlar el despliegue y recogida del pin.

### Estructura general

```ini
# Pin de control servo (despliegue/recogida)
[output_pin probe_enable]
pin: PIN_SERVO          # Ajusta al pin de tu electrónica
value: 0                # Recogido por defecto

# Sensor probe
[probe]
pin: ^!PIN_SEÑAL        # V1: ^PIN  |  V2: ^!PIN
deactivate_on_each_sample: False
x_offset: 0.0           # Offset real de tu instalación
y_offset: 0.0           # Offset real de tu instalación
z_offset: 0.0           # Se calibra con PROBE_CALIBRATE
speed: 5.0
lift_speed: 10.0
samples: 2              # Número de muestras por punto
samples_result: median  # median o average
sample_retract_dist: 3.0
samples_tolerance: 0.050
samples_tolerance_retries: 3
activate_gcode:
    Probe_Deploy
    G4 P500             # 500ms para desplegar
deactivate_gcode:
    Probe_Stow

# Macros de despliegue y recogida
[gcode_macro Probe_Deploy]
gcode:
    SET_PIN PIN=probe_enable VALUE=1

[gcode_macro Probe_Stow]
gcode:
    SET_PIN PIN=probe_enable VALUE=0
```

{% hint style="info" %}
**`samples`, `samples_tolerance` y `samples_tolerance_retries`** son parámetros recomendados para mejorar la fiabilidad de las medidas. Con `samples: 2` y `samples_result: median`, Klipper toma 2 lecturas por punto y usa la mediana — si las lecturas difieren más de `samples_tolerance` (50 µm), lo reintenta hasta 3 veces. Esto evita resultados erróneos por vibraciones o ruido eléctrico.
{% endhint %}

### Configuración por electrónica

{% tabs %}
{% tab title="M8P v2.0" %}
Cableado:

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FQNTC82E1fHv6Q8xAdNaf%2Fimage.png?alt=media&amp;token=ae3cde5e-f02c-40f9-a13d-838afd23166c" alt=""><figcaption></figcaption></figure>

```ini
[output_pin probe_enable]
pin: PD12

[probe]
pin: ^!PD13  # V1: ^PD13  |  V2: ^!PD13
```

{% endtab %}

{% tab title="M8P v1.1" %}
Cableado:

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FKD39salZ1HhE6ZiKAqNc%2Fimage.png?alt=media&amp;token=fa955101-70e1-4e65-a727-8337f56ef860" alt=""><figcaption></figcaption></figure>

```ini
[output_pin probe_enable]
pin: PB1

[probe]
pin: ^!PB2  # V1: ^PB2  |  V2: ^!PB2
```

{% endtab %}

{% tab title="M5P" %}
Cableado:

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2Fl3Nig0pZoYCXwr7iOYDf%2Fimage.png?alt=media&amp;token=12bd9ad9-5193-4b45-8322-ba3c1e4ccc76" alt=""><figcaption></figcaption></figure>

```ini
[output_pin probe_enable]
pin: PC15

[probe]
pin: ^!PC13  # V1: ^PC13  |  V2: ^!PC13
```

{% endtab %}

{% tab title="Octopus" %}
Cableado:

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FPSnFafiEaxGHKWAXoEcC%2Fimage.png?alt=media&amp;token=00b6e259-c4ee-4f1d-9648-aabf03ab1945" alt=""><figcaption></figcaption></figure>

```ini
[output_pin probe_enable]
pin: PB6

[probe]
pin: ^!PB7  # V1: ^PB7  |  V2: ^!PB7
```

{% endtab %}

{% tab title="Octopus MAX" %}
Cableado:

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2F6g0ltsoIeC9KiB7lI1Z5%2Fimage.png?alt=media&amp;token=f3765afc-f5e3-4ba8-8c38-02843c259376" alt=""><figcaption></figcaption></figure>

```ini
[output_pin probe_enable]
pin: PB6

[probe]
pin: ^!PB15  # V1: ^PB15  |  V2: ^!PB15
```

{% endtab %}

{% tab title="E3 EZ" %}
Cableado:

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FOOPdyoKq57Yz4TjzUyWi%2Fimage.png?alt=media&amp;token=ccd6d5cf-ccd7-4773-8b27-cb2056ed9c86" alt=""><figcaption></figcaption></figure>

```ini
[output_pin probe_enable]
pin: PA7

[probe]
pin: ^!PA6  # V1: ^PA6  |  V2: ^!PA6
```

{% endtab %}

{% tab title="SKR 3" %}
Cableado con Z-Endstop:

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FXwiAWtsTl59O7vYIJ6zo%2Fimage.png?alt=media&amp;token=3882aa12-aa1f-423a-b224-01814462f85b" alt=""><figcaption></figcaption></figure>

O usando el conector PROBE:

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FPwIOVk58T0o5RH47OzI2%2Fimage.png?alt=media&amp;token=2437c0cd-f948-4a3e-9f11-a0bfc4ec4ef5" alt=""><figcaption></figcaption></figure>

```ini
[output_pin probe_enable]
pin: PE5

[probe]
pin: ^!PC13  # V1: ^PC13  |  V2: ^!PC13
```

{% endtab %}

{% tab title="MINI E3 v3.0" %}
Cableado:

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2F8OHSxv1PcnoCdya4qLN8%2Fimage.png?alt=media&amp;token=4c227ea9-c74e-4e2f-863f-529111cc1305" alt=""><figcaption></figcaption></figure>

```ini
[output_pin probe_enable]
pin: PA1

[probe]
pin: ^!PC14  # V1: ^PC14  |  V2: ^!PC14
```

{% endtab %}
{% endtabs %}

### Safe Z Homing

Es muy recomendable añadir `[safe_z_home]` para que el homing Z se realice siempre con el sensor desplegado en una posición segura:

```ini
[safe_z_home]
home_xy_position: X_CENTRO, Y_CENTRO  # Ajusta al centro de tu cama
speed: 100
z_hop: 10           # Sube Z antes de mover a la posición de home
z_hop_speed: 20
```

Sustituye `X_CENTRO, Y_CENTRO` por las coordenadas del centro de tu área de impresión (teniendo en cuenta el offset XY del sensor).

### Bed Mesh

Añade la sección `[bed_mesh]` ajustada a tu impresora:

```ini
[bed_mesh]
speed: 150
horizontal_move_z: 10
mesh_min: XMIN, YMIN    # Mínimo alcanzable por el sensor (nozzle offset incluido)
mesh_max: XMAX, YMAX    # Máximo alcanzable por el sensor
probe_count: 5, 5       # Puntos de sondeo en X e Y
mesh_pps: 2, 2
algorithm: bicubic
fade_start: 1
fade_end: 10
```

Para calcular correctamente `mesh_min` y `mesh_max` teniendo en cuenta el offset XY del sensor, consulta la [guía de sensores de nivelación](/klipper/empezamos/sensor-nivelacion).

## Comprobaciones previas — antes del primer home

Antes de lanzar ningún `G28`, verifica que el sensor funciona correctamente:

**1. Despliega el pin:**

```gcode
Probe_Deploy
```

**2. Con el pin desplegado, lanza:**

```gcode
QUERY_PROBE
```

Debe devolver `probe: open`.

**3. Recoge el pin:**

```gcode
Probe_Stow
```

**4. Activa manualmente el sensor acercando un objeto metálico al pin y lanza:**

```gcode
QUERY_PROBE
```

Debe devolver `probe: TRIGGERED`.

### Si el comportamiento es el inverso

Cambia el modificador del pin en la sección `[probe]`:

* Si tienes `^!PIN`, cámbialo a `^PIN`
* Si tienes `^PIN`, cámbialo a `^!PIN`

### Si el pin no se despliega o recoge

* Verifica el cableado físico
* Comprueba que el pin configurado en `[output_pin probe_enable]` corresponde al puerto donde está conectado el sensor
* Revisa en el log de Klipper que la sección se está cargando correctamente

### Si el estado no cambia al activar el sensor

* Verifica el cableado de la señal
* Prueba a cambiar entre pull-up y pull-down en la definición del pin
* En la V2, asegúrate de que el pin tiene suficiente pull-up — considera usar otro pin o añadir resistencia pull-up externa

## Calibración del Z-Offset

Una vez que las comprobaciones son correctas, calibra el z-offset:

```gcode
G28
PROBE_CALIBRATE
```

Sigue el asistente para ajustar la altura del nozzle con el papel. Al terminar, acepta y guarda:

```gcode
SAVE_CONFIG
```

Más información en la [guía de sensores de nivelación → ajuste del z-offset](/klipper/empezamos/sensor-nivelacion#ajuste-del-z-offset-usando-papel-o-galga).


# Nivelación Gantry (Z-TILT)

Viene siendo muy común que nuestras impresoras tengan dos o más motores en el eje Z dependiendo del tipo de máquina.

El **disponer de varios motores en el eje Z nos permite**, y dependiendo del tipo de máquina:

* **poder sustentar un eje X más pesado**, sobre todo cuando usamos extrusión directa en máquinas cartesianas, sin que este “caiga” normalmente en el lado donde no disponga de un punto de anclaje a la cinemática
* poder **sustentar una cama más pesada** en el caso, normalmente, de máquinas CoreXY
* si disponemos de **drivers independientes nos permiten alinear de forma automática** nuestro eje X o cama dependiendo de nuestro tipo de máquina.

## En que consiste el Z-TILT en Klipper

**Z-TILT básicamente es un proceso que nos ayuda a alinear nuestros motores de Z con respecto a nuestro eje/gantry X (cartesiana) o XY (CoreXY)**. Con esto **aseguramos que tenemos siempre alineado nuestro Z perfectamente y de forma precisa y automática**.

Al **usar un sensor de nivelación**, aparte de **precisión**, vamos a poder aprovechar este para el nivelado manual de nuestra cama, el ajuste de nuestro gantry/eje y el mallado de nuestra cama… con lo que tenemos casi **automatizado completamente la nivelación de nuestra máquina**.

{% embed url="<https://www.youtube.com/watch?v=Ptus5hQsJ1I>" %}

Para ello, Klipper cuenta con las macros:

* [**Z\_TILT\_ADJUST**](https://www.klipper3d.org/G-Codes.html#z_tilt), para máquinas que tengan 2 o 3 motores en el eje Z
* **QUAD\_GANTRY\_LEVEL**, en el caso de que dispongamos de 4 motores en Z

## Requerimientos aconsejables para disponer de Z-TILT:

* obviamente, **tener dos o más motores en nuestro eje Z**
* que **cada uno de estos motores se encuentre conectado a un driver independiente**, esto nos va a permitir que Klipper pueda corregir de forma independiente sus alturas
* un **sensor de nivelación**, es el método más sencillo y fiable para realizar estas alineaciones

## Configuración:

Configurar nuestro **Klipper** para Z-TILT es muy sencillo y básicamente tendremos que configurar una nueva sección [\[z\_tilt\]](https://www.klipper3d.org/Config_Reference.html#z_tilt), o [\[quad\_gantry\_level\]](https://www.klipper3d.org/Config_Reference.html#quad_gantry_level) dependiendo de nuestra máquina, en nuestros ficheros de configuración.

{% hint style="warning" %}
Tal como hemos comentado **para que funcione Z-TILT requerimos que nuestros motores en Z estén en drivers separados**. Para ello como **requerimiento previo estos han de estar definidos correctamente en nuestro fichero de configuración**, ejemplo de configuración en una máquina con 3 motores en Z (en la que solamente hacemos referencia a las secciones necesarias):

* definición de drivers por eje:

```django
[tmc2209 stepper_z]
... # your configuration
[tmc2209 stepper_z1]
... # your configuration 
[tmc2209 stepper_z2]
... # your configuration
```

* definición de ejes Z

```django
[stepper_z] 
... # your configuration
[stepper_z1] 
... # your configuration
[stepper_z2] 
... # your configuration
```

{% endhint %}

### \[z-tilt]

En el siguiente ejemplo vemos una sección \[z-tilt] para un triple Z

```django
# 3DWORK Z-TILT https://klipper.3dwork.io/klipper/empezamos/nivelacion-gantry-z-tilt
[z_tilt]
z_positions:
	0,0
	150,300
	300,0

points:
	60,60
	185,270
	260,60
		
speed: 50
horizontal_move_z: 12
retries: 10
retry_tolerance: 0.0125
```

Valores importantes de nuestra sección **\[z-tilt]**:

* **z\_positions**, indicarán las coordenadas donde se encuentran nuestros puntos de unión entre el eje Z y nuestra cama. Las coordenadas XY son con respecto a nuestro nozzle.

{% hint style="danger" %}
Es **muy importante el orden de estos puntos ya que hacen referencia a la asignación de cada stepper** siendo... **stepper\_z para la primera coordenada, stepper\_z1 para la segunda coordenada, stepper\_z2 para la tercera coordenada, etc**...\
En el siguiente ejemplo podéis ver visualmente para un Z-TILT de dos puntos:

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/jKENTOnZXjPlbe61I392/image.png)\
\ <mark style="color:orange;">Este orden de coordenadas es muy importante ya que en el caso de ponerlas de forma incorrecta el sistema no sabrá corregir bien las desviaciones y fallar o incluso provocar algún daño mecánico durante el proceso.</mark>
{% endhint %}

* **points**, al igual que los valores anteriores, estos hacen referencia a las coordenadas XY con respecto a nuestro nozzle de nuevo, que el **comando Z\_TILT\_ADJUST/QUAD\_GANTRY\_LEVEL usará para los sondeos/medidas**.

{% hint style="danger" %}
**Nos aseguraremos que las coordenadas tienen en cuenta los offsets de nuestro sensor y este queda lo más cercano al punto de unión del eje Z con nuestra cama en cada caso.**
{% endhint %}

* **speed,** será la velocidad en mm/s de los movimientos de nuestros ejes durante la calibración... si no se especifica utilizará 50 mm/s
* **horizontal\_move\_z**, la distancia que Z subirá al realizar el traslado entre puntos… por defecto 5 mm aunque podemos ajustarla en caso necesario a nuestras necesidades
* **retries**, ajustaremos el número de reintentos que queremos hacer durante el proceso en el caso de que los ajustes no cumplan con la tolerancia definida
* **retry\_tolerance**, en el caso de que ajustemos **retries** a un número mayor a 0 este será el valor de tolerancia para dar por bueno el ajuste de un eje.

{% hint style="info" %}
**Tolerancia Z-Tilt:**

En ocasiones podemos ver configuraciones de toleranca entre puntos muy pequeñas algo que puede ocasionar ciertos problemas y normalmente no llegan a transformarse en una gran ventaja en la calidad final de nuestras impresiones.

Teniendo en cuenta que 1 step = 0.0125, para un desarrollo de motor y cinemática media de una impresora 3D, podriamos decir que **un valor de tolerancia de 0.0125 a 0.03 sería aceptable** y está en cada uno bajarlo o subirlo más.
{% endhint %}

### \[quad\_gantry\_level]

En este caso disponemos de algunos cambios en los valores a definir:

* **gantry\_corners**, en lugar de z\_positions, en este caso en lugar de definir todos los puntos como se hacía en el caso anterior tan solo **definiremos la esquina inicial (Z) y la opuesta (Z2)**
* **max\_adjust**, esta propiedad es exclusiva de quad\_gantry\_level, es un límite de seguridad que si el ajuste es mayor que este valor el proceso se abortará

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/k0VW8Mg8XTj9tLl1eFwS/image.png)

## Proceso de alineado Z-TILT

Con todo esto configurado pasaremos a tener una **nueva macro de sistema llamada** [**Z\_TILT\_ADJUST**](https://www.klipper3d.org/G-Codes.html#z_tilt) **(o QUAD\_GANTRY\_LEVEL dependiendo de nuestra configuración).**

* **Home de nuestra impresora con un G28** o desde los controles de nuestra UI
* Es **aconsejable realizar un precalentado de nuestra cama y hotend**. En el caso de la cama a la temperatura normal de impresión y para el hotend podemos usar una temperatura de entre 140-170º

{% hint style="info" %}
Suele ser aconsejable realizar un **test de precisión de nuestro sensor con PROBE\_ACCURACY**, nos fijaremos que **la desviación de las lecturas no sea de más de 0.003mm**. De ser más altas de ese valor esperaremos unos minutos para repetir el test hasta que estemos dentro de rango.
{% endhint %}

* **Lanzaremos el comando** [**Z\_TILT\_ADJUST**](https://www.klipper3d.org/G-Codes.html#z_tilt) **o QUAD\_GANTRY\_LEVEL** que realizará el proceso de sondeo y ajuste necesario

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/SptYzTFrATHExQWJi1cx/telegram-cloud-photo-size-4-5920079653068978967-x.jpg" alt=""><figcaption></figcaption></figure>

* **Podemos incorporar** [**Z\_TILT\_ADJUST**](https://www.klipper3d.org/G-Codes.html#z_tilt) **o QUAD\_GANTRY\_LEVEL a nuestra rutina de inicio** de impresión para asegurar siempre un perfecto alineado, idealmente incluyendo este entre el precalentado/homing y el mallado de cama en el caso de que lo hagamos

{% hint style="info" %}
En el caso de ser **nuestra primer alineado usando Z-TILT, o en caso de ajuste de algún componente de nuestra cinemática, es aconsejable**:

* realizar el proceso de nivelación de cama manual con ayuda de nuestro sensor explicado [**aquí**](/klipper/empezamos/nivelacion-cama-manual).
* volveremos a realizar el proceso de Z-TILT
* realizaremos estos dos pasos en bucle hasta que apenas sean necesarios ajustes dando por buena la alineación de cama y gantry
  {% endhint %}

{% hint style="success" %}
**Cuando es aconsejable realizar el Z-TILT?**

* si hemos realizado algún ajuste manual en nuestro sistema en la cinemática, en especial si hemos manipulado alguna parte del eje Z
* si hemos variado la nivelación manual de nuestra cama
  {% endhint %}

{% hint style="warning" %}
A tener en cuenta en caso de **máquinas con cerramiento calefactado**:

* realizaremos primero un **home de nuestra impresora con G28** o desde los controles de nuestra UI
* Nos aseguraremos que nuestro **cerramiento esté estable a la temperatura objetivo y el hotend a la temperatura normal de impresión**.
* Realizaremos un **test de precisión de nuestro sensor con PROBE\_ACCURACY**, nos fijaremos que **la desviación de las lecturas no sea de más de 0.003mm**. De ser más altas de ese valor esperaremos unos minutos para repetir el test hasta que estemos dentro de rango.
* Una vez las **lecturas del sensor sean estable lanzaremos el comando** [**Z\_TILT\_ADJUST**](https://www.klipper3d.org/G-Codes.html#z_tilt) **o QUAD\_GANTRY\_LEVEL normalmente**

En el caso que tengamos problemas con el proceso:

* revisaremos nuestra cinemática para asegurarnos que no tengamos un problema en ella
* revisaremos el orden de la definición de los Z ya que, tal como explicamos en ese punto, si ponemos incorrectamente el orden el proceso no podrá corregir correctamente las desviaciones... es más probablemente las agrave ya que intentara corregir en un eje que no es el correcto por su configuración incorrecta.
* realizaremos un FIRMWARE\_RESTART y realizaremos un nivelado manual de nuestra cama
  {% endhint %}


# Malla nivelación de cama

Configuración completa de la malla de nivelación de cama en Klipper: bed\_mesh, mallado adaptativo nativo, perfiles y compensación física.

Ahora que ya tenemos nuestra cama correctamente nivelada es el turno de hacer una malla con medidas de nuestra cama para poder ajustar/minimizar cualquier desviación de la misma y que nuestras primeras capas sean siempre lo más perfectas posible.

{% hint style="warning" %}
Es muy importante que, tal como explicamos en el punto anterior de [nivelación manual de cama](/klipper/empezamos/nivelacion-cama-manual) tengamos hecho la nivelación explicada así como el [Z-Tilt](/klipper/empezamos/nivelacion-gantry-z-tilt) en el caso que tengamos varios motores en Z independientes.
{% endhint %}

Podéis encontrar la documentación oficial de **Klipper**:

{% embed url="<https://www.klipper3d.org/Bed_Mesh.html>" %}

## Configuración del mallado de cama

Para poder realizar un mallado de nivelación de nuestra cama es fundamental tener en cuenta que antes deberemos de definir las características.

Dentro de nuestro **printer.cfg crearemos**, si no la tenemos ya, la s**ección \[bed\_mesh]** a continuación os vamos a mostrar un ejemplo:

{% tabs %}
{% tab title="Ejemplo" %}

```django
[bed_mesh]
speed: 300
horizontal_move_z: 10

mesh_min: 40, 40
mesh_max: 210,210

fade_start: 0.6
fade_end: 10.0
probe_count: 5,5
algorithm: bicubic
```

En la configuración de **\[bed\_mesh]** de ejemplo podremos encontrar los siguientes parámetros importantes:

* **speed**, creo que es autoexplicativo y hace referencia a la velocidad de nuestra máquina durante el proceso
* **mesh\_min** y **mesh\_max** son las coordenadas de inicio y final del área donde realizaremos nuestro mallado con respecto a nuestro sensor... **tenemos que tener en cuenta que estos puntos de inicio y final permitan que nuestro sensor pueda llegar a hacer las medidas** si no nos indicará problemas al aplicar el proceso de mallado indicando, por ejemplo, que nos hemos salido de las coordenadas

{% hint style="success" %}
Tenemos una pequeña **macro** que, en base a la configuración de nuestro cfg y el margen que queramos añadir de seguridad, **nos va a sugerir los valores mesh\_min y mesh\_max de una forma sencilla**:

{% code title="" %}

```django
# More info https://3dwork.gitbook.io/3dwork.io/klipper/empezamos/malla-nivelacion-de-cama-klipper
### CALCULATE_BED_MESH - Helps to calculate bed mesh boundaries automatically

[gcode_macro CALCULATE_BED_MESH]
description: Calculate bed_mesh boundaries automatically based on your bltouch/probe config
gcode:
  {% set BED_MESH_MARGIN = params.BED_MESH_MARGIN|default(10)|float %}
  # Get Printer built volume dimensions
  {% set X_MAX = printer.toolhead.axis_maximum.x|default(230)|float %}
  {% set Y_MAX = printer.toolhead.axis_maximum.y|default(230)|float %}
  # Get Nothing/BLTouch/Probe X and Y offsets
  {% set X_OFFSET = 0.0 |float %}
  {% set Y_OFFSET = 0.0 |float %}
  #Get BLTouch/Probe X and Y offsets
  {% if printer.configfile.config["bltouch"] is defined %}
    {% set X_OFFSET = (printer.configfile.settings.bltouch.x_offset if printer.configfile.settings.bltouch.x_offset is defined else X_OFFSET)|float %}
    {% set Y_OFFSET = (printer.configfile.settings.bltouch.y_offset if printer.configfile.settings.bltouch.y_offset is defined else Y_OFFSET)|float %}
  {% endif %}
  {% if printer.configfile.config["probe"] is defined %}
    {% set X_OFFSET = (printer.configfile.config.probe.x_offset if printer.configfile.config.probe.x_offset is defined else X_OFFSET)|float %}
    {% set Y_OFFSET = (printer.configfile.config.probe.y_offset if printer.configfile.config.probe.y_offset is defined else Y_OFFSET)|float %}
  {% endif %}

  # bed_mesh boundaries calculations
  # bed_mesh_min and bed_mesh_max
  {% set BED_MESH_MIN_X = BED_MESH_MARGIN if X_OFFSET <= 0.0 else X_OFFSET + BED_MESH_MARGIN |float %}
  {% set BED_MESH_MIN_Y = BED_MESH_MARGIN if Y_OFFSET <= 0.0 else Y_OFFSET + BED_MESH_MARGIN |float %}
  {% set BED_MESH_MAX_X = X_MAX - (X_OFFSET)|abs - BED_MESH_MARGIN if X_OFFSET <= 0.0 else X_MAX - BED_MESH_MARGIN |float %}
  {% set BED_MESH_MAX_Y = Y_MAX - (Y_OFFSET)|abs - BED_MESH_MARGIN if Y_OFFSET <= 0.0 else Y_MAX - BED_MESH_MARGIN |float %}

  # Print values
  {action_respond_info("BED_MESH_MARGIN : %f" % (BED_MESH_MARGIN))}
  {action_respond_info("X_MAX           : %f" % (X_MAX))}
  {action_respond_info("Y_MAX           : %f" % (Y_MAX))}
  {action_respond_info("X_OFFSET        : %f" % (X_OFFSET))}
  {action_respond_info("Y_OFFSET        : %f" % (Y_OFFSET))}
  {action_respond_info("BED_MESH_MIN_X  : %f" % (BED_MESH_MIN_X))}
  {action_respond_info("BED_MESH_MIN_Y  : %f" % (BED_MESH_MIN_Y))}
  {action_respond_info("BED_MESH_MAX_X  : %f" % (BED_MESH_MAX_X))}
  {action_respond_info("BED_MESH_MAX_Y  : %f" % (BED_MESH_MAX_Y))}
  {action_respond_info("--- VALUES TO ADD OR UPDATE TO OUR BED_MESH VALUES ---")}
  {action_respond_info("--- VALORES PARA AGREGAR O ACTUALIZAR EN NUESTRA SECCIÓN BED_MESH ---")}
  {action_respond_info("mesh_max: %s,%s" % (BED_MESH_MAX_X,BED_MESH_MAX_Y))}
  {action_respond_info("mesh_min: %s,%s" % (BED_MESH_MIN_X,BED_MESH_MIN_Y))}
```

{% endcode %}

Para lanzar la macro iremos a nuestra UI y podremos lanzarla **ajustando el valor BED\_MESH\_MARGIN que es un margen de seguridad a aplicar alrededor de nuestra área de mallado**, por defecto usará 10mm:

<img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/qKXRZHEf7yKnuiCx5Ys2/image.png" alt="" data-size="original">

Si todo ha ido de forma correcta veremos en la consola información obtenida de nuestra configuración (recuadro naranja), los cálculos de coordenadas (recuadro rojo) y la sugerencia de configuración para nuestro \[bed\_mesh] en concreto los valores mesh\_min y mesh\_max (recuadro verde):

<img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/8FAu7Ai5EhwkY08ar3Di/image.png" alt="" data-size="original">

Los valores sugeridos los podremos poner en nuestro printer.cfg en la sección \[bed\_mesh]:

{% code title="Ejemplo de modificación de valores en base a lo obtenido de la macro:" %}

```django
[bed_mesh]
### mesh_min: 10, 25
mesh_min: 10,32.0 # From CALCULATE_BED_MESH macro
### mesh_max: 390, 405
mesh_max: 381.5,410.0 # From CALCULATE_BED_MESH macro
probe_count: 7, 7
algorithm: bicubic
speed: 100
```

{% endcode %}
{% endhint %}

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/R2n3ETPgiC3HOPFj4mQ2/image.png)

* **probe\_count**, es el que indicará el número de sondeos en cada eje... normalmente y dependiendo del estado de nuestra cama 5,5 (25 puntos) suelen ser más que suficientes
* **fade\_start** **fade\_end**, estos parámetros muy útiles permiten ajustar la desviación inicial de nuestra cama hasta una altura para asegurar una correcta dimensionalidad de nuestras piezas.
  * **fade\_start**, por defecto 1 es la altura de Z a partir de la cual empezaremos la corrección
  * **fade\_end**, por defecto 0 y es la altura de Z que usará para completar las correcciones, normalmente se suele usar 10

![Ejemplo visual de las correcciones fade](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/I9nx5hkDt9K9eFKfTbib/image.png)

{% hint style="warning" %}
**Precauciones con el uso de fade\_start y fade\_end!!!**\
Todo y que estas configuraciones pueden permitir mejorar la dimensionalidad correcta en nuestras impresiones configuraciones agresivas pueden provocar artefactos como la delaminación (fallos de adhesión entre capas), en especial cuando la distancia entre el inicio y final de las correcciones es muy cercana y no permite realizar unas transiciones entre capas adecuadas para adaptar/compensar las desviaciones o ajustes necesarios.
{% endhint %}

* **faulty\_regions**, es otra función interesante en el caso de que tengamos zonas en las que nuestro sensor falle o reporte medidas incorrectas como camas con imanes integrados o PEI que con su campo magnético pueden afectar a las lecturas de algunos sensores.\
  Esta función puede ayudar a compensar este efecto realizando un sondeo alrededor del punto para obtener valores de compensación en ese punto.\
  La imagen siguiente puede ayudar a entender mejor su funcionamiento, así como el ejemplo de configuración.

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/Nz1cVwg7wSVO6IZDaAUc/image.png)

```django
[bed_mesh]
speed: 120
horizontal_move_z: 5
mesh_min: 35, 6
mesh_max: 240, 198
probe_count: 5, 3
faulty_region_1_min: 130.0, 0.0
faulty_region_1_max: 145.0, 40.0
faulty_region_2_min: 225.0, 0.0
faulty_region_2_max: 250.0, 25.0
faulty_region_3_min: 165.0, 95.0
faulty_region_3_max: 205.0, 110.0
faulty_region_4_min: 30.0, 170.0
faulty_region_4_max: 45.0, 210.0
```

{% endtab %}

{% tab title="Definición \[bed\_mesh]" %}

```
 rectangular bed, probe_count = 3, 3:
             x---x---x (max_point)
             |
             x---x---x
                     |
 (min_point) x---x---x

 round bed, round_probe_count = 5, bed_radius = r:
                 x (0, r) end
               /
             x---x---x
                       \
 (-r, 0) x---x---x---x---x (r, 0)
           \
             x---x---x
                   /
                 x  (0, -r) start
```

```django
[bed_mesh]
#speed: 50
#   The speed (in mm/s) of non-probing moves during the calibration.
#   The default is 50.
#horizontal_move_z: 5
#   The height (in mm) that the head should be commanded to move to
#   just prior to starting a probe operation. The default is 5.
#mesh_radius:
#   Defines the radius of the mesh to probe for round beds. Note that
#   the radius is relative to the coordinate specified by the
#   mesh_origin option. This parameter must be provided for round beds
#   and omitted for rectangular beds.
#mesh_origin:
#   Defines the center X, Y coordinate of the mesh for round beds. This
#   coordinate is relative to the probe's location. It may be useful
#   to adjust the mesh_origin in an effort to maximize the size of the
#   mesh radius. Default is 0, 0. This parameter must be omitted for
#   rectangular beds.
#mesh_min:
#   Defines the minimum X, Y coordinate of the mesh for rectangular
#   beds. This coordinate is relative to the probe's location. This
#   will be the first point probed, nearest to the origin. This
#   parameter must be provided for rectangular beds.
#mesh_max:
#   Defines the maximum X, Y coordinate of the mesh for rectangular
#   beds. Adheres to the same principle as mesh_min, however this will
#   be the furthest point probed from the bed's origin. This parameter
#   must be provided for rectangular beds.
#probe_count: 3, 3
#   For rectangular beds, this is a comma separate pair of integer
#   values X, Y defining the number of points to probe along each
#   axis. A single value is also valid, in which case that value will
#   be applied to both axes. Default is 3, 3.
#round_probe_count: 5
#   For round beds, this integer value defines the maximum number of
#   points to probe along each axis. This value must be an odd number.
#   Default is 5.
#fade_start: 1.0
#   The gcode z position in which to start phasing out z-adjustment
#   when fade is enabled. Default is 1.0.
#fade_end: 0.0
#   The gcode z position in which phasing out completes. When set to a
#   value below fade_start, fade is disabled. It should be noted that
#   fade may add unwanted scaling along the z-axis of a print. If a
#   user wishes to enable fade, a value of 10.0 is recommended.
#   Default is 0.0, which disables fade.
#fade_target:
#   The z position in which fade should converge. When this value is
#   set to a non-zero value it must be within the range of z-values in
#   the mesh. Users that wish to converge to the z homing position
#   should set this to 0. Default is the average z value of the mesh.
#split_delta_z: .025
#   The amount of Z difference (in mm) along a move that will trigger
#   a split. Default is .025.
#move_check_distance: 5.0
#   The distance (in mm) along a move to check for split_delta_z.
#   This is also the minimum length that a move can be split. Default
#   is 5.0.
#mesh_pps: 2, 2
#   A comma separated pair of integers X, Y defining the number of
#   points per segment to interpolate in the mesh along each axis. A
#   "segment" can be defined as the space between each probed point.
#   The user may enter a single value which will be applied to both
#   axes. Default is 2, 2.
#algorithm: lagrange
#   The interpolation algorithm to use. May be either "lagrange" or
#   "bicubic". This option will not affect 3x3 grids, which are forced
#   to use lagrange sampling. Default is lagrange.
#bicubic_tension: .2
#   When using the bicubic algorithm the tension parameter above may
#   be applied to change the amount of slope interpolated. Larger
#   numbers will increase the amount of slope, which results in more
#   curvature in the mesh. Default is .2.
#zero_reference_position:
#   An optional X,Y coordinate that specifies the location on the bed
#   where Z = 0.  When this option is specified the mesh will be offset
#   so that zero Z adjustment occurs at this location.  The default is
#   no zero reference.
#relative_reference_index:
#   **DEPRECATED, use the "zero_reference_position" option**
#   The legacy option superceded by the "zero reference position".
#   Rather than a coordinate this option takes an integer "index" that
#   refers to the location of one of the generated points. It is recommended
#   to use the "zero_reference_position" instead of this option for new
#   configurations. The default is no relative reference index.
#faulty_region_1_min:
#faulty_region_1_max:
#   Optional points that define a faulty region.  See docs/Bed_Mesh.md
#   for details on faulty regions.  Up to 99 faulty regions may be added.
#   By default no faulty regions are set.
```

{% endtab %}
{% endtabs %}

## Mallado de cama con sensor

Lo más aconsejable por precisión y comodidad es el uso de un sensor de nivelación que nos ayude desde el proceso.

Podemos lanzar el proceso de calibración desde las opciones de vuestra UI Mainsail o Fluidd o por consola lanzando **BED\_MESH\_CALIBRATE**, podemos ejecutar **BED\_*****MESH\_CLEAR** para limpiar los valores, una vez efectuado el mallado podemos guardarlo con **SAVE\_*****CONFIG**.

Un valor añadido de la UI es que tiene un visualizador que nos permite ver el estado de nuestro mallado y por ende nuestra cama.

![](https://docs.vorondesign.com/tuning/images/heightmap.png)

{% hint style="info" %}
**IMPORTANTE!!! Habilitar/Cargar un perfil de malla de nivelación:**

**Antiguamente Klipper cargaba por defecto la malla default al iniciarse, actualmente no es así. Si queréis que vuestra malla sea efectiva durante vuestras impresiones tenemos tres opciones.**

**Cargar la malla de forma manual**, es algo engorroso ya que podemos olvidarnos.

**Cargar la malla en nuestra rutina de inicio de impresión en la macro que usemos**, START\_PRINT o el nombre que usemos, o en el gcode de inicio de nuestro laminador aunque os aconsejamos siempre usar la macro ya que es la forma más efectiva... tan solo tendremos que añadir BED\_MESH\_PROFILE LOAD=default antes de comenzar la impresión.

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
```

En este caso adaptaremos el nombre de malla si usamos un nombre diferente, en el caso que usemos diferentes mallas deberemos de tenerlo en cuenta para cargar por el método que sea la correcta antes de iniciar la impresión.
{% endhint %}

## Mallado de cama adaptativo <a href="#bed-mesh-switchwire" id="bed-mesh-switchwire"></a>

Desde enero de 2024, Klipper incluye mallado adaptativo de forma nativa. Ya no necesitas macros externas como KAMP para esta funcionalidad.

{% hint style="warning" %}
Esta función requiere Klipper actualizado (desde enero 2024). Si tienes una máquina con Klipper personalizado del fabricante (Sonic Pad, QIDI, Creality K1, etc.) que no admite actualizaciones, usa la alternativa con KAMP o el script de mallado por área del [3Dwork Klipper Bundle](https://github.com/alienboyxp/gitbook_es_klipper_3dwork_io/blob/main/klipper/empezamos/3dwork-klipper-bundle.md).
{% endhint %}

El mallado adaptativo básicamente nos permite realizar el proceso de sondeo de forma dinámica en la zona donde nuestra pieza va a imprimirse, mejorando de esta forma la efectividad del mallado y sus correcciones.

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2Fz5flOPvpAOvcIHbPFeiC%2Fimage.png?alt=media&amp;token=97cc81bd-d79a-49db-bb19-e56ff4efdcef" alt=""><figcaption></figcaption></figure>

El área de sondeo adaptativo se va a definir dependiendo del área de impresión de nuestras piezas, incluyendo un margen a estas que podremos definir en nuestra configuración. El siguiente paso, una vez definida de forma automática esta área de sondeo, el propio sistema va a escalar el número de puntos a sondear dependiendo de la proporción entre el área normal de sondeo y el área adaptativa calculada para los objetos a imprimir.

{% hint style="warning" %}
Normalmente dada la naturaleza del mallado adaptativo no se suele aprovechar entre impresiones por lo que se genera un nuevo mallado en cada impresión.\
Es importante que el mallado adaptativo esta especialmente pensado para máquinas que pueden sondear toda la superficie de impresión donde tendremos unos mejores resultados.
{% endhint %}

Para usar el mallado adaptativo nativo de Klipper va a ser muy sencillo porque básicamente hemos de activar el procesado de objetos de Klipper :

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

```
[exclude_object]
```

{% endcode %}

También es necesario el procesado de gcodes en Moonraker:

{% code title="moonraker.conf" %}

```
[file_manager]
enable_object_processing: True
```

{% endcode %}

Deberemos asegurarnos que nuestro laminador tenga habilitada el etiquetado de objetos:

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

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2Fy7q6ljVsxwUA9syQRQGg%2Fimage.png?alt=media&amp;token=99e50221-d726-45a0-8caa-534a68c3666e" alt=""><figcaption></figcaption></figure>
{% endtab %}

{% tab title="PrusaSlicer" %}

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FWuyq4A1QVgYS48Dzj97r%2Fimage.png?alt=media&amp;token=93ae0822-9088-4fdc-a08c-466fa38376b5" alt=""><figcaption></figcaption></figure>
{% endtab %}
{% endtabs %}

Por último añadiremos la llamada a la macro BED\_MESH\_CALIBRATE dentro de nuestra macro START\_PRINT (o nombre que usemos en vuestro caso), o en nuestro gcode de inicio si lo tenemos fuera de esta:

{% code title="printer.cfg (inside your START\_PRINT macro)" %}

```
...
BED_MESH_CALIBRATE ADAPTIVE=1 ADAPTIVE_MARGIN=5
...
```

{% endcode %}

Como parámetros en BED\_MESH\_CALIBRATE para utilizar el mallado adaptativo usaremos:

* ADAPTIVE=1 para habilitarlo
* ADAPTIVE\_MARGIN=5 donde cambiaremos el 5 por el margen que queramos

Tenéis más información y detalle como siempre en la [documentación oficial de Klipper](https://www.klipper3d.org/Bed_Mesh.html#adaptive-meshes).

## Mallado de cama manual <a href="#bed-mesh-switchwire" id="bed-mesh-switchwire"></a>

También tienes la opción de realizar un mallado de tu cama sin sensor, para ello podremos lanzar [**`BED_MESH_CALIBRATE METHOD=manual`**](https://www.klipper3d.org/G-Codes.html#bed_mesh_calibrate) Klipper nos irá dando información durante el proceso:

* Haremos un home de la máquina con `G28`
* Iniciaremos la calibración lanzando el comando `BED_MESH_CALIBRATE METHOD=manual`
* Mediante comandos iremos bajando lentamente el nozzle hacia la cama usando **`TESTZ Z=-1`** hasta que estemos cerca para en ese momento realizar movimientos más pequeños usando **`TESTZ Z=-.01`** o incluso menos hasta que nuestro nozzle roce con el papel.\
  Podemos alternar el **`TESTZ`** con valores positivos/negativos y mayores/menores hasta que tengamos nivelado a nuestro gusto en ese momento lanzaremos un ***`ACCEPT`*** y el asistente irá al siguiente punto de sondeo
* Al finalizar el sondeo haremos un `SAVE_CONFIG` que nos guardará la malla "default" o realizaremos un `BED_MESH_PROFILE SAVE="manual"` y un `SAVE_CONFIG` para guardar la malla con el nombre "manual"

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

**Para evitar&#x20;**<mark style="color:red;">**errores de movimientos fuera de rango**</mark>**&#x20;en el proceso de z-offset u otras nivelaciones hemos de ajustar el position\_min de nuestro stepper\_z a un valor adecuado y con cierto margen para que nos permita esos movimientos.**

```django
[stepper_z]
...
position_min: -5
...
```

{% endhint %}

Para cargar el perfil creado manual deberéis aseguraros que vuestra macro o gcode de inicio de vuestro laminador lance la macro **`BED_MESH_PROFILE LOAD=manual` .**

A continuación os facilitamos una macro para poder lanzar el proceso de forma cómoda:

```django
[gcode_macro G29_MANUAL]
description: Realiza la malla de forma manual
gcode:
        BED_MESH_CLEAR
        G28 XY
        G28 Z
        BED_MESH_CALIBRATE METHOD=manual
        BED_MESH_PROFILE SAVE="manual"
        SAVE_CONFIG
```

## zero\_reference\_position — referencia Z de la malla

`zero_reference_position` define el punto de la cama donde Z = 0. La malla se ajusta para que la compensación sea cero en ese punto, lo que garantiza que el Z-offset siga siendo válido en toda la cama.

```ini
[bed_mesh]
...
zero_reference_position: 125, 125   # Centro de la cama (ajusta a tu máquina)
```

{% hint style="info" %}
Si haces home en el centro de la cama o usas un sensor tipo Beacon/Eddy que calibra el Z-offset en un punto fijo, configura `zero_reference_position` en ese mismo punto. Así evitas que la compensación de malla desplace la Z-offset en la zona de home.

La opción anterior `relative_reference_index` está **deprecada** — si la tienes en tu cfg, sustitúyela por `zero_reference_position`.
{% endhint %}

***

## Resolución de problemas

| Síntoma                                                 | Causa probable                                                                      | Solución                                                                                             |
| ------------------------------------------------------- | ----------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- |
| El mallado sondea toda la cama aunque uses ADAPTIVE=1   | `[exclude_object]` no está activo o el laminador no etiqueta objetos                | Activa `[exclude_object]` en printer.cfg y `enable_object_processing: True` en moonraker.conf        |
| Primera capa varía mucho de impresión a impresión       | La malla no se carga en cada impresión                                              | Añade `BED_MESH_CALIBRATE ADAPTIVE=1` en `PRINT_START` en lugar de cargar un perfil guardado         |
| El mallado adaptativo usa menos puntos de los esperados | Objeto muy pequeño → la escala reduce el probe\_count                               | Normal — el sistema escala proporcionalmente. Aumenta `probe_count` base si necesitas más resolución |
| Error "move out of range" al iniciar el mallado         | `mesh_min`/`mesh_max` fuera de los límites de la impresora con el offset del sensor | Usa la macro `CALCULATE_BED_MESH` para calcular los valores correctos                                |
| La malla empeora entre capas (delaminación)             | `fade_end` demasiado bajo o `fade_start` y `fade_end` muy próximos                  | Usa `fade_start: 1` y `fade_end: 10` como mínimo                                                     |
| Puntos erróneos en zonas con imanes del PEI             | Interferencia magnética con el sensor inductivo                                     | Configura `faulty_regions` para esas zonas                                                           |

## Compensación física de cama

En ocasiones nos podemos encontrar con que nuestra plataforma de impresión tenga unas desviaciones bastante grandes, siempre entendiendo que nuestras mediciones fueron fiables, y el sistema de compensación de malla del sistema puede tener problemas para compensar estas.

Un método tradicional ha sido la de usar cinta de aluminio cortada en secciones para intentar compensar estas desviaciones... y vuelvo a recalcar... en aquellos casos en los que tengamos unas medidas fiables de nuestro sensor y no tengamos otra forma alternativa de compensar estas desviaciones

{% columns %}
{% column %}

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2F1VdK1tJWPbLaxDV7Bnfq%2Fimage.png?alt=media&amp;token=a53c4896-4a0d-4e6f-ab50-e1f9e80dc6cb" alt=""><figcaption></figcaption></figure>
{% endcolumn %}

{% column %}

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2F0IDXTHPGTiQcSnWwC8yG%2Fimage.png?alt=media&amp;token=17f960d3-bf4d-4610-b761-e9302134104b" alt=""><figcaption></figcaption></figure>
{% endcolumn %}
{% endcolumns %}

En las anteriores imágenes de ejemplo podemos ver la plataforma de impresión de una impresora y como utilizando estas cintas por secciones podemos compensar estas desviaciones tal como podeis ver en las siguientes imágenes de como afectó la corrección al mallado:

{% columns %}
{% column %}

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FiCUxGAdLMExSavLOjT4b%2Fimage.png?alt=media&amp;token=3dbb32fe-dd1d-4e0f-9f0b-f21a27c47a9f" alt=""><figcaption></figcaption></figure>
{% endcolumn %}

{% column %}

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2F08V7ok6mWELEOxuHhRMq%2Fimage.png?alt=media&amp;token=ae1e01cb-0469-489e-91a2-339c869b15e1" alt=""><figcaption></figcaption></figure>
{% endcolumn %}
{% endcolumns %}

Siempre que el número de capas de cinta de aluminio no sean excesivas este método no suele afectar a la eficiencia en la temperatura de la cama caliente y en ocasiones incluso puede mejorarla a distribuir un poco mejor esta.

Para poder realizar estas compensaciones hemos creado una herramienta que simplemente exportando nuestro printer.cfg va a obtener la configuración de vuestra impresora y mallado actual y con el nombre **default**, que ha de ser fiable, y introduciendo el grosor de la cinta de aluminio que vayáis a utilizar (a menor grosor mejor ajuste fino) os va a proporcionar el número de cuadrantes a cubrir con x número de capas de cinta de aluminio.

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FDbzdOL457jP4ztipZlX8%2Fimage.png?alt=media&amp;token=58fbdcc7-f39a-4340-b665-19ad40935d12" alt=""><figcaption></figcaption></figure>

Una vez cargado vuestro printer.cfg la herramienta os mostrará los datos obtenidos de esta como el tamaño de impresión XY, la matriz del mallado utilizado, y los rangos de desviaciones calculados:

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FV2eouYlUvtQDEwkoBtkd%2Fimage.png?alt=media&amp;token=bac95631-c538-4801-9f4b-75034f525bc6" alt=""><figcaption></figcaption></figure>

Por otro lado os va a sugerir el tamaño de los cuadrantes de cinta de aluminio y mostrar un mapa de cuantos colocar en cada cuadrante:

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2Feu7hDpcMtTVD74tAYHZF%2Fimage.png?alt=media&amp;token=fc5bf671-1c61-4064-9d36-2967486d6350" alt=""><figcaption></figcaption></figure>

También nos va a mostrar una estimación de como deberia quedar el mallado una vez aplicada la cinta de aluminio, es solo a modo de referencia:

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2F2kX0Uf2ID0H6HYAVvZGl%2Fimage.png?alt=media&amp;token=f0861b1e-31ef-4705-b35b-cd77cfdc8cd5" alt=""><figcaption></figcaption></figure>

Por último también disponemos de una gráfica para visualizar el estado de nuestra malla cargada así como los puntos que se tomarán de referencia (los de mayor altura) para realizar los cálculos y otra pestaña para mostrar los datos capturados de vuestra configuración:

{% columns %}
{% column %}

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2F30hVCuorrGNcwvuiQKQ8%2Fimage.png?alt=media&amp;token=2bfe172f-03d9-44f0-8173-705bc1d2b49f" alt=""><figcaption></figcaption></figure>
{% endcolumn %}

{% column %}

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FoZlWD05uqqQfv93QOQC6%2Fimage.png?alt=media&amp;token=24575590-8c9e-4a7d-9abe-ebe50c48b5c7" alt=""><figcaption></figcaption></figure>
{% endcolumn %}
{% endcolumns %}

Aunque lo ideal es que vuestra plataforma de impresión sea lo más plana posible o el sistema de nivelación compense estas desviaciones este método casero ayuda a minimizar estas desviaciones y a mejorar significativamente los resultados. Espero que os sea de ayuda como nos ha sido a nosotros en muchas ocasiones.


# Pressure Advance

Calibración completa de Pressure Advance en Klipper: qué es, cómo afecta a la impresión, métodos de test y ajuste del valor final.

**Pressure Advance** (PA) compensa el retraso entre el movimiento del cabezal y la respuesta real de la extrusión. Cuando el nozzle acelera, la presión en el interior del hotend tarda un instante en igualarse — sin PA el resultado son esquinas con falta de material al entrar y exceso al salir. Con PA bien calibrado las esquinas quedan limpias y las líneas tienen un ancho homogéneo.

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/bJQzyRPkQnLBSpUNB4BQ/image.png" alt=""><figcaption><p>Gráfica generada con <a href="https://github.com/Klipper3d/klipper/blob/master/scripts/graph_extruder.py">graph_extruder.py</a> mostrando el efecto de PA en la extrusión</p></figcaption></figure>

{% tabs %}
{% tab title="PA demasiado bajo" %}
Falta material al entrar en la esquina (zona de aceleración) y exceso al salir (zona de desaceleración). Las líneas rápidas muestran un ancho irregular.
{% endtab %}

{% tab title="PA correcto" %}
Esquinas limpias y bien definidas. Ancho de línea homogéneo tanto en zonas lentas como rápidas.
{% endtab %}

{% tab title="PA demasiado alto" %}
Exceso de material al entrar en la esquina y falta al salir. Las esquinas quedan redondeadas hacia dentro. La extrusión puede ser entrecortada.
{% endtab %}
{% endtabs %}

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/golNNt184xM9cJ8EXPfd/image.png)

{% hint style="info" %}
**Cuándo recalibrar PA:**

* Al cambiar el tipo de filamento (PLA, PETG, ABS, ASA, flexible...)
* Al cambiar de marca o incluso de color dentro del mismo material
* Si modificas la temperatura de impresión de forma significativa
* Tras cualquier cambio físico en el cabezal (nozzle, barrel, PTFE, extrusora)
* Al activar o desactivar [Input Shaper](/klipper/empezamos/input-shaper)
  {% endhint %}

{% hint style="danger" %}
Antes de calibrar PA asegúrate de tener el [extrusor correctamente calibrado](/klipper/empezamos/calibracion-extrusor-e-steps). Un e-steps incorrecto invalida el resultado del test.
{% endhint %}

## Valores de referencia por tipo de extrusor

Estos son rangos orientativos. Tu valor exacto depende de tu setup concreto.

| Tipo de extrusor                             | Rango típico PA |
| -------------------------------------------- | --------------- |
| Extrusión directa (Orbiter, BMG, Sherpa...)  | 0.02 – 0.08     |
| Extrusión directa con barrel largo o volcano | 0.05 – 0.15     |
| Bowden corto (< 200 mm)                      | 0.1 – 0.4       |
| Bowden largo (> 400 mm)                      | 0.4 – 1.0       |

Si con un PA de 1.0 no ves mejora en la calidad, probablemente el problema está en otra parte (temperatura, flujo, retracción).

***

## Cómo funciona el test

El test de PA imprime líneas a tres velocidades distintas en secuencia — lenta / rápida / lenta — y analiza las transiciones:

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/MRre2oFEWV3qIjpiUZbg/image.png" alt=""><figcaption></figcaption></figure>

| Zona                        | Qué observar                                               |
| --------------------------- | ---------------------------------------------------------- |
| **1 — Arranque lento**      | Referencia: extrusión estable sin presión                  |
| **2 — Transición a rápido** | Con PA bajo: falta material al inicio. Con PA alto: exceso |
| **3 — Zona rápida estable** | Debe ser uniforme                                          |
| **4 — Transición a lento**  | Con PA bajo: exceso al frenar. Con PA alto: falta          |
| **5 — Zona lenta final**    | Debe volver a ser uniforme como la zona 1                  |

La línea con la transición más limpia entre zonas — sin huecos ni bultos — indica el valor correcto.

***

## Métodos de calibración

### OrcaSlicer — calibración integrada (recomendado)

[OrcaSlicer](https://github.com/SoftFever/OrcaSlicer) incluye generadores de test de PA directamente en el menú de calibración, sin necesidad de instalar nada extra.

{% tabs %}
{% tab title="Test de líneas" %}
El más rápido y visual. Depende de que tus primeras capas sean buenas — asegúrate de tener bien ajustado el Z-offset antes.

1. En OrcaSlicer: **Calibration → Pressure Advance → Line Method**
2. Selecciona tu impresora y filamento
3. Elige **Direct Drive** o **Bowden** según tu setup
4. Imprime y busca la línea con el trazado más homogéneo en las tres zonas

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/FGvTR5M1IQoCCANrhv2F/orca_pa.gif" alt=""><figcaption></figcaption></figure>

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/EAS1qyisAf80gyQihRNn/image.png)

5. Lee el valor PA de esa línea y [aplícalo a tu configuración](#ajustando-el-valor-de-pa)
   {% endtab %}

{% tab title="Test de torre" %}
Más lento pero no depende de la calidad de la primera capa. Más fiable en máquinas con primera capa irregular.

1. En OrcaSlicer: **Calibration → Pressure Advance → Tower Method**
2. Selecciona tu impresora y filamento
3. Elige **Direct Drive** o **Bowden**
4. El PA incrementa 0.002 por cada 1 mm de altura (extrusión directa) o 0.02 (bowden)
5. Imprime y localiza la altura con las mejores esquinas

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/o6KZqvGn4ltufHkMzNpo/image.png)

6. Calcula el valor: `PA = altura_mm × factor` (ej: 8 mm × 0.002 = 0.016)
7. [Aplica el valor a tu configuración](#ajustando-el-valor-de-pa)
   {% endtab %}
   {% endtabs %}

### Generador online (Andrew Ellis)

Una alternativa sólida si no usas OrcaSlicer.

1. Accede al [generador de patrones PA de Ellis](https://andrewellis93.github.io/pressure_advance/pressure_advance.html)

{% hint style="warning" %}
Lee los tooltips de la página — son importantes. Si controlas la aceleración desde el laminador, asegúrate de marcar la opción de control de aceleración en perímetros externos.
{% endhint %}

2. Genera y descarga el G-code del test
3. Imprime y elige el valor más bajo entre los que parecen buenos — ante la duda, siempre el menor

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/KX5lcfIPc6gcxDe0YrsL/image.png" alt=""><figcaption><p>Ejemplo del test de Ellis: en este caso se elegiría 0.05 en lugar de 0.06 por ser el menor con buen resultado</p></figcaption></figure>

4. [Aplica el valor a tu configuración](#ajustando-el-valor-de-pa)

### Macro de test — PRESSURE\_ADVANCE\_TEST

Una macro para lanzar el test directamente desde Klipper sin salir a un laminador externo:

* Calienta cama y hotend a las temperaturas que indiques
* Hace home y sondeo de cama automáticamente
* Imprime 20 líneas incrementando el PA según los parámetros

```gcode
PRESSURE_ADVANCE_TEST BED_TEMP=65 EXTRUDER_TEMP=205 PA_START=0.01 PA_STEP=0.01 NZL=0.4
```

| Parámetro       | Descripción                           |
| --------------- | ------------------------------------- |
| `BED_TEMP`      | Temperatura objetivo de la cama       |
| `EXTRUDER_TEMP` | Temperatura del hotend                |
| `PA_START`      | Valor PA inicial (línea 1)            |
| `PA_STEP`       | Incremento por línea                  |
| `NZL`           | Diámetro del nozzle (por defecto 0.4) |

Para calcular el valor final: `PA = PA_START + (PA_STEP × número_línea)` — ej: `0.01 + (0.01 × 11) = 0.12`

Código de la macro:

{% embed url="<https://gist.github.com/LauOtero/6e11df5a5c6ef28f793720e628ec49db>" %}

### TUNING\_TOWER — método oficial Klipper

El método más básico. Usa el modelo `square_tower.stl` de Klipper y el comando `TUNING_TOWER` para variar el PA por altura durante la impresión.

1. Descarga [square\_tower.stl](https://www.klipper3d.org/prints/square_tower.stl)
2. Lamina con: 120 mm/s, 1 perímetro, 0% relleno, 0 capas superiores, ventilación máxima
3. Inicia la impresión y en cuanto empiece lanza en la consola:

{% tabs %}
{% tab title="Extrusión directa" %}

```gcode
SET_VELOCITY_LIMIT SQUARE_CORNER_VELOCITY=1 ACCEL=500
TUNING_TOWER COMMAND=SET_PRESSURE_ADVANCE PARAMETER=ADVANCE START=0 FACTOR=.005
```

{% endtab %}

{% tab title="Bowden" %}

```gcode
SET_VELOCITY_LIMIT SQUARE_CORNER_VELOCITY=1 ACCEL=500
TUNING_TOWER COMMAND=SET_PRESSURE_ADVANCE PARAMETER=ADVANCE START=0 FACTOR=.020
```

{% endtab %}
{% endtabs %}

{% hint style="warning" %}

* Puedes parar la impresión en cuanto veas que las esquinas empiezan a degradarse
* Algunos gcodes de inicio pueden resetear el TUNING\_TOWER — en ese caso añade el comando directamente al gcode de inicio temporalmente
* `TUNING_TOWER` ajusta valores por altura de capa, no por tiempo
  {% endhint %}

4. Mide con calibre la altura de la zona con mejores esquinas (evita el punto de costura)
5. Calcula: `PA = START + (FACTOR × altura_mm)` — ej: con FACTOR=.005 y altura 12.9 mm → `0 + (.005 × 12.9) = 0.0645`

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/gw3X0WKj5ubuEQNW9Wnr/image.png)

***

## Ajustando el valor de PA <a href="#ajustando-el-valor-de-pa" id="ajustando-el-valor-de-pa"></a>

### En printer.cfg (permanente)

```ini
[extruder]
pressure_advance: 0.05        # Sustituye con tu valor
pressure_advance_smooth_time: 0.040   # Ver nota abajo
```

### En tiempo real (sin reiniciar)

```gcode
SET_PRESSURE_ADVANCE ADVANCE=0.05
```

El valor se aplica de inmediato pero se pierde al reiniciar. Úsalo para probar antes de guardarlo en el cfg.

### Por filamento en el laminador

La forma más práctica cuando usas varios materiales con PA diferente es configurarlo en el perfil de filamento del laminador:

{% tabs %}
{% tab title="OrcaSlicer / Bambu Studio" %}
En el perfil de filamento: **Filament → Flow ratio and Pressure Advance** → activa PA e introduce tu valor.

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/wTi8czr0tErt8Gug2ehH/image.png)

O mediante G-code de inicio de filamento si quieres más control:

```gcode
SET_PRESSURE_ADVANCE ADVANCE=0.05
```

{% endtab %}

{% tab title="PrusaSlicer / SuperSlicer" %}
En el G-code de inicio del perfil de filamento. También puedes aplicar PA diferente por diámetro de nozzle con condicionales:

```gcode
{if nozzle_diameter[0]==0.4}SET_PRESSURE_ADVANCE ADVANCE=0.05
{elsif nozzle_diameter[0]==0.6}SET_PRESSURE_ADVANCE ADVANCE=0.08
{elsif nozzle_diameter[0]==0.8}SET_PRESSURE_ADVANCE ADVANCE=0.12
{endif}
```

{% endtab %}
{% endtabs %}

***

## pressure\_advance\_smooth\_time

`pressure_advance_smooth_time` es un parámetro secundario que suaviza los cambios de PA en el tiempo para evitar vibraciones en la extrusora. El valor por defecto es `0.040` segundos y en la mayoría de setups no necesita tocarse.

```ini
[extruder]
pressure_advance: 0.05
pressure_advance_smooth_time: 0.040  # Default — no tocar si no hay problemas
```

**Cuándo ajustarlo:**

* Si notas ruido o vibración en la extrusora durante las esquinas → prueba reducir a `0.020`
* En bowden largo con PA alto → valores de `0.040–0.060` suelen dar mejores resultados
* En extrusoras directas muy sensibles → mantén en `0.020–0.040`

{% hint style="warning" %}
Un `smooth_time` alto con Input Shaper activo puede crear desincronías entre el movimiento del cabezal y la extrusión. Si usas IS, mantén `smooth_time` en el valor por defecto o más bajo.
{% endhint %}

***

## Resolución de problemas

| Síntoma                                       | Causa probable                                                      | Solución                                             |
| --------------------------------------------- | ------------------------------------------------------------------- | ---------------------------------------------------- |
| No encuentro un valor que mejore las esquinas | Extrusor mal calibrado, temperatura incorrecta, o desgaste mecánico | Verifica e-steps, temperatura y estado de engranajes |
| Líneas inconsistentes en todo el test         | Flujo inestable, temperatura demasiado baja                         | Sube temperatura 5-10°C y repite                     |
| PA bowden > 1.0 sin mejora                    | Tubo PTFE suelto o dañado, anclajes neumáticos desgastados          | Inspecciona y reemplaza el PTFE y los PC4            |
| Con IS activado las esquinas empeoran         | Interacción PA + Input Shaper                                       | Recalibra PA con IS activado, reduce `smooth_time`   |
| Extrusora hace ruido en esquinas              | `smooth_time` demasiado bajo                                        | Aumenta a `0.040` o `0.060`                          |


# Input Shaper

Guía completa de calibración de Input Shaper en Klipper: compensación de resonancias y ringing con acelerómetro ADXL345/LIS2DW, interpretación de gráficas, Shake\&Tune y método manual.

Una de las grandes funcionalidades de Klipper —y que hoy también está disponible en Marlin (desde la versión 2.1) y en Duet— es el soporte a **Input Shaping**, una **técnica que permite reducir las vibraciones/ondas** (ringing, echoing, ghosting, rippling son otros nombres de ese tipo de artefactos).

![Ejemplo de vibraciones/ondas en nuestras impresiones.](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/l9AHFM3vbYvJchnNqgs2/image.png)

Este tipo de artefactos están **producidos por vibraciones mecánicas** originadas normalmente por los movimientos bruscos en los cambios de direcciones. Algo **ocasionado normalmente por... un chasis no suficientemente rigido, correas muy o poco tensas, problemas de alineación en partes del chasis o cinemática, movimientos de masas grandes en los ejes de movimiento, etc**... por lo que es aconsejable que antes de comenzar en estos ajustes nos aseguremos que hemos intentado solventar lo máximo posible los fallos más comunes comentados.

Input Shaping nos permite minimizar esas vibraciones, normalmente a altas velocidades, optimizando los movimientos de los motores para producir las mínimas vibraciones. El objetivo es realizar unas aceleraciones suaves y fluídas que emitan menos vibraciones para conseguir una mayor calidad en nuestras impresiones.

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/U17MQNxfAjvLLmx0Anrv/image.png" alt=""><figcaption></figcaption></figure>

**Dmitry Butyugin** fué el [primero en implementar Input Shaping en Klipper en Agosto 2020](https://www.patreon.com/posts/klipper-update-39974319). Con la ayuda de un acelerómetro ADXL34X encontró una forma de medir las frecuencias de resonancia de la impresora y determinar los parámetros para minimizarlas tal como os comentamos en el punto anterior.

Dado que es un proceso muy extenso os vamos a explicar las dos formas de poder ajustar Input Shaping facilitando links a la documentación oficial, recordaros que **en nuestro caso usamos un sensor para medir las resonancias** de nuestra máquina ya que suele ser la forma más precisa y automática para obtener los mejores resultados.

{% hint style="info" %}
**¿Qué necesitas para calibrar Input Shaper?**

**Proceso en 5 pasos:**

1. Conectar y configurar el acelerómetro → sección [Acelerómetros](#acelerometros)
2. Verificar que responde (`ACCELEROMETER_QUERY`)
3. Lanzar el test (`TEST_RESONANCES` o `SHAPER_CALIBRATE` en modo automático)
4. Interpretar las gráficas y copiar los valores a `[input_shaper]` en printer.cfg
5. Ajustar `max_accel` en la sección `[printer]`
   {% endhint %}

| Requisito       | Detalles                                                             |
| --------------- | -------------------------------------------------------------------- |
| Acelerómetro    | ADXL345, LIS2DW o el integrado en tu toolhead board (EBB, SB2209...) |
| Host Klipper    | Raspberry Pi, CB1, Orange Pi u otro host compatible                  |
| Software        | numpy + matplotlib (ya incluidos en MainsailOS / FluiddOS / RatOS)   |
| Tiempo estimado | 20-30 minutos la primera vez                                         |

## Acelerómetros

Como os aconsejamos en el punto anterior es aconsejable del uso de un acelerómetro que de una forma más automatizada y fiable nos va a proporcionar datos más fiables.

Aunque no esté relacionado directamente con Klipper creemos muy interesante hacer una muy breve introducción a que es un acelerómetro y como funciona. Un acelerómetro básicamente es un dispositivo que nos va a permitir medir y analizar la aceleración lineal/angular convirtiendo la energía generada por las vibraciones en una señal eléctrica proporcional a la aceleración momentánea del objeto.

Normalmente se suelen usar acelerómetros MEMS (Micro Electro Mechanical System) dado que son precisos, fiables y baratos. Básicamente, tal como podéis ver las siguientes imágenes, es un peso montado en unos resortes mientras el otro es fijo normalmente en forma de peine:

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/bETpDP970iJe6Ew01QqH/image.png) ![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/hLTih9pa3jCgD654knzn/image.png)

Cuando se produce una aceleración la parte en el resorte se desplaza y gracias a ese movimiento podemos medir la capacidad eléctrica que nos va a permitir obtener un valor:

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/SL3UgJ9VYr61ChJdWaef/image.png) ![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/b1UzbmiDmnq1ABY5J5iz/image.png)

Por último y a modo de ejemplo tenéis una imagen de como sería internamente un acelerómetro de 3 ejes donde podréis ver lo anterior en el mundo real:

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/zphqii49CbhEQ808ZHLY/image.png" alt=""><figcaption></figcaption></figure>

### Acelerómetros compatibles con Klipper

Klipper soporta de forma nativa los siguientes acelerómetros para medición de resonancias:

| Sensor                  | Bus       | Notas                                                             |
| ----------------------- | --------- | ----------------------------------------------------------------- |
| **ADXL345 / ADXL343**   | SPI       | El histórico, sigue siendo el más usado. Económico y muy probado. |
| **MPU-6050 / MPU-9250** | I2C       | Alternativa I2C muy habitual en toolheads que no exponen SPI.     |
| **LIS2DW**              | SPI o I2C | Integrado en muchas toolhead boards modernas (EBB, SB2209).       |
| **LIS3DH**              | SPI o I2C | Añadido recientemente a Klipper. Misma configuración que LIS2DW.  |
| **ICM-20948**           | I2C       | Añadido recientemente a Klipper. Compatible con la familia MPU.   |

{% hint style="info" %}
**LIS3DH** se incorporó al árbol oficial de Klipper en 2024 y **ICM-20948** poco después (con una corrección posterior del rango de escala 2g→8g). Antes había que parchear o usar forks; hoy basta con la configuración nativa.

* Documentación oficial: [Measuring Resonances](https://www.klipper3d.org/Measuring_Resonances.html)
* Sección [Acelerómetros adicionales (LIS3DH, ICM-20948)](#acelerometros-adicionales-lis3dh-e-icm-20948) más abajo con los snippets de configuración.
  {% endhint %}

### Acelerómetro, puesta en marcha

En las siguientes pestañas podéis encontrar las diferentes opciones para disponer de un acelerómetro para nuestra máquina:

<details>

<summary>IMPORTANTE!!! Sobre acelerómetros ADXL34X</summary>

Existen diferentes tipos de placas ADXL345, o ADXL343 que son alternativas. Dependiendo del tipo de placa y sus componentes tendremos que tener en consideración cuando la conectemos a nuestro controlador Pi.

* **Regulador de Voltaje**, estas placas pueden alimentarse tanto a 3.3v como 5v. El chip ADXL34X trabaja a 3.3v, pero en el caso de tener un regulador de voltaje permitirá que solo esos 3.3v lleguen al chip, independientemente de la alimentación que usemos\ <mark style="color:red;">**Placas sin regulador de voltaje NO se deben de alimentar a 5v ya que puede/va a dañar nuestra placa.**</mark>
* **Level Shifter**, un level shifter permite traducir señales entre 3.3v y 5v o viceversa. Como ya hemos comentado, ADXL34XX funciona a 3.3v. El level shifter permite que un ADXL34X alimentado a 5v permita que sus salidas funcionen a 5v también.\ <mark style="color:red;">**Es importante recordar que nuestras Raspberry y la mayoría de MCUs están diseñadas para funcionar 3.3v. Una placa ADXLxxx no se debería alimentar a 5v si tiene una circuitería level shifter.**</mark>
*

```
<figure><img src="../../.gitbook/assets/image (1194).png" alt=""><figcaption><p>Ejemplo ADXL34X con regulador de voltaje y level shifter</p></figcaption></figure>
```

*

```
<figure><img src="../../.gitbook/assets/image (1800).png" alt=""><figcaption><p>Ejemplo ADXL34X solamente regulador de voltaje</p></figcaption></figure>
```

</details>

{% tabs %}
{% tab title="ADXL345 - Fysetc Pico" %}
Si no os queréis complicar montando vosotros mismos las soldaduras y cableado necesarios, aunque es muy divertido hacerlo!!!, podéis optar por unos comerciales que ya vienen montados:

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/0Y8HkvRWRAHfTF2CcUxx/image.png)

[https://s.click.aliexpress.com/e/\_DcynuSh](https://s.click.aliexpress.com/e/182731559?productUrl=https://s.click.aliexpress.com/e/182731559?productUrl=https://www.aliexpress.com/item/1005004649494056.html)

## Fysetc Pico firmware Klipper

El siguiente paso a realizar los siguientes pasos para preparar y aplicar el firmware Klipper a nuestra Fysetc Pico accediento a nuestro host Klipper por SSH (PuTTy/Terminus):

* Lanzaremos el comando para preparar nuestro firmware Klipper para nuestra Fysetc Pico:

```bash
cd ~/klipper
make menuconfig
```

* En la configuración del firmware seleccionaremos:

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/uSUrtp4HAnHrDeD2uVTH/image.png" alt=""><figcaption></figcaption></figure>

```bash
[ ] Enable extra low-level configuration options
Micro-controller Architecture (Raspberry Pi RP2040)  --->
Communication interface (USB)  --->
```

* Presionaremos Q y luego Y para guardar los cambios
* Reiniciaremos el servicio Klipper:

```bash
sudo service klipper stop
```

* Haremos una limpieza de make para asegurarnos que todo está limpio

```bash
sudo make clean
```

* Generaremos el firmware:

```bash
make
```

* **Conectaremos nuestra Fysetc Pico por USB a nuestra Raspberry Pi dejando presionado el botón de boot en la Pi Pico para que monte la unidad de boot** y ejecutaremos lo siguiente:

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/Xl5ZpGURyxUFTIYGTCPT/image.png)

{% hint style="warning" %}
**Asumimos que la Fysetc Pico es el único dispositivo USB conectado a la Raspberry Pi y que este se ha montado sobre /dev/sda**
{% endhint %}

```bash
## montamos la unidad de boot de nuestra pi pico
sudo mount /dev/sda1 /mnt
## copiamos el firmware klipper generado previamente a nuestra pi pico
sudo cp out/klipper.uf2 /mnt
## desmontamos nuestra pi pico
sudo umount /mnt
```

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/olx3wIAha61iuHs2V2BO/image.png" alt=""><figcaption></figcaption></figure>

* ya podemos reconectar Fysetc pi pico por USB y buscaremos el serial id el cual anotaremos ya que deberemos de usarlo en siguientes pasos

```bash
ls /dev/serial/by-id/
```

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/5cajPhXsAvMIyaeH6tWO/image.png" alt=""><figcaption></figcaption></figure>

* una vez finalizado el proceso arrancaremos el servicio Klipper de nuevo:

```bash
sudo service klipper start
```

**Configuración Klipper**

* dentro de nuestra interfaz de Klipper y para que el uso sea modular lo ideal es **crear un nuevo fichero de configuración PIS.cfg para incluir la configuración de nuestro acelerómetro Fysetc**:

{% @github-files/github-code-block %}

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

```django
[mcu PIS]
# Obtain definition by "ls -l /dev/serial/by-id/" then unplug to verify
serial: /dev/serial/by-id/xxxx

[adxl345]
cs_pin: PIS:gpio13
#spi_bus: spi1a
spi_software_sclk_pin: PIS:gpio10
spi_software_mosi_pin: PIS:gpio11
spi_software_miso_pin: PIS:gpio12
axes_map: x,-z,y

[resonance_tester]
accel_chip: adxl345
probe_points:
    100,100,20 # an example
```

{% endcode %}

Sobre el PIS.cfg de Fysetc vamos a realizar algunos ajustes importantes:

* En la sección **\[mcu PIS] ajustaremos el valor de serial para que se ajuste al que obtivimos previamente**, en nuestro ejemplo:

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

```django
[mcu PIS]
# Obtain definition by "ls -l /dev/serial/by-id/" then unplug to verify
serial: /dev/serial/by-id/usb-Klipper_rp2040_E66118F5D7537136-if00
```

{% endcode %}

* También, por compatibilidad con algunos sistemas como RatOS, ajustaremos la sección \[adxl345] para añadir un identificador en nuestro caso usaremos fysetc para distinguirlo de otros posibles que podamos tener:

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

```django
[adxl345 fysetc]
cs_pin: PIS:gpio13
#spi_bus: spi1a
spi_software_sclk_pin: PIS:gpio10
spi_software_mosi_pin: PIS:gpio11
spi_software_miso_pin: PIS:gpio12
axes_map: x,-z,y
```

{% endcode %}

* Ajustaremos, `axes_map` que indicara la dirección de movimientos de la máquina.\
  Para más información sobre `axes_map` podéis revisar la documentación oficial de Klipper [aquí](https://www.klipper3d.org/Config_Reference.html#lis2dw). Básicamente es para indicar con respecto a la posicion del acelerómetro y el movimiento de la máquina... por ejemplo si colocamos el sensor con orientación Y para el eje de movimiento X usaremos y, x, z... y si lo tenemos invertido usaremos el simbolo - delante
* Por último y en la **sección \[resonance\_tester] ajustaremos el accel\_chip para indicarle el nuestro con el ID que establecimos en el paso anterior**, y segundo **ajustar las coordenadas probe\_points a unas adecuadas a nuestra máquina**... normalmente en el centro de nuestra cama de impresión:

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

```django
[resonance_tester]
accel_chip: adxl345 fysetc
probe_points:
    210,210,20 # an example
```

{% endcode %}

{% hint style="success" %}
Si queremos un extra :) podemos añadir otra sección, al final de nuestro PIS.cfg, para mostrar los datos de nuestro Fysetc Pico en la sección MACHINE:

```django
[temperature_sensor PIS]
sensor_type = temperature_mcu
sensor_mcu: PIS
```

<img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/5dOtgQ9KOdx6rMc26WIf/image.png" alt="" data-size="original">
{% endhint %}

Con el fichero de configuración de nuestro Fysetc Pico ajustado tan solo tendremos que indicar a nuestro printer.cfg que lo cargue.

* incluiremos nuestro nuevo fichero de adxl345\_pico.cfg en nuestro printer.cfg habilitándolo cuando necesitemos realizar el proceso de input shaper:

  ```django
  # Descomentar la siguiente linea para usar ADXL345 conectada a la Pi Pico
  [include PIS.cfg] 
  ```

{% hint style="warning" %}
En caso de usar una distribución RatOS y usar definiciones de sus configuraciones de electrónica mediante includes o directamente tener una máquina Ratrig has de tener en cuentra:

* NO has de habilitar ningún include de acelerómetro

* el include del fichero PIS.cfg has de realizarlo en la zona USER OVERRIDES si usamos un template de configuración de RatOS
  {% endhint %}

* Reiniciaremos Klipper usando el comando **RESTART**
  {% endtab %}

{% tab title="ADXL345 - CB1" %}
La CB1 de Bigtreetech es una gran alternativa a las Raspberry Pi que cuentan con la ventaja de su precio, grandes prestaciones y poder usarse en la serie Manta de Bigtreetech.

La CB1, al estar conectada a la electrónica Manta o alguno de sus adaptadores, dispone de un GPIO el cual... aunque limitado con respecto a la Raspberry Pi... podremos usar para conectar nuestro acelerómetro.

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/RAzopQHEqHjyDGxJK1S9/image.png" alt=""><figcaption></figcaption></figure>

Para poder cablear nuestro acelerómetro seguiremos el siguiente diagrama:

| ADXL345 | CB1 | Pin    |
| ------- | --- | ------ |
| GND     | 25  | Ground |
| VCC     | 17  | 3v3    |
| CS      | 15  | GPIO22 |
| SDO     | 21  | GPIO9  |
| SDA     | 19  | GPIO10 |
| SCL     | 23  | GPIO11 |

El siguiente paso será habilitar SPI en nuestra CB1 en el directorio /boot/ en su BoardEnv.txt... podéis acceder a el por SSH o [WinSCP](https://winscp.net/eng/index.php).

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/G0JSS1QJvBUlMOIuSkUB/image.png)

Descomentaremos o añadiremos las siguientes líneas:

{% code title="/boot/BoardEnv.txt" %}

```
# uncomment the following overlays and parameters to release 'spidev1.1' to user space
# NOTE: 'spidev1.1' cannot be used together with TFT35_SPI and MCP2515
overlays=spi-spidev
param_spidev_spi_bus=1
param_spidev_spi_cs=1
param_spidev_max_freq=1000000
```

{% endcode %}

Guardamos los cambios y reiniciamos nuestra CB1. Ajustaremos nuestro printer.cfg:

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

```
[mcu cb1]
serial: /tmp/klipper_host_mcu

[adxl345]
cs_pin: cb1:gpiochip0/gpio74
spi_bus: spidev1.1
axes_map: x,-z,y

[resonance_tester]
accel_chip: adxl345
probe_points:
 100, 100, 20
```

{% endcode %}
{% endtab %}

{% tab title="ADXL34X - MCU" %}
Otra opción muy interesante es la de instalar nuestro sensor directamene a nuestra electrónica de esta forma no necesitamos componentes externos.

Es importante aclarar que NO todas las electrónicas pueden usarse de esta manera, en concreto aquellas que no tengan pines SPI expuestos para su uso.

En la siguiente imagen puedes ver como conectar el sensor a una Octopus en su puerto SPI:

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/A0eOtipAc077110HN4dg/image.png" alt=""><figcaption></figcaption></figure>

Añadiremos la configuración de sensor en nuestro printer.cfg:

```django
[adxl345]
spi_bus: spi3
cs_pin: PA15
axes_map: x,-z,y

[resonance_tester]
accel_chip: adxl345
probe_points:
    90,90,20 # coordenadas del test idealmente el centro de tu cama
```

En `axes_map` que indicara la dirección de movimientos de la máquina.\
Para más información sobre `axes_map` podéis revisar la documentación oficial de Klipper [aquí](https://www.klipper3d.org/Config_Reference.html#lis2dw). Básicamente es para indicar con respecto a la posicion del acelerómetro y el movimiento de la máquina... por ejemplo si colocamos el sensor con orientación Y para el eje de movimiento X usaremos y, x, z... y si lo tenemos invertido usaremos el simbolo - delante
{% endtab %}

{% tab title="ADXL34X - Pi Pico" %}
Usando Pi Pico como interfaz/MCU secundaria para conectar nuestro acelerómetro nos permite el tener una solución más cómoda y común para todas nuestras impresoras además que nos permite normalmente reducir enormemente la longitud del cableado entre el sensor y el host/MCU de control reduciendo problemas relacionados con interferencias en los cables de forma considerable.

La Pi Pico es una MCU de Raspberry de bajo coste y fácil de encontrar. Nuestro BOM de componentes.

| Componente                                          | Unidades                                     | Tiendas                                                                                                                                                       |
| --------------------------------------------------- | -------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Raspberry Pi Pico                                   | 1 (es aconsejable 2 por tener una de backup) | <img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/U3bDWNHjlJK7bq79jsVD/image.png" alt="" data-size="line"> - <https://amzn.to/3r86W1r> |
| Adafruit ADXL345                                    | 1 (es aconsejable 2 por tener de backup)     | <img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/U3bDWNHjlJK7bq79jsVD/image.png" alt="" data-size="line"> - <https://amzn.to/3Kh8WMi> |
| Cables USB, conectores DuPont, cable CAT6, soldador |                                              |                                                                                                                                                               |

La conexión entre nuestra Pi Pico y nuestro acelerómetro es relativamente sencilla y podéis usar el siguiente esquema como referencia:

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/C76K8RVIrdSJclgd7etT/image.png)

| Rol       | RPI Pico (pin) | RPI Pico (nombre pin) |
| --------- | :------------: | --------------------- |
| VCC (3v3) |       36       | 3v3 VCC               |
| GND       |       38       | Ground                |
| CS        |        2       | SPIO CSn              |
| SDO       |        1       | SPIO Rx               |
| SDA       |        5       | SPIO Tx               |
| SCL       |        4       | SPIO SCK              |

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/BUomjX6BkJJ13G7C4gu8/image.png" alt=""><figcaption><p>Ejemplo de conexión. OJO!!! en este caso el ADXL345 permite alimentación 5v, en el caso que el tuyo no lo soporte usa la tabla anterior para alimentar a 3v3</p></figcaption></figure>

## Pi Pico firmware Klipper

El siguiente paso a realizar los siguientes pasos para preparar y aplicar el firmware Klipper a nuestra Pi Pico accediento a nuestro host Klipper por SSH (PuTTy/Terminus):

* Lanzaremos el comando para preparar nuestro firmware Klipper para nuestra Pi Pico:

```bash
cd ~/klipper
make menuconfig
```

* En la configuración del firmware seleccionaremos:

```bash
[ ] Enable extra low-level configuration options
Micro-controller Architecture (Raspberry Pi RP2040)  --->
Communication interface (USB)  --->
```

* Presionaremos Q y luego Y para guardar los cambios
* Reiniciaremos el servicio Klipper:

```bash
sudo service klipper stop
```

* Haremos una limpieza de make para asegurarnos que todo está limpio

```bash
sudo make clean
```

* Generaremos el firmware:

```bash
make
```

* **Conectaremos nuestra Pi Pico por USB a nuestra Raspberry Pi dejando presionado el botón de boot en la Pi Pico para que monte la unidad de boot** y ejecutaremos lo siguiente:

```bash
## montamos la unidad de boot de nuestra pi pico
sudo mount /dev/sda1 /mnt
## copiamos el firmware klipper generado previamente a nuestra pi pico
sudo cp out/klipper.uf2 /mnt
## desmontamos nuestra pi pico
sudo umount /mnt
```

{% hint style="warning" %}
**Asumimos que la Pi Pico es el único dispositivo USB conectado a la Raspberry Pi y que este se ha montado sobre /dev/sda**
{% endhint %}

* ya podemos reconectar la pi pico por USB y buscaremos el serial id el cual anotaremos ya que deberemos de usarlo en siguientes pasos

```bash
ls /dev/serial/by-id/
```

* una vez finalizado el proceso arrancaremos el servicio Klipper de nuevo:

```bash
sudo service klipper start
```

## Configuración Klipper

* dentro de nuestra interfaz de Klipper y para que el uso sea modular lo ideal es **crear un nuevo fichero de configuración adxl345\_pico.cfg para incluir la configuración de nuestro acelerómetro**:

{% code title="adxl345\_pico.cfg" %}

```django
## Configuración ADXL345 usando Pi Pico
[mcu pico]
serial: /dev/serial/by-id/usb-Klipper_rp2040_E660REDACTED-if00

[adxl345]
cs_pin: pico:gpio1
spi_bus: spi0a
axes_map: x,z,y

[resonance_tester]
accel_chip: adxl345
probe_points:
    90,90,20 # coordenadas del test idealmente el centro de tu cama
```

{% endcode %}

En `axes_map` que indicara la dirección de movimientos de la máquina.\
Para más información sobre `axes_map` podéis revisar la documentación oficial de Klipper [aquí](https://www.klipper3d.org/Config_Reference.html#lis2dw). Básicamente es para indicar con respecto a la posicion del acelerómetro y el movimiento de la máquina... por ejemplo si colocamos el sensor con orientación Y para el eje de movimiento X usaremos y, x, z... y si lo tenemos invertido usaremos el simbolo - delante

{% hint style="info" %}
**Raspberry Pi Pico, buses SPI disponibles.**

**Es posible conectar múltiples dispositivos SPI a nuestra Pi Pico en paralelo. En la siguiente tabla podéis encontrar los pines y el ID de SPI en cada caso.**

**Para nuestro ejemplo usamos el bus SPI spi0a.**

<img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/ZDG5wYDxkKtdPoTmqrJf/image.png" alt="" data-size="original">
{% endhint %}

* incluiremos nuestro nuevo fichero de adxl345\_pico.cfg en nuestro printer.cfg habilitándolo cuando necesitemos realizar el proceso de input shaper:

  ```django
  # Descomentar la siguiente linea para usar ADXL345 conectada a la Pi Pico
  [include adxl345_pico.cfg] 
  ```
* Reiniciaremos Klipper usando el comando **RESTART**

{% embed url="<https://youtu.be/W_VHbT_tsZw>" %}
Tenéis el siguiente video del compañero Nero3D que puede completar el proceso descrito anteriormente.
{% endembed %}
{% endtab %}

{% tab title="ADXL34X - Pi" %}
La opción más común suele ser conectar directamente nuestro acelerómetro directamente a nuestro host Klipper, en el caso de ser una Raspberry Pi o similar.

{% hint style="warning" %}
Pese a que es la opción más común tenemos que recordar que e**l uso de un acelerómetro directamente a nuestra Pi puede dar algunos quebraderos de cabeza dado que la longitud, calidad y construcción del cableado puede influir en la comunicación entre el sensor y nuestra Pi**.
{% endhint %}

Aunque Klipper es compatible con diferentes tipos de acelerómetros vamos a usar el más común que es el ADXL345 en cualquier caso en la [**documentación de Klipper**](https://www.klipper3d.org/Measuring_Resonances.html) podéis encontrar otras opciones.

| Componente                                          | Unidades                                 | Tiendas                                                                                                                                                       |
| --------------------------------------------------- | ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Adafruit ADXL345                                    | 1 (es aconsejable 2 por tener de backup) | <img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/U3bDWNHjlJK7bq79jsVD/image.png" alt="" data-size="line"> - <https://amzn.to/3Kh8WMi> |
| Cables USB, conectores DuPont, cable CAT6, soldador |                                          |                                                                                                                                                               |

El primer paso será montar el cableado para nuestro sensor y nuestra Pi. Tal como os adelantábamos es importante que usemos conectores dupont que proporcionen una buena conexión y un cableado adecuado, normalmente cable de red CAT6 suele dar un buen resultado gracias al trenzado y apantallado.

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/9PWS1pFODUkT074Fm6g0/image.png" alt=""><figcaption></figcaption></figure>

Una vez tenemos las conexiones nos aseguraremos que tenemos activado la comunicación SPI en nuestra Pi. Para ello conectaremos por SSH (PuTTy o Terminus) a nuestra Pi y lanzaremos la utilidad raspi-config:

```bash
sudo raspi-config
```

Dentro del menú de configuración que aparece seleccionaremos

**#3 >> Interface Options >> P4 SPI >> Yes >> OK >> Finish**

{% hint style="warning" %}
La utilidad raspi-config puede cambiar el orden de los menús anteriores en futuras actualizaciones... aplica el sentido común si no ves exactamente este orden de menús :thumbsup:
{% endhint %}

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/vJAk33xa5qvXC0WW25oM/image.png" alt=""><figcaption></figcaption></figure>

**Configuración Pi como segunda MCU**

Para poder acceder a determinados recursos de nuestra Pi, como es el caso del acelerómetro, deberemos realizar el proceso explicado en esta [<mark style="color:green;">**guía para poder usar nuestra Pi como segunda MCU**</mark>](/klipper/mejoras/raspberry-como-segunda-mcu)<mark style="color:green;">**.**</mark>

**Configuración Klipper**

* dentro de nuestra interfaz de Klipper y para que el uso sea modular lo ideal es **crear un nuevo fichero de configuración adxl345\_rpi.cfg para incluir la configuración de nuestro acelerómetro**:

{% code title="adxl345\_rpi.cfg" %}

```django
[mcu rpi]
serial: /tmp/klipper_host_mcu

[adxl345]
cs_pin: rpi:None
axes_map: x,-z,y

[resonance_tester]
accel_chip: adxl345
probe_points:
    100, 100, 20  # an example
```

{% endcode %}

* En `axes_map` que indicara la dirección de movimientos de la máquina.\
  Para más información sobre `axes_map` podéis revisar la documentación oficial de Klipper [aquí](https://www.klipper3d.org/Config_Reference.html#lis2dw). Básicamente es para indicar con respecto a la posicion del acelerómetro y el movimiento de la máquina... por ejemplo si colocamos el sensor con orientación Y para el eje de movimiento X usaremos y, x, z... y si lo tenemos invertido usaremos el simbolo - delante
* incluiremos nuestro nuevo fichero de adxl345\_rpi.cfg en nuestro printer.cfg habilitándolo cuando necesitemos realizar el proceso de input shaper:

```django
# Descomentar la siguiente linea para usar ADXL345 conectada a la Pi Pico
[include adxl345_rpi.cfg] 
```

* Reiniciaremos Klipper usando el comando **RESTART**
  {% endtab %}

{% tab title="ADXL34X - Arduino" %}
Otra opción es la de usar un Arduino que seguro que tenemos por casa para nuestros proyectos maker para gestionar nuestro acelerómetro. Es importante recordar que es aconsejable usar un Arduino con una MCU relativamente potente dado que el flujo de datos entre el acelerómetro y nuestro Arduino es bastante intensivo.

Conectaremos ambos componentes siguiendo el siguiente esquema de conexiones:

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/sBkUOGrcerovRkDZwLTn/image.png" alt=""><figcaption></figcaption></figure>

| Arduino | ADXL345 |
| :-----: | :-----: |
|   GND   |   GND   |
|   3v3   |   VCC   |
|    10   |    CS   |
|    12   |   SDO   |
|    11   |   SDA   |
|    13   |   SCL   |

## Arduino firmware Klipper

* Conectamos el cable USB a nuestra Raspberry Pi
* Buscaremos el id del serial para detectar nuestro Android mediante el siguiente comando:

```bash
ls /dev/serial/by-id/
```

* Iremos a la carpeta Klipper:

```bash
cd ~/klipper
```

* Lanzaremos el comando para preparar nuestro firmware Klipper para Arduino:

```
make menuconfig
```

* En la configuración del firmware seleccionaremos:
  * Atmega AVR como arquitectura del micro-controlador
  * En el modelo del procesador seleccionaremos el nuestro, para el ejemplo atmega328p
* Presionaremos Q y luego Y para guardar los cambios
* Reiniciaremos el servicio Klipper:

```bash
sudo service klipper stop
```

* Subiremos el firmware Klipper a nuestro Arduino con el siguiente comando, es importante usar el id del serial detectado en pasos anteriores:

```bash
make flash FLASH_DEVICE=/dev/serial/by-id/[id-serial-arduino]
```

* una vez finalizado el proceso arrancaremos el servicio Klipper de nuevo:

```bash
sudo service klipper start
```

## Configuración en Klipper

* En nuestro printer.cfg añadiremos el siguiente include al incio:

```django
[include arduino.cfg]
```

* Crearemos un nuevo archivo con el nombre arduino.cfg a la misma altura que nuestro printer.cfg, deberemos ajustar el serial por el que detectamos en pasos anteriores además de las coordenadas para los test:

```django
[mcu ardu]

serial: /dev/serial/by-id/usb-Arduino__www.arduino.cc__0043_85830303339351409150-if00

[adxl345]
cs_pin: ardu:PB2
axes_map: x,-z,y

[resonance_tester]
accel_chip: adxl345
probe_points:
90,90,50 # como ejemplo
```

* En `axes_map` que indicara la dirección de movimientos de la máquina.\
  Para más información sobre `axes_map` podéis revisar la documentación oficial de Klipper [aquí](https://www.klipper3d.org/Config_Reference.html#lis2dw). Básicamente es para indicar con respecto a la posicion del acelerómetro y el movimiento de la máquina... por ejemplo si colocamos el sensor con orientación Y para el eje de movimiento X usaremos y, x, z... y si lo tenemos invertido usaremos el simbolo - delante
* Reiniciaremos Klipper:

```bash
sudo service klipper restart
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="LIS2DW - BTT S2DW" %}
Los acelerómetros LIS2DW son soportados recientemente (Agosto 2023, por lo que si vuestra instalación es más antigua es hora de actualizar!!!) por parte de Klipper. Al igual que los ADXL345 utilizan el interfaz SPI para cominicarse con el host/MCU lo que permiten unas velocidades de hasta 400kbit/s.

![](https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FQH1OCFCtSGnNAvXhp9tm%2Fimage.png?alt=media\&token=fee1dcb9-b40d-428c-ad19-67ea66f79f35)

En el caso del BTT S2DW es una solución que funciona con su propia MCU, una RPI2040 con doble ARM Cortex-M0+ @ 133MHz que nos asegura que no vamos a tener problemas de proceso, y la conectaremos por USB lo que va a eliminar problemas de cableado y simplificar su uso aunue tambien disponemos del interfaz SPI para poder conectar con cables.\
![](https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2F8iLoKFsmrO0q1li9fAHt%2Fimage.png?alt=media\&token=fc5767fe-2dee-4a22-887f-d62a36fc3445)

Por otro lado estos acelerómetros prometen casi el doble de precisión, menos nivel de ruido y menos afectación por la temperatura comparados con un ADXL345:

![](https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FbbTRNcbuLfrIQS4sW9ug%2Fimage.png?alt=media\&token=6c692a88-e2b6-4ee6-a4b7-0177c809ee6f)

Pasos para preparar y aplicar el firmware Klipper a nuestra BTT S2DW accediento a nuestro host Klipper por SSH (PuTTy/Terminus):

* Lanzaremos el comando para preparar nuestro firmware Klipper para nuestra BTT S2DW:

```bash
cd ~/klipper
make menuconfig
```

* En la configuración del firmware seleccionaremos:

![](https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FNnot2jsMnKNKC8MUBZYc%2Fimage.png?alt=media\&token=f12ef026-7280-4842-9236-5d950d5445fd)

```bash
[*] Enable extra low-level configuration options
Micro-controller Architecture (Raspberry Pi RP2040)  --->
Bootloader offset (No bootloader) --->
Flash chip (W25Q080 with CLKDIV 2) --->
Communication interface (USB)  --->
```

* Presionaremos Q y luego Y para guardar los cambios
* Reiniciaremos el servicio Klipper:

```bash
sudo service klipper stop
```

* Haremos una limpieza de make para asegurarnos que todo está limpio

```bash
sudo make clean
```

* Generaremos el firmware:

```bash
make
```

* **Conectaremos nuestra BTT S2DW por USB a nuestro host dejando presionado el botón de&#x20;**<mark style="color:green;">**BOOT**</mark>**&#x20;para entrar en modo DFU** y ejecutaremos lo siguiente:

![](https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FFa51434xwI0WW6thRKu7%2Fimage.png?alt=media\&token=d22e434f-19dd-4f4e-9bb2-a719f46dfdad)

* Usaremos el comando `lsusb` para listar los dispositivos conectados a nuestro host y localizar el de nuestra BTT S2DW, en nuestro caso 2e8a:0003:

![](https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2Fy1WKsWkAsLuDOVY3Aqqp%2Fimage.png?alt=media\&token=0b9f79bc-3e14-442f-a489-fd5cf0d91c7d)

* A continuación lanzaremos el comando para aplicar el firmware, recuerda ajustar el FLASH\_DEVICE al obtenido en el paso anterior:

```bash
cd klipper
make flash FLASH_DEVICE=2e8a:0003
```

* Una vez ya tenemos el firmware aplicado lanzaremos el siguiente comando para obtener el serial ID (/dev/serial/by-id/xxx) que usaremos mas tarde en Klipper:

```bash
ls /dev/serial/by-id/
```

* Ahora iremos a nuestro interfaz Klipper web para añadir la configuración del acelerómetro, del cual tenéis un ejemplo en <https://github.com/bigtreetech/LIS2DW/blob/master/Firmware/sample-bigtreetech-lis2dw-v1.0.cfg> ,

```django
[mcu btt_lis2dw]
serial: /dev/serial/by-id/usb-Klipper_rp2040_btt_acc-if00

[lis2dw]
cs_pin: btt_lis2dw:gpio9
#spi_bus: spi1a
spi_software_sclk_pin: btt_lis2dw:gpio10
spi_software_mosi_pin: btt_lis2dw:gpio11
spi_software_miso_pin: btt_lis2dw:gpio8
axes_map: -y,x,-z

[resonance_tester]
probe_points: 100, 100, 20
accel_chip: lis2dw
```

* Ajustaremos, de la configuración anterior, nuestro `serial` con el que obtivimos en el paso anterior y `axes_map` que indicara la dirección de movimientos de la máquina.\
  Para más información sobre `axes_map` podéis revisar la documentación oficial de Klipper [aquí](https://www.klipper3d.org/Config_Reference.html#lis2dw). Básicamente es para indicar con respecto a la posicion del acelerómetro y el movimiento de la máquina... por ejemplo si colocamos el sensor con orientación Y para el eje de movimiento X usaremos y, x, z... y si lo tenemos invertido usaremos el simbolo - delante
  {% endtab %}

{% tab title="LIS2DW - MELLOW FLY-USB" %}
Pasos para preparar y aplicar el firmware Klipper a nuestra Mellow FLY-USB accediento a nuestro host Klipper por SSH (PuTTy/Terminus):

* El primer paso para preparar el dispositivo será aplicar el bootloader a nuestro FLY-USB, os aconsejamos seguir el procedimiento directamente desde la web de Mellow, no es complejo pero tenemos diferentes opciones.

{% embed url="<https://mellow.klipper.cn/docs/ProductDoc/ToolBoard/fly-usb-adxl/fly-usb-lis2dw/bl>" %}

* Lanzaremos el comando para preparar nuestro firmware Klipper para nuestra BTT S2DW:

```bash
cd ~/klipper
make menuconfig
```

* En la configuración del firmware seleccionaremos:

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FbHwfysQwT9qYBQd8jIE6%2Fimage.png?alt=media&amp;token=eb4f77a3-8f91-45f5-9287-7d8b999ce43a" alt=""><figcaption></figcaption></figure>

```bash
[*] Enable extra low-level configuration options
Micro-controller Architecture (Raspberry Pi RP2040/RP235x)  --->
Processor model (rp2040) --->
Bootloader offset (16KiB bootloader) --->
Communication interface (USBSERIAL)  --->
USB ids --->
(gpio24) GPIO pins to set at micro-controller startup
```

* Presionaremos Q y luego Y para guardar los cambios
* Reiniciaremos el servicio Klipper:

```bash
sudo service klipper stop
```

* Haremos una limpieza de make para asegurarnos que todo está limpio

```bash
sudo make clean
```

* Generaremos el firmware:

```bash
make
```

* Hemos de disponer de katapult instalado en nuestro host, de no tenerlo podremos instalarlo lanzando

```bash
cd && git clone https://github.com/Arksine/katapult.git
```

* Buscaremos el ID del dispositivo Mellow Fly utilizando `lsusb`\
  Si no nos funciona el comando `lsusb` podemos instalarlo lanzando:

  ```
  sudo apt-get install usbutils
  ```

```
ls /dev/serial/by-id/*
```

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FEikIaXlvCjKh2OUmB220%2Fimage.png?alt=media&amp;token=10b185dd-1f29-447a-9e55-d73be7faab44" alt=""><figcaption></figcaption></figure>

* Nos anotaremos el ID del dispositivo el cual usaremos para lanzar el comando para actualizar el firmware

```
~/klippy-env/bin/python ~/katapult/scripts/flashtool.py -d /dev/serial/by-id/IC_Mellow
```

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FsKWETuemoyl3SaXuqtws%2Fimage.png?alt=media&amp;token=5716e106-25bf-4551-ae46-fc158687805f" alt=""><figcaption></figcaption></figure>

* Si el firmware se aplico correctamente el led de la siguiente imagen se encenderá

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FNHrilaHubPIwNs7YZSAl%2Fimage.png?alt=media&amp;token=5ad95196-4896-4e56-917f-f1b7bc5a59a9" alt=""><figcaption></figcaption></figure>

* Ahora iremos a nuestro interfaz Klipper web para añadir la configuración del acelerómetro, del cual tenéis un ejemplo en

{% embed url="<https://mellow.klipper.cn/docs/ProductDoc/ToolBoard/fly-usb-adxl/fly-usb-lis2dw/cfg>" %}

```django
[mcu LIS]
serial: /dev/serial/by-id/usb-Klipper_rp2040_XXXXXXXXXXXXXXXXXXXXX

[lis2dw]
cs_pin: LIS:gpio9
spi_software_sclk_pin: LIS:gpio10
spi_software_mosi_pin: LIS:gpio11
spi_software_miso_pin: LIS:gpio12

[resonance_tester]
accel_chip: lis2dw
probe_points: 150, 150, 20
min_freq: 5
max_freq: 133
accel_per_hz: 75
hz_per_sec: 1
```

* Ajustaremos, de la configuración anterior, nuestro `serial` con el que obtivimos en el paso anterior y `axes_map` que indicara la dirección de movimientos de la máquina.\
  Para más información sobre `axes_map` podéis revisar la documentación oficial de Klipper [aquí](https://www.klipper3d.org/Config_Reference.html#lis2dw). Básicamente es para indicar con respecto a la posicion del acelerómetro y el movimiento de la máquina... por ejemplo si colocamos el sensor con orientación Y para el eje de movimiento X usaremos y, x, z... y si lo tenemos invertido usaremos el simbolo - delante

Gracias al compañero Xander de nuestro grupo Klipper de Telegram por ayudar en el proceso.
{% endtab %}

{% tab title="ADXL345 — EBB Toolhead (CAN/USB)" %}
Muchas placas toolhead actuales como la **BTT EBB SB2209**, **EBB SB2240**, **EBB36**, **EBB42** o la **Mellow FLY-SB2040** incluyen un **acelerómetro ADXL345 integrado** en la propia placa. Si usas una de estas placas, no necesitas ningún acelerómetro externo — el sensor ya está ahí.

Esta es la opción más recomendada en máquinas CoreXY modernas (Voron 2.4, Trident, VzBot…) ya que el acelerómetro está montado directamente en el cabezal, muy cerca del nozzle, lo que da las medidas más precisas posibles.

{% hint style="info" %}
La configuración es idéntica independientemente de si la placa toolhead se conecta por **CAN bus** o por **USB**. El acelerómetro siempre usa la MCU de la toolhead board como interfaz.
{% endhint %}

**Configuración Klipper** (ajusta el nombre `EBBCan` al que hayas definido en tu `[mcu]`):

```ini
[adxl345]
cs_pin: EBBCan:PB12
spi_software_sclk_pin: EBBCan:PB10
spi_software_mosi_pin: EBBCan:PB11
spi_software_miso_pin: EBBCan:PB2
axes_map: x, y, z
```

```ini
[resonance_tester]
accel_chip: adxl345
probe_points:
    150, 150, 20  # centro de tu cama, ajusta a tus dimensiones
```

Puedes añadir estos bloques directamente en `printer.cfg` o en un archivo separado `adxl.cfg` incluido desde printer.cfg:

```ini
# printer.cfg
[include adxl.cfg]
```

{% hint style="warning" %}
**`axes_map`**: el valor correcto depende de cómo esté orientada físicamente la placa en el cabezal. Para las EBB SB2209/SB2240 montadas en el Stealthburner de Voron, el valor habitual es `x, y, z` o `-x, y, z` dependiendo de la orientación. Si los resultados del test son extraños, prueba a ajustar este parámetro.
{% endhint %}

Para saber exactamente los pines SPI de tu placa toolhead específica consulta su configuración de ejemplo oficial:

* [BTT EBB SB2209 / SB2240 — sample config](https://github.com/bigtreetech/EBB/tree/master/EBB%20SB2240_2209%20CAN)
* [BTT EBB36 / EBB42 — sample config](https://github.com/bigtreetech/EBB/tree/master/EBB%2036%20CAN%20V1.1%20and%20V1.2)
  {% endtab %}

{% tab title="LIS3DH e ICM-20948" %}
**Acelerómetros adicionales soportados nativamente por Klipper**

Desde 2024 Klipper soporta dos sensores adicionales que vienen integrados en cada vez más toolhead boards:

* **LIS3DH** — alternativa al LIS2DW, mismo fabricante (ST) y misma filosofía de uso. Se configura igual, soporta SPI o I2C. Habitual en placas SHT36/SHT42 de Mellow y similares.
* **ICM-20948** — de la familia MPU (Invensense/TDK), conexión I2C. Reemplazo natural del MPU-9250 con mejores prestaciones.

{% hint style="info" %}
Hubo un bug inicial en el driver del ICM-20948 que dejaba el sensor en escala 2g por defecto en vez de 8g. Si tu Klipper es de finales de 2023 o principios de 2024, **actualiza antes de calibrar** — los valores serían incorrectos.
{% endhint %}

**Configuración LIS3DH (SPI), ejemplo en una toolhead Mellow SHT36 v3:**

```django
[lis3dh]
cs_pin: SHT36:gpio9
spi_software_sclk_pin: SHT36:gpio10
spi_software_mosi_pin: SHT36:gpio11
spi_software_miso_pin: SHT36:gpio12
axes_map: x, y, z

[resonance_tester]
accel_chip: lis3dh
probe_points:
    125, 125, 20  # ajusta al centro de tu cama
```

**Configuración LIS3DH (I2C):**

```django
[lis3dh]
i2c_mcu: SHT36
i2c_bus: i2c1
axes_map: x, y, z

[resonance_tester]
accel_chip: lis3dh
probe_points:
    125, 125, 20
```

**Configuración ICM-20948 (I2C):**

```django
[icm20948]
i2c_mcu: rpi
i2c_bus: i2c.1
i2c_speed: 400000   # importante: el ICM-20948 trabaja a 400kHz
axes_map: x, y, z

[resonance_tester]
accel_chip: icm20948
probe_points:
    125, 125, 20
```

{% hint style="success" %}
**Comprobación rápida**

Una vez añadida la configuración y reiniciado Klipper, ejecuta `ACCELEROMETER_QUERY` para verificar que el sensor responde correctamente y devuelve unos valores cercanos a 9800 mm/s² en uno de los ejes (la gravedad). Si no responde o los valores son extraños, revisa el cableado y el `axes_map`.
{% endhint %}

{% hint style="warning" %}
Tanto LIS3DH como ICM-20948 usan exactamente el mismo flujo de calibración que el ADXL345: `TEST_RESONANCES`, `SHAPER_CALIBRATE`, `calibrate_shaper.py`. Solo cambia la sección de configuración y el nombre del `accel_chip`.
{% endhint %}
{% endtab %}
{% endtabs %}

{% hint style="success" %}
Sobre puntos de sondeo Input Shaper.

Dentro de nuestra configuración de \[resonance\_tester] hay un parámetro muy importante a tener en cuenta... probe\_points.

Normalmente, y dado que no vivimos en un mundo perfecto independientemente de la máquina que tengamos, las vibraciones mecánicas de nuestra máquina pueden y van a ser diferentes en distintas partes de nuestra impresora... por ejemplo el patrón de vibraciones puede NO ser, en especial dependiendo del tipo de cinemática, las mismas a diferentes alturas de Z o coordenadas de XY.

En estos casos puede ser aconsejable, al menos para ver el estado de nuestra máquina, el realizar testeos en diferentes puntos de nuestras coordenadas XY y Z.

* en ejes X suele ser aconsejable añadir 3 coordenadas, 1/3 de X, 1/2 de X y 2/3 de X
* aplicaremos en Y y Z la misma fórmula teniendo una malla de 21 puntos

Realizando este check podréis observar como afecta la ubicación de vuestro sensor a vuestras resonancias pudiendo identificar puntos de mejora.

Para un uso normal del test de Input Shaper suele ser suficiente con añadir en nuestro probe\_points una malla de 9 puntos XY en una altura de 1/3 de Z, o en su defecto la altura máxima de nuestras impresiones si normalmente son más bajas que ese valor.

```django
[resonance_tester]
accel_chip: adxl345 fysetc
probe_points:
    73,146,83 # point YrearXleft
    110,146,83 # point YrearXmidle
    146,146,83 # point YrearXright
    73,110,83 # point YmidleXleft
    110,110,83 # point YmidleXmidle
    146,110,83 # point YmidleXright
    73,73,83 # point YfrontXleft
    110,73,83 # point YfrontXmidle
    146,73,83 # point YfrontXright
    
```

Este proceso es aconsejable para usuarios avanzados que quieran averiguar el estado de su máquina e intentar ajustar/mejorar al máximo esta.
{% endhint %}

### Instalando el software necesario en nuestro Klipper

Para procesar los datos del acelerómetro Klipper necesita algunas dependencias Python. **La mayoría de distribuciones modernas (MainsailOS, FluiddOS, RatOS) las incluyen preinstaladas** — si acabas de instalar desde una de ellas puedes pasar directamente a la sección de comprobaciones.

Si tienes una instalación antigua o una imagen base sin estas dependencias, instálalas por SSH:

```bash
# Dependencias del sistema
sudo apt update
sudo apt install python3-numpy python3-matplotlib libatlas-base-dev

# numpy en el entorno virtual de Klipper
~/klippy-env/bin/pip install -v numpy
```

{% hint style="info" %}
En Raspberry Pi 3 o hardware similar este proceso puede tardar 10-15 minutos compilando numpy. Es normal — espera a que termine.
{% endhint %}

{% hint style="warning" %}
Si el comando anterior falla por versión de Python, prueba con:

```bash
~/klippy-env/bin/pip3 install -v numpy
```

{% endhint %}

Más información en la [**documentación de Klipper**](https://www.klipper3d.org/Measuring_Resonances.html).

### Comprobaciones

* Con todo conectado iremos a la consola/terminal de nuestra UI de Klipper y ejecutaremos:

```
ACCELEROMETER_QUERY
```

{% hint style="info" %}
En el caso que tengamos definido nuestro acelerómetro con un ID, como hicimos en el caso del Fysetc Pico, es necesario especificar el ID:

```django
ACCELEROMETER_QUERY CHIP=fysetc
```

{% endhint %}

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

Es posible que al intentar la primera medida de nuestro acelerómetro, asegurándonos que previamente nuestra Pi Pico y/o nuestro Klipper ha sido reiniciado, puede dar errores.

Estos errores iniciales pueden pasar en el caso que nuestra comunicación SPI no se inicializó correctamente. Normalmente si esta todo bien configurado/conectado las siguientes medias deberían de funcionar.

En el caso que nos devuelva error deberemos:

* revisar que nuestro cableado entre la Pi y nuestro acelerómetro sea el correcto y las conexiones mejor soldadas evitando conectores Dupont, JST pueden usarse ya que tienen mejor sujeción por norma general
* que el cableado entre ambos no sea demasiado largo
* en algunos casos raros y dependiendo la calidad del acelerómetro puede dar errores que puedes ver en la siguiente captura. En esos casos podemos mirar de desconectar el cable GND para ver si así funciona de forma correcta

<img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/A9IBlwSllMAYLUs33XDo/image.png" alt="" data-size="original">
{% endhint %}

* Si obtenemos una respuesta como la siguiente el acelerómetro funciona correctamente!!!

```
adxl345 values (x, y, z): 6042.857730, 5507.414640, -5889.873990
```

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/tv6jzqpih9Ua91VXTFTF/image.png" alt=""><figcaption><p>Ejemplo de un ACCELEROMETER_QUERY para un Fysetc Pico</p></figcaption></figure>

{% hint style="warning" %}
**Dado que el proceso genera bastante uso de MCU si usamos un Arduino y no es muy potente se pueded dar problemas de desconexiones.**

**Para evitar este problema&#x20;*****bajaremos el parámetro rate a 1600 o 800 dentro de nuestra sección \[adxl345]*****.**

<img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/zNAnbQ8nfGbPsQVNUmst/image.png" alt="" data-size="original">
{% endhint %}

### Medición de resonancias

Ahora que ya tenemos todo configurado vamos a proceder a realizar nuestro test de resonancias.

En el caso que nuestra impresora sea Cartesiana, nuestra cama es un eje de movimiento, debereis realizar los tests en los ejes X e Y de forma independiente colocando vuestro acelerómetro bien anclado en el eje X y después moverlo al eje Y.

En el caso de una CoreXY no necesitamos cambiar el acelerómetro ya que anclando firmemente este a nuestro cabezal de impresión podremos medir ambos ejes.

{% hint style="info" %}
**A continuación podéis ver el modo manual aconsejado por Klipper, en nuetro caso y para que sea más sencillo la generación y uso de las gráficas os aconsejamos, aunque inicialmente tenga un poco más de trabajo,**[ **realizar este proceso usando macros shell**](#automatizando-el-test-de-resonancias)**.**

**En el caso que ya uses RatOS, que es de donde hemos obtenido esas macros/scripts, no es necesario tener que realizar esos pasos en tu configuración.**
{% endhint %}

#### Test resonancias eje X

* lanzaremos por consola/terminal desde nuestra UI el siguiente comando

```
TEST_RESONANCES AXIS=X
```

#### Test resonancias eje Y

* lanzaremos por consola/terminal desde nuestra UI el siguiente comando

```
TEST_RESONANCES AXIS=Y
```

{% hint style="info" %}
Podemos ajustar los rangos de nuestro test para obtener más detalle añadiendo los siguientes parámetros a nuestro TEST\_RESONANCES:

* FREQ\_START=\<min\_freq>
* FREQ\_END=\<max\_freq>

<https://www.klipper3d.org/G-Codes.html#test_resonances>
{% endhint %}

{% hint style="success" %}
En el caso que usemos los scripts que os aconsejamos anteriormente lanzar el proceso es muy sencillo tal como podéis ver en la siguiente imagen, al finalizar el proceso nos dejara las imágenes generadas en una carpeta **input\_shaper** en la **pestaña MACHINE** en el caso que usemos Mainsail:

<img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/qsdlUy1kzH3xB6CAby2E/image.png" alt="" data-size="original">
{% endhint %}

{% hint style="danger" %}
**Es muy aconsejable, al menos durante la primera vez que lancemos el proceso, estar muy atentos a que las vibraciones provocadas por el test no sean muy violentas y puedan dañar nuestra impresora.**\
**Podéis usar el comando M112 o el botón EMERGENCY STOP en vuestra UI para parar el proceso.**
{% endhint %}

#### Revisar los resultados

El proceso anterior generará dos ficheros CSV con los resultados del test.

{% hint style="info" %}
También disponemos de una[ **herramienta online para analizar estos CSV**](https://3dwork.io/tools/#shaper) y generar estas gráficas al igual que las modificaciones en vuestro printer.cfg.

<https://3dwork.io/tools/#shaper>

<img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FQ1nrqzqAKDydPaOLJpKk%2Fimage.png?alt=media&amp;token=7b2eab56-7f89-4f33-b5e5-caa6b7960d3b" alt="" data-size="original">
{% endhint %}

Estos CSV se procesarán ejecutando (hay algunos scripts/macros que pueden simplificar la vida) los siguientes comandos desde el terminal SSH:

```
~/klipper/scripts/calibrate_shaper.py /tmp/resonances_x_*.csv -o /tmp/shaper_calibrate_x.png
~/klipper/scripts/calibrate_shaper.py /tmp/resonances_y_*.csv -o /tmp/shaper_calibrate_y.png
```

{% hint style="success" %}
**Un pequeño gran truco si no usáis los scrips que os aconsejamos más abajo...**

A la hora de lanzar los comandos anteriores podemos modificar los parámetros del path de la imagen para dejarlo en nuestro /config, donde tenemos nuestro printer.cfg, accesible desde vuestra UI para poder verlo directamente sin tener que hacer nada.

Quedaría algo similar a esto, para un sistema Raspbian... adaptarlo si no es vuestro caso:

<pre class="language-bash"><code class="lang-bash"><strong>~/klipper/scripts/calibrate_shaper.py /tmp/resonances_x_*.csv -o /home/pi/printer_data/config/shaper_calibrate_x.png
</strong>~/klipper/scripts/calibrate_shaper.py /tmp/resonances_y_*.csv -o /home/pi/printer_data/config/shaper_calibrate_y.png

</code></pre>

{% endhint %}

Estos scripts generarán unas imágenes con unas gráficas con información de las respuestas en frecuencia de nuestra máquina además de sugerirnos las más adecuadas:

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/nucviMsjeaK5lUTpFaOX/image.png)

#### Como interpretar los resultados

Un aspecto importante es interpretar los resultados que nos aportan las gráficas generadas de Input Shaper:

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2F7My138D7lq2OPQod93b2%2Fimage.png?alt=media&amp;token=2d0dd8f1-b685-4806-b900-b3b78df6bad3" alt=""><figcaption></figcaption></figure>

las **lineas contínuas son las frecuencias medidas por el acelerómetro**

* las **lineas de puntos representan la teórica reducción de vibraciones dependiendo del tipo de método de compensación de input shaper**.

En cualquier caso os damos algunas sugerencias que pueden ayudar en el proceso.

* la **ubicación y anclaje del sensor es muy importante**, aunque no es necesario estrictamente el ajuste de la orientación del sensor si que es aconsejable seguirla y dejar el sensor centrado en el cabezal de impresion a ser posible lo más cercano a la vertical del nozzle
* generalmente **buscamos que las líneas de puntos (estimación de reducción de vibraciones) se encuentren lo más bajas posibles en contraposición a las líneas continuas (lecturas de vibración del sensor)**
* las **vibraciones por debajo de 25Hz no son buenas amigas**.... básicamente porque las vibraciones a más altas frecuencias son más fáciles de cancelar, idealmente superiores a 50-70 Hz.\
  Si las tienes es aconsejable revisar en detalle holguras/escuadras en el chasis, problemas de cinemática como correas poco o demasiado tensas... básicamente porque van a limitar bastante las aceleraciones de la máquina
* **lo ideal es que las graficas no tengan doble o más picos** siendo lo ideal una onda como podéis ver en la imagen del video de abajo. En el caso de tenerlas revisar holguras además de tensiones de correas. Aunque no siempre tiene porqué ser así ya que es importante fijarse en la escala y sus magnitudes.
* En **máquinas CoreXY el rango de frecuencias debería de ser muy similar en ambos casos** aunque normalmente el eje Y suele estar un poco más bajo que el X

Además de lo anterior es importante, con referencia al tipo de Input Shaper sugerido, que tengamos en cuenta los siguientes puntos:

* los tipos **2HUMP\_EI y 3HUMP\_EI normalmente se sugieren cuando nuestras gráficas tengan varias puntas de resonancias**, picos en nuestra onda, por lo que si se os sugieren este tipo de Input Shaper lo ideal es revisar nuestro chásis (sin holguras y escuadrado), mecánica (motores con su configuración óptima y bien anclados) y cinemática (tensado y alineado de correas, poleas en buen estado, lubricación, ajuste excéntricas) para intentar mitigar esos picos de vibraciones.\
  Por lo anterior **son los métodos idealmente a evitar usar ya que indicaría que nuestra máquina estructuralmente pueda tener deficiencias**.\
  En el siguiente ejemplo veréis una máquina sin ajuste de correas como aparece la gráfica y el tipo que suguiere de input shaper y una vez tensadas correctamente las correas:

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/FFVJG6voQXKiKgbufeJj/image.png) ![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/JjDX460cCvkReQ88uRJP/image.png)

* Normalmente **los Input Shaper más aconsejables son MZV y EI**
  * **EI normalmente suele ser el más adecuado para máquinas Cartesianas** (el eje Y, cama, se desplaza) **y Delta** ya que se comporta mejor con cambios en resonancias en la máquina.
  * **MZV o ZV normalmente funcionan mejor en máquinas CoreXY**

{% hint style="success" %}
Teniendo en cuenta lo anterior nuestro consejo sería realizar el [test de resonancias impreso](#manual) usando el sugerido por el test del acelerómetro y, si no coincide, con el aconsejable para nuestra máquina para ver las diferencias entre ellos ante un test real.
{% endhint %}

#### Smoothing/Alisado

Por último nos gustaría comentar que **Input Shaper puede llegar a generar unas piezas "alisadas" en exceso afectando al acabado final de esta y sus detalles** por lo que en estos casos que el algoritmo elige una frecuencia que no es óptima podemos optar por aplicar menos alisado con el coste de incrementar las resonancias.

Dependiendo del tipo de Input Shaper seleccionado:

* ZV/MZV/EI, suelen tener unos valores bajos de smooth por lo que es un tipo adecuado para no requerir un ajuste fino de alisado
* 2HUMP\_EI/3HUMP\_EI, suelen tener unos altos valores de smooth por lo que si no nos queda mas remedio que usarlo es aconsejable un ajuste fino de alisado

Para realizar un ajuste fino de smooth/alisado cuando usamos Input Shaper:

Teniendo el siguiente resultado de un test normal:

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/KcgLvcvPWHZqoFvTn1ZR/image.png" alt=""><figcaption></figcaption></figure>

Vemos que ZV apenas tiene smoothing/alisado, MZV/EI tienen unos valores medios de smoothing/alisado, y 2HUMP\_EI/3HUMP\_EI tienen unos valores altos.

En el caso que usemos unos de estos tipos con medio/alto smoothing/alisados podremos intentar ver como reducir este lanzando una simulación limitando el valor máximo de smoothing, lo que nos adaptará para aquellos que superen ese valor máximo de smoothing los valores calculados. Añadiremos el valor smoothing máximo deseado, `--max_smoothing=0.2` en la parte final, en el siguiente script :

```terminal
~/klipper/scripts/calibrate_shaper.py /tmp/resonances_x_*.csv -o /tmp/shaper_calibrate_x.png --max_smoothing=0.2
```

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/PgNTYkOit6jM71nFQo0l/image.png" alt=""><figcaption></figcaption></figure>

Comparando ambos resultados veremos que tenemos más resonancias pero el valor de alisado/smoothing es mucho mejor algo que afectará a las las aceleraciones de Input Shaper.

Una vez tengamos el valor de max\_smooth deseado lo meteremos en la sección \[resonance\_tester] y recordad actualizar las aceleraciones máximas de la impresora tal y como las calculamos en puntos anteriores ya que con este ajuste suelen cambiar:

```
[resonance_tester]
accel_chip: ...
probe_points: ...
max_smoothing: 0.25  # an example
```

{% hint style="info" %}
En el caso que usemos el test automático de resonancias que explicamos mas abajo, SHAPER\_CALIBRATE, usará el valor de max\_smoothing como referencia para lanzar el test.
{% endhint %}

**Como siempre os aconsejamos realizar varios tests en real para encontrar el balance en vuestra máquina y piezas impresas que se ajusten más a vuestras necesidades.**

#### Videos interesantes en referencia a como interpretar la información del proceso Input Shaper

A continuación podéis ver estos videos que pueden ayudar a comprender estas gráficas:

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

{% embed url="<https://m.youtube.com/watch?v=M-yc_XM8sP4&feature=youtu.be>" %}

### Añadir la información de Input Shaper en nuestra configuración

Una vez ya tenemos la configuración sugerida para nuestra máquina añadiremos esta a nuestro printer.cfg en la sección \[input\_shaper] y actualizaremos las aceleraciones máximas de nuestro \[printer]

```
## ejemplo de valores input shaper para Y según gráfica anterior
[input_shaper]
shaper_freq_x: ...
shaper_type_x: ...
shaper_freq_y: 34.6
shaper_type_y: mzv
```

En el caso de las acceleraciones máximas es aconsejable seleccionar el valor que no supere los valores calculados en el ejes X e Y (usaremos el más bajo de ellos) además de añadir un cierto margen de seguridad como por ejemplo el 90% del valor que obtuvimos en los tests (de nuevo sobre el eje que nos dio el valor más bajo):

```
## actualizacion de aceleraciones max que no deberia superar los valores maximos de aceleracion obtenidos en X e  Y
[printer]
max_accel: 3000 
```

### Ajuste automático de valores de resonancia por Klipper

{% hint style="info" %}
El siguiente proceso es aconsejable realizarlo en el caso que antes realicemos el proceso anterior prestando especial atención en ajustar nuestra máquina para encontrar el punto óptimo de nuestra máquina para obtener los mejores resultados de Input Shaper.

Aunque usemos el método que suerimos a continuación os recomendamos de forma periódica o cuando ajustemos algo en la máquina a nivel mecánico realizar el proceso manual para volver a ajustarla correctamente.
{% endhint %}

Klipper dispone de una macro que ejecuta los tests de Input Shaper y seleccionará de forma automática, y en ocasiones no tienen porqué ser los más óptimos, los ajustes de Input Shaper.

Lanzaremos desde nuestro terminal la siguiente macro:

* En el caso de **máquinas CoreXY** o si disponemos de 2 acelerómetros instalados y configurados para X e Y:

```django
SHAPER_CALIBRATE
```

* En el caso que tengamos **una máquina no CoreXY y que tengamos que medir de forma independiente cada eje lanzaremos** la macro especificando cada eje a testear:

```django
SHAPER_CALIBRATE AXIS=X
SHAPER_CALIBRATE AXIS=Y
```

Al igual que el proceso manual lanzará el proceso Input Shaper y nos generará nuestro csv en /tmp/calibration\_data\_\*.csv y nos indicará en el terminal también la información del test:

```
Calculating the best input shaper parameters for y axis
Fitted shaper 'zv' frequency = 39.0 Hz (vibrations = 13.2%, smoothing ~= 0.105)
To avoid too much smoothing with 'zv', suggested max_accel <= 5900 mm/sec^2
Fitted shaper 'mzv' frequency = 36.8 Hz (vibrations = 1.7%, smoothing ~= 0.150)
To avoid too much smoothing with 'mzv', suggested max_accel <= 4000 mm/sec^2
Fitted shaper 'ei' frequency = 36.6 Hz (vibrations = 2.2%, smoothing ~= 0.240)
To avoid too much smoothing with 'ei', suggested max_accel <= 2500 mm/sec^2
Fitted shaper '2hump_ei' frequency = 48.0 Hz (vibrations = 0.0%, smoothing ~= 0.234)
To avoid too much smoothing with '2hump_ei', suggested max_accel <= 2500 mm/sec^2
Fitted shaper '3hump_ei' frequency = 59.0 Hz (vibrations = 0.0%, smoothing ~= 0.235)
To avoid too much smoothing with '3hump_ei', suggested max_accel <= 2500 mm/sec^2
Recommended shaper_type_y = mzv, shaper_freq_y = 36.8 Hz
```

En el caso que nos parezcan bien **los parámetros sugeridos ejecutaremos la macro SAVE\_CONFIG y reniciar Klipper.** <mark style="color:orange;">**Recuerda que este proceso no ajusta el max\_accel de la sección \[printer] que deberemos ajustar manualmente**</mark> tal como hicimos anteriormente.

{% hint style="warning" %}
**El proceso de Input Shaper NO es aconsejable realizarlo de forma frecuente, ponerlo al inicio de cada impresion por ejemplo no suele ser buena idea.**

**El proceso de Input Shaper genera una serie de vibraciones extremas que pueden llegar a dañar o desajustar nuestra impresora.**
{% endhint %}

### Calibración en una sola pasada (single pass)

{% hint style="info" %}
Esta funcionalidad ya estaba disponible pero ha pasado a estar **bien documentada y soportada de forma estable** en Klipper. Si tu impresora monta dos acelerómetros (uno en el cabezal y otro en la cama, o uno por toolhead en multi-extrusor) puedes calibrar **los dos ejes a la vez** sin tener que mover físicamente el sensor.
{% endhint %}

Habitualmente en una **cartesiana** (bed slinger) hay que ejecutar `SHAPER_CALIBRATE AXIS=X` y luego `SHAPER_CALIBRATE AXIS=Y` moviendo el acelerómetro entre el cabezal y la cama. Con **dos acelerómetros** ese paso desaparece: Klipper mide ambos ejes simultáneamente en una única ejecución.

**Configuración con dos acelerómetros (ej. ADXL345):**

```django
[adxl345 hotend]
cs_pin: rpi:None     # u otro pin SPI del cabezal
spi_speed: 5000000
spi_bus: spidev0.0

[adxl345 bed]
cs_pin: MCU:PA4      # un segundo SPI, en este ejemplo en la MCU principal

[resonance_tester]
accel_chip_x: adxl345 hotend
accel_chip_y: adxl345 bed
probe_points:
    100,100,20
```

{% hint style="success" %}
Date cuenta del cambio respecto a la configuración estándar: ya no se usa `accel_chip:`, sino `accel_chip_x:` y `accel_chip_y:`. Klipper sabe automáticamente qué acelerómetro corresponde a cada eje y, al lanzar `SHAPER_CALIBRATE` **sin** el parámetro `AXIS=...`, calibra ambos en una sola pasada:

```gcode
SHAPER_CALIBRATE
SAVE_CONFIG
```

{% endhint %}

**Variante con dos MPU-9250 / ICM-20948 (I2C):**

Como ambos chips comparten bus, hay que jugar con `i2c_address` (pin AD0 a GND o a VCC):

```django
[mpu9250 hotend]
i2c_address: 104   # AD0 a GND

[mpu9250 bed]
i2c_address: 105   # AD0 a VCC

[resonance_tester]
accel_chip_x: mpu9250 hotend
accel_chip_y: mpu9250 bed
probe_points:
    100,100,20
```

{% hint style="warning" %}
**Otra mejora importante de SHAPER\_CALIBRATE** — desde mediados de 2023 los valores calculados se aplican **al instante** si ya tienes una sección `[input_shaper]` en tu printer.cfg. Antes hacía falta un `RESTART` después de `SAVE_CONFIG`. Hoy puedes lanzar el test, revisar la gráfica e imprimir un test inmediatamente con los nuevos valores ya activos, y solo guardarlos definitivamente cuando estés convencido.
{% endhint %}

### Sweeping vibrations — método de medición mejorado (Klipper 0.13+)

A partir de **Klipper v0.13.0** (abril 2025) se introdujo un nuevo método de medición de resonancias llamado **sweeping vibrations**. El proceso clásico generaba vibraciones a frecuencia fija con el cabezal parado en un único punto; el nuevo método **superpone un movimiento lento de barrido (sweep)** mientras se inyectan las vibraciones, de forma que el cabezal recorre una pequeña área en lugar de quedarse quieto.

**¿Qué mejora respecto al test clásico?**

* Excita mejor los modos de resonancia mecánica, especialmente los que dependen de la posición del cabezal.
* Reduce los falsos positivos cuando justo el punto de sondeo coincide con una zona con fricción anómala o una holgura local.
* Detecta resonancias a frecuencias ligeramente más bajas que el método antiguo, normalmente más cercanas al comportamiento real durante una impresión.

**Cómo activarlo**

El nuevo método se controla mediante dos parámetros en la sección `[resonance_tester]`:

```django
[resonance_tester]
accel_chip: adxl345
probe_points:
    100,100,20
# Sweeping vibrations
sweeping_accel: 400      # mm/sec² del barrido (valor por defecto razonable)
sweeping_period: 1.2     # periodo del barrido en segundos
```

* `sweeping_period: 0` (valor por defecto) → **desactivado**, se usa el método clásico de toda la vida.
* `sweeping_period > 0` → activa el barrido. La amplitud del recorrido durante el test es aproximadamente `sweeping_accel * sweeping_period² / 32` (con los valores del ejemplo, unos 18 mm).

{% hint style="info" %}
No hace falta cambiar los comandos: se siguen usando `TEST_RESONANCES`, `SHAPER_CALIBRATE`, etc. La diferencia es interna: con `sweeping_period` distinto de 0, Klipper añade el barrido al test.
{% endhint %}

{% hint style="warning" %}
Si tu impresora tiene poco espacio útil alrededor del punto de sondeo (cabezales grandes, accesorios cerca del nozzle...) **asegúrate de que la amplitud del barrido no provoca colisiones**. Reduce `sweeping_accel` y/o `sweeping_period` si es el caso, o vuelve al método clásico con `sweeping_period: 0`.
{% endhint %}

{% hint style="success" %}
**Recomendación 3Dwork:** si vienes del método antiguo, prueba primero los valores por defecto del sweeping y compara los resultados con tu calibración previa. En la mayoría de máquinas el método nuevo da unas gráficas más limpias y unos parámetros más conservadores (y por tanto, más estables en uso diario).
{% endhint %}

### Automatizando el test de resonancias

El proceso anterior es el aconsejado por **Klipper** pero gracias a los amigos de **Ratrig** con su **RatOS** **podemos aprovechar algunas partes para automatizar el proceso y que simplemente con unos clicks desde nuestra UI podamos realizar el proceso de forma mucho más cómoda.**

{% hint style="danger" %}
**Para que Klipper pueda ejecutar shell macros se ha de instalar una extensión, gracias al compañero** [**Arksine**](https://github.com/Arksine)**, que lo permita.**

<mark style="color:green;">**Dependiendo de la distro de Klipper usada pueden venir ya habilitadas.**</mark>

<img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/TfVEVUxY0srHCQCN3Gjw/image.png" alt="" data-size="original">

La forma más sencilla es usando [**Kiauh**](/klipper/instalacion#instalando-kiauh) donde encontraremos en una de sus opciones la posibilidad de instalar esta extensión:

<img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/0FjYUlWC4phJ8vcuaeqT/telegram-cloud-photo-size-4-5837048490604215201-x_partial.jpg" alt="" data-size="original">

También podemos realizar el proceso a mano copiaremos manualmente el plugin para Klipper[ **gcode\_shell\_extension**](https://raw.githubusercontent.com/Rat-OS/RatOS/master/src/modules/ratos/filesystem/home/pi/klipper/klippy/extras/gcode_shell_command.py) dentro de nuestro directorio ***`~/klipper/klippy/extras`*** usando SSH o SCP y reiniciamos Klipper.
{% endhint %}

#### Creando nuestros scripts de test de resonancias

Para seguir con la misma estructura que tiene RatOS lo ideal es **crear una carpeta "scripts" en nuestro directorio de configuraciones Klipper donde crearemos los siguientes ficheros**.

[**generate-shaper-graph-x.sh**](https://raw.githubusercontent.com/Rat-OS/RatOS-configuration/v2.x/scripts/generate-shaper-graph-x.sh) **- para generar gráficas del eje X**

{% code title="generate-shaper-graph-x.sh - <https://github.com/Rat-OS/RatOS-configuration/blob/master/scripts/generate-shaper-graph-x.sh>" %}

```bash
#!/bin/bash

NEWX=$(ls -Art /tmp/resonances_x_*.csv | tail -n 1)
DATE=$(date +'%Y-%m-%d-%H%M%S')
if [ ! -d "/home/pi/printer_data/config/input_shaper" ]
then
    mkdir /home/pi/printer_data/config/input_shaper
    chown pi:pi /home/pi/printer_data/config/input_shaper
fi

~/klipper/scripts/calibrate_shaper.py $NEWX -o /home/pi/printer_data/config/input_shaper/resonances_x_$DATE.png
```

{% endcode %}

[**generate-shaper-graph-y.sh**](https://raw.githubusercontent.com/Rat-OS/RatOS-configuration/v2.x/scripts/generate-shaper-graph-y.sh) **- para generar gráficas del eje Y**

```bash
#!/bin/bash

NEWY=$(ls -Art /tmp/resonances_y_*.csv | tail -n 1)
DATE=$(date +'%Y-%m-%d-%H%M%S')
if [ ! -d "/home/pi/printer_data/config/input_shaper" ]
then
    mkdir /home/pi/printer_data/config/input_shaper
    chown pi:pi /home/pi/printer_data/config/input_shaper
fi

~/klipper/scripts/calibrate_shaper.py $NEWY -o /home/pi/printer_data/config/input_shaper/resonances_y_$DATE.png
```

[**generate-belt-tension-graph.sh**](https://raw.githubusercontent.com/Rat-OS/RatOS-configuration/v2.x/scripts/generate-belt-tension-graph.sh) **- para generar gráficas de tensión de correas (CoreXY aconsejable)**

```bash
#!/bin/bash
set -e -u -o pipefail

## the TEST_RESONANCES command seems to return before all data is completely
## written. it'd be better to poll for the files to be completely written,
## but this has been reliable for me so far…
sleep 10

outdir=/home/pi/printer_data/config/input_shaper
if [ ! -d "${outdir}" ]; then
    mkdir "${outdir}"
fi

~/klipper/scripts/graph_accelerometer.py \
    -c /tmp/raw_data_axis*_belt-tension-*.csv \
    -o "${outdir}/belt-tension-resonances-$( date +'%Y-%m-%d-%H%M%S' ).png"
```

Estos scripts se usarán por nuestras nuevas macros para generar las gráficas con los resultados de nuestros tests de input shaper.

{% hint style="danger" %}
**Es importante recordar que si los path indicados o usados en los scripts no coinciden con tu instalación deberás adaptarlos.**

**Además asegúrate que tus scripts tienen permisos de ejecución con el comando&#x20;*****chmod +x nombre\_fichero.sh*** **desde SSH**
{% endhint %}

#### Creando nuestras nuevas macros para input shaper

Ahora que ya tenemos nuestros scripts listos crearemos nuestras macros de gestion de input shaper.

Para ello y **a la altura de nuestro printer.cfg crearemos un nuevo fichero** **shell-macros.cfg** donde añadiremos nuestras macros que usen scripts, dado que Klipper tiene un sistema modular creemos que es la mejor forma para que quede todo más limpio y fácil de tener la configuración de nuestra máquina ordenada.

{% code title="shell-macros.cfg" %}

```django
[gcode_shell_command generate_shaper_graph_x]
command: /home/pi/printer_data/config/scripts/generate-shaper-graph-x.sh
timeout: 60.
verbose: True

[gcode_shell_command generate_shaper_graph_y]
command: /home/pi/printer_data/config/scripts/generate-shaper-graph-y.sh
timeout: 60.
verbose: True

[gcode_shell_command generate_belt_tension_graph]
command: /home/pi/printer_data/config/scripts/generate-belt-tension-graph.sh
timeout: 90.
verbose: True

[gcode_macro GENERATE_SHAPER_GRAPHS]
description: Genarates input shaper resonances graphs for analysis. Uses the AXIS parameter for if you only want to do one axis at a time, (eg. GENERATE_SHAPER_GRAPHS AXIS=X)
gcode:
    {% if params.AXIS is defined %}
        {% if params.AXIS|lower == 'x' %}
            G28
            TEST_RESONANCES AXIS=X
            RUN_SHELL_COMMAND CMD=generate_shaper_graph_x
            RESPOND MSG="Input shaper graph generated for the X axis. You'll find it in the input_shaper folder in the machine tab!"
        {% elif params.AXIS|lower == 'y' %}
            G28
            TEST_RESONANCES AXIS=Y
            RUN_SHELL_COMMAND CMD=generate_shaper_graph_y
            RESPOND MSG="Input shaper graph generated for the Y axis. You'll find it in the input_shaper folder in the machine tab!"
        {% else %}
            {action_raise_error("Unknown axis specified. Expected X or Y.")}
        {% endif %}
    {% else %}
        G28
        TEST_RESONANCES AXIS=X
        TEST_RESONANCES AXIS=Y
        RUN_SHELL_COMMAND CMD=generate_shaper_graph_x
        RUN_SHELL_COMMAND CMD=generate_shaper_graph_y
        RESPOND MSG="Input shaper graphs generated for X and Y. You'll find them in the input_shaper folder in the machine tab!"
    {% endif %}
    
[gcode_macro MEASURE_COREXY_BELT_TENSION]
description: Generates resonance graph used to ensure belts are equally tensioned.
gcode:
    TEST_RESONANCES AXIS=1,1  OUTPUT=raw_data NAME=belt-tension-upper
    TEST_RESONANCES AXIS=1,-1 OUTPUT=raw_data NAME=belt-tension-lower
    RUN_SHELL_COMMAND CMD=generate_belt_tension_graph
    RESPOND MSG="Belt tension graphs generated. You'll find them in the input_shaper folder in the machine tab!"
```

{% endcode %}

{% hint style="warning" %}
**Estas macros utilizan la macro de sistema** [**RESPOND**](https://www.klipper3d.org/G-Codes.html#respond) **para notificaciones, en el caso que te de problemas asegúrate que tienes la&#x20;*****sección \[respond] en tu printer.cfg*****.**

**Con esto evitaremos el error en el terminal&#x20;*****// Unknown command:"RESPOND"***
{% endhint %}

Recordad que para que estas macros estén disponibles en Klipper hemos de añadir mediante include del fichero **shell-macros.cfg** creado anteriormente:

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

```django
...
[include shell-macros.cfg]
...
```

{% endcode %}

Estas nuevas macros se encargan de:

* **GENERATE\_SHAPER\_GRAPHS**, lanzará el proceso de **generar test de resonancias y las gráficas de input shaper para ambos ejes de forma automatizada (o de uno en concreto si así se lo indicas como parámetro) y nos dejara las imagenes dentro de la carpeta input shaper** para poderlas bajar de forma cómoda desde nuestra UI
* **MEASURE\_COREXY\_BELT\_TENSION***,* generará las gráficas de tensión de correas aconsejable en el caso de máquinas CoreXY

## Klippain Shake\&Tune — análisis avanzado de resonancias

[**Klippain Shake\&Tune**](https://github.com/Frix-x/klippain-shaketune) es una extensión de Klipper desarrollada por [Frix-x](https://github.com/Frix-x) que va mucho más allá del proceso estándar. Genera gráficas más detalladas, analiza la condición mecánica de la máquina y detecta problemas como correas desiguales o holguras.

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2F7My138D7lq2OPQod93b2%2Fimage.png?alt=media&amp;token=2d0dd8f1-b685-4806-b900-b3b78df6bad3" alt=""><figcaption><p>Ejemplo de gráfica Shake&#x26;Tune con análisis completo de resonancias</p></figcaption></figure>

### ¿Qué añade respecto al proceso estándar?

* **Gráficas más completas**: frecuencias, picos de resonancia, nivel de ruido y estimación de smoothing en una sola imagen
* **Análisis de correas (CoreXY)**: compara las resonancias de ambas correas para detectar desequilibrios
* **Análisis del sistema de extrusión**: detecta vibraciones en el motor del extrusor que pueden afectar a la calidad
* **Diagnóstico mecánico**: pistas sobre qué ajustar si los resultados son malos (holguras, correas, tornillos)
* **Macros integradas** desde la UI de Mainsail/Fluidd: no hace falta SSH para nada

### Instalación

```bash
cd ~/
git clone https://github.com/Frix-x/klippain-shaketune.git
```

Añade en tu `moonraker.conf`:

```ini
[update_manager Klippain-ShakeTune]
type: git_repo
origin: https://github.com/Frix-x/klippain-shaketune.git
path: ~/klippain-shaketune
virtualenv: ~/klippy-env
requirements: requirements.txt
system_dependencies: system-dependencies.json
primary_branch: main
managed_services: klipper
```

Añade en tu `printer.cfg`:

```ini
[shaketune]
# result_folder: ~/printer_data/config/ShakeTune_results
# number_of_results_to_keep: 3
# keep_raw_csv: False
# show_macros_in_webui: True
# timeout: 300
```

### Macros disponibles

Una vez instalado tendrás estas macros disponibles desde la UI:

| Macro                       | Descripción                                                     |
| --------------------------- | --------------------------------------------------------------- |
| `AXES_MAP_CALIBRATION`      | Detecta automáticamente el `axes_map` correcto del acelerómetro |
| `COMPARE_BELTS_RESPONSES`   | Compara resonancias de correas A y B (CoreXY)                   |
| `EXCITATE_AXIS_AT_FREQ`     | Excita un eje a una frecuencia para buscar holguras físicamente |
| `AXES_SHAPER_CALIBRATION`   | Test completo de resonancias con gráficas avanzadas             |
| `CREATE_VIBRATIONS_PROFILE` | Crea el perfil de vibraciones para Klipper                      |

{% hint style="info" %}
**Recomendado para usuarios de Voron, VzBot y cualquier CoreXY moderno.** La macro `COMPARE_BELTS_RESPONSES` es especialmente útil para asegurarse de que ambas correas están igual de tensadas antes de calibrar Input Shaper.
{% endhint %}

Para más información y documentación completa: <https://github.com/Frix-x/klippain-shaketune>

***

## Método manual sin acelerómetro.

[**Compensación de resonancias manual**](https://www.klipper3d.org/Resonance_Compensation.html), en este caso y mediante una [**torre de test**](https://www.klipper3d.org/prints/ringing_tower.stl) podremos encontrar y ajustar los valores de Input Shaping siguiendo las instrucciones del link anterior.

![Ajuste de Input Shaping manual.](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/i9g1ZzAnxp7ghmOTAvrT/image.png)

**Ajustes en el laminador para nuestra pieza de test:**

1. Ajustaremos **altura de capa a 0.2**
2. Pondremos a **0 el relleno y capas superiores**
3. **Perímetros en 1 y a ser posible imprimir en modo vaso**, 2 máximo si no usamos modo vaso
4. **Perímetros externos entre 80-120mm/s**, dependiendo de la calidad de nuestra máquina y la calidad de chasis/mecánica/cinemática... es aconsejable hacer el test a 80, 100, 120mm/s para ver en que rangos se comporta mejor la máquina.
5. **Tiempo mínimo de capa 3 segundos**, como mucho idealmente 0.
6. **Deshabilitar cualquier función de gestión o límites de aceleraciones** en el laminador.
7. **No girar el modelo de test**, está hecho para que cada cara coincida con el eje a probar.

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/w6eULzurYzDzR9TnoZ0L/image.png" alt=""><figcaption></figcaption></figure>

**Desde la consola de nuestra UI web de Klipper:**

1. **Si tenemos personalizado el valor `square_corner_velocity` lo dejaremos por defecto a 5.0**
2. **Deshabilitaremos `minimum_cruise_ratio`** para que no limite las aceleraciones del test: `SET_VELOCITY_LIMIT MINIMUM_CRUISE_RATIO=0`
3. Ajustaremos **Pressure Advance a 0** con `SET_PRESSURE_ADVANCE ADVANCE=0`.
4. **Deshabilitaremos Input Shaper** `SET_INPUT_SHAPER SHAPER_FREQ_X=0 SHAPER_FREQ_Y=0`. Si nos diera error no hemos de preocuparnos y continuamos con el siguiente paso.
5. En el caso que queramos testear un tipo de compensación Input Shaper usaremos `SET_INPUT_SHAPER SHAPER_TYPE=MZV` sustituyendo `SHAPER_TYPE` por el que queramos testear
6. Ejecutaremos: `TUNING_TOWER COMMAND=SET_VELOCITY_LIMIT PARAMETER=ACCEL START=1500 STEP_DELTA=500 STEP_HEIGHT=5`. Con este comando incrementamos cada 5mm la aceleración hasta finalizar la prueba de test en 7000 mm/s.

{% hint style="info" %}
Si creemos que nuestra máquina puede moverse correctamente con aceleraciones superiores podemos ajustar el test con estos parámetros:

* `ACCEL START=1500`
* `STEP_DELTA=500`
* `STEP_HEIGHT=5`
  {% endhint %}

**Una vez finalizado el test procederemos a analizar los resultados:**

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/MBFxLy4fnxldG9bP9WgD/image.png" alt=""><figcaption></figcaption></figure>

1. Aunque es obvio, usaremos las letras que aparecen en la pieza de test para identificar en que eje realizaremos los ajustes que obtengamos.
2. Usando un calibre de precisión mediremos la distancia entre varias oscilaciones como vemos en la imagen superior, obviaremos las series a mayor aceleraciones que tengan estas oscilaciones más marcadas y mediremos la distancia total entre 6-8 oscilaciones
3. Calcularemos la frecuencia de cada eje usando la siguiente fórmula:

$$
V\*N/D=Hz
$$

{% hint style="info" %}
**V** es la **velocidad** que usamos en los **perímetros externos**.\
**N** es el **número de oscilaciones medidas**.\
**D** es la **distancia** entre ellas.\
\
A modo de ejemplo, para un test a 100mm/s, medimos 8 oscilaciones con una distancia de 19mm:\
100\*8/19= 42 Hz
{% endhint %}

**Input Shaper configuración en Klipper**[**​**](https://www.obico.io/blog/klipper-input-shaping-ender-3/#input-shaper-configuration-in-klipper)

1. Editaremos nuestro printer.cfg
2. Añadiremos la siguiente sección:

<pre class="language-django"><code class="lang-django">[input_shaper]
<strong>shaper_freq_x: ... # frequencia X calculada
</strong>shaper_freq_y: ... # frequencia Y calculada
</code></pre>

3. Guardaremos los cambios y reiniciaremos Klipper.

Ahora que ya tenemos identificadas las frecuencias óptimas para nuestra máquina deberemos encontrar el tipo de Input Shaper adecuado para nuestra máquina.

Klipper, como tenéis más adelante explicado en detalle, cuenta con diferentes tipos de Input Shaper como MZV, EI, 2HUMP\_EI, o 3HUMP\_EI.

Para encontrar el tipo de Input Shaper adecuado:

1. Ejecutaremos los siguientes comando en consola para verificar nuestra configuración usando MZV como tipo de Input Shaper:<br>

   ```django
   SET_VELOCITY_LIMIT MINIMUM_CRUISE_RATIO=0
   SET_PRESSURE_ADVANCE ADVANCE=0
   SET_INPUT_SHAPER SHAPER_TYPE=MZV
   TUNING_TOWER COMMAND=SET_VELOCITY_LIMIT PARAMETER=ACCEL START=1500 STEP_DELTA=500 STEP_HEIGHT=5
   ```
2. Volveremos a imprimir la torre de test que realizamos en el paso anterior.
3. Reiniciaremos el sistema Klipper y nuestra máquina al finalizar y lanzaremos los siguientes comandos en consola para verificar nuestra configuración con EI como tipo de Input Shaper:<br>

   ```django
   SET_VELOCITY_LIMIT MINIMUM_CRUISE_RATIO=0
   SET_PRESSURE_ADVANCE ADVANCE=0
   SET_INPUT_SHAPER SHAPER_TYPE=EI
   TUNING_TOWER COMMAND=SET_VELOCITY_LIMIT PARAMETER=ACCEL START=1500 STEP_DELTA=500 STEP_HEIGHT=5
   ```
4. Volveremos a imprimir la torre de test y una vez finalizado el proceso comprobaremos ambas impresiones para ver cual de ellas ha mejorado en calidad.\
   En el caso que no veamos mejoras lanzaremos los tests para 2HUMP\_EI y 3HUMP\_EI aunque os adelantamos que si con estos vemos mejoras suele indicar que nuestra impresora pueda tener problemas mecánicos los cual se deberían revisar.\
   Para elegir uno u otro se han de ajustar la línea de comandos `SET_INPUT_SHAPER SHAPER_TYPE=` añadiendo al final los tipos que queramos testear de uno en uno.
5. Una vez tengamos seleccionado el input shaper adecuado para nuestra máquina ajustaremos nuestra configuración de Klipper:

   ```
   [input_shaper]
   shaper_freq_x: ... # frequencia X calculada
   shaper_freq_y: ... # frequencia Y calculada
   shaper_type: ... # el tipo de input shaper MZV, EI, 2HUMP_EI, o 3HUMP_EI
   ```
6. Guardaremos los cambios y reiniciaremos Klipper.

Otro paso aconsejable es ajustar la aceleaceleraciónración máxima ya que, en especial dependiendo del tipo de Input Shaper y tal como tenéis [explicado con más detalle más adelante](#smoothing-alisado), una aceleración muy alta o muy baja puede llegar a "matar"/alisar detalles de nuestras impresiones.

Ya tenemos nuestro Input Shaper calculado, podemos verificar resultados repitiendo la pieza de test pero saltando el punto 3 dentro de la parte de comandos en consola evitando de esa forma deshabilitar Input Shaper.

Para encontrar el valor óptimo para nuestro caso volveremos a revisar la torre donde elegimos el tipo de Input Shaper para revisar:

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FgjgPBZX0E590tnA9pgnd%2Fimage.png?alt=media&amp;token=9cd1906d-2263-4db2-a9e5-9a96730fe3db" alt=""><figcaption></figcaption></figure>

1. Verificaremos donde la hendidura donde comience a ampliarse. La torre de test comienza con aceleración de 1500 mm/S2 y lo aumenta en 500 mm/S2 a cada intervalo de 5 mm.\
   En la imagen anterior (que está rotada de 90 grados), puedes ver que el espacio se amplía y ve un hueco entre las trazadas de capa a aproximadamente 20-25 mm de altura. Esto indica que la mejor configuración de aceleración sería entre 3000-3500 mm/S2.\
   Seleccionaremos el valor más bajo del último rango que salga correctamete, 3000 mm/s2 para la imagen anterior.
2. Iremos a nuestra configuración de Klipper y dentro de la sección `[printer]` añadiremos o actualizaremos el valor de `max_accel` al valor óptimo, para el caso anterior `max_accel: 3000` .

**Si obtenemos un buen resultado podemos empezar a imprimir con un punto más de velocidad sin tener artefactos en nuestras impresiones!!!**

**Recuerda que para ello te aconsejamos revisar la** [**velociada máxima de tu máquina**](/klipper/empezamos/velocidad-maxima) **y tests en real con tus piezas para un ajuste fino.**


# Velocidad Máxima

Si en el paso anterior, [**Input Shaper**](/klipper/empezamos/input-shaper) donde nos centramos en encontrar las aceleraciones correctas para nuestra máquina... en este caso nos centraremos en encontrar la velocidad máxima usando esas aceleraciones óptimas sin perder precisión en nuestra máquina.

{% hint style="warning" %}
**Es importante recalcar que tanto velocidad como aceleraciones máximas obtenidas NO tienen porque ser las optimas o usables en nuestra máquina ya que puede depender de otros aspectos ajustar estas... como por ejemplo el tipo de pieza a imprimir, el tipo de filamento, etc..**

**El objetivo de este test es conocer la máxima velocidad, a las máximas aceleraciones óptimas calculadas previamente, que puede efectuar nuestra máquina sin pérdida de pasos. Lo cual puede ser útil para configuración de nuestros límites de máquina, traslados durante la impresión o** [**configuración MVS**](https://labs.3dwork.io/guias-impresion-3d/calibracion_3d#id-16.-ajuste-de-extrusion-volumetrica-opcional)**.**

**La velocidad máxima en impresión vendrá limitada por la capacidad de nuestro sistema de extrusión.**
{% endhint %}

{% hint style="info" %}
Algunos aspectos a tener en cuenta antes de empezar:

* es importante que **tengamos correctamente ajustadas las corrientes de nuestros motores**, en ocasiones aumentando (dentro de los límites drivers/motores) la corriente podemos obtener un poco más de torque
* tener **correctamente calculadas nuestras aceleraciones mediante Input Shaper** ya que tendremos rangos óptimos para nuestra máquina y sus vibraciones
* **motores de 1.8º pueden llegar generalmente a mayores velocidades/aceleraciones** **que motores de 0.9º**
* **sistemas HV (High Voltage) también ayudan a que nuestra máquina pueda llegar a mayores velocidades/aceleraciones**
  {% endhint %}

## Test de velocidad máxima

Para realizar el test vamos a utilizar la macro de nuestro compañero [**Ellis**](https://ellis3dp.com/) que dispone de una documentación excelente para el ajuste de nuestras máquinas.

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

Añadiendo esta [macro](/klipper/mejoras/macros-mejoras) a nuestro printer.cfg o cualquiera de nuestros includes nos permitirá usar la macro TEST\_SPEED que disponemos de los siguientes parámetros:

<table><thead><tr><th width="217.33333333333331">Parámetro</th><th>Valor x defecto</th><th>Descripción</th></tr></thead><tbody><tr><td><strong>SPEED</strong></td><td><strong>max_velocity</strong> de tu config</td><td>Máxima velocidad a realizar el test, es aconsejable incialmente dejar la de por defecto</td></tr><tr><td><strong>ACCEL</strong></td><td><strong>max_accel</strong> de tu config</td><td>Máxima aceleración al realizar el test, es aconsejable incialmente dejar la de por defecto.</td></tr><tr><td>CRUISE</td><td>minimum_cruise_ratio de tu config</td><td>Define el ratio a aplicar un ajuste de aceleración con base a una distancia de movimiento... por defecto 0.5</td></tr><tr><td><strong>ITERATIONS</strong></td><td>5</td><td>Número de veces a repetir el test.</td></tr><tr><td><strong>BOUND</strong></td><td>20</td><td>Normalmente no es necesario ajustarlo. Permite ajustar un espacio entre los márgenes de nuestra área de impresión y el test.</td></tr><tr><td><strong>SMALLPATTERNSIZE</strong></td><td>20</td><td>Normalmente no es necesario ajustarlo.</td></tr></tbody></table>

{% hint style="danger" %}
**Si ajustas las velocidades/aceleraciones al lanzar la macro a mano pueden cambiar los valores de tu configuración!!!**
{% endhint %}

* Para iniciar el proceso **lanzaremos la macro TEST\_SPEED desde nuestra consola o UI**

{% hint style="warning" %}
**Es importante que durante el proceso estar atentos a la máquina por si escuchamos que los motores pierden pasos o vemos que se hacen unos movimientos extraños que no tengan que ver con el test.**

**Es importante que tengamos correctamente definida el área de impresión en nuestra configuración, tenéis más información y detalle** [**aquí**](/klipper/empezamos/puesta-en-marcha-inicial#otras-secciones-importantes)**.**

**Pararemos la máquina de inmediato en esos casos y ajustaremos los parámetros del test.**
{% endhint %}

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/7ZYJfSo5rUvpY6JwFk1p/image.png" alt=""><figcaption><p>Podemos lanzar la macro desde la CONSOLA</p></figcaption></figure>

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/U7wtADn6iPiqwy04OlRl/image.png" alt=""><figcaption><p>También podemos lanzarla desde la UI ajustando los parámetros de una forma más simple.</p></figcaption></figure>

* Una vez finalizado el proceso nos fijaremos de nuevo en la consola:
  * revisaremos **los números marcados en los recuadros rojos que representan los micropasos de los ejes x e y**
  * **si esos valores no varían entre ellos más de un paso entero, nuestra velocidad máxima es correcta**.\ <mark style="color:red;">**(revisa el comentario al dónde se da más detalle sobre como evaluar si perdimos o no pasos dependiendo del tipo de final de carrera que usemos)**</mark>
  * **si estos valores varían más de un paso significará que nuestros ejes han perdido pasos y deberemos ajustar la velocidad máxima o ajustar nuestra configuración de corriente en motores, drivers o cinemática**

{% hint style="warning" %}
Usamos **la diferencia de un paso completo para minimizar la falta de precisión que puedan tener nuestros finales de carrera en el caso que usemos mecánicos o de alta precisión**.

<mark style="color:blue;">Normalmente los finales de carrera tradicionales, mecánicos/ópticos tienen una precisión de unos 100 micrones más que suficiente... en todo caso si queremos ajustar la precisión aún más podemos usar la función \[endstop\_phase]</mark> [<mark style="color:blue;">para mejorar esta precisión siguiendo estas instrucciones.</mark>](https://www.klipper3d.org/Endstop_Phase.html)

Por ejemplo, en el caso de un final de carrera preciso, si tenemos 16 micropasos la diferencia entre el valor inicial y final no debería superar el valor de 16.\
\
En el caso **de usar sensorless o sensores que tienen menos precisión podemos dar por bueno una desviación de unos pocos pasos enteros, de forma general usaremos 4 como un número límite**.

<mark style="color:red;">En estos casos, sensorless, es importante que vuestra</mark> [rutina de homing este ajustada correctamente](/klipper/empezamos/puesta-en-marcha-inicial#sensorless) <mark style="color:red;">ajustando lo más preciso posible la corriente en el momento del homing, las aceleraciones durante ese proceso y la sensibilidad de nuestros drivers.</mark>

Por ejemplo, y en el caso de sensores con poca precisión, si tenemos 16 micropasos la diferencia entre el valor inicial y final no debería superar el valor de 64.
{% endhint %}

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/oVW0gEfStAqPiDCcGgxU/image.png" alt=""><figcaption></figcaption></figure>

En el **caso de que tengamos una pérdida de pasos o creamos que nuestra máquina puede ir a velocidades superiores, podemos repetir el test hasta encontrar los valores óptimos**.

Ahora que ya tenemos nuestra velocidad máxima “segura” sin pérdida de pasos ajustaremos:

* nuestro printer.cfg para ajustar los límites de velocidad, en la sección \[printer] ajustamos a 300 mm/s:

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

```django
[printer]
kinematics: cartesian
max_velocity: 300
```

{% endcode %}

* si usamos [MVS o gestión de velocidad volumétrica](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) en nuestro laminador es aconsejable ajustarlo... aconsejamos dejar cierto margen y poner entre un 80-90% del valor obtenido
* de nuevo en nuestro laminador, podemos ajustar el valor de velocidad en traslados... aconsejamos dejar cierto margen y poner entre un 80-90% del valor obtenido

{% hint style="warning" %}
**Es importante recalcar que tanto velocidad como aceleraciones máximas obtenidas NO tienen porque ser las optimas o usables en nuestra máquina ya que puede depender de otros aspectos ajustar estas... como por ejemplo el tipo de pieza a imprimir, el tipo de filamento, etc..**

**El objetivo de este test es conocer la máxima velocidad, a las máximas aceleraciones óptimas calculadas previamente, que puede efectuar nuestra máquina sin pérdida de pasos. Lo cual puede ser útil para configuración de nuestros límites de máquina, traslados durante la impresión o configuración** [**MVS**](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)**.**

**La velocidad máxima en impresión vendrá limitada por la capacidad de nuestro sistema de extrusión.**
{% endhint %}


# 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**:

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/FuCWRkmCJYopnijSxAHk/image.png)

{% 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**

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/HlZfmMU3EwL6Z7Bmgns1/image.png) ![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/0qp2GpALg76Gbgahj4r3/image.png)

</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)**.**
{% 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) y [nivelado](/klipper/empezamos/malla-nivelacion-de-cama-klipper)
* 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) **(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="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/7hv1OPOgkT9d3AlupU1v/image.png" 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](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/WdBRcy89NrRtBi4IagKi/image.png)
{% 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="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/l8cdRnhnR1Bg659KdGRi/image.png" 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="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/JF1wHAwGEfFKKDPLLoFz/image.png" 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.

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/mxB9ifM8An6f0MiHKpiq/image.png)

{% 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:\
![](https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FTTAGjbAQEPLA4jyPN3dF%2Fimage.png?alt=media\&token=be3938f9-62f8-47e2-b6e0-bc3e7c44aa12)
{% endtab %}

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

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/QHJAVfaVBqoVBMWJ8C4D/image.png)

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

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

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/8lndSHuYeSa8azbCcouD/image.png)

{% 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)

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/NIDNuoUJQiPaNzfDZbUn/image.png)
{% 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**:

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/rmn7MxdqKC0xdWzsj3Hd/image.png)
{% 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="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FuUyKfmHRfSOQ5wGpwyJA%2Fimage.png?alt=media&amp;token=988f40a6-2656-41c7-91bb-6d6e5a293991" 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="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2Fi9AdsKkjHPM4mVfCsThA%2Fimage.png?alt=media&amp;token=a9f4c683-0ba1-4259-a76a-e1e338e3dbbb" 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:

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/NxtNHN46gktsXFrgotZA/image.png)\
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).

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.


# SKEW : compensación chasis/cinemática

Los tests o ajustes SKEW van a permitir compensar aquellas desviaciones provocadas por un incorrecto ensamblado o ajuste de nuestro chasis y cinemática.

Como siempre os recomendamos un chasis/cinemática bien ajustada es crítico para unos resultados óptimos, así que es más que aconsejable invertir en el tiempo y presupuesto para que siempre sea lo más fiable posible.

En cualquier caso, no siempre es posible y no queda otra que utilizar test/ajustes SKEW para mejorar la fiabilidad dimensional de nuestras piezas impresas.

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

* hemos de asegurarnos que tenemos **correctamente ajustados los** [**pasos de nuestro extrusor**](https://labs.3dwork.io/guias-impresion-3d/calibracion_3d#2.-pasos-extrusor)
* Tener correctamente los pasos o rotation\_distance tal y como hemos leído previamente
* Este procedimiento es para impresoras cartesianas, si buscas un proceso similar para impresoras Delta revisa nuestra [guia de calibración](https://labs.3dwork.io/guias-impresion-3d/calibracion_3d#id-7.-pasos-ejes-movimiento).
* Si vemos <mark style="color:red;">**un error de skew/obliquidad >0.5º os aconsejamos revisar mecánicamente vuestra máquina antes de continuar con este test**</mark>
  {% endhint %}

El siguiente procedimiento está derivado de la documentación de [**Klipper**](https://www.klipper3d.org/Skew_Correction.html) hemos optado por el en este paso por qué utiliza un sistema bastante sencillo, aunque enfocado a impresoras cartesianas... si buscas un proceso avanzado tanto para impresoras cartesianas como Delta comprueba nuestra [guia de calibración](https://labs.3dwork.io/guias-impresion-3d/calibracion_3d#id-7.-pasos-ejes-movimiento).

* Empezaremos por descargar la figura de prueba para calcular las correcciones de SKEW, la podéis encontrar [aquí](https://files.ratrig.com/commissioningvc31/skew_calibration.stl).\
  La colocaremos en nuestro laminador asegurando que la esquina A coincida con la diagonal de la coordenada X0Y0 tal como podéis ver en la siguiente captura y laminaremos normalmente sin enviar a imprimir directamente ya que hemos de realizar algunos pasos previos.

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2Fyv7lp8J7VdvZ7bGHsEGH%2Fimage.png?alt=media&amp;token=bbd4f5d1-4379-4557-bba6-a436203cdb88" alt=""><figcaption></figcaption></figure>

* Antes de imprimir el test hemos de asegurarnos que no tenemos ninguna corrección de SKEW en nuestra configuración. Para ello lanzaremos en la consola de Klipper el comando/macro `SET_SKEW CLEAR=1`.\
  Recordar que si no os funcionan los comandos/macros `SET_SKEW` deberéis añadir a vuestra configuración de Klipper (printer.cfg) la sección`[skew_correction]`.\
  De igual forma os aconsejamos revisar vuestra rutina de inicio de impresión tanto a nivel laminador como macro de inicio de impresión para que no carguéis o habilitéis ningún SKEW al realizar este test
* Mandaremos ahora si imprimir el test, una vez impreso mediremos la pieza... realizarlo con un medidor lo más fiable posible... en las distancias que podéis ver en el siguiente esquema, AC BD y AD y anotaremos el resultado... por ejemplo, en nuestro caso:\
  AC = 141.1 mm\
  BD = 140.5 mm\
  AD = 99.6 mm

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FyQ5iCkVk2A7TAFovfZ76%2Fimage.png?alt=media&amp;token=7345eec5-8c2d-4798-a10f-fcdfdac6f8bb" alt=""><figcaption></figcaption></figure>

* Una vez reiniciado Klipper volveremos a la consola y lanzaremos los siguientes comandos:
  * `SET_SKEW XY=`**`AC`**`,`**`BD`**`,`**`AD` sustituyendo AC**,**BD**,**AD por los valores que medimos en pasos anteriores** `SET_SKEW XY=141.1,140.5,99.6` en nuestro caso
  * Lanzaremos `SKEW_PROFILE SAVE="mi_skew"` para guardar los valores en nuestro perfil de SKEW que definimos en pasos anteriores.
  * Por último, `SAVE_CONFIG` para guardar los cambios en nuestra configuración
* Con los ajustes SKEW hechos es aconsejable volver a imprimir el test, obviando el paso de resetear el SKEW, y verificaremos que las distancias AC son iguales a BD. En caso de no coincidir volveremos a realizar todo el proceso de nuevo.\
  Podemos utilizar el comando `GET_CURRENT_SKEW` para verificar que valores de SKEW tenemos actualmente.\
  Y el siguiente comando para calcular el nuevo SKEW usando las medias de este segundo test `CALC_MEASURED_SKEW AC=<ac_length> BD=<bd_length> AD=<ad_length>`

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

* Si es la primera vez que habilitas SKEW
  * **recuerda que has de cargarlo en tu macro de inicio de impresión!!!** puedes usar [SET\_SKEW](https://www.klipper3d.org/G-Codes.html#set_skew) (si usas los valores directamente) o [SKEW\_PROFILE](https://www.klipper3d.org/G-Codes.html#skew_profile)[ LOAD=mi\_skew ](https://www.klipper3d.org/G-Codes.html#skew_profile)para ello
  * de igual forma es más que aconsejable resetear las correcciones SKEW al finalizar nuestras impresiones añadiendo a nuestra macro de fin de impresión `SET_SKEW CLEAR=1`
* Ten en cuenta que dependiendo de las correcciones SKEW puede darse el caso que, en una impresión que este en los límites del área de impresión, la impresión falle por salirse de los límites del área de impresión... asegúrate que dejas margen al laminar tus piezas
* Si queremos eliminar un SKEW lo haremos con `SKEW_PROFILE REMOVE=mi_skew` y haremos un `SAVE_CONFIG` para guardar los cambios
  {% endhint %}


# Ajustes avanzados TMC (VFA)

TEST AVANZADO!!! REALIZAR SOLAMENTE SI TIENES UNOS CONOCIMIENTOS MINIMOS DE IMPRESORAS/FIRMWARE

Klipper pone a nuestra disposición diferentes funciones para optimizar movimientos y extrusión de la máquina como puede ser [**Pressure Advance**](/klipper/empezamos/pressure-advance), [**Input Shaper**](/klipper/empezamos/input-shaper), y otros...

En este caso vamos a atacar la configuración avanzada de nuestros drivers TMC para mejorar la calidad de sus ajustes junto con nuestros motores. En concreto, vamos a intentar eliminar o disminuir los artefactos verticales (VFA - Vertical Fine Artifacts) que suelen aparecer en nuestras impresiones.

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/ApMjf442TtVBk2AXVeXC/image.png" alt=""><figcaption><p>Ejemplo de VFA a diferentes velocidades</p></figcaption></figure>

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/Q9zOn8eOjVoc0H4Qnnpl/image.png" alt=""><figcaption><p>Resultados una vez realizado el ajuste fino de nuestros TMC para nuestros motores</p></figcaption></figure>

**Klipper**, en las secciones **driver\_xxx**, dispone de [**ajustes avanzados para TMC**](https://www.google.com/url?q=https%3A%2F%2Fwww.klipper3d.org%2FTMC_Drivers.html%3Fh%3Dtmc%23configuring-driver_xxx-settings\&sa=D\&sntz=1\&usg=AOvVaw1ukfKQVQ0lFtXj21OJOWzM) que normalmente no son usados o nos los facilitan algunos fabricantes. Básicamente, estos ajustes que vamos a emplear nos permitirán alterar la forma de onda generada por nuestros drivers para la gestión de nuestros motores.

## Procedimiento

En esta guía vamos a intentar explicar como encontrar esos valores para vuestra máquina.

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

* Nuestra **configuración de drivers deberá de estar en SpreadCycle** (modo torque/potencia).. en cualquier caso este ajuste avanzado mejora el uso de la corriente en los motores lo que permite reducir significativamente el ruído que generan
* Estas **configuraciones avanzadas NO suelen llevarse bien con StealChop** (modo silencioso)
* Estos ajustes son exclusivos para la combinación de drivers/motores para los cuales se calcule
  {% endhint %}

Queremos dejar claro que el proceso de ajuste correcto para estos parámetros sería realizando una batería de tests usando un osciloscopio tal y como podéis encontrar en el siguiente [**PDF con el proceso**](https://www.trinamic.com/fileadmin/assets/Support/AppNotes/AN001-SpreadCycle.pdf).\
En nuestro caso y dado que no todos tenemos un osciloscopio en casa vamos a ajustar esos parámetros mediante unos cálculos en base a nuestros drivers y motores.

Para realizar el proceso descrito en esta guía vamos a necesitar dos cosas:

* Las fórmulas, en este [**caso Trinamic (TMC) nos facilita unas hojas de cálculo**](https://www.trinamic.com/support/app-notes/) para simplificar el proceso... a continuación puedes encontrarlos para los drivers más comunes

{% tabs %}
{% tab title="TMC2209" %}
[TMC2209 Calculations ](https://www.analog.com/en/products/tmc2209.html)en la sección Tools & Simulations deberíais encontrar el link a la hoja de cálculo.
{% endtab %}

{% tab title="TMC2226" %}
[TMC2226 Calculations ](https://www.analog.com/en/products/TMC2226.html)en la sección Tools & Simulations deberíais encontrar el link a la hoja de cálculo.
{% endtab %}

{% tab title="TMC5160" %}
[TM5160 Calculations ](https://www.analog.com/en/products/TMC5160.html)en la sección Tools & Simulations deberíais encontrar el link a la hoja de cálculo.
{% endtab %}

{% tab title="TMC Otros" %}
Podéis encontrar [información de otros drivers aquí](https://www.analog.com/en/parametricsearch/2463#/).
{% endtab %}
{% endtabs %}

* Encontrar el datasheet de nuestro motor

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

un fallo bastante común, sobretodo en máquinas modificadas o DIY, es que e**l cableado de nuestros drivers->motores no estén del todo correctos**.

**Algo que normalmente hacemos mal es, al intentar cambiar el giro de un motor cuando este no lo hace correctamente y por pereza de cambiar nuestro firmware, es invertir cables y lo ideal siempre es ajustar el firmware dejando nuestro cableado siguiendo las especificaciones de los fabricantes**... en este caso de electrónica de control de vuestra impresora y el de los motores.

Las **electrónicas en sus esquemas de pines cuentan con el orden tanto de bobinas como de polaridad inicial**:

<img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/gonPllWxWu30t2I1VUOz/image.png" alt="" data-size="original">

Como puedes observar en la captura anterior para esta electrónica, una SKR Octopus, tienen definidos los pines como A1 A2 B2 B1 donde:

* A/B hacen referencia a la bobina en cada caso
* 1/2 hacen referencia al polo de polaridad de la bobina

Ahora si nos fijamos en el **esquema de un motor estándar de impresora 3D veremos que en su datasheet nos facilitan la información necesaria para identificar nuestras bobinas y polaridad inicial de pines**:

<img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/yNaUhhlbpcPwuKkvJiIb/image.png" alt="" data-size="original">

En el caso anterior lo ideal es realizar el cableado de la siguiente forma:

* A1 (Octopus) -> Bobina A/Polaridad inicial 1/+ -> pin 1 A+ BLK (negro) (motor)
* A2 (Octopus) -> Bobina A/Polaridad inicial 2/- -> pin 2 A- GRN (verde) (motor)
* B2 (Octopus) -> Bobina B/Poladirad inicial 2/- -> pin 4 B- BLU (azul) (motor)
* B1 (Octopus) -> Bobina B/Polaridad inicial 1/+ -> pin 3 B+ RED (rojo) (motor)

**Porqué es importante hacer esto?**

Si bien tener cruzadas las polaridades iniciales o el orden de las bobinas puede hacer que nuestra impresora esté funcionando correctamente **el no disponer de un orden correcto en estas puede provocar pérdida de precisión y pasos, además, que en velocidades medias/altas nuestros motores pueden generar más ruído y vibraciones** que de no estar correctamente.
{% endhint %}

El primer paso será revisar en nuestro printer.cfg, o si tenemos una configuración modular en el include que los contenga, las secciones que hacen referencia a nuestros drivers y motores:

* \[stepper\_x] donde encontramos la configuración del motor, en especial el valor de micropasos que se usarán
* \[tmc2209 stepper\_x] donde veremos la configuración TMC para un eje/motor en concreto

{% hint style="danger" %}
Tal como indica la propia [documentación de Klipper](https://www.klipper3d.org/TMC_Drivers.html) algunos de las propiedades de estas secciones es aconsejables eliminarlas en cualquier caso:

* **interpolate: True**, aunque es una función interesante que el propio driver permita seleccionar dinámica mente el valor de micropasos dependiendo de las necesidades en la práctica esto puede repercutir en pérdida de precisión de ahí que sea **aconsejable cambiarlo a interpolate: False**
* **hold\_current**, otra función que **se aconseja deshabilitar/borrar** es la de definir un valor de corriente cuando los motores están en modo descanso. Estos cambios de corrientes pueden provocar imprecisiones en su posicionamiento en determinados casos
  {% endhint %}

Si tenías actualmente en tu configuración habilitada la opción de interpolate, el driver dinámicamente según las necesidades ajustaba los micropasos desde el valor establecido hasta 256, para realizar el ajuste fino usaremos un valor de micropasos medio en este caso podemos comenzar en 64.

Como norma os diremos que con lo explicado anteriormente nuestra experiencia con los micropasos es que NO siempre es beneficioso usar un número alto de micropasos ya que nos van a limitar considerablemente el rendimiento/velocidad por pérdida de torque, añadir más imprecisión y aumentar exponencialmente la carga del sistema.

Como consejo para máquinas de entrada o gama media (Ender 3, Artillery, etc...) os aconsejamos 16... 32 a lo sumo. Para máquinas de gama media/alta con un buen conjunto cinemática/motores/electrónica y dependiendo de sus características podremos utilizar un valor de micropasos superiores... SIEMPRE realizando los tests oportunos para ver las posibles mejoras en calidad e impacto en velocidad y fiabilidad.

{% hint style="warning" %}
Dependiendo del tipo de máquina, motores, etc... podemos obtener mejores o peores resultados dependiendo de los micropasos. Es aconsejable comenzar en 16 y comparar resultados usando 32 y 64.
{% endhint %}

{% hint style="success" %}
Cambiando esta configuración tal cual explicada directamente veremos que la máquina es sensiblemente más ruidosa que usando interpolate... el procedimiento de ajuste nos va a permitir solventar esto aprovechando el modo SpreadCycle con sus mejoras, torque/velocidad, y con un nivel de ruido similar al no tenerlo.
{% endhint %}

{% hint style="warning" %}
El uso de Stealthchop en los motores Z suele ser aconsejable dado que reduciremos el ruido y al no ser un eje de movimientos particularmente rápido no tendremos problemas.\
Así que **nuestros motores usados en el eje Z podrían operar en modo Stealthchop utilizando un valor de micropasos que mantengan el torque y precisión de nuestra mecánica** especialmente porque a más micropasos perdemos exponencialmente torque/fuerza y precision algo crítico a la hora de procesos como homing o mallado de cama.

Podemos hacer que siempre funcionen en este modo **ajustando la propiedad de la siguiente forma stealthchop\_threshold: 999** en la sección TMC de nuestro eje Z.

Además y **para este eje Z no realizaremos los ajustes/optimizaciones que sugeriremos mas adelante**.
{% endhint %}

{% hint style="info" %}
El **motor de extrusión va a ser un caso especial**, lo que **se recomienda dejarlos en 16 micropasos al igual que no tener activo el modo Stealthchop con** stealthchop\_threshold: 0.

**No suele ser aconsejable utilizar este ajuste fino en ellos ya que como se indicó al inicio de la guía se cuentan con otras funciones para ajustar el control de la extrusión.**
{% endhint %}

Las propiedades de nuestra sección TMC que nos vamos a centrar serán las siguientes:

* `driver_TBL`: Blanking Time
* `driver_TOFF`: Time to Slow Decay
* `driver_HSTRT`: Hysteresis start
* `driver_HEND`: Hysteresis end

Básicamente lo que haremos ajustando estos valores será ajustar los tiempos y configuraciones de histéresis de las señales de nuestros drivers.

{% hint style="info" %}
Si queréis información más detallada de estas opciones os aconsejamos leeros la sección SpreadCycle Settings de, por ejemplo, el [datasheet de los TMC2209](https://www.trinamic.com/fileadmin/assets/Products/ICs_Documents/TMC2209_Datasheet_V103.pdf)
{% endhint %}

Como siguiente paso vamos a centrarnos en los cálculos de la hoja de excel comentadas en puntos anteriores, en concreto en la segunda hoja donde encontraremos Chopper Parameters donde ajustaremos los valores de las celdas en color amarillo:

* **fCLK**, normalmente 12Mhz que suele ser el valor por defecto para unos TMC2209 (no hace referencia al reloj de nuestra electrónica!!!)
* **VM\[V]**, indicaremos el voltaje de nuestra fuente o en su defecto al que alimentemos nuestra electrónica o motores si estos disponen de una fuente dedicada a otro voltaje diferente
* **TBL**, normalmente lo dejaremos en 1 ya que es un valor que suele ir bien en todos los motores de hasta 2A.

{% hint style="info" %}
Dependiendo del fabricante se puede dar el caso que a partir de 1.5A (o si usamos drivers/motores HighVoltage) se puede sugerir utilizar 2.\
Es aconsejable en estos casos realizar los cálculos con ambos valores y revisar resultados.
{% endhint %}

* **L\[H]**, la inductancia de nuestro motor que encontraremos en su datasheet en mH normalmente. Por ejemplo si nuestro datasheet nos indica 1.6mH pondremos 0.0016 como valor en la celda de a hoja
* **Rcoil\[Ohm]**, este valor también lo obtendremos del datasheet de nuestro motor aunque también lo podremos obtener midiendo con un multímetro las bobinas de nuestro motor
* **Icoil(peak)\[A]**, la corriente de pico de nuestros motores y que debería indicar nuestro datasheet, este valor no es el mismo que usamos en current en nuestro cfg de Klipper
* **toff**, es un valor reactivo, lo dejaremos a 3 inicialmente
* **CS**, este valor lo ajusta el driver basado en la corriente (y su resistencia) y lo usaremos para simular más adelante

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/ZyYRuQHSSGmBno8VmExp/image.png" alt=""><figcaption><p>Ejemplo TMC5160</p></figcaption></figure>

{% hint style="info" %}
En el caso que pongamos valores que esten en límites la hoja de cálculo nos mostrará avisos.
{% endhint %}

Una vez ajustado todo **los valores que nos van a interesar son los que aparecen en la sección de color azul Register values for CHOPCONF register bits**, no las dos celdas bajo Desired value.

Lo siguiente será **ajustar manualmente los valores de CS hasta que RSENSE using VSENSE=1 al final de la hoja sea igual a nuestro sense resistor, normalmente 0.110 Ohms** en motores de impresora 3D.\
**Nos interesa mantener el valor CS bastante alto para que nuestros micropasos funcionen correctamente**, la propia hoja de cálculo nos avisará si usamos un valor demasiado bajo.

Cuando encontremos nuestro valor CS óptimo:

* usaremos los **valores en la sección azul antes comentada y los ajustaremos en nuestra configuración de Klipper en driver\_HSTRT y driver\_HEND**
* también **ajustaremos driver\_TBL y driver\_TOFF con los valores indicados en la parte de arriba de nuestra hoja**... normalmente 1 y 3 respectivamente
* ajustaremos nuestro **valor run\_current usando Icoil (RMS)\[A]**

{% tabs %}
{% tab title="EJEMPLO EJE DE MOVIMIENTO:" %}
{% hint style="danger" %}
**Recordemos que tal como os comentamos para el eje Z no haremos estos cálculos**
{% endhint %}

{% hint style="success" %}
Vamos a usar como referencia un motor OMC [17HM19-2004S1](https://www.omc-stepperonline.com/nema-17-bipolar-0-9deg-46ncm-65-1oz-in-2a-2-8v-42x42x48mm-4-wires-full-d-cut-shaft.html) de 48mm y 0.9º donde encontramos en su datasheet 1.45 ohm como resistance y 4 mH como inductancia además de usar 1 A como corriente RMS.

Dejaremos TBL a 1 y TOFF a 3. Ajustando CS para obtener un valor de 0.110 en VSENSE=1 que obtubimos con un CS de 31 y una corriente ICoil(Peak)\[A] a 1.38A.

<img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/0W3i6BybSajVWqrTloND/image.png" alt="" data-size="original">

Usaremos el valor de Icoil (RMS)\[A], de 0.976 A como el valor de run\_current.

Por último los valores de la sección azul CHOPCONF register bits que deberían ser 0 para HSTRT y 3 para HEND.

```django
[tmc2209 stepper_x]
uart_pin: PE7
interpolate: False
stealthchop_threshold: 0
sense_resistor: 0.110
run_current: 0.976
driver_TBL: 1
driver_TOFF: 3
driver_HSTRT: 0
driver_HEND: 3
```

Además os aconsejamos realizar pruebas con los valores TBL y TOFF para ver como varia el resultado en nuestra máquina.
{% endhint %}

Realizaremos los mismos cálculos para el resto de ejes de movimiento en el caso que usemos diferentes componentes/ajustes.
{% endtab %}

{% tab title="EJEMPLO EJE DE EXTRUSIÓN:" %}
{% hint style="success" %}
Os recordamos que **no** **suele ser aconsejable utilizar este ajuste fino en ellos ya que como se indicó al inicio de la guía se cuentan con otras funciones para ajustar el control de la extrusión.**

Vamos a realizar en este caso el proceso directamente con un ejemplo usando el popular LDO 36mm NEMA14. Este motor usa una resistencia de 10 Ohms y una inductancia de 6mH.

Sabemos que este motor necesita alrededor de 300mA de corriente (run\_current: 0.3) algo que tendremos como referencia para el valor CS.

Tal como hicimos antes y ajustando los valores anteriores en este caso intentaremos ajustar el valor CS bastante bajo, será la propia hoja que nos avisará que los valores por debajo de 16 no son aconsejables y por eso no aconsejábamos usar en el extrusor muchos micropasos.

Generalmente nos interesa mantener la frecuencia (chopper) sobre 40Khz ya que normalmente funcionará al 50% de esta frecuencia teniendo en cuenta que 20Khz es el limite del oído humano.

Además os aconsejamos realizar pruebas con los valores TBL y TOFF para ver como varia el resultado en nuestra máquina.

En nuestro caso quedaría nuestra configuración de la siguiente forma:

```django
run_current: 0.336 # results in CS 10
driver_TBL: 1
driver_TOFF: 3 # 41.7Khz max chopper frequency
driver_HSTRT: 0
driver_HEND: 3
```

{% endhint %}

{% hint style="info" %}
Tal como decíamos anteriormente el valor run\_current para este motor es alrededor de 0.3 A.

En nuestro ejemplo hemos usado el valor CS = 10, dado que nos dará un valor de RSENSE=1 de 0.11, y un peak current de 0.475A dejando 0.336 RMS que es el valor que usaremos en nuestra configuración run\_current.

Porqué no usamos CS 9 o 11?

* en el caso de CS 9 obtenemos un pico de 0.434A y 0.307 RMS que es lo más aproximado... pero un valor bajo de CS
* por otro lado un valor de CS 11 nos daría un valor de pico de 0.52A y 0.368A RMS lo cual es ya un poco alto para este motor
  {% endhint %}
  {% endtab %}
  {% endtabs %}

## Pruebas y ajuste fino

Es importante recalcar que estos valores obtenidos son simplemente como punto de referencia y que es posible que, ya sea por hacer los cásculos de forma incorrecta o por peculiaridades de los componentes/mecánica de nuestra máquina, requieran de ajustes manuales en base a tests o simplemente mejor dejarlos deshabilitados.

En cualquier caso si se hace un ajuste manual solamente os aconsejariamos tocar los siguientes valores:

* **driver\_TBL**, este tiempo debe cubrir de forma segura los eventos de conmutación del driver TMC. Tal como comentamos anteriormente un valor de 1 o 2 (dependiendo de las especificaciones o características del motor) debería funcionar bien para la mayoría de máquinas normales, pero cargas capacitivas más altas pueden requerir que se ajuste en 3.\
  Podemos utilizar este valor de 0 a 3.\
  Aunque no suele ser aconsejable habilitar StealthChop, en el caso de que por requerimientos sea necesario, lo ideal es establecer este valor en 0.
* **driver\_TOFF**, establece el tiempo de caída lenta (tiempo de apagado) del ciclo de corte. Esta configuración también limita la frecuencia máxima de corte.\
  Podemos usar este valor de 0 a 15.\
  Si utilizamos velocidades muy altas en nuestra máquina a veces suele funcionar mejor ajustar el valor driver\_TOFF a 1 o 2 y establecer un valor para driver\_TBL corto de 1 o 0

{% hint style="success" %}
Os aconsejamos mucho tener vuestra propia base de datos o documentar estos cálculos de drivers/motores diferentes. El uso de configuración modular mediante includes puede ayudarnos.

Es importante añadir comentarios en nuestra configuración donde guardemos información de nuestro tipo, modelo y características del motor:

```django
#LDO 48mm 1.8 42STH48-2004AC - 1.4Ohm 3mH
[tmc2209 stepper_z]
uart_pin: PD10
uart_address: 0
interpolate: False
run_current: 0.764
sense_resistor: 0.110
stealthchop_threshold: 0
driver_TBL: 1
driver_TOFF: 3
driver_HSTRT: 1
driver_HEND: 3
```

{% endhint %}

## Sensorless homing simplificado con drivers TMC

Aunque no está directamente relacionado con el ajuste fino de VFA, vale la pena documentar aquí los cambios recientes en el **homing sin sensores** con drivers TMC, porque comparten los mismos campos `driver_*` que hemos estado tocando en esta guía.

{% hint style="info" %}
**¿Qué es el sensorless homing?**

Es la posibilidad de hacer `G28` **sin finales de carrera físicos**. El driver TMC (vía el pin `DIAG`) detecta cuándo el motor pierde pasos al chocar contra el final mecánico del eje y le señala a Klipper que ha llegado. Te ahorras los endstops X e Y, el cableado y las macros para sortear histéresis del switch óptico/mecánico.
{% endhint %}

### Configuración mínima — el flujo actual de Klipper

El flujo recomendado actualmente por la documentación oficial de Klipper se ha simplificado bastante respecto a lo que circulaba en guías antiguas. Esta es la receta mínima para un TMC2209 en el eje X:

```django
[stepper_x]
endstop_pin: tmc2209_stepper_x:virtual_endstop
homing_retract_dist: 0
homing_speed: 40         # ajustar según mecánica, ver más abajo
# ...resto de la configuración del stepper...

[tmc2209 stepper_x]
uart_pin: PE7
diag_pin: ^PA1           # pin DIAG del TMC2209 conectado a la MCU
driver_SGTHRS: 80        # sensibilidad inicial; se ajusta tras el tuning
# ...resto de configuración TMC...
```

Los **dos cambios clave** respecto al esquema antiguo:

* **`endstop_pin: tmc2209_stepper_x:virtual_endstop`** — el endstop virtual del driver sustituye al `endstop_pin: PA1` físico que se usaba con final de carrera mecánico.
* **`homing_retract_dist: 0`** — desactiva el segundo movimiento de homing (la "retract + retoque"). En sensorless no es necesario y, si está activo, puede provocar falsos triggers en el segundo intento.

Para drivers que **no** son TMC2209 (TMC2130, TMC5160, TMC2240...) el campo se llama **`driver_SGT`** en lugar de `driver_SGTHRS`, y el rango de valores válido es distinto (típicamente `-64` a `63` en los TMC51xx). Comprueba el datasheet de tu driver.

### Procedimiento de tuning

El tuning es un proceso de **biseccionar la sensibilidad** entre dos extremos:

1. **Elige una velocidad de homing** estable. Como referencia, una vuelta completa del motor cada 2 segundos suele dar buenos resultados. Con un GT2 20T en X, eso equivale aprox. a 20-40 mm/s.
2. **Encuentra la sensibilidad máxima**: pon el valor más sensible posible (`SGTHRS=255` para TMC2209; `SGT=-64` para TMC51xx) y lanza `G28 X`. Con sensibilidad máxima el eje normalmente **no se moverá** o frenará al instante: el driver interpreta cualquier carga como un choque. Ese es el límite superior.
3. **Baja gradualmente** hasta encontrar la **sensibilidad mínima**, el valor justo en el que el homing detecta el final del eje **una sola vez** sin golpear. Lo ideal es probar valor a valor con el comando `SET_TMC_FIELD`:

   ```gcode
   SET_TMC_FIELD STEPPER=stepper_x FIELD=SGTHRS VALUE=80
   G28 X
   ```

   Hacer esto en caliente sin reiniciar Klipper agiliza muchísimo el proceso.
4. **Valor recomendado** = `mínimo + (máximo - mínimo) / 3`. Es decir, te quedas en el tercio inferior del rango útil: lo suficientemente sensible para detectar el choque sin falsos positivos por fricción del carro.
5. **Margen entre extremos**: si la diferencia entre el valor máximo y el mínimo es **menor de 5**, el homing va a ser inestable — toca subir la velocidad de homing o revisar la mecánica.

{% hint style="warning" %}
**Pausa antes del homing**

El TMC necesita un par de segundos de movimiento previo para que el algoritmo StallGuard se estabilice. Klipper se encarga internamente, pero **si haces un homing nada más mover el eje a su tope**, puedes tener falsos triggers. Lo más limpio es envolverlo en una macro:

```django
[gcode_macro SENSORLESS_HOME_X]
gcode:
    G91
    G1 X10 F1200       # separar de un posible tope
    G90
    G4 P2000           # 2s de pausa para que SG se asiente
    G28 X
```

{% endhint %}

### Cuándo volver a calibrar

Tienes que repetir el tuning **siempre que cambies**:

* `run_current` del driver (la sensibilidad escala con la corriente).
* `homing_speed` del eje.
* Mecánica significativa: correas, carros, lubricación pesada, motores...

{% hint style="success" %}
**Sensorless + SpreadCycle**

Los ajustes finos de **TBL/TOFF/HSTRT/HEND** que has hecho en esta guía afectan al ruido del motor en SpreadCycle pero **no rompen el sensorless homing**. Eso sí, si has cambiado el `run_current` después del tuning de homing, retoca `driver_SGTHRS`/`driver_SGT` siguiendo el procedimiento de arriba.
{% endhint %}

## Recursos relacionados

Os aconsejamos este vídeo donde podréis ver el proceso:

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

Créditos y agradecimientos a [MakerBogans](https://github.com/MakerBogans)

## Alternativas

{% hint style="warning" %}
Dado que Klipper es un sistema modular y flexible la comunidad desarrolla extensiones para mejorar este.

Una de estas extensiones es [Klipper TMC Autotune](https://github.com/andrewmcgr/klipper_tmc_autotune).

En nuestro caso y probado en varias máquinas, así como el feedback de usuarios de nuestros grupos, no siempre suele ir bien e incluso empeorar los resultados si no se ajusta correctamente.

Además utiliza algunas funciones que directamente van en contra con las recomendaciones de Klipper en el uso de motores/cinemática.

Os aconsejamos realizar vuestros propios cálculos y tests primero con el método descrito en esta guía, comparar resultados con una configuración estándar... y si aún así queréis utilizar este TMC Autotune hacerlo pudiendo comparar con los dos tests anteriores.

Otra alternativa que puede simplificar el proceso/complejidad es utilizar los scripts [Chopper Resonance Tuner](https://github.com/MRX8024/chopper-resonance-tuner/blob/main/wiki%2Fchopper_tuning_guide_english.md), utilizando datos de un acelerometro ayuda a hacer algunos de estos ajustes finos. Es un sistema más automático pero algo laborioso al realizar el proceso con el acelerómetro.
{% endhint %}


# Retracciones en firmware

{% hint style="danger" %}
Aunque poder controla las retracciones desde el firmware puede tener algunos puntos positivos dado que en un momento dado podremos realizar el ajuste fino, probablemente **la gestión de estas desde el laminador va a aportar más opciones y ajustes aún perdiendo ese ajuste "en caliente".**

**Aconsejamos el usar el proceso clásico de ajuste de retracciones por el laminador tal y como tenéis en la** [**guía de calibración FDM**](https://github.com/alienboyxp/gitbook_es_klipper_3dwork_io/blob/main/broken/pages/-MTqPy_NKPC-R-jkDi7M/README.md#8.-retracciones)**.**
{% endhint %}

Una funcionalidad interesante es la de ejecutar el control de las retracciones desde el firmware Klipper.

## Habilitar las retracciones por firmware en nuestro laminador:

Para ello deberemos realizar los siguientes pasos:

{% tabs %}
{% tab title="PrusaSlicer/SuperSlicer" %}
Iremos a Printer Settings/General/Advanced y marcaremos la opción Use firmware retraction:

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/9VLQMo4pw7MaSmNg7la0/image.png" alt=""><figcaption></figcaption></figure>

Esto generará códigos G10 y G11 en nuestro gcode para que el firmware identifique cuando realizar el proceso.
{% endtab %}

{% tab title="Cura" %}
Para Cura, a partir de la v5, es necesario instalar la extensión/módulo Printer Settings y desde ahi activar las retracciones por firmware.
{% endtab %}
{% endtabs %}

## Habilitar las retracciones por firmware en nuestro Klipper:

Para ello tan solo deberemos de ir a nuestro printer.cfg y añadir la siguiente sección:

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

```django
[firmware_retraction]
retract_length: 0.8
retract_speed: 60
unretract_extra_length: 0
unretract_speed: 60
```

{% endcode %}

{% hint style="info" %}
Obviamente debereis ajustar estos valores a vuestra máquina, normalmente ajustando con los que tengáis en vuestro laminador.
{% endhint %}

## Test de retracciones

A continuación os sugerimos un sencillo test de retracciones desde Klipper.

* Realizaremos un laminado de la siguiente figura de test, recordad tener activadas las retracciones por firmware en vuestro laminador (podéis revisar el gcode generado en busca de G10/G11

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/jZdLnXXQTYa9yGnrhM1I/image.png" alt=""><figcaption></figcaption></figure>

{% file src="/files/Qu1OD0c2dhAAJtOV78LV" %}

* Lo enviamos a la impresora y al inicio de la impresión lanzamos la siguiente macro desde nuestro terminal

```
TUNING_TOWER COMMAND=SET_RETRACTION PARAMETER=RETRACT_LENGTH START=0 FACTOR=0.05
```

* Este proceso variará la distancia de retracción de 0 a 5mm, podremos ver en la consola el proceso
* Para calcular el valor idóneo mediremos la altura en la que no tenemos artefactos o estos son inapreciables y realizaremos la siguiente fórmula:

```
// Formula
retraccion = START + altura_deseada * FACTOR
// Ejemplo lanzado
retraccion = 0 + altura_deseada * 0.05
```


# Configuración de una dirección IP estática y nombre DNS

En ocasiones, en lugar de que se nos asigne una dirección IP dinámica que cambie, nos interesa tener una fija para siempre poder acceder sin necesidad de buscar la asignada cada vez.

Por otro lado, en ocasiones nos es más cómodo acceder por un hostname o nombre DNS, es un nombre que le ponemos al dispositivo que sea más fácilmente de recordar por un humano.

Con el siguiente procedimiento podrás realizar estos pasos.

Para comenzar a configurar una dirección IP estática en nuestra Raspberry Pi, primero necesitaremos recuperar información sobre nuestra configuración de red actual.<br>

## Obtener la configuración actual

Para realizar los siguientes pasos nos conectaremos por SSH a nuestro host usando Terminus/Putty o cualquier otro cliente terminal SSH:

* Primero recuperemos el enrutador definido actualmente para tu red ejecutando el siguiente comando.\
  \&#xNAN;**`ip r | grep default`**\
  Al usar este comando, deberías obtener un resultado similar al que tenemos a continuación.\
  \&#xNAN;**`default via 192.168.0.1 dev eth0 proto dhcp src 192.168.0.159 métrica 202`**\
  Anota la primera IP mencionada en esta cadena. Por ejemplo, la IP que vamos a tomar nota de este comando es "192.168.0.1". Esta dirección IP es la dirección actual del enrutador/gateway.
* A continuación, recuperemos también el servidor DNS actual.\
  Podemos hacer esto abriendo el archivo de configuración “resolv.conf” ejecutando el siguiente comando.\
  \&#xNAN;**`sudo nano /etc/resolv.conf`**\
  Desde este comando, debería ver las líneas de texto a continuación.\
  \&#xNAN;**`# Generado por resolvconf`**\
  **`nameserver 192.168.0.1`**\
  Toma nota de la IP junto a "nameserver". Esto definirá el servidor de nombres (DNS) en nuestros próximos pasos.

## Configurando nuestra IP fija

* Ahora que hemos recuperado nuestra IP actual del “enrutador” y la IP del servidor de nombres, podemos proceder a modificar el archivo de configuración “dhcpcd.conf” ejecutando el siguiente comando.

  **`sudo nano /etc/dhcpcd.conf`**\
  Este archivo de configuración nos permite modificar la forma en que Raspberry Pi maneja la red.
* Dentro de este archivo, pon las siguientes líneas al final.

```bash
interface <RED>
static ip_address=<STATICIP>/24
static routers=<ROUTERIP>
static domain_name_servers=<DNSIP>
```

* Primero, debes decidir si deseas configurar la IP estática para su conector “eth0” (Ethernet) o su conexión “wlan0” (WiFi). Decide cuál deseas y reemplaza “<**RED**>” por él.
* Asegúrate de reemplazar "<**STATICIP**>" con la dirección IP que desea asignar a su Raspberry Pi. Asegúrese de que esta no sea una IP que pueda conectarse fácilmente a otro dispositivo en tu red o si está dentro del rango DHCP (asignacion automática de IP por parte del router) asetúrate que bloqueas la IP en el.
* Reemplaza "<**ROUTERIP**>" con la dirección IP que recuperaste en el paso 1 de este tutorial.
* Finalmente, reemplaza “<**DNSIP**>” con la IP del servidor de nombres de dominio que desea utilizar. Esta es la IP que obtuvo en el paso 2 de este tutorial u otra como Google "8.8.8.8" o "1.1.1.1" de Cloudflare.
* Ahora guarde el archivo presionando CTRL + X, luego Y seguido de ENTE&#x52;**.**
* Ahora que hemos modificado el archivo de configuración DHCP de nuestra Raspberry Pi para que utilicemos una dirección IP estática, debemos continuar y reiniciar la Raspberry Pi.\
  Reiniciar la Raspberry Pi permitirá que se carguen nuestros cambios de configuración y se eliminen los antiguos.\
  Al reiniciar, la Raspberry Pi intentará conectarse al enrutador utilizando la dirección IP estática que definimos en nuestro archivo "dhcpd.conf".\
  Ejecute el siguiente comando para reiniciar su Raspberry Pi.

```bash
sudo reboot
```

## Comprobando nuestra IP estática y conexión a Internet

* Una vez que su Raspberry Pi haya terminado de reiniciarse, ahora debería poder conectarse utilizando la dirección IP que especificó.
* Si se está conectando localmente y desea verificar la dirección IP estática configurada correctamente, puede hacerlo ejecutando el siguiente comando.

```bash
ifconfig -a
```

![Ahí verificaremos que la IP estática/fija asignada sea la correcta.](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/ceosdKjf1tUY2gYu3j7m/image.png)

* Desde este comando, ahora deberíamos poder ver su nueva dirección IP estática. Si es la IP que configuramos anterior, entonces ha configurado con éxito una dirección IP estática en su Raspberry Pi.
* A continuación comprobaremos que tanto el acceso a internet coo la resolución DNS funcionan correctamente

```
// Comprobando acceso a Internet
ping 8.8.8.8
// deberia contestarnos, si no es posible que nuestro router ip no fuera el correcto

// Comprobando resolción DNS
ping google.com
// debería de resolver el nombre si el anterior funcioa y este no nuestro nameserver puede que no sea correcto
```

{% hint style="info" %}
En el caso de tener problemas con el DNS podemos usar las **dnsutils**

***sudo apt-get install dnsutils***

Una vez instalado podemos usar el comando dig para hacer un test

***dig google.com***

Que nos dará una salida similar a esto en el caso de ir bien

***;; Query time: 26 msec***\
***;; SERVER: 8.8.8.8#53(8.8.8.8)***\
***;; WHEN: Sun Dec 23 11:44:52 UTC 2018***\
***;; MSG SIZE rcvd: 75***
{% endhint %}

## Configurando nuestro Hostname

Como ya os hemos comentado, el hostname o nombre DNS es una etiqueta o nombre con el cual podemos acceder a un host de nuestra red sin tener que recordar la IP y de esa forma ser más fácil de recordar.

También suele ser buena idea configurarlo cuando tenemos varios hosts en nuestra red que, por defecto, usen el mismo hostname y puedan darnos problemas.

{% hint style="warning" %}
Es importante recordar que configurar un hostname en local de un host no tiene porqué funcionar o ser resuelto correctamente en todos los casos.
{% endhint %}

{% hint style="success" %}
En el caso que usemos nuestro [**bundle para Klipper**](/klipper/mejoras/3dwork-klipper-bundle) o RatOS disponemos de una macro para realizar este proceso desde nuestro interfaz web Klipper.
{% endhint %}

* Revisaremos cuál es el hostname actual de nuestro host con el siguiente comando:

```bash
hostname
```

* Nos tendría que devolver, en el caso de una Raspberry a modo de ejemplo, algo así:

```
raspberrypi
```

* Para realizar el cambio de hostname, lanzaremos el siguiente comando y pondremos el nombre que mas nos guste... una vez cambiado haremos un CTRL+X seguido de un Y+ENTER para guardar los cambios:

```bash
sudo nano /etc/hostname
```

* Para asegurarnos que el propio host sepa como acceder a el mismo modificaremos el siguiente fichero:

```bash
sudo nano /etc/hosts
```

* A modo de ejemplo, recuerda que para guardar los cambios haremos un CTRL+X seguido de un Y+ENTER :

```
// Old hostname
127.0.0.1    raspberrypi
// Change to the new hostname
127.0.0.1    mynewraspberry
```

* reiniciaremos para aplicar los cambios:

```bash
sudo reboot
```

Ahora si todo funciona correctamente podremos acceder a nuestro host usando su hostname.


# Sincronización horaria

Algo muy importante es que nuestra hora este actualizada ya que puede afectar a actualizaciones de sistema u otras funciones. Para ello usaremos timedatectl que viene por defecto en Raspbian y NTP.

Lanzaremos el comando para ver nuestra configuación actual:

```
timedatectl status
```

Nos devolverá datos como la hora local, la universal el RTC configurado, la zona o si esta activada la sincronizacion NTP, mostrara algo como:

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/Q5nW0oA7f0v2R6s6EEAf/image.png)

En nuestro caso configuraremos nuestra zona a Europe/Madrid:

```
sudo timedatectl set-timezone Europe/Madrid
```

Instalaremos el servicio NTP:

```
sudo apt install ntp
```

Habilitaremos la sincronizacion:

```
sudo timedatectl set-ntp true
```

Revisaremos que tengamos en nuestra configuración los servidores NTP habilitados

```
sudo nano /etc/systemd/timesyncd.conf
```

Y quitaremos la # inicial de la linea FallbackNTP

```
[Time]
#NTP=
FallbackNTP=0.us.pool.ntp.org 1.us.pool.ntp.org
```

Reiniciamos y con el primer comando verifiquemos que nuestra hora este actualizada!!


# Mejoras/Tips

{% hint style="info" %}
**English**: Use your browser's built-in translation — Chrome and Edge detect the language automatically and offer to translate the page.
{% endhint %}


# 3Dwork Klipper Bundle

Paquete de macros, configuraciones y otras utilidades para Klipper

{% hint style="danger" %} <mark style="color:red;">**GUÍA EN PROCESO!!! Aunque las macros son totalmente funcionales estas están en continuo desarrollo.**</mark>

<mark style="color:orange;">**Úsalas bajo tu propia responsabilidad!!!**</mark>
{% endhint %}

<details>

<summary>Changelog</summary>

07/12/2023 - Añadido soporte para automatizar la creación de firmware electrónicas Bigtreetech

</details>

Desde **3Dwork** hemos recopilado y ajustando un conjunto de macros, configuraciones de máquinas y electrónicas, así como otras herramientas para una gestión sencilla y potente de Klipper.

Gran parte de este paquete está basado en [**RatOS**](https://os.ratrig.com/) mejorando las partes que creemos interesantes, así como otras aportaciones de la comunidad.

## Instalación

Para instalar nuestro paquete para Klipper seguiremos los siguientes pasos

### Descarga del repositorio

Nos conectaremos a nuestro host por SSH y lanzaremos los siguientes comandos:

```bash
cd ~/printer_data/config
git clone https://github.com/3dwork-io/3dwork-klipper.git
```

{% hint style="warning" %}
En el caso que el directorio de tu configuración de Klipper esté personalizado recuerda ajustar el primer comando de forma adecuada a tu instalación.
{% endhint %}

{% hint style="info" %}
En nuevas instalaciones:

Dado que Klipper no permite el acceso a las macros hasta que no tiene un printer.cfg correcto y conecta con una MCU podemos "engañar" a Klipper con los siguientes pasos que nos van a permitir utilizar las macros de nuestro bundle para, por ejemplo, lanzar la macro de compilación firmware Klipper si usamos una electrónica compatible:

* Nos aseguramos que tenemos nuestro [host como segunda MCU](/klipper/mejoras/raspberry-como-segunda-mcu)
* A continuación añadiremos un printer.cfg, recuerda que estos pasos es para una instalación limpia donde no tengas ningún printer.cfg y quieras lanzar la macro de crear firmware, como el que puedes ver a continuación:

```django
[mcu]
serial: /tmp/klipper_host_mcu

[printer]
kinematics: none
max_velocity: 1
max_accel: 1

[gcode_macro PAUSE]
rename_existing: PAUSE_BASE
gcode:
  M118 Please install a config first!

[gcode_macro RESUME]
rename_existing: RESUME_BASE
gcode:
  M118 Please install a config first!

[gcode_macro CANCEL_PRINT]
rename_existing: CANCEL_BASE
gcode:
  M118 Please install a config first!
  
[idle_timeout]
gcode:
  {% if printer.webhooks.state|lower == 'ready' %}
    {% if printer.pause_resume.is_paused|lower == 'false' %}
      M117 Idle timeout reached
      TURN_OFF_HEATERS
      M84
    {% endif %}
  {% endif %}
# 2 hour timeout
timeout: 7200

[temperature_sensor raspberry_pi]
sensor_type: temperature_host

[skew_correction]

[input_shaper]

[virtual_sdcard]
path: ~/printer_data/gcodes

[display_status]

[pause_resume]

[force_move]
enable_force_move: True

[respond]
```

Con esto podremos iniciar Klipper para que nos de acceso a nuestra macros.
{% endhint %}

### Usando Moonraker para estar siempre actualizado

Gracias a Moonraker podemos usar su update\_manager para poder estar al día de las mejoras que podamos ir introduciendo en el futuro.

Desde Mainsail/Fluidd editaremos nuestro moonraker.conf (debería encontrarse a la misma altura que vuestro printer.cfg) y añadiremos al final del fichero de configuración:

```django
[include 3dwork-klipper/moonraker.conf]
```

{% hint style="warning" %} <mark style="color:orange;">**Recuerda hacer el paso de instalación previamente si no Moonraker generará un error y no podrá iniciar.**</mark>

**Por otro lado en el caso que el directorio de tu configuración de Klipper esté personalizado recuerda ajustar el path de forma adecuada a tu instalación.**
{% endhint %}

## Macros

Siempre hemos comentado que RatOS es una de las mejores distribuciones de Klipper, con soporte a Raspberry y a módulos CB1, en gran medida por sus configuraciones modulares y sus estupendas macros.

Algunas macros añadidas que nos van a ser de utilidad:

### **Macros de uso general**

| Macro                                                                                         | Descripción                                                                                                                                                                                                                                          |
| --------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **MAYBE\_HOME**                                                                               | Nos permite optimizar el proceso de homing solamente realizando este en aquellos ejes que no están con homing.                                                                                                                                       |
| **PAUSE**                                                                                     | Mediante las variables relacionadas nos permite gestionar una pausa con un parking del cabezal más versátil que las macros normales.                                                                                                                 |
| <p><strong>SET\_PAUSE\_AT\_LAYER</strong><br><strong>SET\_PAUSE\_AT\_NEXT\_LAYER</strong></p> | <p>Una muy útil macro que integra Mainsail en su UI para poder realizar una pausa a demanda en una capa en concreto... por si se nos olvidó al realizar el laminado.<br>También contamos con otra para ejecutar el pausado en la capa siguiente.</p> |
| **RESUME**                                                                                    | Mejorada dado que permite detectar si nuestro nozzle no está a la temperatura de extrusión para poder solventarlo antes de que muestre un error y dañe nuestra impresión.                                                                            |
| **CANCEL\_PRINT**                                                                             | Que permite el uso del resto de macros para realizar una cancelación de impresiónn correctamente.                                                                                                                                                    |

* **Pausado en cambio de capa**, unas macros muy interesantes que nos permiten hacer un pausado programado en una capa o lanzar un comando al iniciar la siguiente capa.\
  ![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/ngLiLpXtNRNiePaNtbwP/image.png)![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/WtXyTwtXfEu7BAwvSNSs/image.png)\
  Además otra ventaja de ellas es que están integradas con Mainsail con lo que tendremos nuevas funciones en nuestra UI como podéis ver a continuación:\
  ![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/fhhW30zu2cZp4u4pOSYt/image.png)![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/ckJ38yJyvWqyeeva5AXi/image.png)

### **Macros de gestión de impresión**

<table><thead><tr><th width="170">Macro</th><th>Descripción</th></tr></thead><tbody><tr><td><strong>START_PRINT</strong></td><td>Nos permitirá poder iniciar nuestras impresiones de una forma segura y al estilo Klipper. Dentro de esta encontraremos algunas funciones interesantes como:<br>- precalentado de nozzle inteligente en el caso de contar con sensor probe<br>- posibilidad de uso de z-tilt mediante variable<br>- mallado de cama adaptativo, forzado o desde una malla guardada<br>- línea de purga personalizable entre normal, línea de purgado adaptativa o gota de purgado<br>- macro segmentada para poder personalizarse tal como os mostraremos más adelante</td></tr><tr><td><strong>END_PRINT</strong></td><td>Macro de fin de impresión donde también disponemos de segmentación para poder personalizar nuestra macro. También contamos con aparcado dinámico del cabezal.</td></tr></tbody></table>

* **Mallado de cama adaptativo**, gracias a la versatilidad de Klipper podemos hacer cosas que a día de hoy parecen imposibles... un proceso importante para la impresion es tener un mallado de desviaciones de nuestra cama que nos permita corregir estas para tener una adherencia de primeras capas perfecta.\
  En muchas ocasiones hacemos este mallado antes de las impresiones para asegurarnos que funcione correctamente y este se hace en toda la superficie de nuestra cama.\
  Con el mallado de cama adaptativo esta se va a realizar en la zona de impresión haciendo que sea mucho más precisa que el método tradicional... en las siguientes capturas veremos las diferencias de una malla tradicional y una adaptativa.\
  ![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/tzhCFrbnNrVj5L2bkdrr/image.png)![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/wajqLHhuYm3u68A8Sy4x/image.png)

### **Macros de gestión de filamento**

Conjunto de macros que nos van a permitir gestionar diferentes acciones con nuestro filamento como la carga o descarga de este.

| Macro                | Descripción                                                                                                          |
| -------------------- | -------------------------------------------------------------------------------------------------------------------- |
| **M600**             | Nos va a permitir compatibilidad con el gcode M600 normalmente usado en los laminadores para el cambio de filamento. |
| **UNLOAD\_FILAMENT** | Configurable mediante las variables nos va a permitir una descarga de filamentos asistida.                           |
| **LOAD\_FILAMENT**   | Igual que la anterior pero relacionada con la carga del filamento.                                                   |

### <mark style="color:orange;">**Macros de gestión de bobinas de filamentos (Spoolman)**</mark>

{% hint style="warning" %}
**SECCIÓN EN PROCESO!!!**
{% endhint %}

[**Spoolman**](https://github.com/Donkie/Spoolman) es un gestor de bobinas de filamento que se integra en Moonraker y que nos permite gestionar nuestro stock y disponibilidad de filamentos.

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FhiSCtknzBswK3eEWyUKS%2Fimage.png?alt=media&amp;token=7119c3c4-45da-4baf-a893-614184c68119" alt=""><figcaption></figcaption></figure>

No vamos a entrar en la instalación y configuración de este dado que es relativamente sencillo utilizando las [**instrucciones de su Github**](https://github.com/Donkie/Spoolman)**,** en cualquier caso **os aconsejamos utilizar Docker** por simplicidad y recordad **activar la configuración en Moonraker** requerida:

{% code title="moonraker.conf" %}

```django
[spoolman]
server: http://192.168.0.123:7912
#   URL to the Spoolman instance. This parameter must be provided.
sync_rate: 5
#   The interval, in seconds, between sync requests with the
#   Spoolman server.  The default is 5.
```

{% endcode %}

| Macro                | Descripción                                           |
| -------------------- | ----------------------------------------------------- |
| SET\_ACTIVE\_SPOOL   | Nos permite indicar cual es el ID de la bobina a usar |
| CLEAR\_ACTIVE\_SPOOL | Nos permite resetear la bobina activa                 |

Lo ideal en cada caso sería el añadir en nuestro laminador, **en los gcodes de filamentos para cada bobina la llamada a esta**, y recuerda **cambiar el ID de esta una vez consumida** para poder llevar un control de lo que resta de filamento en la misma!!!

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FrmYsCT8o5XCgHPgRdi9o%2Fimage.png?alt=media&amp;token=0596900f-2b9a-4f26-ac4b-c13c4db3d786" alt=""><figcaption></figcaption></figure>

### <mark style="color:orange;">**Macros de gestión de superficies de impresión**</mark>

{% hint style="warning" %}
**SECCIÓN EN PROCESO!!!**
{% endhint %}

Suele ser normal que contemos con diferentes superficies de impresión dependiendo del acabado que queramos tener o el tipo de filamento.

Este conjunto de macros, creadas por [Garethky](https://github.com/garethky), van a permitirnos tener tener un control de estas y en especial el ajuste correcto de ZOffset en cada una de ellas al estilo que contamos en máquinas Prusa. A continuación podéis ver algunas de sus funciones:

* podremos almacenar el numero de superficies de impresión que queramos, teniendo cada una un nombre único
* cada superficie de impresión va a tener un ZOffset propio
* si realizamos ajustes de Z durante una impresión (Babystepping) desde nuestro Klipper este cambio se va a almacentar en la superficie habilitada en ese momento

Por otro lado tenemos algunos **requerimientos para implementarlo&#x20;**<mark style="color:orange;">**(se intentará agregar en la lógica del PRINT\_START del bundle en un futuro activando por variable esta función y creando una macro de usuario previa y posterior para poder meter eventos de usuario)**</mark>:

* se necesita el uso de \[save\_variables], en nuestro caso usaremos \~/variables.cfg para almacenar las variables y que ya esta dentro del cfg de estas macros.\
  Esto nos creará automáticamente un fichero variables\_build\_sheets.cfg donde guardara nuestras variables en disco.

{% code title="Example of variables config file" %}

```django
[Variables]
build_sheet flat = {'name': 'flat', 'offset': 0.0}
build_sheet installed = 'build_sheet textured_pei'
build_sheet smooth_pei = {'name': 'Smooth PEI', 'offset': -0.08999999999999997}
build_sheet textured_pei = {'name': 'Textured PEI', 'offset': -0.16000000000000003}
```

{% endcode %}

* deberemos incluis una llamada a APPLY\_BUILD\_SHEET\_ADJUSTMENT en nuestro PRINT\_START para poder aplicar el ZOffset de la superficie seleccionada
* es importante que para que la macro anterior, APPLY\_BUILD\_SHEET\_ADJUSTMENT, funcione correctamente hemos de añadir un SET\_GCODE\_OFFSET Z=0.0 justo antes de llamar a APPLY\_BUILD\_SHEET\_ADJUSTMENT

```django
# Load build sheet
SHOW_BUILD_SHEET                ; show loaded build sheet on console
SET_GCODE_OFFSET Z=0.0          ; set zoffset to 0
APPLY_BUILD_SHEET_ADJUSTMENT    ; apply build sheet loaded zoffset
```

Por otro lado es interesante poder disponer de unas macros para activar una superficie u otra o incluso pasarlo como parámetro desde nuestro laminador para con diferentes perfiles de impresora o de filamento poder cargar una u otra de forma automática:

{% hint style="warning" %}
Es importante que el valor en NAME="xxxx" coincida con el nombre que dimos a la hora de instalar nuestra superficie de impresión
{% endhint %}

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

```django
## Every Build Plate you want to use needs an Install Macro
[gcode_macro INSTALL_TEXTURED_SHEET]
gcode:
    INSTALL_BUILD_SHEET NAME="Textured PEI"

[gcode_macro INSTALL_SMOOTH_SHEET]
gcode:
    INSTALL_BUILD_SHEET NAME="Smooth PEI"
    
[gcode_macro INSTALL_SMOOTH_GAROLITE_SHEET]
gcode:
    INSTALL_BUILD_SHEET NAME="Smooth Garolite"
```

{% endcode %}

También en el caso de contar con KlipperScreen podremos añadir un menú específico para poder gestionar la carga de las diferentes superficies, donde incluiremos una llamada a las macros anteriormente creadas para la carga de cada superficie:

{% code title="\~/printer\_data/config/KlipperScreen.conf" %}

```django
[menu __main actions build_sheets]
name: Build Sheets
icon: bed-level

[menu __main actions build_sheets smooth_pei]
name: Smooth PEI
method: printer.gcode.script
params: {"script":"INSTALL_SMOOTH_PEI_SHEET"}

[menu __main actions build_sheets textured_pei]
name: Textured PEI
method: printer.gcode.script
params: {"script":"INSTALL_TEXTURED_PEI_SHEET"}

[menu __main actions build_sheets smooth_garolite]
name: Smooth Garolite
method: printer.gcode.script
params: {"script":"INSTALL_SMOOTH_GAROLITE_SHEET"}
```

{% endcode %}

| Macro                           | Descripción |
| ------------------------------- | ----------- |
| INSTALL\_BUILD\_SHEET           |             |
| SHOW\_BUILD\_SHEET              |             |
| SHOW\_BUILD\_SHEETS             |             |
| SET\_BUILD\_SHEET\_OFFSET       |             |
| RESET\_BUILD\_SHEET\_OFFSET     |             |
| SET\_GCODE\_OFFSET              |             |
| APPLY\_BUILD\_SHEET\_ADJUSTMENT |             |

### **Macros de configuración de máquina**

| Macro                                                                                           | Descripción                                                                                                                                                                                                                                                                                               |
| ----------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **COMPILE\_FIRMWARE**                                                                           | <p>Con esta macro podremos compilar el firmware Klipper de una forma sencilla, tener el firmware accesible desde la UI para mayor simplicidad y poder aplicarlo a nuestra electrónica.<br><a href="#compilado-de-firmware-mediante-macro">Aquí tenéis más detalle de las electrónicas soportadas.</a></p> |
| **CALCULATE\_BED\_MESH**                                                                        | Una macro extremadamente útil para calcular el área para nuestro mallado porque en ocasiones puede resultar un proceso complicado.                                                                                                                                                                        |
| <p><strong>PID\_ALL</strong><br><strong>PID\_EXTRUDER</strong><br><strong>PID\_BED</strong></p> | Estas macros, donde podemos pasar las temperaturas para el PID en forma de parámetros, nos van a permitir poder realizar la calibración de temperatura de una forma extremadamente sencilla.                                                                                                              |
| <p><strong>TEST\_SPEED</strong><br><strong>TEST\_SPEED\_DELTA</strong></p>                      | Macro original del compañero [Ellis](https://github.com/AndrewEllis93) nos van a permitir de una forma bastante sencilla testear la velocidad a la que podemos mover nuestra máquina de una forma precisa y sin pérdida de pasos.                                                                         |

### Añadiendo las macros 3Dwork a nuestra instalación

Desde nuestra interfaz, Mainsail/Fluidd, editaremos nuestro printer.cfg y añadiremos:

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

```
## 3Dwork standard macros
[include 3dwork-klipper/macros/macros_*.cfg]
## 3Dwork shell macros
[include 3dwork-klipper/shell-macros.cfg]
```

{% endcode %}

{% hint style="info" %}
Es importante que añadamos estas líneas al final de nuestro fichero de configuración... justo por encima de la sección para que en el caso de existir macros en nuestro cfg o includes estas sean sobreescritas por las nuestras :\
\#\*# <---------------------- SAVE\_CONFIG ---------------------->
{% endhint %}

{% hint style="warning" %}
**IMPORTANTE!!!**\
Se han separado las macros normales de las **macros shell** ya que **para habilitar estas es necesario realizar pasos adicionales de forma manual además que están actualmente testeandose** y **pueden requerir de permisos extras para atribuir permisos de ejecución para lo que no se han indicado las instrucciones ya que se esta intentando automatizar.**\ <mark style="color:red;">**Si las utilizas es bajo tu propia responsabilidad.**</mark>

* **Para que Klipper pueda ejecutar shell macros se ha de instalar una extensión, gracias al compañero** [**Arksine**](https://github.com/Arksine)**, que lo permita.**

  <mark style="color:green;">**Dependiendo de la distro de Klipper usada pueden venir ya habilitadas.**</mark>

  ![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/TfVEVUxY0srHCQCN3Gjw/image.png)

  La forma más sencilla es usando [**Kiauh**](/klipper/instalacion#instalando-kiauh) donde encontraremos en una de sus opciones la posibilidad de instalar esta extensión:

  ![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/0FjYUlWC4phJ8vcuaeqT/telegram-cloud-photo-size-4-5837048490604215201-x_partial.jpg)

  También podemos realizar el proceso a mano copiaremos manualmente el plugin para Klipper[ **gcode\_shell\_extension**](https://raw.githubusercontent.com/Rat-OS/RatOS/master/src/modules/ratos/filesystem/home/pi/klipper/klippy/extras/gcode_shell_command.py) dentro de nuestro directorio ***`~/klipper/klippy/extras`*** usando SSH o SCP y reiniciamos Klipper.
  {% endhint %}

### Configuración de nuestro laminador

Dado que nuestras macros son dinámicas van a extraer cierta información de nuestra configuración de impresora y del propio laminador. Para ello os aconsejamos configurar vuestros laminadores de la siguiente forma:

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

{% tabs %}
{% 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](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/WdBRcy89NrRtBi4IagKi/image.png)
{% endtab %}

{% 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="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/7hv1OPOgkT9d3AlupU1v/image.png" alt=""><figcaption></figcaption></figure>
{% 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
```

### Variables

Como ya hemos comentado, estas nuevas macros nos van a permitir disponer de algunas funciones muy útiles como os listamos anteriormente.

Para el ajuste de estas a nuestra máquina utilizaremos las variables que encontraremos en macros/macros\_var\_globals.cfg y que os detallamos a continuación.

#### Idioma de mensajes/notificaciones

Dado que a muchos usuarios les gusta tener las notificaciones de las macros en su idioma hemos ideado un sistema de notificaciones multi-lenguaje, actualmente español (es) e inglés (en). En la siguiente variable podremos ajustarlo:

<table><thead><tr><th width="189">Variable</th><th width="247">Descripción</th><th width="163">Valores posibles</th><th>Valor por defecto</th></tr></thead><tbody><tr><td>variable_language</td><td>Nos permite seleccionar el idioma de las notificaciones. En el caso de no estar bien definido se usará en (inglés)</td><td>es / en</td><td>es</td></tr></tbody></table>

#### Extrusión Relativa

Permite controlar que modo de extrusión usaremos al terminar nuestro START\_PRINT. El valor dependerá de la configuración de nuestro laminador.

{% hint style="success" %}
Es aconsejable que configures tu laminador para el uso de extrusión relativa y ajustar esta variable a True.
{% endhint %}

| Variable                      | Descripción                                                          | Valores posibles | Valor por defecto |
| ----------------------------- | -------------------------------------------------------------------- | ---------------- | ----------------- |
| variable\_relative\_extrusion | Nos permite indicar el modo de extrusión usado en nuestro laminador. | True / False     | True              |

#### Velocidades

Para gestionar las velocidades empleadas en las macros.

| Variable                       | Descripción                        | Valores posibles | Valor por defecto |   |
| ------------------------------ | ---------------------------------- | ---------------- | ----------------- | - |
| variable\_macro\_travel\_speed | Velocidad en translados            | numérico         | 150               |   |
| variable\_macro\_z\_speed      | Velocidad en translados para eje Z | numérico         | 15                |   |

#### Homing

Conjunto de variables relacionadas con el proceso de homing.

| Variable | Descripción | Valores posibles | Valor por defecto |
| -------- | ----------- | ---------------- | ----------------- |
|          |             |                  |                   |

#### Heating

Variables relacionadas con el proceso de calentado de nuestra máquina.

| Variable                                         | Descripción                                                                                        | Valores posibles | Valor por defecto |
| ------------------------------------------------ | -------------------------------------------------------------------------------------------------- | ---------------- | ----------------- |
| variable\_preheat\_extruder                      | Habilita el precalentado del nozzle a la temperatura indicada en variable\_preheat\_extruder\_temp | True / False     | True              |
| variable\_preheat\_extruder\_temp                | Temperatura de precalentado del nozzle                                                             | numérico         | 150               |
| variable\_start\_print\_heat\_chamber\_bed\_temp | Temperatura de la cama durante el proceso de calentar nuestro cerramiento                          | numérico         | 100               |

{% hint style="success" %}
Beneficios de utilizar el precalentado del nozzle:

* nos permite un tiempo adicional para que la cama pueda llegar a su temperatura de una forma uniforme
* si usamos un sensor indutivo que no tiene compensación de temperatura nos va a permitir que nuestras medidas sean mas consistentes y precisas
* permite ablandar cualquier resto de filamento en el nozzle lo que permite que, en determinadas configuraciones, estos restos no afecten a la activación del sensor
  {% endhint %}

#### Mallado de cama (Bed Mesh)

Para controlar el proceso de nivelación contamos con variables que pueden sernos muy útiles. Por ejemplo, podremos controlar el tipo de nivelación que queremos utilizar creando una nueva malla siempre, cargando una almacenada anteriormente o utilizar un mallado adaptativo.

| Variable                       | Descripción                                                                                                                                                                                                                                                                                                                                                                                                                                                   | Valores posibles                                     | Valor por defecto |
| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------- | ----------------- |
| variable\_calibrate\_bed\_mesh | <p>Nos permite seleccionar que tipo de mallado usaremos en nuestro START\_PRINT:<br>- new mesh, nos hará un mallado en cada impresión<br>- storedmesh, cargará un mallado almacenado y no realizará el sondeo de cama<br>- adaptative, nos hará un nuevo mallado pero adaptado a la zona de impresión mejorando en muchas ocasiones nuestras primeras capas<br>- nomesh, en el caso que no tengamos sensor o utilicemos mallado para saltarnos el proceso</p> | <p>newmesh / storedmesh / adaptative /<br>nomesh</p> | adaptative        |
| variable\_bed\_mesh\_profile   | El nombre usado para nuestra malla almacenada                                                                                                                                                                                                                                                                                                                                                                                                                 | texto                                                | default           |

{% hint style="warning" %}
Os aconsejamos usar el nivelado adaptative ya que va a ajustar siempre el mallado al tamaño de nuesta impresión permitiendo tener un área de mallado ajustado.

Es importante que tengamos en nuestro [gcode de incio de nuestro laminador](/klipper/empezamos/configuracion-klipper-en-laminadores#configurando-nuestro-laminador-para-usar-nustras-macros-start_print-y-end_print), en la llamada a nuestro START\_PRINT, los valores PRINT\_MAX y PRINT\_MIN.
{% endhint %}

#### Purgado

Una fase importante de nuestro inicio de impresión es un correcto purgado de nuestro nozzle para evitar restos de filamento o que estos puedan dañar nuestra impresión en algún momento. A continuación tienes las variables que intervienen en este proceso:

| Variable                                  | Descripción                                                                                                                                                                                                                                                                                                                                                                                                                      | Valores posibles                                                       | Valor por defecto   |
| ----------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- | ------------------- |
| variable\_nozzle\_priming                 | <p>Podemos elegir entre diferentes opciones de purgado:<br>- primeline nos va a dibujar la típica línea de purgado<br>- primelineadaptative nos va a generar una línea de purga que se adapta a la zona de la pieza impresa usando variable\_nozzle\_priming\_objectdistance como margen<br>- primeblob nos hará una gota de filamento en una esquina de nuestra cama muy efectiva para limpiar el nozzle y fácil de retirar</p> | <p>primeline /</p><p>primelineadaptative /<br>primeblob /<br>False</p> | primelineadaptative |
| variable\_nozzle\_priming\_objectdistance | Si usamos línea de purga adaptativa será el margen a utilizar entre la línea de purga y el objeto impreso                                                                                                                                                                                                                                                                                                                        | numérico                                                               | 5                   |
| variable\_nozzle\_prime\_start\_x         | <p>Donde queremos ubicar nuestra línea de purga:<br>- min lo hará en X=0 (más un pequeño margen de seguridad)<br>- max lo hará en X=max (menos un pequeño margen de seguridad)<br>- número será la coordenada X donde ubicar la purga</p>                                                                                                                                                                                        | <p>min /<br>max /<br>número</p>                                        | max                 |
| variable\_nozzle\_prime\_start\_y         | <p>Donde queremos ubicar nuestra línea de purga:<br>- min lo hará en Y=0 (más un pequeño margen de seguridad)<br>- max lo hará en Y=max (menos un pequeño margen de seguridad)<br>- número será la coordenada Y donde ubicar la purga</p>                                                                                                                                                                                        | <p>min /<br>max /<br>número</p>                                        | min                 |
| variable\_nozzle\_prime\_direction        | <p>La dirección de nuestra línea o gota:<br>- backwards el cabezal se moverá al frontal de la impresora<br>- forwards se moverá a la parte trasera<br>- auto irá hacia el centro dependiendo de variable\_nozzle\_prime\_start\_y</p>                                                                                                                                                                                            | <p>auto /<br>forwards /<br>backwards</p>                               | auto                |

#### Carga/Descarga de filamento

En este caso este grupo de variables nos van a facilitar la gestión de carga y descarga de nuestro filamento usado en emulación del M600 por ejemplo o al lanzar las macros de carga y descarga de filamento:

| Variable                           | Descripción                                                                                                                                                                                                                                                                                                                                                                               | Valores posibles | Valor por defecto |
| ---------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | ----------------- |
| variable\_filament\_unload\_length | Cuanto retraer en mm el filamento, ajustar a tu máquina, normalmente la medida desde tu nozzle a los engranajes de tu extrusor añadiendo un margen extra.                                                                                                                                                                                                                                 | número           | 130               |
| variable\_filament\_unload\_speed  | Velocidad de retraccíon del filamento en mm/seg normalmente se usa una velocidad lenta.                                                                                                                                                                                                                                                                                                   | número           | 5                 |
| variable\_filament\_load\_length   | Distancia en mm para cargar el nuevo filamento... al igual que en variable\_filament\_unload\_length usaremos la medida desde tu engranaje a extrusor añadiendo un margen extra, en este caso este valor extra dependerá de cuanto quieres que se purgue... normalmente puedes darle más margen que el valor anterior para asegurar que quede limpia la extrusion del filamento anterior. | número           | 150               |
| variable\_filament\_load\_speed    | Velocidad de carga del filamento en mm/seg normalmente se usa una velocidad más rápida que le de descarga.                                                                                                                                                                                                                                                                                | número           | 10                |

{% hint style="warning" %}
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\_filament\_unload\_length** y/o **variable\_filament\_load\_length**.
{% endhint %}

#### Parking

En determinados procesos de nuestra impresora, como el pausado, es aconsejable hacer un parking de nuestro cabezal. Las macros de nuestro bundle disponen de esta opción además de las siguientes variables para gestionar:

{% hint style="warning" %}
Si tienes una impresora con cinemática tipo "delta" (Flsun o similares) por favor asegurate que la variable `variable_start_print_park_in` este con el valor `delta` ya que se tiene en vuenta para las macros que puedan afectar a este tipo de cinemática.

**En cualquier caso el bundle no esta verificado con este tipo de impresoras por lo que si tenéis cualquier problema por favor decirnoslo en los grupos.**
{% endhint %}

| Variable                                | Descripción                                                                                                                                                                                                                                                                  | Valores posibles                              | Valor por defecto |
| --------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------- | ----------------- |
| variable\_start\_print\_park\_in        | Ubicación donde aparcar el cabezal durante el pre-calentado.                                                                                                                                                                                                                 | <p>back /<br>center /<br>front /<br>delta</p> | back              |
| variable\_start\_print\_park\_z\_height | Altura en Z durante el pre-calentado                                                                                                                                                                                                                                         | número                                        | 50                |
| variable\_end\_print\_park\_in          | Ubicación donde aparcar el cabezal al finalizar o cancelar una impresión.                                                                                                                                                                                                    | <p>back /<br>center /<br>front</p>            | back              |
| variable\_end\_print\_park\_z\_hop      | Distancia a subir en Z al finalizar la impresión.                                                                                                                                                                                                                            | número                                        | 20                |
| variable\_pause\_print\_park\_in        | Ubicación donde aparcar el cabezal al pausar la impresión.                                                                                                                                                                                                                   | <p>back /<br>center /<br>front</p>            | back              |
| variable\_pause\_idle\_timeout          | Valor, en segundos, de la activación de proceso de inactividad en la máquina que libera motores y hacer perder coordenadas, **es aconsejable un valor alto para que al activar la macro PAUSE tarde suficiente para realizar cualquier acción antes de perder coordenadas.** | número                                        | 43200             |

#### Z-Tilt

Aprovechar al máximo nuestra máquina para que esta se autonivele y facilitar que nuestra máquina siempre esté en las mejores condiciones es fundamental.

**Z-TILT básicamente es un proceso que nos ayuda a alinear nuestros motores de Z con respecto a nuestro eje/gantry X (cartesiana) o XY (CoreXY)**. Con esto **aseguramos que tenemos siempre alineado nuestro Z perfectamente y de forma precisa y automática**.

| Variable                     | Descripción                                                                                                | Valores posibles | Valor por defecto |
| ---------------------------- | ---------------------------------------------------------------------------------------------------------- | ---------------- | ----------------- |
| variable\_calibrate\_z\_tilt | Permite, en el caso de tenerlo habilitado en nuestra configuración de Klipper, el proceso de ajuste Z-Tilt | True / False     | False             |

#### Skew

El uso de [SKEW](https://github.com/alienboyxp/gitbook_es_klipper_3dwork_io/blob/main/broken/pages/-MTqPy_NKPC-R-jkDi7M/README.md#7.-pasos-ejes) para la corrección o ajuste preciso de nuestras impresoras es extremadamente aconsejable si tenemos desviaciones en nuestras impresiones. Usando la siguiente variable podemos permitir el uso en nuestras macros:

| Variable                | Descripción                                                                                                                                                                                                    | Valores posibles | Valor por defecto |
| ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | ----------------- |
| variable\_skew\_profile | Permite tener en cuenta nuestro perfil de skew que será cargado en nuestra macro START\_PRINT. Para activarlo deberemos des comentar la variable y usar el nombre del perfil de skew de nuestra configuración. | texto            | my\_skew\_profile |

### Personalización de las macros

Nuestro módulo para Klipper emplea el sistema de configuración modular empleado en RatOS y que aprovecha las ventajas de Klipper en el procesado de ficheros de configuración de forma secuencial de este. Por esto es fundamental el orden de los include y ajustes personalizados que queramos aplicar sobre estos módulos.

{% hint style="info" %}
Al usarse como uno módulo las configuraciones de 3Dwork NO pueden editarse directamente desde el directorio 3dwork-klipper dentro de tu directorio de configuración de Klipper dado que estará en read-only (restringido a solo lectura) por seguridad.

Por eso es muy importante entender el funcionamiento de Klipper y como poder personalizar nuestros módulos a tu máquina.
{% endhint %}

#### **Personalizando variables**

Normalmente, será lo que tendremos que ajustar, para realizar ajustes sobre las variables que tengamos por defecto en nuestro módulo **3Dwork** para Klipper.

Simplemente, lo que tengamos que hacer es pegar el contenido de la macro \[gcode\_macro GLOBAL\_VARS] que podremos encontrar en macros/macros\_var\_globals.cfg en nuestro printer.cfg.

Os recordamos lo comentado anteriormente de como procesa Klipper las configuraciones de forma secuencial, por lo que es aconsejable pegarlo después de los includes que os comentamos [aquí](#anadiendo-las-macros-3dwork-a-nuestra-instalacion).

Nos quedará algo así (solo es un ejemplo visual):

<pre class="language-django"><code class="lang-django">### 3Dwork Klipper Includes
[include 3dwork-klipper/macros/macros_*.cfg]

### USER OVERRIDES
<strong>## VARIABLES 3DWORK
</strong>[gcode_macro GLOBAL_VARS]
description: GLOBAL_VARS variable storage macro, will echo variables to the console when run.
# Configuration Defaults
# This is only here to make the config backwards compatible.
# Configuration should exclusively happen in printer.cfg.

# Possible language values: "en" or "es" (if the language is not well defined, "en" is assigned by default.)
variable_language: "es"                         # Possible values: "en", "es"
...


#*# &#x3C;---------------------- SAVE_CONFIG ---------------------->
#*# DO NOT EDIT THIS BLOCK OR BELOW. The contents are auto-generated.
#*#
</code></pre>

{% hint style="warning" %}
Los tres puntos (...) de los ejemplos anteriores son meramente para indicar que puedes tener más configuraciones entre secciones... en ningún caso han de ponerse.
{% endhint %}

{% hint style="info" %}

* os aconsejamos añadir comentarios tal como veis en el caso anterior para identificar que hace cada sección
* aunque no necesites tocar todas las variables te aconsejamos copiar todo el contenido de \[gcode\_macro GLOBAL\_VARS]
  {% endhint %}

#### Personalizando macros

Las macros se han montado de una forma modular para que se puedan ajustar de una forma sencilla. Tal como os hemos comentado anteriormente, si queremos ajustarlas deberemos proceder igual que hicimos con las variables, copiar la macro en cuestión en nuestro printer.cfg (u otro include nuestro propio) y asegurarnos que está después del include donde añadimos nuestro módulo 3Dwork para Klipper.

Tenemos dos grupos de macros:

* Macros para añadir ajustes de usuario, estas macros se pueden añadir y personalizar fácilmente porque se añadieron para que cualquier usuario pueda personalizar las acciones a su gusto en determinadas parte de los procesos que hace cada macro.

**START\_PRINT**

<table><thead><tr><th width="400">Nombre Macro</th><th>Descripción</th></tr></thead><tbody><tr><td>_USER_START_PRINT_HEAT_CHAMBER</td><td>Se ejecuta justo después que nuestro cerramiento empiece a calentar, si CHAMBER_TEMP se pasa como parámetro a nuestro START_PRINT</td></tr><tr><td>_USER_START_PRINT_BEFORE_HOMING</td><td>Se ejecuta antes del homing inicial de inicio de impresión</td></tr><tr><td>_USER_START_PRINT_AFTER_HEATING_BED</td><td>Se ejecuta al llegar nuestra cama a su temperatura, antes de _START_PRINT_AFTER_HEATING_BED</td></tr><tr><td>_USER_START_PRINT_BED_MESH</td><td>Se lanza antes de _START_PRINT_BED_MESH</td></tr><tr><td>_USER_START_PRINT_PARK</td><td>Se lanza antes de _START_PRINT_PARK</td></tr><tr><td>_USER_START_PRINT_AFTER_HEATING_EXTRUDER</td><td>Se lanza antes de _START_PRINT_AFTER_HEATING_EXTRUDER</td></tr></tbody></table>

**END\_PRINT**

| Nombre Macro                             | Descripción                                                                                              |
| ---------------------------------------- | -------------------------------------------------------------------------------------------------------- |
| \_USER\_END\_PRINT\_BEFORE\_HEATERS\_OFF | Se ejecuta antes de realizar el apagado de los calentadores, antes de \_END\_PRINT\_BEFORE\_HEATERS\_OFF |
| \_USER\_END\_PRINT\_AFTER\_HEATERS\_OFF  | Se ejecuta después del apagado de los calentadores, antes de \_END\_PRINT\_AFTER\_HEATERS\_OFF           |
| \_USER\_END\_PRINT\_PARK                 | Se ejecuta antes del aparcado del cabezal, antes de \_END\_PRINT\_PARK                                   |

**PRINT\_BASICS**

| Nombre Macro          | Descripción                       |
| --------------------- | --------------------------------- |
| \_USER\_PAUSE\_START  | Se ejecuta al inicio de un PAUSE  |
| \_USER\_PAUSE\_END    | Se ejecuta al finalizar un PAUSE  |
| \_USER\_RESUME\_START | Se ejecuta al inicio de un RESUME |
| \_USER\_RESUME\_END   | Se ejecuta al finalizar un RESUME |

* Macros internas, son macros para dividir la macro principal en procesos y es importante para este. Es aconsejable que en caso de requerir ajustarse estas se copien tal cual.

**START\_PRINT**

<table><thead><tr><th width="405">Nombre Macro</th><th>Descripción</th></tr></thead><tbody><tr><td>_START_PRINT_HEAT_CHAMBER</td><td>Calienta el cerramiento en el caso de que el parámetro CHAMBER_TEMP sea recibido por nuestra macro START_PRINT desde el laminador</td></tr><tr><td>_START_PRINT_AFTER_HEATING_BED</td><td>Se ejecuta al llegar la cama a la temperatura, después de _USER_START_PRINT_AFTER_HEATING_BED. Normalmente, se usa para el procesado de calibraciones de cama (Z_TILT_ADJUST, QUAD_GANTRY_LEVELING,...)</td></tr><tr><td>_START_PRINT_BED_MESH</td><td>Se encarga de la lógica de mallado de cama.</td></tr><tr><td>_START_PRINT_PARK</td><td>Aparca el cabezal de impresión mientras calienta el nozzle a la temperatura de impresión.</td></tr><tr><td>_START_PRINT_AFTER_HEATING_EXTRUDER</td><td>Realiza el purgado del nozzle y carga el perfil SKEW en caso de que así definamos en las variables</td></tr></tbody></table>

## Impresoras y electrónicas

A medida que trabajemos con diferentes modelos de impresoras y electrónicas iremos añadiendo aquellas que no estén directamente soportadas por RatOS ya sean aportaciones nuestras o de la comunidad.

* printers, en este directorio tendremos todas las configuraciones de impresoras
* boards, aquí encontraremos las de electrónicas

### Parámetros y pines

Nuestro módulo para Klipper emplea el sistema de configuración modular empleado en RatOS y que aprovecha las ventajas de Klipper en el procesado de ficheros de configuración de forma secuencial de este. Por esto es fundamental el orden de los include y ajustes personalizados que queramos aplicar sobre estos módulos.

{% hint style="info" %}
Al usarse como uno módulo las configuraciones de 3Dwork NO pueden editarse directamente desde el directorio 3dwork-klipper dentro de tu directorio de configuración de Klipper dado que estará en read-only (restringido a solo lectura) por seguridad.

Por eso es muy importante entender el funcionamiento de Klipper y como poder personalizar nuestros módulos a tu máquina.
{% endhint %}

Tal como os explicábamos en "[personalizando macros](#personalizando-macros)" usaremos el mismo proceso para ajustar parámetros o pines para ajustarlos a nuestras necesidades.

### Compilado de firmware mediante macro

**Compilado de firmware para electronicas soportadas**, para facilitar el proceso de creación y mantenimiento de nuestro firmware Klipper para nuestras MCU contamos con la macro COMPILE\_FIRMWARE que al ejecutarla, podemos usar como parámetro nuestra electrónica para hacer solamente esta, compilará Klipper para todas las electrónicas soportadas por nuestro bundle:\
![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/ErIelUs1lDcFKMTBIKyR/image.png)\
Encontraremos estas accesibles de forma sencilla desde nuestra UI web en el directorio firmware\_binaries en nuestra pestaña MACHINE (si usamos Mainsail):\
![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/YmubeTDwxD5Yjk7xR6gS/telegram-cloud-photo-size-4-6019366631093943185-y.jpg)\
A continuación tenéis la lista de electrónicas soportadas:

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

* estos scripts están preparados para funcionar sobre un sistema Raspbian con usuario pi, si no es tu caso deberás adaptarlo.
* los firmwares son generados para su uso con conexión USB que siempre es lo que aconsejamos, además el punto de montaje USB siempre es el mismo por lo que vuestra configuración de la conexión de vuestra MCU no va a cambiar si se generan con nuestra macro/script
* **Para que Klipper pueda ejecutar shell macros se ha de instalar una extensión, gracias al compañero** [**Arksine**](https://github.com/Arksine)**, que lo permita.**

  <mark style="color:green;">**Dependiendo de la distro de Klipper usada pueden venir ya habilitadas.**</mark>

  ![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/TfVEVUxY0srHCQCN3Gjw/image.png)

  La forma más sencilla es usando [**Kiauh**](/klipper/instalacion#instalando-kiauh) donde encontraremos en una de sus opciones la posibilidad de instalar esta extensión:

  ![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/0FjYUlWC4phJ8vcuaeqT/telegram-cloud-photo-size-4-5837048490604215201-x_partial.jpg)

  También podemos realizar el proceso a mano copiaremos manualmente el plugin para Klipper[ **gcode\_shell\_extension**](https://raw.githubusercontent.com/Rat-OS/RatOS/master/src/modules/ratos/filesystem/home/pi/klipper/klippy/extras/gcode_shell_command.py) dentro de nuestro directorio ***`~/klipper/klippy/extras`*** usando SSH o SCP y reiniciamos Klipper.
  {% endhint %}

{% tabs %}
{% tab title="Bigtreetech" %}

| Electrónica        | Nombre de parámetro a usar en macro |
| ------------------ | ----------------------------------- |
| Kraken             | btt-kraken                          |
| Manta E3 EZ        | btt-manta-e3ez                      |
| Manta M4P          | btt-manta-m4p                       |
| Manta M4P v2.2     | btt-manta-m4p-22                    |
| Manta M5P          | btt-manta-m5p                       |
| Manta M8P          | btt-manta-m8p                       |
| Manta M8P v1.1     | btt-manta-m8p-11                    |
| Manta M8P v2.0     | manta-m8p-20                        |
| Octopus Max EZ     | btt-octopus-max-ez                  |
| Octopus Pro (446)  | btt-octopus-pro-446                 |
| Octopus Pro (429)  | btt-octopus-pro-429                 |
| Octopus Pro (H723) | btt-octopus-pro-h723                |
| Octopus v1.1       | btt-octopus-11                      |
| Octopus v1.1 (407) | btt-octopus-11-407                  |
| SKR Pro v1.2       | skr\_pro\_12                        |
| SKR 3              | btt\_skr\_3                         |
| SKR 3 (H723)       | btt-skr-3-h723                      |
| SKR 3 EZ           | btt-skr-3-ez                        |
| SKR 3 EZ (H723)    | btt-skr-3-ez-h723                   |
| SKR 2 (429)        | btt-skr-2-429                       |
| SKR 2 (407)        | btt-skr-2-407                       |
| SKR RAT            | btt-skrat-10                        |
| SKR 1.4            | btt-skr-14                          |
| SKR 1.4 Turbo      | btt-skr-14-turbo                    |
| SKR Mini E3 v3     | btt\_skr\_mini\_e3\_30              |

| Toolhead (CAN) | Nombre de parámetro a usar en macro |
| -------------- | ----------------------------------- |
| EBB42 v1       | btt\_ebb42\_10                      |
| EBB36 v1       | btt\_ebb36\_10                      |
| EBB42 v1.1     | btt\_ebb42\_11                      |
| EBB36 v1.1     | btt\_ebb36\_11                      |
| EBB42 v1.2     | btt\_ebb42\_12                      |
| EBB36 v1.2     | btt\_ebb36\_12                      |
| {% endtab %}   |                                     |

{% tab title="MKS/ZNP" %}

| Electrónica          | Nombre de parámetro a usar en macro |
| -------------------- | ----------------------------------- |
| MKS Eagle v1.x       | mks-eagle-10                        |
| MKS Robin Nano v3    | mks-robin-nano-30                   |
| MKS Robin Nano v2    | mks-robin-nano-20                   |
| MKS Gen L            | mks-gen-l                           |
| ZNP Robin Nano DW v2 | znp\_robin\_nano\_dw\_v2            |
| {% endtab %}         |                                     |

{% tab title="Mellow" %}

| Toolhead (CAN)    | Nombre de parámetro a usar en macro |
| ----------------- | ----------------------------------- |
| Mellow FLY SHT 42 | mellow\_fly\_sht\_42                |
| Mellow FLY SHT 36 | mellow\_fly\_sht\_36                |
| {% endtab %}      |                                     |

{% tab title="Fysetc" %}

| Electrónica  | Nombre de parámetro a usar en macro |
| ------------ | ----------------------------------- |
| Spider       | fysetc\_spider                      |
| Spider v2.2  | fysetc\_spider-22                   |
| {% endtab %} |                                     |

{% tab title="Artillery" %}

| Electrónica         | Nombre de parámetro a usar en macro |
| ------------------- | ----------------------------------- |
| Artillery Ruby v1.x | artillery-ruby-12                   |
| {% endtab %}        |                                     |

{% tab title="Raspberry" %}

| Electrónica           | Nombre de parámetro a usar en macro |
| --------------------- | ----------------------------------- |
| Raspberry Pico/RP2040 | rpi-rp2040                          |
| {% endtab %}          |                                     |

{% tab title="LDO" %}

| Electrónica    | Nombre de parámetro a usar en macro |
| -------------- | ----------------------------------- |
| Leviathan v1.2 | ldo-leviathan-12                    |
| {% endtab %}   |                                     |
| {% endtabs %}  |                                     |

#### Personalizando parámetros

Tal como os aconsejamos crear un apartado en vuestro printer.cfg que se llame USER OVERRIDES, colocado después de los includes a nuestras configuraciones, para poder ajustar y personalizar cualquier parámetro usado en ellos.

En el siguiente ejemplo veremos como en nuestro caso estamos interesados en personalizar los parámetros de nuestra nivelación de cama (bed\_mesh) ajustando los puntos de sondeo (probe\_count) con respecto en la configuración que tenemos por defecto en las configuraciones de nuestro módulo Klipper:

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

```django
### 3Dwork Klipper Includes
[include 3dwork-klipper/macros/macros_*.cfg]

### USER OVERRIDES
## VARIABLES 3DWORK
[gcode_macro GLOBAL_VARS]
...

## PARAMETERS 3Dwork
[bed_mesh]
probe_count: 11,11
...

#*# <---------------------- SAVE_CONFIG ---------------------->
#*# DO NOT EDIT THIS BLOCK OR BELOW. The contents are auto-generated.
#*#
```

{% endcode %}

{% hint style="warning" %}
Los tres puntos (...) de los ejemplos anteriores son meramente para indicar que puedes tener más configuraciones entre secciones... en ningún caso han de ponerse.
{% endhint %}

Podemos emplear este mismo proceso con cualquier parámetro que queramos ajustar.

#### Personalizando configuración de pines

Procederemos exactamente tal como hemos hecho anteriormente, en nuestra zona USER OVERRIDES añadiremos aquellas secciones de pins que queramos ajustar a nuestro gusto.

En el siguiente ejemplo vamos a personalizar cual es el pin de nuestro ventilador de electrónica (controller\_fan) para asignarlo a uno diferente al de por defecto:

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

```django
### 3Dwork Klipper Includes
[include 3dwork-klipper/macros/macros_*.cfg]

### USER OVERRIDES
## VARIABLES 3DWORK
[gcode_macro GLOBAL_VARS]
...

## PARAMETERS 3Dwork
[bed_mesh]
probe_count: 11,11
...

## PINS 3Dwork
[controller_fan controller_fan]
pin: PA8

#*# <---------------------- SAVE_CONFIG ---------------------->
#*# DO NOT EDIT THIS BLOCK OR BELOW. The contents are auto-generated.
#*#
```

{% endcode %}

{% hint style="warning" %}
Los tres puntos (...) de los ejemplos anteriores son meramente para indicar que puedes tener más configuraciones entre secciones... en ningún caso han de ponerse.
{% endhint %}


# Backup Klipper

Siempre es aconsejable disponer de una copia de seguridad de nuestro sistema o ficheros de configuración para, en caso de desastre, poder restaurarlo rápidamente.

La mayoría de los usuarios no piensan en el backup hasta que algo sale mal: la SD se corrompe, una actualización rompe algo, o se borra sin querer el `printer.cfg` tras semanas de calibración. En ese momento, tener (o no tener) un backup marca la diferencia entre recuperarse en minutos o empezar desde cero.

Esta guía cubre dos estrategias complementarias:

| Tipo                                  | Qué cubre                                             | Cuándo usarlo                                                                  |
| ------------------------------------- | ----------------------------------------------------- | ------------------------------------------------------------------------------ |
| **Imagen completa de SD**             | Todo el sistema operativo + Klipper + configuraciones | Antes de actualizaciones importantes, cuando el sistema funciona perfectamente |
| **Backup de configuración en GitHub** | Solo los ficheros `.cfg` y scripts                    | Antes de cualquier cambio de configuración, de forma automatizada              |

**Recomendación**: usa ambos métodos. La imagen SD te salva si el hardware falla. El backup en GitHub te salva en el día a día cuando tocas algo que no deberías.

***

## ¿Qué ficheros son críticos?

Antes de hablar de herramientas, es importante saber qué necesitas guardar realmente:

| Fichero / Directorio                   | Importancia    | Descripción                                                |
| -------------------------------------- | -------------- | ---------------------------------------------------------- |
| `~/printer_data/config/printer.cfg`    | **Crítico**    | Configuración principal de la impresora                    |
| `~/printer_data/config/moonraker.conf` | **Crítico**    | Configuración de la API Moonraker                          |
| `~/printer_data/config/*.cfg`          | **Crítico**    | Todos los includes, macros, configuraciones adicionales    |
| `~/printer_data/config/variables.cfg`  | **Importante** | Variables persistentes de macros (z-offset guardado, etc.) |
| `~/klipper/`                           | Opcional       | El código fuente de Klipper — recuperable con `git pull`   |
| `~/moonraker/`                         | Opcional       | Código de Moonraker — recuperable                          |
| `~/printer_data/database/`             | Opcional       | Historial de impresiones, spoolman, estadísticas           |

{% hint style="warning" %}
El directorio `~/printer_data/gcodes/` (archivos de impresión) y los timelapse **no se incluyen** en el backup de configuración. Si los necesitas, inclúyelos manualmente o usa una solución de backup diferente.
{% endhint %}

***

## Cuándo hacer backup

* **Siempre antes de actualizar** Klipper, Moonraker o cualquier componente del sistema
* **Antes de tocar el `printer.cfg`** si vas a hacer cambios importantes
* **Tras finalizar una calibración** que te costó tiempo (Input Shaper, Pressure Advance, z-offset)
* **Cuando la impresora funciona perfectamente** — ese es el momento ideal, no cuando ya hay problemas

***

## Método 1 — Imagen completa de la SD

Una imagen de la SD es una copia bit a bit de todo el sistema: sistema operativo, Klipper, Moonraker, interfaces web, configuraciones y todo lo demás. Si restauras esta imagen en una SD nueva, recuperas exactamente el estado que tenías.

{% hint style="info" %}
Aunque está enfocado a hosts con SD (Raspberry Pi), la lógica aplica a cualquier host Linux con almacenamiento extraíble.
{% endhint %}

### Crear imagen — Windows (Win32DiskImager)

* Apaga el host correctamente antes de extraer la SD:

```bash
sudo shutdown now
```

O desde la interfaz web de Mainsail/Fluidd → botón de apagado del host.

* Extrae la SD e insértala en el PC con Windows
* Descarga e instala [**Win32DiskImager**](https://win32diskimager.com/)
* Selecciona el **Device** correcto (tu SD) y elige la ruta de destino con extensión `.img`

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/oc5WvOi1Ge7LNtPCcBg8/image.png" alt=""><figcaption></figcaption></figure>

* Pulsa **Read** y espera a que finalice

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/7gRjdeuE8xLzxRxSA9WF/image.png" alt=""><figcaption></figcaption></figure>

### Crear imagen — macOS (Disk Utility)

* Inserta la SD en el Mac
* Abre **Disk Utility** (Cmd+Space → "Disk Utility")
* En el menú **File → New Image → Image from...** selecciona tu SD

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/IQ9NMS9x3b6saQ1uWGcu/image.png" alt=""><figcaption></figcaption></figure>

* Elige destino y nombre, asegúrate de no marcar encriptación, y pulsa **Save**

### Crear imagen — desde la propia Raspberry Pi

Puedes crear la imagen directamente desde el host sin extraer la SD. Necesitas un pendrive USB con espacio suficiente.

Conecta el pendrive y comprueba dónde se montó:

```bash
# Lanza antes de y después de insertar el pendrive para ver qué apareció nuevo
df -h
```

Anota el punto de montaje (ejemplo: `/media/pi/MYBACKUP`).

Instala el script de backup:

```bash
cd ~
git clone https://github.com/lzkelley/bkup_rpimage.git
```

Lanza el backup:

```bash
sudo sh ~/bkup_rpimage/bkup_rpimage.sh start -c /media/pi/MYBACKUP/klipper_backup.img
```

{% hint style="success" %}
**Comprimir la imagen con PiShrink**

Las imágenes de SD suelen ocupar más de lo necesario. PiShrink las comprime significativamente y facilita restaurarlas en SDs más pequeñas:

```bash
wget https://raw.githubusercontent.com/Drewsif/PiShrink/master/pishrink.sh
sudo chmod +x pishrink.sh
sudo mv pishrink.sh /usr/local/bin

# Comprimir la imagen recién creada
sudo pishrink.sh -z /media/pi/MYBACKUP/klipper_backup.img
```

La opción `-z` crea un archivo `.gz` comprimido. Para restaurarlo, los programas de flasheo lo admiten directamente.
{% endhint %}

**Automatizar con cron:**

```bash
sudo crontab -e
```

Añade una de estas líneas según tu preferencia:

```bash
# Backup incremental (sobreescribe siempre el mismo fichero) — cada noche a las 2:00
0 2 * * * sudo sh /home/pi/bkup_rpimage/bkup_rpimage.sh start -c /media/pi/MYBACKUP/klipper_backup.img

# Backup con fecha en el nombre — un fichero diferente cada día
0 2 * * * sudo sh /home/pi/bkup_rpimage/bkup_rpimage.sh start -c /media/pi/MYBACKUP/klipper_$(date +%Y-%m-%d).img
```

### Restaurar la imagen SD

{% tabs %}
{% tab title="Raspberry Pi Imager (Win/macOS)" %}
La opción más sencilla. Descárgalo desde [raspberrypi.com/software](https://www.raspberrypi.com/software/).

* Selecciona **Use Custom** como sistema operativo

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/TSVgoFqTv5DSI2ZgScZQ/image.png)

* Selecciona tu imagen `.img` y la SD nueva como destino

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/BHeMvl2EIS0tWSLE12WQ/image.png)

* Pulsa **Write** y espera

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/rNxQYY8aDIFgLrLQIKcb/image.png)
{% endtab %}

{% tab title="balenaEtcher (Win/macOS/Linux)" %}
Descarga [**balenaEtcher**](https://www.balena.io/etcher/).

* Selecciona **Flash from file** y elige tu imagen
* Selecciona la SD nueva como destino

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/ctxuRveUnEx1SZY11rgw/image.png" alt=""><figcaption></figcaption></figure>

* Pulsa **Flash** y acepta los avisos de seguridad que aparezcan
  {% endtab %}

{% tab title="Win32DiskImager (Windows)" %}

* Abre [**Win32DiskImager**](https://win32diskimager.com/) con la nueva SD ya insertada
* Selecciona la imagen previamente creada y la SD como destino
* Pulsa **Write** (en lugar de Read)

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/a0RJNaFVQlIA83S44njG/image.png" alt=""><figcaption></figcaption></figure>
{% endtab %}
{% endtabs %}

***

## Método 2 — Backup de configuración en GitHub

Este método guarda solo los ficheros de configuración (`.cfg`, scripts, etc.) en un repositorio GitHub privado con historial de versiones. Es el complemento perfecto al método anterior: más rápido, siempre accesible online y con control de cambios.

Ventajas respecto a la imagen de SD:

* Se lanza con una macro desde Mainsail/Fluidd en segundos
* Puedes ver qué cambió entre versiones y revertir a un punto concreto
* Accesible desde cualquier ordenador sin extraer la SD
* No necesitas hardware adicional

### Paso 1 — Crear el repositorio en GitHub

Si no tienes cuenta en GitHub, créala en [github.com/signup](https://github.com/signup) (cuenta gratuita).

* Haz login y crea un nuevo repositorio pulsando **New**

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/bQ6Uo9A7hUcEgSoMXI9v/image.png)

* Dale un nombre descriptivo (ej: `voron24_klipper_config`) y elige si quieres que sea **Private** (recomendado — tus configs pueden contener datos de red)

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/Qqa5LqgK8NElVjY9W1LR/image.png" alt=""><figcaption></figcaption></figure>

* Anota la URL del repositorio — la necesitarás más adelante:

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/jCVw0EoWJtWy8ve7Xq9S/image.png" alt=""><figcaption></figcaption></figure>

### Paso 2 — Crear el token de acceso

El script de backup necesita un token para autenticarse con GitHub desde el host.

* Ve a [**GitHub → Settings → Developer settings → Personal access tokens → Tokens (classic)**](https://github.com/settings/tokens)
* Pulsa **Generate new token (classic)**

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/PagwGvz32ZY12gPpYJuR/image.png" alt=""><figcaption></figcaption></figure>

* Dale un nombre descriptivo (ej: `klipper-backup-voron`)
* Expiration: puedes usar **No expiration** o una fecha larga — si el token expira, el backup dejará de funcionar silenciosamente
* Permisos necesarios: marca **`repo`** (acceso completo al repositorio)

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/K4Gxf8Y5wkZG9iHAF81L/image.png" alt=""><figcaption></figcaption></figure>

* Pulsa **Generate token** y **copia el token inmediatamente** — solo se muestra una vez. Guárdalo en un lugar seguro.

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/GEoDKlxypoln3XmP2tju/image.png" alt=""><figcaption></figcaption></figure>

### Paso 3 — Instalar la extensión G-Code Shell Command

El backup se lanza mediante una macro de Klipper que ejecuta un script shell. Para eso necesitas la extensión `gcode_shell_command`.

**Instalación desde KIAUH (recomendada):**

```
Menú principal → 4) Advanced → 9) Shell Command Extension
```

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/YVs0Qbg5l80CE2GPgkii/image.png)

**Instalación manual:**

```bash
# Descarga el plugin desde el repositorio de KIAUH
wget -O ~/klipper/klippy/extras/gcode_shell_command.py   https://raw.githubusercontent.com/dw-0/kiauh/master/kiauh/resources/gcode_shell_command.py

# Reinicia Klipper para que cargue la extensión
sudo systemctl restart klipper
```

### Paso 4 — Descargar y configurar el script de backup

```bash
cd ~/printer_data/config

# Descarga el script
wget -O 3dwork-autocommit.sh   https://raw.githubusercontent.com/3dwork-io/3dwork-klipper/master/scripts/3dwork-autocommit.sh
```

Edita el script para adaptarlo a tu instalación:

```bash
nano ~/printer_data/config/3dwork-autocommit.sh
```

Ajusta estas variables al principio del fichero:

```bash
### Directorio de configuración de Klipper (obligatorio)
config_folder=~/printer_data/config

### Directorio de Klipper (opcional, descomenta si quieres incluirlo)
klipper_folder=~/klipper

### Directorio de Moonraker (opcional)
moonraker_folder=~/moonraker

### Interfaz web — descomenta solo la que uses
mainsail_folder=~/mainsail
#fluidd_folder=~/fluidd

### Rama del repositorio (normalmente main o master — verifica en tu repo)
branch=main
```

Guarda con `Ctrl+X` → `Y` → `Enter` y dale permisos de ejecución:

```bash
chmod +x ~/printer_data/config/3dwork-autocommit.sh
```

{% hint style="warning" %}
Si editas el script desde Mainsail o Fluidd (editor web), los permisos de ejecución se pierden. Tendrás que volver a ejecutar `chmod +x` desde SSH.
{% endhint %}

### Paso 5 — Configurar el repositorio git local

```bash
# Instala git si no está disponible
sudo apt-get install git -y

# Ve al directorio de configuración
cd ~/printer_data/config

# Inicializa el repositorio local
git init

# Configura tu identidad (git lo requiere para los commits)
git config --global user.email "tu@email.com"
git config --global user.name "Tu Nombre"

# Añade el repositorio remoto de GitHub
# Sustituye TU_TOKEN y la URL por los tuyos
git remote add origin https://TU_TOKEN@github.com/tu-usuario/tu-repo.git

# Verifica que se añadió correctamente
git remote -v
```

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/KU6XedDYbEmmu2WUW6Vv/image.png" alt=""><figcaption></figcaption></figure>

Haz el primer commit y push:

```bash
git branch -M main          # Asegura que la rama se llama main
git add .                   # Añade todos los ficheros al commit
git commit -m "Primer backup"
git push -u origin main     # Sube al repositorio remoto

# Prueba el script para verificar que funciona
sh ~/printer_data/config/3dwork-autocommit.sh
```

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/2k9m4WMemuHxBgCsu12i/image.png" alt=""><figcaption></figcaption></figure>

### Paso 6 — Crear la macro de Klipper

Añade esto a tu `printer.cfg` o a un fichero de macros:

```ini
[gcode_shell_command backup_cfg_github]
command: sh /home/pi/printer_data/config/3dwork-autocommit.sh
timeout: 30.
verbose: True

[gcode_macro BACKUP_CFG_GITHUB]
description: Sube los ficheros de configuración a GitHub
gcode:
    RUN_SHELL_COMMAND CMD=backup_cfg_github
```

{% hint style="warning" %}
Ajusta la ruta en `command:` al path real de tu script. Si tu usuario no es `pi` (es el caso en sistemas más nuevos), el path será diferente — usa `echo $HOME` en SSH para comprobarlo.

El `timeout` de 30 segundos puede quedarse corto si el repositorio tiene muchos ficheros o la conexión es lenta. Sube a 60 si experimentas timeouts.
{% endhint %}

Ahora puedes lanzar el backup desde la sección de Macros de Mainsail o Fluidd:

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/o2TJTgnUs4rh6HjjD7Lh/image.png)

En la consola verás el progreso:

![Ejemplo de consola durante el backup](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/V9odhHLklvZ6DH50CwqT/image.png)

Y en GitHub tendrás el historial completo de cambios:

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/0ZzwNgMSECdIW0dQt5kU/image.png" alt=""><figcaption></figcaption></figure>

### Automatizar el backup al final de cada impresión

La mejor estrategia es lanzar el backup automáticamente cuando termina una impresión. Añade la llamada a tu macro `PRINT_END` (o donde finalices tus impresiones):

```ini
[gcode_macro PRINT_END]
gcode:
    # ... tu código de fin de impresión ...
    M84                          # Desactiva motores
    BACKUP_CFG_GITHUB            # Backup automático al terminar
```

Así cada vez que acaba una impresión tienes una copia actualizada en GitHub sin tener que recordarlo.

***

## Método 3 — KGB (Klipper Git Backup)

[**KGB**](https://github.com/Low-Frequency/Klipper-Git-Backup) es una alternativa al script anterior creada por la comunidad, con un asistente de configuración propio y arranque automático con el sistema.

{% hint style="warning" %}
Si ya tienes configurado el método anterior (script 3dwork-autocommit), no necesitas KGB. Elige uno de los dos.
{% endhint %}

**Instalación:**

```bash
sudo apt-get install git -y
cd ~ && git clone https://github.com/Low-Frequency/Klipper-Git-Backup.git
chmod +x ~/Klipper-Git-Backup/*.sh
./Klipper-Git-Backup/kgb.sh
```

El asistente te guiará por la configuración:

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FyExu6UGHhxo38CIOi2LX%2Fimage.png?alt=media&amp;token=5fb230d2-0678-4345-8f26-e8729754aa02" alt=""><figcaption></figcaption></figure>

Como mínimo configura la opción **1) Configure** con tu usuario de GitHub, email, URL del repositorio y directorio de configuración.

{% hint style="warning" %}
**Clave SSH requerida por KGB**

Durante la configuración, KGB genera una clave SSH pública que debes añadir a tu cuenta de GitHub:

GitHub → **Settings → SSH and GPG keys → New SSH key**

Pega la clave pública que te mostró KGB.
{% endhint %}

KGB se ejecuta automáticamente al arrancar el host y hace push a GitHub cuando hay conexión disponible.

***

## Restaurar la configuración desde GitHub

Este es el paso más importante — el que necesitarás cuando algo salga mal.

### Restauración rápida (sobreescribir con lo que hay en GitHub)

```bash
cd ~/printer_data/config
git fetch --all

# Sobreescribe todo el directorio config con el contenido de GitHub
# CUIDADO: esto borra los cambios locales no subidos
git reset --hard origin/main
```

{% hint style="danger" %}
`git reset --hard` borra **todo** lo que tengas en el directorio config que no esté en GitHub. Antes de ejecutarlo, asegúrate de que tienes el estado correcto en el repositorio remoto.
{% endhint %}

### Restauración en instalación nueva

Si la SD murió y estás empezando desde cero con MainsailOS:

```bash
# 1. Instala las dependencias básicas
sudo apt-get install git -y

# 2. Clona directamente tu repositorio en el directorio de config
# (si el directorio ya existe, hazlo en uno temporal y luego mueve los ficheros)
cd ~
git clone https://github.com/tu-usuario/tu-repo.git printer_data/config

# 3. Reinicia Klipper para que cargue la configuración
sudo systemctl restart klipper
sudo systemctl restart moonraker
```

### Recuperar una versión anterior de un fichero concreto

Una de las ventajas del control de versiones es poder recuperar un fichero concreto de un momento específico sin afectar al resto:

```bash
cd ~/printer_data/config

# Ver el historial de commits
git log --oneline

# Recuperar printer.cfg de un commit específico (sustituye HASH por el id del commit)
git checkout HASH -- printer.cfg

# O recuperar el fichero tal como estaba hace 3 commits
git checkout HEAD~3 -- printer.cfg
```

Esto es especialmente útil cuando haces un cambio en la configuración y rompes algo — puedes recuperar exactamente cómo estaba antes sin restaurar todo.

***

## Checklist de backup

Antes de hacer cualquier cambio importante en tu impresora, verifica:

* [ ] ¿Tienes una imagen SD reciente del sistema funcionando?
* [ ] ¿Está el repositorio GitHub actualizado con el estado actual?
* [ ] ¿Está el `variables.cfg` (z-offset, PA, etc.) incluido en el backup?
* [ ] ¿Sabes dónde está guardado el token de GitHub (por si expira)?
* [ ] ¿Probaste alguna vez restaurar desde el backup? (hazlo antes de necesitarlo de verdad)


# Host como segunda MCU

En ocasiones como por ejemplo añadir un sensor acelerómetro, un relé de apagado o la gestión de dispositivos por GPIO nos puede interesar usar nuestro host como segunda MCU y poder integrarla para su uso en Klipper.

## Instalación firmware Klipper en nuestro Host para que actúe como MCU

El proceso es muy sencillo:

* Usando nuestro cliente SSH/Terminal favorito nos conectaremos a nuestro Host. Os aconsejamos usar [Terminus](https://termius.com/) o [PuTTY](https://www.putty.org/) por ejemplo.

{% hint style="info" %}
Para OS Raspberry, recordamos que por defecto normalmente se usa "**pi**" como nombre de usuario y "**raspberry**" como contraseña.

Revisar en cualquier caso el user/password de vuestro sistema
{% endhint %}

* Entraremos en el directorio de Klipper lanzando el siguiente comando:

{% code overflow="wrap" %}

```bash
cd ~/klipper/
```

{% endcode %}

* Instalaremos el soporte local para MCU, al usar el comando sudo nos solicitará la contraseña:

```bash
sudo cp ./scripts/klipper-mcu.service /etc/systemd/system/
```

* Haremos que el servicio de MCU Klipper funcione en el arranque:

```bash
sudo systemctl enable klipper-mcu.service
```

* Crearemos nuestro firmware Klipper para nuestro Host, en las opciones iremos con las flechas a la opción **Micro-controller Architecture** y pulsando enter seleccionaremos de la lista **Linux process** una vez seleccionado pulsaremos **Q** e **Y** para confirmar:

```bash
cd ~/klipper/
make menuconfig
```

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/8eserompl6avUjZJjUdc/image.png" alt=""><figcaption></figcaption></figure>

* Pararemos por seguridad el servicio Klipper con el siguiento comando:

```bash
sudo service klipper stop
```

* Ejecutaremos el comando siguiente para crear y aplicar el firmware Klipper para nuestro Host:

```bash
make flash
```

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/NP1khS0qH6wObOay6nSQ/image.png" alt=""><figcaption></figcaption></figure>

* Ahora tan solo tenemos que iniciar nuestro servicio Klipper y si hemos seguido las instrucciones correctamente y no falló ningún paso ya tendremos nuestro Host como segunda MCU:

```bash
sudo service klipper start
```

{% hint style="warning" %}
Si nuestro **Klipper no conecta con nuestro Host como MCU podemos revisar el log de Klipper (klippy.log):**

* revisaremos que el servicio klipper-mcu funcione correctamente\
  `systemctl status klipper-mcu`\
  Nos debería retornar algo así:\
  `klipper@bigtreetech-cb1:~# systemctl status klipper-mcu ● klipper-mcu.service - Starts the MCU Linux firmware for klipper on startup Loaded: loaded (/etc/systemd/system/klipper-mcu.service; enabled; preset: enabled) Active: activating (auto-restart) (Result: exit-code) since Mon 2023-12-11 19:39:56 CET; 4s ago Docs: https://www.klipper3d.org/RPi_microcontroller.html Process: 2408 ExecStart=/usr/local/bin/klipper_mcu -r -I ${KLIPPER_HOST_MCU_SERIAL} (code=exited, status=255/EXCEPTION) Main PID: 2408 (code=exited, status=255/EXCEPTION) CPU: 6ms`\
  En el caso que nos indique que el servicio no este funcionando y mediante un sudo service klipper-mcu restart nos diga que el servicio no existe realizaremos los pasos previos para montarlo
* **si vemos problemas de Permission denied al intentar conectar a /tmp/klipper\_host\_mcu** podemos intentar reparando añadiendo permisos al usuario pi al grupo tty necesario para el acceso:

```bash
sudo usermod -a -G tty pi
```

{% endhint %}

## Añadir nuestro MCU Host a nuestra configuración

Ahora solo nos queda añadir a nuestro printer.cfg la configuración de nuestra nueva MCU:

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

```django
# The rpi microcontroller is used as secondary.
# Typically, both the X and Y axes
# are connected to the main micro-controller. The rpi microcontroller is used
# on non time-critical functions such as enclosure sensors, additional fan or
# light sources
[mcu host]
serial: /tmp/klipper_host_mcu
```

{% endcode %}

{% hint style="info" %}
Podemos cambiar el nombre de host en la definición de la sección \[mcu por otro más descriptivo como rpi, raspberry, cb1 o host si os es más sencillo para identificarla, en todo caso recordad que ese será el nombre que debereis usar al definir componentes conectados a nuestro host `pin: host:gpio211` a modo de ejemplo
{% endhint %}

## Habilitar SPI (Raspberry)

Este paso es opcional y normalmente se utilizará en el caso de que queramos usar un componente externo SPI conectado a nuestra RPI como por ejemplo un acelerómetro.

Para ello y desde SSH ejecutaremos:

```bash
sudo raspi-config
```

Encontraremos la **opción de habilitar SPI en Interfacing options**:

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/T6hlGYjKFm078VBIjOgQ/image.png)

## Habilitar I2C (Raspberry)

Al igual que el paso anterior, en ocasiones puede interesarnos habilitar el soporte para I2C, normalmente para acelerómetros de la familia MPU.

Para ello y desde SSH ejecutaremos:

```bash
sudo raspi-config
```

Encontraremos la **opción de habilitar I2C en Interfacing options**:

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/MbgAmnzpwYfSi4om200Y/image.png)

Además, en este caso necesitaremos añadir o des comentar unas líneas de nuestro /boot/config.txt (o /boot/firmware/config.txt dependiendo de la distro usada para instalar el OS en nuestra RPI):

{% code title="sudo nano /boot/config.txt" %}

```bash
dtparam=i2c_arm=on,i2c_arm_baudrate=400000
```

{% endcode %}

{% hint style="info" %}
Con este cambio habilitaremos el canal I2C para que use 400000 como baudrate, en caso que nuestro dispositivo use uno diferente deberiamos ajustarlo
{% endhint %}

## Utilidades GPIO (Raspberry)

Ahora que ya podemos usar nuestra Raspberry como segunda MCU de nuestro Klipper y dado que normalmente el objetivo suele ser para poder tener control desde Klipper sobre las funcionalidades de nuestra Raspberry como pueda ser el acceso a los GPIO os sugerimos algunas herramientas que facilitarán la gestión:

* Lo primero que haremos será instalar las herramientas para tenerlas disponibles:

```bash
sudo apt-get install gpiod
```

* Con gpiod instalado ya dispondremos de comandos útiles para la gestión de nuestro GPIO:

  * **gpiodetect**, que nos permitirá detectar nuestros gpio
  * **gpioinfo**, nos proporcionará información sobre gpio

  <figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/7xK5h8IjYtlSUOGYG2II/image.png" alt=""><figcaption></figcaption></figure>


# Sensores de filamento

Guía completa y actualizada de sensores de filamento para Klipper - instalación, configuración y troubleshooting

Una impresión de 12 horas que se queda sin filamento a mitad de camino es frustrante y costosa. Un sensor de filamento **pausa automáticamente la impresión** cuando detecta falta de filamento o problemas de flujo, permitiéndote cambiar material sin perder la pieza.

El sensor vigila el filamento continuamente: detecta si no hay material, pausa de forma limpia, te avisa para cambiar, y reanuda exactamente donde se quedó.

{% hint style="info" %}
**¿No sabes cuál sensor elegir?** Mira la tabla de abajo y busca tu rango de presupuesto, o ve directamente a la sección [¿Cuál elijo?](#cual-elijo).
{% endhint %}

***

## 📊 Comparativa Rápida de Sensores

| Sensor              | Tipo       | Detección             | Costo  | Precisión  | Mantenimiento | Comprar                                                                                                                                    |
| ------------------- | ---------- | --------------------- | ------ | ---------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| **Pulsador/Óptico** | Switch     | Ausencia              | 5-15€  | Baja       | Ninguno       | [AliExpress](https://s.click.aliexpress.com/e/182731559?productUrl=https://www.aliexpress.com/w/wholesale-3d-printer-filament-sensor.html) |
| **Dyze Orthus**     | Movimiento | Ausencia + Atascos    | 80€+   | Muy Alta   | Bajo          | [Dyze.ca](https://www.dyze.ca/pages/products/orthus-filament-sensor)                                                                       |
| **BTT SFS v2.0**    | Hybrid     | Ausencia + Movimiento | 25-35€ | Alta       | Bajo          | [AliExpress](https://s.click.aliexpress.com/e/182731559?productUrl=https://www.aliexpress.com/w/wholesale-BTT-smart-filament-sensor.html)  |
| **BTT SFS v1.0**    | Movimiento | Ausencia + Movimiento | 15-25€ | Media      | Rodamientos   | [AliExpress](https://s.click.aliexpress.com/e/182731559?productUrl=https://www.aliexpress.com/w/wholesale-BTT-SFS-v1.html)                 |
| **Orbiter Sensor**  | Integrado  | Ausencia + Botones    | 30€\*  | Alta       | Bajo          | [AliExpress](https://s.click.aliexpress.com/e/182731559?productUrl=https://www.aliexpress.com/w/wholesale-orbiter-filament-sensor.html)    |
| **Genérico Motion** | Movimiento | Ausencia              | 10-20€ | Baja-Media | Bajo          | [AliExpress](https://s.click.aliexpress.com/e/182731559?productUrl=https://www.aliexpress.com/w/wholesale-filament-motion-sensor.html)     |

{% hint style="info" %}
**Nota sobre Orbiter:** El precio de 30€ es SOLO el sensor. El extrusor Orbiter completo cuesta 80-100€, pero ya incluye el sensor integrado.

**Links de AliExpress:** Son búsquedas con nuestro ID de afiliado. Cambia modelo/marca dentro de AliExpress si prefieres otro proveedor.
{% endhint %}

***

## ¿Cuál elijo?

{% tabs %}
{% tab title="< 20€" %}
**Sensor óptico/pulsador genérico.**

Funciona. No detecta atascos, solo si hay o no hay filamento — pero para la mayoría de usuarios domésticos es suficiente. Si lo rompes, compras otro por 5€.

→ Lee la sección **Pulsador/Óptico** más abajo.
{% endtab %}

{% tab title="20-40€" %}
**BTT SFS v2.0, sin dudar.**

Detecta ausencia Y atascos, sin rodamientos, sin mantenimiento. La mejor relación calidad-precio del mercado ahora mismo.

→ Lee la sección **BTT SFS v2.0** más abajo.
{% endtab %}

{% tab title="> 60€" %}
**Dyze Orthus, si imprimes 24/7 o en granja.**

Encoder óptico de precisión, sin partes móviles, calibración muy fina. Para uso profesional donde no te puedes permitir un fallo.

→ Lee la sección **Dyze Orthus** más abajo.
{% endtab %}

{% tab title="Tienes Orbiter" %}
**Usa el sensor integrado, no compres nada más.**

Si ya tienes un extrusor Orbiter, el sensor viene incluido y está optimizado para esa plataforma.

→ Lee la sección **Orbiter** más abajo.
{% endtab %}
{% endtabs %}

***

## Configuración por Sensor

{% tabs %}
{% tab title="Pulsador/Óptico" %}
Sensores básicos que **detectan si hay filamento o no**. No miden movimiento ni detectan atascos — solo presencia/ausencia. Para la mayoría de usuarios de impresión doméstica es más que suficiente.

Hay dos variantes:

* **Mecánico (pulsador):** una palanca que el filamento presiona al pasar
* **Óptico:** un LED + fotoreceptor que detecta si el filamento corta el haz

Son funcionalmente idénticos. El óptico aguanta mejor en máquinas con mucha vibración.

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/0qzpF2c0FqiDlHZQ8mHQ/image.png" alt=""><figcaption><p>Sensor de pulsador típico - 3 cables (V, S, GND)</p></figcaption></figure>

### Instalación Física

{% stepper %}
{% step %}

#### Elige la ubicación

* **Bowden:** coloca el sensor antes del tubo (entre extrusor y entrada del tubo Bowden)
* **Direct Drive:** monta entre el bloque del extrusor y la entrada de filamento — necesitas unos \~40×30mm de espacio libre
  {% endstep %}

{% step %}

#### Conecta los 3 cables

| Cable         | Destino                                               |
| ------------- | ----------------------------------------------------- |
| **GND**       | GND mainboard                                         |
| **V**         | 5V (o 3.3V — consulta la especificación de tu sensor) |
| **SEÑAL**     | Pin endstop libre (PA4, etc.)                         |
| {% endstep %} |                                                       |

{% step %}

#### Verifica mecánicamente

Pasa filamento manualmente y comprueba que presiona la palanca o corta el haz. Si no hay reacción física, la configuración no servirá de nada.
{% endstep %}
{% endstepper %}

### Configuración en Klipper

```ini
[filament_switch_sensor filament_runout]
switch_pin: PA4                    # Ajusta según tu mainboard
pause_on_runout: True
runout_gcode:
    M118 Sin filamento!
    M600                           # Macro de cambio de filamento
insert_gcode:
    M118 Filamento insertado
    LOAD_FILAMENT
event_delay: 3.0
pause_delay: 0.1

[respond]
# Necesario para M118
```

**Parámetros clave:**

| Parámetro         | Qué hace                                                                        |
| ----------------- | ------------------------------------------------------------------------------- |
| `switch_pin`      | Pin donde va la señal del sensor                                                |
| `pause_on_runout` | `True` = pausa automática al detectar problema                                  |
| `event_delay`     | Espera (segundos) antes de reaccionar — sube este valor si hay falsos positivos |
| `pause_delay`     | Espera antes de ejecutar el `runout_gcode`                                      |

### Pros y Contras

**✅ Lo bueno**

* Muy barato (5-15€) — compra varios de reserva
* Sin mantenimiento
* Compatible con cualquier mainboard
* Fácil de diagnosticar: funciona o no funciona

**❌ Lo malo**

* No detecta atascos
* No detecta flujo lento
* Falsos positivos si el Bowden es muy largo
* Requiere que el filamento presione físicamente bien

### Troubleshooting

<details>

<summary>Sensor no detecta cambios</summary>

1. Invierte la lógica del pin: cambia `switch_pin: PA4` por `switch_pin: !PA4`
2. Comprueba la conexión física (¿el cable SEÑAL está en el pin correcto?)
3. Verifica que el filamento presiona completamente la palanca

</details>

<details>

<summary>Falsos positivos frecuentes</summary>

1. Sube `event_delay` a 5-10 segundos
2. Asegúrate de que el bracket no vibra durante la impresión
3. Monta el sensor en un soporte más rígido

</details>

<details>

<summary>Se activa pero no pausa la impresión</summary>

1. Verifica que `[pause_resume]` está definido en tu `printer.cfg`
2. Comprueba que la macro `M600` existe

</details>

### Test Final

{% stepper %}
{% step %}

#### Test estático

Fluidd/Mainsail → **Miscellaneous** → **Filament Sensors**. Presiona y retira filamento manualmente. ¿El estado cambia? → Sensor OK ✅
{% endstep %}

{% step %}

#### Test en impresión real

Inicia una impresión. A los 20-30 minutos, extrae el filamento manualmente. ¿La máquina pausa en menos de 3 segundos? → Configuración correcta ✅
{% endstep %}
{% endstepper %}
{% endtab %}

{% tab title="Dyze Orthus" %}
Sensor profesional de movimiento. Encoder óptico que detecta cada **0.5mm de desplazamiento**, sin partes móviles, sin mantenimiento. La opción para granjas de impresión o producción 24/7.

**Lo que lo diferencia de los demás:**

* Detecta atascos antes de que arruinen la pieza
* Sensibilidad ajustable por tipo de filamento
* "Instala y olvídate durante años"

{% hint style="warning" %}
**¿Vale la pena para uso doméstico?** Solo si imprimes muy frecuentemente y no te puedes permitir fallos. Para impresión casual, el BTT SFS v2.0 hace el mismo trabajo por mucho menos.
{% endhint %}

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/7Icq4MOAAbelnzAnoeTz/image.png" alt=""><figcaption><p>Dyze Orthus - Sensor profesional de movimiento</p></figcaption></figure>

### Tabla de Calibración

El parámetro `detection_length` depende del diámetro del filamento, la posición del selector y la sensibilidad que quieras.

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/MzYMP3Q6KIpmR2MIghQN/image.png" alt=""><figcaption><p>Tabla oficial Dyze - valores de detection_length según configuración</p></figcaption></figure>

{% hint style="info" %}
**Regla práctica:** Usa el valor de la tabla + 2-3mm para reducir falsos positivos durante los primeros días. Afinas después.
{% endhint %}

### Instalación Física

{% stepper %}
{% step %}

#### Ubica el sensor

Después del drive del extrusor, con el filamento perpendicular al sensor. Espacio necesario: 40×20×30mm. No aprietes demasiado — es un sensor óptico delicado.
{% endstep %}

{% step %}

#### Conecta los 3 cables

| Cable         | Color        | Destino           |
| ------------- | ------------ | ----------------- |
| GND           | Negro        | GND mainboard     |
| 5V            | Rojo         | 5V mainboard      |
| Señal         | Blanco/Verde | Pin endstop libre |
| {% endstep %} |              |                   |

{% step %}

#### Verifica el LED

Debe estar en **verde fijo** tras conectar. Si está rojo o apagado, hay un problema de alimentación — no sigas hasta resolverlo.
{% endstep %}
{% endstepper %}

### Configuración en Klipper

```ini
[filament_motion_sensor orthus]
detection_length: 10               # Ajusta según tabla + margen
extruder: extruder
switch_pin: PA4
pause_on_runout: True
runout_gcode:
    M118 Filamento agotado (Orthus)
    M600
insert_gcode:
    M118 Filamento cargado
    LOAD_FILAMENT
event_delay: 3.0
pause_delay: 0.01                  # Muy bajo: el sensor es preciso

[respond]
```

### Indicadores LED

| LED                  | Significado                                |
| -------------------- | ------------------------------------------ |
| 🟢 Verde fijo        | Alimentado y listo                         |
| 🟢 Verde parpadeante | Filamento en movimiento (detección activa) |
| 🔴 Rojo              | Sin alimentación o error                   |

### Calibración Paso a Paso

{% stepper %}
{% step %}

#### Confirma el LED verde

Sin LED verde no tiene sentido continuar. Si está rojo, revisa la alimentación y el cableado antes de tocar nada en Klipper.
{% endstep %}

{% step %}

#### Test manual de movimiento

Mueve filamento 10mm hacia adelante. El LED debe parpadear. Si no parpadea, el problema está en el pin de señal en la configuración.
{% endstep %}

{% step %}

#### Ajusta detection\_length

* Muchos falsos positivos → **sube** el valor (+2mm cada vez)
* No detecta nunca → **baja** el valor (-2mm) o revisa el cableado
* Objetivo: que detecte al mover entre 5 y 10mm
  {% endstep %}

{% step %}

#### Test en impresión real

Inicia impresión. A los 5 minutos, extrae el filamento manualmente. ¿Pausa en menos de 2 segundos? ✅. ¿Tarda más o no pausa? → Sube `detection_length` 2mm y repite.
{% endstep %}
{% endstepper %}

### Pros y Contras

**✅ Lo bueno**

* Ultra-preciso (cada 0.5mm)
* Sin partes móviles
* Sin mantenimiento
* Compatible con cualquier filamento

**❌ Lo malo**

* Precio elevado (80€+)
* Requiere calibración inicial
* Sobredimensionado para uso doméstico
  {% endtab %}

{% tab title="BTT SFS v2.0" %}
El sensor más recomendado para uso general. Combina dos sensores en uno: un switch que detecta si hay filamento, y un encoder que detecta si está fluyendo. Si uno falla, el otro te cubre.

Sin rodamientos, sin mantenimiento, precio razonable. **Si no sabes qué sensor comprar, compra este.**

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FGdPJsVe9Bc73hRVAVfa0%2Fimage.png?alt=media&amp;token=17caa476-fc0b-420b-af02-a451092c45f6" alt=""><figcaption><p>BTT SFS v2.0 - Compacto y versátil</p></figcaption></figure>

### Instalación Física

{% stepper %}
{% step %}

#### Ubica el sensor

Después del drive del extrusor, con el filamento fluyendo perpendicularmente. Dimensiones: 45×25×25mm. No aprietes demasiado los tornillos.
{% endstep %}

{% step %}

#### Conecta los cables (4-6 según modelo)

| Cable            | Destino                                 |
| ---------------- | --------------------------------------- |
| GND              | GND mainboard                           |
| 5V               | 5V mainboard                            |
| SWITCH\_PIN      | Pin endstop (PA4, etc.)                 |
| ENCODER\_PIN     | Otro pin endstop disponible (PA5, etc.) |
| {% endstep %}    |                                         |
| {% endstepper %} |                                         |

{% hint style="info" %}
**Truco:** Si puedes, usa un bracket de hot-swap. Facilita el reemplazo sin desmontar todo el extrusor.
{% endhint %}

### Configuración (Dual Sensor)

```ini
# SENSOR SWITCH (detección de ausencia de filamento)
[filament_switch_sensor SFS_switch]
switch_pin: gpio18               # Ajusta según tu mainboard
pause_on_runout: False           # Lo controlamos con macros
runout_gcode:
    M118 Switch: Sin filamento
insert_gcode:
    M118 Switch: Filamento insertado

# SENSOR ENCODER (detección de movimiento y atascos)
[filament_motion_sensor SFS_encoder]
switch_pin: gpio17
detection_length: 2.88           # Mínimo recomendado por BTT
extruder: extruder
pause_on_runout: False
runout_gcode:
    M118 Encoder: Atasco detectado
insert_gcode:
    M118 Encoder: Flujo normal

[respond]
```

{% hint style="warning" %}
**`pause_on_runout: False`** es intencional en ambos sensores. Las macros de abajo controlan cuándo pausar realmente. Con `True` en los dos puede haber conflictos y pausas duplicadas.
{% endhint %}

**Parámetros críticos:**

* **`detection_length: 2.88mm`** = mínimo físico del sensor. Si hay falsos positivos, sube de 1 en 1mm (hasta \~5mm como máximo).
* **`pause_on_runout: False`** = la pausa la gestiona la macro `FILAMENT_CHECK`.
* **Pull-up `^` obligatorio en AMBAS señales** (switch y encoder) según el manual oficial de BTT. Sin `^` no hay detección. Excepción: si tu placa ya lleva pull-up físico en ese pin (pasa en algunas Creality), puede funcionar sin él — ver "Pull-up e inversión según tu placa" en Troubleshooting Avanzado.
* **LEDs del v2.0:** el sensor lleva indicadores que distinguen atasco (encoder) de runout (switch). Si ningún LED reacciona al pasar filamento, el problema es alimentación o cableado, no de Klipper.

### Macros de Control

```ini
# Deshabilitar en boot (evita falsos positivos durante precalentamiento)
[delayed_gcode SFS_BOOTDISABLE]
initial_duration: 1
gcode:
    SET_FILAMENT_SENSOR SENSOR=SFS_switch ENABLE=0
    SET_FILAMENT_SENSOR SENSOR=SFS_encoder ENABLE=0

# Activar antes de imprimir (llamar desde START_PRINT)
[gcode_macro SFS_ENABLE]
description: Activar sensores antes de impresión
gcode:
    M117 Activando sensores de filamento
    G92 E0
    SET_FILAMENT_SENSOR SENSOR=SFS_switch ENABLE=1
    SET_FILAMENT_SENSOR SENSOR=SFS_encoder ENABLE=1

# Desactivar al terminar (llamar desde END_PRINT)
[gcode_macro SFS_DISABLE]
description: Desactivar sensores al terminar
gcode:
    M117 Desactivando sensores
    G92 E0
    SET_FILAMENT_SENSOR SENSOR=SFS_switch ENABLE=0
    SET_FILAMENT_SENSOR SENSOR=SFS_encoder ENABLE=0

# Pausa solo si ambos sensores confirman problema (más fiable)
[gcode_macro FILAMENT_CHECK]
gcode:
    {% set sensor_switch = printer["filament_switch_sensor SFS_switch"] %}
    {% set sensor_encoder = printer["filament_motion_sensor SFS_encoder"] %}
    
    {% if sensor_switch.filament_detected == False %}
        PAUSE
        M118 ¡Filamento agotado!
        M600
    {% elif sensor_encoder.filament_detected == False %}
        PAUSE
        M118 ¡Atasco o problema de flujo!
    {% endif %}
```

### Integración en el Laminador

Añade esto al **G-code de inicio** en Cura, PrusaSlicer o el que uses:

```gcode
; Calentamiento
M104 S{material_print_temperature}
M140 S{material_bed_temperature}

; Espera a temperatura
M109 S{material_print_temperature}
M190 S{material_bed_temperature}

; Activar sensores AQUÍ (nozzle ya caliente)
SFS_ENABLE

; Macro de inicio
START_PRINT
```

### v2.0 vs v1.0

**v2.0 — esta versión**

* Sin rodamientos
* Sin mantenimiento
* Más compacto
* 25-35€
* ✅ **Cómprala**

**v1.0 — versión anterior**

* Con rodamientos (lubricar cada 6 meses)
* Más grande
* 15-25€
* Solo si el presupuesto es muy ajustado

### Troubleshooting

<details>

<summary>Ambos sensores reportan false sin razón</summary>

1. Verifica que llegan 5V al sensor (mide con multímetro si es necesario)
2. Comprueba el cableado GPIO pin a pin
3. Ejecuta `FIRMWARE_RESTART`

</details>

<details>

<summary>Solo el switch funciona, el encoder no</summary>

1. Verifica que el filamento pasa correctamente por el canal del encoder
2. Sube `detection_length` a 5mm
3. Comprueba que no hay suciedad o pelos dentro del encoder

</details>

<details>

<summary>Falsos positivos continuos</summary>

1. Sube `event_delay` a 5 segundos
2. Revisa que el filamento está bien alineado en el sensor
3. Comprueba que el soporte está rígido y no vibra

</details>

### Test Final

{% stepper %}
{% step %}

#### Test de switches

Fluidd/Mainsail → **Miscellaneous** → **Filament Sensors**. Presiona y retira filamento. ¿Cambian `SFS_switch` y `SFS_encoder`? ✅
{% endstep %}

{% step %}

#### Test del encoder (motion)

Sigue el test unificado de la sección "Cómo testear un motion sensor" en Troubleshooting Avanzado (verificar ENABLED → QUERY → extruir 50mm lento → QUERY). Si no cambia, revisa el cableado del encoder específicamente.
{% endstep %}

{% step %}

#### Test en impresión

Inicia impresión. A los 20 minutos, extrae filamento manualmente. ¿Pausa en menos de 3 segundos? ✅. Si no pausa, verifica que `SFS_ENABLE` está en tu `START_PRINT`.
{% endstep %}
{% endstepper %}
{% endtab %}

{% tab title="BTT SFS v1.0" %}
La versión anterior del SFS. Mismo principio que el v2.0 pero con rodamientos que necesitan lubricación periódica. Si puedes, coge el v2.0 — por 10€ más te ahorras el mantenimiento.

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/Ha0USZrM2ndMp0hZjAqG/image.png" alt=""><figcaption><p>BTT SFS v1.0 - Con rodamientos (requiere lubricado)</p></figcaption></figure>

{% hint style="warning" %}
**La diferencia clave con el v2.0:** el v1.0 necesita `switch_pin: ^PA9` (nota el `^`). Sin el `^` de pull-up, el sensor no funciona. Es el error más común en esta versión.
{% endhint %}

### Instalación Física

{% stepper %}
{% step %}

#### Ubica el sensor

Después del drive del extrusor. Dimensiones: \~50×30×30mm (más grande que el v2.0). No aprietes demasiado los tornillos sobre los rodamientos.
{% endstep %}

{% step %}

#### Conecta los 3 cables

| Cable         | Destino                              |
| ------------- | ------------------------------------ |
| GND           | GND mainboard                        |
| 5V            | 5V mainboard                         |
| SEÑAL         | Pin endstop **con pull-up** (`^PA9`) |
| {% endstep %} |                                      |

{% step %}

#### Ten aceite a mano

El v1.0 necesita lubricación cada 3-6 meses. Anota la fecha de instalación para no olvidarlo.
{% endstep %}
{% endstepper %}

### Configuración

```ini
[filament_motion_sensor BTT_Smart]
detection_length: 7              # Empieza con 7mm (más alto que el v2.0)
extruder: extruder
switch_pin: ^PA9                 # ^ = pull-up (CRÍTICO en v1.0)
pause_on_runout: True
runout_gcode:
    M118 Filamento agotado
    M600
insert_gcode:
    M118 Filamento cargado
    LOAD_FILAMENT
event_delay: 3.0
pause_delay: 0.01

[respond]
```

**Diferencias clave respecto al v2.0:**

* `detection_length: 7mm` (vs 2.88mm en v2.0 — los rodamientos necesitan más margen)
* `switch_pin: ^PA9` — el `^` activa pull-up, es imprescindible
  * Sin `^`: el sensor nunca detecta nada
  * Si aun así no funciona: prueba sin `^` (algunos modelos lo tienen incorporado) o el resto de la matriz (`!`, `^!`, `~`) — ver "Pull-up e inversión según tu placa" en Troubleshooting Avanzado

### Mantenimiento de Rodamientos

{% stepper %}
{% step %}

#### Cada 3-6 meses

Extrae el cartucho del sensor, aplica 1-2 gotas de aceite ligero (aceite de máquina de coser o 3-en-1), gira manualmente 10-20 veces, y vuelve a instalar.
{% endstep %}

{% step %}

#### Señales de que toca mantenimiento antes de plazo

* El sensor "pega" o se mueve con resistencia
* Detección inconsistente (a veces detecta, a veces no)
* Ruido anormal al pasar filamento

Si ves alguna de estas señales, lubrica aunque no hayan pasado 6 meses.
{% endstep %}
{% endstepper %}

### Macros

```ini
[delayed_gcode SFS_BOOTDISABLE]
initial_duration: 1
gcode:
    SET_FILAMENT_SENSOR SENSOR=BTT_Smart ENABLE=0

[gcode_macro SFS_ENABLE]
description: Activar sensor antes de impresión
gcode:
    M117 SFS ENABLED
    G92 E0
    SET_FILAMENT_SENSOR SENSOR=BTT_Smart ENABLE=1

[gcode_macro SFS_DISABLE]
description: Desactivar sensor después de impresión
gcode:
    M117 SFS DISABLED
    G92 E0
    SET_FILAMENT_SENSOR SENSOR=BTT_Smart ENABLE=0
```

### Pros y Contras

**✅ Lo bueno**

* Más barato que el v2.0 (15-25€)
* Misma capacidad de detección de atascos
* Fácil de encontrar

**❌ Lo malo**

* Rodamientos requieren lubricación periódica
* Más grande y aparatoso
* El pull-up `^` es un punto de fallo frecuente si lo olvidas

### Test Final

{% stepper %}
{% step %}

#### Verifica el pull-up

En Fluidd/Mainsail el estado debe cambiar al mover filamento. Si siempre está "disconnected" o "false", prueba la matriz de la sección "Pull-up e inversión según tu placa" en Troubleshooting Avanzado (`pin` → `!pin` → `^pin` → `^!pin`).
{% endstep %}

{% step %}

#### Test manual

Sigue el test unificado de la sección "Cómo testear un motion sensor" en Troubleshooting Avanzado (verificar ENABLED → QUERY → extruir 50mm lento → QUERY).
{% endstep %}

{% step %}

#### Test en impresión

Inicia impresión. Extrae filamento manualmente. ¿Pausa en menos de 3 segundos? ✅. Si no: sube `detection_length` a 8-10mm y repite.
{% endstep %}

{% step %}

#### Planifica el mantenimiento

Anota la fecha de hoy en el calendario. En 6 meses, lubrica los rodamientos. Es el único mantenimiento que necesita este sensor.
{% endstep %}
{% endstepper %}
{% endtab %}

{% tab title="Orbiter" %}
Sensor integrado en los extrusores **Orbiter v1, v1.5 y v2**. Si ya tienes uno, el sensor viene incluido — solo hace falta cablearlo y configurarlo.

Tiene dos ventajas únicas respecto a otros sensores: **botones físicos** para carga/descarga de emergencia y un **LED de estado** visible en todo momento.

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/UcoGW3flreTKiKmHmw7g/image.png" alt=""><figcaption><p>Orbiter con sensor integrado - LED indicador de estado</p></figcaption></figure>

### LED Indicador

| Color      | Significado                            |
| ---------- | -------------------------------------- |
| 🟢 Verde   | Filamento cargado, listo para imprimir |
| 🟠 Naranja | Botón de descarga presionado           |
| 🔴 Rojo    | Sin filamento detectado                |

### Cableado (4 cables)

| Cable           | Color       | Destino                    |
| --------------- | ----------- | -------------------------- |
| GND             | 🔵 Azul     | GND mainboard              |
| Alimentación    | 🔴 Rojo     | 3.3V (o 5V con adaptación) |
| Señal filamento | 🟢 Verde    | Puerto servo o endstop     |
| Botón descarga  | 🟡 Amarillo | Otro pin endstop           |

**Pines de ejemplo para Octopus:**

| Función          | Puerto        | Pin |
| ---------------- | ------------- | --- |
| GND (Azul)       | Servo GND     | —   |
| 3.3V/5V (Rojo)   | Servo 5V      | —   |
| Sensor (Verde)   | Servo señal   | PA2 |
| Botón (Amarillo) | Endstop señal | PA0 |

### Instalación

{% stepper %}
{% step %}

#### Descarga la configuración oficial

```
https://orbiterprojects.com/download/filamentsensor/OrbiterSensor.cfg
```

{% endstep %}

{% step %}

#### Edita OrbiterSensor.cfg con tus pines

```ini
[gcode_button sensor_fs]
pin: PA2          # VERDE → pin de señal del filamento

[gcode_button sensor_fu]
pin: PA0          # AMARILLO → pin del botón de descarga
```

{% endstep %}

{% step %}

#### Añade a printer.cfg

```ini
[include OrbiterSensor.cfg]

[extruder]
min_extrude_temp: 180   # Necesario para que el sensor funcione correctamente
...
```

{% endstep %}
{% endstepper %}

{% hint style="warning" %}
**Orbiter v2.2:** Las señales están invertidas. Añade `!` delante de cada pin:

```ini
pin: !PA2      # Verde
pin: !PA0      # Amarillo
```

{% endhint %}

### Macros Incluidas en OrbiterSensor.cfg

El archivo ya incluye todo lo necesario:

* **`LOAD_FILAMENT`** — carga automática al insertar filamento
* **`UNLOAD_FILAMENT`** — descarga automática al pulsar el botón
* Los **botones físicos** ejecutan estas macros directamente, sin pasar por la interfaz web

### Macros Adicionales (Opcionales)

```ini
# Pausa personalizada al detectar falta de filamento
[gcode_macro PAUSE_FILAMENT_MISSING]
gcode:
    PAUSE
    M118 Filamento agotado - Presiona botón descarga para cambiar

# Reanudar después de cambio con tiempo de estabilización
[gcode_macro RESUME_AFTER_FILAMENT]
gcode:
    G4 P10000          # Espera 10 segundos antes de reanudar
    RESUME
```

### Pros y Contras

**✅ Lo bueno**

* Integrado = menos cables que gestionar
* Botones físicos = no necesitas la pantalla para emergencias
* LED visible = sabes el estado de un vistazo
* Compatible con Orbiter v1, v1.5 y v2

**❌ Lo malo**

* Solo funciona con extrusores Orbiter
* El extrusor completo cuesta 80-100€
* Configuración algo más compleja que un sensor genérico

### Test Final

{% stepper %}
{% step %}

#### Test del LED

Conecta con filamento cargado. ¿LED verde? ✅. Retira el filamento. ¿LED rojo? ✅. Si los colores no corresponden, revisa el cableado del cable verde.
{% endstep %}

{% step %}

#### Test de botones

Presiona el botón de descarga (cable amarillo). ¿Ejecuta `UNLOAD_FILAMENT`? ✅. Presiona el botón de carga. ¿Ejecuta `LOAD_FILAMENT`? ✅.
{% endstep %}

{% step %}

#### Test en impresión

Con LED verde, inicia impresión. A mitad, presiona el botón de descarga. ¿Pausa automáticamente? ✅. ¿Se descarga el filamento? ✅.
{% endstep %}

{% step %}

#### Test de recuperación completa

Inserta filamento nuevo. ¿El LED cambia a verde? ✅. Ejecuta `RESUME` desde la interfaz. ¿Continúa la impresión desde donde se quedó? ✅.
{% endstep %}
{% endstepper %}
{% endtab %}
{% endtabs %}

***

## 🔍 Troubleshooting Avanzado

### Diagnóstico Rápido

Antes de tocar nada en la configuración, comprueba el estado visual en la interfaz:

{% stepper %}
{% step %}

#### Abre Fluidd o Mainsail

Ve a **Miscellaneous** → **Filament Sensors**.
{% endstep %}

{% step %}

#### Observa el estado en tiempo real

Inserta y retira filamento manualmente. El estado debe cambiar entre `true` y `false`. Si no cambia, hay un problema físico o de configuración.
{% endstep %}

{% step %}

#### Consulta por consola si necesitas más detalle

```gcode
QUERY_FILAMENT_SENSOR

# Resultado esperado:
# SFS_switch: filament_detected=true
# SFS_encoder: filament_detected=true
```

{% endstep %}
{% endstepper %}

### Problemas Frecuentes

<details>

<summary>❌ "Filament sensor not found"</summary>

El nombre del sensor en el comando no coincide con el de `printer.cfg`.

```ini
# Si el sensor se llama "mi_sensor" en la configuración:
QUERY_FILAMENT_SENSOR SENSOR=mi_sensor    # ✅ Correcto
QUERY_FILAMENT_SENSOR SENSOR=SFS_switch   # ❌ Error (nombre incorrecto)
```

</details>

<details>

<summary>❌ Estado siempre "filament_detected = false" sin razón</summary>

En orden de probabilidad:

1. Invierte la lógica del pin: `switch_pin: !PA4`
2. Verifica la alimentación (¿llega tensión al sensor?)
3. Comprueba que el GND está bien conectado
4. Ejecuta `FIRMWARE_RESTART`

</details>

<details>

<summary>❌ El estado no cambia al insertar o retirar filamento</summary>

1. Verifica que el pin en `printer.cfg` es el correcto
2. Prueba combinaciones: `PA4` → `!PA4` → `^PA4` → `^!PA4`
3. Comprueba el montaje mecánico: ¿el sensor presiona bien el filamento?
4. Si el filamento es muy fino o grueso, puede no activar el sensor

</details>

<details>

<summary>❌ Falsos positivos cada 2-3 minutos</summary>

1. Sube `event_delay` a 10 segundos
2. El sensor probablemente vibra con la máquina — monta un bracket más rígido
3. Comprueba que el filamento no roza el sensor lateralmente
4. Añade amortiguación (goma fina) entre el sensor y el chasis

</details>

<details>

<summary>❌ Detecta al inicio pero después deja de responder</summary>

El pin necesita pull-up. Añade `^` antes del valor:

```ini
switch_pin: ^PA4    # El ^ activa el pull-up interno
```

</details>

### Pull-up e inversión según tu placa

Vale igual para v1.0, v2.0 y cualquier switch o motion sensor. El manual de BTT pide `^` en ambas señales del v2.0, y en el v1.0 es imprescindible, **pero** algunas placas ya llevan pull-up físico en sus pines y entonces el `^` sobra o incluso estorba. Por eso no hay un valor universal: hay que probar en este orden (30 segundos por prueba con `QUERY_FILAMENT_SENSOR`):

```ini
switch_pin: PA4     # 1. Tal cual (por si tu placa ya lleva pull-up: pasa en Creality 4.2.x)
switch_pin: !PA4    # 2. Lógica invertida (resolvió casos de falsos permanentes)
switch_pin: ^PA4    # 3. Pull-up software (lo habitual en BTT: Octopus, Manta, SKR)
switch_pin: ^!PA4   # 4. Pull-up + invertido
switch_pin: ~PA4    # 5. Pull-down (raro, solo si tu MCU lo soporta)
```

Quédate con el primero que detecte bien inserción/extracción. Si ninguno funciona, el problema no es el modificador: revisa que el pin exista y esté libre en el pinout de tu placa (ej. en una Manta M8P V2 usa un endstop libre PF0–PF4; PF10 no es una entrada válida), alimentación (5V y GND) y cableado pin a pin.

### Cómo testear un motion sensor

Los motion (v1.0, v2.0, Orthus, genéricos) **solo evalúan mientras extruyen y con el sensor habilitado**. Ver "not detected" en reposo o recién arrancado es NORMAL, no un fallo.

{% stepper %}
{% step %}

#### Confirma que está habilitado

```gcode
QUERY_FILAMENT_SENSOR SENSOR=tu_sensor
```

Si sale `enabled: false`, actívalo (`SET_FILAMENT_SENSOR SENSOR=tu_sensor ENABLE=1` o tu macro `SFS_ENABLE`). Si usas macros de BOOTDISABLE, el sensor nace apagado: es lo correcto, se enciende en `START_PRINT`.
{% endstep %}

{% step %}

#### QUERY → extruye → QUERY

Calienta el nozzle, ejecuta `QUERY_FILAMENT_SENSOR`, extruye 50mm lento (`M83` + `G1 E50 F300`), ejecuta QUERY otra vez. El estado debe cambiar. Si no cambia con filamento moviéndose de verdad: cableado, pin o pull-up (sección anterior).
{% endstep %}

{% step %}

#### Ajusta detection\_length a tu máquina

* v2.0: empieza en 2.88 (mínimo), sube +1mm ante falsos positivos.
* v1.0: empieza en 7 (los rodamientos necesitan más margen).
* Bowden largo: la holgura del tubo genera falsos runouts con valores bajos — sube a 10-20mm.
  {% endstep %}

{% step %}

#### Casos especiales

* **Bucle "Print already paused"** al pausar manual con motion: añade `CLEAR_PAUSE` al inicio de tu laminador o `START_PRINT`.
* **Falsos positivos de golpe en un v2.0 que iba bien:** polvo o restos en el encoder (sobre todo con PLA). Sopla el canal del sensor.
  {% endstep %}
  {% endstepper %}

***

## 📈 Mejores Prácticas

### Timing: Cuándo Activar y Desactivar

**El error más común** es tener los sensores activos durante el precalentamiento. El filamento frío, los micro-movimientos del extrusor y los cambios de temperatura generan falsos positivos que paran la impresión antes de que empiece.

La solución es simple: deshabilita en boot, habilita solo cuando el nozzle ya está caliente.

{% stepper %}
{% step %}

#### Deshabilita en boot

```ini
[delayed_gcode SFS_BOOTDISABLE]
initial_duration: 1
gcode:
    SET_FILAMENT_SENSOR SENSOR=SFS_switch ENABLE=0
    SET_FILAMENT_SENSOR SENSOR=SFS_encoder ENABLE=0
```

{% endstep %}

{% step %}

#### Activa en START\_PRINT, después del calentamiento

```ini
[gcode_macro START_PRINT]
gcode:
    # ... precalentamiento ...
    M109 S{material_print_temperature}   # Espera temperatura nozzle
    M190 S{material_bed_temperature}     # Espera temperatura cama
    
    SFS_ENABLE    # ← Aquí: nozzle ya caliente, listo para imprimir
    
    # ... resto de tu START_PRINT ...
```

{% endstep %}

{% step %}

#### Desactiva en END\_PRINT

```ini
[gcode_macro END_PRINT]
gcode:
    # ... limpieza final ...
    SFS_DISABLE
```

{% endstep %}
{% endstepper %}

### Integración con M600 (Cambio de Filamento)

M600 coordina la pausa limpia: retrae filamento, espera a que insertes el nuevo, y reanuda desde exactamente el mismo punto. Sin ella, una pausa simple deja el nozzle en medio de la pieza.

```ini
[gcode_macro M600]
description: Cambio de filamento
gcode:
    PAUSE                           # Pausa la impresión
    M117 Cambio de filamento...
    UNLOAD_FILAMENT                 # Descarga el filamento actual
    M118 Inserta nuevo filamento y ejecuta RESUME

[gcode_macro RESUME]
rename_existing: RESUME_ORIGINAL
gcode:
    {% if printer.pause_resume.is_paused %}
        LOAD_FILAMENT              # Carga el nuevo filamento
        G92 E0
        RESUME_ORIGINAL            # Reanuda la impresión
    {% endif %}
```

### Referencia de Parámetros

#### [`filament_switch_sensor`](https://www.klipper3d.org/Config_Reference.html#filament_switch_sensor) — Pulsador/Óptico

Detecta **presencia/ausencia** de filamento. Sin capacidad de detectar atascos.

| Parámetro                                                                                   | Default | Rango típico    | Para qué sirve                                                                   |
| ------------------------------------------------------------------------------------------- | ------- | --------------- | -------------------------------------------------------------------------------- |
| [`switch_pin`](https://www.klipper3d.org/Config_Reference.html#filament_switch_sensor)      | —       | Pin (ej. `PA4`) | Pin de señal. Obligatorio. Usa `!PA4` para invertir lógica, `^PA4` para pull-up  |
| [`pause_on_runout`](https://www.klipper3d.org/Config_Reference.html#filament_switch_sensor) | `True`  | True / False    | Pausa automáticamente al detectar falta de filamento                             |
| [`runout_gcode`](https://www.klipper3d.org/Config_Reference.html#filament_switch_sensor)    | —       | gcode           | Comandos ejecutados al detectar falta de filamento (ej. `M600`)                  |
| [`insert_gcode`](https://www.klipper3d.org/Config_Reference.html#filament_switch_sensor)    | —       | gcode           | Comandos ejecutados al reinsertar filamento                                      |
| [`event_delay`](https://www.klipper3d.org/Config_Reference.html#filament_switch_sensor)     | —       | 0.5 – 10s       | Espera antes de procesar el evento. Súbelo si hay falsos positivos por vibración |
| [`pause_delay`](https://www.klipper3d.org/Config_Reference.html#filament_switch_sensor)     | —       | 0.01 – 1s       | Tiempo entre detectar el problema y ejecutar la pausa                            |

***

#### [`filament_motion_sensor`](https://www.klipper3d.org/Config_Reference.html#filament_motion_sensor) — BTT SFS, Dyze Orthus, Genérico Motion

Detecta **movimiento real del filamento**. Cubre ausencia + atascos + flujo lento.

| Parámetro                                                                                    | Default | Rango típico    | Para qué sirve                                                                                                                                                                                |
| -------------------------------------------------------------------------------------------- | ------- | --------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [`switch_pin`](https://www.klipper3d.org/Config_Reference.html#filament_motion_sensor)       | —       | Pin (ej. `PA4`) | Pin de señal. Obligatorio. Usa `!` para invertir lógica, `^` para pull-up                                                                                                                     |
| [`detection_length`](https://www.klipper3d.org/Config_Reference.html#filament_motion_sensor) | `7.0mm` | 2.88 – 15mm     | Distancia mínima de filamento que debe moverse para registrar cambio. **El parámetro más importante de este tipo de sensor** — demasiado bajo = falsos positivos, demasiado alto = no detecta |
| [`extruder`](https://www.klipper3d.org/Config_Reference.html#filament_motion_sensor)         | —       | nombre          | Nombre del extrusor asociado (normalmente `extruder`). Obligatorio                                                                                                                            |
| [`pause_on_runout`](https://www.klipper3d.org/Config_Reference.html#filament_motion_sensor)  | `True`  | True / False    | Pausa automáticamente al detectar problema de flujo                                                                                                                                           |
| [`runout_gcode`](https://www.klipper3d.org/Config_Reference.html#filament_motion_sensor)     | —       | gcode           | Comandos ejecutados al detectar atasco o falta de filamento                                                                                                                                   |
| [`insert_gcode`](https://www.klipper3d.org/Config_Reference.html#filament_motion_sensor)     | —       | gcode           | Comandos ejecutados cuando el flujo se reanuda                                                                                                                                                |
| [`event_delay`](https://www.klipper3d.org/Config_Reference.html#filament_motion_sensor)      | —       | 0.5 – 10s       | Espera antes de procesar el evento. Crítico en sensores de movimiento — demasiado bajo dispara falsas alarmas                                                                                 |
| [`pause_delay`](https://www.klipper3d.org/Config_Reference.html#filament_motion_sensor)      | —       | 0.01 – 1s       | Tiempo entre detectar el problema y ejecutar la pausa                                                                                                                                         |

{% hint style="info" %}
**Diferencia clave entre los dos tipos:** `filament_switch_sensor` no tiene `detection_length` ni `extruder` porque no mide movimiento — solo sabe si el filamento está o no está. `filament_motion_sensor` necesita saber de qué extrusor viene el movimiento para calcular correctamente la distancia.
{% endhint %}

**Latencia total estimada:** 1 – 3 segundos desde el problema hasta la máquina pausada (suma de `event_delay` + `pause_delay` + tiempo de reacción del firmware).

***

## 🎯 Consejos y Advertencias

{% tabs %}
{% tab title="¿Qué sensor compro?" %}

* **< 20€:** Sensor pulsador/óptico genérico — funciona, sin florituras
* **20-40€:** BTT SFS v2.0 — la mejor opción para la mayoría
* **> 60€:** Dyze Orthus — solo para granjas o producción intensiva
* **Tienes Orbiter:** Usa el integrado, no compres nada más
  {% endtab %}

{% tab title="Error del precalentamiento" %}
**Síntomas:**

* La impresora pausa justo antes de empezar a imprimir
* Ves `filament_detected: false` sin razón durante el calentamiento

**Causa:** el sensor estaba activo mientras el nozzle calentaba.

**Solución:**

1. Añade `[delayed_gcode SFS_BOOTDISABLE]` para desactivar en boot
2. Llama a `SFS_ENABLE` solo **después** de `M109`
3. Llama a `SFS_DISABLE` en `END_PRINT`
   {% endtab %}

{% tab title="Vibración y montaje" %}
**Síntomas:** falsos positivos cada 2-3 minutos, especialmente en impresoras rápidas o con camas volantes (bedslinger).

**Soluciones en orden:**

1. `event_delay: 10` — espera más antes de reaccionar
2. Bracket muy rígido — evita el plástico flexible para montar el sensor
3. Amortigua el punto de montaje con goma o espuma fina
4. Alinea bien el filamento — no debe rozar lateralmente el sensor
   {% endtab %}

{% tab title="Óptico vs Mecánico" %}
**Mecánico (pulsador)**

* Más barato
* Aguanta mejor las vibraciones
* La palanca se puede desgastar con el tiempo

**Óptico**

* Sin desgaste mecánico
* Mejor para filamentos abrasivos (fibra de carbono, etc.)
* Puede acumular polvo — limpia el receptor cada meses
  {% endtab %}

{% tab title="Mantenimiento" %}

| Sensor          | Qué necesita            | Cada cuánto    |
| --------------- | ----------------------- | -------------- |
| BTT SFS v2.0    | Nada                    | —              |
| BTT SFS v1.0    | Lubrica rodamientos     | Cada 3-6 meses |
| Pulsador/óptico | Revisa presión mecánica | Cada 3-6 meses |
| Dyze Orthus     | Revisa cableado         | Cada año       |

**Señales de que algo va mal:** detección inconsistente de repente, más falsos positivos que antes, ruido anormal al pasar filamento.
{% endtab %}

{% tab title="El test definitivo" %}
**Antes de dormir mientras imprime:**

{% stepper %}
{% step %}

#### Imprime una pieza de prueba (\~1 hora)

{% endstep %}

{% step %}

#### A mitad de impresión, extrae el filamento manualmente

{% endstep %}

{% step %}

#### Evalúa el resultado

* ¿La máquina pausó en menos de 3 segundos? ✅ Confiable
* ¿Siguió imprimiendo sin pausar? ❌ Revisa configuración
  {% endstep %}

{% step %}

#### Repite 3 veces

Si falla una vez de tres, no lo des por bueno. Revisa timing y parámetros antes de fiarte para impresiones largas sin supervisión.
{% endstep %}
{% endstepper %}
{% endtab %}
{% endtabs %}

***

## 🆘 Referencias

* **Documentación Klipper oficial:** <https://www.klipper3d.org/G-Codes#query\\_filament\\_sensor>
* **BTT SFS v2.0 GitHub:** <https://github.com/bigtreetech/smart-filament-sensor>
* **Dyze Orthus:** <https://www.dyze.ca/pages/products/orthus-filament-sensor>
* **Orbiter sensor:** <https://orbiterprojects.com/orbiter-filament-sensor/>

***

**Última actualización:** 2026-09-16 **Autor:** HAL (Technical Writer - 3Dwork.io)

{% hint style="success" %}
Con un sensor bien configurado y el test definitivo superado 3 veces, tus impresiones largas están aseguradas. Nunca más perderás una pieza por falta de filamento.
{% endhint %}


# Cámaras - Instalación y configuración

Klipper nos permite de forma nativa el poder usar una cámara externa para monitorizar nuestra impresora 3D.

## Para que nos puede ser útil una cámara en nuestra impresora?

* **Detectar problemas durante la impresión**, el poder ver visualmente como va nuestra impresora remotamente nos va a permitir en el caso de cualquier problema poder detener la impresión si contamos con acceso remoto como [Telegram](/klipper/mejoras/moonraker-mejoras/moonraker-telegram) o [VPN](/klipper/mejoras/vpn-con-zerotier).
* **Grabar nuestra impresión o hacer timelapses**, siempre queda genial poder enseñar nuestras obras de arte y como se crean :D
* **Simplemente para monitorizarla**

## ¿Qué cámara es la más adecuada?

La elección de una cámara para nuestra impresora va a depender mucho del objetivo de su uso, tendremos que tener en cuenta algunos aspectos como:

* **Resolución de la cámara**, ya que de ello dependerá la calidad final del video obtenido
* **Calidad de la óptica**, las impresiones suelen durar muchas horas y normalmente puede que no tengamos iluminación durante algunas de ellas, de ahí que la cámara y su óptica tengan una buena sensibilidad ante baja luz es muy interesante.
* **Tamaño/peso**, el tamaño de la misma puede limitar algunos aspectos para su ubicación dependiendo del uso que queramos dar

### Cámaras USB

Normalmente suelen ser las más aconsejables por precio, calidad, variedad y sobre todo porque normalmente son plug\&play y la configuración/instalación es mínima.

Algunos ejemplos aconsejables pueden ser las Logitech... en concreto la C270 y Pro C920..., Microsoft HD-3000 o Wyze V2.

{% tabs %}
{% tab title="Logitech C270 (recomendada)" %}
{% embed url="<https://s.click.aliexpress.com/e/182731559?productUrl=https://www.aliexpress.com/item/1005005033359539.html>" %}
{% endtab %}

{% tab title="Logitech C920 Pro" %}
{% embed url="<https://s.click.aliexpress.com/e/182731559?productUrl=https://www.aliexpress.com/item/32804087083.html>" %}
{% endtab %}
{% endtabs %}

{% hint style="info" %}
} Si utilizas los links de compra, el precio del producto será el mismo que si accedes de manera habitual, pero a 3DWork le quedará una pequeña comisión. Algo que nos ayudará a soportar el proyecto y continuar generando contenido.
{% endhint %}

### Cámaras Raspberry Pi

Estas cámaras están pensadas para usar sobre un host Raspberry Pi por lo que si cambiamos en un futuro de plataforma host no nos serán útiles probablemente.

Existen diferentes modelos, desde la básica V2 (sobre 35€) a 1080 30fpx... hasta la HQ con una sensor de 12Mp y lentes intercambiables.

Por otro lado, estas cámaras tienen un tamaño bastante pequeño y bajo peso aunque normalmente tendremos que tirar de mods para poder ajustarla a nuestra impresora.

{% tabs %}
{% tab title="Raspberry Pi Camera Module V2" %}
{% embed url="<https://s.click.aliexpress.com/e/182731559?productUrl=https://www.aliexpress.com/item/32814661484.html>" %}
{% endtab %}
{% endtabs %}

{% hint style="info" %}
} Si utilizas los links de compra, el precio del producto será el mismo que si accedes de manera habitual, pero a 3DWork le quedará una pequeña comisión. Algo que nos ayudará a soportar el proyecto y continuar generando contenido.
{% endhint %}

### Cámaras DSLR

Si buscamos máxima calidad son las opciones más usadas, sobretodo para videos o timelapses.

En este caso tanto la instalación, configuración y empleo se complica más y solamente son aconsejables para usuarios “avanzados”.

## ¿Como instalar nuestra cámara en Klipper?

Os vamos a enseñar como configurar nuestra cámara web, en este caso USB, utilizando como base MainsailOS.

MainsailOS lleva por defecto instalado Crowsnest que es un demonio para el uso de cámaras, en el caso de que no utilicemos MainsailOS o no lo tengamos instalado a continuación tenéis como hacer la instalación:

{% hint style="success" %}
INSTALACIÓN crowsnest:

Crowsnest es un demonio para gestionar webcam que viene por defecto instalado en distribuciones como MainsailOS.

La instalación es muy sencilla desde línea de comandos desde SSH, aunque también se puede instalar desde Kiauh.

```django
cd ~
git clone https://github.com/mainsail-crew/crowsnest.git
cd ~/crowsnest
sudo make install
```

Una vez instalado lo ideal es ajustar nuestro fichero moonraker.conf para añadir a su gestor de actualizaciones crowsnest:

```django
[update_manager crowsnest]
type: git_repo
path: ~/crowsnest
origin: https://github.com/mainsail-crew/crowsnest.git
install_script: tools/pkglist.sh
```

Por otro lado si queremos hacerlo desde [**Kiauh**](https://github.com/th33xitus/kiauh):

Verificamos si ya lo tenemos instalado desde el menú principal de Kiauh:

<img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/eOP7qAySyXRvhz5HC23V/image.png" alt="" data-size="original">

En el caso de no tenerlo pulsaremos 1 (Install) que nos llevará al menu de instalación donde pulsando 11 (Crowsnest) realizará la instalación de este complemento:

<img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/OE97Al4762qpI8YqwpgY/image.png" alt="" data-size="original">

Durante el proceso de instalación debería preguntar si queremos actualizar nuestro moonraker.conf para añadir a su update manager Crowsnest, es aconsejable contestar Yes.

Una vez finalizada la instalación saldremos de Kiauh y reiniciamos nuestro host, podremos volver a entrar a Kiauh para verificar que esté instalado o desde nuestra UI web deberiamos ver las opciones de este.

También en algunos casos es necesario o interesante instalar multi-instancias de crowsnest, desde la documentación podemos encontrar el proceso [aquí](/klipper/instalacion/multiples-instancias-klipper#crowsnest).

En el caso de requerir desinstalar Crowsnest podemos realizarlo con dos simples comandos, recuerda borrar el directorio crowsnest al finalizar:

`cd ~/crowsnest`

`make uninstall`
{% endhint %}

* Conectaremos la cámara a nuestro host, una Pi en nuestro caso
* Abriremos la configuración de nuestra UI y añadiremos la cámara asignándole un nombre

{% tabs %}
{% tab title="Mainsail" %}

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/tSKMzEuOW5cdCKhSxPOj/image.png" alt=""><figcaption></figcaption></figure>
{% endtab %}

{% tab title="Fluidd" %}

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/AYWeHZPnbKZloY9RxuAi/image.png" alt=""><figcaption></figcaption></figure>
{% endtab %}
{% endtabs %}

* Ya deberíamos tener imágenes de nuestra cámara en el dashboard,
* En caso de que no o fallo el proceso de añadirla o detección, o no tenemos la sección webcam en nuestro dashboard.\
  Iremos a la sección MACHINE y abriremos el fichero crowsnest.conf, [**crowsnest**](https://crowsnest.mainsail.xyz/setup/installation) que es el servicio que gestiona las cámaras en MainsailOS, donde podemos ajustar la resolución, los fps, u otros parámetros necesarios para nuestra impresora/cámara... más información de las opciones disponibles [**aquí**](https://crowsnest.mainsail.xyz/configuration/cam-section).

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/VRVkbQdKl8epYEyeq77V/image.png" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
Es importante **en el caso que no nos detecte por defecto la cámara intentar obtener más información del sistema.**

**Podemos obtener información del propio log de Crowsnest accesible desde el interfaz web normalmente.**

O **dentro del directorio de Crowsnest contamos en tools/dev-helper.sh** una herramienta que nos puede ayudar a encontrar posibles problemas en nuestra instalación o obtener información de las cámaras:

`cd ~/crowsnest`\
`tools/dev-helper.sh -c`

<img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FRcdin8n8h804tjONOfnc%2Fimage.png?alt=media&amp;token=e42496cf-cc50-49a9-bbc2-2e2784c51716" alt="" data-size="original">

crowsnest - dev-helper.sh - flags

```
 dev-helper.sh [Options]

	-h	Prints this help.
	-V	Shows Version of dev-helper.sh
	-a	Shows all available informations gathered
	-c	Shows informations about cameras
	-o	Shows informations about used OS
	-s	Shows informations about host system
	-x	Performs tests to ensure successful install of crowsnest
	-d	Decolorize file (if output is redirected to file)
```

{% endhint %}

{% hint style="warning" %}
Algunas cosas a tener en cuenta:

* dependiendo de la cámara o la configuración de captura o del host que utilicemos va a requerir de un extra de recursos. En el caso de SBC como Raspberry Pi o similares, revisa en tu caso como se ajustaría, es aconsejable ajustar la `gpu_mem` del fichero `/boot/config.txt` en al menos 128MB-256MB dependiendo de lo que disponga nuestro host.
* dependiendo del camera-streamer que elijamos/usemos puede que nuestro navegador web tenga problemas para reproducir WebRTC H264, como por ejemplo en Firefox es necesario habilitar `media.webrtc.hw.h264.enabled` en `about:config` (revisad <https://unix.stackexchange.com/a/761511> y <https://bugzilla.mozilla.org/show_bug.cgi?id=1717679> para más información)
  {% endhint %}

## ¿Añadir varias cámaras a nuestro Klipper?

Disponer de varias cámaras puede ayudar a tener más ángulos, aunque por otro lado va a aumentar la carga de nuestro host Klipper.

Suele ser interesante disponer de varias cámaras cuando por ejemplo usamos una de baja calidad para la monitorización, cargando menos el sistema, y otra de más calidad para videos o timelapses.

### Habilitar varias cámaras en MainsailOS

* de nuevo abriremos el fichero de configuración crowsnest.conf
* clonaremos el contenido de la sección \[cam1] cambiando el nombre del clonado a \[cam2]
* ajustaremos el puerto a 8081 y iremos sumando si necesitamos mas camaras
* al instalar la cámara en el interfaz como hicimos antes nos aseguraremos que en la URL cambiemos el puerto a 8081
* para verificar que las cámaras funcionan usaremos la URL para acceder directamente... <http://tu-ip/webcam1/...http://tu-ip/webcam2/>...


# Timelapses

Cómo crear timelapses de tus impresiones con Klipper, compatible con Mainsail y Fluidd

La extensión **moonraker-timelapse** permite crear vídeos timelapse de tus impresiones directamente desde Klipper. Funciona con cualquier interfaz — tanto **Mainsail** como **Fluidd** — y es compatible con todos los slicers habituales.

## ¿Qué necesitas?

Una cámara conectada a tu host Klipper con una URL de snapshot accesible. Tienes sugerencias y guías de configuración en la sección de [Cámaras](https://github.com/alienboyxp/gitbook_es_klipper_3dwork_io/blob/main/klipper/camaras-instalacion-y-configuracion.md).

## Instalación

{% hint style="success" %}
**MainsailOS y fluiddPi ya incluyen el plugin preinstalado.** Si usas alguna de estas imágenes, puedes saltarte este paso e ir directamente a [Activación](#activación).
{% endhint %}

Si instalaste Klipper manualmente (KIAUH u otro método), instala el plugin via SSH:

```bash
cd ~/
git clone https://github.com/mainsail-crew/moonraker-timelapse.git
cd ~/moonraker-timelapse
make install
```

{% hint style="info" %}
Si configuraste tu OS manualmente y no tienes ffmpeg, instálalo con:

```bash
sudo apt install ffmpeg
```

El script asume que Klipper y Moonraker están en `~/klipper` y `~/moonraker`.
{% endhint %}

## Activación

Tanto si el plugin ya venía incluido como si lo acabas de instalar, hay que activarlo en los archivos de configuración.

Añade la extensión al gestor de actualizaciones de Moonraker en `moonraker.conf`:

{% code title="moonraker.conf" %}

```django
[update_manager timelapse]
type: git_repo
primary_branch: main
path: ~/moonraker-timelapse
origin: https://github.com/mainsail-crew/moonraker-timelapse.git
managed_services: klipper moonraker
```

{% endcode %}

Activa la extensión añadiendo la sección `[timelapse]` en `moonraker.conf`:

{% code title="moonraker.conf" %}

```django
[timelapse]
##   La configuración básica es suficiente para la mayoría de casos.
##   Solo descomenta lo que necesites cambiar.
#output_path: ~/timelapse/
#frame_path: /tmp/timelapse/
#ffmpeg_binary_path: /usr/bin/ffmpeg
```

{% endcode %}

Y añade el include en `printer.cfg`:

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

```
[include timelapse.cfg]
```

{% endcode %}

## Configuración desde la interfaz

Una vez instalado, tanto Mainsail como Fluidd incluyen un panel dedicado para gestionar el timelapse sin necesidad de editar archivos de configuración.

{% tabs %}
{% tab title="Mainsail" %}
Accede a través del icono de engranaje (⚙) → **Timelapse**.

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2Fgit-blob-be99240129c43d0194b84dc3ed00377758b4f548%2Fmainsail-timelapse-settings.png?alt=media" alt="Panel de configuración de timelapse en Mainsail"><figcaption><p>Interface Settings → Timelapse en Mainsail</p></figcaption></figure>

| Opción                        | Descripción                                                                     |
| ----------------------------- | ------------------------------------------------------------------------------- |
| **Enabled**                   | Activa/desactiva las macros y el autorenderizado                                |
| **Autorender**                | Renderiza el vídeo automáticamente al terminar la impresión                     |
| **Camera**                    | Selecciona qué cámara usar para las capturas                                    |
| **Mode**                      | `layermacro` (captura en cada capa) o `hyperlapse` (por intervalo de tiempo)    |
| **Stream Delay Compensation** | Retraso antes de capturar para compensar el lag del stream (por defecto 0,05 s) |
| **Park Toolhead**             | Aparca el cabezal antes de cada captura (ver sección siguiente)                 |
| **Variable FPS**              | Ajusta los FPS para alcanzar una duración objetivo del vídeo                    |
| **Preview Image**             | Guarda una miniatura con el mismo nombre que el vídeo                           |
| **Save Frames**               | Guarda los fotogramas en un ZIP para renderizado externo                        |

{% hint style="warning" %}
Si defines `snapshoturl` en `[timelapse]` dentro de `moonraker.conf`, el selector de cámara de la UI queda deshabilitado. Para usar la selección desde la interfaz, **no incluyas `snapshoturl` en el archivo de configuración**.
{% endhint %}
{% endtab %}

{% tab title="Fluidd" %}
Una vez instalado el componente, aparece una entrada **Timelapse** en el menú de navegación principal de Fluidd.

La configuración está disponible en **Settings → Timelapse** y ofrece las mismas opciones que Mainsail: modo de captura, aparcado del cabezal, opciones de renderizado y selección de cámara.

{% hint style="info" %}
Si alguna opción aparece como solo lectura, es porque está definida en `moonraker.conf`. Elimínala del archivo para gestionarla desde la UI.
{% endhint %}
{% endtab %}
{% endtabs %}

### Opciones avanzadas

Para configuración avanzada más allá de la UI, referencia completa en la [documentación oficial](https://github.com/mainsail-crew/moonraker-timelapse/blob/main/docs/configuration.md).

{% hint style="info" %}
Opciones más usadas en `moonraker.conf`:

```ini
[timelapse]
#enabled: True
#mode: layermacro          # layermacro | hyperlapse
#hyperlapse_cycle: 30      # segundos entre capturas en modo hyperlapse
#parkhead: False
#parkpos: back_left        # back_left | back_right | front_left | front_right | center | custom
#park_custom_pos_x: 0.0
#park_custom_pos_y: 0.0
#park_custom_pos_dz: 0.0
#park_travel_speed: 100
#park_retract_distance: 1.0
#park_extrude_distance: 1.0
#autorender: True
#constant_rate_factor: 23  # calidad del vídeo (menor = mejor calidad)
#output_framerate: 30
#variable_fps: False
#targetlength: 10          # duración objetivo del vídeo en segundos
#variable_fps_min: 5
#variable_fps_max: 60
#flip_x: False
#flip_y: False
#duplicatelastframe: 0
#previewimage: True
#saveframes: False
```

{% endhint %}

## Aparcado del cabezal

La opción **Park Toolhead** (`parkhead`) mueve el cabezal fuera del área de impresión antes de cada captura. Esto evita que el nozzle tape la pieza en la foto y elimina las marcas de movimiento entre capas que pueden arruinar el resultado final.

### Posiciones disponibles

| Posición (`parkpos`) | Descripción                                                |
| -------------------- | ---------------------------------------------------------- |
| `back_left`          | Esquina trasera izquierda (por defecto)                    |
| `back_right`         | Esquina trasera derecha                                    |
| `front_left`         | Esquina delantera izquierda                                |
| `front_right`        | Esquina delantera derecha                                  |
| `center`             | Centro de la cama                                          |
| `custom`             | Coordenadas personalizadas (ver parámetros a continuación) |

Para la posición personalizada, configura en `moonraker.conf`:

```ini
[timelapse]
parkhead: True
parkpos: custom
park_custom_pos_x: 10.0    # posición X en mm
park_custom_pos_y: 10.0    # posición Y en mm
park_custom_pos_dz: 2.0    # elevación adicional del eje Z en mm
park_travel_speed: 100     # velocidad de desplazamiento en mm/s
```

### Retracción durante el aparcado

Al aparcar el cabezal se puede retraer filamento para evitar babeo (oozing) durante la captura, y extruirlo de vuelta antes de continuar imprimiendo:

```ini
[timelapse]
park_retract_distance: 1.0   # mm de retracción al aparcar
park_extrude_distance: 1.0   # mm de extrusión al volver (igual o mayor que retract)
```

{% hint style="info" %}
Si ya tienes firmware retraction activo en Klipper, ajusta estos valores a `0.0` para evitar doble retracción.
{% endhint %}

## Gestión de timelapses

Una vez completada la impresión, el vídeo timelapse queda guardado en el host. Puedes gestionarlos directamente desde la interfaz sin necesidad de SSH.

{% tabs %}
{% tab title="Mainsail" %}
En el menú lateral encontrarás una sección **Timelapse** dedicada con todos los vídeos generados. Desde ahí puedes descargar, previsualizar y eliminar los timelapses.

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2Fgit-blob-36ed2842f502ae8823a1832d805c004d0ed77502%2Fmainsail-timelapse-files.png?alt=media" alt="Gestor de archivos timelapse en Mainsail"><figcaption><p>Sección Timelapse en Mainsail — lista de vídeos y espacio disponible en disco</p></figcaption></figure>
{% endtab %}

{% tab title="Fluidd" %}
Fluidd incluye una sección dedicada **Timelapse** en el menú de navegación principal. Desde ella puedes:

* Previsualizar los vídeos generados directamente en el navegador
* Navegar por los fotogramas capturados durante la impresión con el scrubber de frames
* Descargar o eliminar los vídeos sin necesidad de SSH
* Activar el renderizado manual si el autorenderizado no está habilitado
  {% endtab %}
  {% endtabs %}

{% hint style="warning" %}
**Espacio en disco**: Los timelapses se almacenan en `~/timelapse/` y los fotogramas temporales en `/tmp/timelapse/` del host Klipper (normalmente una Raspberry Pi con tarjeta SD de 16-32 GB).

Una impresión larga puede generar cientos de fotogramas y vídeos de varios cientos de MB. Si el disco se llena, **Klipper puede dejar de funcionar correctamente**.

Revisa y limpia periódicamente la carpeta de timelapses desde la interfaz o via SSH:

```bash
ls -lh ~/timelapse/
rm ~/timelapse/nombre_del_timelapse.mp4
```

{% endhint %}

## Configuración del laminador

Hay que añadir la macro `TIMELAPSE_TAKE_FRAME` en el G-code de cambio de capa del laminador. La ubicación exacta varía según el programa:

{% tabs %}
{% tab title="OrcaSlicer" %}
**Printer Settings → Machine G-code → Before layer change G-code**

```
TIMELAPSE_TAKE_FRAME
```

{% endtab %}

{% tab title="PrusaSlicer / SuperSlicer" %}
**Printer Settings → Custom G-code → Before layer change G-code**

```
TIMELAPSE_TAKE_FRAME
```

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/OCvXdFkP2OHdFIv6P4IX/image.png" alt="PrusaSlicer timelapse gcode"><figcaption><p>PrusaSlicer — Before layer change G-code</p></figcaption></figure>
{% endtab %}

{% tab title="Cura" %}
**Extensions → Post Processing → Modify G-Code → Add a script → Insert at layer change → Before**

```
TIMELAPSE_TAKE_FRAME
```

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/ij2CYZU1fjyRnV2NcJEw/image.png" alt="Cura timelapse gcode"><figcaption><p>Cura — Insert at layer change (Before)</p></figcaption></figure>
{% endtab %}

{% tab title="IdeaMaker" %}
**Advanced Settings → GCode → Layer Change Gcode**

```
TIMELAPSE_TAKE_FRAME
```

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/ragL2RHHSPPxgjiG1DDR/image.png" alt="IdeaMaker timelapse gcode"><figcaption><p>IdeaMaker — Layer Change Gcode</p></figcaption></figure>
{% endtab %}
{% endtabs %}

Con esto, cada vez que el laminador genere un G-code, ejecutará la macro en cada cambio de capa. Al finalizar la impresión, Mainsail o Fluidd renderizarán automáticamente el vídeo timelapse.


# Neopixel

Configuración completa de LEDs inteligentes en Klipper: desde la conexión a la MCU principal hasta opciones avanzadas con WLED, LUMEN o una segunda MCU dedicada.

Klipper tiene soporte nativo para tiras LED inteligentes WS2812/SK6812 (Neopixel) y APA102/SK9822 (Dotstar), más integración con WLED y LUMEN a través de Moonraker. Con esto puedes iluminar el cerramiento, mostrar el progreso de impresión en tiempo real con colores, animar el toolhead o simplemente saber de un vistazo en qué estado está la máquina.

{% hint style="info" %}
Esta guía cubre las tres opciones de conexión de menos a más avanzada. Si ya tienes los LEDs funcionando y solo buscas efectos, salta a [LED Effects](#led-effects-efectos-avanzados) o a la sección de [hardware externo](#opcion-2-hardware-externo-o-segunda-mcu).
{% endhint %}

## Dónde conseguir tiras LED Neopixel

{% tabs %}
{% tab title="WS2812B 5V (más común)" %}
{% embed url="<https://s.click.aliexpress.com/e/182731559?productUrl=https://www.aliexpress.com/item/2036819167.html>" %}
{% endtab %}

{% tab title="SK6812 RGBW 5V" %}
{% embed url="<https://s.click.aliexpress.com/e/182731559?productUrl=https://www.aliexpress.com/item/32742461421.html>" %}
{% endtab %}
{% endtabs %}

{% hint style="info" %}
Si utilizas los links de compra, el precio del producto será el mismo que si accedes de manera habitual, pero a 3DWork le quedará una pequeña comisión. Algo que nos ayudará a soportar el proyecto y continuar generando contenido.
{% endhint %}

## Antes de conectar — instalación física

{% hint style="danger" %}
**Puntos críticos antes de conectar cualquier tira LED:**

* Añade una **resistencia de 300-500 Ω** entre el pin de señal de la MCU y el pin de datos de la tira. Protege la MCU de picos en el bus de datos. Sin ella puedes quemar el pin.
* Las tiras tienen **dirección** — la alimentación y la señal van en el sentido de la flecha marcada en la PCB.

  <figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FRs2D01zioUkiBJpcw3rm%2Fimage.png?alt=media&amp;token=244a3efc-a9bb-4317-9ad4-e63fd857c528" alt="Dirección de la tira LED"><figcaption></figcaption></figure>
* **Alimenta externamente** con una fuente 5V dedicada si tienes más de 15-20 LEDs. La mayoría de electrónicas (SKR, Octopus, Manta) solo aguantan eso antes de necesitar corriente extra. Superar el límite provoca reinicios aleatorios de la MCU.
* **GND común obligatorio** — conecta el GND de la tira y el GND de la MCU al mismo punto. Sin esto la señal de datos no llega bien y los LEDs hacen cosas raras.
* Para calcular el consumo exacto: [WLED Power Calculator](https://wled-calculator.github.io/)
  {% endhint %}

### Tipos de LED y su `color_order`

Este parámetro es el origen de la mayoría de problemas con colores incorrectos. Cada tipo de LED envía los bytes de color en un orden distinto:

| LED                | Protocolo                | `color_order` | Notas                                |
| ------------------ | ------------------------ | ------------- | ------------------------------------ |
| WS2812B            | 1 cable (datos)          | `GRB`         | El más común en impresoras 3D        |
| WS2812B con blanco | 1 cable (datos)          | `GRBW`        | 4 canales                            |
| SK6812 RGBW        | 1 cable (datos)          | `GRBW`        | Muy usado en tiras de cerramiento    |
| SK6812 RGB         | 1 cable (datos)          | `GRB`         | Sin canal blanco                     |
| APA102 / SK9822    | 2 cables (datos + reloj) | `BGR`         | Más robusto, mejor para tiras largas |
| Dotstar (Adafruit) | 2 cables (datos + reloj) | `BGR`         | Mismo chip que APA102                |
| WS2811             | 1 cable (datos)          | `RGB`         | Cuidado: orden diferente al WS2812   |

Si pides rojo y salen verdes, o azul y salen otra cosa, el problema es el `color_order`. Prueba los valores hasta que los colores sean correctos.

{% hint style="info" %}
También puedes especificar un `color_order` diferente para cada LED de la cadena si mezclas tipos distintos: `color_order: GRB, GRB, GRBW`
{% endhint %}

***

## Opción 1 — Conexión a la MCU principal

La forma más directa: conectar la tira al pin RGB de tu electrónica (Octopus, SKR, Manta…) y dejar que Klipper la gestione. Sin hardware extra, configuración en `printer.cfg` y control total desde macros y LED Effects.

{% hint style="warning" %}
Klipper **no soporta Neopixel conectados directamente a los GPIO de la Raspberry Pi** cuando se usa como Linux MCU. El kernel de Linux no tiene la precisión de temporización necesaria para el protocolo WS2812. Si quieres usar los GPIO de la Pi, ve a la sección [LUMEN](#lumen-plugin-moonraker-para-raspberry-pi) o [Segunda MCU RP2040](#segunda-mcu-rp2040-pi-pico).
{% endhint %}

### Configuración en printer.cfg

Lo más limpio es crear un archivo separado `led_effects.cfg` y referenciarlo desde `printer.cfg`:

```ini
# En printer.cfg
[include led_effects.cfg]
```

Así mantienes el cfg principal ordenado y puedes tocar la configuración de LEDs sin tocar el resto.

{% tabs %}
{% tab title="WS2812 / Neopixel" %}
El más común en impresoras 3D. Un único cable de datos, protocolo de 1 hilo.

```ini
[neopixel mi_tira_led]
pin: PA1                  # Pin de datos — ajusta a tu electrónica
chain_count: 15           # Número de LEDs en la tira
color_order: GRB          # Estándar WS2812B — cambia si los colores salen mal
initial_RED: 0.5
initial_GREEN: 0.5
initial_BLUE: 0.5
initial_WHITE: 0.0        # Solo para LEDs RGBW
```

{% endtab %}

{% tab title="SK6812 RGBW" %}
Añade un cuarto canal blanco dedicado. Ideal para iluminación de cámara o cerramiento donde buscas luz neutra.

```ini
[neopixel mi_tira_rgbw]
pin: PB0
chain_count: 20
color_order: GRBW
initial_RED: 0.0
initial_GREEN: 0.0
initial_BLUE: 0.0
initial_WHITE: 0.8        # El canal blanco da una iluminación neutra muy limpia
```

{% endtab %}

{% tab title="APA102 / Dotstar" %}
Usa dos cables (datos + reloj), lo que los hace prácticamente inmunes a interferencias. La mejor opción para tiras largas o entornos con ruido eléctrico (motores, fuentes baratas). Más caros que los WS2812 pero mucho más estables.

```ini
[dotstar mi_dotstar]
data_pin: PA3             # Pin de datos
clock_pin: PA4            # Pin de reloj — exclusivo de Dotstar/APA102
chain_count: 30
color_order: BGR
initial_RED: 0.3
initial_GREEN: 0.3
initial_BLUE: 0.3
```

{% endtab %}
{% endtabs %}

### Pines LED en electrónicas BTT habituales

| Electrónica               | Conector   | Pin Klipper |
| ------------------------- | ---------- | ----------- |
| BTT Octopus v1.x          | RGB header | `PB0`       |
| BTT Manta M4P / M5P / M8P | RGB1       | `PD0`       |
| BTT SKR 3                 | RGB        | `PE2`       |
| BTT SKR Mini E3 v3        | Neopixel   | `PC7`       |

{% hint style="warning" %}
Los manuales de BTT a veces tienen errores en los pines de los conectores RGB. Si el pin no funciona, prueba el alternativo (`PD1` en lugar de `PD0`, etc.) o consulta el esquema del repositorio de BTT en GitHub.
{% endhint %}

### virtual\_leds — segmentar una tira en zonas lógicas

`[virtual_leds]` permite dividir una tira física en segmentos independientes y controlar cada zona por separado. Muy útil en configuraciones como el Stealthburner (logo + nozzle en la misma cadena) o cualquier tira que quieras controlar por zonas.

```ini
[neopixel toolhead_leds]
pin: nhk:gpio7
chain_count: 3
color_order: GRB
initial_RED: 0.0
initial_GREEN: 0.0
initial_BLUE: 0.0

# Segmento 1: LED del logo (LED nº 1 de la cadena)
[virtual_leds logo_leds]
leds: neopixel:toolhead_leds (1)

# Segmento 2: LEDs del nozzle (LEDs 2 y 3)
[virtual_leds nozzle_leds]
leds: neopixel:toolhead_leds (2, 3)
```

Ahora puedes usar `logo_leds` y `nozzle_leds` de forma independiente en tus efectos y macros, aunque físicamente sean la misma tira.

### Comandos SET\_LED y SET\_LED\_TEMPLATE

#### SET\_LED — cambio directo de color

```gcode
# Cambiar todos los LEDs de la tira
SET_LED LED=mi_tira_led RED=0.5 GREEN=0.0 BLUE=0.0

# Cambiar un LED específico (INDEX empieza en 1)
SET_LED LED=mi_tira_led RED=1.0 GREEN=0.0 BLUE=0.0 INDEX=1

# Apagar todos
SET_LED LED=mi_tira_led RED=0 GREEN=0 BLUE=0

# Actualizar varios LEDs de golpe sin parpadeos intermedios
# TRANSMIT=0 acumula el cambio sin enviarlo; TRANSMIT=1 (el último) envía todo junto
SET_LED LED=mi_tira_led RED=1.0 INDEX=1 TRANSMIT=0
SET_LED LED=mi_tira_led GREEN=1.0 INDEX=2 TRANSMIT=0
SET_LED LED=mi_tira_led BLUE=1.0 INDEX=3 TRANSMIT=1
```

| Parámetro                       | Descripción                                                        |
| ------------------------------- | ------------------------------------------------------------------ |
| `LED`                           | Nombre del `[neopixel]`, `[dotstar]` o `[virtual_leds]`            |
| `RED`, `GREEN`, `BLUE`, `WHITE` | Intensidad del canal (0.0 a 1.0)                                   |
| `INDEX`                         | Número de LED en la cadena (1 = primero). Sin INDEX aplica a todos |
| `TRANSMIT`                      | `0` = acumula sin enviar, `1` = envía todo (por defecto 1)         |
| `SYNC`                          | `0` = no espera a que termine el movimiento anterior               |

#### SET\_LED\_TEMPLATE — plantillas dinámicas

`SET_LED_TEMPLATE` asigna un template de display a los LEDs, de modo que el color se actualiza automáticamente en tiempo real según el estado de la impresora. Ideal para barras de progreso o indicadores de temperatura.

```gcode
# Asignar una plantilla al LED
SET_LED_TEMPLATE LED=mi_tira_led TEMPLATE=nombre_template

# Quitar la plantilla y volver a control manual
SET_LED_TEMPLATE LED=mi_tira_led TEMPLATE=""
SET_LED LED=mi_tira_led RED=0 GREEN=0 BLUE=0
```

Ejemplo de plantilla — barra de progreso de impresión:

```ini
[display_template led_progress]
param_led_num: 0
param_led_total: 1
text:
  {% set ratio = printer.display_status.progress %}
  {% set led_ratio = param_led_num|float / param_led_total %}
  {% if ratio > led_ratio %}
    0.0, 0.5, 1.0, 0.0
  {% else %}
    0.0, 0.0, 0.05, 0.0
  {% endif %}
```

Para aplicarla a cada LED de la tira:

```ini
[gcode_macro LEDS_PROGRESS]
gcode:
  {% set leds_count = printer["neopixel mi_tira_led"].chain_count|int %}
  {% for i in range(1, leds_count + 1) %}
    SET_LED_TEMPLATE LED=mi_tira_led TEMPLATE=led_progress param_led_num={i} param_led_total={leds_count} INDEX={i} TRANSMIT={ 1 if i == leds_count else 0 }
  {% endfor %}
```

### Macros para el ciclo de impresión

El set mínimo que vale la pena tener configurado:

```ini
# ─── Iluminación básica ─────────────────────────────────────────────────────

[gcode_macro LEDS_OFF]
description: Apagar todos los LEDs
gcode:
    SET_LED LED=mi_tira_led RED=0 GREEN=0 BLUE=0 WHITE=0

[gcode_macro LEDS_ON]
description: Iluminación blanca para cámara
gcode:
    SET_LED LED=mi_tira_led RED=1.0 GREEN=1.0 BLUE=1.0

# ─── Estados de impresión ───────────────────────────────────────────────────

[gcode_macro LEDS_HEATING]
description: Naranja — calentando hotend/cama
gcode:
    SET_LED LED=mi_tira_led RED=1.0 GREEN=0.3 BLUE=0.0

[gcode_macro LEDS_LEVELING]
description: Azul — nivelando/mesh
gcode:
    SET_LED LED=mi_tira_led RED=0.0 GREEN=0.2 BLUE=1.0

[gcode_macro LEDS_PRINTING]
description: Verde suave — imprimiendo
gcode:
    SET_LED LED=mi_tira_led RED=0.0 GREEN=0.8 BLUE=0.2

[gcode_macro LEDS_DONE]
description: Verde brillante — impresión finalizada
gcode:
    SET_LED LED=mi_tira_led RED=0.0 GREEN=1.0 BLUE=0.0

[gcode_macro LEDS_ERROR]
description: Rojo — error o pausa por filamento
gcode:
    SET_LED LED=mi_tira_led RED=1.0 GREEN=0.0 BLUE=0.0

[gcode_macro LEDS_PAUSED]
description: Amarillo — impresión pausada
gcode:
    SET_LED LED=mi_tira_led RED=1.0 GREEN=0.8 BLUE=0.0
```

Intégralas en `PRINT_START` y `PRINT_END`:

```ini
[gcode_macro PRINT_START]
gcode:
    LEDS_HEATING
    # ... calentar cama y hotend ...
    LEDS_LEVELING
    # ... home + mesh ...
    LEDS_PRINTING
    # ... purga e inicio de impresión ...

[gcode_macro PRINT_END]
gcode:
    # ... retract, park ...
    LEDS_DONE
```

### Control desde Mainsail y Fluidd

Las tiras `[neopixel]` y `[dotstar]` gestionadas directamente por Klipper aparecen automáticamente en el panel web bajo **Dashboard → Miscellaneous**:

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/HxSXMq9tcDy5joo9iQEz/image.png) ![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/EcEBQ0wX2fsGMGNPmv9R/image.png)

Desde ahí puedes cambiar los colores manualmente con sliders sin necesidad de macros.

{% hint style="info" %}
Los LEDs controlados por WLED, LUMEN o LED Effects **no aparecen** en Miscellaneous. Se controlan únicamente a través de macros G-code.
{% endhint %}

### LED Effects — efectos avanzados

[**klipper-led\_effect**](https://github.com/julianschill/klipper-led_effect) añade efectos dinámicos a los LEDs gestionados por Klipper: breathing, chasing, progress bar, temperatura en tiempo real, reacción a errores, arco iris, y muchos más. Es lo que usan la mayoría de configuraciones de Voron y similares.

#### Instalación

```bash
cd ~
git clone https://github.com/julianschill/klipper-led_effect.git
cd klipper-led_effect
./install-led_effect.sh
```

Si tu instalación está en rutas no estándar:

```bash
./install-led_effect.sh [-k <klipper path>] [-s <klipper service name>] [-c <config path>]
```

Añade esto en `moonraker.conf` para recibir actualizaciones automáticas:

```ini
[update_manager led_effect]
type: git_repo
path: ~/klipper-led_effect
origin: https://github.com/julianschill/klipper-led_effect.git
primary_branch: master
is_system_service: False
```

{% hint style="success" %}
El repositorio incluye una **app de escritorio** (Windows y Mac) para simular efectos antes de aplicarlos a la impresora. Descárgala desde [Releases → Assets](https://github.com/julianschill/klipper-led_effect/releases). Ahorra mucho tiempo de prueba y error.

<img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FuITHxsGxkmE5itI3lo9I%2Fimage.png?alt=media&amp;token=6c36389d-86a5-4573-b1e0-8b31596ceb26" alt="" data-size="original">
{% endhint %}

#### Controlar los efectos

```gcode
# Activar un efecto
SET_LED_EFFECT EFFECT=nombre_efecto

# Activar con fade-in de 1 segundo
SET_LED_EFFECT EFFECT=nombre_efecto FADETIME=1.0

# Parar un efecto concreto
SET_LED_EFFECT EFFECT=nombre_efecto STOP=1

# Parar todos los efectos activos
STOP_LED_EFFECTS
```

#### Estructura de `[led_effect]`

```ini
[led_effect nombre_efecto]
leds:
    neopixel:mi_tira_led              # Toda la tira
    neopixel:mi_tira_led (1-8)        # LEDs 1 a 8
    neopixel:mi_tira_led (9-16)       # LEDs 9 a 16
    virtual_leds:logo_leds            # Segmento virtual
    dotstar:mi_dotstar (1,3,5)        # LEDs específicos
autostart: true                       # Activar al arrancar Klipper
frame_rate: 24                        # Fotogramas/segundo
heater: extruder                      # Vincular a temperatura de un heater
run_on_error: false                   # Solo se activa en estado de error crítico
layers:
    # tipo     vel  ciclos  mezcla  (R,G,B) o (R,G,B,W)
    breathing  10   1       top     (0.5, 0.5, 1.0)
```

**Parámetros de capa:**

| Parámetro      | Descripción                                                                |
| -------------- | -------------------------------------------------------------------------- |
| `autostart`    | `true` activa el efecto al iniciar Klipper                                 |
| `frame_rate`   | FPS de actualización. 24 es suficiente para casi todo                      |
| `heater`       | Vincula el efecto a la temperatura de un heater (`extruder`, `heater_bed`) |
| `analog_pin`   | Vincula el efecto al valor de un pin analógico                             |
| `stepper`      | Vincula el efecto al estado de un stepper                                  |
| `run_on_error` | Si `true`, solo activo en estado de error de Klipper                       |

Para la referencia completa de tipos de capa y parámetros: [documentación oficial del plugin](https://github.com/julianschill/klipper-led_effect/blob/master/docs/LED_Effect.md#defining-effect-layers).

#### Ejemplos de efectos

**Breathing — respiración suave, ideal para idle:**

```ini
[led_effect leds_idle]
autostart: true
frame_rate: 24
leds:
    neopixel:mi_tira_led
layers:
    breathing  10  1  top  (0.2, 0.2, 0.8)
```

**Temperatura del nozzle en tiempo real** — azul frío → rojo caliente:

```ini
[led_effect temperatura_nozzle]
leds:
    neopixel:mi_tira_led
autostart: true
frame_rate: 24
heater: extruder
layers:
    heater  50  0  add   (1.0, 0.0, 0.0), (0.0, 0.0, 1.0)
```

**Barra de progreso de impresión:**

```ini
[led_effect barra_progreso]
leds:
    neopixel:mi_tira_led
autostart: false
frame_rate: 24
layers:
    progress  -1  0  add   (0.0, 0.0, 1.0), (0.0, 0.1, 0.6)
    static     0  0  top   (0.0, 0.0, 0.05)
```

**Arco iris continuo:**

```ini
[led_effect rainbow]
leds:
    neopixel:mi_tira_led
autostart: false
frame_rate: 24
layers:
    gradient  0.3  1  add  (0.3, 0.0, 0.0),(0.0, 0.3, 0.0),(0.0, 0.0, 0.3)
```

**Error crítico — rojo parpadeante (se activa automáticamente):**

```ini
[led_effect error_critico]
leds:
    neopixel:mi_tira_led
layers:
    strobe     1  1.5  add         (1.0, 1.0, 1.0)
    breathing  2  0    difference  (0.95, 0.0, 0.0)
    static     1  0    top         (1.0, 0.0, 0.0)
autostart: false
frame_rate: 24
run_on_error: true
```

**Comet / persecución:**

```ini
[led_effect loading]
leds:
    neopixel:mi_tira_led
autostart: false
frame_rate: 24
layers:
    comet  0.3  0  add  (0.0, 0.0, 1.0)
```

***

## LEDs en el toolhead — Stealthburner y similares

Si tienes un cabezal Voron Stealthburner (o cualquier toolhead con LEDs en el hotend), puedes usar el script de post-procesado de JJR para que los LEDs cambien de color según el tipo de trazada que está imprimiendo: perímetros, relleno, soporte, etc.

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

La versión actualizada del script está en [este repositorio](https://github.com/sadaoikebe/my-printer-config/blob/master/stealthburner_colors.py).

### Configuración base para Stealthburner

```ini
[neopixel sb_leds]
pin: toolhead:gpio7       # Ajusta al pin de tu toolboard
chain_count: 3
color_order: GRB
initial_RED: 0.0
initial_GREEN: 0.0
initial_BLUE: 0.0

[virtual_leds sb_logo]
leds: neopixel:sb_leds (1)

[virtual_leds sb_nozzle]
leds: neopixel:sb_leds (2, 3)
```

### Añadir el script al laminador

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

1. Copia `stealthburner_colors.py` a tu ordenador (en una ruta **sin espacios**)
2. Asegúrate de tener **Python 3** instalado
3. En el laminador: **Print Settings → Output Options → Post-processing scripts** — añade la ruta completa al script

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/rM6xUtCE5i4ha9Ri2wI2/image.png)

Al laminar aparece una ventana de terminal confirmando la ejecución.
{% endtab %}

{% tab title="Cura" %}
Copia el script al directorio de scripts de Cura:

* Windows: `%APPDATA%\cura\<VERSION>\scripts`
* Linux: `~/.local/share/cura/<VERSION>/scripts`
* macOS: `~/Library/Application Support/Cura/<VERSION>/scripts`

En Cura: **Extensions → Post Processing → Modify G-Code** → **Add a script → Stealthburner Colors**
{% endtab %}
{% endtabs %}

Para verificar que funcionó, abre el G-code generado con un editor y busca `SET_LED LED=sb_leds`. Deben aparecer cambios de color en los puntos de transición entre tipos de trazada.

***

## Opción 2 — Hardware externo o segunda MCU

Cuando la MCU principal no tiene pines libres, quieres controlar tiras grandes con animaciones fluidas a 60fps, o prefieres un sistema de efectos más rico sin escribir código, estas tres opciones cubren todos los casos.

### WLED vs LUMEN vs RP2040 — ¿cuándo usar cada uno?

|                                     | WLED                                   | LUMEN                                | RP2040 / Pi Pico                 |
| ----------------------------------- | -------------------------------------- | ------------------------------------ | -------------------------------- |
| **Hardware extra**                  | ESP8266/ESP32 (\~5€)                   | Ninguno (usa la Pi)                  | Pi Pico (\~5€)                   |
| **Conexión a Klipper**              | Moonraker (`[wled]`)                   | Moonraker (plugin)                   | MCU secundaria (`[mcu]`)         |
| **FPS / fluidez**                   | Alta (WiFi, alguna latencia)           | 60fps GPIO nativo                    | Igual que MCU principal          |
| **Número de efectos**               | +100 efectos y paletas                 | 12 efectos, 14 estados automáticos   | Los de klipper-led\_effect       |
| **Interfaz de configuración**       | App web propia + presets               | Archivo `lumen.cfg`                  | `printer.cfg`                    |
| **Detección automática de estados** | No — necesita macros                   | Sí — sin tocar PRINT\_START          | No — necesita macros             |
| **Mejor para**                      | Cerramientos grandes, efectos vistosos | Pi ya instalada, cero hardware extra | Pines MCU agotados, tiras largas |

{% hint style="info" %}
Las tres opciones son compatibles entre sí. Puedes tener WLED para el cerramiento, LUMEN para el toolhead, y una segunda MCU para una tira larga simultáneamente.
{% endhint %}

***

### WLED — firmware ESP8266/ESP32

[WLED](https://kno.wled.ge/) es un firmware open-source para ESP8266/ESP32 con más de 100 efectos y paletas de color. Se integra con Moonraker para controlar presets desde macros G-code.

{% hint style="success" %}
WLED es la opción recomendada si quieres efectos visuales llamativos en el cerramiento. La ESP32 cuesta menos de 5€ y aguanta tiras de cientos de LEDs sin problemas.
{% endhint %}

#### Configurar presets en WLED

Antes de integrar con Klipper, define los presets en la app de WLED:

1. Elige color y efecto desde la pantalla principal
2. Pestaña **Presets** → crear nuevo preset. El **ID** del preset es el número que usarás en Klipper
3. Crea al menos: encendido con efecto, apagado, y uno por cada estado de impresión

Asigna una **IP estática** a tu WLED desde la configuración WiFi del propio WLED. Si cambia la IP, los macros dejan de funcionar.

#### moonraker.conf

```ini
[wled cerramiento]
type: http
address: 192.168.1.99    # IP estática de tu WLED
initial_red: 0.5
initial_green: 0.4
initial_blue: 0.3
chain_count: 60

# Si tienes varios WLED, añade más secciones
[wled toolhead_wled]
type: http
address: 192.168.1.100
chain_count: 8
```

#### Macros Klipper para WLED

```ini
[gcode_macro WLED_ON]
description: Encender WLED con preset opcional
gcode:
    {% set strip = params.STRIP | default("cerramiento") | string %}
    {% set preset = params.PRESET | default(1) | int %}
    {action_call_remote_method("set_wled_state",
                               strip=strip,
                               state=True,
                               preset=preset)}

[gcode_macro WLED_OFF]
description: Apagar WLED
gcode:
    {% set strip = params.STRIP | default("cerramiento") | string %}
    {action_call_remote_method("set_wled_state",
                               strip=strip,
                               state=False)}

# Macros de estado usando presets
[gcode_macro WLED_HEATING]
gcode:
    WLED_ON STRIP=cerramiento PRESET=2

[gcode_macro WLED_PRINTING]
gcode:
    WLED_ON STRIP=cerramiento PRESET=3

[gcode_macro WLED_DONE]
gcode:
    WLED_ON STRIP=cerramiento PRESET=4
```

***

### LUMEN — plugin Moonraker para Raspberry Pi

[LUMEN](https://github.com/MakesBadDecisions/Lumen_RPI) es un plugin de Moonraker que controla LEDs directamente desde la Raspberry Pi sin necesidad de hardware externo. Detecta automáticamente 14 estados de la impresora y aplica efectos suaves a 60fps usando el GPIO de la Pi.

{% hint style="success" %}
LUMEN es la mejor opción si ya tienes la Pi y quieres detección automática de estados sin tocar `PRINT_START` ni `PRINT_END`. La instalación es un único script.
{% endhint %}

#### Instalación

```bash
cd ~
git clone https://github.com/MakesBadDecisions/Lumen_RPI.git lumen
cd lumen
chmod +x install.sh
./install.sh
```

El instalador detecta las rutas de Klipper/Moonraker automáticamente, instala la librería `rpi-ws281x`, levanta el servicio `ws281x-proxy` (necesario para acceso GPIO a 60fps) y añade la configuración base al `moonraker.conf`.

#### moonraker.conf

```ini
[lumen]
config_path: ~/printer_data/config/lumen.cfg

[update_manager lumen]
type: git_repo
path: ~/lumen
origin: https://github.com/MakesBadDecisions/Lumen_RPI.git
managed_services: moonraker
primary_branch: main
```

#### Configuración en lumen.cfg

{% tabs %}
{% tab title="GPIO (Pi directa)" %}
Para tiras WS2812B conectadas directamente a los GPIO de la Raspberry Pi. Corre a 60fps sin tocar la cola G-code.

```ini
[lumen_settings]
gpio_fps: 60               # FPS de animación
bored_timeout: 300         # Segundos idle antes de "bored"
sleep_timeout: 600         # Segundos bored antes de "sleep"

[lumen_group cerramiento]
driver: proxy              # GPIO via ws281x-proxy (recomendado para 60fps)
gpio_pin: 18               # Pin BCM válidos: 12, 13, 18, 19
index_start: 1
index_end: 60
color_order: GRB
group_brightness: 0.8
on_idle: pulse cobalt
on_heating: thermal bed ice lava 2.0
on_printing: progress steel matrix 1.5
on_cooldown: pulse ice
on_error: heartbeat red
on_bored: disco
on_sleep: off
```

{% hint style="warning" %}
Los únicos GPIO válidos para WS2812B en la Pi son **12, 13, 18 y 19** (pines PWM hardware). GPIO 18 es el más recomendado — GPIO 19 puede dar conflictos con la salida de audio si está habilitada en `/boot/config.txt`.
{% endhint %}
{% endtab %}

{% tab title="MCU (toolhead/EBB)" %}
Para LEDs conectados a la MCU principal o un toolboard. LUMEN envía `SET_LED` via cola G-code — la animación es más lenta durante la impresión pero funciona en cualquier electrónica BTT.

```ini
# Requiere definir el neopixel en printer.cfg primero:
# [neopixel toolhead_leds]
# pin: EBBCan:PD3
# chain_count: 3
# color_order: GRB

[lumen_group toolhead]
driver: klipper
neopixel: toolhead_leds    # Debe coincidir con [neopixel] en printer.cfg
index_start: 1
index_end: 3
group_brightness: 1.0
on_idle: solid green
on_heating: pulse orange
on_printing: solid white
on_error: heartbeat red
```

{% endtab %}

{% tab title="PWM (tira monocolor)" %}
Para tiras LED no addressables (luz blanca, un solo canal de brillo).

```ini
# Requiere en printer.cfg:
# [output_pin caselight]
# pin: PB7
# pwm: True
# value: 0.5

[lumen_group luz_caja]
driver: pwm
pin_name: caselight
on_idle: 0.5
on_printing: 1.0
on_sleep: 0.0
```

{% endtab %}
{% endtabs %}

#### Estados automáticos de la impresora

LUMEN detecta 14 estados directamente desde Moonraker/Klipper sin necesidad de macros en `PRINT_START`/`PRINT_END`:

| Estado            | Cuándo se activa                                |
| ----------------- | ----------------------------------------------- |
| `idle`            | Impresora fría, sin objetivos de temperatura    |
| `heating`         | Calentando hotend o cama                        |
| `printing`        | Impresión activa a temperatura                  |
| `cooldown`        | Impresión terminada, todavía caliente (>40°C)   |
| `error`           | Klipper en shutdown o error                     |
| `paused`          | Impresión pausada                               |
| `cancelled`       | Impresión cancelada                             |
| `homing`          | Ejecutando homing                               |
| `meshing`         | Haciendo bed mesh                               |
| `leveling`        | Nivelando                                       |
| `probing`         | Probando con el sensor                          |
| `filament_change` | Cambio de filamento (requiere sensor de runout) |
| `bored`           | Idle durante N minutos (configurable)           |
| `sleep`           | Bored durante N minutos (configurable)          |

#### Efectos disponibles

```ini
on_idle: solid white           # Sólido
on_idle: pulse cobalt          # Respiración/fade
on_error: heartbeat red        # Doble pulso (latido)
on_bored: disco                # Destellos arcoíris
on_bored: rainbow              # Arcoíris continuo
on_heating: fire               # Llama simulada
on_printing: comet cobalt      # Cometa con estela
on_cooldown: chase 1           # Persecución predador/presa (multi-grupo)
on_idle: kitt red              # Scanner KITT (Knight Rider)

# Gradiente térmico: thermal <fuente> <color_frío> <color_caliente> <curva>
on_heating: thermal bed ice lava 2.0

# Barra de progreso: progress <color_inicio> <color_fin> <curva>
on_printing: progress steel matrix 1.5

on_sleep: off                  # Apagado
```

#### Integración opcional con macros

LUMEN funciona sin macros — los estados se detectan automáticamente. Para control manual añade el archivo de macros de ejemplo a `printer.cfg`:

```ini
[include lumen_macros.cfg]
```

```gcode
LUMEN_RELOAD                                       # Recargar config sin reiniciar Moonraker
LUMEN_SET GROUP=cerramiento EFFECT=solid COLOR=white DURATION=10  # Override temporal
LUMEN_TEST STATE=heating                           # Probar un estado
```

#### Modo test — verificar efectos sin imprimir

```gcode
LUMEN_TEST_START                           # Entrar en modo test
LUMEN_TEST_NEXT_STATE                      # Ciclar: idle → heating → printing → ...
LUMEN_TEST_NEXT_EFFECT GROUP=cerramiento   # Ciclar efectos en un grupo
LUMEN_TEST_STOP                            # Salir y recargar config
```

#### API REST

```bash
curl http://localhost:7125/server/lumen/status | jq                            # Estado + métricas
curl -X POST "http://localhost:7125/server/lumen/set_group?group=cerramiento&effect=solid&color=white"
curl -X POST "http://localhost:7125/server/lumen/reload"                       # Hot reload config
curl -X POST "http://localhost:7125/server/lumen/test_event?event=heating"     # Forzar estado
```

***

### Segunda MCU — RP2040 / Pi Pico

Si tu electrónica no tiene pines libres o quieres controlar tiras de más de 20 LEDs sin saturar la MCU principal, un microcontrolador dedicado con firmware Klipper es la solución más limpia: los LEDs aparecen en Klipper como cualquier otro neopixel y son compatibles con LED Effects.

**La opción más recomendada: Raspberry Pi Pico (RP2040)**

Cuesta menos de 5€, tiene soporte nativo en Klipper, y puede manejar centenares de LEDs sin esfuerzo. Mucho más potente que un Arduino Nano para este uso.

#### Compilar firmware para RP2040

```bash
cd ~/klipper
make clean
make menuconfig
```

Configuración en menuconfig:

* **Micro-controller Architecture**: `Raspberry Pi RP2040`
* **Bootloader offset**: `No bootloader`
* **Communication interface**: `USB`

```bash
make
```

Con el Pico en modo BOOTSEL (mantén el botón pulsado al conectar el USB), aparece como unidad de almacenamiento. Copia el archivo `.uf2` generado.

#### Configurar en printer.cfg

```ini
[mcu pico_leds]
serial: /dev/serial/by-id/usb-Klipper_rp2040_XXXXX-if00

[neopixel tira_pico]
pin: pico_leds:gpio0      # GPIO del Pico conectado a la tira
chain_count: 60
color_order: GRB
initial_RED: 0.3
initial_GREEN: 0.3
initial_BLUE: 0.3
```

Una vez configurado puedes usar este `[neopixel]` con cualquier macro `SET_LED` o con el plugin LED Effects exactamente igual que si estuviera en la MCU principal.

{% hint style="info" %}
**Arduino Nano como alternativa**

Si tienes un Arduino Nano disponible también funciona. En `make menuconfig` selecciona `Atmega AVR` → `atmega328p`. El RP2040 es preferible por capacidad y mejor soporte, pero el Nano funciona perfectamente para tiras pequeñas.
{% endhint %}

***

## Solución de problemas

### Los colores salen incorrectos

El problema casi siempre es el `color_order`. Prueba en este orden:

1. Comprueba el modelo exacto de tu LED (WS2812B, SK6812, APA102...)
2. Consulta la tabla de tipos más arriba y ajusta `color_order`
3. Si mezclas LEDs de distinto tipo en la misma cadena, puedes especificar uno por LED: `color_order: GRB, GRB, GRBW`

### Los LEDs parpadean o hacen cosas raras

{% columns %}
{% column %}
**Causa probable: señal**

* Falta resistencia en el pin de datos (300-500 Ω)
* Cable de señal demasiado largo (más de 50 cm sin repetidor)
* GND no compartido entre MCU y tira
  {% endcolumn %}

{% column %}
**Causa probable: alimentación**

* Tira alimentada desde el 5V de la electrónica con más de 20 LEDs
* Fuente 5V insuficiente — usa la calculadora WLED para verificar amperaje
* Capacitor 1000 µF entre +5V y GND al inicio de la tira estabiliza la tensión
  {% endcolumn %}
  {% endcolumns %}

### "Neopixel update did not succeed" en el log

Este error aparece cuando el timing de la señal falla. Causas más frecuentes:

* MCU demasiado cargada — reduce `frame_rate` en LED Effects (de 24 a 10 o menos)
* Tira conectada a pin de Raspberry Pi directamente sin usar LUMEN ni segunda MCU
* Interferencias en el cable de señal — acorta el cable o añade el condensador

### Solo se enciende el primer LED

Comprobaciones:

1. Verifica que `chain_count` coincide con el número real de LEDs
2. El sentido de la tira es incorrecto — invierte la conexión o usa otro punto de entrada
3. Alimentación insuficiente — a partir del LED 15-20 sin alimentación externa la señal se degrada

### Los efectos de LED Effects no se activan

1. Confirma que el plugin está instalado: en Mainsail → Sistema → Extensiones, debe aparecer `led_effect`
2. Reinicia Klipper tras instalar el plugin
3. Verifica que los nombres de `[neopixel]` en el `[led_effect]` coinciden exactamente con los definidos en el cfg
4. Si usas `virtual_leds`, la referencia en `[led_effect]` debe ser `virtual_leds:nombre` no `neopixel:nombre`


# Mainsail - Mejoras

{% hint style="info" %}
**English**: Use your browser's built-in translation — Chrome and Edge detect the language automatically and offer to translate the page.
{% endhint %}


# Exclude Objects

Cancelación de objetos individuales durante nuestras impresiones

Una función muy útil para nuestro Klipper es Exclude Objects, con ella podemos cancelar/omitir un objeto de nuestra impresión en caso de que tenga algún problema, ponga en peligro el conjunto de la impresión o que lo incluyésemos por equivocación.

{% hint style="success" %}
La función Exclude Objects está disponible en todas las versiones actuales de Klipper, Moonraker, Mainsail y Fluidd. No se requiere ninguna versión específica si tu instalación está actualizada.
{% endhint %}

## Habilitar la función Label Objects en tu laminador/slicer

Para que Exclude Objects funcione, tu laminador tiene que estar configurado para crear etiquetas en el gcode generado para cada objeto de la impresión. Los laminadores modernos (PrusaSlicer 2.6+, OrcaSlicer, Bambu Studio, Cura 5+) generan estas etiquetas de forma nativa, lo que evita tener que usar el pre-procesado de Moonraker.

{% tabs %}
{% tab title="PrusaSlicer" %}
En PrusaSlicer deberemos habilitar la siguiente opción:

```
Print Settings > Output options > Output file > Label objects
```

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/VgYYtCeo45k71muWkn8N/image.png)

{% hint style="info" %}
SuperSlicer, el fork de PrusaSlicer, ya no tiene desarrollo activo. Se recomienda migrar a PrusaSlicer u OrcaSlicer.
{% endhint %}
{% endtab %}

{% tab title="Bambu Studio / OrcaSlicer" %}
En Bambu Studio y OrcaSlicer deberemos habilitar la siguiente opción:

```
Process > Others > Label objects / Exclude objects
```

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/s76hF06YusahXBC0K7Xz/image.png)
{% endtab %}

{% tab title="Cura / Ideamaker" %}
Cura e Ideamaker etiquetan los objetos por defecto en el gcode generado y por lo tanto son compatibles directamente sin realizar ninguna configuración adicional.
{% endtab %}
{% endtabs %}

## Habilitar el pre-procesado en Moonraker

Este paso convierte las etiquetas generadas por el laminador en gcode que Klipper pueda procesar. Solo es necesario si tu laminador no genera las etiquetas de forma nativa.

Para habilitarlo abriremos nuestro `moonraker.conf` y añadiremos:

{% code title="./moonraker.conf" %}

```django
[file_manager]
enable_object_processing: True
```

{% endcode %}

{% hint style="warning" %}
**Si tu laminador ya genera etiquetas nativas** (PrusaSlicer 2.6+, OrcaSlicer, Bambu Studio, Cura 5+) **no necesitas activar este pre-procesado**.

Si decides activarlo, ten en cuenta que es un proceso intensivo en I/O. **No se recomienda en hosts de baja potencia como Raspberry Pi Zero**.

Como alternativa externa puedes usar [preprocess-cancellation](https://github.com/kageurufu/cancelobject-preprocessor) desde tu propio ordenador antes de cargar el fichero.
{% endhint %}

## Habilitando Exclude Objects en Klipper

Para que Klipper procese correctamente la exclusión de objetos tenemos que habilitarlo en nuestro `printer.cfg`:

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

```django
[exclude_object]
```

{% endcode %}

{% hint style="info" %}
Tenéis más información sobre el [módulo exclude\_object](https://www.klipper3d.org/Exclude_Object.html) en la documentación oficial de Klipper.
{% endhint %}

{% hint style="danger" %}
\*\*Para que Exclude Objects funcione es necesario reiniciar Klipper.\*\*Un `FIRMWARE_RESTART` desde la UI es suficiente; no hace falta reiniciar el sistema completo.
{% endhint %}

## Uso desde la interfaz web

Con todo activado y un gcode que incluya las etiquetas de objetos, todos los interfaces compatibles mostrarán controles para excluir objetos durante la impresión:

{% tabs %}
{% tab title="Mainsail" %}
Aparecerá un nuevo botón en el apartado de estado de impresión:

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/DVM6KT2lotkba1outa4j/image.png" alt=""><figcaption></figcaption></figure>

Ese botón abre una ventana donde seleccionamos los objetos a excluir:

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/nviGdhpKk5XvyeaXa7r5/image.png" alt=""><figcaption></figcaption></figure>
{% endtab %}

{% tab title="Fluidd" %}
Fluidd también soporta Exclude Objects desde sus versiones actuales. Mostrará los objetos disponibles en el panel de estado de impresión con controles equivalentes a Mainsail.
{% endtab %}

{% tab title="KlipperScreen" %}
KlipperScreen muestra los objetos en pantalla durante la impresión y permite excluirlos directamente desde el panel táctil, sin necesidad de acceder a la interfaz web.
{% endtab %}
{% endtabs %}

## Uso desde consola

También puedes excluir objetos manualmente desde la consola de Klipper con el comando:

```
EXCLUDE_OBJECT NAME=<nombre_del_objeto>
```

El nombre del objeto es el que aparece en la interfaz o en el gcode bajo la etiqueta `EXCLUDE_OBJECT_DEFINE NAME=`.


# Moonraker - Mejoras

{% hint style="info" %}
**English**: Use your browser's built-in translation — Chrome and Edge detect the language automatically and offer to translate the page.
{% endhint %}


# Moonraker-Telegram

Con este complemento es posible enviar mensajes sobre el estado de las impresiones 3D, incluidas fotos, a un bot de Telegram (obviamente, solo si se ha configurado una cámara en la Raspberry Pi) y todo ello sin necesidad de configuraciones poco seguras en nuestros routers o con complicadas instalaciones de VPN.

Este complemento nos ofrece las siguientes funcionalidades:

* Notificaciones a intervalos con imágenes de nuestra cámara durante la impresión
* Contol de luces para la toma de imágenes o videos
* Timelapse, un ejemplo <https://youtu.be/gzbzW7Vv2cs>
* Ejecución de macros/gcode desde Telegram
* Control del apagado del sistema via Moonraker
* Obtención de una captura de imágen cuando deseemos
* Pausar, cancelar y retomar nuestra impresión
* Parada de emergencia

Lista de comandos disponibles en el bot:

```
	/status			- get the status (printing, paused, error) of the printer
	/pause			- pause the current print
	/resume			- resume the current print
	/cancel			- cancel the current print
	/files			- get the last 5 .gcode files, and the option to print them
	/macros			- list all available non-hidden macros
	/gcode %gcode%		- run any gcode command, spaces are supported
	/photo 			- capture a picture from the webstream/webcam
	/video 			- capture a video from the webstream/webcam
	/power			- turn off a specified moonraker power device
	/light			- toggle a specified moonraker power device
	/emergency		- run an emergency stop
	/bot_restart		- Restart the bot to apply config changes
	/shutdown		- Shut down the host system
	/%macro_name%		- Run any macro available on your system.
```

## **Instalando el componente Moonraker-Telegram**

Nos conectaremos por SSH, usando [**Putty**](https://www.putty.org/)/[**Terminus**](https://termius.com/) u otro cliente SSH, a nuestra Raspberry Pi y lanzaremos **Kiauh** ya que nos facilitará enormemente el proceso, si no tienes **Kiauh** te aconsejamos instalarlo siguiendo estas instrucciones.

```bash
// Una vez conectados por SSH lanzaremos Kiauh
cd kiauh
./kiauh.sh
```

Dentro de **Kiauh** iremos a la opción **Install** (*1)\[Install]*) y seleccionaremos **Telegram Bot** (*9)\[telegram Bot]*) y **Kiauh** hará su magia para instalar el componente!!!

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/cJKETzZRjphByfahkepi/image.png" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
El proceso de instalación puede durar unos minutos dependiendo del modelo/potencia de tu Raspberry Pi... como se suele decir... la paciencia es la madre de la ciencia!!! :)
{% endhint %}

Una vez finalizado el proceso nos fijaremos en la parte final para verificar que todo fué correcto:

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/ikE1J41rFhZvhg5JPcMX/image.png)

{% hint style="info" %}
En el caso que no queramos utilizar Kiauh, de nuevo os recomendamos usarlo, podéis instalar el componente de forma manual realizando los siguientes pasos:

* clonaremos el repositorio

  ```
  cd ~
  git clone https://github.com/nlef/moonraker-telegram-bot.git
  cd moonraker-telegram-bot
  ```
* a continuación lanzaremos el script de instalación que nos solicitará erectrio de nuestras configuraciones de Klipper

  ```
  ./scripts/install.sh
  ```
* actualizaremos nuestro fichero de configuración de Moonraker para añadir el nuevo componente al update manager (para poder actualizar de forma sencilla más tarde desde nuestra UI de Klipper)

  ```
  [update_manager client moonraker-telegram-bot]
  type: git_repo
  path: ~/moonraker-telegram-bot
  origin: https://github.com/nlef/moonraker-telegram-bot.git
  env: ~/moonraker-telegram-bot-env/bin/python
  requirements: scripts/requirements.txt
  install_script: scripts/install.sh
  ```
* recuerda que después de cada cambio en la configuración del bot es necesario reiniciar el servicio lo cual puedes hacer desde Telegram con el comando **/bot\_restart** o desde SSH usando **sudo systemctl restart moonraker-telegram-bot**
  {% endhint %}

##

## Creando un bot de Telegram

Busque el usuario [**@BotFather**](https://t.me/BotFather) dentro de la aplicación Telegram

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/bnBb4i0hCduPyKfAUyR8/image.png)

Haga clic en Iniciar para iniciar una conversación con [**@BotFather**](https://t.me/BotFather)

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/lNvzwhC179iXFc6s1pYc/image.png)

Lanzaremos el comando **/newbot** para comenzar con el proceso

```
Alright, a new bot. How are we going to call it? Please choose a name for your bot.
```

Nos indicará que le demos un nombre a nuestro bot, por ejemplo 3DWork Voron 0.1 Bot

```
Good. Now let's choose a username for your bot. It must end in `bot`. Like this, for example: TetrisBot or tetris_bot.
```

Seguidamente nos solicitará un nombre de usuario sin espacios y que termine en "bot", por ejemplo tres**dwork\_*****voron0I*****\_bot**

```
Done! Congratulations on your new bot. You will find it at t.me/3dwork_voron01_bot. You can now add a description, about section and profile picture for your bot, see /help for a list of commands. By the way, when you've finished creating your cool bot, ping our Bot Support if you want a better username for it. Just make sure the bot is fully operational before you do this.

Use this token to access the HTTP API:
<HTTP API token>
Keep your token secure and store it safely, it can be used by anyone to control your bot.

For a description of the Bot API, see this page: https://core.telegram.org/bots/api
```

**Si todo ha ido de forma correcta nos dará un HTTP API Token el cual tendremos que guardar de forma segura ya que lo usaremos a posteriori!!!**

{% hint style="danger" %}
**Como recuperar un token HTTP API**\
Como hemos visto durante el proceso @BotFather nos facilita el token para usar en nuestro componente de Moonraker. En el caso que lo perdamos podremos usar @BotFather para crear uno nuevo usando el comando /token
{% endhint %}

Dentro del mensaje también nos devuelve un link para comenzar a hablar con nuestro nuevo bot ***t.me/***&#x74;res**dwork*****voron0I*****bot**

## ***Obtener el Chat ID de Telegram***

Los dos parámetros que necesitamos para configurar nuestro componente Telegram de Moonraker es el token HTTP API y el Chat ID, ya que en el punto anterior obtuvimos el token v**amos a encontrar nuestro Chat ID**.

{% tabs %}
{% tab title="Desde el propio BOT" %}
Desde Telegram abrimos una conversación con nuestro BOT y este nos dará un mensaje incluyendo nuestro chat\_id:

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/xUj9d0pF3I8VNMAG7xU6/image.png" alt=""><figcaption></figcaption></figure>
{% endtab %}

{% tab title="Usando un BOT de Telegram" %}
La forma más rápida y sencilla es usando @raw\_data\_bot que es un bot al que le enviamos un mensaje de nuestro bot y nos dirá los datos que buscamos:

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FGJHw09pntroyZF4THZZZ%2Fimage.png?alt=media&amp;token=35c549fe-85cc-4066-b16b-ca4af43ead06" alt=""><figcaption></figcaption></figure>
{% endtab %}

{% tab title="Manual usando navegador web" %}
Lo primero de todo es asegurarnos que **iniciamos un chat con nuestro nuevo bot**, esto lo haremos en el link que nos puso @BotFather durante la creación... en nuestro ejemplo t.me/3dwork\_voron01\_bot y **daremos el botón START/INICIAR o usaremos el comando /start**.

**Abriremos un navegador web**, Chrome por ejemplo y **pondremos la siguiente URL, recuerda cambiar la parte \<API-access-token> por el token que obtuvimos en el punto anterior!!!**

```
https://api.telegram.org/bot<API-access-token>/getUpdates?offset=0
```

Deberiamos obtener una pagina con el siguiente texto:

```
{"ok":true,"result":[]}
```

Volveremos a Telegram en nuestro chat con nuestro nuevo bot y le escribiremos cualquier mensaje. Y volveremos al navegador y refrescaremos la página donde veremos que aparece más información:

![Por seguridad se han difuminado los valores.](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/p3Z64XiALEPCh9U2iYRl/image.png)

El valor que deberemos anotar para nuestra configuración será el marcado en el cuadro rojo.
{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Añadiendo el bot a un grupo de Telegram para compartir acceso,** en este caso seguiremos un proceso similar al utilizado para obtener el ID anteriores pero por simplicidad usaremos un bot

Añadiremos el bot @raw\_data\_bot a nuestro grupo que nos facilitará la información del ID del chat que buscamos:\
![](https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FkBnrb5TXJ3T12mkL1Lam%2Fimage.png?alt=media\&token=bc3e5032-266e-4ed7-85ac-0a8a11a66335)\
Anotaremos el ID facilitado para añadirlo en los siguientes puntos a la configuración de Moonraker-Telegram.

**Una vez tengamos la información es aconsejable eliminar el bot del grupo!!!**
{% endhint %}

## Configurar el complemento Moonraker Telegram

Ya casi estamos!!!, ahora iremos a nuestra UI de Klipper, en nuestro caso y para este ejemplo Mainsail, y **editaremos el fichero de configuración telegram.conf** del módulo de Telegram Moonraker:

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/AWwCgG6TyeHunWdxykY9/image.png)

En el fichero de configuración básicamente pondremos en chat\_*id nuestro valor de Chat ID y en bot\_token nuestro token*

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/i0Vfzy1YhTsrjqcA6bbY/image.png)

¡Reiniciaremos el servicio Moonraker-telegram-bot para que cargue los nuevos valores y si todo va bien ya tendremos nuestro bot hablándonos!!!

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/PPBdgh9sdK9M1Xw9Wbt1/image.png)

## Extras

### Actualización del complemento

Podremos actualizar el complemento ya sea desde Kiauh o desde la UI de Klipper:

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/5y937UjNdRzxY3mkg18p/image.png)

Actualizaremos nuestro fichero de configuración de Moonraker para añadir el nuevo componente al update manager (para poder actualizar de forma sencilla más tarde desde nuestra UI de Klipper)

```
[update_manager client moonraker-telegram-bot]
type: git_repo
path: ~/moonraker-telegram-bot
origin: https://github.com/nlef/moonraker-telegram-bot.git
env: ~/moonraker-telegram-bot-env/bin/python
requirements: scripts/requirements.txt
install_script: scripts/install.sh
```

Recuerda reiniciar el servicio Moonraker después del cambio.

### Añadir \[respond] a nuestra configuración Klipper

Actualmente, la mayoría de funciones de notificación de eventos de Moonraker-Telegram emplean la funcionalidad RESPOND de Klipper. En el caso de no tenerla y para habilitarla es tan sencillo como añadir la siguiente sección en vuestro printer.cfg:

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

```django
[respond]
```

{% endcode %}

### Macro para almacenar las configuraciones de timelapse

En el caso de que tengamos pensado utilizar el módulo de timelapses es aconsejable añadir una macro que almacenar los parámetros del mismo. Para hacerlo simplemente añadiremos esto a nuestra configuración de **Klipper**:

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

```django
[gcode_macro _bot_data]
variable_lapse_video_size: 0
variable_lapse_filename: 'None'
variable_lapse_path: 'None'
gcode:
    M118 Setting bot lapse variablesn
```

{% endcode %}

### Personalizar el icono/imagen de nuestro bot

Podremos personalizar el icono de nuestro bot de una forma muy sencilla.

¡Volvemos a hablar con @BotFather y lanzamos el comando /setuuserpic y seleccionamos nuestro bot, y a continuación le enviaremos una imagen que deseemos como icono... listo!!!

### Usos avanzados

Para otros usos avanzados os recomendamos ver la [siguiente página de la documentación oficial](https://github.com/nlef/moonraker-telegram-bot/wiki/Interacting-with-klipper#controlling-timelapse-parameters-via-gcode).

### Input Shaper

En el caso de que usemos [**Input Shaper con acelerómetro**](/klipper/empezamos/input-shaper), nos puede ser muy útil la posibilidad de lanzar y obtener las gráficas en nuestro Telegram.

Añadiremos las siguientes macros a nuestro printer.cfg o un include donde las carguéis:

```django
[gcode_macro measure_resonances]
gcode:
	{% set HZ_PER_SEC = params.HZ_PER_SEC|default(1)|float %} #Parse parameters
	{% set POSITION_X = params.POSITION_X|default(175)|int %}
	{% set POSITION_Y = params.POSITION_Y|default(175)|int %}
	{% set POSITION_Z = params.POSITION_Z|default(50)|int %}

	{% if printer.toolhead.homed_axes != 'xyz' %} #home if not homed
		G28
	{% endif %}
	TEST_RESONANCES AXIS=X HZ_PER_SEC={ HZ_PER_SEC } POINT={ POSITION_X },{ POSITION_Y },{POSITION_Z}
	TEST_RESONANCES AXIS=Y HZ_PER_SEC={ HZ_PER_SEC } POINT={ POSITION_X },{ POSITION_Y },{POSITION_Z}
	RUN_SHELL_COMMAND CMD=shaper_calibrate
	RESPOND PREFIX=tg_send_image MSG="path=['/home/trident/printer_data/logs/resonances/resonances_x.png', '/home/trident/printer_data/logs/resonances/resonances_y.png'], message='Shaper results'"



[gcode_shell_command shaper_calibrate]
command: bash /home/pi/printer_data/config/shaper_calibrate.sh
timeout: 600.
verbose: True
```

{% hint style="info" %}
Recuerda que para poder ejecutar [shell macros antes se han de habilitar](https://3dwork.qitec.net/klipper/mejoras/backup-klipper#habilitamos-las-extensiones-g-code-shell-command) si no lo hicimos antes.
{% endhint %}

{% hint style="warning" %}
Revisar y ajustar las coordenadas por defecto para realizar el test Input Shaper:

```django
{% set POSITION_X = params.POSITION_X|default(175)|int %}
{% set POSITION_Y = params.POSITION_Y|default(175)|int %}
{% set POSITION_Z = params.POSITION_Z|default(50)|int %}
```

{% endhint %}

Crearemos desde nuestro terminal SSH (PuttY, Terminus, etc...) un script shaper\_calibrate.sh en nuestro directorio printer\_data/config/... o aquel que uséis en vuestro Klipper para almacenar las configuraciones de vuestra máquina:

```bash
sudo nano /home/pi/printer_data/config/shaper_calibrate.sh
```

Copiaremos este script, recuerda CTR+X para salir y Y para guardar cambios:

```bash
#! /bin/bash
OUTPUT_FOLDER=logs/resonances
PRINTER_DATA=home/pi/printer_data
KLIPPER_SCRIPTS_LOCATION=~/klipper/scripts
RESONANCE_CSV_LOCATION=tmp

if [ ! -d  /$PRINTER_DATA/$OUTPUT_FOLDER/ ] #Check if we have an output folder
then
    mkdir /$PRINTER_DATA/$OUTPUT_FOLDER/
fi

cd /$RESONANCE_CSV_LOCATION/

shopt -s nullglob
set -- resonances*.csv  

if [ "$#" -gt 0 ]
then
    for each_file in resonances*.csv
    do
        $KLIPPER_SCRIPTS_LOCATION/calibrate_shaper.py $each_file -o /$PRINTER_DATA/$OUTPUT_FOLDER/${each_file:0:12}.png
        rm /$RESONANCE_CSV_LOCATION/$each_file
    done
else
    echo "Something went wrong, no csv found to process"
fi
```

Nos aseguraremos que sea ejecutable:

```bash
sudo chmod +x /home/pi/printer_data/config/shaper_calibrate.sh
```

Con nuestra nueva macro tan solo tendremos que llamarla desde nuestro cliente Telegram y, si tenemos todo correcto y preparado en nuestra máquina, realizará el test y nos enviará el resultado gráfico de este que siempre es de gran ayuda:

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/Z6CUlGgnBZtcMUrwlXmw/image.png" alt=""><figcaption></figcaption></figure>

### Telegram Multi-Instancia

En el caso que usemos el módulo de Telegram para controlar nuestras impresoras de forma remota podremos tener diferentes instancias de este para poder gestionarlas de forma individual.

No vamos a entrar en el proceso de instalación o configuración detallado, el cual podéis encontrar aquí.

Comenzaremos clonando el repositorio e instalando:

```bash
cd
git clone https://github.com/Raabi91/moonraker-telegram moonraker-telegram2
cd moonraker-telegram2
chmod 755 ./scripts/install.sh
./scripts/install.sh
```

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

* en el comando git clone la parte final indica el directorio donde lo instalaremos. Os aconsejamos usar moonraker-telegram2, moonraker-telegram3,...
* en el comando cd lo adaptaremos dependiendo a lo usado en el punto anterior
  {% endhint %}

Durante la instalación nos solicitará el path de Moonraker y de Klipper de cada instancia, aseguraos de poner el correcto para cada instancia ya que ahí dejará el fichero de configuración necesario para su configuración.

Por último nos preguntará el identificador del servicio que es útil para poder evitar problemas de arranque, parada o reinicio del serivicio.

```
if you want to use multiple instances on one pi, enter an identifier here. this is needed to create the sytemd service
If you only use it once per hardware, simply press enter.
```

Por ejemplo si usamos 2 la instalación creará una instancia de servicio de arranque llamada moonraker-telegram2.service

Revisaremos en cada instancia nuestro telegram\_config.sh ajustando el puerto de Moonraker para que coincida con el de cada instancia.

Además si contamos con varias cámaras nos aseguraremos que la URL en el valor webcam (sobretodo el puerto) es el correcto de nuestra instancia.


# KlipperScreen - Mejoras

{% hint style="info" %}
**English**: Use your browser's built-in translation — Chrome and Edge detect the language automatically and offer to translate the page.
{% endhint %}


# KlipperScreen - Personaliza arranque con un video con tu logo

{% hint style="danger" %}
**Este proceso no se puede usar en OS actuales dado que el reproductor usado, OMXplayer, usa MMAL y no es compatible a día de hoy con instalaciones de 64b o con OS actuales.**
{% endhint %}

Los makers del 3D si algo nos gusta es personalizar nuestras máquinas así que con esta guía vas a poder personalizar el arranque de tu host Klipper, está pensada para usar un host Raspberry pero puedes ajustarla para cualquier otro, sea un video con tu logo o animación preferida.

Para realizar este proceso necesitamos acceso SSH a nuestro host y obviamente un video en formato MP4 idealmente.

## Limpiando nuestro arranque en pantalla

Vamos a comenzar por eliminar el "bonito" logo multicolor y pantalla de arranque repleto de lineas estilo matrix :D y para ello hemos de modificar 3 ficheros.

### /boot/config.txt

Abriremos nuestro cliente SSH y lanzaremos el comando:

```bash
sudo nano /boot/config.txt
```

{% hint style="warning" %}
Es importante lanzar el comando con sudo o en su defecto hacer un sudo su antes ya que al ser ficheros de sistema no vamos a poder modificarlos si no lo hacemos de esta forma.
{% endhint %}

Añadiremos la siguiente linea al final del fichero:

{% code title="/boot/config.txt" %}

```bash
disable_splash=1
```

{% endcode %}

Nos aseguramos que el fichero de configuración tenga permisos de ejecución:

```bash
sudo chmod +X /boot/config.txt
```

### /boot/cmdline.txt

Editaremos el fichero con el siguiente comando:

```bash
sudo nano /boot/cmdline.txt
```

Añadiremos lo siguiente al final de la línea:

{% code title="/boot/cmdline.txt" %}

```bash
consoleblank=1 logo.nologo quiet loglevel=0 plymouth.enable=0 vt.global_cursor_default=0 plymouth.ignore-serial-consoles splash fastboot noatime nodiratime noram
```

{% endcode %}

{% hint style="warning" %}
Es importante que añadamos el contenido directamente en una misma linea separando simplemente con un espacio con el contenido que ya tengamos... ni nuevas lineas ni espacios extras.
{% endhint %}

Daremos permisos de ejecución:

```bash
sudo chmod +X /boot/cmdline.txt
```

### **/etc/rc.local**

Como último paso editaremos este fichero:

```bash
sudo nano /etc/rc.local
```

Añadiremos la siguiente línea al final del mismo:

{% code title="/etc/rc.local" %}

```bash
dmesg –console-off
```

{% endcode %}

{% hint style="warning" %}
**Esta línea ha de estar antes de exit 0** que debería de estar ya en el fichero, **de no estar añadiremos otra línea con exit 0 al final del mismo**.
{% endhint %}

De nuevo, nos aseguramos que el fichero sea ejecutable:

```bash
sudo chmod +X /etc/rc.local
```

## Añadiendo nuestro vídeo para el arranque

Para poder insertar nuestro vídeo de arranque hemos de instalar un reproductor que pueda funcionar sin ningún tipo de GUI, hemos elegido omxplayer. Para instalarlo ejecutaremos:

```bash
sudo apt-get install omxplayer
```

A continuación crearemos nuestro servicio para poder cargar nuestro vídeo en el arranque, para ello crearemos un fichero llamado splash.service dentro de /etc/systemd/system/

```bash
sudo nano /etc/systemd/system/splash.service
```

Donde añadiremos el siguiente contenido:

{% code title="/etc/systemd/system/splash.service" %}

```bash
[Unit]
Description=Splash screen 
DefaultDependencies=no 
After=local-fs.target 

[Service]
ExecStart=/usr/bin/omxplayer -b -loop /path/to/video.mp4 
StandardInput=tty 
StandardOutput=tty 

[Install]
WantedBy=sysinit.target
```

{% endcode %}

{% hint style="info" %}
Deberemos ajustar /path/to/video.mp4 al path donde tengamos nuestro video. Os aconsejamos usar uno que sea accesible desde la UI de Klipper para poder ajustarlo de una forma más sencilla... en nuestro caso usamos el siguiente:

**/home/pi/klipper\_config/3Dwork.mp4**

Por otro lado y dependiendo de la duración del video o lo que tarde en arrancar el sistema puede ser interesante añadir o quitar el **-loop** para permitir/evitar que el video se reproduzca en bucle.

Como consejo para el video suele ser mejor realizarlo en formato 4:3 aunque nuestra pantalla sea 16:9.
{% endhint %}

Indicaremos que tiene permisos de ejecución:

```bash
sudo chmod /etc/systemd/system/splash.service
```

Por último habilitaremos la ejecución como servicio en el arranque:

```bash
sudo systemctl enable splash
```

Por último y para verificar que todo ha ido bien reiniciaremos nuestro host:

```bash
sudo reboot
```

{% hint style="success" %}
En el caso que no aparezca nuestro logo:

* revisa cuidadosamente las instrucciones y en especial las anotaciones en determinados pasos
* cualquier espacio o línea extra puede evitar que el proceso funcione correctamente
  {% endhint %}

Os dejamos nuestro video logo de ejemplo para realizar pruebas:

{% file src="/files/eZ3ci03iHVuQH9Isd1hj" %}


# KlipperScreen - Guia de pantallas

## Sugerimos las siguientes pantalla para disfrutar de KlipperScreen:

En el caso que nuestra pantalla no funcione por defecto con KlipperScreen o necesiteis alguna configuracion especial como rotarla o ajustar ciertos parámetros

### Waveshare 3.5" (GPIO) o clones

{% embed url="<https://s.click.aliexpress.com/e/182731559?productUrl=https://s.click.aliexpress.com/e/182731559?productUrl=https://www.aliexpress.com/item/32918104361.html>" %}

Instalando los drivers Waveshare:

```bash
# Descargar los drivers Waveshare:
git clone https://github.com/waveshare/LCD-show.git

# Cambiar los permisos de la carpeta:
chmod -R 755 LCD-show

# Cambiamos al directorio:
cd LCD-show/

# Cambiamos permisos de ficheros:
chmod +x LCD35-show

# Ejecutamos el script de nuestro modelo de pantalla, en nuestro caso 3.5
sudo ./LCD35-show

# Podemos volver a ejecutarlo indicando el angulo de giro si queremos cambiarlo
sudo ./LCD35-show 180

```

Cambios a realizar para su funcionamiento (añadir al final del fichero):

```bash
sudo nano /boot/config.txt
```

Y modificaremos/añadiremos lo siguiente

```bash
# Enable audio (loads snd_bcm2835)
dtparam=audio=on
dtoverlay=waveshare35a
#dtoverlay=ads7846,cs=1,penirq=17,penirq_pull=2,speed=1000000,keep_vref_on=1,swapxy=1,pmax=255,xohms=60,xmin=200,xmax=3900,ymin=200,ymax=3900
hdmi_force_hotplug=1
#max_usb_current=1
hdmi_group=2
hdmi_mode=1
hdmi_mode=87
hdmi_cvt 800 533 60 6 0 0 0
hdmi_drive=2
```

ificaremos/añadiremos lo siguiente

### Waveshare 7" HDMI Touch (HDMI)

{% embed url="<https://www.amazon.es/dp/B07PKLGMSY/ref=cm_sw_r_cp_apa_fabc_jm77FbPWNZKBZ?_encoding=UTF8&psc=1>" %}

Cambios a realizar para su funcionamiento (añadir al final del fichero):

```
sudo nano /boot/config.txt
```

Y modificaremos/añadiremos lo siguiente

```bash
max_usb_current=1

hdmi_force_hotplug=1
config_hdmi_boost=7
hdmi_group=2
hdmi_mode=87
hdmi_drive=1
display_rotate=0 # 0 conectores a la derecha, 1 a 90 grados, 2 connectores a la izquierda, 3 270 grados
hdmi_cvt 1024 600 60 6 0 0 0
```

### **WAVESHARE 5" (DSI)**

Esta pantalla al conectarse usando el cable plano para display no suele ser necesaria configuración en todo caso nos puede interesar rotarla.

{% embed url="<https://amzn.to/3LdKfl1>" %}

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/eRTJ7pDHxOuulXpQsOyq/image.png)

Cambios a realizar para su funcionamiento (añadir al final del fichero o dentro de la sección \[all]):

```
sudo nano /boot/config.txt
```

```
# For 0 degree rotation:
# (no additional entries - default setting)

# For 90 degree rotation (top to right):
#display_lcd_rotate=1
#dtoverlay=rpi-ft5406,touchscreen-swapped-x-y=1,touchscreen-inverted-x=1

# For 180 degree rotation (upside down)
#display_lcd_rotate=2
#dtoverlay=rpi-ft5406,touchscreen-inverted-x=1,touchscreen-inverted-y=1

# For 270 degree rotation (top to left)
#display_lcd_rotate=3
#dtoverlay=rpi-ft5406,touchscreen-swapped-x-y=1,touchscreen-inverted-y=1
```

### BIQU HDMI5

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/b83VloJgZUEfd1Za2FTN/image.png" alt=""><figcaption></figcaption></figure>

{% embed url="<https://s.click.aliexpress.com/e/182731559?productUrl=https://s.click.aliexpress.com/e/182731559?productUrl=https://www.aliexpress.com/item/1005004673794018.html>" %}

{% code title="/boot/config.txt" %}

```bash
### BIQU HDMI5
# HDMI mode
hdmi_group=2
hdmi_mode=87
hdmi_cvt 800 480 60 6 0 0 0
hdmi_drive=1
```

{% endcode %}

### LongRunner 5" XPT2046 (HDMI GPIO Táctil)

{% embed url="<https://www.amazon.es/gp/product/B07QC6G6S9/ref=ppx_yo_dt_b_asin_image_o00_s00?ie=UTF8&psc=1>" %}

Cambios a realizar para su funcionamiento (añadir al final del fichero):

```
sudo nano /boot/config.txt
```

Y modificaremos/añadiremos lo siguiente:

```bash
# uncomment if you get no picture on HDMI for a default "safe" mode
#hdmi_safe=1

# uncomment this if your display has a black border of unused pixels visible
# and your display can output without overscan
disable_overscan=0

# uncomment if hdmi display is not detected and composite is being output
#hdmi_force_hotplug=1

# uncomment to force a specific HDMI mode (this will force VGA)
hdmi_group=2
hdmi_mode=1
hdmi_mode=87
hdmi_cvt=800 480 60 6 0 0 0

# Enable touchscreen on Elecrow HDMI interface.
dtparam=spi=on
dtparam=i2c_arm=on
dtoverlay=ads7846,cs=1,penirq=25,penirq_pull=2,speed=50000,keep_vref_on=0,swapxy=0,pmax=255,xohms=150,xmin=200,xmax=3900,ymin=200,ymax=3900
dtoverlay=w1-gpio-pullup,gpiopin=4,extpullup=1
```

### **FYSECT CTP40 (GPIO)**

Para esta pantalla asegurarse de instslar los drivers siguiendo las instrucciones

{% embed url="<https://github.com/FYSETC/FYSETC-CTP40/tree/main/Pi3>" %}

## Troubleshooting

### Táctil incorrecto después de rotar UI en pantalla

En ocasion**e**s nos interesa girar los gráficos en nuestra pantalla y nos encontramos que el táctil sigue estando en la posición original.

En estos casos después de realizar el proceso para nuestra pantalla para rotarla iremos al fichero **/usr/share/X11/xorg.conf.d/45-edev.conf** añadiendo lo siguiente a la sección InputClass:

```
// /usr/share/X11/xorg.conf.d/45-edev.conf
Section "InputClass"
        Identifier "evdev touchscreen catchall"
        MatchIsTouchscreen "on"
        MatchDevicePath "/dev/input/event*"
        Driver "evdev"
        Option "TransformationMatrix" "-1 0 1 0 -1 1 0 0 1
EndSection
```


# KlipperScreen Android (Wifi)

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/3PeiDT0EdHgPzE6ElbiB/image.png)

KlipperScreen es un interfaz muy cómodo para gestionar nuestra máquina, hoy os vamos a enseñar una forma de usarlo sin necesidad de comprarnos una pantalla para nuestra pi y aprovechando algún teléfono que tengamos antiguo por casa.

Los siguientes pasos se realizan una vez ya tenemos KlipperScreen ya instalado, os aconsejamos realizarlo desde [**Kiauh**](https://3dwork.qitec.net/klipper/instalacion#instalando-kiauh).

## Instalación

* Instalamos XServer XSDL desde la app store

{% embed url="<https://play.google.com/store/apps/details?gl=US&hl=de&id=x.org.server>" %}

{% hint style="info" %}
En el caso que uséis un Android que no esté soportado ya os aconsejamos coger una versión anterior desde [**aquí**](https://sourceforge.net/projects/libsdl-android/files/apk/XServer-XSDL/)

<https://sourceforge.net/projects/libsdl-android/files/apk/XServer-XSDL/>
{% endhint %}

* editaremos el fichero de lanzamiento de klipperScreen

```bash
cd ~/KlipperScreen 
nano ./launch_klipperscreen.sh
```

* Añadiremos el siguiente código y pulsaremos CTRL+X para guardarlos

```bash
#!/bin/bash
DISPLAY=<IPXServerXSDLApp>:0 /home/pi/.KlipperScreen-env/bin/python3 /home/pi/KlipperScreen/screen.py
```

{% hint style="info" %}
Para conocer el valor de DISPLAY abriremos desde nuestro Android la aplicación XServer XSDL que nos dará esta información

<img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/SJEPrMOHN8YYizqohb6I/image.png" alt="" data-size="original">
{% endhint %}

{% hint style="danger" %}
**IMPORTANTE!!! si la IP varía en vuestro Android el proceso no funcionará por lo que os aconsejamos fijar esta IP en vuestro router.**
{% endhint %}

* Una vez guardados los cambios daremos permisos de ejecución

```bash
sudo chmod +x ./launch_klipperscreen.sh
```

* Lanzamos el script para comprobar que funcione todo y pulsaremos **CTRL+C para salir**

```bash
./launch_klipperscreen.sh
```

* configuramos el servicio para que arranque con klipperScreen

```bash
cd /etc/systemd/system
sudo nano ./KlippyScreenAndroid.service
```

* añadiremos el siguiente código y **CTRL+X para guardar/salir**

```bash
	[Unit]
	Description=KlippyScreen
	After=moonraker.service
	StartLimitIntervalSec=0

	[Service]
	Type=simple
	Restart=always
	RestartSec=1
	User=pi
	WorkingDirectory=/home/pi/KlipperScreen
	ExecStart=/usr/bin/bash  /home/pi/KlipperScreen/launch_klipperscreen.sh

	[Install]
	WantedBy=multi-user.target
```

* Reiniciaremos los siguientes servicios

```bash
	sudo systemctl daemon-reload
	sudo systemctl enable KlippyScreenAndroid
	sudo systemctl restart KlippyScreenAndroid
```

Ya deberiamos de tener nuestro KlipperScreen de forma inalámbrica en nuestro teléfono!!!

## Agradecimientos

Gracias al usuario <https://t.me/zhrosanFPV> de nuestro [**grupo de Telegram Klipper**](https://t.me/Klipper_Firmware_ES)


# Macros - Mejoras

{% hint style="info" %}
**English**: Use your browser's built-in translation — Chrome and Edge detect the language automatically and offer to translate the page.
{% endhint %}

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](https://jinja.palletsprojects.com/) como lenguaje.

Algunos empleos de macros es el [START\_PRINT](/klipper/empezamos/configuracion-klipper-en-laminadores#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](broken://pages/-MTqPy_NKPC-R-jkDi7M#klipper-pid), [cambio de filamentos](/klipper/mejoras/macros-mejoras/cambio-filamentos-m600), 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**](https://klipper.discourse.group/t/macro-creation-tutorial/30) creado por el compañero [**mental**](https://klipper.discourse.group/u/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:

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/CG50ZctdkjUEKIYUe7du/image.png" alt=""><figcaption></figcaption></figure>

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/YS9af07zTefHDUqsyiiM/image.png" alt=""><figcaption></figcaption></figure>

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:

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/WZnHTTsUMz4mCLpFQvhK/image.png" alt=""><figcaption></figcaption></figure>

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

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/P3xgq5kDcaJ3WLoavYVJ/image.png" alt=""><figcaption></figcaption></figure>

* Anidando macros dentro de otras macros como el caso de la[ macro de cambio filamentos o M600](/klipper/mejoras/macros-mejoras/cambio-filamentos-m600)

## 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\]](https://www.klipper3d.org/Config_Reference.html#gcode_macro) donde también indicaremos el nombre de nuestra macro (NOMBRE\_MACRO):

```
[gcode_macro NOMBRE_MACRO]
gcode:
    codigo gcode
    ...
```

{% hint style="info" %}
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.
{% endhint %}

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

###


# Mallado de cama inteligente

{% hint style="warning" %}
IMPORTANTE!!!

En versiones de Klipper desde 26 de Enero de 2024 contamos con una nueva funcionalidad en el mallado de cama... el mallado adaptativo. Ya no necesitaremos macros o extensiones externas a Klipper para disponer de esta funcionalidad!!!

Podéis ver [**más información aquí**](/klipper/empezamos/malla-nivelacion-de-cama-klipper#bed-mesh-switchwire).
{% endhint %}

El mallado de nivelación de cama es un gran avance para corregir desviaciones en nuestra superficie de impresión pero en ocasiones se podría mejorar para que fuera más efectivo.

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/IexBU2YRmiAQ7mUf9Vtr/image.png" alt=""><figcaption></figcaption></figure>

Gracias a la versatilidad de Klipper podremos usar la siguiente macro que permitirá hacer un mallado de nuestra cama basada en el tamaño de la pieza que queramos imprimir, mejorando de esta forma el mallado y correcciones.

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/bv5FQ53syKnUn1Rm74GQ/image.png" alt=""><figcaption></figcaption></figure>

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/4h8hypeUUJ5MoF0dP63Y/image.png" alt=""><figcaption></figcaption></figure>

Además, este sistema nos permite:

* Reusar el mallado si el área de impresión es menor o igual que el anterior
* Tener en cuenta nuestros offsets del sensor
* Número de puntos por eje dinamico
* Compatible con sistemas de nivelación que usen sus propias macros como el Klicky

## Configuración

* Descargaremos e instalaremos la macro lanzando los siguientes comandos desde nuestro terminal SSH:

```bash
cd ~
git clone https://github.com/Turge08/print_area_bed_mesh.git
~/print_area_bed_mesh/install.sh
```

{% hint style="warning" %}
En el caso que usemos unos path/directorios diferentes a los normales es aconsejable revisar el script de instalación para adaptarlo a nuestras necesidades.
{% endhint %}

* Añadiremos esta macro en nuestro printer.cfg o cfg añadido como include que usemos para nuestras macros. Esta macro básicamente reemplazará a la macro BED\_MESH\_CALIBRATE usada por defecto

```django
[include print_area_bed_mesh.cfg]
```

* Añadiremos a nuestra configuración de Moonraker el update automático del repositorio para tener siempre actualizado de forma sencilla

{% code title="moonraker.conf" %}

```django
[update_manager print_area_bed_mesh]
type: git_repo
path: ~/print_area_bed_mesh
origin: https://github.com/Turge08/print_area_bed_mesh.git
is_system_service: False
```

{% endcode %}

{% hint style="warning" %}
Debemos asegurarnos que hemos realizado el primer paso antes o veremos un error en el apartado actualizaciones de nuestra UI.
{% endhint %}

Por último deberemos ajustar nuestro laminador y/o nuestra macro de inicio

* **Si usamos BED\_MESH\_CALIBRATE en nuestra macro de inicio** de impresión tendremos que reemplazar la llamada así:
  * ```
    BED_MESH_CALIBRATE PRINT_MIN={params.PRINT_MIN} PRINT_MAX={params.PRINT_MAX}
    ```
  * Si queremos forzar el mallado en cada impresión:
  * ```
    BED_MESH_CALIBRATE PRINT_MIN={params.PRINT_MIN} PRINT_MAX={params.PRINT_MAX} FORCE_NEW_MESH=True
    ```
  * Ajustaremos nuestro script de inicio de nuestro laminador

{% tabs %}
{% tab title="PrusaSlicer/SuperSlicer" %}
En el caso que actualmente usemos la macro START\_PRINT pasando temperaturas del estilo `START_PRINT BED_TEMP={material_bed_temperature_layer_0} EXTRUDER_TEMP={material_print_temperature_layer_0}.`

Tendremos que hacer algunos ajustes en la nueva macro y en START\_PRINT tal como vemos a continuación para adaptar el gcode de inicio con respecto a lo comentado inicialmente:

```gcode
START_PRINT EXTRUDER_TEMP={first_layer_temperature[initial_extruder] + extruder_temperature_offset[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]}
```

Con esta modificación desde START\_PRINT capturamos parámetros y llamamos a nuestra nueva macro de mallado.
{% endtab %}

{% tab title="IdeaMaker" %}

```
BED_MESH_CALIBRATE PRINT_MIN={print_pos_min_x},{print_pos_min_y} PRINT_MAX={print_pos_max_x},{print_pos_max_y}
```

{% endtab %}

{% tab title="Cura" %}

```
BED_MESH_CALIBRATE PRINT_MIN=%MINX%,%MINY% PRINT_MAX=%MAXX%,%MAXY%
```

{% hint style="info" %}
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 %}
{% endtabs %}

* **En el caso de que lancemos la macro** **BED\_MESH\_CALIBRATE directamente desde el gcode de inicio de nuestro laminador**

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

```
BED_MESH_CALIBRATE PRINT_MIN={first_layer_print_min[0]},{first_layer_print_min[1]} PRINT_MAX={first_layer_print_max[0]},{first_layer_print_max[1]}
```

{% endtab %}

{% tab title="IdeaMaker" %}

```
BED_MESH_CALIBRATE PRINT_MIN={print_pos_min_x},{print_pos_min_y} PRINT_MAX={print_pos_max_x},{print_pos_max_y}
```

{% endtab %}

{% tab title="Cura" %}

```
BED_MESH_CALIBRATE PRINT_MIN=%MINX%,%MINY% PRINT_MAX=%MAXX%,%MAXY%
```

{% endtab %}
{% endtabs %}

<br>


# Test de cinemática

Con esta macro podremos comprobar o hacer un test de stress/velocidad/aceleraciones de nuestros ejes X/Y.

{% embed url="<https://www.youtube.com/watch?app=desktop&v=zc_ZwB-K2kc>" %}

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


# Cambio Filamentos/M600

## VARIABLES GLOBALES

Esta macro nos va a permitir guardar una serie de valores y configuraciones que usaremos en el resto de macros.

{% hint style="warning" %}
Estas macros de cambio de filamentos ya no se mantienen/mejoran aunque deberían ser totalmente funcionales.

Os aconsejamos utilizar nuestro [bundle de macros Klipper](/klipper/mejoras/3dwork-klipper-bundle) del cual si que seguimos manteniendo y mejorando constantemente además de que mantenerlo al día en tu máquina va a ser más sencillo.
{% endhint %}

De esta forma, para ajustar alguno de estos parámetros y que se apliquen a todas las macros involucradas en un cambio de filamentos, estén ajustadas de forma automática, requiriendo el mínimo de ajuste extra.

{% hint style="danger" %}
Ajusta estas variables a tu máquina para un mejor resultado
{% endhint %}

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

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

**Para el correcto funcionamiento del resto de macros y dado que dependen de las variables globales definidas en la macro anterior es más que aconsejable asegurarse que estas variables están correctamente cargadas en tu Klipper**... de no hacerse tal como hemos comentado las macros siguientes no van a funcionar porque no recibirán los parámetros adecuados.

Una vez **recargada la configuración en Klipper y desde la Consola/Terminal lanzaremos la nueva macro ECHO\_VAR\_GLOBALS** y nos debería devolver todos los valores de esta. Debemos estar conectados a nuestra MCU para poder usar esta nueva macro.

<img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/Y13jrGSE0WZPkoVDDniF/image.png" alt="" data-size="original">
{% endhint %}

## CAMBIO FILAMENTOS

{% hint style="danger" %}
**Recuerda que si no tienes definida un pin de buzzer la macro BEEP te va a reportar un error, si no tienes buzzer te aconsejamos comentar esas lineas que usen la macro BEEP**
{% endhint %}

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

## SENSOR FILAMENTOS

{% hint style="warning" %}
En esta macro es **importante ajustar switch\_pin al alias o identificador del pin donde se encuentra la señal del sensor**.

En este caso dado que usamos alias se ha colocado el alias del pin.
{% endhint %}

```django
[filament_switch_sensor fsensor]
# EODET
switch_pin: FIL_RUNOUT0_PIN
pause_on_runout: False
event_delay: 3.0
runout_gcode:
   NOTIFY TEXT="Filamento no detectado"
   M601
insert_gcode:
   NOTIFY TEXT="Insertando filamento"
   LOAD_FILAMENT
```

## PARK

Utilizaremos esta macro para posicionar nuestro cabezal de impresión en una zona segura para realizar ciertas acciones.

{% hint style="info" %}
Esta macro usa variables globales:

* **z\_park**, que indica la distancia a subir el eje Z para una posición segura
* **retract\_length**, indicará cuanta retracción realizar
* **x\_park** e **y\_park**, las coordenadas XY donde posicionar el cabezal de forma segura y cómoda en el caso de necesitar manipularlo
  {% endhint %}

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

## PAUSE

Esta macro sobreescribe la macro PAUSE de sistema añadiendo más funcionalidad:

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

## RESUME

Al igual que la anterior, esta macro sustituye a la macro RESUME del sistema:

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

## CANCEL PRINT

En este caso sobreescribimos la macro CANCEL\_PRINT de sistema:

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


# Pausado en capa

Unas macros muy útiles y que normalmente podemos obtener de Mainsail son sus macros de pausado en capa:

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

Añadiendo estas macros obtendremos interesantes funciones para el pausado en capa para realizar ciertas acciones que no se puedan realizar mediante el laminador o simplemente porque se nos olvidaron aplicarlas al laminar:

* SET\_PAUSE\_NEXT\_LAYER, que indicando como parámetro la macro que queramos ejecutar nos pausará la impresión en el siguiente cambio de capa

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/grpypMa8DqNWi4N8V0DZ/image.png" alt=""><figcaption></figcaption></figure>

* SET\_PAUSE\_AT\_LAYER, podremos indicar en que capa queremos que se ejecute la pausa

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/QB4sdbz01DgEgH3wOquZ/image.png" alt=""><figcaption></figcaption></figure>


# CANbus

Guía completa de CANbus en Klipper: componentes, configuración de red CAN, Katapult, toolheads EBB, bridge mode con Octopus/Manta y actualización de firmware.

{% hint style="info" %}
**English**: Use your browser's built-in translation — Chrome and Edge detect the language automatically and offer to translate the page.
{% endhint %}

## Que es CANbus?

CANbus es un estándard utilizado para la comunicación de múltiples dispositivos y que se ha usado en automoción desde los años 90´s.

Puedes encontrar más información en la [**Wikipedia**](https://en.wikipedia.org/wiki/CAN_bus) **o revisar el siguiente video y esquema general de como funciona CANbux:**

{% tabs %}
{% tab title="Video" %}
{% embed url="<https://youtu.be/tN4qmdOxJNE?si=epWYIso5-Sq-n_BD>" %}
{% endtab %}

{% tab title="Esquema" %}
Esquema simplificado del cableado de un CANbus:

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/xLHPhBFcaEADOFkGe8c1/image.png)
{% endtab %}
{% endtabs %}

## Que mejoras puede aportar a las impresoras 3D?

El uso de CANbus puede aportar algunos beneficios en nuestras impresoras 3D:

* **Solo necesitas 4 cables hasta el cabezal de impresión**, (2 para 24v y 2 para datos) lo cual reduce el coste en cableado.
* Estos 4 cables solo llevan voltaje, por canbus la comunicación se hace por diferencia de potencial, se **evita cualquier tipo de interferencia o perdida por conexiones o campos electromagnéticos**, etc.
* Por ejemplo, si montas cualquier impresora, tipo Voron, Rat Rig **en vez de estar cableando 20 hilos al cabezal pasas esos 4, reduciendo peso en el gantry y problemas de falsos contactos a la larga y simplificando el mantenimiento/expansiones futuras a nivel de cableado**.
* El uso del **firmware/bootloader Katapult/CANboot simplifica el proceso de actualización de nuestros componentes CAN,** explicaremos más adelante esto.

Con todo esto si sumas los costes de cables que soporten altas temperaturas (PTFE), pcbs de conexión y tiempo de cableado, **merece la pena montar canbus sobretodo en según que tipo de máquinas o para expandir otras que están limitadas en el número de drivers o de pines de expansión**.

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/Hls8Dy1GWMn9ylxgj4Vo/image.png)

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/lzPkJGXM9ADSs7dUKIyV/image.png)

### Katapult (antiguamente CANboot)

Aunque ya lo adelantabamos antes el **uso de Katapult/CANboot puede simplificarnos más la gestión/actualización de nuestros componentes CAN**.

**Kataput/CANboot es un firmware/bootloader que nos va a permitir actualizar el firmware Klipper de nuestros componentes/toolheads desde el propio cableado CAN** sin necesidad de tener que usar cables USB.

En cualquier caso no es algo estrictamente necesario pero si al final optamos por utilizar CANbus en nuestra impresora es aconsejable implementarlo ya que nos va a facilitar la vida en la gestión de los dispositivos CAN.

## Necesito un CAN en mi máquina?

Aunque en el punto anterior os pusimos brevemente pros y contras del uso de CAN en nuestras máquinas me gustaría dar algunas explicaciones por las que creo que CAN NO es aconsejable en muchas situaciones.

Los **fabricantes como siempre quieren vender y los maker como nosotros en 3D probar cosas nuevas y el caso de las conexiones CAN bus es un claro ejemplo de ambas cosas**.

Para entender los siguientes razonamientos sobre CAN vs usar USB para expandir el sistema en la siguiente tabla podéis ver los puntos fuertes de cada tecnología:

| USB                                     | CAN                         |
| --------------------------------------- | --------------------------- |
| Plug\&Play (dependiendo del componente) | Redundancia                 |
| Baja latencia                           | Tolerancia a interferencias |
| Alto ancho de banda                     | Largas distancias           |

Algunas de las ventajas comentadas por parte de CANbus es su arquitectura donde mediante su cableado (bus, 2 cables) podemos crear una red de dispositivos pero... verdaderamente eso me beneficia en algo?

* normalmente en las electrónicas de nuestras impresoras no contamos con conectores T para crear estas conexiones
* la mayoría de electrónicas están pensadas para actuar como nodos terminales, no disponen de la opción de continuar el bus
* está pensado para solamente tener el toolhead.

En **impresoras con un host Klipper este es el cerebro y donde los beneficios de redundancia de CAN no van a aplicar además en esta arquitectura la latencia es crítica** por lo que la comunicación USB en lugar de CAN nos va a aportar más beneficios eliminando cuellos de botella que puedan limitar el funcionamiento de nuestra máquina.

Además **el uso de CAN require de un mayor uso de recursos de sistema para su gestión y un extra de complejidad en su configuración/mantenimiento dependiendo de como se implemente**.

En este escenario lo que **queremos diferenciar es el uso de CAN para su uso al conectar nuestra electrónica principal** y que esta pueda estar controlando el resto de componentes del bus como por ejemplo uno o más toolhead **o solo para la gestión de partes satélite de nuestra impresora dejando las controladoras principales usando USB/USART**.

Por otro lado estas expansiones de nuestra electrónica, como los toolhead, podemos utilizarlos en modo USB y cuando se discute entre CANbus y USB suelen salir los siguientes puntos de discusión:

* **Con USB necesitas más cables que con CANbus, si y no**... lo ideal y aconsejable desde nuestro punto de vista es el uso de un cable USB acorde con el uso y 2 cables de alimentación, algo que tampoco hace complicada la instalación ya que al final acaban siendo 3 cables vs 4 de CANbus dependiendo del tipo de cable que usemos. En cualquier caso con el uso de determinados cables se podría incluso llevar la alimentación a través de este mismo cable USB, algo que de nuevo no aconsejamos.
* **Los cables USB no están preparados para un sistema móvil como las impresoras 3D, rotundamente falso**... existen cables USB preparados sin problemas para entornos de este tipo además de aguantar la temperatura. Además que puedes montar cualquier cable que sea adecuado que disponga de 4 hilos y adaptar en cada extremo unos conectores USB de calidad DIY. Lo curioso de esta afirmación por parte de mucha gente que usa CANbus es que cuando les preguntas por las características del cable que usan en su instalación en la mayoría de casos estos cuentan con cables que tampoco están preparados para este uso en un entorno de impresora 3D.
* **Los cables USB no permiten cables largos o son proclives a interferencias, algo que no es cierto**... claro está usando cables de calidad y con unas longitudes conformes al estándar que dan sobradamente para cualquier impresora 3D

Creo que **CAN es una buena solución para determinadas máquinas donde, principalmente por su tamaño, reducir el cableado al toolhead supone una ventaja, si disponemos de multi tool, o aquellas que queramos ampliar las funciones de la electronica sin invertir en una nueva** tenemos otra opción a explorar aunque a veces puede ser más complicada de montar/mantener aunque sea muy "cool" decir que usamos CAN :smile:

Así que antes de aventuraros al mundo CAN me gustaría que pensarais el porqué verdaderamente necesitais CAN o no además de entender los pros y contras del uso del mismo.

## CAN en nuestra impresora

Si hemos llegado hasta aquí es porque tenemos claro que queremos implementar CAN a nuestra impresora. Para simplificar el proceso lo hemos dividido en 2 partes... una nueva instalación o si queremos actualizar nuestro CANbus.

<table data-card-size="large" data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-cover data-type="files"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td></td><td><strong>Nueva Instalación CAN</strong></td><td></td><td><a href="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FttrvFo6ZV9vYYdv457Gv%2FInstallCAN.png?alt=media&amp;token=085c93e9-1c3d-4a55-bc5f-ca34c5b86683">InstallCAN.png</a></td><td><a href="#instalacion-can-desde-0">#instalacion-can-desde-0</a></td></tr><tr><td></td><td>Actualizar CAN</td><td></td><td><a href="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FWmLneGgGV5a7Gz6qXe8R%2FUpdateCAN.png?alt=media&amp;token=00d815a7-ef79-4ccc-9d24-f491b426c7b0">UpdateCAN.png</a></td><td><a href="#actualizando-firmware-en-nuestros-dispositivos-can">#actualizando-firmware-en-nuestros-dispositivos-can</a></td></tr></tbody></table>

## Comandos de referencia rápida

Los comandos más usados en el día a día con CANbus en Klipper:

```bash
# Verificar que la interfaz CAN está activa
ip -s -d link show can0

# Buscar dispositivos CAN sin configurar (obtener UUID)
~/klippy-env/bin/python ~/klipper/scripts/canbus_query.py can0

# Poner un dispositivo en modo bootloader via CAN (para actualizar firmware)
~/klippy-env/bin/python ~/katapult/scripts/flashtool.py -i can0 -u <UUID> -r

# Flashear Klipper a un dispositivo via CAN (requiere Katapult en el dispositivo)
~/klippy-env/bin/python ~/katapult/scripts/flashtool.py -i can0 -u <UUID> -f ~/klipper/out/klipper.bin
```

| Comando                           | Cuándo usarlo                                                                     |
| --------------------------------- | --------------------------------------------------------------------------------- |
| `canbus_query.py can0`            | Primera puesta en marcha, tras resetear un dispositivo, cuando un UUID desaparece |
| `flashtool.py ... -r`             | Antes de actualizar Klipper en un dispositivo que ya tiene Katapult activo        |
| `flashtool.py ... -f klipper.bin` | Actualizar Klipper via CAN sin desmontar nada                                     |
| `ip -s -d link show can0`         | Verificar bitrate, estado y errores del bus CAN                                   |

***

## Instalación CAN desde 0

Si es la primera vez que instalamos CAN en nuestra máquina deberemos seguir los siguientes pasos.

### Red CAN

Para poder utilizar CAN en nuestra máquina y que nuestros dispositivos CAN puedan interactuar necesitamos habilitar un interfaz CAN en nuestro host Klipper.

Dependiendo del sistema operativo de nuestro host puede que la gestión de redes de este utilice los comandos de servicios de red ifupdown (es el "de toda la vida") o systemd-networkd... en nuestro caso os sugerimos realizar el proceso en ambos para asegurarnos que no tenemos problemas.

{% tabs %}
{% tab title="ifupdown" %}
Nos conectaremos a nuestro host por SSH y lanzaremos el siguiente comando para crear un fichero de configuración para nuestro interfaz `can0`, en nuestro caso usamos el editor de texto `nano` que suele venir instalado normalmente pero puedes utilizar el que te sea más cómodo:

```bash
sudo nano /etc/network/interfaces.d/can0
```

Ya en el editor copiaremos esta configuración:

<pre data-title="/etc/network/interfaces.d/can0"><code><strong>  allow-hotplug can0
</strong>  iface can0 can static
    bitrate 1000000
    up ip link set can0 txqueuelen 1024
</code></pre>

Os intentamos explicar para que sirve algunas partes de esta configuración:

* `allow-hotplug`, permite que ante un restart o reinicio de servicios los dispositivos CAN puedan volver a conectarse de forma automática
* `bitrate`, indica la velocidad de comunicación del interfaz CAN lo normal y aconsejable es utilizar 1000000 (1M) siempre que nuestros dispositivos CAN lo soporten y nos aseguraremos que a la hora de crear el firmware establezcamos este bitrate en sus opciones. De no hacerlo deberemos ajustar este valor al del dispositivo con el valor más bajo. Como veremos más adelante ajustar este parámetro correctamente es crucial para evitar cuellos de botella (por ejemplo si usamos acelerómetros o tiras led gestionadas por un dispositivo CAN) y problemas de comunicación.
* `txqueuelen`, se sugiere 1024 y básicamente permite crear una cola/buffer de gestión de mensajes que en caso de saturación permita evitar problemas de cuellos de botella con el típico error "Timer too close".

Una vez ya tenemos nuestro fichero de configuración para nuestra interfaz `can0` podemos reiniciar nuestro host con un `sudo reboot`
{% endtab %}

{% tab title="systemd-networkd" %}
En el caso que contemos con un sistema operativo para nuestro host, normalmente reciente, que funcione utilizando systemd-networkd (o netplan) el procedimiento es similar.

Nos conectaremos a nuestro host por SSH y lanzaremos el siguiente comando para crear un fichero de configuración para nuestro interfaz `10-can-link`, en nuestro caso usamos el editor de texto `nano` que suele venir instalado normalmente pero puedes utilizar el que te sea más cómodo:

```bash
sudo nano /etc/systemd/network/10-can.link
```

Ya en el editor copiaremos esta configuración:

{% code title="/etc/systemd/network/10-can.link" %}

```bash
  [Match]
  Type=can

  [Link]
  TransmitQueueLength=1024
```

{% endcode %}

En este fichero de configuración estableceremos el tipo de interfaz y el tamaño de la cola/buffer de mensajes tal como explicamos anteriormente en el proceso ifupdown.

De nuevo crearemos otro fichero de configuracion, en este caso llamado 25-can.network donde indiacremos el bitrate:

```bash
  sudo nano /etc/systemd/network/25-can.network
```

{% code title="/etc/systemd/network/25-can.network" %}

```bash
  [Match]
  Name=can*

  [CAN]
  BitRate=1M
```

{% endcode %}
{% endtab %}
{% endtabs %}

### Componentes CAN

Antes de continuar con los siguientes pasos os vamos a explicar de forma general los componentes de un CANbus.

#### Adaptador/Electrónica bridge CAN

Para que nuestro host pueda tener acceso a nuestra interfaz/red CAN necesitamos un dispositivo que haga de "puente" entre los dispositivos CAN y nuestro host. Normalmente disponemos de dos opciones:

* **Adaptadores CAN**, normalmente estos son unas pequeñas controladoras que disponen de conexión para cableado CAN y un interfaz USB para conectar a nuestro host Klipper.\
  Por ejemplo tenemos el Bigtreetech U2C que es uno de los que solemos aconsejar por la compatibilidad con diferentes tipos de conexiones, comunidad/soporte/documantación y calidad/precio.

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FI48sLJ1Wj1IeD4CDmWjh%2Fimage.png?alt=media&amp;token=ccc7f4c3-cddd-4d7d-9863-1233fc7d9943" alt="" width="375"><figcaption><p>Diagrama de conexión CAN utilizando un adaptador USB CAN (Bigtreetech U2C)</p></figcaption></figure>

* **Electrónicas con CAN/bridge**, también recientemente se ha extendido por parte de los fabricantes añadir conexiones CAN en las electrónicas. En este caso tenemos que distinguir aquellas que disponen CAN para ser utilizadas como un dispositivo o aquellas que disponen CAN bridge con un transceiver CAN que nos va a hacer de "puente" entre los dispositivos CAN y nuestro host Klipper.\
  En este caso las electrónicas Bigtreetech de nuevo dan soporte en muchos de sus modelos (Octopus/Manta/Kraken) a CAN/bridge.\
  En este caso si queremos habilitar CAN en nuestra instalación y nuestra electrónica dispone de opciones de CAN/bridge con transceiver no será necesario del uso de un adaptador CAN extra.

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FJpYLbGbsLb5TFWE4pn4o%2Fimage.png?alt=media&amp;token=474e25f1-1144-4b52-8905-91e8c4f57017" alt="" width="375"><figcaption><p>Diagrama de conexión CAN utilizando una electrónica como CAN bridge (Bigtreetech Octopus)</p></figcaption></figure>

#### Toolheads

Normalmente el uso de CAN en las impresoras 3D tiene sentido para colocar una electrónica en el cabezal de impresión para reducir la cantidad de cableado.

En este caso disponemos de controladoras/electrónicas específicamente diseñadas para ello de diferentes marcas como Bigtreetech, Fysetc, Mellow y que con los diferentes modelos y versiones se acaptan a practicamente cualquier cabezal de impresión

### Adaptador CAN

Ahora que explicamos los diferentes componetes CAN y en especial los adaptadores CAN vamos a continuar con la configuración de estos donde tenemo dos opciones:

<table data-card-size="large" data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-cover data-type="files"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td></td><td><strong>Adaptador CAN USB</strong></td><td></td><td><a href="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FjzFXoRj6qcZiI77SpUlj%2FCANAdapter.png?alt=media&amp;token=f36cce74-b2ee-4c42-9bfe-c486f7831361">CANAdapter.png</a></td><td><a href="#adaptador-can-usb-como-interfaz-can">#adaptador-can-usb-como-interfaz-can</a></td></tr><tr><td></td><td><strong>Electrónica CAN/bridge</strong></td><td></td><td><a href="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FeRLWqGPAjW6c4CPChIHX%2FCANMaingoard.png?alt=media&amp;token=1fb74bfb-147f-4a1d-948d-57de9bd58042">CANMaingoard.png</a></td><td><a href="#electronica-can-bridge-como-interfaz-can">#electronica-can-bridge-como-interfaz-can</a></td></tr></tbody></table>

#### Adaptador CAN USB como interfaz CAN

Tal como os hemos comentado estos adaptadores se suelen conectar por USB a nuestro host y nos permiten que este pueda "hablar" con los dispositivos CAN a través de nuestra red CAN que montamos en pasos anteriores.

Al conectarse estos mediante USB una forma sencilla para detectar si estos fueron detectados por el sistema es lanzando el comando `lsusb` desde SSH y veremos un dispositivo con una descripción `OpenMoko, Ink`, `Geschwister Schneider CAN adapter` o similares.

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FDDsMDqKIu4MK3f1YJRDc%2Fimage.png?alt=media&amp;token=945c8df6-2103-4fd6-a0f6-bbf56dd8c053" alt=""><figcaption></figcaption></figure>

Si vemos que nuestro adaptador CAN fué detectado el siguiente paso será configurar que nuestro interfaz CAN, el cual configuramos previamente está levantado y funcionando correctamente, mediante el siguiente comando:

```bash
ip -s -d link show can0
```

Deberemos ver algo similar a la siguiente captura donde podremos ver los parámetros de bitrate y cola/buffer que configuramos en el interfaz:

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FEJia6ytd5KL6SrGzaAOl%2Fimage.png?alt=media&amp;token=7e99149d-0cbe-40e4-87f1-5757f70cc754" alt=""><figcaption></figcaption></figure>

{% hint style="warning" %}
Si no detectamos nuestro adaptador USB CAN o tenemos problemas con el interfaz:

* es posible que el firmware del adaptador no sea el correcto, este dañado o falle el dispositivo. En este caso os aconsejamos ir al Github o repositorio del fabricante del mismo para aplicar de nuevo el firmware actualizado.
* en algunos casos podemos ver fallow del interfaz arriba o abajo, normalmente también suele estar relacionado con problemas de firmware en el adaptador
  {% endhint %}

A continuación os damos información de algunos de los adaptadores USB más comunes:

{% tabs %}
{% tab title="Bigtreetech U2C" %}
Dependiendo del modelo de U2C contamos con opciones de varios buses CAN usando USB los cuales podéis ver en el siguiente esquema, es importante recordar que cada uno de ellos tienen su propio terminador en forma de jumper y sus jumpers VUSB1 y 2 para el control de la alimentacion reversa en esos USB.

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/Kh5uoNXzdJ8z2OlfIco7/image.png)

En la siguiente imagen os aconsejamos prestar especial atención a los jumpers de terminación CAN (120R) y su ubicación dependiendo del o los buses que utilicemos en nuestro caso.

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/FqmhwXThuvj5pAGT8StJ/image.png)

También en el caso de utilizar los buses USB (VBUS1-2) disponemos unos jumpers para evitar la retroalimentación de 5V

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/ry8WSdyM3sDLH7b4vpIM/image.png)

En el siguiente esquema podéis ver mejor a que conexión corresponde cada uno de los conectores CAN disponibles en nuestra U2C.

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/Gz8ZrYK6luagE8OsnoqI/image.png)

**Firmware,** módulo U2C de Bigtreetech usa CandeLight que es un firmware open source que podéis encontrar [**aquí**](https://github.com/candle-usb/candleLight_fw). Os recordamos el el U2C usa una MCU STM32F072C8.

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/Nj59WMwkM1rYQC0mQp4K/image.png)

Para actualizar el firmware con el módulo sin alimentación pulsaremos el botón BOOT y conectaremos el cable USB C para entrar en modo DFU. Con STM32CubeProgrammer actualizaremos el firmware.

{% hint style="info" %}
También tenéis una forma alternativa para actualizar usando esta web que, si os funciona, es una forma bastante sencilla:

<https://canable.io/updater/canable2.html>
{% endhint %}

{% hint style="warning" %}
**U2C v2.1!!!!**

Para poder usar correctamente esta versión de U2C es aconsejable utilizar el firmware que podéis encontrar [**aquí**](https://github.com/Esoterical/voron_canbus/tree/main/can_adapter/BigTreeTech%20U2C%20v2.1) ya que aparentemente el **proporcionado por el fabricante con las versiones de Klipper actuales no funciona correctamente**.

El proceso es el mismo para poner el U2C en modo DFU y comprobar con `dfu-util -l`

<img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2Fe2LDgGR0X6FteLlbfvUY%2Fimage.png?alt=media&amp;token=ef1b63de-45d9-400f-9514-b3e102d41b6d" alt="" data-size="original">

Aplicamos el firmware con `dfu-util -D ~/G0B1_U2C_V2.bin -a 0 -s 0x08000000:leave`

<img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FE7zTEz02Bb384EPg43AW%2Fimage.png?alt=media&amp;token=9029c0c8-7507-4f20-a043-e6406d4395a7" alt="" data-size="original">

El error de `get-status` no suele afectar. Una vez aplicado desconectamos y volvemos a conectar el U2C y ya deberiamos tener visible nuestro interfaz `can0` (si hemos configurado correctamente el interfaz `/etc/network/interfaces.d/can0`)
{% endhint %}
{% endtab %}

{% tab title="Mellow UTC" %}
Otro adaptador USB popular es el Mellow UTC.

En este caso cuenta con la resistencia de terminación (120R) directamente soldada por lo que no es necesario ningún jumper.

Aunque el adaptador viene con el firmware pre-instalado puede ser útil tener el siguiente procedimiento a mano para actualizar o restaurar el firmware.

Tenéis el [proceso descrito en detalle en la Wiki de Mellow ](https://mellow-3d.github.io/fly-utoc_firmware.html#flashing-utoc-firmware)y podéis descargar la última versión del firmware desde [aquí](https://mellow-3d.github.io/files/utoc_firmware.bin).

Para actualizar el firmware, y con todas las conexiones retiradas, pondremos el jumper DFU tal como podeis ver en la siguiene imagen:

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FTVWNhtqxTbOmZu3czLum%2Fimage.png?alt=media&amp;token=d63df452-6c67-489b-8721-59fdf99cdf93" alt=""><figcaption></figcaption></figure>

Conectaremos el adaptador Mellow UTC a nuestro host Klipper con un cable USB-C y lanzaremos el comando `lsusb` que dentro de la lista de dispositivos debería listarnos uno con las siguientes características:

```
Bus 001 Device 004: ID 0483:df11 STMicroelectronics STM Device in DFU Mode
```

A continuación y con el firmware descargado del link que os facilitamos anteriormente copiado en nuestro host Klipper actualizaremos con el siguiente comando:

```bash
sudo dfu-util --dfuse-address -d 0483:df11 -c 1 -i 0 -a 0 -s 0x08000000 -D ~/utoc_firmware.bin
```

**Conexión de nuestra controladora UTOC:**

* USB de nuestra PI a nuestra controladora UTOC
* H en UTOC a H en nuestra SHT o Toolhead
* L en UTOC a L en nuestra SHT o Toolhead
* 24V de nuestra fuente a nuestra UTOC
* GND de nuestra fuente a nuestra UTOC
* 24 de nuestra UTOC a 24 en nuestra SHT o Toolhead
* GND de nuestra UTOC a GND en nuestra SHT o Toolhead

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/3jacQnEJ39u04AWiiicn/image.png)
{% endtab %}

{% tab title="Waveshare Raspberry Pi CAN" %}
El adaptador Waveshare Raspberry Pi CAN hat conectable directamente al gpio o mediante cableado a través de los puertos SPI y UART.

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/PTs9uhrRehq5dXtI5ndD/image.png)

El puerto en la Raspberry Pi se utiliza para la salida de la consola de Linux de forma predeterminada, por lo que necesitamos desactivarlo primero:

* Ejecute Comando para abrir RASPI-CONFIG:

```bash
sudo raspi-config
```

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/B0OiibBgVuHogvTiYMYo/image.png)

* Elija Interfacing Options -> Serial -> No

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/FPnddIg2QxxKTI6t8TZy/image.png)

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/LsyHPJ4fEsk39uaYogun/image.png)

* Abra el archivo /boot/config.txt, agregue la siguiente línea:

```bash
enable_uart=1
```

* Para Raspberry PI, el puerto serie se utiliza para Bluetooth, está línea tiene que estar comentada:

```bash
#dtoverlay=pi-minuart-b
```

* Definimos la configuración del puerto CAN bus.

  Añadimos la siguiente línea en el archivo /boot/config.txt según las dos versiones disponibles. La única diferencia entre estas versiones es la frecuencia del oscilador de cristal.

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/cnMdllwcNIWVU903dU87/image.png)

```bash
// Si tenemos el cristal de 8Mhz
dtoverlay=mcp2515-
can0,oscillator=8000000,interrupt=25,spimax
frequency=1000000
// Si tenemos el cristal de 12Mhz
dtoverlay=mcp2515-
can0,oscillator=12000000,interrupt=25,spi
maxfrequency=2000000
```

{% endtab %}
{% endtabs %}

Una vez tenemos detectado nuestro adaptador y el interfaz está levantado podemos continuar con la [configuración de nuestro toolhead.](#toolheads-hotend-canbus)

#### Electrónica CAN/bridge como interfaz CAN

Tal como os comentamos anteriormente podemos utilizar nuestra electrónica de control de la impresora como adaptador CAN siempre que esta lo soporte, en concreto hemos de fijarnos en electrónicas que soporten CAN/bridge e integren un transceptor CAN.

Antes de comenzar con el proceso es aconsejable asegurarnos que nuestro sistema instalado en el host disponga de todas las dependencias instaladas, para ello lanzaremos:

```bash
sudo apt update
sudo apt upgrade
sudo apt install python3 python3-pip python3-can
pip3 install pyserial
```

**Instalación de Katapult/CANboot en electrónica de control**

Aunque no es algo obligatorio si que es algo que os aconsejamos el uso de Katapult si optáis por montar CAN en vuestra máquina... os va a facilitar mucho algunos procesos.

El primer paso será clonar el repositorio de Katapult:

```bash
test -e ~/katapult && (cd ~/katapult && git pull) || (cd ~ && git clone https://github.com/Arksine/katapult) ; cd ~
```

El siguiente paso será crear nuestro firmware Katapult para nuestra electrónica, lanzaremos los siguientes comandos:

```bash
cd ~/katapult
make menuconfig
```

{% hint style="warning" %}
**Los siguientes pasos son un ejemplo, deberás de ajustar las opciones dependiendo de tu electrónica. A modo de ejemplo al finalizar esta sección os facilitamos las configuraciones para las electrónicas más comunes.**

**Recuerda que no nos hacemos responsables de ningún problema o daño que se pueda ocasionar a tu electrónica... tú eres el único responsable de lo que haces.**
{% endhint %}

Y ajustaremos las opciones para nuestra electrónica, en nuestro caso:

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FWrqC7kwVqBz71795hopg%2Fimage.png?alt=media&amp;token=e11280b1-f448-42d8-9f9e-a2e420f855df" alt=""><figcaption></figcaption></figure>

Saldremos (Q) guardando cambios (Y), **pondremos nuestra electrónica en modo DFU** y con el comando sudo `dfu-util -l`del resultado del comando anterior prestaremos especial atención al **ID del dispositivo (0483:df11) y al valor de Internal Flash (0x08000000)** ya que los vamos a necesitar en pasos siguientes:

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FSLFJ96l6ahFQWw01O2J3%2Fimage.png?alt=media&amp;token=a5358505-3738-40b0-a80a-cee38efe8414" alt=""><figcaption></figcaption></figure>

Ahora ya tenemos todo para compilar y aplicar lanzando los siguientes comandos ajustando el valor de -s al valor de Internal Flash obtenido anteriormente, y el valor de -d al ID del dispositivo también del paso anterior:

```bash
cd ~/katapult
make
sudo dfu-util -R -a 0 -s 0x08000000:leave -D ~/katapult/out/katapult.bin -d 0483:df11
```

{% hint style="info" %}
Dependiendo del entorno o estado de la electrónica puede ser necesario aplicar el firmware forzando que se aplique:

`sudo dfu-util -a 0 -D ~/katapult/out/katapult.bin --dfuse-address 0x08000000:force:mass-erase -d 0483:df11`
{% endhint %}

Puede que al final del proceso veamos un error en la linea dfu-util, no pasa nada mientras que File downloaded sea <mark style="color:green;">**successfully**</mark>.

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FhHRf2URG6bDzimcpjwpN%2Fimage.png?alt=media&amp;token=fdac76c0-8f32-489d-bed1-7acc7d2479b4" alt=""><figcaption></figcaption></figure>

Para verificar que todo ha ido correctamente saldremos del modo DFU de la electronica, mediante un reset de esta o retirando un jumper dependiendo de cada electrónica, y lanzaremos el comando `ls /dev/serial/by-id` que nos debería retornar un dispositivo conectado que el inicio del nombre sea `usb-katapult`...

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2Fj3C1hiUsL0hyIN054KGN%2Fimage.png?alt=media&amp;token=6b8efe85-8b2d-4886-b3b5-81e0a1c4839a" alt=""><figcaption></figcaption></figure>

Ahora que ya tenemos nuestro bootloader Katapult aplicado en nuestra electrónica el siguiente paso es **generar y aplicar el firmware Klipper** a esta.

Para ello no nos vamos a extender en esta parte y os aconsejamos seguir las instrucciones normales de Klipper para vuestra electrónica pero muy importante asegurarnos que indicamos como `Communication interface` a `USB to CAN bus bridge` en los pines correctos (en nuestro ejemplo USB on PA11/PA12) de esta y ajustar `CAM bus speed` a la velocidad que ajustamos en la configuración de nuestro interfaz CAN, en nuestro caso 1000000 (1M).

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FfMLoZlecUIjlGUypHFsY%2Fimage.png?alt=media&amp;token=9ad8a5a5-fb0d-42f9-b732-feccec65e0a8" alt=""><figcaption></figcaption></figure>

También podremos reallizar este proceso utilizando Katapult, una vez configurado y compilado el firmware tal como explicamos en el paso antrior, para ello y por seguridad vamos a detener el servicio Klipper con el comando `sudo service klipper stop` y seguidamente `ls /dev/serial/by-id/` para obtener el ID de nuestro dispositivo Katapult, nuestra electrónica en este caso:

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FVGTV2lBz9EBT6vvaV0ud%2Fimage.png?alt=media&amp;token=02856efb-7a91-4f93-b73b-345437db34f5" alt=""><figcaption></figcaption></figure>

Y con el siguiente comando, donde usaremos nuestro ID obtenido en el paso anterior, podremos aplicar el firmware Klipper de forma directa:

```bash
python3 ~/katapult/scripts/flashtool.py -f ~/klipper/out/klipper.bin -d /dev/serial/by-id/usb-katapult_rp2040_E6613893F5D7224-if00
```

El siguiente paso a realizar sería obtener el UUID de nuestra electrónica que tenéis explicado [aquí](#encontrar-el-canbus_uuid-para-nuevas-mcus) y continuar con el siguiente paso que es preparar nuestro [toolhead](#toolheads-can).

A continuación os facilitamos información de las más comunes/usadas:

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

* **no nos hacemos responsables de ningún problema o daño que se pueda ocasionar a tu electrónica... tú eres el único responsable de lo que haces**
* **antes de aplicar ninguna configuración descrita en los siguientes pasos verifica con la documentación del fabricante que los valores/configuraciones son correctas para tu caso**
  {% endhint %}

{% tabs %}
{% tab title="BTT Kraken" %}

* Configuración para Katapult/Canboot

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2F598rmbmA0b8MVVSN9PHr%2Fimage.png?alt=media&amp;token=9a368802-c4ce-4a3a-a7a4-aa09c62d6ab1" alt=""><figcaption></figcaption></figure>

* Configuración CAN/bridge

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FfMLoZlecUIjlGUypHFsY%2Fimage.png?alt=media&amp;token=9ad8a5a5-fb0d-42f9-b732-feccec65e0a8" alt=""><figcaption></figcaption></figure>

* DFU, mientras presionamos el boton BOOT0 pulsamos una vez el botón RESET y soltamos el boton BOOT0 a los 5s

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FBXNbiVqSHTppjciX0Eko%2Fimage.png?alt=media&amp;token=7d9532c0-7073-47f4-87aa-0ea53c1a1094" alt=""><figcaption></figcaption></figure>

* 120R, resistencia de terminador CAN

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FAvY9xAq4iEkpvSDtp4cR%2Fimage.png?alt=media&amp;token=55705e35-60e3-4840-ad08-ce4e7a1cc036" alt=""><figcaption></figcaption></figure>
{% endtab %}

{% tab title="BTT Manta" %}
**Bigtreetech Manta M8P v2.0**

* Configuración para Katapult/Canboot

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FcFkJJgfMlQ7532iuwYLy%2Fimage.png?alt=media&amp;token=de883bf1-f162-4eb9-b72c-46e4c9e90ada" alt=""><figcaption></figcaption></figure>

* Configuración CAN/bridge

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FN4OobnhoYxi93YtC1zE2%2Fimage.png?alt=media&amp;token=2b68e8dd-881c-4a5a-86cc-de550e441512" alt=""><figcaption></figcaption></figure>

* 120R, resistencia de terminador CAN

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FYP5HgORCsG5KSQjLxBtE%2Fimage.png?alt=media&amp;token=fe53b620-e857-40fc-90dc-f3846ec6cb6c" alt=""><figcaption></figcaption></figure>

**Bigtreetech Manta M8P v1.1**

* Configuración para Katapult/Canboot

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FMHRg1vk3NixWQc7Yqvwk%2Fimage.png?alt=media&amp;token=d5782660-d96f-483a-9097-437a8cc2a771" alt=""><figcaption></figcaption></figure>

* Configuración CAN/bridge

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FJxyasmgwHLnqHiikJKaH%2Fimage.png?alt=media&amp;token=b7848881-a1ac-45d6-92f5-fd81500537fa" alt=""><figcaption></figcaption></figure>

* 120R, resistencia de terminador CAN

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FOpvTSyOAalsAbeOe7Ia3%2Fimage.png?alt=media&amp;token=a2dc5035-e2f1-4c07-bc1c-c72442add747" alt=""><figcaption></figcaption></figure>

**Bigtreetech Manta M5P v1.0**

* Configuración para Katapult/Canboot

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2F8nED3ydgtNvTVlonUuUc%2Fimage.png?alt=media&amp;token=5c0dc720-dbf9-46b3-aa48-297826e26941" alt=""><figcaption></figcaption></figure>

* Configuración CAN/bridge

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FBfdylQcAXEDHHXLfIR7e%2Fimage.png?alt=media&amp;token=c7b9c95f-b089-4cf8-a22e-057feeef8085" alt=""><figcaption></figcaption></figure>

* DFU, mientras presionamos el boton BOOT0 pulsamos una vez el botón RESET y soltamos el boton BOOT0 a los 5s

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2F18Y6DmzczxHfamwymn1w%2Fimage.png?alt=media&amp;token=9b4a5bb2-79b0-4863-826b-d6bb395aed6d" alt=""><figcaption></figcaption></figure>

* 120R, resistencia de terminador CAN

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FymjbPzim42IMN4EHKVKy%2Fimage.png?alt=media&amp;token=071a9f82-9612-49c9-b42c-14d3782f81cc" alt=""><figcaption></figcaption></figure>

**Bigtreetech Manta E3EZ**

* Configuración para Katapult/Canboot

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FrqAzv5aWGkKLZevNY9CO%2Fimage.png?alt=media&amp;token=f65a33d7-f974-414a-b93d-c6def8743f97" alt=""><figcaption></figcaption></figure>

* Configuración CAN/bridge

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FSa9F8rhqbTlGJu1XblWE%2Fimage.png?alt=media&amp;token=fafb71ec-0be4-4479-943c-298eac315fee" alt=""><figcaption></figcaption></figure>

* 120R, resistencia de terminador CAN

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FrhYD7I3dRKHd2hJoavpL%2Fimage.png?alt=media&amp;token=a295aab5-3866-4415-bfed-09587e4fa1e3" alt=""><figcaption></figcaption></figure>
{% endtab %}

{% tab title="BTT Octopus" %}
**Bigtreetech Octopus Max EZ**

* Configuración para Katapult/Canboot

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FlIryMwZ5KstSDfj5cBss%2Fimage.png?alt=media&amp;token=bf75b46f-a771-4058-8ac9-b8af6fb2d86a" alt=""><figcaption></figcaption></figure>

* Configuración CAN/bridge

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2F9B9NOgzaKFtW3vkDFMzE%2Fimage.png?alt=media&amp;token=c4813711-0570-4d2b-894f-bf3c92bdfe79" alt=""><figcaption></figcaption></figure>

* 120R, resistencia de terminador CAN

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FUFXFTb76hFGTVMFgz20u%2Fimage.png?alt=media&amp;token=bdb25eb9-6607-4924-a907-350235ef7cad" alt=""><figcaption></figcaption></figure>

**Bigtreetech Octopus**

* Configuración para Katapult/Canboot

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FJ6FTIQ92EYkWIxUuVIaB%2Fimage.png?alt=media&amp;token=5832b601-9ae8-49f1-a4b7-e92f015c1689" alt=""><figcaption><p>MCU STM32F446</p></figcaption></figure>

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FO7Bgbzmi3zGIf105crje%2Fimage.png?alt=media&amp;token=62340b43-3c7a-4613-a8cd-72dfa5c24b8b" alt=""><figcaption><p>MCU STM32F429</p></figcaption></figure>

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FXowRd480ma2tJv9EE7rw%2Fimage.png?alt=media&amp;token=61f32d87-6744-4ac7-8660-e319b501fec0" alt=""><figcaption><p>MCU STM32F407</p></figcaption></figure>

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2F79gG4hAcgBHJReakcQqH%2Fimage.png?alt=media&amp;token=dfdf85cb-cebe-4e2d-9f5e-e4972a4c1af2" alt=""><figcaption><p>MCU STM32H723</p></figcaption></figure>

* Configuración CAN/bridge

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FAoxF2fx6ZGlLGtrRnP1u%2Fimage.png?alt=media&amp;token=0d4666fa-a81f-4323-8d61-9af0ebf7ccb1" alt=""><figcaption><p>MCU STM32F446</p></figcaption></figure>

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FXdtlPdr6F3DRIyOIa7ds%2Fimage.png?alt=media&amp;token=1890c686-e02f-4ae4-95ca-42f20817783c" alt=""><figcaption><p>MCU STM32F429</p></figcaption></figure>

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FjOmcM4BFuGPrRLPugKeW%2Fimage.png?alt=media&amp;token=a16ddb2a-a597-4ffd-8ec4-c5ede7c82a04" alt=""><figcaption><p>MCU STM32F407</p></figcaption></figure>

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FGoDuBuivyFNSjrWQTGT0%2Fimage.png?alt=media&amp;token=90349df2-9d66-4529-8915-cf3fcea11884" alt=""><figcaption><p>MCU STM32H723</p></figcaption></figure>

* DFU, en este caso necesitaremos colocar un jumper en el pin marcado en púrpura/morado y presionaremos el botón de RESET (verde). Usaremos el jumper marcado en azul para indicar si la electrónica se alimenta por USB o la fuente de la impresora.

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FsCz1SoMSncwhxonEYPoN%2Fimage.png?alt=media&amp;token=7314bc81-109e-4d57-90d7-9990c37be761" alt=""><figcaption></figcaption></figure>
{% endtab %}

{% tab title="SKR 3" %}
**Bigtreetech SKR 3 / 3 EZ**

* Configuración para Katapult/Canboot

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FpGLVmtoO5lPrdJqNYYIu%2Fimage.png?alt=media&amp;token=1d55e547-ec0d-4f17-8d9c-ac3fdab0954d" alt=""><figcaption></figcaption></figure>

* Configuración CAN/bridge

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FCAKwLep3vOzFHn9gfSV0%2Fimage.png?alt=media&amp;token=0def7f4d-7a0e-4f9b-b46b-2a7b19f9f28e" alt=""><figcaption></figcaption></figure>
{% endtab %}

{% tab title="Fysetc Spider" %}
**Fysetc Spicer v3.0**

* Configuración para Katapult/Canboot

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FGzyErEqyRU4aFeHhKejB%2Fimage.png?alt=media&amp;token=9e4f3868-0029-40e4-b7f7-4c095a9e60fa" alt=""><figcaption></figcaption></figure>

* Configuración CAN/bridge

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FBrHlm3vQ68nGQ76RJ9R4%2Fimage.png?alt=media&amp;token=59323e61-3a15-47f2-b4cf-cb483ab9c04b" alt=""><figcaption></figcaption></figure>

* DFU, pulsaremos el boton BT0 y con este pulsado haremos una pulsacion en el RST esperando 5s hasta soltar el BT0

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2F6ri9Ay795SQsUZARWhRY%2Fimage.png?alt=media&amp;token=2bc5bd3c-4395-48f2-95ca-c7bc33efdf52" alt=""><figcaption></figcaption></figure>

{% hint style="warning" %}
Los **siguientes modelos de Fysetc Spider no incorporan un transceptor** **CAN** por lo que ha de añadirse de forma externa como un TJA1050.

<img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FVtVNEgE3plhITAfojb60%2Fimage.png?alt=media&amp;token=5ad3d36c-95ff-4c3b-b04f-084bbd0394a1" alt="" data-size="original">

Os daremos una sugerencia en cada caso de como conectarlo a la electrónica.
{% endhint %}

**Fysetc Spicer v2.3**

* Configuración para Katapult/Canboot

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FkQzYuZ21KfEZWXV7sOMO%2Fimage.png?alt=media&amp;token=4f49b980-fd61-4f9a-87d0-a78f85dba0ea" alt=""><figcaption></figcaption></figure>

* Configuración CAN/bridge

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2F45FJJQAmkdF5YhXPqvzI%2Fimage.png?alt=media&amp;token=bc2fcf1b-569b-4b0a-8ece-d2a98f4a2ae1" alt=""><figcaption></figcaption></figure>

* Transceptor externo, TJA1050, conectaremos el CAN Rx/Tx a los pines PD0/PD1 del conector CAN que cuenta la electrónica y 5v/GND para alimentar el transceptor

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FAvufO7aKEl0aFVpEgxZn%2Fimage.png?alt=media&amp;token=e2474d21-2d29-461e-9a23-33b317c2d887" alt=""><figcaption></figcaption></figure>

**Fysetc Spicer v2.2**

* Configuración para Katapult/Canboot

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FGzyErEqyRU4aFeHhKejB%2Fimage.png?alt=media&amp;token=9e4f3868-0029-40e4-b7f7-4c095a9e60fa" alt=""><figcaption></figcaption></figure>

* Configuración CAN/bridge

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2F7zegRHEVqRyX8iUpCtA1%2Fimage.png?alt=media&amp;token=0ebcf801-b80f-4d1a-8874-55e788082107" alt=""><figcaption></figcaption></figure>

* Transceptor externo, TJA1050, conectaremos el CAN Rx/Tx a los pines PD0/PD1 del conector CAN que cuenta la electrónica y 5v/GND para alimentar el transceptor

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FhEdlUkxcKtbnX7xCCbQB%2Fimage.png?alt=media&amp;token=2d8ce40f-e463-4c8e-96f3-fd26e3407912" alt=""><figcaption></figcaption></figure>

**Fysetc Spicer v1.0**

* Configuración para Katapult/Canboot

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FGzyErEqyRU4aFeHhKejB%2Fimage.png?alt=media&amp;token=9e4f3868-0029-40e4-b7f7-4c095a9e60fa" alt=""><figcaption></figcaption></figure>

* Configuración CAN/bridge

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FyPFSVcULQlAZp4ptQjmp%2Fimage.png?alt=media&amp;token=07738d8a-30ec-4e25-b29d-7695e4fce791" alt=""><figcaption></figcaption></figure>

* Transceptor externo, TJA1050, conectaremos el CAN Rx/Tx a los pines PD0/PD1 del conector CAN que cuenta la electrónica y 5v/GND para alimentar el transceptor

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2F9ru2Qm7Hv2dMAT3GSArh%2Fimage.png?alt=media&amp;token=6fe51fd2-da79-4d0b-9ff1-3403164ebfaf" alt=""><figcaption></figcaption></figure>
{% endtab %}
{% endtabs %}

### Dónde conseguir los componentes CAN

{% tabs %}
{% tab title="BTT EBB36 / EBB42 CAN toolboard" %}
{% embed url="<https://s.click.aliexpress.com/e/182731559?productUrl=https://www.aliexpress.com/item/1005006210646037.html>" %}
{% endtab %}

{% tab title="BTT U2C v2.1 (adaptador USB-CAN)" %}
{% embed url="<https://s.click.aliexpress.com/e/182731559?productUrl=https://www.aliexpress.com/item/1005004243282918.html>" %}
{% endtab %}
{% endtabs %}

{% hint style="info" %}
Si utilizas los links de compra, el precio del producto será el mismo que si accedes de manera habitual, pero a 3DWork le quedará una pequeña comisión. Algo que nos ayudará a soportar el proyecto y continuar generando contenido.
{% endhint %}

### ToolHeads CAN

Antes de comenzar con el proceso es aconsejable asegurarnos que nuestro sistema instalado en el host disponga de todas las dependencias instaladas, para ello lanzaremos:

```bash
sudo apt update
sudo apt upgrade
sudo apt install python3 python3-pip python3-can
pip3 install pyserial
```

**Instalación de Katapult/CANboot en Toolhead**

Aunque no es algo obligatorio si que es algo que os aconsejamos el uso de Katapult si optáis por montar CAN en vuestra máquina... os va a facilitar mucho algunos procesos.

El primer paso será clonar el repositorio de Katapult:

```bash
test -e ~/katapult && (cd ~/katapult && git pull) || (cd ~ && git clone https://github.com/Arksine/katapult) ; cd ~
```

{% hint style="info" %}
Los pasos anteriores no son necesarios si ya los hemos previamente al utilizar nuestra electrónica como adaptador CAN ya que durante los pasos de puesta en marcha explicados anteriormente ya se han realizado.
{% endhint %}

El siguiente paso será crear nuestro firmware Katapult para nuestra electrónica, lanzaremos los siguientes comandos:

```bash
cd ~/katapult
make menuconfig
```

{% hint style="warning" %}
**Los siguientes pasos son un ejemplo, deberás de ajustar las opciones dependiendo de tu toolhead. A modo de ejemplo al finalizar esta sección os facilitamos las configuraciones para los toolhead más comunes.**

**Recuerda que no nos hacemos responsables de ningún problema o daño que se pueda ocasionar a tu electrónica... tú eres el único responsable de lo que haces.**
{% endhint %}

Y ajustaremos las opciones para nuestro toolhead, en nuestro caso:

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FNEAVUx5aPCNBprwe3XFr%2Fimage.png?alt=media&amp;token=d5e8fb5f-376a-4024-acc3-494d8354ea2a" alt=""><figcaption><p>Ejemplo configuración toolhead</p></figcaption></figure>

Saldremos (Q) guardando cambios (Y).

Normalmente los toolhead cuentan con MCU STM32xxx o con RP2040, en este caso los siguientes pasos varían dependiendo de esto:

{% tabs %}
{% tab title="STM32xxx" %}
P**ondremos nuestra electrónica en modo DFU** y con el comando sudo `dfu-util -l`del resultado del comando anterior prestaremos especial atención al **ID del dispositivo (0483:df11) y al valor de Internal Flash (0x08000000)** ya que los vamos a necesitar en pasos siguientes:

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FSLFJ96l6ahFQWw01O2J3%2Fimage.png?alt=media&amp;token=a5358505-3738-40b0-a80a-cee38efe8414" alt=""><figcaption></figcaption></figure>

Ahora ya tenemos todo para compilar y aplicar lanzando los siguientes comandos ajustando el valor de -s al valor de Internal Flash obtenido anteriormente, y el valor de -d al ID del dispositivo también del paso anterior:

```bash
cd ~/katapult
make
sudo dfu-util -R -a 0 -s 0x08000000:force:mass-erase:leave -D ~/katapult/out/katapult.bin -d 0483:df11
```

Puede que al final del proceso veamos un error en la linea dfu-util, no pasa nada mientras que File downloaded sea <mark style="color:green;">**successfully**</mark>.

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FhHRf2URG6bDzimcpjwpN%2Fimage.png?alt=media&amp;token=fdac76c0-8f32-489d-bed1-7acc7d2479b4" alt=""><figcaption></figcaption></figure>

Para verificar que todo ha ido correctamente saldremos del modo DFU del toolhead, mediante un reset de esta o retirando un jumper dependiendo de cada toolhead, y lanzaremos el comando `ls /dev/serial/by-id` que nos debería retornar un dispositivo conectado que el inicio del nombre sea `usb-katapult`...

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2Fj3C1hiUsL0hyIN054KGN%2Fimage.png?alt=media&amp;token=6b8efe85-8b2d-4886-b3b5-81e0a1c4839a" alt=""><figcaption></figcaption></figure>
{% endtab %}

{% tab title="RP2040" %}
Siguiendo las instrucciones del fabricante del toolhead pondremos esta en modo BOOT, y ejecutaremos el comando `lsusb` para listar los dispositivos conectados donde tendremos que ver uno con el nombre `Raspberry Pi boot`.

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2F88oaytSBlwmu24oj0N8Y%2Fimage.png?alt=media&amp;token=fd24fbd9-4cab-4214-9803-9ba3efd80688" alt=""><figcaption></figcaption></figure>

Y donde nos anotaremos el ID del dispositivo (2e8a:003 en nuestro ejemplo). El cual usaremos para aplicar el firmware/bootloader Katapult a nuestro toolhead:

```bash
cd ~/katapult
make flash FLASH_DEVICE=2e8a:0003
```

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2F0Y9LuF6g7FmbeMM25tq8%2Fimage.png?alt=media&amp;token=9416bff4-e163-4cc9-944a-11ef8c7ccdbf" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
Si tenemos problemas para aplicar el firmware katapult.uf2 mediante comandos siempre podemos utilizar el método manual, básicamente es poner el toolhead en modo BOOT conectarlo a nuestro host/ordenador donde veremos una unidad y copiaremos el katapult.uf2 dentro.
{% endhint %}
{% endtab %}
{% endtabs %}

Ahora que ya tenemos nuestro bootloader Katapult aplicado en nuestro toolhead el siguiente paso es verificar que este está funcionando correctamente.

Para ello apagaremos con sudo shutdown now nuestro host y la impresora en el caso que usen alimentación separada. Dependiendo del toolhead, si este utiliza jumpers para entrar en modo DFU, retiraremos los jumpers, retiraremos el cable USB del toolhead a nuestro host y conectaremos los cables CAN (CANL/H) y los de alimentación al toolhead (Vin/GND).

Volveremos a iniciar/encender nuestro host y después nuestra impresora y volveremos a conectar por SSH revisando que nuestra interfaz CAN esté levantada y revisando los dispositivos en esta con los siguientes comandos:

```bash
ip -s -d link show can0
python3 ~/katapult/scripts/flashtool.py -i can0 -q
```

Nos debería de aparecer un dispositivo `Application: Katapult` en el listado que es nuestro toolhead y tomaremos nota del UUID de este (en nuestro ejemplo 66f03f24c715):

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FSykwzOWnADkzUeepKIEy%2Fimage.png?alt=media&amp;token=bbfa90f0-fa62-4816-888a-6d84de2a3661" alt=""><figcaption></figcaption></figure>

Ahora toca **generar y aplicar el firmware Klipper** a nuestro toolhead una vez aplicado el bootloader Katapult. Lanzaremos los siguientes comandos para configurar las opciones del firmware Klipper:

```bash
cd ~/klipper
make menuconfig
```

Para ello no nos vamos a extender en esta parte y os aconsejamos seguir las instrucciones normales de Klipper para vuestro toolhead pero muy importante asegurarnos que indicamos como `CAN Bus` donde pondremos los pines correctos de esta y ajustar `CAM bus speed` a la velocidad que ajustamos en la configuración de nuestro interfaz CAN, en nuestro caso 1000000 (1M).

Ejecutaremos los siguientes comandos para compilar nuestro firmware Klipper que se guardará, el la extensión dependerá de la MCU que monte nuestro toolhead, en \~/klipper/out/klipper.bin y aplicaremos siguiendo las intrucciones normales de nuestro fabricante:

```bash
make clean
make
```

También podremos reallizar este proceso utilizando Katapult, una vez configurado y compilado el firmware tal como explicamos en el paso antrior, para ello y por seguridad vamos a detener el servicio Klipper con el comando `sudo service klipper stop` y seguidamente utilizaremos el siguiente comando para aplicar el firmware en nuestro toolhead usando como parámetro `-d` el UUID obtenido en pasos anteriores:

<pre class="language-bash"><code class="lang-bash"><strong>python3 ~/katapult/scripts/flashtool.py -i can0 -u b6d9de35f24f -f ~/klipper/out/klipper.bin
</strong></code></pre>

Para verificar que todo se aplicó correctamente volveremos a ejecutar `python3 ~/katapult/scripts/flashtool.py -i can0 -q` para listar los dispositivos CAN donde deberiamos de ver nuestro UUID con la descipción `Application: Klipper`:

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FhAqy0XmoGPngJMfVq3lP%2Fimage.png?alt=media&amp;token=4c434ab3-bb0e-4cf5-b4ea-fd722576dd76" alt=""><figcaption></figcaption></figure>

Arrancaremos de nuevo Klipper con el comando `sudo service klipper start`.

También podemos lanzar el comando de Klipper `~/klippy-env/bin/python ~/klipper/scripts/canbus_query.py can0` donde veremos el UUID que usaremos posteriormente en nuestro printer.cfg como cadena de conexión CAN (en nuestro ejemplo 66f03f24c715):

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FSykwzOWnADkzUeepKIEy%2Fimage.png?alt=media&amp;token=bbfa90f0-fa62-4816-888a-6d84de2a3661" alt=""><figcaption></figcaption></figure>

A continuación os facilitamos información de las más comunes/usadas:

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

* **no nos hacemos responsables de ningún problema o daño que se pueda ocasionar a tu electrónica... tú eres el único responsable de lo que haces**
* **antes de aplicar ninguna configuración descrita en los siguientes pasos verifica con la documentación del fabricante que los valores/configuraciones son correctas para tu caso**
  {% endhint %}

{% hint style="warning" %}
**Resistencias de terminación**

Un CAN bus debe tener dos resistencias de 120 ohmios entre los cables CANH y CANL. Preferiblemente,una resistencia ubicada en cada extremo del bus.

Tenga en cuenta que algunos dispositivos tienen una resistencia integrada de 120 ohmios (por ejemplo, el "Waveshare Raspberry Pi CAN hat" tiene una resistencia soldada en la pcb). Algunos dispositivos no incluyen ninguna resistencia.

Otros dispositivos tienen un mecanismo para seleccionar la resistencia (normalmente conectando un "jumper").

<img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/sWDK8Mz7FlsIxV7Sv3Nk/image.png" alt="" data-size="original"><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/7oVBrhTD0V5bYkgwwHvf/image.png" alt="" data-size="original">

Asegúrese de revisar los esquemas de todos los dispositivos en el bus CAN para verificar que haya dos y solo dos resistencias de 120 ohmios en el bus.

Para probar que las resistencias son correctas, se puede desconectar la alimentación de la impresora y usar un multímetro para verificar la resistencia entre los cables CANH y CANL; debería medir \~60 ohmios en un CAN bus cableado correctamente.
{% endhint %}

{% tabs %}
{% tab title="BTT EBB v1.x" %}

* Configuración para Katapult/Canboot

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FD9XOCJuiU6agTcfkh6CN%2Fimage.png?alt=media&amp;token=4d790023-524a-4fd2-8779-4dc509ff3043" alt=""><figcaption><p>EBB36 v1.2</p></figcaption></figure>

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FD9XOCJuiU6agTcfkh6CN%2Fimage.png?alt=media&amp;token=4d790023-524a-4fd2-8779-4dc509ff3043" alt=""><figcaption><p>EBB42 v1.2</p></figcaption></figure>

* Configuración firmware Klipper para CAN/bridge

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FjengjZQAaru9y7CyK0Ci%2Fimage.png?alt=media&amp;token=d6891c01-cdc6-4ee6-a0a6-2c54b0c7e366" alt=""><figcaption><p>EBB36 v1.2</p></figcaption></figure>

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FjengjZQAaru9y7CyK0Ci%2Fimage.png?alt=media&amp;token=d6891c01-cdc6-4ee6-a0a6-2c54b0c7e366" alt=""><figcaption><p>EBB42 v1.2</p></figcaption></figure>

* DFU, colocar el jumper... conectamos a nuestro host por USB... pulsamos RESET/BOOT... lanzando un `lsusb` deberiamos obtener : `Bus 001 Device 005: ID 0483:df11 STMicroelectronics STM Device in DFU Mode`

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2Fb9CZ87gR9BFHiFC70ApM%2Fimage.png?alt=media&amp;token=a88221c9-a282-40d9-9e04-14372ad4f94b" alt=""><figcaption><p>EBB36 v1.2</p></figcaption></figure>

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FAXmEpjWMUMVLoBnco2T5%2Fimage.png?alt=media&amp;token=e089cfd5-a407-474d-9793-cabd0d8c7e1b" alt=""><figcaption><p>EBB42 v1.2</p></figcaption></figure>

* 120R, resistencia de terminador CAN

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2F4PUIEWk48pV6F9eZvPFM%2Fimage.png?alt=media&amp;token=d96435dc-97ed-4c74-97fa-e5aa0865e509" alt=""><figcaption><p>EBB36 v1.2</p></figcaption></figure>

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FDyQhDA96rQ8QL4vpl02Q%2Fimage.png?alt=media&amp;token=b274a101-4498-4f02-97ef-ecbc73761eb4" alt=""><figcaption><p>EBB42 v1.2</p></figcaption></figure>
{% endtab %}

{% tab title="BTT MMB CAN" %}

* Configuración para Katapult/Canboot

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FlAWpvWYEBnVAp3bDoFVe%2Fimage.png?alt=media&amp;token=e498dbb1-9f54-4581-8aa1-f64b288cb629" alt=""><figcaption></figcaption></figure>

* Configuración firmware Klipper para CAN/bridge

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2F3z73SDPraKM1BrFXK4xk%2Fimage.png?alt=media&amp;token=94f9a791-8d35-4c07-94b6-6a429b0113b5" alt=""><figcaption></figcaption></figure>

* DFU, colocar el jumper... conectamos a nuestro host por USB... pulsamos RESET/BOOT... lanzando un `lsusb` deberiamos obtener : `Bus 001 Device 005: ID 0483:df11 STMicroelectronics STM Device in DFU Mode`

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FnY7Nv47BvK2bKwHmOlnJ%2Fimage.png?alt=media&amp;token=68a3322f-532c-4686-a41f-12b03796326b" alt=""><figcaption></figcaption></figure>

* 120R, resistencia de terminador CAN

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FWUzPnonE7wpBSOVtE55B%2Fimage.png?alt=media&amp;token=7e4d8366-146f-4cd2-9248-6b2ea7cdf200" alt=""><figcaption></figcaption></figure>
{% endtab %}

{% tab title="BTT SB22XX" %}

* Configuración para Katapult/Canboot

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FD9XOCJuiU6agTcfkh6CN%2Fimage.png?alt=media&amp;token=4d790023-524a-4fd2-8779-4dc509ff3043" alt=""><figcaption><p>SB2240 / SB2209</p></figcaption></figure>

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FAMBRrlMTzokyZvBjmQEp%2Fimage.png?alt=media&amp;token=439b246d-4845-4c57-b079-6aabf6702214" alt=""><figcaption><p>SB2209 RP2240 MCU</p></figcaption></figure>

* Configuración firmware Klipper para CAN/bridge

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FjengjZQAaru9y7CyK0Ci%2Fimage.png?alt=media&amp;token=d6891c01-cdc6-4ee6-a0a6-2c54b0c7e366" alt=""><figcaption><p>SB2240 / SB2209</p></figcaption></figure>

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FIrUvb8pLmloUCjxbXoBj%2Fimage.png?alt=media&amp;token=e86b9066-36c7-43fc-b83d-825b58652a16" alt=""><figcaption><p>SB2209 RP2240 MCU</p></figcaption></figure>

* DFU,
  * SB2240 / SB2209...colocar el jumper... conectamos a nuestro host por USB... pulsamos RESET/BOOT... lanzando un `lsusb` deberiamos obtener : `Bus 001 Device 005: ID 0483:df11 STMicroelectronics STM Device in DFU Mode`
  * SB2209 RP2240 MCU...sin ningún cable conectado pondremos el jumper en USB\_5V... conectaremos el cable USB de nuestro host a la SBB2209... pulsaremos BOOT, y con este pulsado, haremos lo mismo pero brevemente con el RST... continuamos unos segundos con el BOOT pulsado y al soltarlo ya deberiamos estar en modo DFU que podemos verificar con un `lsusb`

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FTV7MNP8TBC9jWB0j5HBM%2Fimage.png?alt=media&amp;token=d51ea66c-7921-4199-b47b-42a9d579659f" alt=""><figcaption></figcaption></figure>

* 120R, resistencia de terminador CAN

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2Fq5I4LSFuIfiK3oYGUo8Y%2Fimage.png?alt=media&amp;token=86e66c24-65d3-4df7-b287-7631da072c9e" alt=""><figcaption></figcaption></figure>
{% endtab %}
{% endtabs %}

## Encontrar el canbus\_uuid para nuevas MCUs

A cada MCU se le asigna un UUID único para ser identificado en el CAN bus, este identificador está codificado en el chip de la MCU.

{% hint style="warning" %}
Para encontrar el identificador de cada MCU, asegúrese de que el hardware esté encendido, con sus terminadores y cableado correctamente
{% endhint %}

Y luego ejecutaremos:

```bash
~/klippy-env/bin/python ~/klipper/scripts/canbus_query.py can0
```

{% hint style="warning" %}
Podemos levantar el interfaz **can0** manualmente ejecutando:

> **sudo ip link set up can0 type can bitrate 1000000**

En el caso que nuestro interfaz CAN no se levante automáticamente:

* Editaremos el fichero nano /etc/rc0.d/K01klipper\_mcu
* Añadiremos esta linea al final:\
  PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\
  ip link set up can0 type can bitrate 1000000
  {% endhint %}

Solo se detectan dispositivos CAN bus que estén disponibles para ser activados, el comando anterior informará con líneas como las siguientes:

```
Found canbus_uuid = 11aa22bb33cc
```

Cada dispositivo tendrá un identificador único. En el ejemplo anterior, 11aa22bb33cc es el "canbus\_uuid" de un dispositivo que no está en funcionamiento y puede ser activado.

Tenga en cuenta que la herramienta canbus\_query.py solo informará sobre dispositivos no activados: si Klipper (o una herramienta similar) activa un dispositivo, ya no aparecerá en dicha lista.

## Configuración de Klipper

Actualice su configuración de mcu en Klipper para conectar a través del puerto CAN bus a dicho dispositivo, un ejemplo utilizando nuestra electrónica utilizando CAN ejemplo:

```
[mcu]

canbus_uuid: 11aa22bb33cc
```

En el caso de la configuración de un toolhead CAN hemos de dar un nombre/ID a la mcu:

```
[mcu]
canbus_uuid: 11aa22bb33cc
```

Os aconsejamos para tener un printer.cfg ordenado, simplificado y aprovechar las funciones de Klipper... el tener las configuraciones relacionadas con vuestro toolhead en un fichero toolboard-config.cfg que crearemos a la misma altura de nuetro printer.cfg y en este último añadiremos como include:

```
[include toolboard-config.cfg]
```

En la siguiente tabla tenéis configuraciones de ejemplo para los toolhead más comunes:

| Toolhead                      | toolboard-config.cfg                                                            |
| ----------------------------- | ------------------------------------------------------------------------------- |
| BigTreeTech EBB36 V1.2        | <https://github.com/bigtreetech/EBB/tree/master/EBB%20CAN%20V1.1%20(STM32G0B1)> |
| BigTreeTech EBB42 V1.2        | <https://github.com/bigtreetech/EBB/tree/master/EBB%20CAN%20V1.1%20(STM32G0B1)> |
| BigTreeTech MMB CAN V1.0      | <https://github.com/bigtreetech/MMB/tree/master/Firmware>                       |
| BigTreeTech SB2209 (RP2040)   | <https://github.com/bigtreetech/EBB/tree/master/EBB%20SB2209%20CAN%20(RP2040)>  |
| BigTreeTech SB2209 and SB2240 | <https://github.com/bigtreetech/EBB/tree/master/EBB%20SB2240_2209%20CAN>        |
| Fysetc SB-CAN-TH              | <https://github.com/FYSETC/FYSETC_SB_CAN_TOOLHEAD>                              |
| Mellow Fly ERCF               | <https://mellow.klipper.cn/#/board/fly_ercf/>                                   |
| Mellow Fly SB2040             | <https://mellow-3d.github.io/fly_sb2040_v1_general.html>                        |
| Mellow Fly SHT36 and SHT42    | <https://mellow-3d.github.io/fly-sht36_klipper_config.html>                     |
| Mellow Fly SHT36v2            | <https://mellow-3d.github.io/fly-sht36_v2_general.html>                         |

## Actualizando firmware en nuestros dispositivos CAN

En ocasiones Klipper puede eliminar soporte para versiones antiguas de su firmware, cuando esto sucede veremos que después de actualizar Klipper nos reporta un error que la versión de Klipper en nuestros dispositivos esta desactualizada.

Dado que hemos aconsejado el uso de Katapult esto va a facilitar enormemente el proceso de actualización en estos casos ya que no va a ser necesario desmontar parcialmente vuestra máquina, conectar cables USB de nuevo ni nada parecido... vamos a poder actualizar nuestros dispositivos a través del CANbus y gracias a Katapult.

El primer paso que haremos en cualquier caso será asegurarnos que tenemos la última revisión de Katapult en nuestro sistema ejecutando el siguiente comando por SSH:

```bash
test -e ~/katapult && (cd ~/katapult && git pull) || (cd ~ && git clone https://github.com/Arksine/katapult) ; cd ~
```

El siguiente paso, y dependiendo de cual sea el dispositivo que se tenga que actualizar, deberemos de seguir los siguientes pasos:

{% tabs %}
{% tab title="Electrónica  CAN" %}
En el caso que tengamos que actualizar el firmware Klipper de nuestra electrónica deberemos de realizar los siguientes pasos que a rasgos generales serán los mismos que realizamos durante la [instalación de 0](#instalacion-can-desde-0).

**Actualización del firmware/bootloader Katapult**

En el caso que hayamos actualizado nuestra versión de Katapult, lo cual aconsejamos en el punto anterior, lo primero a hacer es volver a aplicar la versión actualizada de Katapult en nuestra electrónica.

Para ello ejecutaremos los siguientes comandos por SSH:

```bash
cd ~/katapult
make menuconfig
```

Tal como hicimos en pasos anteriores ajustaremos las opciones para nuestra electrónica y que ya os dimos algunos ejemplos en los pasos anteriores, en nuestro caso os ponemos un ejemplo:

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2Fttv67lnX2dWMaiB20VoV%2Fimage.png?alt=media&amp;token=f55d3732-ebc5-42f1-a6e6-95b22baf85e6" alt=""><figcaption></figcaption></figure>

Una vez ajustado salimos (Q) y guardamos los cambios (Y) y lanzaremos un comando `make` a continuación.

Una vez finalizada la compilación se nos generará el firmware katapult.bin y un deployer.bin el cual va a contener la actualización de Katapult. Para poder aplicar estos cambios lo primero será poner nuestra electrónica en modo bootloader Katapult con el siguiente comando utilizando nuestro UUID que ya obtuvimos previamente (como parámetro -u, b6d9de35f24f en nuestro ejemplo):

```bash
python3 ~/katapult/scripts/flashtool.py -i can0 -u b6d9de35f24f -r
```

Con nuestra electrónica en el modo bootloader Katapult ya podremos lanzar el comando `ls /dev/serial/by-id` para verificar que nuestra electronica tiene el identificador como `usb-katapult-xxx` (usb-katapult\_rp2040\_E66138935F5D7224-if00 en nuestro ejemplo) y nos anotaremos este valor:

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2Fj3C1hiUsL0hyIN054KGN%2Fimage.png?alt=media&amp;token=6b8efe85-8b2d-4886-b3b5-81e0a1c4839a" alt=""><figcaption></figcaption></figure>

Si todo ha ido bien lanzaremos el siguiente comando para actualizar nuestro firmware/bootloader Katapult (deployer.bin) :

```bash
python3 ~/katapult/scripts/flashtool.py -f ~/katapult/out/deployer.bin -d /dev/serial/by-id/usb-katapult_rp2040_E66138935F5D7224-if00
```

**Actualización del firmware Klipper**

Ahora nos toca generar el firmware Klipper de nuestra electrónica deberemos de realizar los siguientes pasos que a rasgos generales serán los mismos que realizamos durante la [instalación de 0](#instalacion-can-desde-0).

No entraremos en detalles ya que se explicó ya en pasos anteriores, básicamente ejecutaremos `cd ~/klipper` y lanzaremos el configurador de firmware Klipper con `make menuconfig` donde configuraremos los parámetros para nuestra electrónica prestando atanción a `Communication interface` a `USB to CAN bus bridge`, `CAN Bus interface` donde ajustaremos los pines de nuestra electrónica donde esté conectado nuestro CAN y por último `CAN bus speed` que coincida con la configuación de nuestro interfaz CAN (can0).

Saldremos (Q) y guardamos (Y), y lanzaremos un `make clean` y seguido un `make`, si todo ha ido bien nos va a generar nuestro firmware Klipper `~/klipper/out/klipper.bin`.

Por seguridad pararemos el servicio Klipper con `sudo service klipper stop` y para poder aplicar estos cambios lo primero será poner nuestra electrónica en modo bootloader Katapult con el siguiente comando utilizando nuestro UUID que ya obtuvimos previamente (como parámetro -u, b6d9de35f24f en nuestro ejemplo):

```bash
python3 ~/katapult/scripts/flashtool.py -i can0 -u b6d9de35f24f -r
```

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FKca8cWOwhzfWhFCvrm32%2Fimage.png?alt=media&amp;token=5c8cfd22-62fe-4e0a-a26f-ec82eca1afef" alt=""><figcaption></figcaption></figure>

Con nuestra electrónica en el modo bootloader Katapult ya podremos lanzar el comando `ls /dev/serial/by-id` para verificar que nuestra electronica tiene el identificador como `usb-katapult-xxx` (usb-katapult\_rp2040\_E66138935F5D7224-if00 en nuestro ejemplo) y nos anotaremos este valor:

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2Fj3C1hiUsL0hyIN054KGN%2Fimage.png?alt=media&amp;token=6b8efe85-8b2d-4886-b3b5-81e0a1c4839a" alt=""><figcaption></figcaption></figure>

Si todo ha ido bien lanzaremos el siguiente comando para actualizar nuestro firmware Klipper (klipper.bin) :

```
python3 ~/katapult/scripts/flashtool.py -f ~/klipper/out/klipper.bin -d /dev/serial/by-id/usb-katapult_rp2040_E66138935F5D7224
```

{% endtab %}

{% tab title="Toolhead CAN" %}

{% endtab %}
{% endtabs %}

<details>

<summary>Bibliografia</summary>

Klipper > <https://www.klipper3d.org/CANBUS.html>

Bigtreetech Wiki > <https://bttwiki.com/>

Mellow Wiki >

Esoterical CANbus guide > <https://jtd.esoterical.online/>

</details>


# CANbus Troubleshooting

Este documento nos puede ayudar a solucionar problemas de comunicación relacionados con nuestro CANbus

Aunque poner en funcionamiento no es excesivamente complejo si que depende de diferentes factores para que funcione de forma correcta. Os vamos a sugerir algunos puntos a tener en cuenta cuando montemos nuestro CANbus:

## Cableado

El primer paso a realizar en caso de problemas ha de ser todo lo relacionado con el cableado CANbus.

* Asegúrate que disponemos de dos terminadores correctamente instalados en tu sistema CAN, normalmente suelen ser unos jumpers que habilitan los terminadores 120Ohm.
* Dado que el cableado va a estar en unas condiciones de temperatura y movimientos especiales, en una impresora 3D se aconseja usar un cableado que sea relativamente flexible y aguante temperatura... cables PTFE suelen ser aconsejables
* La sección del cable debería de ser >= 0.22mm2
* La impedancia de los cables CAN debe ser de unos 120 ohms (+- 10%), para facilitar esto el cable utilizado tiene que tener una baja resistencia para mantener el umbral requerido por los receptores junto con los terminadores resistivos del bus
* Revisa que las conexiones a tus dispositivos sean seguras, evitando malas conexiones y falsos contactos que pueden conllevar errores de conexión intermitentes
* Es importante también que los cables, CANL y CANH, estén trenzados e incluso en según que condiciones que estos tengan un mallado extra de protección. Intenta evitar trenzar estos junto con los cables de alimentación siempre que sea posible.

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/kCSNU4yXI8H9vJYFCH22/image.png)

* Es importante encontrar la combinación adecuada entre el bitrate y la longitud del cable, al final de la guía tenéis más información al respecto

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/jVeA2OZZnfwGeFGqe84g/image.png)

## Configuración

### **Firmware**

Es crítico que todos nuestros dispositivos tengan instalado el firmware Klipper tanto en configuración de MCU, pines CAN de comunicaciones y bitrate.

Ya os explicamos en nuestra [guía CANbus](/klipper/mejoras/canbus) como crear, aplicar y actualizar nuestros frimwares CAN.

### Configuración Klipper

En ocasiones una incorrecta configuración de Klipper va a generar errores a la hora de que Klipper pueda acceder o comunicarse con nuestros dispositivos CAN.

#### MCU

Muchos de estos errores relacionados con problemas de comunicación entre Klipper y nuestros dispositivos CAN se pueden dar por una incorrecta configuración de las cadenas de conexión a nuestras MCU.

A modo de ejemplo, si conectamos nuestra MCU utilizando serial/USB en lugar de CAN nuestra configuración deber ser algo similar a:

```
[mcu]
serial: /dev/serial/by-id/usb-Klipper_stm32f446xx_37001A001851303439363932-if00
```

Por otro lado si tenemos conectada nuestra MCU utilizando CAN la definición cambia a algo como lo siguiente, utilizando en este caso el valor UUID:

```
[mcu]
canbus_uuid: a396d68a95a3
```

Por último, si utilizamos un toolhead CAN las definiciones de la MCU han de incluir un ID/nombre para poder identificarlo, además de obviamente el UUID:

```
[mcu EBBCan]
canbus_uuid: ec60cf516124
```

#### Pins

Otro aspecto importante cuando trabajamos con dispositivos CAN, en especial aquellos extras a nuestra MCU principal, la definición de pines van a usar el ID/nombre de esta. A modo de ejemplo para un EBB:

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2F8Eph5aFCpUetvRZKKfOi%2Fimage.png?alt=media&amp;token=0cbdffd8-8472-4e70-969f-657d8c9b55d6" alt=""><figcaption></figcaption></figure>

### Interfaz

Otro aspecto necesario es una correcta configuración de nuestra interfaz CAN de red nuestro host.

Aunque en las diferentes guías ya hemos explicado como montarlo dependiendo del dispositivo vamos a repasar.

Vamos a iniciar el proceso ajustando nuestra configuración de la interfaz de comunicación CAN para nuestro host Klipper.\
Para ello y desde el terminal SSH lanzaremos el siguiente comando:

```bash
sudo nano /etc/network/interfaces.d/can0
```

Nano es un editor de textos en línea de comandos, podemos utilizar cualquier otro que nos sea cómodo, y deberemos añadir/actualizar el contenido de la configuración de nuestro can0 de la siguiente manera:

{% code title="/etc/network/interfaces.d/can0" %}

```bash
allow-hotplug can0
iface can0 can static
    bitrate 1000000
    up ifconfig $IFACE txqueuelen 1024
```

{% endcode %}

{% hint style="info" %}
Usando CTRL+X y Y y ENTER guardaremos los cambios
{% endhint %}

La configuración anterior puede variar dependiendo del sistema operativo de vuestro host o el/los dispositivos utilizados, os aconsejamos revisar la documentación del fabricante de los dispositivos que utilicéis.

Una vez realizado el cambio reiniciaremos nuestro host:

```bash
reboot
```

{% hint style="success" %}
Una vez reiniciado el host es aconsejable revisar que nuestro interfaz CAN se encuentre levantando. Podremos hacerlo lanzando el siguiente comando desde SSH:

* Podemos levantar el interfaz **can0** manualmente ejecutando:

```bash
ip -s link show can0
```

<img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/nhKA3dJgBPJYats8RE6t/image.png" alt="" data-size="original">

* Si diera error podemos intentar levantar el interfaz con:

```bash
sudo ip link set up can0
```

* En el caso que no se levante nuestro interfaz de forma automática
  * revisaremos el contenido del fichero de configuración, con el editor nano por ejemplo,`/etc/network/interfaces` este debería de contener algo parecido a lo siguiente si queremos que cargue nuestras configuraciones anteriores:\
    `## Include files from /etc/network/interfaces.d:`

    `source /etc/network/interfaces.d/*`
  * En caso que lo anterior este correcto, incluyendo temas de cableado y firmware, pero aún así no se levante correctamente nuestro interfaz os aconsejamos revisar el log de sistema y dmesg.\
    Es importante revisar el orden de arranque de los dispositivos y de la interfaz, en ocasiones se hace la carga de la interfaz y a posteriori los drivers o soporte de los dispositivos relacionados haciendo que no sea posible levantar el interfaz de forma correcta.\
    En estos casos y dado que controlar el orden de arranque de dispositivos y opciones de sistema suele ser relativamente complicado podemos crear un simple script en el arranque que lance los comandos indicados anteriormente para levantar el interfaz de forma manual.
    {% endhint %}

### **Bitrate CANbus**

Es importante en un canal de comunicación es el ancho de banda disponible en este, su latencia y porcentaje de errores de comunicación.\
Teniendo en cuenta esto, no todos los dispositivos CAN para 3D se comportan de igual forma y siempre deberemos configurar el bitrate de nuestro CANbus a la velocidad del dispositivo que soporte menos bitrate.\
Es fundamental que a un menos bitrate tendremos un menor ancho de banda para el flujo de datos y, por lo tanto, en determinadas situaciones (como gestión de acelerómetro, leds neopixel, etc...) podemos tener un cuello de botella y aumentar la latencia.\
Por otro lado, un alto bitrate nos va a permitir no tener problemas de latencia pero, por otro lado, y en dispositivos con características limitadas o calidad, pueden ocasionar errores de comunicación que también afectarán.\
Podremos obtener información de la comunicación CANbus desde SSH con este comando:<br>

```
ip -details -statistics link show can0
```

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/20wbxylSDDXQp6MyKSAA/image.png)\
Desde Mainsail podemos acceder a estas estadísticas desde la sección MACHINE haciendo click en nuestra MCU CAN.

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/QgVCpbXZiQ99w0mkkfBM/image.png) ![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/PgLoqmUwz1a8sYbaDVWn/image.png)

## Tests

### Simulando carga en nuestro CANbus

Para poder asegurarnos que nuestro bitrate y cableado funcionan de forma óptima, podemos utilizar can-utils que nos permitirá al simular una carga de datos darnos información ver si tenemos pérdida de paquetes.

```bash
// install can-utils to our system
sudo apt install can-utils
// testing our can0 network at 250k bitrate
canbusload can0@250000 -c -b
```

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FBXq3NUwXHuywysGYMBoi%2Fimage.png?alt=media&amp;token=e788d317-21c8-4559-9a52-81de92771812" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
Normalmente las acciones que suelen cargar más la comunicación son aquellas relacionadas con [Input Shaper](/klipper/empezamos/input-shaper) (si nuestro CAN dispone de acelerómetro) o gestión de tiras leds neopixel... por eso es aconsejable lanzar una de estas acciones para ver si tenemos pérdidas de paquetes.

También es aconsejable realizar por ejemplo un [test de velocidad](/klipper/empezamos/velocidad-maxima), ya que en este caso simularemos movimiento para ver si este afecta a la comunicación, normalmente por un problema de cableado.

También podremos ver desde Mainsail como explicamos en el punto anterior un resumen de las métricas de nuestro interfaz CAN.
{% endhint %}

### Capturando el tráfico de nuestro CANbus

Siguiendo con las herramientas can-utils podemos encontrar candump que nos va a permitir capturar el tráfico de nuestro CANbus:

<pre class="language-bash"><code class="lang-bash"><strong>candump -tz -Ddex can0,#FFFFFFFF > mycanlog
</strong></code></pre>

El comando anterior nos va a permitir capturar el tráfico en nuestra interfaz can0 cobre un fichero mycanlog. Una vez finalizada la captura podemos utilizar la herramienta de Klipper parsecandump.py para parsear esos mensajes:

```bash
./scripts/parsecandump.py mycanlog 108 ./out/klipper.dict
```


# Octopus/Octopus Pro + EBB Toolhead (CANbridge)

En esta guía os mostraremos el proceso para tener nuestra Octopus/Octopus Pro usando un módulo EBB conectada directamente a nuestra Octopus.

{% hint style="info" %}
📖 **Review y guía completa:** [BTT Octopus: Análisis y Guía de configuración con Marlin y Klipper](https://3dwork.io/btt-octopus/) — análisis detallado del hardware, pinout y ejemplos de configuración.
{% endhint %}

## Conexiones

En la siguiente imágen podremos ver el diagrama de conexiones que vamos a utilizar:

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/x4kTWkToeFuBu0a95Kl1/image.png" alt=""><figcaption></figcaption></figure>

Conectaremos nuestra Octopus mediante cable USB y nuestro toolhead EBB usando el conector CAN de nuestra Octopus... a continuación tenéis más detalle sobre las conexiones:

* Usaremos un cable de calidad y de la menos distancia posible USB-A a USB-c para conectar nuestra Octopus (USB-C) a nuestro host (USB-A)
* Alimentaremos desde nuestra fuente de alimentación de la impresora nuestra Octopus y el toolhead EBB
* Para el cable CANbus entre nuestra Octopus y el EBB.

  Necesitaremos un conector RJ11/12 (telefono 6 pins) y un tramo de cable, os acosejamos leer más abajo las sugerencias para el cableado CANbus, al igual que una crimpadora para esos conectores

{% tabs %}
{% tab title="Octopus CAN" %}

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/4NphIija6m78XtL3t8Mk/image.png" alt=""><figcaption></figcaption></figure>
{% endtab %}

{% tab title="EBB36 CAN" %}

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/v5Y5HxJgw7Ag3ugv0RCY/image.png" alt=""><figcaption></figcaption></figure>
{% endtab %}

{% tab title="EBB42" %}

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/Stq0AM9srNp96QkXSs4y/image.png" alt=""><figcaption></figcaption></figure>
{% endtab %}
{% endtabs %}

{% hint style="info" %}
Sugerencias sobre el cableado CAN:

* La impedancia de los cables CAN debe ser de unos 120 ohms (+- 10%), para facilitar esto el cable utilizado tiene que tener una baja resistencia para mantener el umbral requerido por los receptores junto con los terminadores resistivos del bus
* La sección del cable debería de ser >= 0.22mm2
* Es aconsejable que el par de cables usados para la comunicación CAN sean trenzados o incluso en según que condiciones que estos tengan protección con un mallado extra en el cable

<img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/kCSNU4yXI8H9vJYFCH22/image.png" alt="" data-size="original">

* Es importante encontrar la combinación adecuada entre el bitrate y la longitud del cable, al final de la guía tenéis más información al respecto

<img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/jVeA2OZZnfwGeFGqe84g/image.png" alt="" data-size="original">

* Dado que el cableado va a estar en unas condiciones de temperatura y movimientos especiles en una impresora 3D se aconseja usar un cableado que sea relativamente flexible y aguante temperatura... cables PTFE suelen ser aconsejables
  {% endhint %}

## Instalando CANboot

Antes de comenzar con el proceso vamos a explicar brevemente que es CANboot y para/porque lo vamos a utilizar:

* CANboot es un bootloader que se aplica a nuestras electrónicas (Octopus y EBB en este caso) que nos va a permitir poder aplicar el firmware Klipper usando USB, USART o CAN sin necesidad de acceder físicamente a la electrónica para realizar procesos como un reset o DFU
* Utiliza un sistema similar a Klipper y su `make menuconfig` para crear, configurar y compilar el firmware

Vamos a comenzar instalando y entrando en el menú de creación del firmware/bootloader, desde el terminal SSH ejecutaremos:

```bash
cd ~
git clone https://github.com/Arksine/CanBoot
cd CanBoot
make menuconfig
```

### CANboot para Octopus

En el menu de configuración de firmware/bootloader configuraremos de la siguiente forma, recuerda que tendrás que hacerlo para tu Octopus:

{% tabs %}
{% tab title="Octopus F446" %}

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/JG4ho14HIq9uoscWAPh5/image.png" alt=""><figcaption></figcaption></figure>
{% endtab %}

{% tab title="Octopus F407" %}

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/ZkaeR6cLyRy47RxuWekK/image.png" alt=""><figcaption></figcaption></figure>
{% endtab %}

{% tab title="Octopus F429" %}

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/3nxoNu1pnwcjHu5v8SSP/image.png" alt=""><figcaption></figcaption></figure>
{% endtab %}
{% endtabs %}

Una vez ajustadas las opciones pulsaremos Q y Y para salir y guardar la configuración.\
Lanzaremos el comando make:

```bash
make
```

Al finalizar obtendremos un firmware canboot.bin en /home/pi/CanBoot/out/canboot.bin el cual deberemos de copiar a nuestro equipo si aplicamos el firmware usando la SD en la electrónica.

A continuación vamos a aplicar nuestro firmware/bootloader CANboot a nuestra Octopus, y para ello necesitaremos la aplicación [**STM32CubeProgrammer**](https://www.st.com/en/development-tools/stm32cubeprog.html) para ello necesitaremos poner nuestra Octopus en modo DFU.

* Conectaremos el cable USB entre nuestro ordenador y nuestra Octopus
* Quitaremos el jumper de los pines USB-C y pondremos un jumper en BOOT0

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/PXA4YH2BQu2g4IklWBZx/image.png" alt=""><figcaption><p>Octopus v1.0/v1.1</p></figcaption></figure>

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/PKjl62RVNHSC4mKhxBUd/image.png" alt=""><figcaption><p>Octopus Pro</p></figcaption></figure>

* Aplicaremos alimentación a nuestra Octpus desde la fuente de la impresora y pulsaremos y soltaremos el boton RESET, esto hará que entre en modo DFU.

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/52gJFamasnPL9mwbnjGC/image.png" alt=""><figcaption></figcaption></figure>

* Abriremos en nuestro ordenador STM32CubeProgrammer, deberemos asegurarnos que tenemos **seleccionado USB** y pulsaremos el botón de **Connect** en el caso que no nos indique que estemos conectados.

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/oVjTeEvROUboSLXbV82i/image.png" alt=""><figcaption></figcaption></figure>

* Deberemos de limpiar la memoria flash de nuestra Octopus.

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/0241cSKms4L2G7Icgp1O/image.png) ![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/ZhO5j8e4ogGRoYezdCUX/image.png)

* Volveremos al inicio pulsando sobre el icono del lápiz y cargaremos nuestro firmware canboot.bin, el que preparamos para nuestra Octopus, y daremos a Download que descargará el firmware/bootloader a nuestra Octopus.

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/6hn0zMDOHfsBXW2cIkZr/image.png" alt=""><figcaption></figcaption></figure>

* Una vez aplicado apagaremos la alimentación de nuestra Octopus y quitaremos el jumper de BOOT0... ya tenemos nuestra Octopus con CANboot!!!

### CANboot para EBB

Volveremos al menu de CANboot para crear el firmware/bootloader para nuestro toolhead EBB:

```bash
make clean
make menuconfig
```

{% tabs %}
{% tab title="EBB36/42 v1.0 F072" %}

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/brCSSBzjYDZCnSDuRVQF/image.png" alt=""><figcaption></figcaption></figure>
{% endtab %}

{% tab title="EBB36/42 v1.1 G0B1" %}

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/cJUqYb6vbZLcrEFwu7Ei/image.png" alt=""><figcaption></figcaption></figure>
{% endtab %}
{% endtabs %}

{% hint style="warning" %}
En los ejemplos anteriores usamos 500000 como velocidad del bus CAN, en cualquier caso es interesante realizar la pruebas con 1000000 para ver si funciona correctamente.
{% endhint %}

Una vez ajustadas las opciones, pulsaremos Q y Y para salir y guardar la configuración.\
Lanzaremos el comando `make`:

```bash
make
```

Al finalizar obtendremos un firmware canboot.bin en /home/pi/CanBoot/out/canboot.bin el cual deberemos de copiar a nuestro equipo.

A continuación vamos a aplicar nuestro firmware/bootloader CANboot a nuestra EBB, y para ello necesitaremos la aplicación [**STM32CubeProgrammer**](https://www.st.com/en/development-tools/stm32cubeprog.html) para ello necesitaremos poner nuestra EBB en modo DFU.

* Comenzaremos colocando el jumper VUSB para que permita encender la EBB mediante USB

{% tabs %}
{% tab title="EBB36/42 v1.0 F072" %}

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/nfkVsGMFN4pJ6gvHQneu/image.png" alt=""><figcaption></figcaption></figure>
{% endtab %}

{% tab title="EBB36/42 v1.1/v1.2 G0B1" %}

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/c72kQnkIVzE2hFbN81re/image.png" alt=""><figcaption></figcaption></figure>

{% hint style="danger" %}
IMPORTANTE!!

Para los modelos EBB36/42 v1.1 al entrar en modo DFU se activa el pin del calentador del hotend.\
Si tenemos alimentada nuestra EBB con la fuente de la impresora puede calentar el hotend sin ningún tipo de protección lo que puede causar daños importantes!!!
{% endhint %}
{% endtab %}
{% endtabs %}

* Activaremos el modo DFU

{% tabs %}
{% tab title="EBB36/42 v1.0 F072" %}

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/jtrMlVwmwPVLeUY19BnT/image.png" alt=""><figcaption></figcaption></figure>
{% endtab %}

{% tab title="EBB36/42 v1.1/v1.2 G0B1" %}
![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/rjLd4v1mEgP776ZH2L5z/image.png) ![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/EqVz5qmu52ektgze7yjx/image.png)
{% endtab %}
{% endtabs %}

* Conectaremos la EBB a nuestro ordenador y desde STM32CubeProgrammer realizaremos los mismos pasos que hicimos para nuestra Octopus.
* Una vez finalizado el proceso apagaremos nuestra EBB quitando el cable USB, quitaremos el jumper VBUS y pondremos el jumper 120R.

{% tabs %}
{% tab title="EBB36/42 v1.0 F072" %}

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/wPaRQZck3FHG7DfSmEJV/image.png" alt=""><figcaption></figcaption></figure>
{% endtab %}

{% tab title="EBB36/42 v1.1/v1.2 G0B1" %}

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/MDSA9Jjs3K7B8GvvqcO7/image.png" alt=""><figcaption></figcaption></figure>
{% endtab %}
{% endtabs %}

## Instalando Klipper

Ahora que ya tenemos preparadas nuestra Octopus y EBB con CANboot toca ponerse con el firmware Klipper.

### Klipper para Octopus (CANbus Bridge)

* Comenzaremos creando el firmware Klipper desde make menuconfig seleccionando la configuración para nuestra Octopus usando CANbus bridge.

```bash
cd ~/klipper
make menuconfig
```

{% hint style="warning" %}
IMPORTANTE!!!

A la hora de generar el firmware Klipper usando como conexión CANbus asegúrate que seleccionas la velocidad correcta que usaste previamente al generar el fimware/bootloader CANboot.\
En el ejemplo usamos 500000 pero os aconsejamos hacer pruebas con 1000000.
{% endhint %}

{% tabs %}
{% tab title="Octopus F446" %}

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/ntThp6h2hiik5V6UosFA/image.png" alt=""><figcaption></figcaption></figure>
{% endtab %}

{% tab title="Octopus F407" %}

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/mHAVI5iUt49EwHT0Kjfd/image.png" alt=""><figcaption></figcaption></figure>
{% endtab %}

{% tab title="Octopus F429" %}

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/2Tmj5kRR36F7lifVUNvR/image.png" alt=""><figcaption></figcaption></figure>
{% endtab %}
{% endtabs %}

* Una vez ajustadas las opciones, pulsaremos Q y Y para salir y guardar la configuración.\
  Lanzaremos el comando `make`:

```bash
make
```

* Os aconsejamos cambiar el nombre del firmware creado a octopus\_klipper.bin y lo dejaremos en el directorio de klipper para evitar que se sobreescriba

```bash
mv ~/klipper/out/klipper.bin octopus_klipper.bin
```

### Klipper para EBB

Vamos a continuar generando el firmware Klipper para nuestra EBB.

* Limpiaremos y lanzaremos nuestro `make` ajustando las opciones dependiendo de nuestro modelo:

```bash
make clean
make menuconfig
```

{% tabs %}
{% tab title="EBB36/42 v1.0 F072" %}

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/dLN90ntVtY6d7g6celuv/image.png" alt=""><figcaption></figcaption></figure>
{% endtab %}

{% tab title="EBB36/42 v1.1/v1.2 G0B1" %}

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/93kfqt5maTgBQe3voQa0/image.png" alt=""><figcaption></figcaption></figure>
{% endtab %}
{% endtabs %}

* Una vez ajustadas las opciones, pulsaremos Q y Y para salir y guardar la configuración.\
  Lanzaremos el comando `make` y copiaremos el firmware creado a ebb\_klipper.bin en nuestro directorio klipper:

```bash
make
mv ~/klipper/out/klipper.bin ebb_klipper.bin
```

## Configuración Klipper

Conectaremos por USB nuestro host y Octopus alimentando esta con la alimentación de nuestra impresora. Desde el terminal SSH lanzaremos el comando:

```bash
ls /dev/serial/by-id/*
```

Esto nos devolverá el serial id de nuestra Octopus, en nuestro caso `/dev/serial/by-id/usb-CanBoot_stm32f429xx_350026000B50314B33323220-if00` :

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/tit0jYSBVGfgWyaCx4O9/image.png" alt=""><figcaption></figcaption></figure>

{% hint style="warning" %}
El serial id puede variar en tu caso, adapta los siguientes pasos a tu caso!!!
{% endhint %}

Ahora procederemos a aplicar el firmware Klipper que generamos en el punto anterior usando CANboot:

```bash
cd CanBoot/scripts
pip3 install pyserial
python3 flash_can.py -f ~/klipper/octopus_klipper.bin -d /dev/serial/by-id/usb-CanBoot_stm32f429xx_350026000B50314B33323220-if0
```

{% hint style="info" %}
Recuerda poner tu serial id, y el paso de pip3 install pyserial solamente es necesario que lo hagas la primera vez.
{% endhint %}

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/e1aCSqHkFmXSbWovTovF/image.png" alt=""><figcaption></figcaption></figure>

Ahora que ya tenemos nuestra Octopus con el firmware Klipper que habilita CANbridge procederemos a configurar nuestra interfaz CAN.

```bash
sudo nano /etc/network/interfaces.d/can0
```

Y copiaremos la siguiente configuración:

{% code title="/etc/network/interfaces.d/can0" %}

```bash
allow-hotplug can0
iface can0 can static
    bitrate 500000
    up ifconfig $IFACE txqueuelen 1024
```

{% endcode %}

* Recuerda ajustar el bitrate al mismo que indicases en tu firmware/bootloader!!!
* Usando CTRL+X y Y y ENTER guardaremos los cambios

Apagaremos la impresora, conectaremos los cables de alimentación y RJ11/12 a nuestro EBB... Volveremos a encender la impresora.

Ahora que nuestra interfaz CAN vamos a revisar que esté levantado y funcionando con el comando, `ip -s link show can0` en el caso de que diera un error podemos intentar levantarlo con `sudo ip link set up can0` :

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/9cKMX4Q0rbqbOvOX9rnc/image.png" alt=""><figcaption></figcaption></figure>

Si todo funcionó correctamente, lanzaremos el siguiente comando para encontrar los UUID de nuestros dispositivos CAN:

```bash
cd CanBoot/scripts
python3 flash_can.py -i can0 -q
```

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/ukEQxeScEDsHVDZWa9QL/image.png" alt=""><figcaption></figcaption></figure>

Podemos ver los UUID de nuestra Octopus con Klipper (463b35222d7b) y nuestra EBB en CANboot (127081e7e3c6).

Ahora lanzaremos el comando para aplicar el firmware Klipper previamente creado para nuestra EBB usando la interfaz CAN:

```
python3 flash_can.py -f ~/klipper/ebb_klipper.bin -u 127081e7e3c6
```

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/u8qFkGQOAiIrV9Xazbv6/image.png" alt=""><figcaption></figcaption></figure>

## Ajustando nuestro printer.cfg

Si hemos llegado hasta aquí ya tenemos nuestro CAN montado, aplicado nuestros firmwares Klipper/CANboot y disponemos de nuestro bus CAN funcionando y los UUID de nuestros componentes.

Ahora deberemos de configurar nuestro fichero de configuración de Klipper, printer.cfg o alguno de sus includes, para indicarle que conecte con nuestros componentes usando el bus CAN.

Modificaremos nuestras secciones mcu y mcu EBBCan para indicar sus UUID:

```django
[mcu]
canbus_uuid: 463b35222d7b

[mcu EBBCan]
canbus_uuid: 127081e7e3c6
```

{% hint style="success" %}
Si tenemos problemas de conexión:

* En ocasiones el interfaz/bus CAN puede tardar en levantarse, prueba a realizar un reset o un reinicio de la máquina
* Podemos lanzar el comando `sudo ip link set up can0`
* Revisa nuestra guía de [Troubleshooting CAN](/klipper/mejoras/canbus/canbus-troubleshooting)
  {% endhint %}

## Actualizando nuestro firmware Klipper mediante CANboot

Dado que ya tenemos montada nuestra red CANbus y disponemos de CANboot en nuestras electrónicas, podemos realizar actualizaciones de firmware de una forma sencilla.

* Volveremos a crear el firmware tal como realizamos en pasos anteriores
* Lanzaremos el script flash\_can.py para aplicar el firmware, es importante tener el UUID

```bash
python3 flash_can.py -f ~/klipper/octopus_klipper.bin -u 463b35222d7b
```

* Realizaremos el proceso tanto para nuestra Octopus como EBB


# Bigtreetech Manta + EBB Toolhead

Con el uso de **Klipper** cada vez más extendido, los fabricantes están invirtiendo en soluciones centradas en él.

Un ejemplo claro es **Bigtreetech** con su serie Manta donde tenemos una electrónica de primer nivel al que podemos integrar un módulo **CM4** para poder instalar **Klipper** en él y gestionar nuestra electrónica.

Otra funcionalidad que en ocasiones nos puede simplificar el cableado de nuestra máquina o expandir esta es CANbus.

{% hint style="warning" %}
Esto es un comentario a nivel personal:

El uso de CANbus se ha extendido pero aún así y aún con las mejoras implementadas por Klipper suele ser un proceso que puede ser complejo y añade más puntos de fallo.

Personalmente, y siempre que es posible, utilizamos los módulos EBB o similares mediante una conexión USB en lugar de CANbus, obviamente utilizando un cable USB de calidad hecho en silicona para que la flexibilidad y soporte a altas temaperatura no lo dañen, además de dos de alimentación.

De esta forma tratamos nuestro EBB como cualquier otra electrónica por USB sin tener que entrar en configuraciones de Klipper y el sistema operativo que compliquen aún más nuestra instalación, algo que vemos constantemente en los usuarios que intentan implementar CANbus ya sea en la puesta en marcha, la gestión o fallos que suceden al tenerlo.

El uso de USB en lugar de CANbus tiene otros beneficios os aconsejamos leer el siguiente [post de RatOS](https://os.ratrig.com/blog/no-you-dont-want-to-use-can) que es más que interesante y que en lineas generales estamos totalmente de acuerdo con lo que comentan.
{% endhint %}

En esta guía os mostraremos el proceso para tener nuestra Manta (M8P v1.1 o superior) con un módulo CM1 (compatible con esta electrónica y el zócalo CM4 de esta) con Klipper y posteriormente usar un módulo EBB SB2240 conectada directamente a nuestra M8P.

{% hint style="success" %}
La siguiente guía debería de ser similar para otras electrónicas de la serie Manta y otros toolheads CAN realizando en cada caso los ajustes aconsejados por el fabricante.

Es importante recordar que NO todas las electrónicas de la serie Manta tienen las conexiones CAN disponisbles para ser usadas:

* Manta M8P v1.0 no dispone de estas mientras que la v1.1 y v2.0 si.
  {% endhint %}

{% hint style="info" %}
📖 **Review y guía completa:** [BTT Manta M8P/M5P/M4P: Análisis y guía para Klipper](https://3dwork.io/manta-m8p-m5p-m4p-e3ez-analisis-y-guia-completa/) — análisis del hardware, configuración Klipper y casos de uso.
{% endhint %}

## Conexiones

{% hint style="info" %}
Sugerencias sobre el cableado CAN:

* La impedancia de los cables CAN debe ser de unos 120 ohms (+- 10%), para facilitar esto el cable utilizado tiene que tener una baja resistencia para mantener el umbral requerido por los receptores junto con los terminadores resistivos del bus
* La sección del cable debería de ser >= 0.22mm2
* Es aconsejable que el par de cables usados para la comunicación CAN sean trenzados o incluso en según que condiciones que estos tengan protección con un mallado extra en el cable

<img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/kCSNU4yXI8H9vJYFCH22/image.png" alt="" data-size="original">

* Es importante encontrar la combinación adecuada entre el bitrate y la longitud del cable, al final de la guía tenéis más información al respecto

<img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/jVeA2OZZnfwGeFGqe84g/image.png" alt="" data-size="original">

* Dado que el cableado va a estar en unas condiciones de temperatura y movimientos especiles en una impresora 3D se aconseja usar un cableado que sea relativamente flexible y aguante temperatura... cables PTFE suelen ser aconsejables
  {% endhint %}

* Comenzaremos por cablear nuestra M8P y nuestro EBB usando la interfaz CAN que tenemos en nuestra M8P:
  * En el caso de la M8P, y dado que durante el proceso alimentaremos la electrónica mediante USB, colocaremos el jumper V\_USB tal como puedes ver en la siguiente imagen.\
    Es aconsejable el uso de una alimentación

{% tabs %}
{% tab title="M8P v1.1" %}

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/TjwYsMUAfMrINJ1lsUyk/image.png" alt=""><figcaption></figcaption></figure>
{% endtab %}

{% tab title="M8P v2.0" %}

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2F9IIEiE8PQRUlrdQ3WUc0%2Fimage.png?alt=media&amp;token=2cff0a36-6340-4574-98cc-5986b608da43" alt=""><figcaption></figcaption></figure>
{% endtab %}
{% endtabs %}

* En nuestro módulo EBB SB2240, <mark style="color:red;">**si dispones de otro toolhead mira las características del fabricante**</mark>
  * Conectaremos mediante USB nuestra EBB con la M8P
  * También pondremos los jumpers USB\_5V y el 120R\
    ![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/rj3KhmBS3tPrmCIj9aVU/image.png)
    * Finalmente, conectaremos cables CAN en el orden correcto

{% tabs %}
{% tab title="M8P v1.1" %}

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/r4TLd8a8G8TQZtbK95BD/image.png" alt=""><figcaption><p>Foto provisional de <a href="https://mpx.wiki/">https://mpx.wiki/</a></p></figcaption></figure>
{% endtab %}

{% tab title="M8P v2.0" %}

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2Fk3KKGVxgilD2cMLazqzr%2Fimage.png?alt=media&amp;token=50a91718-6cd7-4176-b323-93529ea6e132" alt=""><figcaption></figcaption></figure>
{% endtab %}
{% endtabs %}

{% hint style="warning" %}
**Solamente tenemos que conectar los dos cables del CanBus dejando los dos de alimentación sin conectar y correctamente protegidos para que no hagan contacto entre si ni con ninguna parte metálica.**
{% endhint %}

## Instalando el firmware Klipper en nuestro módulo CB1

A continuación procederemos a **instalar el sistema Klipper en nuestro módulo CB1**, tenemos dos opciones:

* Usar la distribución genérica de **Bigtreetech**

{% embed url="<https://github.com/bigtreetech/CB1/releases>" %}

* Utilizando **RatOS** que tiene algunas ventajas, y desventajas dependiendo de tu nivel de conocimientos en **Klipper**, como la pre-instalación de varios componentes, compatibilidad con varias electrónicas e impresoras con pre configurados y macros por defecto.

{% embed url="<https://github.com/Rat-OS/RatOS/releases>" %}

* Una vez descargada la distribución de **Klipper** que más nos guste, emplearemos [**Raspberry Pi Imager**](https://www.raspberrypi.com/software/) o [**balenaEtcher**](https://www.balena.io/etcher) para transferir la imagen de **Klipper** a nuestra tarjeta SD.\
  Es aconsejable una tarjeta de al menos 16-32Gb.\
  Para esta guía usaremos **RatOS** que es la distribución de **Klipper** que solemos usar normalmente.

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/ijTDFDjGKIJMBm0MJDYj/image.png) ![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/64YQi5u025xQIVsMGgv3/image.png)

* Una vez finalizado el proceso y desde el explorador de nuestro ordenador accederemos a nuestra SD donde tendremos una **partición llamada BOOT**.\
  En esta encontraremos un **fichero system.cfg**

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/jLanD7vMX4vEsczQbdqQ/image.png" alt=""><figcaption><p>Foto provisional de <a href="https://mpx.wiki/">https://mpx.wiki/</a></p></figcaption></figure>

* Abriremos nuestro system.cfg con un editor de textos, importante usar uno específico para programación como [Notepad++](https://notepad-plus-plus.org/downloads/), [Visual Studio Code](https://code.visualstudio.com/download), [Sublime](https://www.sublimetext.com/)... Y ajustaremos las configuraciones de nuestra WiFi.\
  Básicamente, **cambiaremos Your SSID por el nombre de nuestra red WiFi** y **cambiaremos Your Password por la contraseña que utilicemos en nuestra WiFi**.

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/LW7nSclBh0owFVlZSBq6/image.png" alt=""><figcaption><p>Foto provisional de <a href="https://mpx.wiki/">https://mpx.wiki/</a></p></figcaption></figure>

## Arrancando nuestra M8p+CB1 y accediendo a Klipper

Ahora que ya tenemos nuestra SD lista con nuestra distribución de Klipper y nuestros datos WiFi configurados es el momento de insertar la SD en nuestra M8P.

{% hint style="success" %}
**Es importante instalar la SD en el zócalo SOC-CARD**

<img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/4vXKCsM3QkjaUvaB4dkQ/image.png" alt="" data-size="original">
{% endhint %}

**Encenderemos nuestra M8P empleando el cable USB**, es aconsejable el uso de un cargador con cierta potencia en A, y esperaremos unos minutos para que el sistema arranque y se conecte a nuestra WiFi.

Para poder encontrar la IP de nuestra M8P podemos usar [**Fing**](https://www.fing.com/) que es una aplicación multiplataforma que nos escaneará y listará todos los dispositivos de nuestra red. Debería aparecer con el nombre de host BTT-CB1 (en el caso de utilizar la imagen CB1) o ratos (si utilizamos la imagen CB1 de RatOS).

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/aRrze3eyghpNvEswNBRr/image.png" alt=""><figcaption></figcaption></figure>

{% hint style="success" %}
En el caso que no encontremos la IP conectaremos la SD de nuevo a nuestro ordenador y revisaremos el fichero system.cfg en busca de cualquier fallo al añadir nuestros datos WiFi.
{% endhint %}

Una vez identificada nuestra IP iremos a nuestro navegador y la usaremos para acceder a la interfaz web de **Klipper**... os aconsejamos que lo primero a hacer sea una actualización de todos los componentes de **Klipper**:

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/V7sebu113AfIRvKopT37/image.png" alt=""><figcaption></figcaption></figure>

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/rBTjHKmAqbQagvezCdLC/image.png" alt=""><figcaption></figcaption></figure>

## Creando nuestro firmware Klipper para nuestras electrónicas y ajustando CAN

Una vez que ya tenemos nuestro sistema **Klipper** actualizado toca empezar con los ajustes de **Klipper**.

Para ello vamos a necesitar conectarnos al terminal SSH de nuestro **Klipper** mediante nuestra IP, os sugerimos usar [**Terminus**](https://termius.com/) o [**PuttY**](https://www.putty.org/) para conectarnos mediante SSH.

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/aME9ivgRj8jLg3dIjnlu/image.png" alt=""><figcaption></figcaption></figure>

### Ajustes comunicación CAN

Vamos a iniciar el proceso ajustando nuestra configuración del interfaz de comunicación CAN para nuestro host Klipper.\
Para ello y desde el terminal SSH lanzaremos el siguiente comando:

```bash
sudo nano /etc/network/interfaces.d/can0
```

Nano es un editor de textos en línea de comandos y deberemos añadir/actualizar el contenido de la configuración de nuestro can0 de la siguiente manera:

{% code title="/etc/network/interfaces.d/can0" %}

```bash
allow-hotplug can0
iface can0 can static
    bitrate 1000000
    up ifconfig $IFACE txqueuelen 1024
```

{% endcode %}

{% hint style="info" %}
Usando CTRL+X y Y y ENTER guardaremos los cambios
{% endhint %}

Una vez realizado el cambio reiniciaremos nuestra CB1:

```bash
reboot
```

### Preparando nuestra M8P

Para **crear nuestro firmware Klipper para nuestra M8P** realizaremos los siguientes pasos.

* De nuevo desde el terminal SSH lanzaremos el configurador de firmware Klipper:

```bash
cd ~/klipper
make menuconfig
```

* Ajustaremos las opciones tal como vemos en la siguiente imagen pulsando la tecla Q y guardaremos los ajustes:

{% hint style="danger" %}
**Este ejemplo es para una M8P v1.0/1.1, si tienes otro modelo de elctrónica revisa las configuraciones específicas de tu electrónica.**
{% endhint %}

{% tabs %}
{% tab title="M8P v1.1" %}

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/UzqMcmOgWfajVQlzAuzj/image.png" alt=""><figcaption><p>Foto provisional de <a href="https://mpx.wiki/">https://mpx.wiki/</a></p></figcaption></figure>
{% endtab %}

{% tab title="M8P v2.0" %}

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FExlBEcEg2WMtKuKRfjF8%2Ftelegram-cloud-photo-size-4-5771369193583787857-y.jpg?alt=media&amp;token=094e3b9a-70fb-4d53-a228-0e3a7ce83fe1" alt=""><figcaption></figcaption></figure>
{% endtab %}
{% endtabs %}

* lanzamos la build del firmware con el siguiente comando:

```bash
make
```

* si todo ha ido bien nos habrá quedado un fichero out/klipper.bin que será nuestro firmware para nuestra M8P

#### Aplicando el firmware Klipper a nuestra M8P mediante DFU

Ahora que ya tenemos nuestro **firmware Klipper generado para nuestra M8P y configurado para usar comunicación CAN mediante Bridge USB** (la electrónica hace de transceiver CAN para Klipper en lugar de usar uno externo USB conectado al host como el UTOC (Mellow) o U2C (Bigtreetech)).<br>

El siguiente paso será aplicar el firmware a la electrónica. Para ello utilizaremos el modo DFU de estas electrónicas para hacerlo sin salir de nuestro entorno SSH.

* Primero pondremos nuestra **M8P en modo DFU pulsando el botón BOOT0 y RESET** a la vez

{% tabs %}
{% tab title="M8P v1.1" %}

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/Q0RG4faaTcbSYSi5huMV/image.png" alt=""><figcaption></figcaption></figure>
{% endtab %}

{% tab title="M8P v2.0" %}

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FBcEWuxhF07dakNXNrR1p%2Fimage.png?alt=media&amp;token=e9231db9-59c1-42a4-a9ba-928ccb2f0758" alt=""><figcaption></figcaption></figure>
{% endtab %}
{% endtabs %}

* desde el terminal SSH lanzaremos el siguiente comando que nos listará todos los dispositivos USB conectados:

```bash
lsusb
```

* del listado escogeremos el ID de nuestra M8P, normalmente 0483:df11

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/Q2G0Lf1DGEqa2Ida8VP9/image.png" alt=""><figcaption></figcaption></figure>

* con el ID anterior lanzaremos el siguiente comando, donde debemos ajustar el ID en FLASH\_DEVICE, aplicaremos nuestro firmware a la M8P

```
make flash FLASH_DEVICE=0483:df11
```

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/z2EqPfC6TD9K9XPWVA06/image.png" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
Aunque veamos algunos errores lo importante es que el proceso marcado en el recuadro verde esté correcto.
{% endhint %}

* Una vez aplicado el firmware pulsaremos el botón RESET de nuestra M8P
* si todo ha ido bien ya podremos obtener el UUID CAN de nuestra M8P, para ello volveremos a conectarnos por terminal SSH y lanzaremos el siguiente comando y anotaremos nuestro UUID:

{% hint style="warning" %}
Es aconsejable revisar que nuestro interfaz CAN se encuentre levantando.

* Podemos verificar el interfaz **can0** manualmente ejecutando:

```bash
ip -s link show can0
```

<img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/nhKA3dJgBPJYats8RE6t/image.png" alt="" data-size="original">

* Si diera error podemos intentar levantar el interfaz con:

```bash
sudo ip link set up can0
```

* En el caso que no se levante nuestro interfaz de forma automática
  * revisaremos el contenido del fichero de configuración, con el editor nano por ejemplo,`/etc/network/interfaces` este debería de contener algo parecido a lo siguiente si queremos que cargue nuestras configuraciones anteriores:\
    `## Include files from /etc/network/interfaces.d:`

    `source /etc/network/interfaces.d/*`
  * En caso que lo anterior este correcto, incluyendo temas de cableado y firmware, pero aún así no se levante correctamente nuestro interfaz os aconsejamos revisar el log de sistema y dmesg.\
    Es importante revisar el orden de arranque de los dispositivos y de la interfaz, en ocasiones se hace la carga de la interfaz y a posteriori los drivers o soporte de los dispositivos relacionados haciendo que no sea posible levantar el interfaz de forma correcta.\
    En estos casos y dado que controlar el orden de arranque de dispositivos y opciones de sistema suele ser relativamente complicado podemos crear un simple script en el arranque que lance los comandos indicados anteriormente para levantar el interfaz de forma manual.
    {% endhint %}

```bash
python3 lib/canboot/flash_can.py -q
```

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/vWiq39CTZw42530foSI4/image.png" alt=""><figcaption></figcaption></figure>

### Preparando nuestra EBB

Le llega el turno a nuestro módulo EBB, antes de comenzar con el proceso tenemos que asegurarnos que tenemos el jumper USB\_5V y conectamos nuestra M8P con la EBB usando un cable USB.

Para una gestión más sencilla de los componentes CAN vamos a usar CANboot.

* instalaremos los componentes CANboot, desde el terminal SSH ejecutaremos:

```bash
cd ~
git clone https://github.com/Arksine/CanBoot
cd CanBoot
make menuconfig
```

* al igual que hicimos con la M8P ajustaremos las opciones para nuestra EBB siguiendo como ejemplo la siguiente captura... una vez teminado pulsaremos Q y salvaremos la configuración:

{% hint style="danger" %}
**Este ejemplo es para una EBB SB2240, si tienes otro modelo de elctrónica revisa las configuraciones específicas de tu electrónica.**
{% endhint %}

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/B4W7dizx6ODP4FibAuVq/image.png" alt=""><figcaption></figcaption></figure>

* compilaremos el firmware lanzando el siguiente comando desde nuestro terminal SSH:

```bash
make
```

* buscaremos el ID de nuestro EBB y nos lo anotaremos, debería de ser 0483:df11

```bash
lsusb
```

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/DN77zckkQcmI5CyykaZ1/image.png" alt=""><figcaption></figcaption></figure>

* pondremos nuestra EBB en modo DFU presionando el botón BOOT y lanzaremos el siguiente comando para aplicar nuestro bootloader CANboot... asegúrate que pones el ID correcto

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/j1IcCBl0sk6DySdPhHx6/image.png)

```bash
dfu-util -a 0 -d 0483:df11 --dfuse-address 0x08000000 -D ~/CanBoot/out/canboot.bin
```

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/lWBQmh1AOitCUlQr9p1W/image.png" alt=""><figcaption></figcaption></figure>

* ahora **prepararemos el firmware Klipper para nuestro EBB**, para ello desde el terminal lanzaremos los siguientes comandos... ajustaremos las opciones como la imagen adjunta y presionamos Q para guardar los ajustes:

```bash
cd ~/klipper
make menuconfig
```

{% hint style="danger" %}
**Este ejemplo es para una EBB SB2240, si tienes otro modelo de elctrónica revisa las configuraciones específicas de tu electrónica.**
{% endhint %}

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/VBvVFY7uDNZQRZTQtauC/image.png" alt=""><figcaption></figcaption></figure>

* ejecutaremos la compilación del firmware con el comando:

```bash
make
```

* ya tenemos todo listo para aplicar el firmware Klipper en nuestra EBB, pondremos esta en modo DFU (presionando RST) y ejecutaremos lsusb para encontrar su ID

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/t5TLSmjS5dLMOR6D2Q6a/image.png)

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/Lw4Hyx3V5kUpQ1fLGtR0/image.png" alt=""><figcaption></figcaption></figure>

* aplicaremos el firmware, recuerda asegurarte que usas el ID correcto:

```bash
dfu-util -a 0 -d 0483:df11 --dfuse-address 0x08002000 -D out/klipper.bin
```

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/04y9rowWgCXXmsXmnLta/image.png" alt=""><figcaption></figcaption></figure>

Ahora procederemos a verificar nuestra comunicación CAN

* verificando CANboot, pulsando dos veces en el botón RST (el led rojo debería parpadear) lanzaremos el siguiente comando donde deberíamos ver que ambos dispositivos tienen CANboot

```bash
cd ~/klipper
python3 lib/canboot/flash_can.py -q
```

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/66c67E1C41DXmeknqugk/image.png" alt=""><figcaption></figcaption></figure>

* verificando Klipper, pulsaremos el botón RST (el led rojo no debería de parpadear) y lanzaremos el siguiente comando para comprobar nuestros dispositivos tienen Klipper:

```bash
cd ~/klipper
python3 lib/canboot/flash_can.py -q
```

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/akgEjEmSg0QwUFPxajnO/image.png" alt=""><figcaption></figcaption></figure>

Ya podemos ajustar nuestro printer.cfg para añadir nuestras MCU utilizando su UUID, en nuestro ejemplo 4b94c57be78e (M8P) y 2f0b1ce14660 (EBB).

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

```django
[mcu]
canbus_uuid: 4b94c57be78e
[mcu EBBCan]
canbus_uuid: 2f0b1ce14660
```

{% endcode %}

{% hint style="danger" %} <mark style="color:red;">**Recuerda quitar los jumpers V\_USB (M8P) y USB\_5V (EBB).**</mark>

<mark style="color:green;">**El jumper 120R lo deberemos mantener.**</mark>
{% endhint %}

## Actualizar Klipper usando CANboot

Ahora que ya tenemos todo montado y teniendo en cuenta futuras actualizaciones del firmware Klipper es cuando podremos ver las ventajas de CANboot.

En algunas actualizaciones de Klipper vamos a necesitar actualizar el firmware en nuestras MCU así que sería un poco engorroso tener que conectar el cable USB a nuestro EBB y realizar todo el proceso... aquí es donde CANboot nos va a solucionar la papeleta permitiendo actualizar el firmware Klipper desde el propio bus CAN.

Los pasos serán similares a los que hicimos en la configuración inicial.

* ahora **prepararemos el firmware Klipper para nuestro EBB**, para ello desde el terminal lanzaremos los siguientes comandos... ajustaremos las opciones como la imagen adjunta y presionamos Q para guardar los ajustes:

```bash
cd ~/klipper
make menuconfig
```

{% hint style="danger" %}
**Este ejemplo es para una EBB SB2240, si tienes otro modelo de elctrónica revisa las configuraciones específicas de tu electrónica.**
{% endhint %}

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/VBvVFY7uDNZQRZTQtauC/image.png" alt=""><figcaption></figcaption></figure>

* ejecutaremos la compilación del firmware con el comando:

```bash
make
```

* ya tenemos todo listo para aplicar el firmware Klipper en nuestra EBB, pondremos esta en **modo BOOT (presionando RST dos veces)**

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/t5TLSmjS5dLMOR6D2Q6a/image.png)

* lanzaremos el siguiente **comando desde SSH para actualizar el firmware usando CANboot**, recuerda poner el UUID de tu EBB en tu caso (en el ejemplo 110a62ed1c3c)

```bash
python3 lib/canboot/flash_can.py -i can0 -f ./out/klipper.bin -u 110a62ed1c3c
```

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/BFAWHgocdTw05QQt9sHd/image.png" alt=""><figcaption></figcaption></figure>

Y ya tendremos nuestra EBB actualizada!!!

{% hint style="success" %}
Este mismo proceso podemos utilizar en nuestra M8P por CANbus ajustando en cada paso a las configuraciones de nuestra electrónica.
{% endhint %}

## Resolución de problemas

Aunque poner en funcionamiento no es excesivamente complejo si que depende de diferentes factores para que funcione de forma correcta. Os vamos a sugerir algunos puntos a tener en cuenta cuando montemos nuestro CANbus:

* **Bitrate CANbus**... un aspecto importante en un canal de comunicación es el ancho de banda disponible en este, su latencia y porcentaje de errores de comunicación.\
  Teniendo en cuenta esto no todos los dispositivos CAN para 3D se comportan de igual forma y siempre deberemos configurar el bitrate de nuestro CANbus a la velocidad del dispositivo que soporte menos bitrate.\
  Es importante que a un menos bitrate tendremos un menor ancho de banda para el flujo de datos y por lo tanto en determinadas situaciones (como gestión de acelerómetor, leds neopixel, etc...) podemos tener un cuello de botella y aumentar la latencia.\
  Por otro lado un alto bitrate nos va a permitir no tener problemas de latencia pero por otro lado y en dispositivos con características limitadas o calidad pueden ocasionar errores de comunicación que también afectarán.\
  Podremos obtener información de la comunicación CANbus desde SSH con este comando:<br>

  ```
  ip -details -statistics link show can0
  ```

  ![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/20wbxylSDDXQp6MyKSAA/image.png)\
  Desde Mainsail podemos acceder a estas estadísticas desde la sección MACHINE haciendo click en nuestra MCU CAN.

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/QgVCpbXZiQ99w0mkkfBM/image.png) ![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/PgLoqmUwz1a8sYbaDVWn/image.png)

* **Cableado**, aunque el cableado de CANbus es simple hay que prestar especial atención a el.
  * Es aconsejable usar el cableado correcto tanto en soporte a temperatura, flexibilidad y diámetro necesario para el dispositivo CAN y los componentes que "cuelguen" de el.
  * Comprobar que el crimpado y la continuidad en los cables es la correcta
  * Terminadores en ambos finales del bus, midiendo la resistencia entre el cable H y L deberíamos de tener 60ohms.
  * Aunque el protocolo CAN no suele afectarse demasiado por interferencias en el cableado no está de mas en trenzar los cables H y L para evitarlas.
* **Firmware,** es importante que todos nuestros dispositivos tengan instalado el firmware Klipper tanto en configuración de MCU, pines CAN de comunicaciones y bitrate
* **Testeando nuestra instalación**, para poder asegurarnos que nuestro bitrate y cableado funcionan de forma óptima, podemos utilizar can-utils que nos permitirá al simular una carga de datos darnos información ver si tenemos pérdida de paquetes.

```
// install can-utils to our system
sudo apt install can-utils
// testing our can0 network at 250k bitrate
canbusload can0@250000 -c -b
```

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FN9JHsEq4wbvuihGhg9Iw%2Fimage.png?alt=media&amp;token=9b2d16de-105c-41d5-bae0-140c76f22555" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
Normalmente las acciones que suelen cargar más la comunicación son aquellas relacionadas con [Input Shaper](/klipper/empezamos/input-shaper) (si nuestro CAN dispone de acelerómetro) o gestión de tiras leds neopixel... por eso es aconsejable lanzar una de estas acciones para ver si tenemos pérdidas de paquetes.

También es aconsejable realizar por ejemplo un [test de velocidad](/klipper/empezamos/velocidad-maxima), ya que en este caso simularemos movimiento para ver si este afecta a la comunicación, normalmente por un problema de cableado.

También podremos ver desde Mainsail como explicamos en el punto anterior un resumen de las métricas de nuestro interfaz CAN.
{% endhint %}

* Capturando el tráfico de nuestro CANbus, Siguiendo con las herramientas can-utils podemos encontrar candump que nos va a permitir capturar el tráfico de nuestro CANbus:\
  `candump -tz -Ddex can0,#FFFFFFFF > mycanlog`\
  El comando anterior nos va a permitir capturar el tráfico en nuestra interfaz can0 cobre un fichero mycanlog. Una vez finalizada la captura podemos utilizar la herramienta de Klipper parsecandump.py para parsear esos mensajes:\
  `./scripts/parsecandump.py mycanlog 108 ./out/klipper.dict`


# MMU — Impresión multifilamento

Guía completa de sistemas MMU (Multi-Material Unit) en Klipper: ERCF v2, Tradrack, Box Turtle, PicoMMU, ACE Anycubic, Happy Hare y tips de configuración.

<figure><img src="https://raw.githubusercontent.com/wiki/moggieuk/Happy-Hare/resources/universal_mmu_driver.png" alt="Happy Hare — driver universal MMU para Klipper"><figcaption><p>Happy Hare soporta más de 15 sistemas MMU diferentes desde una única capa de software</p></figcaption></figure>

Si quieres imprimir en varios colores o materiales desde una sola impresora, necesitas un sistema MMU (Multi-Material Unit). En Klipper hay varias opciones — desde proyectos open source de la comunidad hasta soluciones comerciales — y la mayoría se gestiona hoy en día a través de **Happy Hare**, el firmware unificado de referencia para MMU en Klipper.

{% hint style="warning" %}
**Antes de meterte en un MMU**: asegúrate de que tu impresora está bien calibrada y funciona sin problemas. Un MMU no arregla problemas previos — los amplifica. Pressure Advance, retracción y temperatura de purga son los ajustes más críticos.
{% endhint %}

Si tienes dudas o necesitas ayuda en el proceso, únete al grupo de Telegram [**Klipper ES — ERCF/MMU**](https://t.me/Klipper_Firmware_ES/94927) donde encontrarás a gente con experiencia real en estos sistemas.

Os recordamos que tienes más guías de ayuda en nuestro bot de Telegram [@ThreeDWorkHelpBot](https://t.me/ThreeDWorkHelpBot)

***

## ¿Qué es Happy Hare?

Antes de hablar de hardware, es imprescindible entender [**Happy Hare**](https://github.com/moggieuk/Happy-Hare) porque es el cerebro de casi todos los sistemas MMU en Klipper.

Happy Hare es una extensión de Klipper desarrollada por [**moggieuk**](https://github.com/moggieuk) que actúa como **driver universal para sistemas MMU**. En lugar de tener cada sistema su propio firmware con sus propias macros, Happy Hare proporciona una capa unificada que funciona con más de 15 sistemas de hardware diferentes.

### ¿Qué aporta Happy Hare?

* **Gestión de estado completa**: sabe en todo momento dónde está el filamento — cargado, en el selector, en el buffer, etc.
* **Recuperación de errores automática**: si hay un atasco o un fallo de carga, intenta resolver el problema solo antes de pausar
* **Endless Spool**: si un carrete se agota durante la impresión, puede cambiar automáticamente a otro carrete del mismo material
* **Integración con Mainsail/Fluidd**: panel de control visual dentro de la UI
* **KlipperScreen compatible**: panel táctil con control completo del MMU
* **Soporte de cortador de filamento**: compatible con sistemas que incluyen cuchilla (ERF, FilamATrix, etc.)
* **Integración con secadores de filamento**: puede activar/desactivar secado según el filamento cargado

### Sistemas soportados por Happy Hare

| Sistema          | Tipo                  | Estado soporte |
| ---------------- | --------------------- | -------------- |
| ERCF v1 / v2     | Selector lineal       | ✅ Oficial      |
| Tradrack         | Selector lineal       | ✅ Oficial      |
| Box Turtle (AFC) | Estilo AMS, lanes     | ✅ Oficial      |
| 3MS              | Modular 2+ bobinas    | ✅ Oficial      |
| BTT ViViD        | Comercial multi-color | ✅ Oficial      |
| PicoMMU          | Compacto PCB          | ✅ Oficial      |
| Night Owl        | Dual spool integrado  | ✅ Oficial      |
| QuattroBox       | Filamentalist-based   | ✅ Oficial      |
| SMuFF v6         | Modular               | ✅ Oficial      |
| 3D Chameleon MK4 | Comercial             | ⚠️ Limitado    |

<figure><img src="https://raw.githubusercontent.com/wiki/moggieuk/Happy-Hare/resources/my_klipperscreen.png" alt="Happy Hare KlipperScreen"><figcaption><p>Panel Happy Hare en KlipperScreen — control táctil completo del MMU desde la pantalla de la impresora</p></figcaption></figure>

### Instalación de Happy Hare

```bash
cd ~/
git clone https://github.com/moggieuk/Happy-Hare.git
cd Happy-Hare
./install.sh -i
```

El instalador es interactivo y te preguntará qué hardware MMU tienes. Genera automáticamente todos los archivos de configuración necesarios.

**Archivos de configuración que genera:**

| Archivo                       | Qué configura                                     |
| ----------------------------- | ------------------------------------------------- |
| `mmu/base/mmu.cfg`            | Include principal — carga el resto                |
| `mmu/base/mmu_hardware.cfg`   | Pines físicos del MMU (motores, sensores, LEDs)   |
| `mmu/base/mmu_parameters.cfg` | Parámetros de operación (velocidades, distancias) |
| `mmu/base/mmu_macro_vars.cfg` | Variables de comportamiento de las macros         |

**Macros principales:**

| Macro                 | Función                                   |
| --------------------- | ----------------------------------------- |
| `T0`, `T1`, `T2`...   | Cambio de herramienta (filamento)         |
| `MMU_HOME`            | Homing del selector                       |
| `MMU_LOAD`            | Cargar filamento al nozzle                |
| `MMU_UNLOAD`          | Descargar filamento                       |
| `MMU_PAUSE`           | Pausar y esperar intervención             |
| `MMU_RESUME`          | Continuar tras resolver un error          |
| `MMU_STATUS`          | Ver estado actual del sistema             |
| `MMU_SYNC_GEAR_MOTOR` | Sincronizar motor del extrusor con el MMU |

***

## Sistemas MMU compatibles con Klipper

### ERCF v2 — Enraged Rabbit Carrot Feeder

<figure><img src="https://raw.githubusercontent.com/Carrot-collective/ERCF_v2/master/Assets/ERCFv2.png" alt="ERCF v2"><figcaption><p>ERCF v2 — el MMU open source más popular y veterano de la comunidad Klipper</p></figcaption></figure>

El **ERCF** es el MMU open source más popular de la comunidad Klipper. Nació como proyecto para máquinas Voron pero funciona prácticamente con cualquier impresora.

La versión **v2** es una revisión completa respecto a la v1.1 con construcción simplificada, mayor fiabilidad y opciones de expansión:

* **Selector lineal** con un motor de control para seleccionar el canal activo
* **Un motor de empuje por canal** (o en algunos diseños, motores de engrane)
* **Soporte de buffer integrado** mediante el módulo ERCT (Enraged Rabbit Cotton Tail)
* **Opción de cortador de filamento** con el módulo ERF (Enraged Rabbit Filament Cutter)
* **Kits disponibles**: Fysetc, Funsor, Blurolls, Trianglelab — entre 80€ y 200€ según versión y número de canales

**Canales disponibles**: de 2 a 12 filamentos según el modelo que montes.

**GitHub**: <https://github.com/Enraged-Rabbit-Community/ERCF_v2>

**Firmware recomendado**: Happy Hare (obligatorio para v2)

{% hint style="info" %}
Si tienes un ERCF v1 funcionando con el firmware antiguo (ERCF Software V2/V3), puedes migrar a Happy Hare sin cambiar el hardware. La migración merece la pena por las mejoras en recuperación de errores.
{% endhint %}

**Electrónica recomendada:**

* **BTT MMB** (MMU Management Board): placa dedicada con pines optimizados para ERCF
* **Mellow MMU Board**: alternativa con soporte de CAN
* Cualquier Raspberry Pi / BTT Pi con puertos GPIO libres

***

### Tradrack — ANNEX Engineering

<figure><img src="https://raw.githubusercontent.com/Annex-Engineering/TradRack/main/Images/render3.png" alt="Tradrack ANNEX Engineering"><figcaption><p>Tradrack — diseño modular de selector único, escalable a bajo coste por canal</p></figcaption></figure>

[**Tradrack**](https://github.com/Annex-Engineering/TradRack) es el MMU de ANNEX Engineering (los mismos de las impresoras K3 y Gasherbrum). Su filosofía de diseño es diferente al ERCF:

* En lugar de un motor por canal, usa un **selector tipo carril único con un solo motor** para seleccionar el filamento activo
* **Diseño modular**: se puede ampliar el número de canales añadiendo módulos sin cambiar la mecánica principal
* **Menor coste por canal** que ERCF gracias a la mecánica más simple
* **Muy buena documentación** y comunidad activa dentro de ANNEX Engineering

**Canales**: modular, desde 2 hasta N filamentos.

**GitHub**: <https://github.com/Annex-Engineering/TradRack>

**Firmware**: Happy Hare — soporte oficial completo.

***

### Box Turtle — AFC (Automated Filament Changer)

[**Box Turtle**](https://github.com/ArmoredTurtle/BoxTurtle) es el sistema de la comunidad **ArmoredTurtle** que más se asemeja conceptualmente a un Bambu AMS: un sistema de carriles con rebobinado automático y gestión de buffer integrada.

* **Estilo AMS**: carriles independientes con motores de rebobinado eléctrico
* **Buffer TurtleNeck**: buffer integrado entre el Box Turtle y el toolhead
* **FilamATrix**: módulo de corte de filamento integrado
* **Plugin Klipper**: [AFC-Klipper-Add-On](https://github.com/ArmoredTurtle/AFC-Klipper-Add-On) — se puede usar de forma independiente o junto a Happy Hare

**Estado**: v1.0 estable, en desarrollo activo (2025-2026).

**GitHub**: <https://github.com/ArmoredTurtle/BoxTurtle>

{% hint style="success" %}
Box Turtle es una de las opciones más interesantes si buscas una experiencia similar al Bambu AMS en una impresora DIY con Klipper. El rebobinado automático hace la experiencia mucho más cómoda.
{% endhint %}

***

### PicoMMU

<figure><img src="https://raw.githubusercontent.com/AdamTuraj/PicoMMU/main/images/3DView.png" alt="PicoMMU"><figcaption><p>PicoMMU — PCB compacto para multifilamento a bajo coste</p></figcaption></figure>

[**PicoMMU**](https://github.com/AdamTuraj/PicoMMU) es la opción más compacta y económica para quienes quieren probar el multifilamento sin una gran inversión. Está diseñado alrededor de una PCB que controla un único motor/servo para cambiar entre 4-8 filamentos.

* **Precio**: muy bajo, pensado para presupuestos ajustados
* **Simplicidad**: configuración mucho más sencilla que ERCF o Tradrack
* **Limitaciones**: menor fiabilidad en cambios de filamento largos, no tan robusto para impresiones largas
* **Compatible con Happy Hare**: soporte oficial

Ideal para **iniciarse en el mundo MMU** o para impresoras con espacio muy limitado.

***

### BTT ViViD — Bigtreetech

<figure><img src="https://raw.githubusercontent.com/bigtreetech/docs/master/docs/img/ViViD/product.webp" alt="BTT ViViD"><figcaption><p>BTT ViViD — solución comercial con secado activo integrado y soporte de hasta 16 colores</p></figcaption></figure>

El **BTT ViViD** es la apuesta comercial de Bigtreetech para el multifilamento en Klipper. A diferencia de los sistemas open source, incluye todo integrado en una caja: selector, motores, secado activo y gestión de filamentos.

**Especificaciones:**

| Característica                         | Detalle                                              |
| -------------------------------------- | ---------------------------------------------------- |
| **Colores por unidad**                 | 4 filamentos                                         |
| **Expansión**                          | Hasta 16 colores conectando 4 unidades en cadena     |
| **Secado integrado**                   | Cámara calefactada hasta 60°C, imprime mientras seca |
| **Materiales beneficiados por secado** | Nylon, PETG, TPU, PA, ASA                            |
| **Detección RFID**                     | Detecta el tipo de filamento automáticamente         |
| **Alimentación de respaldo**           | Smart backup feeding para evitar fallos por rotura   |
| **Indicadores**                        | LEDs RGB con estado visual configurable              |
| **Dimensiones**                        | 373 × 293 × 252 mm                                   |
| **Firmware**                           | Firmware nativo BTT + soporte Happy Hare             |
| **Precio**                             | \~300-330€ por unidad                                |

<figure><img src="https://raw.githubusercontent.com/bigtreetech/docs/master/docs/img/ViViD/MMS1.webp" alt="BTT ViViD multi-unit expandido"><figcaption><p>4 unidades BTT ViViD en cadena = 16 colores disponibles simultáneamente</p></figcaption></figure>

**Lo que lo diferencia del resto:**

* **Secado activo integrado**: el ViViD puede secar el filamento mientras imprime. En materiales higroscópicos (Nylon, PA, PETG) esto es una ventaja real que los sistemas DIY no tienen sin añadir hardware externo.
* **RFID automático**: detecta el filamento y puede ajustar parámetros automáticamente si el slicer lo soporta.
* **Experiencia plug-and-play**: instalación mucho más sencilla que ERCF o Box Turtle. Pensado para usuarios que no quieren pasar días montando hardware imprimible.
* **Escalable comercialmente**: 4 unidades = 16 colores sin rediseñar nada.

**¿Cuándo elegir BTT ViViD?**

* Quieres multifilamento sin un proyecto DIY complejo
* Trabajas con materiales higroscópicos que se degradan sin secado
* Valoras una solución integrada con soporte de fabricante
* Tu presupuesto permite \~300€+ por unidad

**¿Cuándo no es la mejor opción?**

* Quieres más de 4-16 colores a bajo coste por canal
* Prefieres máxima personalización y control del firmware
* Tu impresora tiene espacio limitado para el sistema externo

**Dónde comprar:**

| Tienda      | Enlace                                                                                                                           |
| ----------- | -------------------------------------------------------------------------------------------------------------------------------- |
| BTT Oficial | [biqu.equipment/products/biqu-vivid](https://biqu.equipment/products/biqu-vivid)                                                 |
| AliExpress  | [Ver en AliExpress](https://s.click.aliexpress.com/e/182731559?productUrl=https://www.aliexpress.com/item/1005010375381781.html) |

**GitHub**: <https://github.com/bigtreetech/BIGTREETECH_ViViD>

**Wiki oficial**: [global.bttwiki.com/BIGTREETECH\_ViViD.html](https://global.bttwiki.com/BIGTREETECH_ViViD.html)

***

### Anycubic ACE Pro — compatibilidad con Klipper

El **Anycubic ACE Pro** es la unidad multi-material comercial de Anycubic diseñada para sus impresoras Kobra S1 y K3. A diferencia de los sistemas open source anteriores, el ACE Pro **no está diseñado para Klipper** nativo.

**Estado actual de compatibilidad:**

{% tabs %}
{% tab title="ACE Pro en impresoras Anycubic Klipper" %}
Las impresoras Anycubic que usan Klipper internamente (Kobra S1, K3 series) incluyen el ACE Pro con firmware propietario. La comunicación entre la impresora y el ACE Pro es mediante protocolo propietario Anycubic.

Actualmente **no existe soporte oficial de Happy Hare para el ACE Pro**. Hay trabajo exploratorio en la comunidad para entender el protocolo, pero aún no hay una solución lista para producción.
{% endtab %}

{% tab title="ACE Pro con Happy Hare (experimental)" %}
Existe un fork experimental de la comunidad para el K1 Max con soporte limitado:

<https://github.com/swilsonnc/ACEPROK1Max>

Este proyecto es **experimental y no recomendado para producción**. Si quieres multifilamento fiable con Klipper, te aconsejamos optar por uno de los sistemas open source del apartado anterior.
{% endtab %}
{% endtabs %}

{% hint style="warning" %}
Si tienes una impresora Anycubic con ACE Pro y quieres usar Klipper estándar con Happy Hare, la realidad es que en 2025-2026 no es una opción directa. El camino más viable para multifilamento en Klipper sigue siendo un sistema open source como ERCF, Tradrack o Box Turtle.
{% endhint %}

***

### Otros sistemas destacados

**3MS (Modular Multimaterial System)** — [GitHub](https://github.com/3dcoded/3ms): sistema de entrada muy accesible (\~150€) para 2+ bobinas. Sencillo de montar y configurar, excelente para empezar. Soportado por Happy Hare.

**SMuFF v6** — Proyecto veterano y maduro, muy modular, soporte Klipper disponible. Para usuarios que quieren mucho control y personalización.

**3D Chameleon MK4** — Sistema comercial con soporte parcial para Klipper, pero con menor comunidad que las opciones anteriores.

***

## Preparar la impresora para MMU — hardware recomendado

Antes de instalar un MMU hay que preparar la impresora. No todas las configuraciones de hardware funcionan igual de bien con multifilamento. Estas son las mejoras que marcan la diferencia real.

### Sensor de filamento en el toolhead

El sensor de filamento en el toolhead es **la mejora más importante** que puedes hacer. Va montado justo antes del extrusor y le dice a Happy Hare exactamente cuándo el filamento ha llegado o se ha retirado del extrusor, sin tener que confiar solo en cálculos de distancias.

**Sin sensor**: Happy Hare usa distancias calculadas para cargar/descargar. Cualquier pequeña variación en el filamento, temperatura o desgaste del Bowden puede causar fallos.

**Con sensor**: Happy Hare sabe con certeza cuándo el filamento ha llegado a su posición. La tasa de éxito en cambios de filamento mejora drásticamente.

Los sensores más usados son:

* **Microswitch** montado en el toolhead/extrusor — la opción más sencilla y fiable
* **Sensor óptico** (tipo SL1) — sin contacto mecánico, larga vida útil
* Muchos toolheads modernos (Stealthburner, Orbiter, Galileo 2) ya tienen posición para sensor integrado

***

### Zona de purga / Poop chute

La **zona de purga** (también llamada "poop chute" o cubo de purga) es el área de la cama donde la impresora purga el filamento anterior antes de empezar a imprimir con el nuevo color. Hay dos enfoques:

{% tabs %}
{% tab title="Torre de purga (Wipe Tower)" %}
La torre de purga es un objeto auxiliar que el laminador genera automáticamente al lado de la pieza. La impresora va a ese objeto y purga el filamento anterior antes de volver a imprimir.

**Ventajas:**

* Funciona en cualquier impresora sin modificaciones físicas
* Configuración sencilla en OrcaSlicer/Bambu Studio
* Fiable y predecible

**Desventajas:**

* Consume filamento y tiempo de impresión
* Ocupa espacio en la cama
* Para muchos cambios de color, la torre puede ser grande

La torre de purga es el método recomendado para **empezar** con MMU.
{% endtab %}

{% tab title="Purga en el relleno/objeto (Purge to Infill)" %}
Con un cortador de filamento, el cambio es limpio y no quedan restos. En lugar de una torre de purga, el filamento sobrante se purga directamente en las zonas de relleno de la pieza (donde no se ve) o en las paredes internas.

**Ventajas:**

* No hay torre de purga — la cama queda libre
* Ahorra tiempo y filamento
* Impresiones más limpias visualmente

**Requiere:**

* Sistema cortador en el toolhead (ver sección siguiente)
* Configuración específica en OrcaSlicer

Es el método preferido cuando el hardware lo permite.
{% endtab %}

{% tab title="Cubo de purga físico (Poop Bucket)" %}
Una solución intermedia muy popular: un pequeño cubo o bandeja montado en un extremo del eje X. La impresora se desplaza allí, purga el filamento antiguo (que cae en el cubo) y vuelve a imprimir.

**Ventajas:**

* Sin torre de purga en la cama
* Funciona sin cortador
* Purga más rápida que la torre

**Desventajas:**

* Requiere diseñar/imprimir el soporte del cubo para tu máquina
* El "poop" (bloque de filamento purgado) hay que retirarlo periódicamente
* Necesita macros específicas en Happy Hare

El cubo de purga es muy popular en setups ERCF para CoreXY.
{% endtab %}
{% endtabs %}

***

### Sistema cortador de filamento en el toolhead

El cortador de filamento es la **mejora que más impacto tiene en la calidad** de los cambios. Cuando se retira el filamento del nozzle, la punta queda deformada por el calor (forma de bulbo o "tip"). Ese extremo deformado puede causar atascos en la siguiente carga. El cortador lo elimina.

**¿Qué hace exactamente?**

1. Antes del cambio, el filamento se retira y se corta limpiamente
2. El extremo cortado es recto y entra sin problemas en el siguiente ciclo de carga
3. No hay formación de tips problemáticos

**Opciones populares de cortadores:**

| Sistema                                  | Compatible con                  | Tipo                           |
| ---------------------------------------- | ------------------------------- | ------------------------------ |
| **ERF** (Enraged Rabbit Filament cutter) | ERCF v2                         | Cuchilla integrada en toolhead |
| **FilamATrix**                           | Box Turtle / AFC                | Cuchilla + purga integrada     |
| **Filametrix** (de la comunidad)         | Cualquier toolhead Voron/CoreXY | Mod imprimible + cuchilla      |
| **Bambu-style cutter**                   | Voron, VzBot y otros            | Adaptación del diseño Bambu    |

{% hint style="info" %}
**Happy Hare soporta cortadores de filamento de forma nativa.** La integración se configura en `mmu_macro_vars.cfg` activando `variable_tool_cut: 1` y ajustando los parámetros de posición del corte. Una vez configurado, cada cambio de filamento incluye automáticamente el ciclo de corte.
{% endhint %}

Configuración básica en `mmu_macro_vars.cfg` para cortador:

```ini
# mmu_macro_vars.cfg — activar cortador
variable_tool_cut: 1                    # 1 = usar cortador en cada cambio
variable_tool_cut_coord: "x=-10 y=355" # posición XY del cortador en tu máquina
variable_tool_cut_retract_speed: 25     # velocidad de retracción antes del corte
variable_tool_cut_fast_retract: 50      # distancia retracción rápida (mm)
```

***

### Buffer de filamento

El buffer es **obligatorio** en cualquier setup MMU serio. Sin él, el filamento puede ir tenso desde la bobina hasta el MMU, lo que causa:

* Fallo de carga al no poder tirar del filamento
* Errores de encoder (detecta que el filamento no se mueve como debería)
* Desgaste prematuro del motor de empuje

**Opciones:**

* **ERCT** (Cotton Tail) — buffer oficial para ERCF v2, muy compacto
* **TurtleNeck** — buffer de Box Turtle, con sensor integrado
* **Filamentalist** — buffer pasivo muy popular, funciona con cualquier sistema
* Guías de filamento en arco / sin guías rígidas como alternativa mínima

***

## Configuración laminador (Orca Slicer)

El laminador es tan importante como el hardware. Para multifilamento en Klipper, **OrcaSlicer** es el más completo y compatible.

### Configuración básica en OrcaSlicer

1. En **Printer Settings → Single extruder multimaterial** activa la opción correspondiente
2. Configura la **torre de purga** (Wipe Tower): es la herramienta más fiable para eliminar restos de filamento anterior entre cambios. Para impresiones con muchos cambios de color, asegúrate de que la torre es suficientemente grande.
3. Ajusta los **volúmenes de purga** por par de materiales en la tabla de purga (Filament Change → Purge volumes). Los valores dependen del contraste de colores y la opacidad de tus filamentos.

{% hint style="info" %}
**Valores de purga orientativos:**

* Mismo material, colores similares: 40-60 mm³
* Mismo material, colores contrastados (negro→blanco): 100-150 mm³
* Materiales diferentes (PLA→TPU): consulta la guía de compatibilidad de tu slicer
  {% endhint %}

4. Si usas **cortador de filamento** (ERF, FilamATrix), desactiva la torre de purga y usa el sistema de purge to infill o purge to object en su lugar — mucho más eficiente.

***

## Tips y consejos

### Mecánicos

* **Buffer de filamento**: siempre necesario entre las bobinas y el selector. Sin buffer, la tensión del filamento causa fallos de carga. El ERCT para ERCF o el TurtleNeck para Box Turtle son las soluciones más probadas.
* **Cableado limpio**: los motores del MMU son sensibles a interferencias. Usa cable de calidad y mantén los cables separados de las cadenas de movimiento.
* **Guías de filamento (PTFE)**: usa tubo Capricorn o equivalente de calidad. Un tubo flojo o con uniones deficientes es la causa número uno de atascos en MMU.
* **Sensores en el toolhead**: aunque no son obligatorios, un sensor de filamento en el toolhead (antes del extrusor) mejora enormemente la fiabilidad. Happy Hare lo soporta y lo usa para confirmar cargas/descargas.

### Calibración Happy Hare

La calibración es el paso más crítico de todo el proceso. Una calibración correcta determina si tu MMU funciona bien o da problemas constantemente. No te saltes ningún paso ni cambies el orden.

{% hint style="danger" %}
**La calibración se hace una sola vez** (salvo que cambies hardware). Una vez calibrado correctamente, Happy Hare recuerda todos los valores. No es necesario recalibrar antes de cada impresión.
{% endhint %}

#### Paso 1 — Homing del selector

Lo primero es hacer homing del selector para que Happy Hare sepa dónde está:

```
MMU_HOME
```

Si el homing falla, revisa los endstops del selector antes de continuar. Puedes verificar el estado con:

```
MMU_STATUS
```

#### Paso 2 — Calibración del motor de empuje (gear motor)

Este es el paso más importante. El **gear motor** es el que mueve el filamento dentro del MMU. Si la calibración de rotación no es precisa, todas las distancias de carga/descarga serán incorrectas y tendrás atascos o filamento que no llega al nozzle.

```
MMU_CALIBRATE_GEAR
```

Happy Hare te pedirá que midas con un calibre cuánto filamento se ha movido respecto al esperado y calculará el factor de corrección (`gear_rotation_distance`). El proceso:

1. Marca el filamento con un rotulador a una distancia conocida del selector (normalmente 100mm)
2. Lanza el comando — moverá el filamento esa distancia
3. Mide la distancia real movida con el calibre
4. Introduce el valor medido cuando te lo pida

{% hint style="info" %}
El valor resultante se guarda en `mmu_vars.cfg` como `gear_rotation_distance`. Si usas varios motores de empuje (uno por canal), cada uno puede tener un valor ligeramente diferente. Happy Hare soporta valores por canal.
{% endhint %}

#### Paso 3 — Calibración del encoder (si tu MMU lo tiene)

Los sistemas ERCF incluyen un encoder óptico que mide el movimiento real del filamento. Happy Hare usa este encoder como verificación — detecta si el filamento se está moviendo realmente o si hay slippage en los engranajes.

```
MMU_CALIBRATE_ENCODER
```

El proceso es similar: mueve filamento y compara distancia comandada vs. medida por el encoder. La relación se guarda como `encoder_resolution`.

{% hint style="warning" %}
Si no tienes encoder (PicoMMU, algunos Tradrack), salta este paso. Happy Hare funciona sin encoder, pero con menor capacidad de detectar atascos suaves.
{% endhint %}

#### Paso 4 — Calibración de distancias de carga por canal

Cada canal del MMU tiene una distancia diferente desde el selector hasta el extrusor. Happy Hare puede calibrar esto automáticamente:

```
MMU_CALIBRATE_BOWDEN BOWDEN_LENGTH=xxx
```

Donde `xxx` es la longitud aproximada en mm del tubo Bowden desde el MMU hasta el extrusor. No tiene que ser exacta — Happy Hare la usará como punto de partida y buscará el sensor de filamento (si tienes) para ajustar la distancia real.

Si quieres calibrar canal por canal manualmente:

```
MMU_CALIBRATE_BOWDEN GATE=0
MMU_CALIBRATE_BOWDEN GATE=1
# ...y así para cada canal
```

{% hint style="info" %}
Si tienes un sensor de filamento en el toolhead (muy recomendable), Happy Hare puede hacer esta calibración de forma completamente automática usando el sensor como referencia de posición.
{% endhint %}

#### Paso 5 — Calibración de la zona de carga del extrusor (homing extruder)

Esta calibración define cuánto filamento hay que empujar desde que entra en el extrusor hasta que llega al nozzle. Hay varias formas de medir este punto dependiendo de los sensores que tengas:

{% tabs %}
{% tab title="Con sensor en toolhead" %}
Si tienes sensor de filamento justo antes del extrusor, Happy Hare puede usar ese punto como referencia exacta:

```
MMU_CALIBRATE_TOOLHEAD HOMING_METHOD=sensor
```

Happy Hare empujará filamento hasta activar el sensor, medirá la distancia y guardará el valor `toolhead_extruder_to_nozzle`.
{% endtab %}

{% tab title="Con extrusor de referencia (homing)" %}
Algunos extrusores (Orbiter, Galileo 2) pueden actuar como sensor de colisión detectando la resistencia al empujar el filamento:

```
MMU_CALIBRATE_TOOLHEAD HOMING_METHOD=collision
```

El extrusor detecta el aumento de corriente cuando el filamento toca el nozzle o el punto de fusión y para automáticamente.
{% endtab %}

{% tab title="Sin sensor — manual" %}
Si no tienes sensor ni homing por colisión, calibra midiendo físicamente la distancia y ajustando a mano en `mmu_parameters.cfg`:

```ini
# mmu_parameters.cfg
toolhead_extruder_to_nozzle: 72    # distancia en mm extrusor → nozzle
toolhead_sensor_to_nozzle: 40     # distancia sensor → nozzle (si aplica)
```

Para medir: carga filamento manualmente hasta que salga por el nozzle, mide el recorrido desde la entrada del extrusor.
{% endtab %}
{% endtabs %}

#### Paso 6 — Verificación del ciclo completo

Una vez calibrados todos los parámetros, haz una prueba de ciclo completo con un canal:

```
MMU_HOME
MMU_SELECT GATE=0
MMU_LOAD
```

El filamento debe cargarse completamente hasta el nozzle. Verifica en el terminal de Klipper que no hay errores y que las distancias reportadas coinciden con lo esperado.

Para descargar:

```
MMU_UNLOAD
```

{% hint style="success" %}
Si la carga y descarga funcionan sin errores en el canal 0, repite la prueba con el resto de canales. Si alguno falla, revisa el cableado de ese canal y vuelve a calibrar `gear_rotation_distance` para ese gate específico.
{% endhint %}

#### Paso 7 — Ajuste de parámetros de operación

Con la calibración básica lista, ajusta los parámetros de comportamiento en `mmu_parameters.cfg`:

```ini
# mmu_parameters.cfg — parámetros clave a revisar

# Velocidades (en mm/s)
gear_from_buffer_speed: 150        # velocidad carga desde buffer
gear_from_spool_speed: 60          # velocidad carga desde bobina (más lento = más fiable)
gear_short_move_speed: 60          # velocidad para movimientos cortos
gear_homing_speed: 50              # velocidad durante homing

# Sincronización con extrusor durante impresión
sync_to_extruder: 1                # 1 = sincronizar gear motor con extrusor (recomendado)
sync_feedback_enable: 1            # usar feedback de tensión del filamento

# Comportamiento ante errores
pause_on_runout: 1                 # pausar si se detecta falta de filamento
enable_endless_spool: 0            # 1 = cambio automático al agotarse bobina

# Número de reintentos antes de pausar
load_retries: 2
unload_retries: 2
```

{% hint style="info" %}
**`sync_to_extruder: 1`** es uno de los ajustes más importantes. Con él activado, el motor del MMU se sincroniza con el extrusor durante la impresión, reduciendo el estrés en el filamento y mejorando la consistencia de extrusión. Salvo casos muy específicos, déjalo siempre a 1.
{% endhint %}

#### Resumen — orden de calibración

| Paso                               | Comando                          | Obligatorio            |
| ---------------------------------- | -------------------------------- | ---------------------- |
| 1. Homing selector                 | `MMU_HOME`                       | ✅                      |
| 2. Gear motor                      | `MMU_CALIBRATE_GEAR`             | ✅                      |
| 3. Encoder                         | `MMU_CALIBRATE_ENCODER`          | Solo si tienes encoder |
| 4. Bowden (distancia MMU→extrusor) | `MMU_CALIBRATE_BOWDEN`           | ✅                      |
| 5. Toolhead (extrusor→nozzle)      | `MMU_CALIBRATE_TOOLHEAD`         | ✅                      |
| 6. Prueba ciclo completo           | `MMU_SELECT GATE=0` + `MMU_LOAD` | ✅ (verificación)       |
| 7. Ajuste parámetros               | editar `mmu_parameters.cfg`      | Recomendado            |

### Impresión

* Empieza con impresiones simples de 2 colores antes de escalar a 8+
* Imprime la torre de purga con un skirt para evitar que se despegue
* La primera capa es crítica: usa velocidades bajas y asegura buena adhesión de la torre de purga
* Monitoriza los primeros cambios de filamento. Happy Hare puede resolver muchos errores automáticamente, pero al principio es mejor ver qué hace.

### Si algo falla

* Consulta el log de Klipper buscando `MMU` para ver qué pasó
* `MMU_STATUS` te da el estado actual del sistema
* `MMU_RECOVER` intenta recuperar la posición del filamento si el sistema se ha desorientado
* El canal de Discord de Happy Hare tiene una comunidad muy activa: <https://discord.gg/moggieuk>
* Grupo Telegram español: [Klipper ES — ERCF/MMU](https://t.me/Klipper_Firmware_ES/94927)

***

## Recursos y documentación

* [Happy Hare — GitHub](https://github.com/moggieuk/Happy-Hare)
* [Happy Hare — Wiki completa](https://github.com/moggieuk/Happy-Hare/wiki)
* [ERCF v2 — GitHub](https://github.com/Carrot-collective/ERCF_v2)
* [Tradrack — ANNEX Engineering](https://github.com/Annex-Engineering/TradRack)
* [Box Turtle + AFC — ArmoredTurtle](https://github.com/ArmoredTurtle/BoxTurtle)
* [3MS — GitHub](https://github.com/3dcoded/3ms)
* [OrcaSlicer — Multi-material guide](https://github.com/SoftFever/OrcaSlicer/wiki)


# Impresión desde USB

Aunque Klipper está enfocado en usarlo remotamente, en ocasiones puede sernos útil el disponer nuestros gcodes en un pendrive USB para imprimirlos localmente.

* Primero de todo nos fijaremos cuál es el punto de montaje de nuestro USB normalmente suele ser en /media o creando un nuevo bloque dentro de /dev/
* Para poder identificar nuestro punto de montaje podemos usar el comando fdisk... en el siguiente ejemplo veremos que nos ha montado nuestro USB en /dev/sdc1

{% hint style="info" %}
Normalmente el comando fdisk requiere permisos root por lo que es necesario lanzarlo con sudo delante para introducir nuestro password root
{% endhint %}

```bash
sudo fdisk -l
```

{% code title="Salida del comando anterior:" %}

```bash
Disk /dev/sdc: 7.4 GiB, 7948206080 bytes, 15523840 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x00000000

Device     Boot Start      End  Sectors  Size Id Type
/dev/sdc1  *     8192 15523839 15515648  7.4G  b W95 FAT32
```

{% endcode %}

* Montaremos nuestro USB en /media/usb

```bash
mount /dev/sdc1 /media/usb/
```

{% hint style="success" %}
**Como montar de forma permanente nuestro USB**:

El proceso seguido en los pasos no es permanente dado que dejará de funcionar al reiniciar nuestro host, si queremos que sea permanente:

* editaremos nuestro fichero /etc/fstab

```bash
sudo nano /etc/fstab
```

* añadiremos nuestro punto de montaje añadiendo esta linea prestando atencion al sistema de archivos que usemos... normalmente vfat

```
/dev/sdc1       /media/usb           vfat    defaults        0       0
```

* <mark style="color:orange;">**IMPORTANTE!!! en el punto anterior os sugerimos el punto de montaje basado en un bloque /dev/ que dependiendo del numero de USB que pongamos puede variar. En ese caso lo mas correcto seria usar el UUID**</mark>
* Podemos encontrar nuestro UUID con el siguiente comando

```bash
ls -l /dev/disk/by-uuid/*
lrwxrwxrwx 1 root root 10 Mar 27 23:38 /dev/disk/by-uuid/2016-08-30-11-31-31-00 -> ../../sdb1
lrwxrwxrwx 1 root root 10 Mar 27 23:38 /dev/disk/by-uuid/3eccfd4e-bd8b-4b5f-9fd8-4414a32ac289 -> ../../sda1
lrwxrwxrwx 1 root root 10 Mar 27 23:38 /dev/disk/by-uuid/4082248b-809d-4e63-93d2-56b5f13c875f -> ../../sda5
lrwxrwxrwx 1 root root 10 Mar 28 01:09 /dev/disk/by-uuid/8765-4321 -> ../../sdc1
lrwxrwxrwx 1 root root 10 Mar 27 23:38 /dev/disk/by-uuid/E6E3-F2A2 -> ../../sdb2
```

* Ahora una vez identificado el UUID de nuestro USB ajustaremos nuestro /etc/fstab usando este en lugar del bloque /dev

```
/dev/disk/by-uuid/8765-4321       /media/usb           vfat    defaults        0       0
```

* Por último y ya sea mediante bloque /dev o mediante UUID montaremos nuestras unidades con el siguiente comando

```bash
mount -a
```

{% endhint %}

{% hint style="info" %}
Si queremos tener compatibilidad con otros sistemas de archivos podemos:

* NTFS

```bash
sudo apt install ntfs-3g
```

* exFAT

```bash
sudo apt install exfat-fuse
sudo apt install exfat-utils
```

{% endhint %}

* Averiguaremos cuál es nuestro path en Klipper para nuestros gcodes, normalmente suele ser \~/printer\_data/gcodes

{% hint style="info" %}
Para asegurarnos en que path guardamos nuestros gcodes podemos revisar nuestros ficheros de configuración y encontrar la sección \[virtual\_sdcard] donde encontraremos esta información.

```django
[virtual_sdcard]
path: ~/printer_data/gcodes
on_error_gcode: CANCEL_PRINT
```

En el caso que usemos, por ejemplo, una distribución basada en MainsailOS podremos encontrarlo dentro de mainsail.cfg
{% endhint %}

* Dentro de nuestro path en Klipper para almacenar nuestros gcodes crearemos una nueva carpeta llamada usb -> \~/printer\_data/gcodes/usb

```bash
mkdir ~/printer_data/gcodes/usb
```

* Crearemos un link simbólico de nuestro punto de montaje USB /media a nuestro nuevo directorio

```bash
ln -s /media/usb /home/pi/gcode_files/usbs
```

{% hint style="info" %}
Podemos mirar nuestros puntos de montaje con:

```bash
mount | grep sdc1
/dev/sdc1 on /media/usb type vfat (rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=utf8,shortname=mixed,errors=remount-ro
```

{% endhint %}

### Resolución de problemas:

En ocasiones puede que no se monten las unidades correctamente al iniciarse el proceso antes de que estas estén disponibles. La forma más sencilla es **editando el fichero /etc/rc.local**

```bash
sudo nano /etc/rc.local
```

**y añadiendo las siguientes líneas encima de exit 0**

```bash
sleep 20
sudo mount -a 
```


# VPN con ZeroTier

By @laureanootero - Telegram

**ZeroTier** es un software que le permite crear redes virtuales entre sus dispositivos mediante una sencilla interfaz web central. Puede comparar estas redes virtuales con la configuración de una VPN en su Raspberry Pi. Sin embargo, la experiencia de aprovisionamiento es mucho más simple, especialmente cuando se administran varios dispositivos.

Las conexiones se realizan entre cada uno de sus dispositivos mediante una red de igual a igual. Estas conexiones están protegidas mediante cifrado de extremo a extremo para ayudar a mantener sus datos seguros y privados.

Además de ejecutar **ZeroTier** en una **Raspberry Pi**, también puede ejecutarlo en la mayoría de los demás dispositivos, incluidos los **teléfonos**. Además, puede funcionar en **Linux, Windows y macOS**, lo que significa que puede crear una red virtual sin preocuparle que su dispositivo no es compatible.

**ZeroTier** se ejecuta en el modo gratuito. Para el **plan gratuito** que estamos usando en esta guía, **puede tener hasta 50 dispositivos autorizados** en su red virtual. Como beneficio adicional, el equipo de ZeroTier ha puesto su [**código a disposición en GitHub**](https://github.com/zerotier/ZeroTierOne) .

Una de las ventajas de un proyecto de código abierto es que puede ver lo que se supone que debe hacer el código.

## Creación de ID para ZeroTier

Para utilizar el [**software ZeroTier**](https://my.zerotier.com/) en su Raspberry Pi, debe registrarse en su sitio web. La razón de esto es que su sitio web actúa como la pasarela de control de la red virtual.

Con esta interfaz web, puede controlar todos los aspectos de su red virtual, con la capacidad de configurar direcciones IP estáticas para dispositivos específicos.

* Para crear una ID de red, primero deberá registrarse en la interfaz web central de ZeroTier. Esta es la interfaz web que le permitirá crear y administrar redes virtuales.\
  En su navegador web favorito, vaya al [**sitio web de ZeroTier Central**](https://my.zerotier.com/). Una vez en la web haga click en Register para comenzar con el proceso de crear una cuenta.

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/KcfDSCXIfBkxRIhjDclX/image.png)

* En la pantalla de registro, complete todos los datos que desea utilizar en su cuenta de ZeroTier (1).

  Cuando haya completado de introducir los datos, haga click en el botón Register en la parte inferior de la pantalla (2).

  Una vez que se haya registrado para obtener una cuenta, se le pedirá que verifique la dirección de correo electrónico especificada. No podrá continuar hasta que se haya verificado el correo electrónico.

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/lX1EezifqMpbtS8YlGki/image.png)

* Después de registrar su cuenta e iniciar sesión en la interfaz web, aparecerá la siguiente pantalla. Todo lo que necesitas hacer ahora es click en el botón **Create A Network**.

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/oi68WkdLWOoLSk0vy3WB/image.png)

* Al hacer click en el botón, el sitio web de ZeroTier creará su primera red. En esta tabla, puede encontrar el ID de red.

  Necesitaremos esta identificación para conectar su Raspberry Pi a esta red virtual ZeroTier. **Anote esta identificación, ya que la necesitaremos más adelante.**

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/XWfuguiJgwozqfF4XHrw/image.png)

* Si desea ajustar detalles como el nombre de la red, debe hacer click en la red deseada.

  A continuación se muestran las configuraciones básicas que puede cambiar para su red ZeroTier.\
  Ahora podría cambiar:

  1\. El nombre de la red.

  2\. Establecer una descripción

  3\. Cambiar el control de acceso

  ZeroTier también le permite ajustar varios otros aspectos de la red virtual, como la subred IP.

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/r1nKqzTmIL8UnYD5kKUj/image.png)

## Ejecución de ZeroTier en Raspberry Pi

Ahora que hemos instalado ZeroTier en nuestra Raspberry Pi, podemos conectarlo a la red que configuramos anteriormente en la guía.

Asegúrese de tener el ID de la red a la que desea conectarse antes de continuar.

* Necesitaremos usar el cliente de ZeroTier para unirnos a la red en la Raspberry Pi.\
  Para hacer esto, necesitará usar el siguiente comando. Primero, asegúrese de reemplazar “ \[NETWORKID]” con el ID que obtuvo anteriormente en esta guía.

```shell
sudo zerotier-cli join [NETWORKID]
```

{% hint style="info" %}
Si su Raspberry Pi se une con éxito a la red ZeroTier, debería ver el siguiente mensaje.

***200 join OK***
{% endhint %}

* Aunque se haya unido a la red ZeroTier, debe autenticar su dispositivo antes de que se convierta en un miembro real de la red.\
  Para hacer esto, deberá volver a la interfaz Web de ZeroTier y seleccionar su red. Si lo desea, también puede ir a la siguiente URL, reemplazando \[NETWORKID] con su ID de red.\
  **<https://my.zerotier.com/network/> \[NETWORKID ]**\
  Una vez que esté en la página de administración de la red ZeroTier de su Raspberry Pi,\
  deberá desplazarse hacia abajo para ver la sección Members.

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/AhTEYoCgTchTsyhOqyav/image.png)

* Dentro de esta sección, deberá identificar el dispositivo que agregó y hacer click en la casilla de verificación.\
  Esto permitirá que su Raspberry Pi se conecte con cualquier otro dispositivo en la red y viceversa.\
  **A medida que vaya instalando el cliente de ZeroTier a los diferentes dispositivos y añadiéndolos a la red que acaba de crear, deberá hacer este proceso de activación para que puedan acceder entre ellos.**
* La columna Address es lo que identifica ese dispositivo en particular dentro de su red ZeroTier.

{% hint style="info" %}
Puede hacer que su Raspberry Pi emita esta información usando el comando:

***sudo zerotier-cli status***
{% endhint %}

* Para que sea más fácil identificar este nuevo dispositivo en el futuro, puede usar el Name/Description para darle un nombre que identifique claramente el dispositivo en la red.
* La columna más importante que querrá consultar es la columna Managed IPs.

  Esta columna enumerará las direcciones IP que se han asignado a ese dispositivo en particular. Puede utilizar estas direcciones IP para conectarse a ese dispositivo en particular.

  Si desea asignar otra dirección IP a un dispositivo, puede usar esta columna.

  Tenga en cuenta que pueden pasar unos segundos antes de que se asigne una dirección IP nueva a un dispositivo recién autorizado.

  Puede verificar que su Raspberry Pi ahora se haya conectado a la red ZeroTier ejecutando el siguiente comando.

  ***sudo zerotier-cli listnetworks***

  Este comando enumerará todas las redes a las que está conectada su instalación de ZeroTier y el estado de esa conexión.

  A continuación se muestra un ejemplo de lo que debería ver cuando su Raspberry Pi se haya

  conectado correctamente a su red ZeroTier. El último valor es la dirección IP que se asignó a su

  Raspberry Pi como miembro de la red virtual.

  *200 listnetworks \[Network ID] \[Network NAME] \[Network Address] OK PRIVATE \[Virtual Name] \[Virtual IP]*

  Su Raspberry Pi ahora debería haberse unido con éxito a su red ZeroTier.

  Ahora podrá conectarse con cualquier otro dispositivo que forme parte de la red virtual. Todo lo que necesita saber es la dirección IP de ese dispositivo.

  El lugar más fácil para encontrar las direcciones IP asignadas a un dispositivo es a través de la interfaz central ZeroTier.

  Recuerde que si está utilizando un firewall en su Raspberry Pi, como UFW , aún deberá permitir el tráfico de aplicaciones para la red virtual.


# Recuperar impresión fallida en Klipper

Cómo recuperar una impresión fallida en Klipper: guía completa con SET\_KINEMATIC\_POSITION, BLTouch/ABL, edición de G-Code y macros de rescate.

No hay nada que duela más que ver una pieza al 80% y que, de repente, se produzca un atasco, se acabe el filamento o un gato decida que el cable de alimentación es un juguete.

Si no has movido la pieza de la cama, respira hondo. Aquí tienes posibles caminos de cómo resucitar tu impresión.

{% hint style="danger" %}
**Antes de hacer nada, asegúrate de que:**

1. **La pieza sigue pegada**: Si se ha despegado o la has movido, apaga y vámonos. No hay alineación que salve eso.
2. **No hagas Home (G28) completo**: Si haces un Home en Z con la pieza en la cama, el cabezal chocará. Haremos el homing con "trampas".
3. **Mantén la temperatura de la cama**: Si la cama se enfría, la pieza se contraerá y se despegará. Usa el panel web o el comando `SET_HEATER_TEMPERATURE HEATER=heater_bed TARGET=60` (ajusta el `TARGET` a la temperatura que usabas).
   {% endhint %}

## ¿Todavía tienes el homing?

Si la impresora se ha pausado o detenido pero **no ha perdido el posicionamiento** (los motores siguen activos), prueba primero lo más sencillo:

1. **Intenta hacer Resume** desde Mainsail/Fluidd. A veces es suficiente.
2. Si el Resume falla, comprueba que el `idle_timeout` no haya desactivado los motores. Añade esto a tu `printer.cfg` para evitarlo:

```ini
[idle_timeout]
timeout: 3600  ; 1 hora — ajusta según tus necesidades
```

O envía por consola mientras trabajas:

```
SET_IDLE_TIMEOUT TIMEOUT=4200
```

3. Si el resume sigue fallando, sigue leyendo.

***

## Preparación previa (hazlo ANTES de que falle una impresión)

Esta sección es para configurar Klipper correctamente antes de que ocurra un problema. Si ya tienes una impresión fallida, continúa al siguiente paso.

### Guardar la malla de cama (esencial con BLTouch/CRTouch/ABL)

Si usas nivelación automática, **guarda siempre tu malla con un nombre**, nunca uses el perfil `default`. Si Klipper se reinicia, el perfil `default` puede desaparecer:

```
BED_MESH_PROFILE SAVE=impresion_actual
```

O desde la UI de Klipper (Mainsail): ve a **HEIGHTMAP → CURRENT MESH**, haz clic en el nombre `default` y cámbialo.

### Macros de rescate (añade a `macros.cfg`)

Instala estas macros antes de que las necesites. Te ahorrarán tiempo y errores cuando estés en modo pánico:

```jinja
#=====================================================
# RESCUE_Z — Posicionar Z en altura conocida
#=====================================================
[gcode_macro RESCUE_Z]
description: "Establece la posición Z a la altura medida de la impresión fallida"
gcode:
    {% set z_height = params.Z|default(0)|float %}
    SET_KINEMATIC_POSITION Z={z_height}
    M117 Z establecido a {z_height}mm

#=====================================================
# SET_Z0 — Poner Z actual a 0
#=====================================================
[gcode_macro SET_Z0]
description: "Establece la posición Z actual como Z=0"
gcode:
    G92 Z0

#=====================================================
# IDLE_TO_70MIN — Ampliar timeout para trabajar sin prisas
#=====================================================
[gcode_macro IDLE_TO_70MIN]
description: "Establece idle timeout a 70 minutos"
gcode:
    SET_IDLE_TIMEOUT TIMEOUT=4200

#=====================================================
# FORCE_MOVE_Z — Mover Z por fuerza sin homing
#=====================================================
[force_move]
enable_force_move: True

[gcode_macro FORCE_MOVE_Z]
description: "Mueve Z por fuerza sin homing — usar con cuidado"
gcode:
    SET_FORCE_MOVE ENABLE=1
    {% set stepper = params.STEPPER|default("stepper_z")|string %}
    {% set distance = params.DISTANCE|default(-0.1)|float %}
    {% set velocity = params.VELOCITY|default(10)|float %}
    SET_KINEMATIC_POSITION Z=0
    FORCE_MOVE STEPPER={stepper} DISTANCE={distance} VELOCITY={velocity}
    SET_GCODE_OFFSET Z=0
    G92 Z={distance}
    SET_FORCE_MOVE ENABLE=0
```

{% hint style="warning" %}
`FORCE_MOVE_Z` mueve en **milímetros reales** sin límites de software. Empieza siempre con valores pequeños (0.1–1mm) y verifica visualmente antes de continuar. Un valor incorrecto puede dañar la pieza o la impresora.
{% endhint %}

### Macro de inicio para impresión rescatada (con BLTouch/ABL)

Esta macro sustituye a tu `START_PRINT` habitual: solo hace home en X/Y, carga la malla guardada y **no toca el eje Z**:

```jinja
[gcode_macro START_PRINT_RESCUE]
gcode:
    {% set BED_TEMP = params.BED_TEMP|default(60)|float %}
    {% set EXTRUDER_TEMP = params.EXTRUDER_TEMP|default(190)|float %}
    {% set MESH_PROFILE = params.MESH|default("impresion_actual")|string %}

    SET_IDLE_TIMEOUT TIMEOUT=600
    G90               ; coordenadas absolutas
    M83               ; extrusor en modo relativo

    M104 S{EXTRUDER_TEMP}   ; calentar extrusor
    M140 S{BED_TEMP}        ; calentar cama

    G28 X Y                             ; home solo X e Y — NUNCA Z
    BED_MESH_PROFILE LOAD={MESH_PROFILE} ; cargar malla guardada

    M109 S{EXTRUDER_TEMP}   ; esperar temperatura extrusor
    M190 S{BED_TEMP}        ; esperar temperatura cama

    G0 Z10 F240             ; subir a altura segura
    M106 S255               ; ventilador al máximo
```

***

## Proceso de recuperación

{% stepper %}
{% step %}

#### Paso 1 — Determinar la altura de fallo (Z)

Necesitamos saber exactamente en qué milímetro se quedó la impresora.

* **Método calibre (más preciso)**: Mide la altura de la pieza impresa con un calibre digital. Si mide 42.4 mm, esa es tu referencia.
* **Método visual**: Busca una geometría reconocible en la pieza (una ranura, un cambio de forma) y búscala en la previsualización del G-code del laminador para identificar la altura exacta.
* **Método Klipper**: Mueve el cabezal sobre una zona terminada de la pieza y baja el eje Z de 0.1 en 0.1 hasta que la boquilla casi toque la última capa. Lee el valor de Z en la consola.

{% hint style="info" %}
Es mejor quedarse 0.1–0.2 mm corto (que la boquilla imprima ligeramente en el aire al principio) que pasarse y que el cabezal choque y arranque la pieza de la cama.
{% endhint %}
{% endstep %}

{% step %}

#### Paso 2 — Establecer el home de Z sin mover la impresora

Aquí hay dos métodos dependiendo de si tienes BLTouch/ABL o no:

{% tabs %}
{% tab title="Con BLTouch / ABL — Método Z-Booking" %}
Este método usa el sensor ABL para hacer un home "falso" de Z sobre un objeto plano colocado encima de la pieza:

1. **Ten el botón de parada de emergencia a mano en todo momento**.
2. Coloca un objeto **rígido, plano y fino** (un libro de tapa dura, una lámina metálica) encima de tu impresión. El BLTouch necesita apoyarse en él.
3. Ejecuta `G28 X Y` para hacer home solo en X e Y.
4. Ejecuta `G28 Z` (o "Home Z" desde la UI). El sensor tocará el libro, no la cama. Klipper cree que ha hecho home en Z, pero en realidad está sobre tu pieza.
5. Retira el objeto con cuidado.
6. Amplía el timeout para trabajar sin prisa: `IDLE_TO_70MIN`
7. Mueve el cabezal cerca de la última capa usando `FORCE_MOVE_Z DISTANCE=-XX` (valores pequeños, verifica visualmente con un papel).
8. Cuando el papel roza la boquilla con algo de fricción, estás en la altura correcta.
9. Establece la altura real: `RESCUE_Z Z=42.4` (usa tu medida).
   {% endtab %}

{% tab title="Sin ABL — SET\_KINEMATIC\_POSITION directo" %}
Si no tienes sensor ABL o prefieres el método directo:

1. Haz home en X e Y: `G28 X Y` (nunca en Z).
2. Mueve el cabezal manualmente sobre la pieza y baja en pequeños incrementos hasta estar a \~0.2 mm de la última capa.
3. Engaña a Klipper sobre la posición Z:

```
SET_KINEMATIC_POSITION Z=42.4
```

*Sustituye 42.4 por tu altura medida.* Klipper "cree" que está en esa altura y ya puedes moverte con seguridad.

O usa la macro de rescate:

```
RESCUE_Z Z=42.4
```

{% endtab %}
{% endtabs %}
{% endstep %}

{% step %}

#### Paso 3 — Editar el G-Code

Aquí ocurre la "magia". Descarga el archivo `.gcode` desde Mainsail (sección **G-CODE FILES**) y ábrelo con un editor de texto (VS Code, Notepad++):

**3.1 — Encontrar la altura**

Usa `Ctrl+F` para buscar el valor de Z donde falló la impresión. Si la altura es 42.4 mm, busca `Z42.4`, `Z42.39`, etc., hasta encontrar la línea exacta o la más cercana por debajo.

**3.2 — Eliminar el G-code ya impreso**

Borra todo desde el inicio hasta justo antes de la capa donde se quedó. **Mantén** únicamente:

* La llamada al macro de inicio (la cambiarás en el siguiente punto)
* El G-code desde la última capa hacia el final

**3.3 — Sustituir el macro de inicio**

Cambia la llamada a `START_PRINT` por `START_PRINT_RESCUE`:

```
; Antes:
START_PRINT BED_TEMP=60 EXTRUDER_TEMP=210

; Después:
START_PRINT_RESCUE BED_TEMP=60 EXTRUDER_TEMP=210 MESH=impresion_actual
```

**3.4 — Corregir el contador de extrusión**

{% hint style="warning" %}
**Crítico si tu laminador usa extrusión absoluta (la mayoría: Cura, OrcaSlicer, etc.)**

Si empiezas en mitad del archivo, el G-code tendrá algo como `G1 E1500.5`. Si tu impresora cree que está en `E0`, intentará empujar 1.5 metros de filamento de golpe.

**Solución**: Justo antes de la primera línea de impresión, añade:

```
G92 E1500.5 ; Sustituye 1500.5 por el valor E de la línea donde empiezas
```

{% endhint %}

**3.5 — Restaurar el ventilador**

Busca el último `M106 S...` antes del punto de reinicio e insértalo después del `G92 E` anterior. Alternativamente, ajústalo manualmente desde la UI antes de imprimir.

**3.6 — Limpiar la malla activa**

Para evitar conflictos con cualquier malla cargada previamente, añade al inicio del G-code editado:

```
BED_MESH_CLEAR
```

**3.7 — Bloque de seguridad para el movimiento inicial**

Esto evita que el cabezal se mueva en línea recta desde su posición actual hasta el primer punto de la capa (riesgo de colisión lateral):

```gcode
G91             ; coordenadas relativas
G1 Z5 F600      ; sube 5 mm por seguridad
G90             ; coordenadas absolutas
G1 X... Y...    ; mueve a la posición XY de inicio de la capa (mira el G-Code)
G1 Z...         ; baja a la altura de la capa de rescate
```

{% endstep %}

{% step %}

#### Paso 4 — Reinicio de impresión seguro

1. Calienta el nozzle a temperatura de impresión.
2. Limpia bien la punta de cualquier resto de filamento.
3. Carga el archivo G-code modificado e inicia la impresión.
4. **Vigila los primeros minutos** para asegurarte de que la nueva capa se adhiere correctamente a la impresión existente y no hay desplazamiento.
   {% endstep %}
   {% endstepper %}

***

## Método alternativo — Reslicear con 0 capas inferiores

Si conservas el proyecto de tu laminador (archivo de Cura, OrcaSlicer, etc.), este método puede ser más limpio que editar el G-code:

1. En el laminador, baja el objeto en el eje Z hasta que el inicio de la pieza quede en la altura exacta donde falló. Ejemplo: si falló a 36.95 mm, el objeto debe estar 36.95 mm por debajo de la cama (Z negativo).
2. **Elimina las capas inferiores** (Bottom Layers = 0 en Cura: sección Top/Bottom → Bottom Thickness).
3. Lamina normalmente.
4. En el G-code generado, sustituye `START_PRINT` por `START_PRINT_RESCUE` (como en el paso 3.3).
5. En la impresora, sigue el proceso de los pasos 1 y 2 para establecer la posición Z.
6. En el paso final, usa `SET_Z0` en lugar de `RESCUE_Z` (porque el nuevo G-code empieza en Z=0 relativo).

{% hint style="info" %}
Este método puede dar problemas si el infill o los perímetros no se alinean exactamente con la impresión existente. Para piezas funcionales o con geometría compleja, el método de edición de G-code suele dar mejores resultados.
{% endhint %}

***

## Referencias y recursos

{% embed url="<https://www.youtube.com/watch?v=-wjE8eDiKWg>" %}
CNC Kitchen — HOW TO: Resume a failed 3D print
{% endembed %}

{% embed url="<https://www.youtube.com/watch?v=kwywIc7wUn4>" %}
Emily The Engineer — How to Resume an Unfinished/Failed 3D Print
{% endembed %}

* [Documentación Klipper — SET\_KINEMATIC\_POSITION](https://www.klipper3d.org/G-Codes.html#set_kinematic_position)
* [Documentación Klipper — idle\_timeout](https://www.klipper3d.org/Config_Reference.html#idle_timeout)
* [Documentación Klipper — force\_move](https://www.klipper3d.org/Config_Reference.html#force_move)


# Klipper Troubleshooting

Guía completa de resolución de problemas en Klipper: diagnóstico, errores MCU, TMC, CAN bus, ADXL, configuración y cómo reportar correctamente en los grupos de soporte.

Pásate por nuestro [**grupo en español de Telegram sobre Klipper**](https://t.me/Klipper_Firmware_ES) para cualquier duda, y por nuestro [**grupo general 3Dwork**](https://t.me/trastornados) si el problema es más general.

Os recordamos que tienes más guías de ayuda en **nuestro bot de Telegram** [**@ThreeDWorkHelpBot**](https://t.me/ThreeDWorkHelpBot)

***

## 🆘 Cómo reportar un problema — léelo antes de preguntar

Esta sección existe por una razón muy sencilla: **sin información, no hay solución**. Klipper es un sistema complejo con cientos de variables. Decir "me da error" o "no funciona" es el equivalente a llamar al médico y decir "me duele algo". La persona que quiere ayudarte necesita datos reales para poder hacerlo.

{% hint style="danger" %}
**Las preguntas sin información no se pueden responder.**

Antes de publicar en cualquier grupo de soporte asegúrate de haber incluido **como mínimo** el log de Klipper. Sin él, cualquier diagnóstico es pura especulación y pierde el tiempo de todos.
{% endhint %}

### Checklist antes de preguntar

Marca estos puntos **antes** de publicar en el grupo:

* [ ] He leído el mensaje de error **completo** — no solo la primera línea
* [ ] He buscado el error en esta guía y en la [documentación oficial de Klipper](https://www.klipper3d.org/)
* [ ] He buscado si alguien tuvo el mismo problema en nuestros grupos: [**Klipper ES en Telegram**](https://t.me/Klipper_Firmware_ES) y [**3DWork**](https://t.me/trastornados)
* [ ] He revisado el log de Klipper (`klippy.log`) y buscado `!!` para encontrar los errores
* [ ] Si el error apareció tras una actualización, he revisado los [cambios de configuración de Klipper](https://github.com/Klipper3d/klipper/blob/master/docs/Config_Changes.md)
* [ ] **He ejecutado el script `klipper_logs` por SSH y tengo el enlace listo** (ver sección siguiente — es obligatorio)

### Qué información incluir en tu reporte

Usa este template cuando pidas ayuda:

```
🖨️ MODELO DE IMPRESORA: [ej. Voron 2.4, Ender 3 Pro, etc.]
⚡ ELECTRÓNICA / MCU: [ej. BTT Octopus, SKR Mini E3 v3]
🖥️ HOST: [ej. Raspberry Pi 4, BTT Pi v1.2, Orange Pi Zero 2W]
📦 VERSIÓN KLIPPER: [ver en Mainsail: Settings → About, o en klippy.log]
📦 VERSIÓN MAINSAIL/FLUIDD: [ver en la UI]

❌ DESCRIPCIÓN DEL PROBLEMA:
[Describe qué pasa exactamente, cuándo ocurre, si apareció tras algún cambio]

📋 MENSAJE DE ERROR EXACTO:
[Copia y pega el mensaje de error completo, no hagas foto de la pantalla]

🔗 LOGS: [link del script klipper_logs o adjunta el klippy.log]
```

{% hint style="warning" %}
**Fotos de la pantalla del móvil**: no las mandes. Los logs son texto — cópialos como texto o usa el script de abajo. Una foto de la pantalla hace imposible buscar el error y copiar comandos.
{% endhint %}

### 🔗 Compartir los logs en un enlace — el paso más importante

{% hint style="success" %}
**Esto es lo primero que debes hacer** antes de escribir en cualquier grupo de soporte. Un enlace de logs vale más que mil palabras. Sin logs, cualquier diagnóstico es especulación.
{% endhint %}

Existe un script SSH desarrollado por [**Andrey Kozhevnikov**](https://coderus.openrepos.net/klipper_logs/) que hace todo el trabajo por ti: se conecta a tu Raspberry Pi / host, recoge automáticamente los logs de Klipper, Moonraker, dmesg y los archivos de configuración, los sube a un servidor web y te devuelve **un enlace listo para pegar en el grupo**.

**¿Qué recopila el script?**

* `klippy.log` completo (el log principal de Klipper)
* `moonraker.log`
* Salida de `dmesg` (arranque del sistema y USB)
* Archivos de configuración (`printer.cfg` y todos los includes)

**Ejecución por SSH** — una sola línea en el terminal:

```bash
curl -L https://coderus.openrepos.net/klipper_logs/getlogs | bash -s
```

Si tienes una instalación no estándar o multi-instancia (cambia `printer_2_data` por tu directorio):

```bash
curl -L https://coderus.openrepos.net/klipper_logs/getlogs | bash -s -- printer_2_data
```

El script pedirá tu contraseña de usuario (la del host, no la de Klipper), recogerá todos los datos y al finalizar te mostrará algo así:

```
✅ Logs uploaded. Share this link:
https://logs.coderus.openrepos.net/logs/abc123xyz
```

Pega ese enlace en el grupo junto al template de reporte. Es todo lo que necesitan para diagnosticar tu problema.

![](https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FkxqQCum6RMQHpNC8mb47%2Fimage.png?alt=media\&token=6ade02ff-02d6-4601-8fc8-4ebec762b2d5)

{% hint style="info" %}
**Antes de ejecutar el script**, limpia los logs para que solo contengan información del problema actual. Instrucciones en [Log de Klipper](#acceder-al-log-de-klipper) y [Log de Moonraker](#acceder-al-log-de-moonraker).
{% endhint %}

{% hint style="info" %}
**Analizador de logs 3Dwork** — si quieres una primera pista antes de preguntar, pega tu log aquí:

<https://3dwork.io/tools/index.html#loganalyzer>
{% endhint %}

{% hint style="warning" %}
Aunque los logs no suelen contener información crítica, compártelos de forma privada con quien te esté ayudando cuando sea posible. Es tu responsabilidad el uso que se haga de esa información.
{% endhint %}

***

## 🔍 Diagnóstico inicial — por aquí siempre

Antes de ir a secciones específicas, sigue estos pasos en orden. Resuelven el **70% de los casos**:

{% stepper %}
{% step %}

#### 1. Lee el error completo

El error de Klipper siempre aparece en la UI (Mainsail/Fluidd) en el banner rojo. Haz clic en él para ver el texto completo. Busca las líneas que empiezan por `!!` en el log — ahí está la causa raíz.
{% endstep %}

{% step %}

#### 2. Comprueba el estado de los servicios

```bash
systemctl status klipper
systemctl status moonraker
```

Si alguno está en `failed` o `inactive`, ahí está el primer problema. Ve a la sección correspondiente.
{% endstep %}

{% step %}

#### 3. Revisa si el error apareció tras una actualización

Si actualizaste Klipper y algo dejó de funcionar, revisa primero:

* [Config\_Changes.md](https://github.com/Klipper3d/klipper/blob/master/docs/Config_Changes.md) — cambios que requieren adaptar la configuración
* Los errores `option XXX is not valid in section XXX` siempre son de configuración, no de hardware
  {% endstep %}

{% step %}

#### 4. Reinicia en el orden correcto

Muchos errores transitorios se resuelven con un reinicio ordenado:

```bash
sudo systemctl restart klipper
sudo systemctl restart moonraker
```

O desde Mainsail: **Power** → reiniciar host si el problema persiste.
{% endstep %}

{% step %}

#### 5. Si nada funciona: reinstala el firmware de la electrónica

Los errores de conexión MCU persistentes tras comprobar cableado y configuración casi siempre se resuelven recompilando y reflasheando el firmware Klipper en la electrónica.
{% endstep %}
{% endstepper %}

***

## Revisión de errores de servicios

Cuando un servicio no arranca, estos comandos dan la información detallada:

```bash
# Estado resumido del servicio
systemctl status klipper

# Log completo del servicio (útil para errores de arranque)
journalctl -u klipper -n 50 --no-pager

# Guardar en fichero para compartir
systemctl status klipper > ~/printer_data/logs/klipper_status.txt
journalctl -u klipper > ~/printer_data/logs/klipper_journal.txt
```

Aplica lo mismo para `moonraker`, `klipperscreen`, `crowsnest`, etc.

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FvwBi3VlVzvuVZdVObbSL%2Fimage.png?alt=media&amp;token=a8a3b8ed-654e-4668-a688-066ba70d5ef3" alt=""><figcaption></figcaption></figure>

***

## Klipper

El **60% de los problemas** se resuelven con los puntos siguientes. El **39% restante** son problemas de configuración. El **1% final** son bugs reales de Klipper.

### Errores MCU: Serial connection closed / Timeout on connect / Wait for identify\_response

Estos errores en el log (`klippy.log`) indican que Klipper no puede comunicarse con la electrónica.

**Posibles causas:**

* Cable USB de mala calidad, demasiado largo o con conectores flojos
* Firmware Klipper no flasheado correctamente en la electrónica (o no flasheado)
* Parámetros incorrectos en `make menuconfig` al compilar el firmware
* Electrónica dañada (parcialmente o en su comunicación serial)
* Versión de firmware en la electrónica desincronizada con la versión del host (ver más abajo)

**Diagnóstico:**

Desconecta y reconecta la electrónica por USB y ejecuta `sudo dmesg -e`. Una electrónica correctamente conectada debe mostrar algo como:

```
[xxx] usb X-X: New USB device found, idVendor=1d50, idProduct=614e
[xxx] usb X-X: Product: lpc1769
[xxx] usb X-X: Manufacturer: Klipper
[xxx] cdc_acm X-X:1.0: ttyACMX: USB ACM device
```

Si en `Manufacturer` no pone `Klipper` sino algo como `STMicroelectronics`, el firmware no se flasheó correctamente o la electrónica está en modo DFU.

**Soluciones:**

1. Verifica que `ls /dev/serial/by-id/*` muestra tu electrónica y que la ruta coincide exactamente con la que tienes en `[mcu]` de tu `printer.cfg`
2. Recompila y reflashea el firmware con `make menuconfig` verificando procesador, comunicación y bootloader
3. Prueba con otro cable USB (preferiblemente corto y de calidad, con datos — no solo carga)

### Pérdidas de comunicación / Reinicios MCU-Host

Causas habituales:

* **Alimentación insuficiente en el SBC** — el temido `undervoltage` en Raspberry Pi y similares. Usa fuente oficial o equivalente (5.1V, 3A mínimo), cable USB-C de calidad. Verifica con `vcgencmd get_throttled` — debe devolver `0x0`.
* **Temperatura del SBC** — throttling térmico provoca inestabilidad. Añade disipadores o ventilación activa.
* **Cable USB largo o de baja calidad** entre host y MCU.
* **Retroalimentación USB** — si tu electrónica no tiene jumper de aislamiento entre la alimentación USB y la de la impresora, tapa el pin VBUS del conector USB con cinta.

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/RHlbA2pdMXy5rCSdy59b/image.png" alt=""><figcaption></figcaption></figure>

{% hint style="warning" %}
**SBC undervoltage** es la causa número 1 de desconexiones aleatorias en Klipper con Raspberry Pi. Un cable USB de carga barato puede tener suficiente caída de tensión para provocar esto incluso con una buena fuente.
{% endhint %}

### Versión de firmware desincronizada

Si actualizas Klipper en el host pero no reflasheas el firmware en la electrónica (o viceversa), obtendrás errores de conexión o comportamientos inesperados.

**Cómo comprobarlo:** en Mainsail, la sección **System** muestra la versión de Klipper del host y la versión del firmware en cada MCU. Deben coincidir.

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/vBcBsuHCCeye6w5YtWgu/image.png" alt=""><figcaption></figcaption></figure>

**Solución:** recompila y reflashea el firmware en la electrónica cada vez que actualices Klipper en el host.

### Error ADC — fallo en lectura de termistores

Klipper se para por seguridad cuando no puede leer correctamente la temperatura de un termistor.

**Causas:**

* Pin incorrecto en la configuración
* Termistor desconectado, dañado o con mala conexión
* Tipo de termistor incorrecto en `sensor_type`

**Diagnóstico:**

```ini
# Verifica en printer.cfg que el sensor_type coincide con el termistor físico
# Ejemplo para NTC 100k estándar:
[extruder]
sensor_type: ATC Semitec 104GT-2
sensor_pin: PA0
```

Si el pin es correcto, mide la resistencia del termistor con un multímetro (a temperatura ambiente debe ser \~100kΩ para un NTC 100k). Un valor muy diferente indica termistor defectuoso.

### Errores TMC

Los drivers TMC pueden reportar errores por varias razones:

* **Driver sin alimentación**: los TMC2208/2209/2130/2160 no se inicializan si la electrónica no está alimentada por la fuente de la impresora (solo por USB no es suficiente)
* **Driver mal insertado**: verifica que el driver está correctamente colocado en su zócalo y los jumpers de microstepping/UART/SPI están correctos
* **Temperatura excesiva del driver**: sin refrigeración adecuada los TMC entran en protección térmica
* **Corriente demasiado alta**: baja el `run_current` en la configuración del driver

Para errores específicos consulta la [guía oficial de Klipper sobre drivers TMC](https://www.klipper3d.org/TMC_Drivers.html).

### Problemas con CAN bus

El CAN bus es cada vez más común (BTT EBB, Mellow FLY-UTOC, etc.) y tiene su propio proceso de diagnóstico.

**Verificar que el interface CAN está activo:**

```bash
ip link show can0
```

Si no aparece `can0`, el interface no está configurado. Debe aparecer como `UP` con la bitrate correcta (normalmente 1000000).

**Detectar dispositivos CAN:**

```bash
~/klippy-env/bin/python ~/klipper/scripts/canbus_query.py can0
```

Esto lista los UUIDs de todos los dispositivos en el bus. Si no aparece tu electrónica:

* Verifica el cableado: CANH y CANL deben ir trenzados entre sí (mínimo una vuelta cada 5 cm)
* Verifica que hay exactamente **dos resistencias de terminación de 120 Ω** en el bus — una en cada extremo
* Comprueba que el conector de alimentación del módulo CAN (U2C, UTOC, etc.) está bien conectado

{% hint style="info" %}
**120 Ω en ambos extremos es obligatorio.** Un bus CAN sin las resistencias de terminación correctas tendrá comunicación esporádica o nula. Mide con multímetro entre CANH y CANL: debe leer \~60 Ω (las dos resistencias en paralelo).
{% endhint %}

**Errores `bytes_invalid` incrementando:**

```bash
cat /proc/net/can/stats
```

Si el contador `bytes_invalid` no para de crecer, indica errores en el bus. Causas: velocidad de bitrate incorrecta, cableado defectuoso, interferencias.

**Tras una actualización de Klipper:**

Después de actualizar Klipper en el host, el firmware CAN en las placas cabezal (EBB, etc.) puede quedar desincronizado. Hay que reflashear también esas placas usando Katapult:

```bash
python3 ~/katapult/scripts/flashtool.py -i can0 -u <UUID> -f ~/klipper/out/klipper.bin
```

### Acelerómetros ADXL345 / MPU-6050 / LIS2DW

**Error: `Invalid adxl345 id (got XX vs e5)`:**

Problema de inicialización SPI. Intenta de nuevo — si persiste, revisa el cableado (MOSI, MISO, SCK, CS) y la calidad de las soldaduras. Un ID `xx` diferente de `e5` puede indicar sensor defectuoso o falsificado.

**Error: `Lost communication with MCU` al ejecutar `ACCELEROMETER_QUERY`:**

* Verifica que los pines SPI/I2C en `printer.cfg` son correctos para tu conexión
* Si usas SPI por software (`spi_software_*`), prueba reducir la velocidad: `spi_speed: 1000000`
* En Orange Pi y algunos SBC el SPI hardware puede ser inestable — prueba con SPI por software

**El test de resonancias genera gráficos extraños:**

* Asegúrate de que el acelerómetro está bien fijado mecánicamente — cualquier holgura contamina los datos
* Ejecuta primero `ACCELEROMETER_QUERY` para verificar que responde antes de lanzar `TEST_RESONANCES`
* Los picos múltiples o ruido de fondo alto suelen indicar tornillos del acelerómetro flojos

### Actualizar Klipper, Moonraker y frontends

La forma recomendada de actualizar es desde la propia UI de Mainsail/Fluidd (sección **Update Manager**), que actualiza todos los componentes de forma coordinada.

Si prefieres hacerlo por SSH:

```bash
# Actualizar Klipper
cd ~/klipper
git pull
sudo systemctl restart klipper

# Actualizar Moonraker
cd ~/moonraker
git pull
sudo systemctl restart moonraker
```

{% hint style="warning" %}
**Después de actualizar Klipper siempre:**

1. Revisa [Config\_Changes.md](https://github.com/Klipper3d/klipper/blob/master/docs/Config_Changes.md) por si hay cambios que afectan a tu configuración
2. Recompila y reflashea el firmware en **todas** tus MCUs (placa principal + cabezales CAN si los tienes)
   {% endhint %}

**Volver a una versión anterior de Klipper:**

```bash
cd ~/klipper
git log --oneline -10          # ver commits recientes
git checkout <commit_hash>     # volver a un commit específico
sudo systemctl restart klipper
```

### Error: `Heater not heating at expected rate` / `Heating timeout`

{% hint style="danger" %}
**Errores típicos:**

```
Heater extruder not heating at expected rate
Heating timeout: Extruder did not reach target temperature
Heater bed not heating at expected rate
```

Klipper monitoriza que el calentador sube de temperatura a un ritmo razonable. Si en 20 segundos no sube al menos 2 °C, cancela por seguridad.
{% endhint %}

**Causas y soluciones:**

| Causa                                 | Diagnóstico                                     | Solución                                           |
| ------------------------------------- | ----------------------------------------------- | -------------------------------------------------- |
| PID no calibrado (oscilaciones)       | Temperatura sube y baja sin estabilizarse       | Ejecuta `PID_CALIBRATE HEATER=extruder TARGET=200` |
| Tipo de termistor incorrecto          | Temperatura en pantalla muy diferente a la real | Verifica `sensor_type` en `printer.cfg`            |
| Cartucho calentador defectuoso        | No sube temperatura o sube muy lento            | Mide resistencia del cartucho (\~15-25 Ω a 24V)    |
| Entorno muy frío / corrientes de aire | Funciona en verano, falla en invierno           | Encierra la impresora o aumenta `heating_gain`     |
| Tensión de alimentación baja          | LED del hotend tenue                            | Mide voltaje en fuente: debe ser 24V ±0,5V         |
| Pin del calentador incorrecto         | Nunca calienta                                  | Verifica `heater_pin` en la configuración          |

**Cómo recalibrar el PID:**

```bash
# Para el hotend (reemplaza el target por tu temperatura habitual de impresión)
PID_CALIBRATE HEATER=extruder TARGET=200

# Para la cama
PID_CALIBRATE HEATER=heater_bed TARGET=60

# Al terminar, guarda los nuevos valores
SAVE_CONFIG
```

{% hint style="info" %}
Si el error ocurre solo con cama de gran formato (300×300 mm o más), es normal que tarde más en calentar. Puedes ajustar en `printer.cfg`:

```ini
[heater_bed]
heating_gain: 2        # tiempo mínimo de calentamiento (segundos por grado)
```

{% endhint %}

### Errores de homing / Endstop

**Error: `Endstop 'x' still triggered after retract`**

El endstop sigue reportando activado incluso después de que el cabezal retrocedió. Causas:

* **Polaridad invertida**: prueba añadir o quitar el `!` en el pin (`endstop_pin: !PG6` ↔ `endstop_pin: PG6`)
* **Endstop mecánico dañado**: con un multímetro en modo continuidad, verifica que el switch se abre y cierra correctamente al pulsarlo
* **Cableado**: cable cortocircuitado o con mala conexión

**Error: `Endstop 'x' not triggered` / `Homing failed: Timeout`**

El eje llega al límite de movimiento sin que el endstop lo detecte. Causas:

* **Posición del endstop**: el cabezal no alcanza el sensor antes de llegar al límite de recorrido del eje
* **Pin incorrecto**: verifica que `endstop_pin` apunta al pin físico correcto según el pinout de tu electrónica
* **Conector suelto**: revisa el conector del endstop en la placa

**Diagnóstico rápido desde la consola:**

```bash
# Comprueba el estado actual de todos los endstops
QUERY_ENDSTOPS
```

Con el endstop en reposo debe mostrar `open`. Al pulsarlo manualmente debe cambiar a `TRIGGERED`. Si siempre muestra `TRIGGERED` o nunca cambia, el problema es físico o de polaridad.

{% hint style="warning" %}
Con **sensores virtuales** (sensorless homing con TMC) los errores de homing son más difíciles de diagnosticar. El parámetro `driver_SGTHRS` (sensibilidad de stall) debe ajustarse para cada máquina. Consulta la [guía de sensorless homing](https://www.klipper3d.org/TMC_Drivers.html#sensorless-homing).
{% endhint %}

### Errores de probe (BLTouch / CR Touch / Klicky / Beacon)

**BLTouch / CR Touch — `BLTouch failed to deploy` o no retrae la aguja**

```
BLTouch failed to deploy
BLTouch failed to verify sensor state
```

| Síntoma                                                  | Causa probable                              | Solución                                                          |
| -------------------------------------------------------- | ------------------------------------------- | ----------------------------------------------------------------- |
| Aguja no baja al enviar `BLTOUCH_DEBUG COMMAND=pin_down` | Fallo eléctrico o de señal                  | Verifica los 5 cables: GND, 5V, GND señal, IN, OUT                |
| Aguja baja pero no sube                                  | Mecanismo interno atascado                  | Limpia el interior con aire comprimido; puede necesitar reemplazo |
| Probe triggered antes de tocar                           | Interferencias eléctricas                   | Añade condensador 100nF entre GND y la señal del probe            |
| Error intermitente                                       | `probe_count` muy alto o velocidad excesiva | Reduce velocidad: `speed: 2` en `[probe]`                         |

**Probe triggered prior to movement / probe already triggered:**

Klipper detecta el probe activo antes de intentar la medición. Causas:

* Aguja BLTouch bajada por un reset previo — envía `BLTOUCH_DEBUG COMMAND=reset`
* Polaridad incorrecta en `pin_up_reports_not_triggered` o `pin_up_touch_mode_reports_triggered`

**Calibración del offset Z del probe:**

Recuerda que el `z_offset` debe medirse con `PROBE_CALIBRATE` y guardarse con `SAVE_CONFIG`. Un offset incorrecto provoca que la primera capa sea demasiado alta o que el nozzle choque contra la cama.

```bash
# Lanza el asistente de calibración del probe
PROBE_CALIBRATE

# Al terminar, mueve Z manualmente hasta que una hoja de papel deslice con ligera resistencia
# Acepta con:
ACCEPT
SAVE_CONFIG
```

{% hint style="info" %}
Para una guía completa sobre todos los sensores de nivelación compatibles con Klipper (BLTouch, CR Touch, Klicky, Beacon, Eddy, inductivos...) consulta: [Sensor de nivelación — guía completa](https://klipper.3dwork.io/klipper/empezamos/sensor-nivelacion)
{% endhint %}

{% hint style="info" %}
**Sensores de inducción** (como el PL-08N): verifica que el voltaje de salida (NPN vs PNP) es compatible con tu electrónica. Un sensor PNP con una entrada NPN puede quemar el pin de la placa.
{% endhint %}

### Errores de configuración: `option XXX is not valid in section XXX`

Estos errores indican un problema en el parser del fichero de configuración. El log siempre indica el fichero y la línea exacta.

**Causas habituales:**

* Opción con nombre incorrecto o desactualizado
* Valor fuera del rango permitido
* Sección duplicada (Klipper carga los includes de forma secuencial; la última definición prevalece)

**Cambios de configuración frecuentes tras actualizar:**

{% tabs %}
{% tab title="minimum\_cruise\_ratio" %}
Desde el 13/03/2024, `max_accel_to_decel` fue reemplazado por `minimum_cruise_ratio`.

{% code title="Antes" %}

```ini
[printer]
max_accel: 1500
max_accel_to_decel: 750
```

{% endcode %}

{% code title="Ahora" %}

```ini
[printer]
max_accel: 1500
minimum_cruise_ratio: 0.5
```

{% endcode %}

`minimum_cruise_ratio: 0.5` es equivalente a `max_accel_to_decel` = 50% de `max_accel`. Si no defines este parámetro, Klipper usará 0.5 por defecto.
{% endtab %}

{% tab title="homing\_retract\_dist con scanners" %}
Con sensores tipo Beacon, Cartographer o Voron TAP, hay que añadir en `[stepper_z]`:

```ini
[stepper_z]
homing_retract_dist: 0
```

Sin esta línea Klipper intentará hacer una segunda pasada de homing que chocará con la cama.
{% endtab %}
{% endtabs %}

Consulta el historial completo de cambios en: <https://github.com/Klipper3d/klipper/blob/master/docs/Config_Changes.md>

### Error: `Move exceeds maximum extrusion`

{% hint style="danger" %}
**Error típico:**

```
! Move exceeds maximum extrusion (X.XXXmm^2 vs 0.640mm^2)
```

Este error aparece cuando Klipper detecta que la cantidad de filamento a extruir en un movimiento es desproporcionada respecto a la distancia recorrida. El valor `0.640mm^2` es el límite por defecto para una boquilla de 0,4 mm.
{% endhint %}

#### ¿Por qué ocurre?

Klipper calcula la sección transversal de la extrusión en cada movimiento: `mm_de_filamento / mm_de_desplazamiento`. Si ese cociente supera el parámetro `max_extrude_cross_section` del bloque `[extruder]`, detiene la impresión.

| Causa habitual                                  | Por qué lo provoca                                         |
| ----------------------------------------------- | ---------------------------------------------------------- |
| Línea de purga sin desplazamiento (o muy corto) | Extruye mucho filamento con muy poco movimiento            |
| Macro `START_PRINT` con purgado estático        | Igual que arriba: purga concentrada en un punto            |
| Torre de purga (AMS / MMU / ERCF)               | El cambio de color extruye en un área pequeña              |
| Mismatch `M82` / `M83` (absoluto vs relativo)   | Klipper interpreta la posición E como longitud enorme      |
| Boquilla grande (0,6 mm o más)                  | La sección transversal natural es mayor y supera el límite |

#### Solución 1 — Ajustar `max_extrude_cross_section`

En `printer.cfg`, dentro del bloque `[extruder]`:

```ini
[extruder]
max_extrude_cross_section: 5   # boquilla 0,4 mm
# max_extrude_cross_section: 10  # boquilla 0,6 mm
# max_extrude_cross_section: 15  # boquilla 0,8 mm o multicolor
```

{% hint style="warning" %}
No pongas valores de millones (ej. `99999999`). Eso desactiva la protección por completo y puede provocar atascos o daños al hotend. Un valor de **5–20** es suficiente para todos los casos normales.
{% endhint %}

#### Solución 2 — Corregir la línea de purga en el laminador

La purga debe **mover el cabezal mientras extruye**. Ejemplo correcto en el G-code de inicio:

```gcode
; Mover al punto de inicio de purga
G1 X5 Y5 Z0.3 F3000
; Purgar extrudiendo A LA VEZ que se mueve
G1 X120 E15 F1500
; Retraer y resetear la posición E
G92 E0
```

Si usas la macro `START_PRINT`, asegúrate de que la purga incluye `G92 E0` al final y que el cabezal se desplaza durante la extrusión. Consulta la guía de [configuración Klipper en laminadores](https://github.com/alienboyxp/gitbook_es_klipper_3dwork_io/blob/main/empezamos/configuracion-klipper-en-laminadores.md) para la estructura completa de la macro.

#### Solución 3 — Revisar el modo de extrusión (`M82` / `M83`)

Si el error muestra un valor de extrusión enorme (cientos o millones de mm²), el problema es casi seguro un mismatch de modo absoluto/relativo:

* `M82` → extrusión **absoluta** (el valor E es posición acumulada)
* `M83` → extrusión **relativa** (el valor E es incremento por movimiento)

Verifica que tu laminador y tu macro `START_PRINT` usan el mismo modo. Lo más seguro es añadir `M83` explícito al inicio de la macro y `G92 E0` tras cualquier purga.

#### Solución 4 — Impresión multicolor (AMS / MMU / ERCF)

Las torres de purga y los purge buckets generan extrusiones de alta densidad. Aumenta el límite:

```ini
[extruder]
max_extrude_cross_section: 15  # o 20 para torres grandes
```

Y asegúrate de que los scripts de cambio de filamento incluyen `G92 E0` antes de reanudar la impresión.

### Acceder al log de Klipper

{% tabs %}
{% tab title="UI (Mainsail/Fluidd)" %}
En Mainsail: **MACHINE → Log Files → klippy.log**

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/zN1t0gS3t07MJJ5V51jB/image.png" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
Para limpiar el log antes de reproducir el error (muy recomendable para el diagnóstico): haz clic en el icono de papelera junto a `klippy.log`.

<img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/kZy2CGFHUNe4Mqdb2TSV/image.png" alt="" data-size="original">
{% endhint %}
{% endtab %}

{% tab title="SSH" %}

```bash
# Localización del log
$HOME/printer_data/logs/klippy.log

# Limpiar el log (para reproducir el error en limpio)
: > ~/printer_data/logs/klippy.log
sudo systemctl restart klipper

# Ver las últimas líneas en tiempo real
tail -f ~/printer_data/logs/klippy.log

# Extraer información de un fallo de apagado
mkdir ~/work_dir && cd ~/work_dir
cp ~/printer_data/logs/klippy.log .
~/klipper/scripts/logextract.py ./klippy.log
```

{% endtab %}
{% endtabs %}

### Reiniciar el servicio Klipper

{% tabs %}
{% tab title="UI (Mainsail)" %}

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/njV9SaRAwv4058J3zpAH/image.png" alt=""><figcaption></figcaption></figure>
{% endtab %}

{% tab title="SSH" %}

```bash
sudo systemctl stop klipper       # parar
sudo systemctl start klipper      # iniciar
sudo systemctl restart klipper    # reiniciar
```

{% endtab %}
{% endtabs %}

***

## Mainsail / Fluidd

### Requerimientos en printer.cfg

Mainsail y Fluidd necesitan ciertas secciones en `printer.cfg` para funcionar correctamente. Si ves errores de acceso a gcodes o funciones que no aparecen, probablemente falta alguna de estas:

{% hint style="success" %}
La forma más sencilla es añadir el include correspondiente a tu `printer.cfg`:

```ini
[include mainsail.cfg]    # para Mainsail
# o
[include fluidd.cfg]      # para Fluidd
```

Si no tienes ese fichero, créalo a partir de:

* Mainsail: <https://github.com/mainsail-crew/mainsail-config/blob/master/client.cfg>
* Fluidd: <https://github.com/fluidd-core/fluidd-config/blob/master/client.cfg>
  {% endhint %}

Si necesitas añadirlas manualmente:

```ini
[pause_resume]
[display_status]
[virtual_sdcard]
path: ~/printer_data/gcodes
on_error_gcode: CANCEL_PRINT
```

### Errores de acceso a gcodes — "Unable to open file"

<figure><img src="https://276162026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH6gCE2fgkkpOScJ72TP7%2Fuploads%2FPwJ63hfyAtodFsU9WhUh%2Fimage.png?alt=media&amp;token=ec76a24b-5483-45dd-aec5-cc1b65733009" alt=""><figcaption></figcaption></figure>

**Causas:**

1. El path de `[virtual_sdcard]` no existe o es incorrecto
2. El usuario de Klipper no tiene permisos sobre ese directorio

**Solución:**

```bash
# Verificar que el directorio existe
ls ~/printer_data/gcodes

# Si no existe, crearlo
mkdir -p ~/printer_data/gcodes

# Corregir permisos (sustituye 'pi' por tu usuario si es diferente)
chown pi ~/printer_data/gcodes
chmod 755 ~/printer_data/gcodes
```

***

## Crowsnest

### Upgrade v3 a v4

Si tu webcam dejó de funcionar después de una actualización de Crowsnest, probablemente sea el cambio v3→v4 que modificó completamente la arquitectura del componente.

{% embed url="<https://crowsnest.mainsail.xyz/faq/upgrade-from-v3-to-v4>" %}

### Webcam no aparece en la UI

```bash
# Listar dispositivos de vídeo detectados
ls /dev/video*

# Ver log de Crowsnest
journalctl -u crowsnest -n 50 --no-pager
```

Si no hay ningún `/dev/video*`, el problema es de reconocimiento del dispositivo (driver), no de Crowsnest.

***

## Moonraker

### Incidentes históricos

<details>

<summary>Octubre 2022 — Cambio de estructura de directorios</summary>

Moonraker cambió la estructura de carpetas esperada. Síntoma: después de actualizar, Moonraker no se comunica con Klipper o no hay acceso a ficheros de configuración desde la UI.

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/UvGBpsbcUpbEo8IOeB5v/image.png)

La estructura correcta es:

```
~/printer_data/
├── config/          → printer.cfg, moonraker.conf, etc.
├── database/        → base de datos Moonraker
├── gcodes/          → ficheros gcode
├── logs/            → klippy.log, moonraker.log
└── systemd/         → moonraker.env
```

Para adaptar una instalación antigua, ejecuta el script incluido en Moonraker:

```bash
cd ~/moonraker
git pull
./scripts/data-path-fix.sh
```

</details>

<details>

<summary>Enero 2022 — Problema de permisos PolicyKit</summary>

Moonraker cambió de `sudo` a D-Bus para comunicarse con el sistema. Síntoma: aviso de PolicyKit en la UI.

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/H8VGQzoeXXWg6ijzJvpI/image.png)

```bash
cd ~/moonraker/scripts
./set-policykit-rules.sh
sudo systemctl restart moonraker
```

Si el script da errores:

```bash
sudo apt update && sudo apt install packagekit
```

</details>

### Acceder al log de Moonraker

{% tabs %}
{% tab title="UI (Mainsail)" %}
**MACHINE → Log Files → moonraker.log**

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/ILIFR4pLesyaaV2aKLpg/image.png" alt=""><figcaption></figcaption></figure>
{% endtab %}

{% tab title="SSH" %}

```bash
# Localización
$HOME/printer_data/logs/moonraker.log

# Limpiar
: > ~/printer_data/logs/moonraker.log
sudo systemctl restart moonraker

# Ver en tiempo real
tail -f ~/printer_data/logs/moonraker.log
```

{% endtab %}
{% endtabs %}

### Reiniciar Moonraker

{% tabs %}
{% tab title="UI (Mainsail)" %}

<figure><img src="https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/eBeCTIERe4hhH6uQHLt1/image.png" alt=""><figcaption></figcaption></figure>
{% endtab %}

{% tab title="SSH" %}

```bash
sudo systemctl restart moonraker
```

{% endtab %}
{% endtabs %}

***

## KlipperScreen

KlipperScreen tiene su propia documentación de troubleshooting muy completa que cubre la mayoría de problemas:

{% embed url="<https://klipperscreen.readthedocs.io/en/latest/Troubleshooting/>" %}

Los problemas más frecuentes son:

* **Pantalla en negro tras arrancar**: verifica la configuración del display en `/boot/config.txt` (para Raspberry Pi) o el overlay correspondiente para tu SBC
* **Touch no responde**: verifica la calibración táctil y los parámetros del overlay
* **KlipperScreen no conecta con Klipper**: revisa que Moonraker está funcionando y que la IP/socket en la configuración de KlipperScreen es correcta

```bash
# Log de KlipperScreen
journalctl -u KlipperScreen -n 50 --no-pager
```

***

## Creality Sonic Pad

{% hint style="warning" %}
**El Creality Sonic Pad fue descontinuado por Creality en 2024.** Si buscas una solución similar (Klipper en hardware dedicado), considera las alternativas: **BTT Pad 7** o cualquier SBC genérico con MainsailOS/FluiddOS.
{% endhint %}

La Sonic Pad usa una MCU Creality T800 sobre una distribución Linux especial (Tina, fork de OpenWRT para Allwinner). Los componentes Klipper que incluye son versiones muy antiguas y no actualizables directamente por el usuario.

**Por qué el grupo no da soporte habitual a la Sonic Pad:**

* Hardware propietario con poca documentación pública
* Klipper, Moonraker y Mainsail muy desactualizados (no se pueden actualizar sin intervención de Creality)
* Sin acceso a muchas funciones modernas de Klipper (macros, electrónicas nuevas, etc.)
* La comunidad no puede reproducir los problemas sin tener el hardware específico

**Si tienes una Sonic Pad y quieres Klipper oficial sin estas limitaciones**, existe un firmware alternativo no oficial:

{% content-ref url="/pages/YueUijEFKUo1HCuzEMwS" %}
[Creality Sonic Pad - Klipper Oficial, custom firmware](/klipper/instalacion/guias-instalacion-especificas-impresora-electronica/creality-klipper/creality-sonic-pad-klipper-oficial-custom-firmware)
{% endcontent-ref %}


# Creality

{% hint style="info" %}
**English**: Use your browser's built-in translation — Chrome and Edge detect the language automatically and offer to translate the page.
{% endhint %}


# QIDI

{% hint style="info" %}
**English**: Use your browser's built-in translation — Chrome and Edge detect the language automatically and offer to translate the page.
{% endhint %}


# Enraged Rabbit Carrot Feeder (ERCF)

MMU para tu máquina Klipper

El Enraged Rabbit Carrot Feeder, en adelante ERCF, es una máquina a modo de expansión para nuestras impresoras 3D que nos va a permitir poder utilizar multiples filamentos durante una impresión de una forma automatizada... simplificando... que vas a poder imprimir en varios colores/materiales.

Este proyecto fue iniciado por la comunidad, disponemos de **más información en su** [**Github**](https://github.com/EtteGit/EnragedRabbitProject), e inicialmente fue pensado para máquinas Voron aunque a día de hoy puede adaptarse a casi cualquier máquina.

## **Antes de comenzar!!!**

![](https://content.gitbook.com/content/H6gCE2fgkkpOScJ72TP7/blobs/X80gAmPPLStcEvFTI7hx/image.png)

Por favor, entiende que montar **ERCF** en tu impresora requiere de cierta experiencia con impresoras 3d, hardware y software. Puede no ser una tarea trivial para gente que se acaba de iniciar en el mundo 3D o que no dispone de unos mínimos conocimientos.

Lee antes la guía completa y entiende todos los pasos que explicamos. Si tienes cualquier duda del proceso por favor te aconsejamos unirte al grupo de Telegram[ ](https://t.me/Klipper_Firmware_ES/94927)[**Klipper ES - ERCF/MMU**](https://t.me/Klipper_Firmware_ES/94927) donde seguro te echaran una mano.

* Construccion
  * Kits disponibles (Fysetc, Funsor, Blurolls, Triangelabs)
  * Partes impresas
    * Buffer <https://github.com/geoffrey-young/filament-buffer>
  * Electronica (Bigtreetech, Mellow)
* Puesta en marcha
  * Ajustes máquina
  * Ajustes firmware
    * Sensorless <https://github.com/EtteGit/EnragedRabbitProject/tree/no_toolhead_sensor>
    * Happy <https://github.com/moggieuk/ERCF-Software-V3>
    * KlipperScreen <https://github.com/moggieuk/ERCF-Software-V3#klipperscreen-happy-hare-edition>
* Mods
  * Correa -> varilla <https://www.printables.com/model/544684-ercf-lead-screw-conversion>


# Quieres promocionar tus productos/empresa?

¿Tu empresa se dedica a la impresión 3D? En 3Dwork tendrás una oportunidad única para promocionar tus productos y servicios entre los usuarios del sector.

Ponte en contacto con nosotros hoy mismo para descubrir las opciones publicitarias. Estaremos encantados de ayudarte con ello.

{% embed url="<https://forms.gle/SgBQryZG9uvBax6e7>" %}


