From c74ede5ecc65c2bdd48927b5ee6d4be619dde670 Mon Sep 17 00:00:00 2001 From: william-aqn Date: Fri, 3 Oct 2025 00:23:37 +0300 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Micromake=C2=A0D1=20with=20MKS?= =?UTF-8?q?=C2=A0Gen=C2=A0L=C2=A0V2.1=20(#1146)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MKS-Gen-L-V2.1/Configuration.h | 3774 +++++++++++++ .../MKS-Gen-L-V2.1/Configuration_adv.h | 4753 +++++++++++++++++ .../Micromake-D1/MKS-Gen-L-V2.1/README.md | 42 + .../assets/makeboard_mini_2.1.2.webp | Bin 0 -> 175666 bytes .../MKS-Gen-L-V2.1/assets/mks_gen_l_v2.1.webp | Bin 0 -> 101362 bytes .../Micromake-D1/RAMPS-1.4/Configuration.h | 3777 +++++++++++++ .../RAMPS-1.4/Configuration_adv.h | 4751 ++++++++++++++++ 7 files changed, 17097 insertions(+) create mode 100644 config/examples/delta/Micromake-D1/MKS-Gen-L-V2.1/Configuration.h create mode 100644 config/examples/delta/Micromake-D1/MKS-Gen-L-V2.1/Configuration_adv.h create mode 100644 config/examples/delta/Micromake-D1/MKS-Gen-L-V2.1/README.md create mode 100644 config/examples/delta/Micromake-D1/MKS-Gen-L-V2.1/assets/makeboard_mini_2.1.2.webp create mode 100644 config/examples/delta/Micromake-D1/MKS-Gen-L-V2.1/assets/mks_gen_l_v2.1.webp create mode 100644 config/examples/delta/Micromake-D1/RAMPS-1.4/Configuration.h create mode 100644 config/examples/delta/Micromake-D1/RAMPS-1.4/Configuration_adv.h diff --git a/config/examples/delta/Micromake-D1/MKS-Gen-L-V2.1/Configuration.h b/config/examples/delta/Micromake-D1/MKS-Gen-L-V2.1/Configuration.h new file mode 100644 index 0000000000..d7d9011908 --- /dev/null +++ b/config/examples/delta/Micromake-D1/MKS-Gen-L-V2.1/Configuration.h @@ -0,0 +1,3774 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2025 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once +#error "Don't build with import-2.1.x configurations!" +#error "Use the 'bugfix...' or 'release...' configurations matching your Marlin version." + +/** + * Configuration.h + * + * Basic settings such as: + * + * - Type of electronics + * - Type of temperature sensor + * - Printer geometry + * - Endstop configuration + * - LCD controller + * - Extra features + * + * Advanced settings can be found in Configuration_adv.h + */ +#define CONFIGURATION_H_VERSION 02010300 + +//=========================================================================== +//============================= Getting Started ============================= +//=========================================================================== + +/** + * Here are some useful links to help get your machine configured and calibrated: + * + * Example Configs: https://github.com/MarlinFirmware/Configurations/branches/all + * + * Průša Calculator: https://blog.prusa3d.com/calculator_3416/ + * + * Calibration Guides: https://reprap.org/wiki/Calibration + * https://reprap.org/wiki/Triffid_Hunter%27s_Calibration_Guide + * https://web.archive.org/web/20220907014303/sites.google.com/site/repraplogphase/calibration-of-your-reprap + * https://youtu.be/wAL9d7FgInk + * https://teachingtechyt.github.io/calibration.html + * + * Calibration Objects: https://www.thingiverse.com/thing:5573 + * https://www.thingiverse.com/thing:1278865 + */ + +// @section info + +// Author info of this build printed to the host during boot and M115 +#define STRING_CONFIG_H_AUTHOR "DCRM" // Original author or contributor. +//#define CUSTOM_VERSION_FILE Version.h // Path from the root directory (no quotes) + +// @section machine + +// Choose the name from boards.h that matches your setup +#ifndef MOTHERBOARD + #define MOTHERBOARD BOARD_MKS_GEN_L_V21 + //#define BOARD_INFO_NAME "Micromake 1.0" +#endif + +// @section serial + +/** + * Select the serial port on the board to use for communication with the host. + * This allows the connection of wireless adapters (for instance) to non-default port pins. + * Serial port -1 is the USB emulated serial port, if available. + * Note: The first serial port (-1 or 0) will always be used by the Arduino bootloader. + * + * :[-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9] + */ +#define SERIAL_PORT 0 + +/** + * Serial Port Baud Rate + * This is the default communication speed for all serial ports. + * Set the baud rate defaults for additional serial ports below. + * + * 250000 works in most cases, but you might try a lower speed if + * you commonly experience drop-outs during host printing. + * You may try up to 1000000 to speed up SD file transfer. + * + * :[2400, 9600, 19200, 38400, 57600, 115200, 250000, 500000, 1000000] + */ +#define BAUDRATE 115200 + +//#define BAUD_RATE_GCODE // Enable G-code M575 to set the baud rate + +/** + * Select a secondary serial port on the board to use for communication with the host. + * Currently Ethernet (-2) is only supported on Teensy 4.1 boards. + * :[-2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9] + */ +//#define SERIAL_PORT_2 -1 +//#define BAUDRATE_2 250000 // :[2400, 9600, 19200, 38400, 57600, 115200, 250000, 500000, 1000000] Enable to override BAUDRATE + +/** + * Select a third serial port on the board to use for communication with the host. + * Currently supported for AVR, DUE, SAMD51, LPC1768/9, STM32/STM32F1/HC32, and Teensy 4.x + * :[-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9] + */ +//#define SERIAL_PORT_3 1 +//#define BAUDRATE_3 250000 // :[2400, 9600, 19200, 38400, 57600, 115200, 250000, 500000, 1000000] Enable to override BAUDRATE + +/** + * Select a serial port to communicate with RS485 protocol + * :[-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9] + */ +//#define RS485_SERIAL_PORT 1 +#ifdef RS485_SERIAL_PORT + //#define M485_PROTOCOL 1 // Check your host for protocol compatibility + //#define RS485_BUS_BUFFER_SIZE 128 +#endif + +// Enable CAN bus support and protocol +//#define CAN_HOST +//#define CAN_TOOLHEAD +#if ANY(CAN_HOST, CAN_TOOLHEAD) + //#define CAN_DEBUG +#endif + +// Enable the Bluetooth serial interface on AT90USB devices +//#define BLUETOOTH + +// Name displayed in the LCD "Ready" message and Info menu +#define CUSTOM_MACHINE_NAME "Micromake D1" +//#define CONFIGURABLE_MACHINE_NAME // Add G-code M550 to set/report the machine name + +// Printer's unique ID, used by some programs to differentiate between machines. +// Choose your own or use a service like https://www.uuidgenerator.net/version4 +//#define MACHINE_UUID "00000000-0000-0000-0000-000000000000" + +// @section stepper drivers + +/** + * Stepper Drivers + * + * These settings allow Marlin to tune stepper driver timing and enable advanced options for + * stepper drivers that support them. You may also override timing options in Configuration_adv.h. + * + * Use TMC2208/TMC2208_STANDALONE for TMC2225 drivers and TMC2209/TMC2209_STANDALONE for TMC2226 drivers. + * + * Options: A4988, A5984, DRV8825, LV8729, TB6560, TB6600, TMC2100, + * TMC2130, TMC2130_STANDALONE, TMC2160, TMC2160_STANDALONE, + * TMC2208, TMC2208_STANDALONE, TMC2209, TMC2209_STANDALONE, + * TMC2240, TMC2660, TMC2660_STANDALONE, + * TMC5130, TMC5130_STANDALONE, TMC5160, TMC5160_STANDALONE + * :['A4988', 'A5984', 'DRV8825', 'LV8729', 'TB6560', 'TB6600', 'TMC2100', 'TMC2130', 'TMC2130_STANDALONE', 'TMC2160', 'TMC2160_STANDALONE', 'TMC2208', 'TMC2208_STANDALONE', 'TMC2209', 'TMC2209_STANDALONE', 'TMC2240', 'TMC2660', 'TMC2660_STANDALONE', 'TMC5130', 'TMC5130_STANDALONE', 'TMC5160', 'TMC5160_STANDALONE'] + */ +#define X_DRIVER_TYPE TMC2209 +#define Y_DRIVER_TYPE TMC2209 +#define Z_DRIVER_TYPE TMC2209 +//#define X2_DRIVER_TYPE A4988 +//#define Y2_DRIVER_TYPE A4988 +//#define Z2_DRIVER_TYPE A4988 +//#define Z3_DRIVER_TYPE A4988 +//#define Z4_DRIVER_TYPE A4988 +//#define I_DRIVER_TYPE A4988 +//#define J_DRIVER_TYPE A4988 +//#define K_DRIVER_TYPE A4988 +//#define U_DRIVER_TYPE A4988 +//#define V_DRIVER_TYPE A4988 +//#define W_DRIVER_TYPE A4988 +#define E0_DRIVER_TYPE TMC2209 +//#define E1_DRIVER_TYPE A4988 +//#define E2_DRIVER_TYPE A4988 +//#define E3_DRIVER_TYPE A4988 +//#define E4_DRIVER_TYPE A4988 +//#define E5_DRIVER_TYPE A4988 +//#define E6_DRIVER_TYPE A4988 +//#define E7_DRIVER_TYPE A4988 + +/** + * Additional Axis Settings + * + * Define AXISn_ROTATES for all axes that rotate or pivot. + * Rotational axis coordinates are expressed in degrees. + * + * AXISn_NAME defines the letter used to refer to the axis in (most) G-code commands. + * By convention the names and roles are typically: + * 'A' : Rotational axis parallel to X + * 'B' : Rotational axis parallel to Y + * 'C' : Rotational axis parallel to Z + * 'U' : Secondary linear axis parallel to X + * 'V' : Secondary linear axis parallel to Y + * 'W' : Secondary linear axis parallel to Z + * + * Regardless of these settings the axes are internally named I, J, K, U, V, W. + */ +#ifdef I_DRIVER_TYPE + #define AXIS4_NAME 'A' // :['A', 'B', 'C', 'U', 'V', 'W'] + #define AXIS4_ROTATES +#endif +#ifdef J_DRIVER_TYPE + #define AXIS5_NAME 'B' // :['B', 'C', 'U', 'V', 'W'] + #define AXIS5_ROTATES +#endif +#ifdef K_DRIVER_TYPE + #define AXIS6_NAME 'C' // :['C', 'U', 'V', 'W'] + #define AXIS6_ROTATES +#endif +#ifdef U_DRIVER_TYPE + #define AXIS7_NAME 'U' // :['U', 'V', 'W'] + //#define AXIS7_ROTATES +#endif +#ifdef V_DRIVER_TYPE + #define AXIS8_NAME 'V' // :['V', 'W'] + //#define AXIS8_ROTATES +#endif +#ifdef W_DRIVER_TYPE + #define AXIS9_NAME 'W' // :['W'] + //#define AXIS9_ROTATES +#endif + +// @section extruder + +// This defines the number of extruders +// :[0, 1, 2, 3, 4, 5, 6, 7, 8] +#define EXTRUDERS 1 + +// Generally expected filament diameter (1.75, 2.85, 3.0, ...). Used for Volumetric, Filament Width Sensor, etc. +#define DEFAULT_NOMINAL_FILAMENT_DIA 1.75 + +// For Cyclops or any "multi-extruder" that shares a single nozzle. +//#define SINGLENOZZLE + +// Save and restore temperature and fan speed on tool-change. +// Set standby for the unselected tool with M104/106/109 T... +#if ENABLED(SINGLENOZZLE) + //#define SINGLENOZZLE_STANDBY_TEMP + //#define SINGLENOZZLE_STANDBY_FAN +#endif + +// A dual extruder that uses a single stepper motor +//#define SWITCHING_EXTRUDER +#if ENABLED(SWITCHING_EXTRUDER) + #define SWITCHING_EXTRUDER_SERVO_NR 0 + #define SWITCHING_EXTRUDER_SERVO_ANGLES { 0, 90 } // Angles for E0, E1[, E2, E3] + #if EXTRUDERS > 3 + #define SWITCHING_EXTRUDER_E23_SERVO_NR 1 + #endif +#endif + +// Switch extruders by bumping the toolhead. Requires EVENT_GCODE_TOOLCHANGE_#. +//#define MECHANICAL_SWITCHING_EXTRUDER + +/** + * A dual-nozzle that uses a servomotor to raise/lower one (or both) of the nozzles. + * Can be combined with SWITCHING_EXTRUDER. + */ +//#define SWITCHING_NOZZLE +#if ENABLED(SWITCHING_NOZZLE) + #define SWITCHING_NOZZLE_SERVO_NR 0 + //#define SWITCHING_NOZZLE_E1_SERVO_NR 1 // If two servos are used, the index of the second + #define SWITCHING_NOZZLE_SERVO_ANGLES { 0, 90 } // A pair of angles for { E0, E1 }. + // For Dual Servo use two pairs: { { lower, raise }, { lower, raise } } + #define SWITCHING_NOZZLE_SERVO_DWELL 2500 // Dwell time to wait for servo to make physical move + #define SWITCHING_NOZZLE_LIFT_TO_PROBE // Lift toolheads out of the way while probing +#endif + +// Switch nozzles by bumping the toolhead. Requires EVENT_GCODE_TOOLCHANGE_#. +//#define MECHANICAL_SWITCHING_NOZZLE + +/** + * Two separate X-carriages with extruders that connect to a moving part + * via a solenoid docking mechanism. Requires SOL1_PIN and SOL2_PIN. + */ +//#define PARKING_EXTRUDER + +/** + * Two separate X-carriages with extruders that connect to a moving part + * via a magnetic docking mechanism using movements and no solenoid + * + * project : https://www.thingiverse.com/thing:3080893 + * movements : https://youtu.be/0xCEiG9VS3k + * https://youtu.be/Bqbcs0CU2FE + */ +//#define MAGNETIC_PARKING_EXTRUDER + +#if ANY(PARKING_EXTRUDER, MAGNETIC_PARKING_EXTRUDER) + + #define PARKING_EXTRUDER_PARKING_X { -78, 184 } // X positions for parking the extruders + #define PARKING_EXTRUDER_GRAB_DISTANCE 1 // (mm) Distance to move beyond the parking point to grab the extruder + + #if ENABLED(PARKING_EXTRUDER) + + #define PARKING_EXTRUDER_SOLENOIDS_INVERT // If enabled, the solenoid is NOT magnetized with applied voltage + #define PARKING_EXTRUDER_SOLENOIDS_PINS_ACTIVE LOW // LOW or HIGH pin signal energizes the coil + #define PARKING_EXTRUDER_SOLENOIDS_DELAY 250 // (ms) Delay for magnetic field. No delay if 0 or not defined. + //#define MANUAL_SOLENOID_CONTROL // Manual control of docking solenoids with M380 S / M381 + + #elif ENABLED(MAGNETIC_PARKING_EXTRUDER) + + #define MPE_FAST_SPEED 9000 // (mm/min) Speed for travel before last distance point + #define MPE_SLOW_SPEED 4500 // (mm/min) Speed for last distance travel to park and couple + #define MPE_TRAVEL_DISTANCE 10 // (mm) Last distance point + #define MPE_COMPENSATION 0 // Offset Compensation -1 , 0 , 1 (multiplier) only for coupling + + #endif + +#endif + +/** + * Switching Toolhead + * + * Support for swappable and dockable toolheads, such as + * the E3D Tool Changer. Toolheads are locked with a servo. + */ +//#define SWITCHING_TOOLHEAD + +/** + * Magnetic Switching Toolhead + * + * Support swappable and dockable toolheads with a magnetic + * docking mechanism using movement and no servo. + */ +//#define MAGNETIC_SWITCHING_TOOLHEAD + +/** + * Electromagnetic Switching Toolhead + * + * Parking for CoreXY / HBot kinematics. + * Toolheads are parked at one edge and held with an electromagnet. + * Supports more than 2 Toolheads. See https://youtu.be/JolbsAKTKf4 + */ +//#define ELECTROMAGNETIC_SWITCHING_TOOLHEAD + +#if ANY(SWITCHING_TOOLHEAD, MAGNETIC_SWITCHING_TOOLHEAD, ELECTROMAGNETIC_SWITCHING_TOOLHEAD) + #define SWITCHING_TOOLHEAD_Y_POS 235 // (mm) Y position of the toolhead dock + #define SWITCHING_TOOLHEAD_Y_SECURITY 10 // (mm) Security distance Y axis + #define SWITCHING_TOOLHEAD_Y_CLEAR 60 // (mm) Minimum distance from dock for unobstructed X axis + #define SWITCHING_TOOLHEAD_X_POS { 215, 0 } // (mm) X positions for parking the extruders + #if ENABLED(SWITCHING_TOOLHEAD) + #define SWITCHING_TOOLHEAD_SERVO_NR 2 // Index of the servo connector + #define SWITCHING_TOOLHEAD_SERVO_ANGLES { 0, 180 } // (degrees) Angles for Lock, Unlock + #elif ENABLED(MAGNETIC_SWITCHING_TOOLHEAD) + #define SWITCHING_TOOLHEAD_Y_RELEASE 5 // (mm) Security distance Y axis + #define SWITCHING_TOOLHEAD_X_SECURITY { 90, 150 } // (mm) Security distance X axis (T0,T1) + //#define PRIME_BEFORE_REMOVE // Prime the nozzle before release from the dock + #if ENABLED(PRIME_BEFORE_REMOVE) + #define SWITCHING_TOOLHEAD_PRIME_MM 20 // (mm) Extruder prime length + #define SWITCHING_TOOLHEAD_RETRACT_MM 10 // (mm) Retract after priming length + #define SWITCHING_TOOLHEAD_PRIME_FEEDRATE 300 // (mm/min) Extruder prime feedrate + #define SWITCHING_TOOLHEAD_RETRACT_FEEDRATE 2400 // (mm/min) Extruder retract feedrate + #endif + #elif ENABLED(ELECTROMAGNETIC_SWITCHING_TOOLHEAD) + #define SWITCHING_TOOLHEAD_Z_HOP 2 // (mm) Z raise for switching + #endif +#endif + +/** + * "Mixing Extruder" + * - Adds G-codes M163 and M164 to set and "commit" the current mix factors. + * - Extends the stepping routines to move multiple steppers in proportion to the mix. + * - Optional support for Repetier Firmware's 'M164 S' supporting virtual tools. + * - This implementation supports up to two mixing extruders. + * - Enable DIRECT_MIXING_IN_G1 for M165 and mixing in G1 (from Pia Taubert's reference implementation). + */ +//#define MIXING_EXTRUDER +#if ENABLED(MIXING_EXTRUDER) + #define MIXING_STEPPERS 2 // Number of steppers in your mixing extruder + #define MIXING_VIRTUAL_TOOLS 16 // Use the Virtual Tool method with M163 and M164 + //#define DIRECT_MIXING_IN_G1 // Allow ABCDHI mix factors in G1 movement commands + //#define GRADIENT_MIX // Support for gradient mixing with M166 and LCD + //#define MIXING_PRESETS // Assign 8 default V-tool presets for 2 or 3 MIXING_STEPPERS + #if ENABLED(GRADIENT_MIX) + //#define GRADIENT_VTOOL // Add M166 T to use a V-tool index as a Gradient alias + #endif +#endif + +// Offset of the extruders (uncomment if using more than one and relying on firmware to position when changing). +// The offset has to be X=0, Y=0 for the extruder 0 hotend (default extruder). +// For the other hotends it is their distance from the extruder 0 hotend. +//#define HOTEND_OFFSET_X { 0.0, 20.00 } // (mm) relative X-offset for each nozzle +//#define HOTEND_OFFSET_Y { 0.0, 5.00 } // (mm) relative Y-offset for each nozzle +//#define HOTEND_OFFSET_Z { 0.0, 0.00 } // (mm) relative Z-offset for each nozzle + +// @section multi-material + +/** + * Multi-Material Unit + * Set to one of these predefined models: + * + * PRUSA_MMU1 : Průša MMU1 (The "multiplexer" version) + * PRUSA_MMU2 : Průša MMU2 + * PRUSA_MMU2S : Průša MMU2S (Requires MK3S extruder with motion sensor, EXTRUDERS = 5) + * PRUSA_MMU3 : Průša MMU3 (Requires MK3S extruder with motion sensor and MMU firmware version 3.x.x, EXTRUDERS = 5) + * EXTENDABLE_EMU_MMU2 : MMU with configurable number of filaments (ERCF, SMuFF or similar with Průša MMU2 compatible firmware) + * EXTENDABLE_EMU_MMU2S : MMUS with configurable number of filaments (ERCF, SMuFF or similar with Průša MMU2 compatible firmware) + * + * Requires NOZZLE_PARK_FEATURE to park print head in case MMU unit fails. + * See additional options in Configuration_adv.h. + * :["PRUSA_MMU1", "PRUSA_MMU2", "PRUSA_MMU2S", "PRUSA_MMU3", "EXTENDABLE_EMU_MMU2", "EXTENDABLE_EMU_MMU2S"] + */ +//#define MMU_MODEL PRUSA_MMU3 + +// @section psu control + +/** + * Power Supply Control + * + * Enable and connect the power supply to the PS_ON_PIN. + * Specify whether the power supply is active HIGH or active LOW. + */ +//#define PSU_CONTROL +//#define PSU_NAME "Power Supply" + +#if ENABLED(PSU_CONTROL) + //#define MKS_PWC // Using the MKS PWC add-on + //#define PS_OFF_CONFIRM // Confirm dialog when power off + //#define PS_OFF_SOUND // Beep 1s when power off + #define PSU_ACTIVE_STATE LOW // Set 'LOW' for ATX, 'HIGH' for X-Box + + //#define PSU_DEFAULT_OFF // Keep power off until enabled directly with M80 + //#define PSU_POWERUP_DELAY 250 // (ms) Delay for the PSU to warm up to full power + //#define LED_POWEROFF_TIMEOUT 10000 // (ms) Turn off LEDs after power-off, with this amount of delay + + //#define PSU_OFF_REDUNDANT // Second pin for redundant power control + //#define PSU_OFF_REDUNDANT_INVERTED // Redundant pin state is the inverse of PSU_ACTIVE_STATE + + //#define PS_ON1_PIN 6 // Redundant pin required to enable power in combination with PS_ON_PIN + + //#define PS_ON_EDM_PIN 8 // External Device Monitoring pins for external power control relay feedback. Fault on mismatch. + //#define PS_ON1_EDM_PIN 9 + #define PS_EDM_RESPONSE 250 // (ms) Time to allow for relay action + + //#define POWER_OFF_TIMER // Enable M81 D to power off after a delay + //#define POWER_OFF_WAIT_FOR_COOLDOWN // Enable M81 S to power off only after cooldown + + //#define PSU_POWERUP_GCODE "M355 S1" // G-code to run after power-on (e.g., case light on) + //#define PSU_POWEROFF_GCODE "M355 S0" // G-code to run before power-off (e.g., case light off) + + //#define AUTO_POWER_CONTROL // Enable automatic control of the PS_ON pin + #if ENABLED(AUTO_POWER_CONTROL) + #define AUTO_POWER_FANS // Turn on PSU for fans + #define AUTO_POWER_E_FANS // Turn on PSU for E Fans + #define AUTO_POWER_CONTROLLERFAN // Turn on PSU for Controller Fan + #define AUTO_POWER_CHAMBER_FAN // Turn on PSU for Chamber Fan + #define AUTO_POWER_COOLER_FAN // Turn on PSU for Cooler Fan + #define AUTO_POWER_SPINDLE_LASER // Turn on PSU for Spindle/Laser + #define POWER_TIMEOUT 30 // (s) Turn off power if the machine is idle for this duration + //#define POWER_OFF_DELAY 60 // (s) Delay of poweroff after M81 command. Useful to let fans run for extra time. + #endif + #if ANY(AUTO_POWER_CONTROL, POWER_OFF_WAIT_FOR_COOLDOWN) + //#define AUTO_POWER_E_TEMP 50 // (°C) PSU on if any extruder is over this temperature + //#define AUTO_POWER_CHAMBER_TEMP 30 // (°C) PSU on if the chamber is over this temperature + //#define AUTO_POWER_COOLER_TEMP 26 // (°C) PSU on if the cooler is over this temperature + #endif +#endif + +//=========================================================================== +//============================= Thermal Settings ============================ +//=========================================================================== +// @section temperature + +/** + * Temperature Sensors: + * + * NORMAL IS 4.7kΩ PULLUP! Hotend sensors can use 1kΩ pullup with correct resistor and table. + * + * ================================================================ + * Analog Thermistors - 4.7kΩ pullup - Normal + * ================================================================ + * 1 : 100kΩ EPCOS - Best choice for EPCOS thermistors + * 331 : 100kΩ Same as #1, but 3.3V scaled for MEGA + * 332 : 100kΩ Same as #1, but 3.3V scaled for DUE + * 2 : 200kΩ ATC Semitec 204GT-2 + * 202 : 200kΩ Copymaster 3D + * 3 : ???Ω Mendel-parts thermistor + * 4 : 10kΩ Generic Thermistor !! DO NOT use for a hotend - it gives bad resolution at high temp. !! + * 5 : 100kΩ ATC Semitec 104GT-2/104NT-4-R025H42G - Used in ParCan, J-Head, and E3D, SliceEngineering 300°C + * 501 : 100kΩ Zonestar - Tronxy X3A + * 502 : 100kΩ Zonestar - used by hot bed in Zonestar Průša P802M + * 503 : 100kΩ Zonestar (Z8XM2) Heated Bed thermistor + * 504 : 100kΩ Zonestar P802QR2 (Part# QWG-104F-B3950) Hotend Thermistor + * 505 : 100kΩ Zonestar P802QR2 (Part# QWG-104F-3950) Bed Thermistor + * 512 : 100kΩ RPW-Ultra hotend + * 6 : 100kΩ EPCOS - Not as accurate as table #1 (created using a fluke thermocouple) + * 7 : 100kΩ Honeywell 135-104LAG-J01 + * 71 : 100kΩ Honeywell 135-104LAF-J01 + * 8 : 100kΩ Vishay 0603 SMD NTCS0603E3104FXT + * 9 : 100kΩ GE Sensing AL03006-58.2K-97-G1 + * 10 : 100kΩ RS PRO 198-961 + * 11 : 100kΩ Keenovo AC silicone mats, most Wanhao i3 machines - beta 3950, 1% + * 12 : 100kΩ Vishay 0603 SMD NTCS0603E3104FXT (#8) - calibrated for Makibox hot bed + * 13 : 100kΩ Hisens up to 300°C - for "Simple ONE" & "All In ONE" hotend - beta 3950, 1% + * 14 : 100kΩ (R25), 4092K (beta25), 4.7kΩ pull-up, bed thermistor as used in Ender-5 S1 + * 15 : 100kΩ Calibrated for JGAurora A5 hotend + * 17 : 100kΩ Dagoma NTC white thermistor + * 18 : 200kΩ ATC Semitec 204GT-2 Dagoma.Fr - MKS_Base_DKU001327 + * 22 : 100kΩ GTM32 Pro vB - hotend - 4.7kΩ pullup to 3.3V and 220Ω to analog input + * 23 : 100kΩ GTM32 Pro vB - bed - 4.7kΩ pullup to 3.3v and 220Ω to analog input + * 30 : 100kΩ Kis3d Silicone heating mat 200W/300W with 6mm precision cast plate (EN AW 5083) NTC100K - beta 3950 + * 60 : 100kΩ Maker's Tool Works Kapton Bed Thermistor - beta 3950 + * 61 : 100kΩ Formbot/Vivedino 350°C Thermistor - beta 3950 + * 66 : 4.7MΩ Dyze Design / Trianglelab T-D500 500°C High Temperature Thermistor + * 67 : 500kΩ SliceEngineering 450°C Thermistor + * 68 : PT100 Smplifier board from Dyze Design + * 70 : 100kΩ bq Hephestos 2 + * 75 : 100kΩ Generic Silicon Heat Pad with NTC100K MGB18-104F39050L32 + * 666 : 200kΩ Einstart S custom thermistor with 10k pullup. + * 2000 : 100kΩ Ultimachine Rambo TDK NTCG104LH104KT1 NTC100K motherboard Thermistor + * + * ================================================================ + * Analog Thermistors - 1kΩ pullup + * Atypical, and requires changing out the 4.7kΩ pullup for 1kΩ. + * (but gives greater accuracy and more stable PID) + * ================================================================ + * 51 : 100kΩ EPCOS (1kΩ pullup) + * 52 : 200kΩ ATC Semitec 204GT-2 (1kΩ pullup) + * 55 : 100kΩ ATC Semitec 104GT-2 - Used in ParCan & J-Head (1kΩ pullup) + * + * ================================================================ + * Analog Thermistors - 10kΩ pullup - Atypical + * ================================================================ + * 99 : 100kΩ Found on some Wanhao i3 machines with a 10kΩ pull-up resistor + * + * ================================================================ + * Analog RTDs (Pt100/Pt1000) + * ================================================================ + * 110 : Pt100 with 1kΩ pullup (atypical) + * 147 : Pt100 with 4.7kΩ pullup + * 1010 : Pt1000 with 1kΩ pullup (atypical) + * 1022 : Pt1000 with 2.2kΩ pullup + * 1047 : Pt1000 with 4.7kΩ pullup (E3D) + * 20 : Pt100 with circuit in the Ultimainboard V2.x with mainboard ADC reference voltage = INA826 amplifier-board supply voltage. + * NOTE: (1) Must use an ADC input with no pullup. (2) Some INA826 amplifiers are unreliable at 3.3V so consider using sensor 147, 110, or 21. + * 21 : Pt100 with circuit in the Ultimainboard V2.x with 3.3v ADC reference voltage (STM32, LPC176x....) and 5V INA826 amplifier board supply. + * NOTE: ADC pins are not 5V tolerant. Not recommended because it's possible to damage the CPU by going over 500°C. + * 201 : Pt100 with circuit in Overlord, similar to Ultimainboard V2.x + * + * ================================================================ + * SPI RTD/Thermocouple Boards + * ================================================================ + * -5 : MAX31865 with Pt100/Pt1000, 2, 3, or 4-wire (only for sensors 0-2 and bed) + * NOTE: You must uncomment/set the MAX31865_*_OHMS_n defines below. + * -3 : MAX31855 with Thermocouple, -200°C to +700°C (only for sensors 0-2 and bed) + * -2 : MAX6675 with Thermocouple, 0°C to +700°C (only for sensors 0-2 and bed) + * + * NOTE: Ensure TEMP_n_CS_PIN is set in your pins file for each TEMP_SENSOR_n using an SPI Thermocouple. By default, + * Hardware SPI on the default serial bus is used. If you have also set TEMP_n_SCK_PIN and TEMP_n_MISO_PIN, + * Software SPI will be used on those ports instead. You can force Hardware SPI on the default bus in the + * Configuration_adv.h file. At this time, separate Hardware SPI buses for sensors are not supported. + * + * ================================================================ + * Analog Thermocouple Boards + * ================================================================ + * -4 : AD8495 with Thermocouple + * -1 : AD595 with Thermocouple + * + * ================================================================ + * SoC internal sensor + * ================================================================ + * 100 : SoC internal sensor + * + * ================================================================ + * Custom/Dummy/Other Thermal Sensors + * ================================================================ + * 0 : not used + * 1000 : Custom - Specify parameters in Configuration_adv.h + * + * !!! Use these for Testing or Development purposes. NEVER for production machine. !!! + * 998 : Dummy Table that ALWAYS reads 25°C or the temperature defined below. + * 999 : Dummy Table that ALWAYS reads 100°C or the temperature defined below. + */ +#define TEMP_SENSOR_0 1 +#define TEMP_SENSOR_1 0 +#define TEMP_SENSOR_2 0 +#define TEMP_SENSOR_3 0 +#define TEMP_SENSOR_4 0 +#define TEMP_SENSOR_5 0 +#define TEMP_SENSOR_6 0 +#define TEMP_SENSOR_7 0 +#define TEMP_SENSOR_BED 1 +#define TEMP_SENSOR_PROBE 0 +#define TEMP_SENSOR_CHAMBER 0 +#define TEMP_SENSOR_COOLER 0 +#define TEMP_SENSOR_BOARD 0 +#define TEMP_SENSOR_SOC 0 +#define TEMP_SENSOR_REDUNDANT 0 + +// Dummy thermistor constant temperature readings, for use with 998 and 999 +#define DUMMY_THERMISTOR_998_VALUE 25 +#define DUMMY_THERMISTOR_999_VALUE 100 + +// Resistor values when using MAX31865 sensors (-5) on TEMP_SENSOR_0 / 1 / 2 / BED +#if TEMP_SENSOR_IS_MAX_TC(0) + #define MAX31865_SENSOR_OHMS_0 100 // (Ω) Typically 100 or 1000 (PT100 or PT1000) + #define MAX31865_CALIBRATION_OHMS_0 430 // (Ω) Typically 430 for Adafruit PT100; 4300 for Adafruit PT1000 +#endif +#if TEMP_SENSOR_IS_MAX_TC(1) + #define MAX31865_SENSOR_OHMS_1 100 + #define MAX31865_CALIBRATION_OHMS_1 430 +#endif +#if TEMP_SENSOR_IS_MAX_TC(2) + #define MAX31865_SENSOR_OHMS_2 100 + #define MAX31865_CALIBRATION_OHMS_2 430 +#endif +#if TEMP_SENSOR_IS_MAX_TC(BED) + #define MAX31865_SENSOR_OHMS_BED 100 + #define MAX31865_CALIBRATION_OHMS_BED 430 +#endif + +#if HAS_E_TEMP_SENSOR + #define TEMP_RESIDENCY_TIME 10 // (seconds) Time to wait for hotend to "settle" in M109 + #define TEMP_WINDOW 1 // (°C) Temperature proximity for the "temperature reached" timer + #define TEMP_HYSTERESIS 3 // (°C) Temperature proximity considered "close enough" to the target +#endif + +#if TEMP_SENSOR_BED + #define TEMP_BED_RESIDENCY_TIME 10 // (seconds) Time to wait for bed to "settle" in M190 + #define TEMP_BED_WINDOW 1 // (°C) Temperature proximity for the "temperature reached" timer + #define TEMP_BED_HYSTERESIS 3 // (°C) Temperature proximity considered "close enough" to the target +#endif + +#if TEMP_SENSOR_CHAMBER + #define TEMP_CHAMBER_RESIDENCY_TIME 10 // (seconds) Time to wait for chamber to "settle" in M191 + #define TEMP_CHAMBER_WINDOW 1 // (°C) Temperature proximity for the "temperature reached" timer + #define TEMP_CHAMBER_HYSTERESIS 3 // (°C) Temperature proximity considered "close enough" to the target +#endif + +/** + * Redundant Temperature Sensor (TEMP_SENSOR_REDUNDANT) + * + * Use a temp sensor as a redundant sensor for another reading. Select an unused temperature sensor, and another + * sensor you'd like it to be redundant for. If the two thermistors differ by TEMP_SENSOR_REDUNDANT_MAX_DIFF (°C), + * the print will be aborted. Whichever sensor is selected will have its normal functions disabled; i.e. selecting + * the Bed sensor (-1) will disable bed heating/monitoring. + * + * For selecting source/target use: COOLER, PROBE, BOARD, CHAMBER, BED, E0, E1, E2, E3, E4, E5, E6, E7 + */ +#if TEMP_SENSOR_REDUNDANT + #define TEMP_SENSOR_REDUNDANT_SOURCE E1 // The sensor that will provide the redundant reading. + #define TEMP_SENSOR_REDUNDANT_TARGET E0 // The sensor that we are providing a redundant reading for. + #define TEMP_SENSOR_REDUNDANT_MAX_DIFF 10 // (°C) Temperature difference that will trigger a print abort. +#endif + +// Below this temperature the heater will be switched off +// because it probably indicates a broken thermistor wire. +#define HEATER_0_MINTEMP 5 +#define HEATER_1_MINTEMP 5 +#define HEATER_2_MINTEMP 5 +#define HEATER_3_MINTEMP 5 +#define HEATER_4_MINTEMP 5 +#define HEATER_5_MINTEMP 5 +#define HEATER_6_MINTEMP 5 +#define HEATER_7_MINTEMP 5 +#define BED_MINTEMP 5 +#define CHAMBER_MINTEMP 5 + +// Above this temperature the heater will be switched off. +// This can protect components from overheating, but NOT from shorts and failures. +// (Use MINTEMP for thermistor short/failure protection.) +#define HEATER_0_MAXTEMP 275 +#define HEATER_1_MAXTEMP 275 +#define HEATER_2_MAXTEMP 275 +#define HEATER_3_MAXTEMP 275 +#define HEATER_4_MAXTEMP 275 +#define HEATER_5_MAXTEMP 275 +#define HEATER_6_MAXTEMP 275 +#define HEATER_7_MAXTEMP 275 +#define BED_MAXTEMP 120 +#define CHAMBER_MAXTEMP 60 + +/** + * Thermal Overshoot + * During heatup (and printing) the temperature can often "overshoot" the target by many degrees + * (especially before PID tuning). Setting the target temperature too close to MAXTEMP guarantees + * a MAXTEMP shutdown! Use these values to forbid temperatures being set too close to MAXTEMP. + */ +#define HOTEND_OVERSHOOT 15 // (°C) Forbid temperatures over MAXTEMP - OVERSHOOT +#define BED_OVERSHOOT 10 // (°C) Forbid temperatures over MAXTEMP - OVERSHOOT +#define COOLER_OVERSHOOT 2 // (°C) Forbid temperatures closer than OVERSHOOT + +//=========================================================================== +//============================= PID Settings ================================ +//=========================================================================== + +// @section hotend temp + +/** + * Temperature Control + * + * (NONE) : Bang-bang heating + * PIDTEMP : PID temperature control (~4.1K) + * MPCTEMP : Predictive Model temperature control. (~1.8K without auto-tune) + */ +#define PIDTEMP // See the PID Tuning Guide at https://reprap.org/wiki/PID_Tuning +//#define MPCTEMP // See https://marlinfw.org/docs/features/model_predictive_control.html + +#define PID_MAX 255 // Limit hotend current while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define PID_K1 0.95 // Smoothing factor within any PID loop + +#if ENABLED(PIDTEMP) + //#define MIN_POWER 0 // Min power to improve PID stability (0..PID_MAX). + // Get the power from the temperature report ('M105' => @:nnn) and try P*2-20 to P*2-10. + //#define PID_DEBUG // Print PID debug data to the serial port. Use 'M303 D' to enable/disable. + //#define PID_PARAMS_PER_HOTEND // Use separate PID parameters for each extruder (useful for mismatched extruders) + // Set/get with G-code: M301 E[extruder number, 0-2] + + #if ENABLED(PID_PARAMS_PER_HOTEND) + // Specify up to one value per hotend here, according to your setup. + // If there are fewer values, the last one applies to the remaining hotends. + #define DEFAULT_Kp_LIST { 22.20, 22.20 } + #define DEFAULT_Ki_LIST { 1.08, 1.08 } + #define DEFAULT_Kd_LIST { 114.00, 114.00 } + #else + #define DEFAULT_Kp 37.73 + #define DEFAULT_Ki 4.34 + #define DEFAULT_Kd 81.90 + #endif +#else + #define BANG_MAX 255 // Limit hotend current while in bang-bang mode; 255=full current +#endif + +/** + * Model Predictive Control for hotend + * + * Use a physical model of the hotend to control temperature. When configured correctly this gives + * better responsiveness and stability than PID and removes the need for PID_EXTRUSION_SCALING + * and PID_FAN_SCALING. Enable MPC_AUTOTUNE and use M306 T to autotune the model. + * @section mpc temp + */ +#if ENABLED(MPCTEMP) + #define MPC_AUTOTUNE // Include a method to do MPC auto-tuning (~6.3K bytes of flash) + #if ENABLED(MPC_AUTOTUNE) + //#define MPC_AUTOTUNE_DEBUG // Enable MPC debug logging (~870 bytes of flash) + #endif + //#define MPC_EDIT_MENU // Add MPC editing to the "Advanced Settings" menu. (~1.3K bytes of flash) + //#define MPC_AUTOTUNE_MENU // Add MPC auto-tuning to the "Advanced Settings" menu. (~350 bytes of flash) + + #define MPC_MAX 255 // (0..255) Current to nozzle while MPC is active. + #define MPC_HEATER_POWER { 40.0f } // (W) Nominal heat cartridge powers. + //#define MPC_PTC // Hotend power changes with temperature (e.g., PTC heat cartridges). + #if ENABLED(MPC_PTC) + #define MPC_HEATER_ALPHA { 0.0028f } // Temperature coefficient of resistance of the heat cartridges. + #define MPC_HEATER_REFTEMP { 20 } // (°C) Reference temperature for MPC_HEATER_POWER and MPC_HEATER_ALPHA. + #endif + + #define MPC_INCLUDE_FAN // Model the fan speed? + + // Measured physical constants from M306 + #define MPC_BLOCK_HEAT_CAPACITY { 16.7f } // (J/K) Heat block heat capacities. + #define MPC_SENSOR_RESPONSIVENESS { 0.22f } // (K/s per ∆K) Rate of change of sensor temperature from heat block. + #define MPC_AMBIENT_XFER_COEFF { 0.068f } // (W/K) Heat transfer coefficients from heat block to room air with fan off. + #if ENABLED(MPC_INCLUDE_FAN) + #define MPC_AMBIENT_XFER_COEFF_FAN255 { 0.097f } // (W/K) Heat transfer coefficients from heat block to room air with fan on full. + #endif + + // For one fan and multiple hotends MPC needs to know how to apply the fan cooling effect. + #if ENABLED(MPC_INCLUDE_FAN) + //#define MPC_FAN_0_ALL_HOTENDS + //#define MPC_FAN_0_ACTIVE_HOTEND + #endif + + // Filament Heat Capacity (joules/kelvin/mm) + // Set at runtime with M306 H + #define FILAMENT_HEAT_CAPACITY_PERMM { 5.6e-3f } // 0.0056 J/K/mm for 1.75mm PLA (0.0149 J/K/mm for 2.85mm PLA). + // 0.0036 J/K/mm for 1.75mm PETG (0.0094 J/K/mm for 2.85mm PETG). + // 0.00515 J/K/mm for 1.75mm ABS (0.0137 J/K/mm for 2.85mm ABS). + // 0.00522 J/K/mm for 1.75mm Nylon (0.0138 J/K/mm for 2.85mm Nylon). + + // Advanced options + #define MPC_SMOOTHING_FACTOR 0.5f // (0.0...1.0) Noisy temperature sensors may need a lower value for stabilization. + #define MPC_MIN_AMBIENT_CHANGE 1.0f // (K/s) Modeled ambient temperature rate of change, when correcting model inaccuracies. + #define MPC_STEADYSTATE 0.5f // (K/s) Temperature change rate for steady state logic to be enforced. + + #define MPC_TUNING_POS { X_CENTER, Y_CENTER, 1.0f } // (mm) M306 Autotuning position, ideally bed center at first layer height. + #define MPC_TUNING_END_Z 10.0f // (mm) M306 Autotuning final Z position. + //#define EVENT_GCODE_AFTER_MPC_TUNE "M84" // G-code to execute after MPC tune finished and Z raised. +#endif + +//=========================================================================== +//====================== PID > Bed Temperature Control ====================== +//=========================================================================== + +// @section bed temp + +/** + * Max Bed Power + * Applies to all forms of bed control (PID, bang-bang, and bang-bang with hysteresis). + * When set to any value below 255, enables a form of PWM to the bed that acts like a divider + * so don't use it unless you are OK with PWM on your bed. (See the comment on enabling PIDTEMPBED) + */ +#define MAX_BED_POWER 255 // limits duty cycle to bed; 255=full current + +/** + * PID Bed Heating + * + * The PID frequency will be the same as the extruder PWM. + * If PID_dT is the default, and correct for the hardware/configuration, that means 7.689Hz, + * which is fine for driving a square wave into a resistive load and does not significantly + * impact FET heating. This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W + * heater. If your configuration is significantly different than this and you don't understand + * the issues involved, don't use bed PID until someone else verifies that your hardware works. + * + * With this option disabled, bang-bang will be used. BED_LIMIT_SWITCHING enables hysteresis. + */ +//#define PIDTEMPBED + +#if ENABLED(PIDTEMPBED) + //#define MIN_BED_POWER 0 // Min power to improve PID stability (0..MAX_BED_POWER). + // Get the power from the temperature report ('M105' => B@:nnn) and try P*2-20 to P*2-10. + //#define PID_BED_DEBUG // Print Bed PID debug data to the serial port. Use 'M303 D' to enable/disable. + + // 120V 250W silicone heater into 4mm borosilicate (MendelMax 1.5+) + // from FOPDT model - kp=.39 Tp=405 Tdead=66, Tc set to 79.2, aggressive factor of .15 (vs .1, 1, 10) + #define DEFAULT_bedKp 10.00 + #define DEFAULT_bedKi 0.023 + #define DEFAULT_bedKd 305.4 + + // FIND YOUR OWN: "M303 E-1 C8 S90" to run autotune on the bed at 90 degreesC for 8 cycles. +#else + //#define BED_LIMIT_SWITCHING // Keep the bed temperature within BED_HYSTERESIS of the target +#endif + +/** + * Peltier Bed - Heating and Cooling + * + * A Peltier device transfers heat from one side to the other in proportion to the amount of + * current flowing through the device and the direction of current flow. So the same device + * can both heat and cool. + * + * When "cooling" in addition to rejecting the heat transferred from the hot side to the cold + * side, the dissipated power (voltage * current) must also be rejected. Be sure to set up a + * fan that can be powered in sync with the Peltier unit. + * + * This feature is only set up to run in bang-bang mode because Peltiers don't handle PWM + * well without filter circuitry. + * + * Since existing 3D printers are made to handle relatively high current for the heated bed, + * we can use the heated bed power pins to control the Peltier power using the same G-codes + * as the heated bed (M140, M190, etc.). + * + * A second GPIO pin is required to control current direction. + * Two configurations are possible: Relay and H-Bridge + * + * (At this time only relay is supported. H-bridge requires 4 MOS switches configured in H-Bridge.) + * + * Power is handled by the bang-bang control loop: 0 or 255. + * Cooling applications are more common than heating, so the pin states are commonly: + * LOW = Heating = Relay Energized + * HIGH = Cooling = Relay in "Normal" state + */ +//#define PELTIER_BED +#if ENABLED(PELTIER_BED) + #define PELTIER_DIR_PIN -1 // Relay control pin for Peltier + #define PELTIER_DIR_HEAT_STATE LOW // The relay pin state that causes the Peltier to heat +#endif + +// Add 'M190 R T' for more gradual M190 R bed cooling. +//#define BED_ANNEALING_GCODE + +//=========================================================================== +//==================== PID > Chamber Temperature Control ==================== +//=========================================================================== + +/** + * PID Chamber Heating + * + * If this option is enabled set PID constants below. + * If this option is disabled, bang-bang will be used and CHAMBER_LIMIT_SWITCHING will enable + * hysteresis. + * + * The PID frequency will be the same as the extruder PWM. + * If PID_dT is the default, and correct for the hardware/configuration, that means 7.689Hz, + * which is fine for driving a square wave into a resistive load and does not significantly + * impact FET heating. This also works fine on a Fotek SSR-10DA Solid State Relay into a 200W + * heater. If your configuration is significantly different than this and you don't understand + * the issues involved, don't use chamber PID until someone else verifies that your hardware works. + * @section chamber temp + */ +//#define PIDTEMPCHAMBER +//#define CHAMBER_LIMIT_SWITCHING + +/** + * Max Chamber Power + * Applies to all forms of chamber control (PID, bang-bang, and bang-bang with hysteresis). + * When set to any value below 255, enables a form of PWM to the chamber heater that acts like a divider + * so don't use it unless you are OK with PWM on your heater. (See the comment on enabling PIDTEMPCHAMBER) + */ +#define MAX_CHAMBER_POWER 255 // limits duty cycle to chamber heater; 255=full current + +#if ENABLED(PIDTEMPCHAMBER) + //#define MIN_CHAMBER_POWER 0 // Min power to improve PID stability. (0..MAX_CHAMBER_POWER) + // Get the power from the temperature report ('M105' => C@:nnn) and try P*2-20 to P*2-10. + //#define PID_CHAMBER_DEBUG // Print Chamber PID debug data to the serial port. Use 'M303 D' to enable/disable. + + // Lasko "MyHeat Personal Heater" (200w) modified with a Fotek SSR-10DA to control only the heating element + // and placed inside the small Creality printer enclosure tent. + #define DEFAULT_chamberKp 37.04 + #define DEFAULT_chamberKi 1.40 + #define DEFAULT_chamberKd 655.17 + // M309 P37.04 I1.04 D655.17 + + // FIND YOUR OWN: "M303 E-2 C8 S50" to run autotune on the chamber at 50 degreesC for 8 cycles. +#endif // PIDTEMPCHAMBER + +// @section pid temp + +#if ANY(PIDTEMP, PIDTEMPBED, PIDTEMPCHAMBER) + //#define PID_OPENLOOP // Puts PID in open loop. M104/M140 sets the output power from 0 to PID_MAX + //#define SLOW_PWM_HEATERS // PWM with very low frequency (roughly 0.125Hz=8s) and minimum state time of approximately 1s useful for heaters driven by a relay + #define PID_FUNCTIONAL_RANGE 20 // If the temperature difference between the target temperature and the actual temperature + // is more than PID_FUNCTIONAL_RANGE then the PID will be shut off and the heater will be set to min/max. + + //#define PID_EDIT_MENU // Add PID editing to the "Advanced Settings" menu. (~700 bytes of flash) + //#define PID_AUTOTUNE_MENU // Add PID auto-tuning to the "Advanced Settings" menu. (~250 bytes of flash) +#endif + +// @section safety + +/** + * Prevent extrusion if the temperature is below EXTRUDE_MINTEMP. + * Add M302 to set the minimum extrusion temperature and/or turn + * cold extrusion prevention on and off. + * + * *** IT IS HIGHLY RECOMMENDED TO LEAVE THIS OPTION ENABLED! *** + */ +#define PREVENT_COLD_EXTRUSION +#define EXTRUDE_MINTEMP 170 + +/** + * Prevent a single extrusion longer than EXTRUDE_MAXLENGTH. + * Note: For Bowden Extruders make this large enough to allow load/unload. + */ +#define PREVENT_LENGTHY_EXTRUDE +#define EXTRUDE_MAXLENGTH 300 + +//=========================================================================== +//======================== Thermal Runaway Protection ======================= +//=========================================================================== + +/** + * Thermal Protection provides additional protection to your printer from damage + * and fire. Marlin always includes safe min and max temperature ranges which + * protect against a broken or disconnected thermistor wire. + * + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. + * + * If you get "Thermal Runaway" or "Heating failed" errors the + * details can be tuned in Configuration_adv.h + */ + +#define THERMAL_PROTECTION_HOTENDS // Enable thermal protection for all extruders +#define THERMAL_PROTECTION_BED // Enable thermal protection for the heated bed +#define THERMAL_PROTECTION_CHAMBER // Enable thermal protection for the heated chamber +#define THERMAL_PROTECTION_COOLER // Enable thermal protection for the laser cooling + +//=========================================================================== +//============================= Mechanical Settings ========================= +//=========================================================================== + +// @section kinematics + +// Enable one of the options below for CoreXY, CoreXZ, or CoreYZ kinematics, +// either in the usual order or reversed +//#define COREXY +//#define COREXZ +//#define COREYZ +//#define COREYX +//#define COREZX +//#define COREZY + +// +// MarkForged Kinematics +// See https://reprap.org/forum/read.php?152,504042 +// +//#define MARKFORGED_XY +//#define MARKFORGED_YX +#if ANY(MARKFORGED_XY, MARKFORGED_YX) + //#define MARKFORGED_INVERSE // Enable for an inverted Markforged kinematics belt path +#endif + +// Enable for a belt style printer with endless "Z" motion +//#define BELTPRINTER + +// Articulated robot (arm). Joints are directly mapped to axes with no kinematics. +//#define ARTICULATED_ROBOT_ARM + +// For a hot wire cutter with parallel horizontal axes (X, I) where the heights of the two wire +// ends are controlled by parallel axes (Y, J). Joints are directly mapped to axes (no kinematics). +//#define FOAMCUTTER_XYUV + +// @section polargraph + +// Enable for Polargraph Kinematics +//#define POLARGRAPH +#if ENABLED(POLARGRAPH) + #define POLARGRAPH_MAX_BELT_LEN 1035.0 // (mm) Belt length at full extension. Override with M665 H. + #define DEFAULT_SEGMENTS_PER_SECOND 5 // Move segmentation based on duration + #define PEN_UP_DOWN_MENU // Add "Pen Up" and "Pen Down" to the MarlinUI menu +#endif + +// @section delta + +// Enable for DELTA kinematics and configure below +#define DELTA +#if ENABLED(DELTA) + + // Make delta curves from many straight lines (linear interpolation). + // This is a trade-off between visible corners (not enough segments) + // and processor overload (too many expensive sqrt calls). + #define DEFAULT_SEGMENTS_PER_SECOND 160 + + // After homing move down to a height where XY movement is unconstrained + #define DELTA_HOME_TO_SAFE_ZONE + + // Delta calibration menu + // Add three-point calibration to the MarlinUI menu. + // See http://minow.blogspot.com/index.html#4918805519571907051 + #define DELTA_CALIBRATION_MENU + + // G33 Delta Auto-Calibration. Enable EEPROM_SETTINGS to store results. + #define DELTA_AUTO_CALIBRATION + + #if ENABLED(DELTA_AUTO_CALIBRATION) + // Default number of probe points : n*n (1 -> 7) + #define DELTA_CALIBRATION_DEFAULT_POINTS 4 + #endif + + #if ANY(DELTA_AUTO_CALIBRATION, DELTA_CALIBRATION_MENU) + // Step size for paper-test probing + #define PROBE_MANUALLY_STEP 0.025 // (mm) + #endif + + // Print surface diameter/2 minus unreachable space (avoid collisions with vertical towers). + #define PRINTABLE_RADIUS 85.0 // (mm) + + // Center-to-center distance of the holes in the diagonal push rods. + #define DELTA_DIAGONAL_ROD 216.0 // (mm) + + // Distance between bed and nozzle Z home position + #define DELTA_HEIGHT 325.00 // (mm) Get this value from G33 auto calibrate + + #define DELTA_ENDSTOP_ADJ { -0.78, -0.51, 0.00 } // (mm) Get these values from G33 auto calibrate + // Horizontal offset from middle of printer to smooth rod center. + #define DELTA_SMOOTH_ROD_OFFSET 157 // 151 mm + + // Horizontal offset of the universal joints on the end effector. + #define DELTA_EFFECTOR_OFFSET 32 // 24 mm + + // Horizontal offset of the universal joints on the carriages. + #define DELTA_CARRIAGE_OFFSET 31 // 22 mm + + // Horizontal distance bridged by diagonal push rods when effector is centered. + #define DELTA_RADIUS (DELTA_SMOOTH_ROD_OFFSET-(DELTA_EFFECTOR_OFFSET)-(DELTA_CARRIAGE_OFFSET)) // (mm) Get this value from G33 auto calibrate + + // Trim adjustments for individual towers + // tower angle corrections for X and Y tower / rotate XYZ so Z tower angle = 0 + // measured in degrees anticlockwise looking from above the printer + #define DELTA_TOWER_ANGLE_TRIM { -0.40, -0.05, 0.45 } // (mm) Get these values from G33 auto calibrate + + // Delta radius and diagonal rod adjustments + //#define DELTA_RADIUS_TRIM_TOWER { 0.0, 0.0, 0.0 } // (mm) + //#define DELTA_DIAGONAL_ROD_TRIM_TOWER { 0.0, 0.0, 0.0 } // (mm) +#endif + +// @section scara + +/** + * MORGAN_SCARA was developed by QHARLEY in South Africa in 2012-2013. + * Implemented and slightly reworked by JCERNY in June, 2014. + * + * Mostly Printed SCARA is an open source design by Tyler Williams. See: + * https://www.thingiverse.com/thing:2487048 + * https://www.thingiverse.com/thing:1241491 + */ +//#define MORGAN_SCARA +//#define MP_SCARA +#if ANY(MORGAN_SCARA, MP_SCARA) + // If movement is choppy try lowering this value + #define DEFAULT_SEGMENTS_PER_SECOND 200 + + // Length of inner and outer support arms. Measure arm lengths precisely. + #define SCARA_LINKAGE_1 150 // (mm) + #define SCARA_LINKAGE_2 150 // (mm) + + // SCARA tower offset (position of Tower relative to bed zero position) + // This needs to be reasonably accurate as it defines the printbed position in the SCARA space. + #define SCARA_OFFSET_X 100 // (mm) + #define SCARA_OFFSET_Y -56 // (mm) + + #if ENABLED(MORGAN_SCARA) + + //#define DEBUG_SCARA_KINEMATICS + #define FEEDRATE_SCALING // Convert XY feedrate from mm/s to degrees/s on the fly + + // Radius around the center where the arm cannot reach + #define MIDDLE_DEAD_ZONE_R 0 // (mm) + + #elif ENABLED(MP_SCARA) + + #define SCARA_OFFSET_THETA1 12 // degrees + #define SCARA_OFFSET_THETA2 131 // degrees + + #endif + +#endif + +// @section tpara + +// Enable for TPARA kinematics and configure below +//#define AXEL_TPARA +#if ENABLED(AXEL_TPARA) + #define DEBUG_TPARA_KINEMATICS + #define DEFAULT_SEGMENTS_PER_SECOND 200 + + // Length of inner and outer support arms. Measure arm lengths precisely. + #define TPARA_LINKAGE_1 120 // (mm) + #define TPARA_LINKAGE_2 120 // (mm) + + // TPARA tower offset (position of Tower relative to bed zero position) + // This needs to be reasonably accurate as it defines the printbed position in the TPARA space. + #define TPARA_OFFSET_X 0 // (mm) + #define TPARA_OFFSET_Y 0 // (mm) + #define TPARA_OFFSET_Z 0 // (mm) + + #define FEEDRATE_SCALING // Convert XY feedrate from mm/s to degrees/s on the fly + + // Radius around the center where the arm cannot reach + #define MIDDLE_DEAD_ZONE_R 0 // (mm) +#endif + +// @section polar + +/** + * POLAR Kinematics + * developed by Kadir ilkimen for PolarBear CNC and babyBear + * https://github.com/kadirilkimen/Polar-Bear-Cnc-Machine + * https://github.com/kadirilkimen/babyBear-3D-printer + * + * A polar machine can have different configurations. + * This kinematics is only compatible with the following configuration: + * X : Independent linear + * Y or B : Polar + * Z : Independent linear + * + * For example, PolarBear has CoreXZ plus Polar Y or B. + * + * Motion problem for Polar axis near center / origin: + * + * 3D printing: + * Movements very close to the center of the polar axis take more time than others. + * This brief delay results in more material deposition due to the pressure in the nozzle. + * + * Current Kinematics and feedrate scaling deals with this by making the movement as fast + * as possible. It works for slow movements but doesn't work well with fast ones. A more + * complicated extrusion compensation must be implemented. + * + * Ideally, it should estimate that a long rotation near the center is ahead and will cause + * unwanted deposition. Therefore it can compensate the extrusion beforehand. + * + * Laser cutting: + * Same thing would be a problem for laser engraving too. As it spends time rotating at the + * center point, more likely it will burn more material than it should. Therefore similar + * compensation would be implemented for laser-cutting operations. + * + * Milling: + * This shouldn't be a problem for cutting/milling operations. + */ +//#define POLAR +#if ENABLED(POLAR) + #define DEFAULT_SEGMENTS_PER_SECOND 180 // If movement is choppy try lowering this value + #define PRINTABLE_RADIUS 82.0f // (mm) Maximum travel of X axis + + // Movements fall inside POLAR_FAST_RADIUS are assigned the highest possible feedrate + // to compensate unwanted deposition related to the near-origin motion problem. + #define POLAR_FAST_RADIUS 3.0f // (mm) + + // Radius which is unreachable by the tool. + // Needed if the tool is not perfectly aligned to the center of the polar axis. + #define POLAR_CENTER_OFFSET 0.0f // (mm) + + #define FEEDRATE_SCALING // Convert XY feedrate from mm/s to degrees/s on the fly +#endif + +//=========================================================================== +//============================== Endstop Settings =========================== +//=========================================================================== + +// @section endstops + +// Enable pullup for all endstops to prevent a floating state +#define ENDSTOPPULLUPS +#if DISABLED(ENDSTOPPULLUPS) + // Disable ENDSTOPPULLUPS to set pullups individually + //#define ENDSTOPPULLUP_XMIN + //#define ENDSTOPPULLUP_YMIN + //#define ENDSTOPPULLUP_ZMIN + //#define ENDSTOPPULLUP_IMIN + //#define ENDSTOPPULLUP_JMIN + //#define ENDSTOPPULLUP_KMIN + //#define ENDSTOPPULLUP_UMIN + //#define ENDSTOPPULLUP_VMIN + //#define ENDSTOPPULLUP_WMIN + //#define ENDSTOPPULLUP_XMAX + //#define ENDSTOPPULLUP_YMAX + //#define ENDSTOPPULLUP_ZMAX + //#define ENDSTOPPULLUP_IMAX + //#define ENDSTOPPULLUP_JMAX + //#define ENDSTOPPULLUP_KMAX + //#define ENDSTOPPULLUP_UMAX + //#define ENDSTOPPULLUP_VMAX + //#define ENDSTOPPULLUP_WMAX + //#define ENDSTOPPULLUP_ZMIN_PROBE +#endif + +// Enable pulldown for all endstops to prevent a floating state +//#define ENDSTOPPULLDOWNS +#if DISABLED(ENDSTOPPULLDOWNS) + // Disable ENDSTOPPULLDOWNS to set pulldowns individually + //#define ENDSTOPPULLDOWN_XMIN + //#define ENDSTOPPULLDOWN_YMIN + //#define ENDSTOPPULLDOWN_ZMIN + //#define ENDSTOPPULLDOWN_IMIN + //#define ENDSTOPPULLDOWN_JMIN + //#define ENDSTOPPULLDOWN_KMIN + //#define ENDSTOPPULLDOWN_UMIN + //#define ENDSTOPPULLDOWN_VMIN + //#define ENDSTOPPULLDOWN_WMIN + //#define ENDSTOPPULLDOWN_XMAX + //#define ENDSTOPPULLDOWN_YMAX + //#define ENDSTOPPULLDOWN_ZMAX + //#define ENDSTOPPULLDOWN_IMAX + //#define ENDSTOPPULLDOWN_JMAX + //#define ENDSTOPPULLDOWN_KMAX + //#define ENDSTOPPULLDOWN_UMAX + //#define ENDSTOPPULLDOWN_VMAX + //#define ENDSTOPPULLDOWN_WMAX + //#define ENDSTOPPULLDOWN_ZMIN_PROBE +#endif + +/** + * Endstop "Hit" State + * Set to the state (HIGH or LOW) that applies to each endstop. + */ +#define X_MIN_ENDSTOP_HIT_STATE HIGH +#define X_MAX_ENDSTOP_HIT_STATE HIGH +#define Y_MIN_ENDSTOP_HIT_STATE HIGH +#define Y_MAX_ENDSTOP_HIT_STATE HIGH +#define Z_MIN_ENDSTOP_HIT_STATE LOW +#define Z_MAX_ENDSTOP_HIT_STATE HIGH +#define I_MIN_ENDSTOP_HIT_STATE HIGH +#define I_MAX_ENDSTOP_HIT_STATE HIGH +#define J_MIN_ENDSTOP_HIT_STATE HIGH +#define J_MAX_ENDSTOP_HIT_STATE HIGH +#define K_MIN_ENDSTOP_HIT_STATE HIGH +#define K_MAX_ENDSTOP_HIT_STATE HIGH +#define U_MIN_ENDSTOP_HIT_STATE HIGH +#define U_MAX_ENDSTOP_HIT_STATE HIGH +#define V_MIN_ENDSTOP_HIT_STATE HIGH +#define V_MAX_ENDSTOP_HIT_STATE HIGH +#define W_MIN_ENDSTOP_HIT_STATE HIGH +#define W_MAX_ENDSTOP_HIT_STATE HIGH +#define Z_MIN_PROBE_ENDSTOP_HIT_STATE LOW + +// Enable this feature if all enabled endstop pins are interrupt-capable. +// This will remove the need to poll the interrupt pins, saving many CPU cycles. +//#define ENDSTOP_INTERRUPTS_FEATURE + +/** + * Endstop Noise Threshold + * + * Enable if your probe or endstops falsely trigger due to noise. + * + * - Higher values may affect repeatability or accuracy of some bed probes. + * - To fix noise install a 100nF ceramic capacitor in parallel with the switch. + * - This feature is not required for common micro-switches mounted on PCBs + * based on the Makerbot design, which already have the 100nF capacitor. + * + * :[2,3,4,5,6,7] + */ +//#define ENDSTOP_NOISE_THRESHOLD 2 + +// Check for stuck or disconnected endstops during homing moves. +//#define DETECT_BROKEN_ENDSTOP + +//============================================================================= +//============================== Movement Settings ============================ +//============================================================================= +// @section motion + +/** + * Default Settings + * + * These settings can be reset by M502 + * + * Note that if EEPROM is enabled, saved values will override these. + */ + +#define NEMA_FULL_STEPS 200 +#define NEMA_MICROSTEPS 16 +#define XYZ_BELT_PITCH 2 +#define XYZ_PULLEY_TEETH 16 +#define XYZ_STEPS (NEMA_FULL_STEPS * NEMA_MICROSTEPS / XYZ_BELT_PITCH / XYZ_PULLEY_TEETH) + +#define E_GEAR_CIRCUMFERENCE 20 +#define E_STEPS NEMA_FULL_STEPS * NEMA_MICROSTEPS / E_GEAR_CIRCUMFERENCE +/** + * With this option each E stepper can have its own factors for the + * following movement settings. If fewer factors are given than the + * total number of extruders, the last value applies to the rest. + */ +//#define DISTINCT_E_FACTORS + +/** + * Default Axis Steps Per Unit (linear=steps/mm, rotational=steps/°) + * Override with M92 (when enabled below) + * X, Y, Z [, I [, J [, K...]]], E0 [, E1[, E2...]] + */ +#define DEFAULT_AXIS_STEPS_PER_UNIT { XYZ_STEPS, XYZ_STEPS, XYZ_STEPS, E_STEPS } + +/** + * Enable support for M92. Disable to save at least ~530 bytes of flash. + */ +#define EDITABLE_STEPS_PER_UNIT + +/** + * Default Max Feed Rate (linear=mm/s, rotational=°/s) + * Override with M203 + * X, Y, Z [, I [, J [, K...]]], E0 [, E1[, E2...]] + */ +#define DEFAULT_MAX_FEEDRATE { 200, 200, 200, 25 } + +//#define LIMITED_MAX_FR_EDITING // Limit edit via M203 or LCD to DEFAULT_MAX_FEEDRATE * 2 +#if ENABLED(LIMITED_MAX_FR_EDITING) + #define MAX_FEEDRATE_EDIT_VALUES { 300, 300, 300, 50 } // ...or, set your own edit limits +#endif + +/** + * Default Max Acceleration (speed change with time) (linear=mm/(s^2), rotational=°/(s^2)) + * (Maximum start speed for accelerated moves) + * Override with M201 + * X, Y, Z [, I [, J [, K...]]], E0 [, E1[, E2...]] + */ +#define DEFAULT_MAX_ACCELERATION { 1200, 1200, 1200, 300 } + +//#define LIMITED_MAX_ACCEL_EDITING // Limit edit via M201 or LCD to DEFAULT_MAX_ACCELERATION * 2 +#if ENABLED(LIMITED_MAX_ACCEL_EDITING) + #define MAX_ACCEL_EDIT_VALUES { 6000, 6000, 6000, 20000 } // ...or, set your own edit limits +#endif + +/** + * Default Acceleration (speed change with time) (linear=mm/(s^2), rotational=°/(s^2)) + * Override with M204 + * + * M204 P Acceleration + * M204 R Retract Acceleration + * M204 T Travel Acceleration + */ +#define DEFAULT_ACCELERATION 300 // X, Y, Z and E acceleration for printing moves +#define DEFAULT_RETRACT_ACCELERATION 150 // E acceleration for retracts +#define DEFAULT_TRAVEL_ACCELERATION 300 // X, Y, Z acceleration for travel (non printing) moves + +/** + * Default Jerk limits (mm/s) + * Override with M205 X Y Z . . . E + * + * "Jerk" specifies the minimum speed change that requires acceleration. + * When changing speed and direction, if the difference is less than the + * value set here, it may happen instantaneously. + */ +#define CLASSIC_JERK +#if ENABLED(CLASSIC_JERK) + #define DEFAULT_XJERK DEFAULT_ZJERK + #define DEFAULT_YJERK DEFAULT_ZJERK + #define DEFAULT_ZJERK 10.0 + #define DEFAULT_EJERK 5.0 + //#define DEFAULT_IJERK 0.3 + //#define DEFAULT_JJERK 0.3 + //#define DEFAULT_KJERK 0.3 + //#define DEFAULT_UJERK 0.3 + //#define DEFAULT_VJERK 0.3 + //#define DEFAULT_WJERK 0.3 + + //#define TRAVEL_EXTRA_XYJERK 0.0 // Additional jerk allowance for all travel moves + + //#define LIMITED_JERK_EDITING // Limit edit via M205 or LCD to DEFAULT_aJERK * 2 + #if ENABLED(LIMITED_JERK_EDITING) + #define MAX_JERK_EDIT_VALUES { 20, 20, 20, 10 } // ...or, set your own edit limits + #endif +#endif + +/** + * Junction Deviation Factor + * + * See: + * https://reprap.org/forum/read.php?1,739819 + * https://blog.kyneticcnc.com/2018/10/computing-junction-deviation-for-marlin.html + */ +#if DISABLED(CLASSIC_JERK) + #define JUNCTION_DEVIATION_MM 0.013 // (mm) Distance from real junction edge + #define JD_HANDLE_SMALL_SEGMENTS // Use curvature estimation instead of just the junction angle + // for small segments (< 1mm) with large junction angles (> 135°). +#endif + +/** + * S-Curve Acceleration + * + * This option eliminates vibration during printing by fitting a Bézier + * curve to move acceleration, producing much smoother direction changes. + * + * See https://github.com/synthetos/TinyG/wiki/Jerk-Controlled-Motion-Explained + */ +//#define S_CURVE_ACCELERATION + +//=========================================================================== +//============================= Z Probe Options ============================= +//=========================================================================== +// @section probes + +// +// See https://marlinfw.org/docs/configuration/probes.html +// + +/** + * Enable this option for a probe connected to the Z-MIN pin. + * The probe replaces the Z-MIN endstop and is used for Z homing. + * (Automatically enables USE_PROBE_FOR_Z_HOMING.) + */ +#define Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + +// Force the use of the probe for Z-axis homing +//#define USE_PROBE_FOR_Z_HOMING + +/** + * Z_MIN_PROBE_PIN + * + * Override this pin only if the probe cannot be connected to + * the default Z_MIN_PROBE_PIN for the selected MOTHERBOARD. + * + * - The simplest option is to use a free endstop connector. + * - Use 5V for powered (usually inductive) sensors. + * + * - For simple switches... + * - Normally-closed (NC) also connect to GND. + * - Normally-open (NO) also connect to 5V. + */ +//#define Z_MIN_PROBE_PIN -1 + +/** + * Probe Type + * + * Allen Key Probes, Servo Probes, Z-Sled Probes, FIX_MOUNTED_PROBE, etc. + * Activate one of these to use Auto Bed Leveling below. + */ + +/** + * The "Manual Probe" provides a means to do "Auto" Bed Leveling without a probe. + * Use G29 repeatedly, adjusting the Z height at each point with movement commands + * or (with LCD_BED_LEVELING) the LCD controller. + */ +//#define PROBE_MANUALLY + +/** + * A Fix-Mounted Probe either doesn't deploy or needs manual deployment. + * (e.g., an inductive probe or a nozzle-based probe-switch.) + */ +#define FIX_MOUNTED_PROBE + +/** + * Use the nozzle as the probe, as with a conductive + * nozzle system or a piezo-electric smart effector. + */ +//#define NOZZLE_AS_PROBE + +/** + * Z Servo Probe, such as an endstop switch on a rotating arm. + */ +//#define Z_PROBE_SERVO_NR 0 +#ifdef Z_PROBE_SERVO_NR + //#define Z_SERVO_ANGLES { 70, 0 } // Z Servo Deploy and Stow angles + //#define Z_SERVO_MEASURE_ANGLE 45 // Use if the servo must move to a "free" position for measuring after deploy + //#define Z_SERVO_INTERMEDIATE_STOW // Stow the probe between points + //#define Z_SERVO_DEACTIVATE_AFTER_STOW // Deactivate the servo when probe is stowed +#endif + +/** + * The BLTouch probe uses a Hall effect sensor and emulates a servo. + */ +//#define BLTOUCH + +/** + * MagLev V4 probe by MDD + * + * This probe is deployed and activated by powering a built-in electromagnet. + */ +//#define MAGLEV4 +#if ENABLED(MAGLEV4) + //#define MAGLEV_TRIGGER_PIN 11 // Set to the connected digital output + #define MAGLEV_TRIGGER_DELAY 15 // Changing this risks overheating the coil +#endif + +/** + * Touch-MI Probe by hotends.fr + * + * This probe is deployed and activated by moving the X-axis to a magnet at the edge of the bed. + * By default, the magnet is assumed to be on the left and activated by a home. If the magnet is + * on the right, enable and set TOUCH_MI_DEPLOY_XPOS to the deploy position. + * + * Also requires: BABYSTEPPING, BABYSTEP_ZPROBE_OFFSET, Z_SAFE_HOMING, + * and a minimum Z_CLEARANCE_FOR_HOMING of 10. + */ +//#define TOUCH_MI_PROBE +#if ENABLED(TOUCH_MI_PROBE) + #define TOUCH_MI_RETRACT_Z 0.5 // Height at which the probe retracts + //#define TOUCH_MI_DEPLOY_XPOS (X_MAX_BED + 2) // For a magnet on the right side of the bed + //#define TOUCH_MI_MANUAL_DEPLOY // For manual deploy (LCD menu) +#endif + +/** + * Bed Distance Sensor + * + * Measures the distance from bed to nozzle with accuracy of 0.01mm. + * For information about this sensor https://github.com/markniu/Bed_Distance_sensor + * Uses I2C port, so it requires I2C library markyue/Panda_SoftMasterI2C. + */ +//#define BD_SENSOR +#if ENABLED(BD_SENSOR) + //#define BD_SENSOR_PROBE_NO_STOP // Probe bed without stopping at each probe point +#endif + +/** + * BIQU MicroProbe + * + * A lightweight, solenoid-driven probe. + * For information about this sensor https://github.com/bigtreetech/MicroProbe + * + * Also requires PROBE_ENABLE_DISABLE + */ +//#define BIQU_MICROPROBE_V1 // Triggers HIGH +//#define BIQU_MICROPROBE_V2 // Triggers LOW + +// A probe that is deployed and stowed with a solenoid pin (SOL1_PIN) +//#define SOLENOID_PROBE + +// A sled-mounted probe like those designed by Charles Bell. +//#define Z_PROBE_SLED +//#define SLED_DOCKING_OFFSET 5 // The extra distance the X axis must travel to pickup the sled. 0 should be fine but you can push it further if you'd like. + +// A probe deployed by moving the x-axis, such as the Wilson II's rack-and-pinion probe designed by Marty Rice. +//#define RACK_AND_PINION_PROBE +#if ENABLED(RACK_AND_PINION_PROBE) + #define Z_PROBE_DEPLOY_X X_MIN_POS + #define Z_PROBE_RETRACT_X X_MAX_POS +#endif + +/** + * Magnetically Mounted Probe + * For probes such as Euclid, Klicky, Klackender, etc. + */ +//#define MAG_MOUNTED_PROBE +#if ENABLED(MAG_MOUNTED_PROBE) + #define PROBE_DEPLOY_FEEDRATE (133*60) // (mm/min) Probe deploy speed + #define PROBE_STOW_FEEDRATE (133*60) // (mm/min) Probe stow speed + + /** + * Magnetically Mounted Probe with a Servo mechanism + * Probe Deploy and Stow both follow the same basic sequence: + * - Rotate the SERVO to its Deployed angle + * - Perform XYZ moves to deploy or stow the PROBE + * - Rotate the SERVO to its Stowed angle + */ + //#define MAG_MOUNTED_PROBE_SERVO_NR 0 // Servo Number for this probe + #ifdef MAG_MOUNTED_PROBE_SERVO_NR + #define MAG_MOUNTED_PROBE_SERVO_ANGLES { 90, 0 } // Servo Angles for Deployed, Stowed + #define MAG_MOUNTED_PRE_DEPLOY { PROBE_DEPLOY_FEEDRATE, { 15, 160, 30 } } // Safe position for servo activation + #define MAG_MOUNTED_PRE_STOW { PROBE_DEPLOY_FEEDRATE, { 15, 160, 30 } } // Safe position for servo deactivation + #endif + + #define MAG_MOUNTED_DEPLOY_1 { PROBE_DEPLOY_FEEDRATE, { 245, 114, 30 } } // Move to side Dock & Attach probe + #define MAG_MOUNTED_DEPLOY_2 { PROBE_DEPLOY_FEEDRATE, { 210, 114, 30 } } // Move probe off dock + #define MAG_MOUNTED_DEPLOY_3 { PROBE_DEPLOY_FEEDRATE, { 0, 0, 0 } } // Extra move if needed + #define MAG_MOUNTED_DEPLOY_4 { PROBE_DEPLOY_FEEDRATE, { 0, 0, 0 } } // Extra move if needed + #define MAG_MOUNTED_DEPLOY_5 { PROBE_DEPLOY_FEEDRATE, { 0, 0, 0 } } // Extra move if needed + #define MAG_MOUNTED_STOW_1 { PROBE_STOW_FEEDRATE, { 245, 114, 20 } } // Move to dock + #define MAG_MOUNTED_STOW_2 { PROBE_STOW_FEEDRATE, { 245, 114, 0 } } // Place probe beside remover + #define MAG_MOUNTED_STOW_3 { PROBE_STOW_FEEDRATE, { 230, 114, 0 } } // Side move to remove probe + #define MAG_MOUNTED_STOW_4 { PROBE_STOW_FEEDRATE, { 210, 114, 20 } } // Side move to remove probe + #define MAG_MOUNTED_STOW_5 { PROBE_STOW_FEEDRATE, { 0, 0, 0 } } // Extra move if needed +#endif + +// Duet Smart Effector (for delta printers) - https://docs.duet3d.com/en/Duet3D_hardware/Accessories/Smart_Effector +// When the pin is defined you can use M672 to set/reset the probe sensitivity. +//#define DUET_SMART_EFFECTOR +#if ENABLED(DUET_SMART_EFFECTOR) + #define SMART_EFFECTOR_MOD_PIN -1 // Connect a GPIO pin to the Smart Effector MOD pin +#endif + +/** + * Use StallGuard2 to probe the bed with the nozzle. + * Requires stallGuard-capable Trinamic stepper drivers. + * CAUTION: This can damage machines with Z lead screws. + * Take extreme care when setting up this feature. + */ +//#define SENSORLESS_PROBING + +/** + * Allen key retractable z-probe as seen on many Kossel delta printers - https://reprap.org/wiki/Kossel#Autolevel_probe + * Deploys by touching z-axis belt. Retracts by pushing the probe down. + */ +//#define Z_PROBE_ALLEN_KEY +#if ENABLED(Z_PROBE_ALLEN_KEY) + // 2 or 3 sets of coordinates for deploying and retracting the spring loaded touch probe on G29, + // if servo actuated touch probe is not defined. Uncomment as appropriate for your printer/probe. + + #define Z_PROBE_ALLEN_KEY_DEPLOY_1 { 30.0, PRINTABLE_RADIUS, 100.0 } + #define Z_PROBE_ALLEN_KEY_DEPLOY_1_FEEDRATE XY_PROBE_FEEDRATE + + #define Z_PROBE_ALLEN_KEY_DEPLOY_2 { 0.0, PRINTABLE_RADIUS, 100.0 } + #define Z_PROBE_ALLEN_KEY_DEPLOY_2_FEEDRATE (XY_PROBE_FEEDRATE)/10 + + #define Z_PROBE_ALLEN_KEY_DEPLOY_3 { 0.0, (PRINTABLE_RADIUS) * 0.75, 100.0 } + #define Z_PROBE_ALLEN_KEY_DEPLOY_3_FEEDRATE XY_PROBE_FEEDRATE + + #define Z_PROBE_ALLEN_KEY_STOW_1 { -64.0, 56.0, 23.0 } // Move the probe into position + #define Z_PROBE_ALLEN_KEY_STOW_1_FEEDRATE XY_PROBE_FEEDRATE + + #define Z_PROBE_ALLEN_KEY_STOW_2 { -64.0, 56.0, 3.0 } // Push it down + #define Z_PROBE_ALLEN_KEY_STOW_2_FEEDRATE (XY_PROBE_FEEDRATE)/10 + + #define Z_PROBE_ALLEN_KEY_STOW_3 { -64.0, 56.0, 50.0 } // Move it up to clear + #define Z_PROBE_ALLEN_KEY_STOW_3_FEEDRATE XY_PROBE_FEEDRATE + + #define Z_PROBE_ALLEN_KEY_STOW_4 { 0.0, 0.0, 50.0 } + #define Z_PROBE_ALLEN_KEY_STOW_4_FEEDRATE XY_PROBE_FEEDRATE + +#endif // Z_PROBE_ALLEN_KEY + +/** + * Nozzle-to-Probe offsets { X, Y, Z } + * + * X and Y offset + * Use a caliper or ruler to measure the distance from the tip of + * the Nozzle to the center-point of the Probe in the X and Y axes. + * + * Z offset + * - For the Z offset use your best known value and adjust at runtime. + * - Common probes trigger below the nozzle and have negative values for Z offset. + * - Probes triggering above the nozzle height are uncommon but do exist. When using + * probes such as this, carefully set Z_CLEARANCE_DEPLOY_PROBE and Z_CLEARANCE_BETWEEN_PROBES + * to avoid collisions during probing. + * + * Tune and Adjust + * - Probe Offsets can be tuned at runtime with 'M851', LCD menus, babystepping, etc. + * - PROBE_OFFSET_WIZARD (Configuration_adv.h) can be used for setting the Z offset. + * + * Assuming the typical work area orientation: + * - Probe to RIGHT of the Nozzle has a Positive X offset + * - Probe to LEFT of the Nozzle has a Negative X offset + * - Probe in BACK of the Nozzle has a Positive Y offset + * - Probe in FRONT of the Nozzle has a Negative Y offset + * + * Some examples: + * #define NOZZLE_TO_PROBE_OFFSET { 10, 10, -1 } // Example "1" + * #define NOZZLE_TO_PROBE_OFFSET {-10, 5, -1 } // Example "2" + * #define NOZZLE_TO_PROBE_OFFSET { 5, -5, -1 } // Example "3" + * #define NOZZLE_TO_PROBE_OFFSET {-15,-10, -1 } // Example "4" + * + * +-- BACK ---+ + * | [+] | + * L | 1 | R <-- Example "1" (right+, back+) + * E | 2 | I <-- Example "2" ( left-, back+) + * F |[-] N [+]| G <-- Nozzle + * T | 3 | H <-- Example "3" (right+, front-) + * | 4 | T <-- Example "4" ( left-, front-) + * | [-] | + * O-- FRONT --+ + */ +#define NOZZLE_TO_PROBE_OFFSET { 0, 0, -22.57 } + +// Enable and set to use a specific tool for probing. Disable to allow any tool. +#define PROBING_TOOL 0 +#ifdef PROBING_TOOL + //#define PROBE_TOOLCHANGE_NO_MOVE // Suppress motion on probe tool-change +#endif + +// Most probes should stay away from the edges of the bed, but +// with NOZZLE_AS_PROBE this can be negative for a wider probing area. +#define PROBING_MARGIN 10 + +// X and Y axis travel speed between probes. +// Leave undefined to use the average of the current XY homing feedrate. +#define XY_PROBE_FEEDRATE (70*60) // (mm/min) + +// Feedrate for the first approach when double-probing (MULTIPLE_PROBING == 2) +#define Z_PROBE_FEEDRATE_FAST (20*60) // (mm/min) + +// Feedrate for the "accurate" probe of each point +#define Z_PROBE_FEEDRATE_SLOW (Z_PROBE_FEEDRATE_FAST / 3) // (mm/min) + +/** + * Probe Activation Switch + * A switch indicating proper deployment, or an optical + * switch triggered when the carriage is near the bed. + */ +//#define PROBE_ACTIVATION_SWITCH +#if ENABLED(PROBE_ACTIVATION_SWITCH) + #define PROBE_ACTIVATION_SWITCH_STATE LOW // State indicating probe is active + //#define PROBE_ACTIVATION_SWITCH_PIN PC6 // Override default pin +#endif + +/** + * Tare Probe (determine zero-point) prior to each probe. + * Useful for a strain gauge or piezo sensor that needs to factor out + * elements such as cables pulling on the carriage. + */ +//#define PROBE_TARE +#if ENABLED(PROBE_TARE) + #define PROBE_TARE_TIME 200 // (ms) Time to hold tare pin + #define PROBE_TARE_DELAY 200 // (ms) Delay after tare before + #define PROBE_TARE_STATE HIGH // State to write pin for tare + //#define PROBE_TARE_PIN PA5 // Override default pin + //#define PROBE_TARE_MENU // Display a menu item to tare the probe + #if ENABLED(PROBE_ACTIVATION_SWITCH) + //#define PROBE_TARE_ONLY_WHILE_INACTIVE // Fail to tare/probe if PROBE_ACTIVATION_SWITCH is active + #endif +#endif + +/** + * Probe Enable / Disable + * The probe only provides a triggered signal when enabled. + */ +//#define PROBE_ENABLE_DISABLE +#if ENABLED(PROBE_ENABLE_DISABLE) + //#define PROBE_ENABLE_PIN -1 // Override the default pin here +#endif + +/** + * Multiple Probing + * + * You may get improved results by probing 2 or more times. + * With EXTRA_PROBING the more atypical reading(s) will be disregarded. + * + * A total of 2 does fast/slow probes with a weighted average. + * A total of 3 or more adds more slow probes, taking the average. + */ +#define MULTIPLE_PROBING 3 +//#define EXTRA_PROBING 1 + +/** + * Z probes require clearance when deploying, stowing, and moving between + * probe points to avoid hitting the bed and other hardware. + * Servo-mounted probes require extra space for the arm to rotate. + * Inductive probes need space to keep from triggering early. + * + * Use these settings to specify the distance (mm) to raise the probe (or + * lower the bed). The values set here apply over and above any (negative) + * probe Z Offset set with NOZZLE_TO_PROBE_OFFSET, M851, or the LCD. + * Only integer values >= 1 are valid here. + * + * Example: 'M851 Z-5' with a CLEARANCE of 4 => 9mm from bed to nozzle. + * But: 'M851 Z+1' with a CLEARANCE of 2 => 2mm from bed to nozzle. + */ +#define Z_CLEARANCE_DEPLOY_PROBE 10 // (mm) Z Clearance for Deploy/Stow +#define Z_CLEARANCE_BETWEEN_PROBES 5 // (mm) Z Clearance between probe points +#define Z_CLEARANCE_MULTI_PROBE 5 // (mm) Z Clearance between multiple probes +#define Z_PROBE_ERROR_TOLERANCE 3 // (mm) Tolerance for early trigger (<= -probe.offset.z + ZPET) +//#define Z_AFTER_PROBING 5 // (mm) Z position after probing is done + +#define Z_PROBE_LOW_POINT -2 // (mm) Farthest distance below the trigger-point to go before stopping + +// For M851 provide ranges for adjusting the X, Y, and Z probe offsets +//#define PROBE_OFFSET_XMIN -50 // (mm) +//#define PROBE_OFFSET_XMAX 50 // (mm) +//#define PROBE_OFFSET_YMIN -50 // (mm) +//#define PROBE_OFFSET_YMAX 50 // (mm) +#define PROBE_OFFSET_ZMIN -30 // (mm) +#define PROBE_OFFSET_ZMAX 30 // (mm) + +// Enable the M48 repeatability test to test probe accuracy +//#define Z_MIN_PROBE_REPEATABILITY_TEST + +// Before deploy/stow pause for user confirmation +//#define PAUSE_BEFORE_DEPLOY_STOW +#if ENABLED(PAUSE_BEFORE_DEPLOY_STOW) + //#define PAUSE_PROBE_DEPLOY_WHEN_TRIGGERED // For Manual Deploy Allenkey Probe +#endif + +/** + * Enable one or more of the following if probing seems unreliable. + * Heaters and/or fans can be disabled during probing to minimize electrical + * noise. A delay can also be added to allow noise and vibration to settle. + * These options are most useful for the BLTouch probe, but may also improve + * readings with inductive probes and piezo sensors. + */ +//#define PROBING_HEATERS_OFF // Turn heaters off when probing +#if ENABLED(PROBING_HEATERS_OFF) + //#define WAIT_FOR_BED_HEATER // Wait for bed to heat back up between probes (to improve accuracy) + //#define WAIT_FOR_HOTEND // Wait for hotend to heat back up between probes (to improve accuracy & prevent cold extrude) +#endif +//#define PROBING_FANS_OFF // Turn fans off when probing +//#define PROBING_ESTEPPERS_OFF // Turn all extruder steppers off when probing +//#define PROBING_STEPPERS_OFF // Turn all steppers off (unless needed to hold position) when probing (including extruders) +//#define DELAY_BEFORE_PROBING 200 // (ms) To prevent vibrations from triggering piezo sensors + +// Require minimum nozzle and/or bed temperature for probing +//#define PREHEAT_BEFORE_PROBING +#if ENABLED(PREHEAT_BEFORE_PROBING) + #define PROBING_NOZZLE_TEMP 120 // (°C) Only applies to E0 at this time + #define PROBING_BED_TEMP 50 +#endif + +// @section stepper drivers + +// For Inverting Stepper Enable Pins (Active Low) use 0, Non Inverting (Active High) use 1 +// :['LOW', 'HIGH'] +#define X_ENABLE_ON LOW +#define Y_ENABLE_ON LOW +#define Z_ENABLE_ON LOW +#define E_ENABLE_ON LOW // For all extruders +//#define I_ENABLE_ON LOW +//#define J_ENABLE_ON LOW +//#define K_ENABLE_ON LOW +//#define U_ENABLE_ON LOW +//#define V_ENABLE_ON LOW +//#define W_ENABLE_ON LOW + +// Disable axis steppers immediately when they're not being stepped. +// WARNING: When motors turn off there is a chance of losing position accuracy! +//#define DISABLE_X +//#define DISABLE_Y +//#define DISABLE_Z +//#define DISABLE_I +//#define DISABLE_J +//#define DISABLE_K +//#define DISABLE_U +//#define DISABLE_V +//#define DISABLE_W + +// Turn off the display blinking that warns about possible accuracy reduction +//#define DISABLE_REDUCED_ACCURACY_WARNING + +// @section extruder + +//#define DISABLE_E // Disable the extruder when not stepping +#define DISABLE_OTHER_EXTRUDERS // Keep only the active extruder enabled + +// @section motion + +// Invert the stepper direction. Change (or reverse the motor connector) if an axis goes the wrong way. +#define INVERT_X_DIR false +#define INVERT_Y_DIR false +#define INVERT_Z_DIR false +//#define INVERT_I_DIR false +//#define INVERT_J_DIR false +//#define INVERT_K_DIR false +//#define INVERT_U_DIR false +//#define INVERT_V_DIR false +//#define INVERT_W_DIR false + +// @section extruder + +// For direct drive extruder v9 set to true, for geared extruder set to false. +#define INVERT_E0_DIR true +#define INVERT_E1_DIR false +#define INVERT_E2_DIR false +#define INVERT_E3_DIR false +#define INVERT_E4_DIR false +#define INVERT_E5_DIR false +#define INVERT_E6_DIR false +#define INVERT_E7_DIR false + +// @section homing + +//#define NO_MOTION_BEFORE_HOMING // Inhibit movement until all axes have been homed. Also enable HOME_AFTER_DEACTIVATE for extra safety. +//#define HOME_AFTER_DEACTIVATE // Require rehoming after steppers are deactivated. Also enable NO_MOTION_BEFORE_HOMING for extra safety. + +/** + * Set Z_IDLE_HEIGHT if the Z-Axis moves on its own when steppers are disabled. + * - Use a low value (i.e., Z_MIN_POS) if the nozzle falls down to the bed. + * - Use a large value (i.e., Z_MAX_POS) if the bed falls down, away from the nozzle. + */ +//#define Z_IDLE_HEIGHT Z_HOME_POS + +//#define Z_CLEARANCE_FOR_HOMING 4 // (mm) Minimal Z height before homing (G28) for Z clearance above the bed, clamps, ... + // You'll need this much clearance above Z_MAX_POS to avoid grinding. + +//#define Z_AFTER_HOMING 10 // (mm) Height to move to after homing (if Z was homed) +//#define XY_AFTER_HOMING { 10, 10 } // (mm) Move to an XY position after homing (and raising Z) + +//#define EVENT_GCODE_AFTER_HOMING "M300 P440 S200" // Commands to run after G28 (and move to XY_AFTER_HOMING) + +// Direction of endstops when homing; 1=MAX, -1=MIN +// :[-1,1] +#define X_HOME_DIR 1 +#define Y_HOME_DIR 1 +#define Z_HOME_DIR 1 +//#define I_HOME_DIR -1 +//#define J_HOME_DIR -1 +//#define K_HOME_DIR -1 +//#define U_HOME_DIR -1 +//#define V_HOME_DIR -1 +//#define W_HOME_DIR -1 + +/** + * Safety Stops + * If an axis has endstops on both ends the one specified above is used for + * homing, while the other can be used for things like SD_ABORT_ON_ENDSTOP_HIT. + */ +//#define X_SAFETY_STOP +//#define Y_SAFETY_STOP +//#define Z_SAFETY_STOP +//#define I_SAFETY_STOP +//#define J_SAFETY_STOP +//#define K_SAFETY_STOP +//#define U_SAFETY_STOP +//#define V_SAFETY_STOP +//#define W_SAFETY_STOP + +// @section geometry + +// The size of the printable area +#define X_BED_SIZE ((PRINTABLE_RADIUS) * 2) +#define Y_BED_SIZE ((PRINTABLE_RADIUS) * 2) + +// Travel limits (linear=mm, rotational=°) after homing, corresponding to endstop positions. +#define X_MIN_POS -(PRINTABLE_RADIUS) +#define Y_MIN_POS -(PRINTABLE_RADIUS) +#define Z_MIN_POS 0 +#define X_MAX_POS PRINTABLE_RADIUS +#define Y_MAX_POS PRINTABLE_RADIUS +#define Z_MAX_POS MANUAL_Z_HOME_POS +//#define I_MIN_POS 0 +//#define I_MAX_POS 50 +//#define J_MIN_POS 0 +//#define J_MAX_POS 50 +//#define K_MIN_POS 0 +//#define K_MAX_POS 50 +//#define U_MIN_POS 0 +//#define U_MAX_POS 50 +//#define V_MIN_POS 0 +//#define V_MAX_POS 50 +//#define W_MIN_POS 0 +//#define W_MAX_POS 50 + +/** + * Software Endstops + * + * - Prevent moves outside the set machine bounds. + * - Individual axes can be disabled, if desired. + * - X and Y only apply to Cartesian robots. + * - Use 'M211' to set software endstops on/off or report current state + */ + +// Min software endstops constrain movement within minimum coordinate bounds +#define MIN_SOFTWARE_ENDSTOPS +#if ENABLED(MIN_SOFTWARE_ENDSTOPS) + #define MIN_SOFTWARE_ENDSTOP_X + #define MIN_SOFTWARE_ENDSTOP_Y + #define MIN_SOFTWARE_ENDSTOP_Z + #define MIN_SOFTWARE_ENDSTOP_I + #define MIN_SOFTWARE_ENDSTOP_J + #define MIN_SOFTWARE_ENDSTOP_K + #define MIN_SOFTWARE_ENDSTOP_U + #define MIN_SOFTWARE_ENDSTOP_V + #define MIN_SOFTWARE_ENDSTOP_W +#endif + +// Max software endstops constrain movement within maximum coordinate bounds +#define MAX_SOFTWARE_ENDSTOPS +#if ENABLED(MAX_SOFTWARE_ENDSTOPS) + #define MAX_SOFTWARE_ENDSTOP_X + #define MAX_SOFTWARE_ENDSTOP_Y + #define MAX_SOFTWARE_ENDSTOP_Z + #define MAX_SOFTWARE_ENDSTOP_I + #define MAX_SOFTWARE_ENDSTOP_J + #define MAX_SOFTWARE_ENDSTOP_K + #define MAX_SOFTWARE_ENDSTOP_U + #define MAX_SOFTWARE_ENDSTOP_V + #define MAX_SOFTWARE_ENDSTOP_W +#endif + +#if ANY(MIN_SOFTWARE_ENDSTOPS, MAX_SOFTWARE_ENDSTOPS) + #define SOFT_ENDSTOPS_MENU_ITEM // Enable/Disable software endstops from the LCD +#endif + +/** + * @section filament runout sensors + * + * Filament Runout Sensors + * Mechanical or opto endstops are used to check for the presence of filament. + * + * IMPORTANT: Runout will only trigger if Marlin is aware that a print job is running. + * Marlin knows a print job is running when: + * 1. Running a print job from media started with M24. + * 2. The Print Job Timer has been started with M75. + * 3. The heaters were turned on and PRINTJOB_TIMER_AUTOSTART is enabled. + * + * RAMPS-based boards use SERVO3_PIN for the first runout sensor. + * For other boards you may need to define FIL_RUNOUT_PIN, FIL_RUNOUT2_PIN, etc. + */ +//#define FILAMENT_RUNOUT_SENSOR +#if ENABLED(FILAMENT_RUNOUT_SENSOR) + #define FIL_RUNOUT_ENABLED_DEFAULT true // Enable the sensor on startup. Override with M412 followed by M500. + #define NUM_RUNOUT_SENSORS 1 // Number of sensors, up to one per extruder. Define a FIL_RUNOUT#_PIN for each. + + #define FIL_RUNOUT_STATE LOW // Pin state indicating that filament is NOT present. + #define FIL_RUNOUT_PULLUP // Use internal pullup for filament runout pins. + //#define FIL_RUNOUT_PULLDOWN // Use internal pulldown for filament runout pins. + //#define WATCH_ALL_RUNOUT_SENSORS // Execute runout script on any triggering sensor, not only for the active extruder. + // This is automatically enabled for MIXING_EXTRUDERs. + + // Override individually if the runout sensors vary + //#define FIL_RUNOUT1_STATE LOW + //#define FIL_RUNOUT1_PULLUP + //#define FIL_RUNOUT1_PULLDOWN + + //#define FIL_RUNOUT2_STATE LOW + //#define FIL_RUNOUT2_PULLUP + //#define FIL_RUNOUT2_PULLDOWN + + //#define FIL_RUNOUT3_STATE LOW + //#define FIL_RUNOUT3_PULLUP + //#define FIL_RUNOUT3_PULLDOWN + + //#define FIL_RUNOUT4_STATE LOW + //#define FIL_RUNOUT4_PULLUP + //#define FIL_RUNOUT4_PULLDOWN + + //#define FIL_RUNOUT5_STATE LOW + //#define FIL_RUNOUT5_PULLUP + //#define FIL_RUNOUT5_PULLDOWN + + //#define FIL_RUNOUT6_STATE LOW + //#define FIL_RUNOUT6_PULLUP + //#define FIL_RUNOUT6_PULLDOWN + + //#define FIL_RUNOUT7_STATE LOW + //#define FIL_RUNOUT7_PULLUP + //#define FIL_RUNOUT7_PULLDOWN + + //#define FIL_RUNOUT8_STATE LOW + //#define FIL_RUNOUT8_PULLUP + //#define FIL_RUNOUT8_PULLDOWN + + // Commands to execute on filament runout. + // With multiple runout sensors use the %c placeholder for the current tool in commands (e.g., "M600 T%c") + // NOTE: After 'M412 H1' the host handles filament runout and this script does not apply. + #define FILAMENT_RUNOUT_SCRIPT "M600" + + // After a runout is detected, continue printing this length of filament + // before executing the runout script. Useful for a sensor at the end of + // a feed tube. Requires 4 bytes SRAM per sensor, plus 4 bytes overhead. + //#define FILAMENT_RUNOUT_DISTANCE_MM 25 + + #ifdef FILAMENT_RUNOUT_DISTANCE_MM + // Enable this option to use an encoder disc that toggles the runout pin + // as the filament moves. (Be sure to set FILAMENT_RUNOUT_DISTANCE_MM + // large enough to avoid false positives.) + //#define FILAMENT_MOTION_SENSOR + + #if ENABLED(FILAMENT_MOTION_SENSOR) + //#define FILAMENT_SWITCH_AND_MOTION // Define separate pins below to sense motion + #if ENABLED(FILAMENT_SWITCH_AND_MOTION) + + #define FILAMENT_MOTION_DISTANCE_MM 3.0 // (mm) Missing distance required to trigger runout + + #define NUM_MOTION_SENSORS 1 // Number of sensors, up to one per extruder. Define a FIL_MOTION#_PIN for each. + //#define FIL_MOTION1_PIN -1 + + // Override individually if the motion sensors vary + //#define FIL_MOTION1_STATE LOW + //#define FIL_MOTION1_PULLUP + //#define FIL_MOTION1_PULLDOWN + + //#define FIL_MOTION2_STATE LOW + //#define FIL_MOTION2_PULLUP + //#define FIL_MOTION2_PULLDOWN + + //#define FIL_MOTION3_STATE LOW + //#define FIL_MOTION3_PULLUP + //#define FIL_MOTION3_PULLDOWN + + //#define FIL_MOTION4_STATE LOW + //#define FIL_MOTION4_PULLUP + //#define FIL_MOTION4_PULLDOWN + + //#define FIL_MOTION5_STATE LOW + //#define FIL_MOTION5_PULLUP + //#define FIL_MOTION5_PULLDOWN + + //#define FIL_MOTION6_STATE LOW + //#define FIL_MOTION6_PULLUP + //#define FIL_MOTION6_PULLDOWN + + //#define FIL_MOTION7_STATE LOW + //#define FIL_MOTION7_PULLUP + //#define FIL_MOTION7_PULLDOWN + + //#define FIL_MOTION8_STATE LOW + //#define FIL_MOTION8_PULLUP + //#define FIL_MOTION8_PULLDOWN + #endif // FILAMENT_SWITCH_AND_MOTION + #endif // FILAMENT_MOTION_SENSOR + #endif // FILAMENT_RUNOUT_DISTANCE_MM +#endif // FILAMENT_RUNOUT_SENSOR + +//=========================================================================== +//=============================== Bed Leveling ============================== +//=========================================================================== +// @section calibrate + +/** + * Choose one of the options below to enable G29 Bed Leveling. The parameters + * and behavior of G29 will change depending on your selection. + * + * If using a Probe for Z Homing, enable Z_SAFE_HOMING also! + * + * - AUTO_BED_LEVELING_3POINT + * Probe 3 arbitrary points on the bed (that aren't collinear) + * You specify the XY coordinates of all 3 points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_LINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_BILINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a mesh, best for large or uneven beds. + * + * - AUTO_BED_LEVELING_UBL (Unified Bed Leveling) + * A comprehensive bed leveling system combining the features and benefits + * of other systems. UBL also includes integrated Mesh Generation, Mesh + * Validation and Mesh Editing systems. + * + * - MESH_BED_LEVELING + * Probe a grid manually + * The result is a mesh, suitable for large or uneven beds. (See BILINEAR.) + * For machines without a probe, Mesh Bed Leveling provides a method to perform + * leveling in steps so you can manually adjust the Z height at each grid-point. + * With an LCD controller the process is guided step-by-step. + */ +//#define AUTO_BED_LEVELING_3POINT +//#define AUTO_BED_LEVELING_LINEAR +#define AUTO_BED_LEVELING_BILINEAR +//#define AUTO_BED_LEVELING_UBL +//#define MESH_BED_LEVELING + +/** + * Commands to execute at the start of G29 probing, + * after switching to the PROBING_TOOL. + */ +//#define EVENT_GCODE_BEFORE_G29 "M300 P440 S200" + +/** + * Commands to execute at the end of G29 probing. + * Useful to retract or move the Z probe out of the way. + */ +//#define EVENT_GCODE_AFTER_G29 "G1 Z10 F12000\nG1 X15 Y330\nG1 Z0.5\nG1 Z10" + +/** + * Normally G28 leaves leveling disabled on completion. Enable one of + * these options to restore the prior leveling state or to always enable + * leveling immediately after G28. + */ +#define RESTORE_LEVELING_AFTER_G28 +//#define ENABLE_LEVELING_AFTER_G28 + +/** + * Auto-leveling needs preheating + */ +//#define PREHEAT_BEFORE_LEVELING +#if ENABLED(PREHEAT_BEFORE_LEVELING) + #define LEVELING_NOZZLE_TEMP 120 // (°C) Only applies to E0 at this time + #define LEVELING_BED_TEMP 50 +#endif + +/** + * Enable detailed logging of G28, G29, M48, etc. + * Turn on with the command 'M111 S32'. + * NOTE: Requires a lot of flash! + */ +//#define DEBUG_LEVELING_FEATURE + +#if ANY(MESH_BED_LEVELING, AUTO_BED_LEVELING_UBL, PROBE_MANUALLY) + // Set a height for the start of manual adjustment + #define MANUAL_PROBE_START_Z 0.2 // (mm) Comment out to use the last-measured height +#endif + +#if ANY(MESH_BED_LEVELING, AUTO_BED_LEVELING_BILINEAR, AUTO_BED_LEVELING_UBL) + /** + * Gradually reduce leveling correction until a set height is reached, + * at which point movement will be level to the machine's XY plane. + * The height can be set with M420 Z + */ + #define ENABLE_LEVELING_FADE_HEIGHT + #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) + #define DEFAULT_LEVELING_FADE_HEIGHT 10.0 // (mm) Default fade height. + #endif + + /** + * Add Z offset (M424 Z) that applies to all moves at the planner level. + * This Z offset will be automatically set to the middle value with G29. + */ + //#define GLOBAL_MESH_Z_OFFSET + + /** + * For Cartesian machines, instead of dividing moves on mesh boundaries, + * split up moves into short segments like a Delta. This follows the + * contours of the bed more closely than edge-to-edge straight moves. + */ + #define SEGMENT_LEVELED_MOVES + #define LEVELED_SEGMENT_LENGTH 5.0 // (mm) Length of all segments (except the last one) + + /** + * Enable the G26 Mesh Validation Pattern tool. + */ + //#define G26_MESH_VALIDATION + #if ENABLED(G26_MESH_VALIDATION) + #define MESH_TEST_NOZZLE_SIZE 0.4 // (mm) Diameter of primary nozzle. + #define MESH_TEST_LAYER_HEIGHT 0.2 // (mm) Default layer height for G26. + #define MESH_TEST_HOTEND_TEMP 205 // (°C) Default nozzle temperature for G26. + #define MESH_TEST_BED_TEMP 60 // (°C) Default bed temperature for G26. + #define G26_XY_FEEDRATE 20 // (mm/s) Feedrate for G26 XY moves. + #define G26_XY_FEEDRATE_TRAVEL 100 // (mm/s) Feedrate for G26 XY travel moves. + #define G26_RETRACT_MULTIPLIER 1.0 // G26 Q (retraction) used by default between mesh test elements. + #endif + +#endif + +#if ANY(AUTO_BED_LEVELING_LINEAR, AUTO_BED_LEVELING_BILINEAR) + + // Set the number of grid points per dimension. + #define GRID_MAX_POINTS_X 9 + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + // Probe along the Y axis, advancing X after each column + //#define PROBE_Y_FIRST + + #if ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Beyond the probed grid, continue the implied tilt? + // Default is to maintain the height of the nearest edge. + //#define EXTRAPOLATE_BEYOND_GRID + + // + // Subdivision of the grid by Catmull-Rom method. + // Synthesizes intermediate points to produce a more detailed mesh. + // + //#define ABL_BILINEAR_SUBDIVISION + #if ENABLED(ABL_BILINEAR_SUBDIVISION) + // Number of subdivisions between probe points + #define BILINEAR_SUBDIVISIONS 3 + #endif + + #endif + +#elif ENABLED(AUTO_BED_LEVELING_UBL) + + //=========================================================================== + //========================= Unified Bed Leveling ============================ + //=========================================================================== + + //#define MESH_EDIT_GFX_OVERLAY // Display a graphics overlay while editing the mesh + + #define MESH_INSET 1 // Set Mesh bounds as an inset region of the bed + #define GRID_MAX_POINTS_X 10 // Don't use more than 15 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + //#define UBL_HILBERT_CURVE // Use Hilbert distribution for less travel when probing multiple points + + //#define UBL_TILT_ON_MESH_POINTS // Use nearest mesh points with G29 J for better Z reference + //#define UBL_TILT_ON_MESH_POINTS_3POINT // Use nearest mesh points with G29 J0 (3-point) + + #define UBL_MESH_EDIT_MOVES_Z // Sophisticated users prefer no movement of nozzle + #define UBL_SAVE_ACTIVE_ON_M500 // Save the currently active mesh in the current slot on M500 + + //#define UBL_Z_RAISE_WHEN_OFF_MESH 2.5 // When the nozzle is off the mesh, this value is used + // as the Z-Height correction value. + + //#define UBL_MESH_WIZARD // Run several commands in a row to get a complete mesh + + /** + * Probing not allowed within the position of an obstacle. + */ + //#define AVOID_OBSTACLES + #if ENABLED(AVOID_OBSTACLES) + #define CLIP_W 23 // Bed clip width, should be padded a few mm over its physical size + #define CLIP_H 14 // Bed clip height, should be padded a few mm over its physical size + + // Obstacle Rectangles defined as { X1, Y1, X2, Y2 } + #define OBSTACLE1 { (X_BED_SIZE) / 4 - (CLIP_W) / 2, 0, (X_BED_SIZE) / 4 + (CLIP_W) / 2, CLIP_H } + #define OBSTACLE2 { (X_BED_SIZE) * 3 / 4 - (CLIP_W) / 2, 0, (X_BED_SIZE) * 3 / 4 + (CLIP_W) / 2, CLIP_H } + #define OBSTACLE3 { (X_BED_SIZE) / 4 - (CLIP_W) / 2, (Y_BED_SIZE) - (CLIP_H), (X_BED_SIZE) / 4 + (CLIP_W) / 2, Y_BED_SIZE } + #define OBSTACLE4 { (X_BED_SIZE) * 3 / 4 - (CLIP_W) / 2, (Y_BED_SIZE) - (CLIP_H), (X_BED_SIZE) * 3 / 4 + (CLIP_W) / 2, Y_BED_SIZE } + + // The probed grid must be inset for G29 J. This is okay, since it is + // only used to compute a linear transformation for the mesh itself. + #define G29J_MESH_TILT_MARGIN ((CLIP_H) + 1) + #endif + +#elif ENABLED(MESH_BED_LEVELING) + + //=========================================================================== + //=================================== Mesh ================================== + //=========================================================================== + + #define MESH_INSET 10 // Set Mesh bounds as an inset region of the bed + #define GRID_MAX_POINTS_X 3 + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + //#define MESH_G28_REST_ORIGIN // After homing all axes ('G28' or 'G28 XYZ') rest Z at Z_MIN_POS + +#endif // BED_LEVELING + +/** + * Add a bed leveling sub-menu for ABL or MBL. + * Include a guided procedure if manual probing is enabled. + */ +#define LCD_BED_LEVELING + +#if ENABLED(LCD_BED_LEVELING) + #define MESH_EDIT_Z_STEP 0.025 // (mm) Step size while manually probing Z axis. + #define LCD_PROBE_Z_RANGE 4 // (mm) Z Range centered on Z_MIN_POS for LCD Z adjustment + //#define MESH_EDIT_MENU // Add a menu to edit mesh points +#endif + +// Add a menu item to move between bed corners for manual bed adjustment +//#define LCD_BED_TRAMMING + +#if ENABLED(LCD_BED_TRAMMING) + #define BED_TRAMMING_INSET_LFRB { 30, 30, 30, 30 } // (mm) Left, Front, Right, Back insets + #define BED_TRAMMING_HEIGHT 0.0 // (mm) Z height of nozzle at tramming points + #define BED_TRAMMING_Z_HOP 4.0 // (mm) Z raise between tramming points + //#define BED_TRAMMING_INCLUDE_CENTER // Move to the center after the last corner + //#define BED_TRAMMING_USE_PROBE + #if ENABLED(BED_TRAMMING_USE_PROBE) + #define BED_TRAMMING_PROBE_TOLERANCE 0.1 // (mm) + #define BED_TRAMMING_VERIFY_RAISED // After adjustment triggers the probe, re-probe to verify + //#define BED_TRAMMING_AUDIO_FEEDBACK + #endif + + /** + * Corner Leveling Order + * + * Set 2 or 4 points. When 2 points are given, the 3rd is the center of the opposite edge. + * + * LF Left-Front RF Right-Front + * LB Left-Back RB Right-Back + * + * Examples: + * + * Default {LF,RB,LB,RF} {LF,RF} {LB,LF} + * LB --------- RB LB --------- RB LB --------- RB LB --------- RB + * | 4 3 | | 3 2 | | <3> | | 1 | + * | | | | | | | <3>| + * | 1 2 | | 1 4 | | 1 2 | | 2 | + * LF --------- RF LF --------- RF LF --------- RF LF --------- RF + */ + #define BED_TRAMMING_LEVELING_ORDER { LF, RF, RB, LB } +#endif + +// @section homing + +// The center of the bed is at (X=0, Y=0) +//#define BED_CENTER_AT_0_0 + +// Manually set the home position. Leave these undefined for automatic settings. +// For DELTA this is the top-center of the Cartesian print volume. +//#define MANUAL_X_HOME_POS 0 +//#define MANUAL_Y_HOME_POS 0 +#define MANUAL_Z_HOME_POS DELTA_HEIGHT // Distance between the nozzle to printbed after homing +//#define MANUAL_I_HOME_POS 0 +//#define MANUAL_J_HOME_POS 0 +//#define MANUAL_K_HOME_POS 0 +//#define MANUAL_U_HOME_POS 0 +//#define MANUAL_V_HOME_POS 0 +//#define MANUAL_W_HOME_POS 0 + +/** + * Use "Z Safe Homing" to avoid homing with a Z probe outside the bed area. + * + * - Moves the Z probe (or nozzle) to a defined XY point before Z homing. + * - Allows Z homing only when XY positions are known and trusted. + * - If stepper drivers sleep, XY homing may be required again before Z homing. + */ +#define Z_SAFE_HOMING + +#if ENABLED(Z_SAFE_HOMING) + #define Z_SAFE_HOMING_X_POINT X_CENTER // (mm) X point for Z homing + #define Z_SAFE_HOMING_Y_POINT Y_CENTER // (mm) Y point for Z homing + //#define Z_SAFE_HOMING_POINT_ABSOLUTE // Ignore home offsets (M206) for Z homing position +#endif + +// Homing speeds (linear=mm/min, rotational=°/min) +#define HOMING_FEEDRATE_MM_M { (50*60), (50*60), (50*60) } + +// Edit homing feedrates with M210 and MarlinUI menu items +//#define EDITABLE_HOMING_FEEDRATE + +// Validate that endstops are triggered on homing moves +#define VALIDATE_HOMING_ENDSTOPS + +// @section calibrate + +/** + * Bed Skew Compensation + * + * This feature corrects for misalignment in the XYZ axes. + * + * Take the following steps to get the bed skew in the XY plane: + * 1. Print a test square (e.g., https://www.thingiverse.com/thing:2563185) + * 2. For XY_DIAG_AC measure the diagonal A to C + * 3. For XY_DIAG_BD measure the diagonal B to D + * 4. For XY_SIDE_AD measure the edge A to D + * + * Marlin automatically computes skew factors from these measurements. + * Skew factors may also be computed and set manually: + * + * - Compute AB : SQRT(2*AC*AC+2*BD*BD-4*AD*AD)/2 + * - XY_SKEW_FACTOR : TAN(PI/2-ACOS((AC*AC-AB*AB-AD*AD)/(2*AB*AD))) + * + * If desired, follow the same procedure for XZ and YZ. + * Use these diagrams for reference: + * + * Y Z Z + * ^ B-------C ^ B-------C ^ B-------C + * | / / | / / | / / + * | / / | / / | / / + * | A-------D | A-------D | A-------D + * +-------------->X +-------------->X +-------------->Y + * XY_SKEW_FACTOR XZ_SKEW_FACTOR YZ_SKEW_FACTOR + */ +//#define SKEW_CORRECTION + +#if ENABLED(SKEW_CORRECTION) + // Input all length measurements here: + #define XY_DIAG_AC 282.8427124746 + #define XY_DIAG_BD 282.8427124746 + #define XY_SIDE_AD 200 + + // Or, set the XY skew factor directly: + //#define XY_SKEW_FACTOR 0.0 + + //#define SKEW_CORRECTION_FOR_Z + #if ENABLED(SKEW_CORRECTION_FOR_Z) + #define XZ_DIAG_AC 282.8427124746 + #define XZ_DIAG_BD 282.8427124746 + #define YZ_DIAG_AC 282.8427124746 + #define YZ_DIAG_BD 282.8427124746 + #define YZ_SIDE_AD 200 + + // Or, set the Z skew factors directly: + //#define XZ_SKEW_FACTOR 0.0 + //#define YZ_SKEW_FACTOR 0.0 + #endif + + // Enable this option for M852 to set skew at runtime + //#define SKEW_CORRECTION_GCODE +#endif + +//============================================================================= +//============================= Additional Features =========================== +//============================================================================= + +// @section eeprom + +/** + * EEPROM + * + * Persistent storage to preserve configurable settings across reboots. + * + * M500 - Store settings to EEPROM. + * M501 - Read settings from EEPROM. (i.e., Throw away unsaved changes) + * M502 - Revert settings to "factory" defaults. (Follow with M500 to init the EEPROM.) + */ +#define EEPROM_SETTINGS // Persistent storage with M500 and M501 +//#define DISABLE_M503 // Saves ~2700 bytes of flash. Disable for release! +#define EEPROM_CHITCHAT // Give feedback on EEPROM commands. Disable to save flash. +#define EEPROM_BOOT_SILENT // Keep M503 quiet and only give errors during first load +#if ENABLED(EEPROM_SETTINGS) + //#define EEPROM_AUTO_INIT // Init EEPROM automatically on any errors. + //#define EEPROM_INIT_NOW // Init EEPROM on first boot after a new build. +#endif + +// @section host + +// +// Host Keepalive +// +// When enabled Marlin will send a busy status message to the host +// every couple of seconds when it can't accept commands. +// +#define HOST_KEEPALIVE_FEATURE // Disable this if your host doesn't like keepalive messages +#define DEFAULT_KEEPALIVE_INTERVAL 2 // Number of seconds between "busy" messages. Set with M113. +#define BUSY_WHILE_HEATING // Some hosts require "busy" messages even during heating + +// @section units + +// +// G20/G21 Inch mode support +// +//#define INCH_MODE_SUPPORT + +// +// M149 Set temperature units support +// +//#define TEMPERATURE_UNITS_SUPPORT + +// @section temperature + +// +// Preheat Constants - Up to 10 are supported without changes +// +#define PREHEAT_1_LABEL "PLA" +#define PREHEAT_1_TEMP_HOTEND 180 +#define PREHEAT_1_TEMP_BED 70 +#define PREHEAT_1_TEMP_CHAMBER 35 +#define PREHEAT_1_FAN_SPEED 0 // Value from 0 to 255 + +#define PREHEAT_2_LABEL "ABS" +#define PREHEAT_2_TEMP_HOTEND 240 +#define PREHEAT_2_TEMP_BED 110 +#define PREHEAT_2_TEMP_CHAMBER 35 +#define PREHEAT_2_FAN_SPEED 0 // Value from 0 to 255 + +/** + * @section nozzle park + * + * Nozzle Park + * + * Park the nozzle at the given XYZ position on idle or G27. + * + * The "P" parameter controls the action applied to the Z axis: + * + * P0 (Default) If Z is below park Z raise the nozzle. + * P1 Raise the nozzle always to Z-park height. + * P2 Raise the nozzle by Z-park amount, limited to Z_MAX_POS. + */ +#define NOZZLE_PARK_FEATURE + +#if ENABLED(NOZZLE_PARK_FEATURE) + // Specify a park position as { X, Y, Z_raise } + #define NOZZLE_PARK_POINT { 0, Y_MIN_POS, 10 } + #define NOZZLE_PARK_MOVE 0 // Park motion: 0 = XY Move, 1 = X Only, 2 = Y Only, 3 = X before Y, 4 = Y before X + #define NOZZLE_PARK_Z_RAISE_MIN 2 // (mm) Always raise Z by at least this distance + #define NOZZLE_PARK_XY_FEEDRATE 100 // (mm/s) X and Y axes feedrate (also used for delta Z axis) + #define NOZZLE_PARK_Z_FEEDRATE 5 // (mm/s) Z axis feedrate (not used for delta printers) +#endif + +/** + * @section nozzle clean + * + * Clean Nozzle Feature + * + * Adds the G12 command to perform a nozzle cleaning process. + * + * Parameters: + * P Pattern + * S Strokes / Repetitions + * T Triangles (P1 only) + * + * Patterns: + * P0 Straight line (default). This process requires a sponge type material + * at a fixed bed location. "S" specifies strokes (i.e. back-forth motions) + * between the start / end points. + * + * P1 Zig-zag pattern between (X0, Y0) and (X1, Y1), "T" specifies the + * number of zig-zag triangles to do. "S" defines the number of strokes. + * Zig-zags are done in whichever is the narrower dimension. + * For example, "G12 P1 S1 T3" will execute: + * + * -- + * | (X0, Y1) | /\ /\ /\ | (X1, Y1) + * | | / \ / \ / \ | + * A | | / \ / \ / \ | + * | | / \ / \ / \ | + * | (X0, Y0) | / \/ \/ \ | (X1, Y0) + * -- +--------------------------------+ + * |________|_________|_________| + * T1 T2 T3 + * + * P2 Circular pattern with middle at NOZZLE_CLEAN_CIRCLE_MIDDLE. + * "R" specifies the radius. "S" specifies the stroke count. + * Before starting, the nozzle moves to NOZZLE_CLEAN_START_POINT. + * + * Caveats: The ending Z should be the same as starting Z. + */ +//#define NOZZLE_CLEAN_FEATURE + +#if ENABLED(NOZZLE_CLEAN_FEATURE) + #define NOZZLE_CLEAN_PATTERN_LINE // Provide 'G12 P0' - a simple linear cleaning pattern + #define NOZZLE_CLEAN_PATTERN_ZIGZAG // Provide 'G12 P1' - a zigzag cleaning pattern + #define NOZZLE_CLEAN_PATTERN_CIRCLE // Provide 'G12 P2' - a circular cleaning pattern + + // Default pattern to use when 'P' is not provided to G12. One of the enabled options above. + #define NOZZLE_CLEAN_DEFAULT_PATTERN 0 + + #define NOZZLE_CLEAN_STROKES 12 // Default number of pattern repetitions + + #if ENABLED(NOZZLE_CLEAN_PATTERN_ZIGZAG) + #define NOZZLE_CLEAN_TRIANGLES 3 // Default number of triangles + #endif + + // Specify positions for each tool as { { X, Y, Z }, { X, Y, Z } } + // Dual hotend system may use { { -20, (Y_BED_SIZE / 2), (Z_MIN_POS + 1) }, { 420, (Y_BED_SIZE / 2), (Z_MIN_POS + 1) }} + #define NOZZLE_CLEAN_START_POINT { { 30, 30, (Z_MIN_POS + 1) } } + #define NOZZLE_CLEAN_END_POINT { { 100, 60, (Z_MIN_POS + 1) } } + + #if ENABLED(NOZZLE_CLEAN_PATTERN_CIRCLE) + #define NOZZLE_CLEAN_CIRCLE_RADIUS 6.5 // (mm) Circular pattern radius + #define NOZZLE_CLEAN_CIRCLE_FN 10 // Circular pattern circle number of segments + #define NOZZLE_CLEAN_CIRCLE_MIDDLE NOZZLE_CLEAN_START_POINT // Middle point of circle + #endif + + // Move the nozzle to the initial position after cleaning + #define NOZZLE_CLEAN_GOBACK + + // For a purge/clean station that's always at the gantry height (thus no Z move) + //#define NOZZLE_CLEAN_NO_Z + + // For a purge/clean station mounted on the X axis + //#define NOZZLE_CLEAN_NO_Y + + // Require a minimum hotend temperature for cleaning + #define NOZZLE_CLEAN_MIN_TEMP 170 + //#define NOZZLE_CLEAN_HEATUP // Heat up the nozzle instead of skipping wipe + + // Explicit wipe G-code script applies to a G12 with no arguments. + //#define WIPE_SEQUENCE_COMMANDS "G1 X-17 Y25 Z10 F4000\nG1 Z1\nM114\nG1 X-17 Y25\nG1 X-17 Y95\nG1 X-17 Y25\nG1 X-17 Y95\nG1 X-17 Y25\nG1 X-17 Y95\nG1 X-17 Y25\nG1 X-17 Y95\nG1 X-17 Y25\nG1 X-17 Y95\nG1 X-17 Y25\nG1 X-17 Y95\nG1 Z15\nM400\nG0 X-10.0 Y-9.0" + +#endif + +// @section host + +/** + * Print Job Timer + * + * Automatically start and stop the print job timer on M104/M109/M140/M190/M141/M191. + * The print job timer will only be stopped if the bed/chamber target temp is + * below BED_MINTEMP/CHAMBER_MINTEMP. + * + * M104 (hotend, no wait) - high temp = none, low temp = stop timer + * M109 (hotend, wait) - high temp = start timer, low temp = stop timer + * M140 (bed, no wait) - high temp = none, low temp = stop timer + * M190 (bed, wait) - high temp = start timer, low temp = none + * M141 (chamber, no wait) - high temp = none, low temp = stop timer + * M191 (chamber, wait) - high temp = start timer, low temp = none + * + * For M104/M109, high temp is anything over EXTRUDE_MINTEMP / 2. + * For M140/M190, high temp is anything over BED_MINTEMP. + * For M141/M191, high temp is anything over CHAMBER_MINTEMP. + * + * The timer can also be controlled with the following commands: + * + * M75 - Start the print job timer + * M76 - Pause the print job timer + * M77 - Stop the print job timer + */ +#define PRINTJOB_TIMER_AUTOSTART + +// @section stats + +/** + * Print Counter + * + * Track statistical data such as: + * + * - Total print jobs + * - Total successful print jobs + * - Total failed print jobs + * - Total time printing + * + * View the current statistics with M78. + */ +#define PRINTCOUNTER +#if ENABLED(PRINTCOUNTER) + #define PRINTCOUNTER_SAVE_INTERVAL 60 // (minutes) EEPROM save interval during print. A value of 0 will save stats at end of print. +#endif + +// @section security + +/** + * Password + * + * Set a numerical password for the printer which can be requested: + * + * - When the printer boots up + * - Upon opening the 'Print from Media' Menu + * - When SD printing is completed or aborted + * + * The following G-codes can be used: + * + * M510 - Lock Printer. Blocks all commands except M511. + * M511 - Unlock Printer. + * M512 - Set, Change and Remove Password. + * + * If you forget the password and get locked out you'll need to re-flash + * the firmware with the feature disabled, reset EEPROM, and (optionally) + * re-flash the firmware again with this feature enabled. + */ +//#define PASSWORD_FEATURE +#if ENABLED(PASSWORD_FEATURE) + #define PASSWORD_LENGTH 4 // (#) Number of digits (1-9). 3 or 4 is recommended + #define PASSWORD_ON_STARTUP + #define PASSWORD_UNLOCK_GCODE // Unlock with the M511 P command. Disable to prevent brute-force attack. + #define PASSWORD_CHANGE_GCODE // Change the password with M512 P S. + //#define PASSWORD_ON_SD_PRINT_MENU // This does not prevent G-codes from running + //#define PASSWORD_AFTER_SD_PRINT_END + //#define PASSWORD_AFTER_SD_PRINT_ABORT + //#include "Configuration_Secure.h" // External file with PASSWORD_DEFAULT_VALUE +#endif + +// @section media + +/** + * SD CARD + * + * SD Card support is disabled by default. If your controller has an SD slot, + * you must uncomment the following option or it won't work. + */ +#define SDSUPPORT + +/** + * SD CARD: ENABLE CRC + * + * Use CRC checks and retries on the SD communication. + */ +#if ENABLED(SDSUPPORT) + //#define SD_CHECK_AND_RETRY +#endif + +// @section interface + +/** + * LCD LANGUAGE + * + * Select the language to display on the LCD. These languages are available: + * + * en, an, bg, ca, cz, da, de, el, el_CY, es, eu, fi, fr, gl, hr, hu, it, + * jp_kana, ko_KR, nl, pl, pt, pt_br, ro, ru, sk, sv, tr, uk, vi, zh_CN, zh_TW + * + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cz':'Czech', 'da':'Danish', 'de':'German', 'el':'Greek (Greece)', 'el_CY':'Greek (Cyprus)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'hu':'Hungarian', 'it':'Italian', 'jp_kana':'Japanese', 'ko_KR':'Korean (South Korea)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt_br':'Portuguese (Brazilian)', 'ro':'Romanian', 'ru':'Russian', 'sk':'Slovak', 'sv':'Swedish', 'tr':'Turkish', 'uk':'Ukrainian', 'vi':'Vietnamese', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Traditional)' } + */ +#define LCD_LANGUAGE en + +/** + * LCD Character Set + * + * Note: This option is NOT applicable to Graphical Displays. + * + * All character-based LCDs provide ASCII plus one of these + * language extensions: + * + * - JAPANESE ... the most common + * - WESTERN ... with more accented characters + * - CYRILLIC ... for the Russian language + * + * To determine the language extension installed on your controller: + * + * - Compile and upload with LCD_LANGUAGE set to 'test' + * - Click the controller to view the LCD menu + * - The LCD will display Japanese, Western, or Cyrillic text + * + * See https://marlinfw.org/docs/development/lcd_language.html + * + * :['JAPANESE', 'WESTERN', 'CYRILLIC'] + */ +#define DISPLAY_CHARSET_HD44780 JAPANESE + +/** + * Info Screen Style (0:Classic, 1:Průša, 2:CNC) + * + * :[0:'Classic', 1:'Průša', 2:'CNC'] + */ +#define LCD_INFO_SCREEN_STYLE 0 + +/** + * LCD Menu Items + * + * Disable all menus and only display the Status Screen, or + * just remove some extraneous menu items to recover space. + */ +//#define NO_LCD_MENUS +//#define SLIM_LCD_MENUS + +// +// ENCODER SETTINGS +// +// This option overrides the default number of encoder pulses needed to +// produce one step. Should be increased for high-resolution encoders. +// +//#define ENCODER_PULSES_PER_STEP 4 + +// +// Use this option to override the number of step signals required to +// move between next/prev menu items. +// +//#define ENCODER_STEPS_PER_MENU_ITEM 1 + +/** + * Encoder Direction Options + * + * Test your encoder's behavior first with both options disabled. + * + * Reversed Value Edit and Menu Nav? Enable REVERSE_ENCODER_DIRECTION. + * Reversed Menu Navigation only? Enable REVERSE_MENU_DIRECTION. + * Reversed Value Editing only? Enable BOTH options. + */ + +// +// This option reverses the encoder direction everywhere. +// +// Set this option if CLOCKWISE causes values to DECREASE +// +//#define REVERSE_ENCODER_DIRECTION + +// +// This option reverses the encoder direction for navigating LCD menus. +// +// If CLOCKWISE normally moves DOWN this makes it go UP. +// If CLOCKWISE normally moves UP this makes it go DOWN. +// +//#define REVERSE_MENU_DIRECTION + +// +// This option reverses the encoder direction for Select Screen. +// +// If CLOCKWISE normally moves LEFT this makes it go RIGHT. +// If CLOCKWISE normally moves RIGHT this makes it go LEFT. +// +//#define REVERSE_SELECT_DIRECTION + +// +// Encoder EMI Noise Filter +// +// This option increases encoder samples to filter out phantom encoder clicks caused by EMI noise. +// +//#define ENCODER_NOISE_FILTER +#if ENABLED(ENCODER_NOISE_FILTER) + #define ENCODER_SAMPLES 10 +#endif + +// +// Individual Axis Homing +// +// Add individual axis homing items (Home X, Home Y, and Home Z) to the LCD menu. +// +//#define INDIVIDUAL_AXIS_HOMING_MENU +//#define INDIVIDUAL_AXIS_HOMING_SUBMENU + +// +// SPEAKER/BUZZER +// +// If you have a speaker that can produce tones, enable it here. +// By default Marlin assumes you have a buzzer with a fixed frequency. +// +#define SPEAKER + +// +// The duration and frequency for the UI feedback sound. +// Set these to 0 to disable audio feedback in the LCD menus. +// +// Note: Test audio output with the G-Code: +// M300 S P +// +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 2 +//#define LCD_FEEDBACK_FREQUENCY_HZ 5000 + +// +// Tone queue size, used to keep beeps from blocking execution. +// Default is 4, or override here. Costs 4 bytes of SRAM per entry. +// +//#define TONE_QUEUE_LENGTH 4 + +// +// A sequence of tones to play at startup, in pairs of tone (Hz), duration (ms). +// Silence in-between tones. +// +//#define STARTUP_TUNE { 698, 300, 0, 50, 523, 50, 0, 25, 494, 50, 0, 25, 523, 100, 0, 50, 554, 300, 0, 100, 523, 300 } + +//============================================================================= +//======================== LCD / Controller Selection ========================= +//======================== (Character-based LCDs) ========================= +//============================================================================= +// @section lcd + +// +// RepRapDiscount Smart Controller. +// https://reprap.org/wiki/RepRapDiscount_Smart_Controller +// +// Note: Usually sold with a white PCB. +// +#define REPRAP_DISCOUNT_SMART_CONTROLLER + +// +// GT2560 (YHCB2004) LCD Display +// +// Requires Testato, Koepel softwarewire library and +// Andriy Golovnya's LiquidCrystal_AIP31068 library. +// +//#define YHCB2004 + +// +// Original RADDS LCD Display+Encoder+SDCardReader +// https://web.archive.org/web/20200719145306/doku.radds.org/dokumentation/lcd-display/ +// +//#define RADDS_DISPLAY + +// +// ULTIMAKER Controller. +// +//#define ULTIMAKERCONTROLLER + +// +// ULTIPANEL as seen on Thingiverse. +// +//#define ULTIPANEL + +// +// PanelOne from T3P3 (via RAMPS 1.4 AUX2/AUX3) +// https://reprap.org/wiki/PanelOne +// +//#define PANEL_ONE + +// +// GADGETS3D G3D LCD/SD Controller +// https://reprap.org/wiki/RAMPS_1.3/1.4_GADGETS3D_Shield_with_Panel +// +// Note: Usually sold with a blue PCB. +// +//#define G3D_PANEL + +// +// RigidBot Panel V1.0 +// +//#define RIGIDBOT_PANEL + +// +// Makeboard 3D Printer Parts 3D Printer Mini Display 1602 Mini Controller +// https://www.aliexpress.com/item/32765887917.html +// +//#define MAKEBOARD_MINI_2_LINE_DISPLAY_1602 + +/** + * ANET and Tronxy 20x4 Controller + * LCD2004 display with 5 analog buttons. + * + * NOTE: Requires ADC_KEYPAD_PIN to be assigned to an analog pin. + * This LCD is known to be susceptible to electrical interference which + * scrambles the display. Press any button to clear it up. + */ +//#define ZONESTAR_LCD + +// +// Generic 16x2, 16x4, 20x2, or 20x4 character-based LCD. +// +//#define ULTRA_LCD + +//============================================================================= +//======================== LCD / Controller Selection ========================= +//===================== (I2C and Shift-Register LCDs) ===================== +//============================================================================= + +// +// CONTROLLER TYPE: I2C +// +// Note: These controllers require the installation of Arduino's LiquidCrystal_I2C +// library. For more info: https://github.com/kiyoshigawa/LiquidCrystal_I2C +// + +// +// Elefu RA Board Control Panel +// https://web.archive.org/web/20140823033947/www.elefu.com/index.php?route=product/product&product_id=53 +// +//#define RA_CONTROL_PANEL + +// +// Sainsmart (YwRobot) LCD Displays +// +// These require LiquidCrystal_I2C library: +// https://github.com/MarlinFirmware/New-LiquidCrystal +// https://github.com/fmalpartida/New-LiquidCrystal/wiki +// +//#define LCD_SAINSMART_I2C_1602 +//#define LCD_SAINSMART_I2C_2004 + +// +// Generic LCM1602 LCD adapter +// +//#define LCM1602 + +// +// PANELOLU2 LCD with status LEDs, +// separate encoder and click inputs. +// +// Note: This controller requires Arduino's LiquidTWI2 library v1.2.3 or later. +// For more info: https://github.com/lincomatic/LiquidTWI2 +// +// Note: The PANELOLU2 encoder click input can either be directly connected to +// a pin (if BTN_ENC defined to != -1) or read through I2C (when BTN_ENC == -1). +// +//#define LCD_I2C_PANELOLU2 + +// +// Panucatt VIKI LCD with status LEDs, +// integrated click & L/R/U/D buttons, separate encoder inputs. +// +//#define LCD_I2C_VIKI + +// +// CONTROLLER TYPE: Shift register panels +// + +// +// 2-wire Non-latching LCD SR from https://github.com/fmalpartida/New-LiquidCrystal/wiki/schematics#user-content-ShiftRegister_connection +// LCD configuration: https://reprap.org/wiki/SAV_3D_LCD +// +//#define SAV_3DLCD + +// +// 3-wire SR LCD with strobe using 74HC4094 +// https://github.com/mikeshub/SailfishLCD +// Uses the code directly from Sailfish +// +//#define FF_INTERFACEBOARD + +// +// TFT GLCD Panel with Marlin UI +// Panel connected to main board by SPI or I2C interface. +// See https://github.com/Serhiy-K/TFTGLCDAdapter +// +//#define TFTGLCD_PANEL_SPI +//#define TFTGLCD_PANEL_I2C + +//============================================================================= +//======================= LCD / Controller Selection ======================= +//========================= (Graphical LCDs) ======================== +//============================================================================= + +// +// CONTROLLER TYPE: Graphical 128x64 (DOGM) +// +// IMPORTANT: The U8glib library is required for Graphical Display! +// https://github.com/olikraus/U8glib_Arduino +// +// NOTE: If the LCD is unresponsive you may need to reverse the plugs. +// + +// +// RepRapDiscount FULL GRAPHIC Smart Controller +// https://reprap.org/wiki/RepRapDiscount_Full_Graphic_Smart_Controller +// +//#define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER + +// +// K.3D Full Graphic Smart Controller +// +//#define K3D_FULL_GRAPHIC_SMART_CONTROLLER + +// +// ReprapWorld Graphical LCD +// https://reprapworld.com/electronics/3d-printer-modules/autonomous-printing/graphical-lcd-screen-v1-0/ +// +//#define REPRAPWORLD_GRAPHICAL_LCD + +// +// Activate one of these if you have a Panucatt Devices +// Viki 2.0 or mini Viki with Graphic LCD +// https://www.panucatt.com +// +//#define VIKI2 +//#define miniVIKI + +// +// Alfawise Ex8 printer LCD marked as WYH L12864 COG +// +//#define WYH_L12864 + +// +// MakerLab Mini Panel with graphic +// controller and SD support - https://reprap.org/wiki/Mini_panel +// +//#define MINIPANEL + +// +// MaKr3d Makr-Panel with graphic controller and SD support. +// https://reprap.org/wiki/MaKrPanel +// +//#define MAKRPANEL + +// +// Adafruit ST7565 Full Graphic Controller. +// https://github.com/eboston/Adafruit-ST7565-Full-Graphic-Controller/ +// +//#define ELB_FULL_GRAPHIC_CONTROLLER + +// +// BQ LCD Smart Controller shipped by +// default with the BQ Hephestos 2 and Witbox 2. +// +//#define BQ_LCD_SMART_CONTROLLER + +// +// Cartesio UI +// https://web.archive.org/web/20180605050442/mauk.cc/webshop/cartesio-shop/electronics/user-interface +// +//#define CARTESIO_UI + +// +// LCD for Melzi Card with Graphical LCD +// +//#define LCD_FOR_MELZI + +// +// Original Ulticontroller from Ultimaker 2 printer with SSD1309 I2C display and encoder +// https://github.com/Ultimaker/Ultimaker2/tree/master/1249_Ulticontroller_Board_(x1) +// +//#define ULTI_CONTROLLER + +// +// MKS MINI12864 with graphic controller and SD support +// https://reprap.org/wiki/MKS_MINI_12864 +// +//#define MKS_MINI_12864 + +// +// MKS MINI12864 V3 is an alias for FYSETC_MINI_12864_2_1. Type A/B. NeoPixel RGB Backlight. +// +//#define MKS_MINI_12864_V3 + +// +// MKS LCD12864A/B with graphic controller and SD support. Follows MKS_MINI_12864 pinout. +// https://www.aliexpress.com/item/33018110072.html +// +//#define MKS_LCD12864A +//#define MKS_LCD12864B + +// +// FYSETC variant of the MINI12864 graphic controller with SD support +// https://wiki.fysetc.com/docs/Mini12864Panel +// +//#define FYSETC_MINI_12864_X_X // Type C/D/E/F. No tunable RGB Backlight by default +//#define FYSETC_MINI_12864_1_2 // Type C/D/E/F. Simple RGB Backlight (always on) +//#define FYSETC_MINI_12864_2_0 // Type A/B. Discreet RGB Backlight +//#define FYSETC_MINI_12864_2_1 // Type A/B. NeoPixel RGB Backlight +//#define FYSETC_GENERIC_12864_1_1 // Larger display with basic ON/OFF backlight. + +// +// BigTreeTech Mini 12864 V1.0 / V2.0 is an alias for FYSETC_MINI_12864_2_1. Type A/B. NeoPixel RGB Backlight. +// https://github.com/bigtreetech/MINI-12864 +// +//#define BTT_MINI_12864 + +// +// BEEZ MINI 12864 is an alias for FYSETC_MINI_12864_2_1. Type A/B. NeoPixel RGB Backlight. +// +//#define BEEZ_MINI_12864 + +// +// Factory display for Creality CR-10 / CR-7 / Ender-3 +// https://marlinfw.org/docs/hardware/controllers.html#cr10_stockdisplay +// +// Connect to EXP1 on RAMPS and compatible boards. +// +//#define CR10_STOCKDISPLAY + +// +// Ender-2 OEM display, a variant of the MKS_MINI_12864 +// +//#define ENDER2_STOCKDISPLAY + +// +// ANET and Tronxy 128×64 Full Graphics Controller as used on Anet A6 +// +//#define ANET_FULL_GRAPHICS_LCD + +// +// GUCOCO CTC 128×64 Full Graphics Controller as used on GUCOCO CTC A10S +// +//#define CTC_A10S_A13 + +// +// AZSMZ 12864 LCD with SD +// https://www.aliexpress.com/item/32837222770.html +// +//#define AZSMZ_12864 + +// +// Silvergate GLCD controller +// https://github.com/android444/Silvergate +// +//#define SILVER_GATE_GLCD_CONTROLLER + +// +// eMotion Tech LCD with SD +// https://www.reprap-france.com/produit/1234568748-ecran-graphique-128-x-64-points-2-1 +// +//#define EMOTION_TECH_LCD + +//============================================================================= +//============================== OLED Displays ============================== +//============================================================================= + +// +// SSD1306 OLED full graphics generic display +// +//#define U8GLIB_SSD1306 + +// +// SAV OLEd LCD module support using either SSD1306 or SH1106 based LCD modules +// +//#define SAV_3DGLCD +#if ENABLED(SAV_3DGLCD) + #define U8GLIB_SSD1306 + //#define U8GLIB_SH1106 +#endif + +// +// TinyBoy2 128x64 OLED / Encoder Panel +// +//#define OLED_PANEL_TINYBOY2 + +// +// MKS OLED 1.3" 128×64 Full Graphics Controller +// https://reprap.org/wiki/MKS_12864OLED +// +// Tiny, but very sharp OLED display +// +//#define MKS_12864OLED // Uses the SH1106 controller +//#define MKS_12864OLED_SSD1306 // Uses the SSD1306 controller + +// +// Zonestar OLED 128×64 Full Graphics Controller +// +//#define ZONESTAR_12864LCD // Graphical (DOGM) with ST7920 controller +//#define ZONESTAR_12864OLED // 1.3" OLED with SH1106 controller +//#define ZONESTAR_12864OLED_SSD1306 // 0.96" OLED with SSD1306 controller + +// +// Einstart S OLED SSD1306 +// +//#define U8GLIB_SH1106_EINSTART + +// +// Overlord OLED display/controller with i2c buzzer and LEDs +// +//#define OVERLORD_OLED + +// +// FYSETC OLED 2.42" 128×64 Full Graphics Controller with WS2812 RGB +// Where to find : https://www.aliexpress.com/item/4000345255731.html +//#define FYSETC_242_OLED_12864 // Uses the SSD1309 controller + +// +// K.3D SSD1309 OLED 2.42" 128×64 Full Graphics Controller +// +//#define K3D_242_OLED_CONTROLLER // Software SPI + +//============================================================================= +//========================== Extensible UI Displays =========================== +//============================================================================= + +/** + * DGUS Touch Display with DWIN OS. (Choose one.) + * + * ORIGIN (Marlin DWIN_SET) + * - Download https://github.com/coldtobi/Marlin_DGUS_Resources + * - Copy the downloaded DWIN_SET folder to the SD card. + * - Product: https://www.aliexpress.com/item/32993409517.html + * + * FYSETC (Supplier default) + * - Download https://github.com/FYSETC/FYSTLCD-2.0 + * - Copy the downloaded SCREEN folder to the SD card. + * - Product: https://www.aliexpress.com/item/32961471929.html + * + * HIPRECY (Supplier default) + * - Download https://github.com/HiPrecy/Touch-Lcd-LEO + * - Copy the downloaded DWIN_SET folder to the SD card. + * + * MKS (MKS-H43) (Supplier default) + * - Download https://github.com/makerbase-mks/MKS-H43 + * - Copy the downloaded DWIN_SET folder to the SD card. + * - Product: https://www.aliexpress.com/item/1005002008179262.html + * + * RELOADED (T5UID1) + * - Download https://github.com/Neo2003/DGUS-reloaded/releases + * - Copy the downloaded DWIN_SET folder to the SD card. + * + * IA_CREALITY (T5UID1) + * - Download https://github.com/InsanityAutomation/Marlin/raw/CrealityDwin_2.0/TM3D_Combined480272_Landscape_V7.7z + * - Copy the downloaded DWIN_SET folder to the SD card. + * + * E3S1PRO (T5L) + * - Download https://github.com/CrealityOfficial/Ender-3S1/archive/3S1_Plus_Screen.zip + * - Copy the downloaded DWIN_SET folder to the SD card. + * + * CREALITY_TOUCH + * - CR-6 OEM touch screen. A DWIN display with touch. + * + * Flash display with DGUS Displays for Marlin: + * - Format the SD card to FAT32 with an allocation size of 4kb. + * - Download files as specified for your type of display. + * - Plug the microSD card into the back of the display. + * - Boot the display and wait for the update to complete. + * + * :[ 'ORIGIN', 'FYSETC', 'HYPRECY', 'MKS', 'RELOADED', 'IA_CREALITY', 'E3S1PRO', 'CREALITY_TOUCH' ] + */ +//#define DGUS_LCD_UI ORIGIN +#if DGUS_UI_IS(MKS) + #define USE_MKS_GREEN_UI +#elif DGUS_UI_IS(IA_CREALITY) + //#define LCD_SCREEN_ROTATE 90 // Portrait Mode or 800x480 displays + //#define IA_CREALITY_BOOT_DELAY 1500 // (ms) +#endif + +// +// LCD for Malyan M200/M300 printers +// +//#define MALYAN_LCD + +// +// Touch UI for FTDI EVE (FT800/FT810) displays +// See Configuration_adv.h for all configuration options. +// +//#define TOUCH_UI_FTDI_EVE + +// +// Touch-screen LCD for Anycubic Chiron +// +//#define ANYCUBIC_LCD_CHIRON + +// +// Touch-screen LCD for Anycubic i3 Mega +// +//#define ANYCUBIC_LCD_I3MEGA +#if ENABLED(ANYCUBIC_LCD_I3MEGA) + //#define ANYCUBIC_LCD_GCODE_EXT // Add ".gcode" to menu entries for DGUS clone compatibility +#endif + +// +// Touch-screen LCD for Anycubic Vyper +// +//#define ANYCUBIC_LCD_VYPER + +// +// Sovol SV-06 Resistive Touch Screen +// +//#define SOVOL_SV06_RTS + +// +// 320x240 Nextion 2.8" serial TFT Resistive Touch Screen NX3224T028 +// +//#define NEXTION_TFT + +// +// PanelDue touch controller by Escher3D +// http://escher3d.com/pages/order/products/product2.php +// +//#define PANELDUE + +// +// Third-party or vendor-customized controller interfaces. +// Sources should be installed in 'src/lcd/extui'. +// +//#define EXTENSIBLE_UI + +#if ENABLED(EXTENSIBLE_UI) + //#define EXTUI_LOCAL_BEEPER // Enables use of local Beeper pin with external display +#endif + +//============================================================================= +//=============================== Graphical TFTs ============================== +//============================================================================= + +/** + * Specific TFT Model Presets. Enable one of the following options + * or enable TFT_GENERIC and set sub-options. + */ + +// +// 480x320, 3.5", SPI Display with Rotary Encoder from MKS +// Usually paired with MKS Robin Nano V2 & V3 +// https://github.com/makerbase-mks/MKS-TFT-Hardware/tree/master/MKS%20TS35 +// +//#define MKS_TS35_V2_0 + +// +// 320x240, 2.4", FSMC Display From MKS +// Usually paired with MKS Robin Nano V1.2 +// +//#define MKS_ROBIN_TFT24 + +// +// 320x240, 2.8", FSMC Display From MKS +// Usually paired with MKS Robin Nano V1.2 +// +//#define MKS_ROBIN_TFT28 + +// +// 320x240, 3.2", FSMC Display From MKS +// Usually paired with MKS Robin Nano V1.2 +// +//#define MKS_ROBIN_TFT32 + +// +// 480x320, 3.5", FSMC Display From MKS +// Usually paired with MKS Robin Nano V1.2 +// +//#define MKS_ROBIN_TFT35 + +// +// 480x272, 4.3", FSMC Display From MKS +// +//#define MKS_ROBIN_TFT43 + +// +// 320x240, 3.2", FSMC Display From MKS +// Usually paired with MKS Robin +// +//#define MKS_ROBIN_TFT_V1_1R + +// +// 480x320, 3.5", FSMC Stock Display from Tronxy +// +//#define TFT_TRONXY_X5SA + +// +// 480x320, 3.5", FSMC Stock Display from AnyCubic +// +//#define ANYCUBIC_TFT35 + +// +// 320x240, 2.8", FSMC Stock Display from Longer/Alfawise +// +//#define LONGER_LK_TFT28 + +// +// 320x240, 2.8", FSMC Stock Display from ET4 +// +//#define ANET_ET4_TFT28 + +// +// 480x320, 3.5", FSMC Stock Display from ET5 +// +//#define ANET_ET5_TFT35 + +// +// 1024x600, 7", RGB Stock Display with Rotary Encoder from BIQU BX +// https://github.com/bigtreetech/BIQU-BX/tree/master/Hardware +// +//#define BIQU_BX_TFT70 + +// +// 480x320, 3.5", SPI Stock Display with Rotary Encoder from BIQU B1 SE Series +// https://github.com/bigtreetech/TFT35-SPI/tree/master/v1 +// +//#define BTT_TFT35_SPI_V1_0 + +// +// Generic TFT with detailed options +// +//#define TFT_GENERIC +#if ENABLED(TFT_GENERIC) + // :[ 'AUTO', 'ST7735', 'ST7789', 'ST7796', 'R61505', 'ILI9328', 'ILI9341', 'ILI9488' ] + #define TFT_DRIVER AUTO + + // Interface. Enable one of the following options: + //#define TFT_INTERFACE_FSMC + //#define TFT_INTERFACE_SPI + + // TFT Resolution. Enable one of the following options: + //#define TFT_RES_320x240 + //#define TFT_RES_480x272 + //#define TFT_RES_480x320 + //#define TFT_RES_1024x600 +#endif + +/** + * TFT UI - User Interface Selection. Enable one of the following options: + * + * TFT_CLASSIC_UI - Emulated DOGM - 128x64 Upscaled + * TFT_COLOR_UI - Marlin Default Menus, Touch Friendly, using full TFT capabilities + * TFT_LVGL_UI - A Modern UI using LVGL + * + * For LVGL_UI also copy the 'assets' folder from the build directory to the + * root of your SD card, together with the compiled firmware. + */ +//#define TFT_CLASSIC_UI +//#define TFT_COLOR_UI +//#define TFT_LVGL_UI + +#if ENABLED(TFT_COLOR_UI) + /** + * TFT Font for Color UI. Choose one of the following: + * + * NOTOSANS - Default font with anti-aliasing. Supports Latin Extended and non-Latin characters. + * UNIFONT - Lightweight font, no anti-aliasing. Supports Latin Extended and non-Latin characters. + * HELVETICA - Lightweight font, no anti-aliasing. Supports Basic Latin (0x0020-0x007F) and Latin-1 Supplement (0x0080-0x00FF) characters only. + * :['NOTOSANS', 'UNIFONT', 'HELVETICA'] + */ + #define TFT_FONT NOTOSANS + + /** + * TFT Theme for Color UI. Choose one of the following or add a new one to 'Marlin/src/lcd/tft/themes' directory + * + * BLUE_MARLIN - Default theme with 'midnight blue' background + * BLACK_MARLIN - Theme with 'black' background + * ANET_BLACK - Theme used for Anet ET4/5 + * :['BLUE_MARLIN', 'BLACK_MARLIN', 'ANET_BLACK'] + */ + #define TFT_THEME BLACK_MARLIN + + //#define TFT_SHARED_IO // I/O is shared between TFT display and other devices. Disable async data transfer. + + #define COMPACT_MARLIN_BOOT_LOGO // Use compressed data to save Flash space +#endif + +#if ENABLED(TFT_LVGL_UI) + //#define MKS_WIFI_MODULE // MKS WiFi module +#endif + +/** + * TFT Rotation. Set to one of the following values: + * + * TFT_ROTATE_90, TFT_ROTATE_90_MIRROR_X, TFT_ROTATE_90_MIRROR_Y, + * TFT_ROTATE_180, TFT_ROTATE_180_MIRROR_X, TFT_ROTATE_180_MIRROR_Y, + * TFT_ROTATE_270, TFT_ROTATE_270_MIRROR_X, TFT_ROTATE_270_MIRROR_Y, + * TFT_MIRROR_X, TFT_MIRROR_Y, TFT_NO_ROTATION + * + * :{ 'TFT_NO_ROTATION':'None', 'TFT_ROTATE_90':'90°', 'TFT_ROTATE_90_MIRROR_X':'90° (Mirror X)', 'TFT_ROTATE_90_MIRROR_Y':'90° (Mirror Y)', 'TFT_ROTATE_180':'180°', 'TFT_ROTATE_180_MIRROR_X':'180° (Mirror X)', 'TFT_ROTATE_180_MIRROR_Y':'180° (Mirror Y)', 'TFT_ROTATE_270':'270°', 'TFT_ROTATE_270_MIRROR_X':'270° (Mirror X)', 'TFT_ROTATE_270_MIRROR_Y':'270° (Mirror Y)', 'TFT_MIRROR_X':'Mirror X', 'TFT_MIRROR_Y':'Mirror Y' } + */ +//#define TFT_ROTATION TFT_NO_ROTATION + +//============================================================================= +//============================ Other Controllers ============================ +//============================================================================= + +// +// Ender-3 v2 OEM display. A DWIN display with Rotary Encoder. +// +//#define DWIN_CREALITY_LCD // Creality UI +//#define DWIN_LCD_PROUI // Pro UI by MRiscoC +//#define DWIN_CREALITY_LCD_JYERSUI // Jyers UI by Jacob Myers +//#define DWIN_MARLINUI_PORTRAIT // MarlinUI (portrait orientation) +//#define DWIN_MARLINUI_LANDSCAPE // MarlinUI (landscape orientation) + +#if ENABLED(DWIN_CREALITY_LCD) + //#define USE_STRING_HEADINGS // Use string headings for Creality UI instead of images + //#define USE_STRING_TITLES // Use string titles for Creality UI instead of images +#endif + +// +// Touch Screen Settings +// +//#define TOUCH_SCREEN +#if ENABLED(TOUCH_SCREEN) + #define BUTTON_DELAY_EDIT 50 // (ms) Button repeat delay for edit screens + #define BUTTON_DELAY_MENU 250 // (ms) Button repeat delay for menus + + #if ANY(TFT_CLASSIC_UI, TFT_COLOR_UI) + //#define NO_BACK_MENU_ITEM // Don't display a top menu item to go back to the parent menu + #endif + + #define TOUCH_SCREEN_CALIBRATION + + //#define TOUCH_CALIBRATION_X 12316 + //#define TOUCH_CALIBRATION_Y -8981 + //#define TOUCH_OFFSET_X -43 + //#define TOUCH_OFFSET_Y 257 + //#define TOUCH_ORIENTATION TOUCH_LANDSCAPE + + #if ALL(TOUCH_SCREEN_CALIBRATION, EEPROM_SETTINGS) + #define TOUCH_CALIBRATION_AUTO_SAVE // Auto save successful calibration values to EEPROM + #endif + + #if ENABLED(TFT_COLOR_UI) + //#define SINGLE_TOUCH_NAVIGATION + #endif +#endif + +// +// RepRapWorld REPRAPWORLD_KEYPAD v1.1 +// https://reprapworld.com/products/electronics/ramps/keypad_v1_0_fully_assembled/ +// +//#define REPRAPWORLD_KEYPAD +#if ENABLED(REPRAPWORLD_KEYPAD) + //#define REPRAPWORLD_KEYPAD_MOVE_STEP 10.0 // (mm) Distance to move per key-press +#endif + +// +// EasyThreeD ET-4000+ with button input and status LED +// +//#define EASYTHREED_UI + +//============================================================================= +//=============================== Extra Features ============================== +//============================================================================= + +// @section fans + +// Set number of user-controlled fans. Disable to use all board-defined fans. +// :[1,2,3,4,5,6,7,8] +//#define NUM_M106_FANS 1 + +/** + * Use software PWM to drive the fan, as for the heaters. This uses a very low frequency + * which is not as annoying as with the hardware PWM. On the other hand, if this frequency + * is too low, you should also increment SOFT_PWM_SCALE. + */ +#define FAN_SOFT_PWM + +/** + * Incrementing this by 1 will double the software PWM frequency, affecting heaters, and + * the fan if FAN_SOFT_PWM is enabled. However, control resolution will be halved for each + * increment; at zero value, there are 128 effective control positions. + * :[0,1,2,3,4,5,6,7] + */ +#define SOFT_PWM_SCALE 0 + +/** + * If SOFT_PWM_SCALE is set to a value higher than 0, dithering can be used to mitigate the + * associated resolution loss. If enabled, some of the PWM cycles are stretched so on average + * the desired duty cycle is attained. + */ +//#define SOFT_PWM_DITHER + +// @section extras + +// Support for the BariCUDA Paste Extruder +//#define BARICUDA + +// @section lights + +/** + * Temperature status LEDs that display the hotend and bed temperature. + * If all hotends, bed temperature, and target temperature are under 54C + * the BLUE led is on. Otherwise the RED led is on. (1C hysteresis) + */ +//#define TEMP_STAT_LEDS + +// Support for BlinkM/CyzRgb +//#define BLINKM + +// Support for PCA9632 PWM LED driver +//#define PCA9632 + +// Support for PCA9533 PWM LED driver +//#define PCA9533 + +/** + * RGB LED / LED Strip Control + * + * Enable support for an RGB LED connected to 5V digital pins, or + * an RGB Strip connected to MOSFETs controlled by digital pins. + * + * Adds the M150 command to set the LED (or LED strip) color. + * If pins are PWM capable (e.g., 4, 5, 6, 11) then a range of + * luminance values can be set from 0 to 255. + * For NeoPixel LED an overall brightness parameter is also available. + * + * === CAUTION === + * LED Strips require a MOSFET Chip between PWM lines and LEDs, + * as the Arduino cannot handle the current the LEDs will require. + * Failure to follow this precaution can destroy your Arduino! + * + * NOTE: A separate 5V power supply is required! The NeoPixel LED needs + * more current than the Arduino 5V linear regulator can produce. + * + * Requires PWM frequency between 50 <> 100Hz (Check HAL or variant) + * Use FAST_PWM_FAN, if possible, to reduce fan noise. + */ + +// LED Type. Enable only one of the following two options: +//#define RGB_LED +//#define RGBW_LED + +#if ANY(RGB_LED, RGBW_LED) + //#define RGB_LED_R_PIN 34 + //#define RGB_LED_G_PIN 43 + //#define RGB_LED_B_PIN 35 + //#define RGB_LED_W_PIN -1 +#endif + +#if ANY(RGB_LED, RGBW_LED, PCA9632) + //#define RGB_STARTUP_TEST // For PWM pins, fade between all colors + #if ENABLED(RGB_STARTUP_TEST) + #define RGB_STARTUP_TEST_INNER_MS 10 // (ms) Reduce or increase fading speed + #endif +#endif + +// Support for Adafruit NeoPixel LED driver +//#define NEOPIXEL_LED +#if ENABLED(NEOPIXEL_LED) + #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW, NEO_RGBW, NEO_GRB, NEO_RBG, etc. + // See https://github.com/adafruit/Adafruit_NeoPixel/blob/master/Adafruit_NeoPixel.h + //#define NEOPIXEL_PIN 4 // LED driving pin + //#define NEOPIXEL2_TYPE NEOPIXEL_TYPE + //#define NEOPIXEL2_PIN 5 + #define NEOPIXEL_PIXELS 30 // Number of LEDs in the strip. (Longest strip when NEOPIXEL2_SEPARATE is disabled.) + #define NEOPIXEL_IS_SEQUENTIAL // Sequential display for temperature change - LED by LED. Disable to change all LEDs at once. + #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness (0-255) + //#define NEOPIXEL_STARTUP_TEST // Cycle through colors at startup + + // Support for second Adafruit NeoPixel LED driver controlled with M150 S1 ... + //#define NEOPIXEL2_SEPARATE + #if ENABLED(NEOPIXEL2_SEPARATE) + #define NEOPIXEL2_PIXELS 15 // Number of LEDs in the second strip + #define NEOPIXEL2_BRIGHTNESS 127 // Initial brightness (0-255) + #define NEOPIXEL2_STARTUP_TEST // Cycle through colors at startup + #define NEOPIXEL_M150_DEFAULT -1 // Default strip for M150 without 'S'. Use -1 to set all by default. + #else + //#define NEOPIXEL2_INSERIES // Default behavior is NeoPixel 2 in parallel + #endif + + // Use some of the NeoPixel LEDs for static (background) lighting + //#define NEOPIXEL_BKGD_INDEX_FIRST 0 // Index of the first background LED + //#define NEOPIXEL_BKGD_INDEX_LAST 5 // Index of the last background LED + //#define NEOPIXEL_BKGD_COLOR { 255, 255, 255, 0 } // R, G, B, W + //#define NEOPIXEL_BKGD_TIMEOUT_COLOR { 25, 25, 25, 0 } // R, G, B, W + //#define NEOPIXEL_BKGD_ALWAYS_ON // Keep the backlight on when other NeoPixels are off +#endif + +/** + * Printer Event LEDs + * + * During printing, the LEDs will reflect the printer status: + * + * - Gradually change from blue to violet as the heated bed gets to target temp + * - Gradually change from violet to red as the hotend gets to temperature + * - Change to white to illuminate work surface + * - Change to green once print has finished + * - Turn off after the print has finished and the user has pushed a button + */ +#if ANY(BLINKM, RGB_LED, RGBW_LED, PCA9632, PCA9533, NEOPIXEL_LED) + #define PRINTER_EVENT_LEDS +#endif + +// @section servos + +/** + * Number of servos + * + * For some servo-related options NUM_SERVOS will be set automatically. + * Set this manually if there are extra servos needing manual control. + * Set to 0 to turn off servo support. + */ +//#define NUM_SERVOS 3 // Note: Servo index starts with 0 for M280-M282 commands + +// (ms) Delay before the next move will start, to give the servo time to reach its target angle. +// 300ms is a good value but you can try less delay. +// If the servo can't reach the requested position, increase it. +#define SERVO_DELAY { 300 } + +// Only power servos during movement, otherwise leave off to prevent jitter +//#define DEACTIVATE_SERVOS_AFTER_MOVE + +// Edit servo angles with M281 and save to EEPROM with M500 +//#define EDITABLE_SERVO_ANGLES + +// Disable servo with M282 to reduce power consumption, noise, and heat when not in use +//#define SERVO_DETACH_GCODE diff --git a/config/examples/delta/Micromake-D1/MKS-Gen-L-V2.1/Configuration_adv.h b/config/examples/delta/Micromake-D1/MKS-Gen-L-V2.1/Configuration_adv.h new file mode 100644 index 0000000000..3c113bef1a --- /dev/null +++ b/config/examples/delta/Micromake-D1/MKS-Gen-L-V2.1/Configuration_adv.h @@ -0,0 +1,4753 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2025 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/** + * Configuration_adv.h + * + * Advanced settings. + * Only change these if you know exactly what you're doing. + * Some of these settings can damage your printer if improperly set! + * + * Basic settings can be found in Configuration.h + */ +#define CONFIGURATION_ADV_H_VERSION 02010300 + +// @section develop + +/** + * Configuration Export + * + * Export the configuration as part of the build. (See signature.py) + * Output files are saved with the build (e.g., .pio/build/mega2560). + * + * See `build_all_examples --ini` as an example of config.ini archiving. + * + * 1 = marlin_config.json - Dictionary containing the configuration. + * This file is also generated for CONFIGURATION_EMBEDDING. + * 2 = config.ini - File format for PlatformIO preprocessing. + * 3 = schema.json - The entire configuration schema. (13 = pattern groups) + * 4 = schema.yml - The entire configuration schema. + * 5 = Config.h - Minimal configuration by popular demand. + */ +//#define CONFIG_EXPORT 105 // :[1:'JSON', 2:'config.ini', 3:'schema.json', 4:'schema.yml', 5:'Config.h'] + +//=========================================================================== +//============================= Thermal Settings ============================ +//=========================================================================== +// @section temperature + +/** + * Thermocouple sensors are quite sensitive to noise. Any noise induced in + * the sensor wires, such as by stepper motor wires run in parallel to them, + * may result in the thermocouple sensor reporting spurious errors. This + * value is the number of errors which can occur in a row before the error + * is reported. This allows us to ignore intermittent error conditions while + * still detecting an actual failure, which should result in a continuous + * stream of errors from the sensor. + * + * Set this value to 0 to fail on the first error to occur. + */ +#define THERMOCOUPLE_MAX_ERRORS 15 + +// +// Custom Thermistor 1000 parameters +// +#if TEMP_SENSOR_0 == 1000 + #define HOTEND0_PULLUP_RESISTOR_OHMS 4700 // Pullup resistor + #define HOTEND0_RESISTANCE_25C_OHMS 100000 // Resistance at 25C + #define HOTEND0_BETA 3950 // Beta value + #define HOTEND0_SH_C_COEFF 0 // Steinhart-Hart C coefficient +#endif + +#if TEMP_SENSOR_1 == 1000 + #define HOTEND1_PULLUP_RESISTOR_OHMS 4700 // Pullup resistor + #define HOTEND1_RESISTANCE_25C_OHMS 100000 // Resistance at 25C + #define HOTEND1_BETA 3950 // Beta value + #define HOTEND1_SH_C_COEFF 0 // Steinhart-Hart C coefficient +#endif + +#if TEMP_SENSOR_2 == 1000 + #define HOTEND2_PULLUP_RESISTOR_OHMS 4700 // Pullup resistor + #define HOTEND2_RESISTANCE_25C_OHMS 100000 // Resistance at 25C + #define HOTEND2_BETA 3950 // Beta value + #define HOTEND2_SH_C_COEFF 0 // Steinhart-Hart C coefficient +#endif + +#if TEMP_SENSOR_3 == 1000 + #define HOTEND3_PULLUP_RESISTOR_OHMS 4700 // Pullup resistor + #define HOTEND3_RESISTANCE_25C_OHMS 100000 // Resistance at 25C + #define HOTEND3_BETA 3950 // Beta value + #define HOTEND3_SH_C_COEFF 0 // Steinhart-Hart C coefficient +#endif + +#if TEMP_SENSOR_4 == 1000 + #define HOTEND4_PULLUP_RESISTOR_OHMS 4700 // Pullup resistor + #define HOTEND4_RESISTANCE_25C_OHMS 100000 // Resistance at 25C + #define HOTEND4_BETA 3950 // Beta value + #define HOTEND4_SH_C_COEFF 0 // Steinhart-Hart C coefficient +#endif + +#if TEMP_SENSOR_5 == 1000 + #define HOTEND5_PULLUP_RESISTOR_OHMS 4700 // Pullup resistor + #define HOTEND5_RESISTANCE_25C_OHMS 100000 // Resistance at 25C + #define HOTEND5_BETA 3950 // Beta value + #define HOTEND5_SH_C_COEFF 0 // Steinhart-Hart C coefficient +#endif + +#if TEMP_SENSOR_6 == 1000 + #define HOTEND6_PULLUP_RESISTOR_OHMS 4700 // Pullup resistor + #define HOTEND6_RESISTANCE_25C_OHMS 100000 // Resistance at 25C + #define HOTEND6_BETA 3950 // Beta value + #define HOTEND6_SH_C_COEFF 0 // Steinhart-Hart C coefficient +#endif + +#if TEMP_SENSOR_7 == 1000 + #define HOTEND7_PULLUP_RESISTOR_OHMS 4700 // Pullup resistor + #define HOTEND7_RESISTANCE_25C_OHMS 100000 // Resistance at 25C + #define HOTEND7_BETA 3950 // Beta value + #define HOTEND7_SH_C_COEFF 0 // Steinhart-Hart C coefficient +#endif + +#if TEMP_SENSOR_BED == 1000 + #define BED_PULLUP_RESISTOR_OHMS 4700 // Pullup resistor + #define BED_RESISTANCE_25C_OHMS 100000 // Resistance at 25C + #define BED_BETA 3950 // Beta value + #define BED_SH_C_COEFF 0 // Steinhart-Hart C coefficient +#endif + +#if TEMP_SENSOR_CHAMBER == 1000 + #define CHAMBER_PULLUP_RESISTOR_OHMS 4700 // Pullup resistor + #define CHAMBER_RESISTANCE_25C_OHMS 100000 // Resistance at 25C + #define CHAMBER_BETA 3950 // Beta value + #define CHAMBER_SH_C_COEFF 0 // Steinhart-Hart C coefficient +#endif + +#if TEMP_SENSOR_COOLER == 1000 + #define COOLER_PULLUP_RESISTOR_OHMS 4700 // Pullup resistor + #define COOLER_RESISTANCE_25C_OHMS 100000 // Resistance at 25C + #define COOLER_BETA 3950 // Beta value + #define COOLER_SH_C_COEFF 0 // Steinhart-Hart C coefficient +#endif + +#if TEMP_SENSOR_PROBE == 1000 + #define PROBE_PULLUP_RESISTOR_OHMS 4700 // Pullup resistor + #define PROBE_RESISTANCE_25C_OHMS 100000 // Resistance at 25C + #define PROBE_BETA 3950 // Beta value + #define PROBE_SH_C_COEFF 0 // Steinhart-Hart C coefficient +#endif + +#if TEMP_SENSOR_BOARD == 1000 + #define BOARD_PULLUP_RESISTOR_OHMS 4700 // Pullup resistor + #define BOARD_RESISTANCE_25C_OHMS 100000 // Resistance at 25C + #define BOARD_BETA 3950 // Beta value + #define BOARD_SH_C_COEFF 0 // Steinhart-Hart C coefficient +#endif + +#if TEMP_SENSOR_REDUNDANT == 1000 + #define REDUNDANT_PULLUP_RESISTOR_OHMS 4700 // Pullup resistor + #define REDUNDANT_RESISTANCE_25C_OHMS 100000 // Resistance at 25C + #define REDUNDANT_BETA 3950 // Beta value + #define REDUNDANT_SH_C_COEFF 0 // Steinhart-Hart C coefficient +#endif + +/** + * Thermocouple Options — for MAX6675 (-2), MAX31855 (-3), and MAX31865 (-5). + */ +//#define TEMP_SENSOR_FORCE_HW_SPI // Ignore SCK/MOSI/MISO pins; use CS and the default SPI bus. +//#define MAX31865_SENSOR_WIRES_0 2 // (2-4) Number of wires for the probe connected to a MAX31865 board. +//#define MAX31865_SENSOR_WIRES_1 2 +//#define MAX31865_SENSOR_WIRES_2 2 +//#define MAX31865_SENSOR_WIRES_BED 2 + +//#define MAX31865_50HZ_FILTER // Use a 50Hz filter instead of the default 60Hz. +//#define MAX31865_USE_READ_ERROR_DETECTION // Treat value spikes (20°C delta in under 1s) as read errors. + +//#define MAX31865_USE_AUTO_MODE // Read faster and more often than 1-shot; bias voltage always on; slight effect on RTD temperature. +//#define MAX31865_MIN_SAMPLING_TIME_MSEC 100 // (ms) 1-shot: minimum read interval. Reduces bias voltage effects by leaving sensor unpowered for longer intervals. +//#define MAX31865_IGNORE_INITIAL_FAULTY_READS 10 // Ignore some read faults (keeping the temperature reading) to work around a possible issue (#23439). + +//#define MAX31865_WIRE_OHMS_0 0.95f // For 2-wire, set the wire resistances for more accurate readings. +//#define MAX31865_WIRE_OHMS_1 0.0f +//#define MAX31865_WIRE_OHMS_2 0.0f +//#define MAX31865_WIRE_OHMS_BED 0.0f + +/** + * Hephestos 2 24V heated bed upgrade kit. + * https://www.en3dstudios.com/product/bq-hephestos-2-heated-bed-kit/ + */ +//#define HEPHESTOS2_HEATED_BED_KIT +#if ENABLED(HEPHESTOS2_HEATED_BED_KIT) + #define HEATER_BED_INVERTING true +#endif + +// +// Heated Bed Bang-Bang options +// +#if DISABLED(PIDTEMPBED) + #define BED_CHECK_INTERVAL 5000 // (ms) Interval between checks in bang-bang control + #if ANY(BED_LIMIT_SWITCHING, PELTIER_BED) + #define BED_HYSTERESIS 2 // (°C) Only set the relevant heater state when ABS(T-target) > BED_HYSTERESIS + #endif +#endif + +// +// Heated Chamber options +// + +#if TEMP_SENSOR_CHAMBER + //#define HEATER_CHAMBER_PIN P2_04 // Required heater on/off pin (example: SKR 1.4 Turbo HE1 plug) + //#define HEATER_CHAMBER_INVERTING false + //#define FAN1_PIN -1 // Remove the fan signal on pin P2_04 (example: SKR 1.4 Turbo HE1 plug) + + #if DISABLED(PIDTEMPCHAMBER) + #define CHAMBER_CHECK_INTERVAL 5000 // (ms) Interval between checks in bang-bang control + #if ENABLED(CHAMBER_LIMIT_SWITCHING) + #define CHAMBER_HYSTERESIS 2 // (°C) Only set the relevant heater state when ABS(T-target) > CHAMBER_HYSTERESIS + #endif + #endif + + //#define CHAMBER_FAN // Enable a fan on the chamber + #if ENABLED(CHAMBER_FAN) + //#define CHAMBER_FAN_INDEX 2 // Index of a fan to repurpose as the chamber fan. (Default: first unused fan) + #define CHAMBER_FAN_MODE 2 // Fan control mode: 0=Static; 1=Linear increase when temp is higher than target; 2=V-shaped curve; 3=similar to 1 but fan is always on. + #if CHAMBER_FAN_MODE == 0 + #define CHAMBER_FAN_BASE 255 // Chamber fan PWM (0-255) + #elif CHAMBER_FAN_MODE == 1 + #define CHAMBER_FAN_BASE 128 // Base chamber fan PWM (0-255); turns on when chamber temperature is above the target + #define CHAMBER_FAN_FACTOR 25 // PWM increase per °C above target + #elif CHAMBER_FAN_MODE == 2 + #define CHAMBER_FAN_BASE 128 // Minimum chamber fan PWM (0-255) + #define CHAMBER_FAN_FACTOR 25 // PWM increase per °C difference from target + #elif CHAMBER_FAN_MODE == 3 + #define CHAMBER_FAN_BASE 128 // Base chamber fan PWM (0-255) + #define CHAMBER_FAN_FACTOR 25 // PWM increase per °C above target + #endif + #endif + + //#define CHAMBER_VENT // Enable a servo-controlled vent on the chamber + #if ENABLED(CHAMBER_VENT) + #define CHAMBER_VENT_SERVO_NR 1 // Index of the vent servo + #define HIGH_EXCESS_HEAT_LIMIT 5 // How much above target temp to consider there is excess heat in the chamber + #define LOW_EXCESS_HEAT_LIMIT 3 + #define MIN_COOLING_SLOPE_TIME_CHAMBER_VENT 20 + #define MIN_COOLING_SLOPE_DEG_CHAMBER_VENT 1.5 + #endif +#endif + +// +// Laser Cooler options +// +#if TEMP_SENSOR_COOLER + #define COOLER_MINTEMP 8 // (°C) + #define COOLER_MAXTEMP 26 // (°C) + #define COOLER_DEFAULT_TEMP 16 // (°C) + #define TEMP_COOLER_HYSTERESIS 1 // (°C) Temperature proximity considered "close enough" to the target + #define COOLER_PIN 8 // Laser cooler on/off pin used to control power to the cooling element (e.g., TEC, External chiller via relay) + #define COOLER_INVERTING false + #define TEMP_COOLER_PIN 15 // Laser/Cooler temperature sensor pin. ADC is required. + #define COOLER_FAN // Enable a fan on the cooler, Fan# 0,1,2,3 etc. + #define COOLER_FAN_INDEX 0 // FAN number 0, 1, 2 etc. e.g. + #if ENABLED(COOLER_FAN) + #define COOLER_FAN_BASE 100 // Base Cooler fan PWM (0-255); turns on when Cooler temperature is above the target + #define COOLER_FAN_FACTOR 25 // PWM increase per °C above target + #endif +#endif + +// +// Motherboard Sensor options +// +#if TEMP_SENSOR_BOARD + #define THERMAL_PROTECTION_BOARD // Halt the printer if the board sensor leaves the temp range below. + #define BOARD_MINTEMP 8 // (°C) + #define BOARD_MAXTEMP 70 // (°C) + //#define TEMP_BOARD_PIN -1 // Board temp sensor pin override. +#endif + +// +// SoC Sensor options +// +#if TEMP_SENSOR_SOC + #define THERMAL_PROTECTION_SOC // Halt the printer if the SoC sensor leaves the temp range below. + #define SOC_MAXTEMP 85 // (°C) +#endif + +/** + * Thermal Protection provides additional protection to your printer from damage + * and fire. Marlin always includes safe min and max temperature ranges which + * protect against a broken or disconnected thermistor wire. + * + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. + * + * The solution: Once the temperature reaches the target, start observing. + * If the temperature stays too far below the target (hysteresis) for too + * long (period), the firmware will halt the machine as a safety precaution. + * + * If you get false positives for "Thermal Runaway", increase + * THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD + */ +#if ALL(HAS_HOTEND, THERMAL_PROTECTION_HOTENDS) + #define THERMAL_PROTECTION_PERIOD 40 // (seconds) + #define THERMAL_PROTECTION_HYSTERESIS 4 // (°C) + + //#define ADAPTIVE_FAN_SLOWING // Slow down the part-cooling fan if the temperature drops + #if ENABLED(ADAPTIVE_FAN_SLOWING) + //#define REPORT_ADAPTIVE_FAN_SLOWING // Report fan slowing activity to the console + #if ANY(MPCTEMP, PIDTEMP) + //#define TEMP_TUNING_MAINTAIN_FAN // Don't slow down the fan speed during M303 or M306 T + #endif + #endif + + /** + * Whenever an M104, M109, or M303 increases the target temperature, the + * firmware will wait for the WATCH_TEMP_PERIOD to expire. If the temperature + * hasn't increased by WATCH_TEMP_INCREASE degrees, the machine is halted and + * requires a hard reset. This test restarts with any M104/M109/M303, but only + * if the current temperature is far enough below the target for a reliable + * test. + * + * If you get false positives for "Heating failed", increase WATCH_TEMP_PERIOD + * and/or decrease WATCH_TEMP_INCREASE. WATCH_TEMP_INCREASE should not be set + * below 2. + */ + #define WATCH_TEMP_PERIOD 40 // (seconds) + #define WATCH_TEMP_INCREASE 2 // (°C) +#endif + +/** + * Thermal Protection parameters for the bed are just as above for hotends. + */ +#if TEMP_SENSOR_BED && ENABLED(THERMAL_PROTECTION_BED) + #define THERMAL_PROTECTION_BED_PERIOD 20 // (seconds) + #define THERMAL_PROTECTION_BED_HYSTERESIS 2 // (°C) + + /** + * As described above, except for the bed (M140/M190/M303). + */ + #define WATCH_BED_TEMP_PERIOD 60 // (seconds) + #define WATCH_BED_TEMP_INCREASE 2 // (°C) +#endif + +/** + * Thermal Protection parameters for the heated chamber. + */ +#if TEMP_SENSOR_CHAMBER && ENABLED(THERMAL_PROTECTION_CHAMBER) + #define THERMAL_PROTECTION_CHAMBER_PERIOD 20 // (seconds) + #define THERMAL_PROTECTION_CHAMBER_HYSTERESIS 2 // (°C) + + /** + * Heated chamber watch settings (M141/M191). + */ + #define WATCH_CHAMBER_TEMP_PERIOD 60 // (seconds) + #define WATCH_CHAMBER_TEMP_INCREASE 2 // (°C) +#endif + +/** + * Thermal Protection parameters for the laser cooler. + */ +#if TEMP_SENSOR_COOLER && ENABLED(THERMAL_PROTECTION_COOLER) + #define THERMAL_PROTECTION_COOLER_PERIOD 10 // (seconds) + #define THERMAL_PROTECTION_COOLER_HYSTERESIS 3 // (°C) + + /** + * Laser cooling watch settings (M143/M193). + */ + #define WATCH_COOLER_TEMP_PERIOD 60 // (seconds) + #define WATCH_COOLER_TEMP_INCREASE 3 // (°C) +#endif + +#if ANY(THERMAL_PROTECTION_HOTENDS, THERMAL_PROTECTION_BED, THERMAL_PROTECTION_CHAMBER, THERMAL_PROTECTION_COOLER) + /** + * Thermal Protection Variance Monitor - EXPERIMENTAL + * Kill the machine on a stuck temperature sensor. + * + * This feature may cause some thermally-stable systems to halt. Be sure to test it thoroughly under + * a variety of conditions. Disable if you get false positives. + * + * This feature ensures that temperature sensors are updating regularly. If sensors die or get "stuck", + * or if Marlin stops reading them, temperatures will remain constant while heaters may still be powered! + * This feature only monitors temperature changes so it should catch any issue, hardware or software. + * + * By default it uses the THERMAL_PROTECTION_*_PERIOD constants (above) for the time window, within which + * at least one temperature change must occur, to indicate that sensor polling is working. If any monitored + * heater's temperature remains totally constant (without even a fractional change) during this period, a + * thermal malfunction error occurs and the printer is halted. + * + * A very stable heater might produce a false positive and halt the printer. In this case, try increasing + * the corresponding THERMAL_PROTECTION_*_PERIOD constant a bit. Keep in mind that uncontrolled heating + * shouldn't be allowed to persist for more than a minute or two. + * + * Be careful to distinguish false positives from real sensor issues before disabling this feature. If the + * heater's temperature appears even slightly higher than expected after restarting, you may have a real + * thermal malfunction. Check the temperature graph in your host for any unusual bumps. + */ + //#define THERMAL_PROTECTION_VARIANCE_MONITOR + #if ENABLED(THERMAL_PROTECTION_VARIANCE_MONITOR) + // Variance detection window to override the THERMAL_PROTECTION...PERIOD settings above. + // Keep in mind that some heaters heat up faster than others. + //#define THERMAL_PROTECTION_VARIANCE_MONITOR_PERIOD 30 // (s) Override all watch periods + #endif +#endif + +#if ENABLED(PIDTEMP) + // Add an additional term to the heater power, proportional to the extrusion speed. + // A well-chosen Kc value should add just enough power to melt the increased material volume. + //#define PID_EXTRUSION_SCALING + #if ENABLED(PID_EXTRUSION_SCALING) + #define DEFAULT_Kc (100) // heating power = Kc * e_speed + #define LPQ_MAX_LEN 50 + #endif + + /** + * Add an additional term to the heater power, proportional to the fan speed. + * A well-chosen Kf value should add just enough power to compensate for power-loss from the cooling fan. + * You can either just add a constant compensation with the DEFAULT_Kf value + * or follow the instruction below to get speed-dependent compensation. + * + * Constant compensation (use only with fan speeds of 0% and 100%) + * --------------------------------------------------------------------- + * A good starting point for the Kf-value comes from the calculation: + * kf = (power_fan * eff_fan) / power_heater * 255 + * where eff_fan is between 0.0 and 1.0, based on fan-efficiency and airflow to the nozzle / heater. + * + * Example: + * Heater: 40W, Fan: 0.1A * 24V = 2.4W, eff_fan = 0.8 + * Kf = (2.4W * 0.8) / 40W * 255 = 12.24 + * + * Fan-speed dependent compensation + * -------------------------------- + * 1. To find a good Kf value, set the hotend temperature, wait for it to settle, and enable the fan (100%). + * Make sure PID_FAN_SCALING_LIN_FACTOR is 0 and PID_FAN_SCALING_ALTERNATIVE_DEFINITION is not enabled. + * If you see the temperature drop repeat the test, increasing the Kf value slowly, until the temperature + * drop goes away. If the temperature overshoots after enabling the fan, the Kf value is too big. + * 2. Note the Kf-value for fan-speed at 100% + * 3. Determine a good value for PID_FAN_SCALING_MIN_SPEED, which is around the speed, where the fan starts moving. + * 4. Repeat step 1. and 2. for this fan speed. + * 5. Enable PID_FAN_SCALING_ALTERNATIVE_DEFINITION and enter the two identified Kf-values in + * PID_FAN_SCALING_AT_FULL_SPEED and PID_FAN_SCALING_AT_MIN_SPEED. Enter the minimum speed in PID_FAN_SCALING_MIN_SPEED + */ + //#define PID_FAN_SCALING + #if ENABLED(PID_FAN_SCALING) + //#define PID_FAN_SCALING_ALTERNATIVE_DEFINITION + #if ENABLED(PID_FAN_SCALING_ALTERNATIVE_DEFINITION) + // The alternative definition is used for an easier configuration. + // Just figure out Kf at full speed (255) and PID_FAN_SCALING_MIN_SPEED. + // DEFAULT_Kf and PID_FAN_SCALING_LIN_FACTOR are calculated accordingly. + + #define PID_FAN_SCALING_AT_FULL_SPEED 13.0 //=PID_FAN_SCALING_LIN_FACTOR*255+DEFAULT_Kf + #define PID_FAN_SCALING_AT_MIN_SPEED 6.0 //=PID_FAN_SCALING_LIN_FACTOR*PID_FAN_SCALING_MIN_SPEED+DEFAULT_Kf + #define PID_FAN_SCALING_MIN_SPEED 10.0 // Minimum fan speed at which to enable PID_FAN_SCALING + + #define DEFAULT_Kf (255.0*PID_FAN_SCALING_AT_MIN_SPEED-PID_FAN_SCALING_AT_FULL_SPEED*PID_FAN_SCALING_MIN_SPEED)/(255.0-PID_FAN_SCALING_MIN_SPEED) + #define PID_FAN_SCALING_LIN_FACTOR (PID_FAN_SCALING_AT_FULL_SPEED-DEFAULT_Kf)/255.0 + + #else + #define PID_FAN_SCALING_LIN_FACTOR (0) // Power-loss due to cooling = Kf * (fan_speed) + #define DEFAULT_Kf 10 // A constant value added to the PID-tuner + #define PID_FAN_SCALING_MIN_SPEED 10 // Minimum fan speed at which to enable PID_FAN_SCALING + #endif + #endif +#endif + +/** + * Automatic Temperature Mode + * + * Dynamically adjust the hotend target temperature based on planned E moves. + * + * (Contrast with PID_EXTRUSION_SCALING, which tracks E movement and adjusts PID + * behavior using an additional kC value.) + * + * Autotemp is calculated by (mintemp + factor * mm_per_sec), capped to maxtemp. + * + * Enable Autotemp Mode with M104/M109 F S B. + * Disable by sending M104/M109 with no F parameter (or F0 with AUTOTEMP_PROPORTIONAL). + */ +#define AUTOTEMP +#if ENABLED(AUTOTEMP) + #define AUTOTEMP_OLDWEIGHT 0.98 // Factor used to weight previous readings (0.0 < value < 1.0) + #define AUTOTEMP_MIN 210 + #define AUTOTEMP_MAX 250 + #define AUTOTEMP_FACTOR 0.1f + // Turn on AUTOTEMP on M104/M109 by default using proportions set here + //#define AUTOTEMP_PROPORTIONAL + #if ENABLED(AUTOTEMP_PROPORTIONAL) + #define AUTOTEMP_MIN_P 0 // (°C) Added to the target temperature + #define AUTOTEMP_MAX_P 5 // (°C) Added to the target temperature + #define AUTOTEMP_FACTOR_P 1 // Apply this F parameter by default (overridden by M104/M109 F) + #endif +#endif + +// Show Temperature ADC value +// Enable for M105 to include ADC values read from temperature sensors. +//#define SHOW_TEMP_ADC_VALUES + +/** + * High Temperature Thermistor Support + * + * Thermistors able to support high temperature tend to have a hard time getting + * good readings at room and lower temperatures. This means TEMP_SENSOR_X_RAW_LO_TEMP + * will probably be caught when the heating element first turns on during the + * preheating process, which will trigger a MINTEMP error as a safety measure + * and force stop everything. + * To circumvent this limitation, we allow for a preheat time (during which, + * MINTEMP error won't be triggered) and add a min_temp buffer to handle + * aberrant readings. + * + * If you want to enable this feature for your hotend thermistor(s) + * uncomment and set values > 0 in the constants below + */ + +// The number of consecutive low temperature errors that can occur +// before a MINTEMP error is triggered. (Shouldn't be more than 10.) +//#define MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED 0 + +/** + * The number of milliseconds a hotend will preheat before starting to check + * the temperature. This value should NOT be set to the time it takes the + * hot end to reach the target temperature, but the time it takes to reach + * the minimum temperature your thermistor can read. The lower the better/safer. + * This shouldn't need to be more than 30 seconds (30000) + */ +//#define PREHEAT_TIME_HOTEND_MS 0 +//#define PREHEAT_TIME_BED_MS 0 + +// @section extruder + +/** + * Extruder runout prevention. + * If the machine is idle and the temperature over MINTEMP + * then extrude some filament every couple of SECONDS. + */ +//#define EXTRUDER_RUNOUT_PREVENT +#if ENABLED(EXTRUDER_RUNOUT_PREVENT) + #define EXTRUDER_RUNOUT_MINTEMP 190 + #define EXTRUDER_RUNOUT_SECONDS 30 + #define EXTRUDER_RUNOUT_SPEED 1500 // (mm/min) + #define EXTRUDER_RUNOUT_EXTRUDE 5 // (mm) +#endif + +/** + * Hotend Idle Timeout + * Prevent filament in the nozzle from charring and causing a critical jam. + */ +//#define HOTEND_IDLE_TIMEOUT +#if ENABLED(HOTEND_IDLE_TIMEOUT) + #define HOTEND_IDLE_TIMEOUT_SEC (5*60) // (seconds) Time without extruder movement to trigger protection + #define HOTEND_IDLE_MIN_TRIGGER 180 // (°C) Minimum temperature to enable hotend protection + #define HOTEND_IDLE_NOZZLE_TARGET 0 // (°C) Safe temperature for the nozzle after timeout + #define HOTEND_IDLE_BED_TARGET 0 // (°C) Safe temperature for the bed after timeout +#endif + +// @section temperature + +// Calibration for AD595 / AD8495 sensor to adjust temperature measurements. +// The final temperature is calculated as (measuredTemp * GAIN) + OFFSET. +#define TEMP_SENSOR_AD595_OFFSET 0.0 +#define TEMP_SENSOR_AD595_GAIN 1.0 +#define TEMP_SENSOR_AD8495_OFFSET 0.0 +#define TEMP_SENSOR_AD8495_GAIN 1.0 + +// @section fans + +/** + * Controller Fan + * To cool down the stepper drivers and MOSFETs. + * + * The fan turns on automatically whenever any driver is enabled and turns + * off (or reduces to idle speed) shortly after drivers are turned off. + */ +//#define USE_CONTROLLER_FAN +#if ENABLED(USE_CONTROLLER_FAN) + //#define CONTROLLER_FAN_PIN -1 // Set a custom pin for the controller fan + //#define CONTROLLER_FAN2_PIN -1 // Set a custom pin for second controller fan + //#define CONTROLLER_FAN_USE_Z_ONLY // With this option only the Z axis is considered + //#define CONTROLLER_FAN_IGNORE_Z // Ignore Z stepper. Useful when stepper timeout is disabled. + #define CONTROLLERFAN_SPEED_MIN 0 // (0-255) Minimum speed. (If set below this value the fan is turned off.) + #define CONTROLLERFAN_SPEED_ACTIVE 255 // (0-255) Active speed, used when any motor is enabled + #define CONTROLLERFAN_SPEED_IDLE 0 // (0-255) Idle speed, used when motors are disabled + #define CONTROLLERFAN_IDLE_TIME 60 // (seconds) Extra time to keep the fan running after disabling motors + + // Use TEMP_SENSOR_BOARD as a trigger for enabling the controller fan + //#define CONTROLLER_FAN_MIN_BOARD_TEMP 40 // (°C) Turn on the fan if the board reaches this temperature + + // Use TEMP_SENSOR_SOC as a trigger for enabling the controller fan + //#define CONTROLLER_FAN_MIN_SOC_TEMP 40 // (°C) Turn on the fan if the SoC reaches this temperature + + #define CONTROLLER_FAN_BED_HEATING // Turn on the fan when heating the bed + + //#define CONTROLLER_FAN_EDITABLE // Enable M710 configurable settings + #if ENABLED(CONTROLLER_FAN_EDITABLE) + #define CONTROLLER_FAN_MENU // Enable the Controller Fan submenu + #endif +#endif + +/** + * Fan Kickstart + * When part cooling or controller fans first start, run at a speed that + * gets it spinning reliably for a short time before setting the requested speed. + * (Does not work on Sanguinololu with FAN_SOFT_PWM.) + */ +//#define FAN_KICKSTART_TIME 100 // (ms) +//#define FAN_KICKSTART_POWER 180 // 64-255 +//#define FAN_KICKSTART_LINEAR // Set kickstart time linearly based on the speed, e.g., for 20% (51) it will be FAN_KICKSTART_TIME * 0.2. + // Useful for quick speed up to low speed. Kickstart power must be set to 255. + +// Some coolers may require a non-zero "off" state. +//#define FAN_OFF_PWM 1 + +/** + * PWM Fan Scaling + * + * Define the min/max speeds for PWM fans (as set with M106). + * + * With these options the M106 0-255 value range is scaled to a subset + * to ensure that the fan has enough power to spin, or to run lower + * current fans with higher current. (e.g., 5V/12V fans with 12V/24V) + * Value 0 always turns off the fan. + * + * Define one or both of these to override the default 0-255 range. + */ +//#define FAN_MIN_PWM 50 +//#define FAN_MAX_PWM 128 + +/** + * Fan Fast PWM + * + * Combinations of PWM Modes, prescale values and TOP resolutions are used internally + * to produce a frequency as close as possible to the desired frequency. + * + * FAST_PWM_FAN_FREQUENCY + * Set this to your desired frequency. + * For AVR, if left undefined this defaults to F = F_CPU/(2*255*1) + * i.e., F = 31.4kHz on 16MHz micro-controllers or F = 39.2kHz on 20MHz micro-controllers. + * For non AVR, if left undefined this defaults to F = 1Khz. + * This F value is only to protect the hardware from an absence of configuration + * and not to complete it when users are not aware that the frequency must be specifically set to support the target board. + * + * NOTE: Setting very low frequencies (< 10 Hz) may result in unexpected timer behavior. + * Setting very high frequencies can damage your hardware. + * + * USE_OCR2A_AS_TOP [undefined by default] + * Boards that use TIMER2 for PWM have limitations resulting in only a few possible frequencies on TIMER2: + * 16MHz MCUs: [62.5kHz, 31.4kHz (default), 7.8kHz, 3.92kHz, 1.95kHz, 977Hz, 488Hz, 244Hz, 60Hz, 122Hz, 30Hz] + * 20MHz MCUs: [78.1kHz, 39.2kHz (default), 9.77kHz, 4.9kHz, 2.44kHz, 1.22kHz, 610Hz, 305Hz, 153Hz, 76Hz, 38Hz] + * A greater range can be achieved by enabling USE_OCR2A_AS_TOP. But note that this option blocks the use of + * PWM on pin OC2A. Only use this option if you don't need PWM on 0C2A. (Check your schematic.) + * USE_OCR2A_AS_TOP sacrifices duty cycle control resolution to achieve this broader range of frequencies. + */ +//#define FAST_PWM_FAN // Increase the fan PWM frequency. Removes the PWM noise but increases heating in the FET/Arduino +#if ENABLED(FAST_PWM_FAN) + //#define FAST_PWM_FAN_FREQUENCY 31400 // Define here to override the defaults below + //#define USE_OCR2A_AS_TOP + #ifndef FAST_PWM_FAN_FREQUENCY + #ifdef __AVR__ + #define FAST_PWM_FAN_FREQUENCY ((F_CPU) / (2 * 255 * 1)) + #else + #define FAST_PWM_FAN_FREQUENCY 1000U + #endif + #endif +#endif + +/** + * Assign more PWM fans for part cooling, synchronized with Fan 0 + */ +//#define REDUNDANT_PART_COOLING_FAN 1 // Index of the first fan to synchronize with Fan 0 +#ifdef REDUNDANT_PART_COOLING_FAN + //#define NUM_REDUNDANT_FANS 1 // Number of sequential fans to synchronize with Fan 0 +#endif + +/** + * Extruder cooling fans + * + * Extruder auto fans automatically turn on when their extruders' + * temperatures go above EXTRUDER_AUTO_FAN_TEMPERATURE. + * + * Your board's pins file specifies the recommended pins. Override those here + * or set to -1 to disable completely. + * + * Multiple extruders can be assigned to the same pin in which case + * the fan will turn on when any selected extruder is above the threshold. + */ + +#define FAN1_PIN 7 +#define E0_AUTO_FAN_PIN FAN1_PIN +#define E1_AUTO_FAN_PIN -1 +#define E2_AUTO_FAN_PIN -1 +#define E3_AUTO_FAN_PIN -1 +#define E4_AUTO_FAN_PIN -1 +#define E5_AUTO_FAN_PIN -1 +#define E6_AUTO_FAN_PIN -1 +#define E7_AUTO_FAN_PIN -1 +#define CHAMBER_AUTO_FAN_PIN -1 +#define COOLER_AUTO_FAN_PIN -1 + +#define EXTRUDER_AUTO_FAN_TEMPERATURE 50 +#define EXTRUDER_AUTO_FAN_SPEED 255 // 255 == full speed +#define CHAMBER_AUTO_FAN_TEMPERATURE 30 +#define CHAMBER_AUTO_FAN_SPEED 255 +#define COOLER_AUTO_FAN_TEMPERATURE 18 +#define COOLER_AUTO_FAN_SPEED 255 + +/** + * Hotend Cooling Fans tachometers + * + * Define one or more tachometer pins to enable fan speed + * monitoring, and reporting of fan speeds with M123. + * + * NOTE: Only works with fans up to 7000 RPM. + */ +//#define FOURWIRES_FANS // Needed with AUTO_FAN when 4-wire PWM fans are installed +//#define E0_FAN_TACHO_PIN -1 +//#define E0_FAN_TACHO_PULLUP +//#define E0_FAN_TACHO_PULLDOWN +//#define E1_FAN_TACHO_PIN -1 +//#define E1_FAN_TACHO_PULLUP +//#define E1_FAN_TACHO_PULLDOWN +//#define E2_FAN_TACHO_PIN -1 +//#define E2_FAN_TACHO_PULLUP +//#define E2_FAN_TACHO_PULLDOWN +//#define E3_FAN_TACHO_PIN -1 +//#define E3_FAN_TACHO_PULLUP +//#define E3_FAN_TACHO_PULLDOWN +//#define E4_FAN_TACHO_PIN -1 +//#define E4_FAN_TACHO_PULLUP +//#define E4_FAN_TACHO_PULLDOWN +//#define E5_FAN_TACHO_PIN -1 +//#define E5_FAN_TACHO_PULLUP +//#define E5_FAN_TACHO_PULLDOWN +//#define E6_FAN_TACHO_PIN -1 +//#define E6_FAN_TACHO_PULLUP +//#define E6_FAN_TACHO_PULLDOWN +//#define E7_FAN_TACHO_PIN -1 +//#define E7_FAN_TACHO_PULLUP +//#define E7_FAN_TACHO_PULLDOWN + +/** + * Part-Cooling Fan Multiplexer + * + * This feature allows you to digitally multiplex the fan output. + * The multiplexer is automatically switched at tool-change. + * Set FANMUX[012]_PINs below for up to 2, 4, or 8 multiplexed fans. + */ +#define FANMUX0_PIN -1 +#define FANMUX1_PIN -1 +#define FANMUX2_PIN -1 + +/** + * @section caselight + * M355 Case Light on-off / brightness + */ +//#define CASE_LIGHT_ENABLE +#if ENABLED(CASE_LIGHT_ENABLE) + //#define CASE_LIGHT_PIN 4 // Override the default pin if needed + #define INVERT_CASE_LIGHT false // Set true if Case Light is ON when pin is LOW + #define CASE_LIGHT_DEFAULT_ON true // Set default power-up state on + #define CASE_LIGHT_DEFAULT_BRIGHTNESS 105 // Set default power-up brightness (0-255, requires PWM pin) + //#define CASE_LIGHT_NO_BRIGHTNESS // Disable brightness control. Enable for non-PWM lighting. + //#define CASE_LIGHT_MAX_PWM 128 // Limit PWM duty cycle (0-255) + //#define CASE_LIGHT_MENU // Add Case Light options to the LCD menu + #if ENABLED(NEOPIXEL_LED) + //#define CASE_LIGHT_USE_NEOPIXEL // Use NeoPixel LED as case light + #endif + #if ANY(RGB_LED, RGBW_LED) + //#define CASE_LIGHT_USE_RGB_LED // Use RGB / RGBW LED as case light + #endif + #if ANY(CASE_LIGHT_USE_NEOPIXEL, CASE_LIGHT_USE_RGB_LED) + #define CASE_LIGHT_DEFAULT_COLOR { 255, 255, 255, 255 } // { Red, Green, Blue, White } + #endif +#endif + +// @section endstops + +// If you want endstops to stay on (by default) even when not homing +// enable this option. Override at any time with M120, M121. +//#define ENDSTOPS_ALWAYS_ON_DEFAULT + +// @section extras + +//#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats. + +// Employ an external closed loop controller. Override pins here if needed. +//#define EXTERNAL_CLOSED_LOOP_CONTROLLER +#if ENABLED(EXTERNAL_CLOSED_LOOP_CONTROLLER) + //#define CLOSED_LOOP_ENABLE_PIN -1 + //#define CLOSED_LOOP_MOVE_COMPLETE_PIN -1 +#endif + +// @section idex + +/** + * Dual X Carriage + * + * This setup has two X carriages that can move independently, each with its own hotend. + * The carriages can be used to print an object with two colors or materials, or in + * "duplication mode" it can print two identical or X-mirrored objects simultaneously. + * The inactive carriage is parked automatically to prevent oozing. + * X1 is the left carriage, X2 the right. They park and home at opposite ends of the X axis. + * By default the X2 stepper is assigned to the first unused E plug on the board. + * + * The following Dual X Carriage modes can be selected with M605 S: + * + * 0 : (FULL_CONTROL) The slicer has full control over both X-carriages and can achieve optimal travel + * results as long as it supports dual X-carriages. (M605 S0) + * + * 1 : (AUTO_PARK) The firmware automatically parks and unparks the X-carriages on tool-change so + * that additional slicer support is not required. (M605 S1) + * + * 2 : (DUPLICATION) The firmware moves the second X-carriage and extruder in synchronization with + * the first X-carriage and extruder, to print 2 copies of the same object at the same time. + * Set the constant X-offset and temperature differential with M605 S2 X[offs] R[deg] and + * follow with M605 S2 to initiate duplicated movement. + * + * 3 : (MIRRORED) Formbot/Vivedino-inspired mirrored mode in which the second extruder duplicates + * the movement of the first except the second extruder is reversed in the X axis. + * Set the initial X offset and temperature differential with M605 S2 X[offs] R[deg] and + * follow with M605 S3 to initiate mirrored movement. + */ +//#define DUAL_X_CARRIAGE +#if ENABLED(DUAL_X_CARRIAGE) + #define X1_MIN_POS X_MIN_POS // Set to X_MIN_POS + #define X1_MAX_POS X_BED_SIZE // A max coordinate so the X1 carriage can't hit the parked X2 carriage + #define X2_MIN_POS 80 // A min coordinate so the X2 carriage can't hit the parked X1 carriage + #define X2_MAX_POS 353 // The max position of the X2 carriage, typically also the home position + #define X2_HOME_POS X2_MAX_POS // Default X2 home position. Set to X2_MAX_POS. + // NOTE: For Dual X Carriage use M218 T1 Xn to override the X2_HOME_POS. + // This allows recalibration of endstops distance without a rebuild. + // Remember to set the second extruder's X-offset to 0 in your slicer. + + // This is the default power-up mode which can be changed later using M605 S. + #define DEFAULT_DUAL_X_CARRIAGE_MODE DXC_AUTO_PARK_MODE + + // Default x offset in duplication mode (typically set to half print bed width) + #define DEFAULT_DUPLICATION_X_OFFSET 100 + + // Default action to execute following M605 mode change commands. Typically G28X to apply new mode. + //#define EVENT_GCODE_IDEX_AFTER_MODECHANGE "G28X" +#endif + +// @section multi stepper + +/** + * Multi-Stepper / Multi-Endstop + * + * When X2_DRIVER_TYPE is defined, this indicates that the X and X2 motors work in tandem. + * The following explanations for X also apply to Y and Z multi-stepper setups. + * Endstop offsets may be changed by 'M666 X Y Z' and stored to EEPROM. + * + * - Enable INVERT_X2_VS_X_DIR if the X2 motor requires an opposite DIR signal from X. + * + * - Enable X_DUAL_ENDSTOPS if the second motor has its own endstop, with adjustable offset. + * + * - Extra endstops are included in the output of 'M119'. + * + * - Set X_DUAL_ENDSTOP_ADJUSTMENT to the known error in the X2 endstop. + * Applied to the X2 motor on 'G28' / 'G28 X'. + * Get the offset by homing X and measuring the error. + * Also set with 'M666 X' and stored to EEPROM with 'M500'. + * + * - Define the extra endstop pins here to override defaults. No auto-assignment. + */ +#if HAS_X2_STEPPER && DISABLED(DUAL_X_CARRIAGE) + //#define INVERT_X2_VS_X_DIR // X2 direction signal is the opposite of X + //#define X_DUAL_ENDSTOPS // X2 has its own endstop + #if ENABLED(X_DUAL_ENDSTOPS) + //#define X2_STOP_PIN X_MAX_PIN // X2 endstop pin override + #define X2_ENDSTOP_ADJUSTMENT 0 // X2 offset relative to X endstop + #endif +#endif + +#if HAS_Y2_STEPPER + //#define INVERT_Y2_VS_Y_DIR // Y2 direction signal is the opposite of Y + //#define Y_DUAL_ENDSTOPS // Y2 has its own endstop + #if ENABLED(Y_DUAL_ENDSTOPS) + //#define Y2_STOP_PIN Y_MAX_PIN // Y2 endstop pin override + #define Y2_ENDSTOP_ADJUSTMENT 0 // Y2 offset relative to Y endstop + #endif +#endif + +// +// Multi-Z steppers +// +#ifdef Z2_DRIVER_TYPE + //#define INVERT_Z2_VS_Z_DIR // Z2 direction signal is the opposite of Z + + //#define Z_MULTI_ENDSTOPS // Other Z axes have their own endstops + #if ENABLED(Z_MULTI_ENDSTOPS) + //#define Z2_STOP_PIN X_MAX_PIN // Z2 endstop pin override + #define Z2_ENDSTOP_ADJUSTMENT 0 // Z2 offset relative to Z endstop + #endif + #ifdef Z3_DRIVER_TYPE + //#define INVERT_Z3_VS_Z_DIR // Z3 direction signal is the opposite of Z + #if ENABLED(Z_MULTI_ENDSTOPS) + //#define Z3_STOP_PIN Y_MAX_PIN // Z3 endstop pin override + #define Z3_ENDSTOP_ADJUSTMENT 0 // Z3 offset relative to Z endstop + #endif + #endif + #ifdef Z4_DRIVER_TYPE + //#define INVERT_Z4_VS_Z_DIR // Z4 direction signal is the opposite of Z + #if ENABLED(Z_MULTI_ENDSTOPS) + //#define Z4_STOP_PIN Z_MAX_PIN // Z4 endstop pin override + #define Z4_ENDSTOP_ADJUSTMENT 0 // Z4 offset relative to Z endstop + #endif + #endif +#endif + +// Drive the E axis with two synchronized steppers +//#define E_DUAL_STEPPER_DRIVERS +#if ENABLED(E_DUAL_STEPPER_DRIVERS) + //#define INVERT_E1_VS_E0_DIR // E direction signals are opposites +#endif + +// @section extruder + +// Activate a solenoid on the active extruder with M380. Disable all with M381. +// Define SOL0_PIN, SOL1_PIN, etc., for each extruder that has a solenoid. +//#define EXT_SOLENOID + +// @section homing + +/** + * Homing Procedure + * Homing (G28) does an indefinite move towards the endstops to establish + * the position of the toolhead relative to the workspace. + */ + +//#define SENSORLESS_BACKOFF_MM { 2, 2, 0 } // (linear=mm, rotational=°) Backoff from endstops before sensorless homing + +#define HOMING_BUMP_MM { 5, 5, 5 } // (linear=mm, rotational=°) Backoff from endstops after first bump +#define HOMING_BUMP_DIVISOR { 4, 4, 4 } // Re-Bump Speed Divisor (Divides the Homing Feedrate) + +//#define HOMING_BACKOFF_POST_MM { 2, 2, 2 } // (linear=mm, rotational=°) Backoff from endstops after homing +//#define XY_COUNTERPART_BACKOFF_MM 0 // (mm) Backoff X after homing Y, and vice-versa + +//#define QUICK_HOME // If G28 contains XY do a diagonal move first +//#define HOME_Y_BEFORE_X // If G28 contains XY home Y before X +//#define HOME_Z_FIRST // Home Z first. Requires a real endstop (not a probe). +//#define CODEPENDENT_XY_HOMING // If X/Y can't home without homing Y/X first + +// @section bltouch + +#if ENABLED(BLTOUCH) + /** + * Either: Use the defaults (recommended) or: For special purposes, use the following DEFINES + * Do not activate settings that the probe might not understand. Clones might misunderstand + * advanced commands. + * + * Note: If the probe is not deploying, do a "Reset" and "Self-Test" and then check the + * wiring of the BROWN, RED and ORANGE wires. + * + * Note: If the trigger signal of your probe is not being recognized, it has been very often + * because the BLACK and WHITE wires needed to be swapped. They are not "interchangeable" + * like they would be with a real switch. So please check the wiring first. + * + * Settings for all BLTouch and clone probes: + */ + + // Safety: The probe needs time to recognize the command. + // Minimum command delay (ms). Enable and increase if needed. + //#define BLTOUCH_DELAY 500 + + /** + * Settings for BLTOUCH Classic 1.2, 1.3 or BLTouch Smart 1.0, 2.0, 2.2, 3.0, 3.1, and most clones: + */ + + // Feature: Switch into SW mode after a deploy. It makes the output pulse longer. Can be useful + // in special cases, like noisy or filtered input configurations. + //#define BLTOUCH_FORCE_SW_MODE + + /** + * Settings for BLTouch Smart 3.0 and 3.1 + * Summary: + * - Voltage modes: 5V and OD (open drain - "logic voltage free") output modes + * - High-Speed mode + * - Disable LCD voltage options + */ + + /** + * Danger: Don't activate 5V mode unless attached to a 5V-tolerant controller! + * V3.0 or 3.1: Set default mode to 5V mode at Marlin startup. + * If disabled, OD mode is the hard-coded default on 3.0 + * On startup, Marlin will compare its EEPROM to this value. If the selected mode + * differs, a mode set EEPROM write will be completed at initialization. + * Use the option below to force an EEPROM write to a V3.1 probe regardless. + */ + //#define BLTOUCH_SET_5V_MODE + + // Safety: Enable voltage mode settings in the LCD menu. + //#define BLTOUCH_LCD_VOLTAGE_MENU + + /** + * Safety: Activate if connecting a probe with an unknown voltage mode. + * V3.0: Set a probe into mode selected above at Marlin startup. Required for 5V mode on 3.0 + * V3.1: Force a probe with unknown mode into selected mode at Marlin startup ( = Probe EEPROM write ) + * To preserve the life of the probe, use this once then turn it off and re-flash. + */ + //#define BLTOUCH_FORCE_MODE_SET + + /** + * Enable "HIGH SPEED" option for probing. + * Danger: Disable if your probe sometimes fails. Only suitable for stable well-adjusted systems. + * This feature was designed for Deltabots with very fast Z moves; however, higher speed Cartesians + * might be able to use it. If the machine can't raise Z fast enough the BLTouch may go into ALARM. + * + * Set the default state here, change with 'M401 S' or UI, use M500 to save, M502 to reset. + */ + //#define BLTOUCH_HS_MODE true + + #ifdef BLTOUCH_HS_MODE + // The probe Z offset (M851 Z) is the height at which the probe triggers. + // This must be large enough to keep the probe pin off the bed and prevent + // it from snagging on the bed clips. + #define BLTOUCH_HS_EXTRA_CLEARANCE 7 // Extra Z Clearance + #endif + +#endif // BLTOUCH + +// @section calibrate + +/** + * Z Steppers Auto-Alignment + * Add the G34 command to align multiple Z steppers using a bed probe. + */ +//#define Z_STEPPER_AUTO_ALIGN +#if ENABLED(Z_STEPPER_AUTO_ALIGN) + /** + * Define probe X and Y positions for Z1, Z2 [, Z3 [, Z4]] + * These positions are machine-relative and do not shift with the M206 home offset! + * If not defined, probe limits will be used. + * Override with 'M422 S X Y'. + */ + //#define Z_STEPPER_ALIGN_XY { { 10, 190 }, { 100, 10 }, { 190, 190 } } + + /** + * Orientation for the automatically-calculated probe positions. + * Override Z stepper align points with 'M422 S X Y' + * + * 2 Steppers: (0) (1) + * | | 2 | + * | 1 2 | | + * | | 1 | + * + * 3 Steppers: (0) (1) (2) (3) + * | 3 | 1 | 2 1 | 2 | + * | | 3 | | 3 | + * | 1 2 | 2 | 3 | 1 | + * + * 4 Steppers: (0) (1) (2) (3) + * | 4 3 | 1 4 | 2 1 | 3 2 | + * | | | | | + * | 1 2 | 2 3 | 3 4 | 4 1 | + */ + #ifndef Z_STEPPER_ALIGN_XY + //#define Z_STEPPERS_ORIENTATION 0 + #endif + + /** + * Z Stepper positions for more rapid convergence in bed alignment. + * Requires 3 or 4 Z steppers. + * + * Define Stepper XY positions for Z1, Z2, Z3... corresponding to the screw + * positions in the bed carriage, with one position per Z stepper in stepper + * driver order. + */ + //#define Z_STEPPER_ALIGN_STEPPER_XY { { 210.7, 102.5 }, { 152.6, 220.0 }, { 94.5, 102.5 } } + + #ifndef Z_STEPPER_ALIGN_STEPPER_XY + // Amplification factor. Used to scale the correction step up or down in case + // the stepper (spindle) position is farther out than the test point. + #define Z_STEPPER_ALIGN_AMP 1.0 // Use a value > 1.0 NOTE: This may cause instability! + #endif + + // On a 300mm bed a 5% grade would give a misalignment of ~1.5cm + #define G34_MAX_GRADE 5 // (%) Maximum incline that G34 will handle + #define Z_STEPPER_ALIGN_ITERATIONS 5 // Number of iterations to apply during alignment + #define Z_STEPPER_ALIGN_ACC 0.02 // Stop iterating early if the accuracy is better than this + + #define RESTORE_LEVELING_AFTER_G34 // Restore leveling after G34 is done? + + // After G34, re-home Z (G28 Z) or just calculate it from the last probe heights? + // Re-homing might be more precise in reproducing the actual 'G28 Z' homing height, especially on an uneven bed. + #define HOME_AFTER_G34 + + /** + * Commands to execute at the start of G34 probing, + * after switching to the PROBING_TOOL. + */ + //#define EVENT_GCODE_BEFORE_G34 "M300 P440 S200" + + /** + * Commands to execute at the end of G34 probing. + * Useful to retract or move the Z probe out of the way. + */ + //#define EVENT_GCODE_AFTER_G34 "G1 Z10 F12000\nG1 X15 Y330\nG1 Z0.5\nG1 Z10" + +#endif // Z_STEPPER_AUTO_ALIGN + +/** + * Assisted Tramming + * + * Add the G35 command to measure bed corners and help adjust screws. Requires a bed probe. + */ +//#define ASSISTED_TRAMMING +#if ENABLED(ASSISTED_TRAMMING) + + // Define from 3 to 9 points to probe. + #define TRAMMING_POINT_XY { { 20, 20 }, { 180, 20 }, { 180, 180 }, { 20, 180 } } + + // Define position names for probe points. + #define TRAMMING_POINT_NAME_1 "Front-Left" + #define TRAMMING_POINT_NAME_2 "Front-Right" + #define TRAMMING_POINT_NAME_3 "Back-Right" + #define TRAMMING_POINT_NAME_4 "Back-Left" + + #define RESTORE_LEVELING_AFTER_G35 // Enable to restore leveling setup after operation + //#define REPORT_TRAMMING_MM // Report Z deviation (mm) for each point relative to the first + + //#define ASSISTED_TRAMMING_WIZARD // Add a Tramming Wizard to the LCD menu + + //#define ASSISTED_TRAMMING_WAIT_POSITION { X_CENTER, Y_CENTER, 30 } // Move the nozzle out of the way for adjustment + + /** + * Screw Thread. Use one of the following defines: + * + * M3_CW = M3 Clockwise, M3_CCW = M3 Counter-Clockwise + * M4_CW = M4 Clockwise, M4_CCW = M4 Counter-Clockwise + * M5_CW = M5 Clockwise, M5_CCW = M5 Counter-Clockwise + * + * :{'M3_CW':'M3 Clockwise','M3_CCW':'M3 Counter-Clockwise','M4_CW':'M4 Clockwise','M4_CCW':'M4 Counter-Clockwise','M5_CW':'M5 Clockwise','M5_CCW':'M5 Counter-Clockwise'} + */ + #define TRAMMING_SCREW_THREAD M3_CW + +#endif + +// @section motion control + +/** + * Fixed-time-based Motion Control -- BETA FEATURE + * Enable/disable and set parameters with G-code M493 and M494. + * See ft_types.h for named values used by FTM options. + */ +//#define FT_MOTION +#if ENABLED(FT_MOTION) + //#define FTM_IS_DEFAULT_MOTION // Use FT Motion as the factory default? + //#define FT_MOTION_MENU // Provide a MarlinUI menu to set M493 and M494 parameters + //#define FTM_HOME_AND_PROBE // Use FT Motion for homing / probing. Disable if FT Motion breaks these functions. + + #define FTM_DEFAULT_DYNFREQ_MODE dynFreqMode_DISABLED // Default mode of dynamic frequency calculation. (DISABLED, Z_BASED, MASS_BASED) + + #define FTM_LINEAR_ADV_DEFAULT_ENA false // Default linear advance enable (true) or disable (false) + #define FTM_LINEAR_ADV_DEFAULT_K 0.0f // Default linear advance gain. (Acceleration-based scaling factor.) + + #define FTM_DEFAULT_SHAPER_X ftMotionShaper_NONE // Default shaper mode on X axis (NONE, ZV, ZVD, ZVDD, ZVDDD, EI, 2HEI, 3HEI, MZV) + #define FTM_SHAPING_DEFAULT_FREQ_X 37.0f // (Hz) Default peak frequency used by input shapers + #define FTM_SHAPING_ZETA_X 0.1f // Zeta used by input shapers for X axis + #define FTM_SHAPING_V_TOL_X 0.05f // Vibration tolerance used by EI input shapers for X axis + + #define FTM_DEFAULT_SHAPER_Y ftMotionShaper_NONE // Default shaper mode on Y axis + #define FTM_SHAPING_DEFAULT_FREQ_Y 37.0f // (Hz) Default peak frequency used by input shapers + #define FTM_SHAPING_ZETA_Y 0.1f // Zeta used by input shapers for Y axis + #define FTM_SHAPING_V_TOL_Y 0.05f // Vibration tolerance used by EI input shapers for Y axis + + //#define FTM_SHAPER_Z // Include Z shaping support + #define FTM_DEFAULT_SHAPER_Z ftMotionShaper_NONE // Default shaper mode on Z axis + #define FTM_SHAPING_DEFAULT_FREQ_Z 21.0f // (Hz) Default peak frequency used by input shapers + #define FTM_SHAPING_ZETA_Z 0.03f // Zeta used by input shapers for Z axis + #define FTM_SHAPING_V_TOL_Z 0.05f // Vibration tolerance used by EI input shapers for Z axis + + //#define FTM_SHAPER_E // Include E shaping support + // Required to synchronise extruder with XYZ (better quality) + #define FTM_DEFAULT_SHAPER_E ftMotionShaper_NONE // Default shaper mode on Extruder axis + #define FTM_SHAPING_DEFAULT_FREQ_E 21.0f // (Hz) Default peak frequency used by input shapers + #define FTM_SHAPING_ZETA_E 0.03f // Zeta used by input shapers for E axis + #define FTM_SHAPING_V_TOL_E 0.05f // Vibration tolerance used by EI input shapers for E axis + + //#define FTM_SMOOTHING // Smoothing can reduce artifacts and make steppers quieter + // on sharp corners, but too much will round corners. + #if ENABLED(FTM_SMOOTHING) + #define FTM_MAX_SMOOTHING_TIME 0.10f // Maximum smoothing time (seconds), higher consumes more RAM. + // Increase smoothing time to reduce jerky motion, ghosting and noises. + #define FTM_SMOOTHING_TIME_X 0.00f // (s) Smoothing time for X axis. Zero means disabled. + #define FTM_SMOOTHING_TIME_Y 0.00f // (s) Smoothing time for Y axis + #define FTM_SMOOTHING_TIME_Z 0.00f // (s) Smoothing time for Z axis + #define FTM_SMOOTHING_TIME_E 0.02f // (s) Smoothing time for E axis. Prevents noise/skipping from LA by + // smoothing acceleration peaks, which may also smooth curved surfaces. + #endif + + #define FTM_TRAJECTORY_TYPE TRAPEZOIDAL // Block acceleration profile (TRAPEZOIDAL, POLY5, POLY6) + // TRAPEZOIDAL: Continuous Velocity. Max acceleration is respected. + // POLY5: Like POLY6 with 1.5x but cpu cheaper. + // POLY6: Continuous Acceleration (aka S_CURVE). + // POLY trajectories not only reduce resonances without rounding corners, but also + // reduce extruder strain due to linear advance. + + #define FTM_POLY6_ACCELERATION_OVERSHOOT 1.875f // Max acceleration overshoot factor for POLY6 (1.25 to 1.875) + + /** + * Advanced configuration + */ + #define FTM_UNIFIED_BWS // DON'T DISABLE unless you use Ulendo FBS (not implemented) + #if ENABLED(FTM_UNIFIED_BWS) + #define FTM_BW_SIZE 100 // Unified Window and Batch size with a ratio of 2 + #else + #define FTM_WINDOW_SIZE 200 // Custom Window size for trajectory generation needed by Ulendo FBS + #define FTM_BATCH_SIZE 100 // Custom Batch size for trajectory generation needed by Ulendo FBS + #endif + + #define FTM_FS 1000 // (Hz) Frequency for trajectory generation. (Reciprocal of FTM_TS) + + #if DISABLED(COREXY) + #define FTM_STEPPER_FS 20000 // (Hz) Frequency for stepper I/O update + + // Use this to adjust the time required to consume the command buffer. + // Try increasing this value if stepper motion is choppy. + #define FTM_STEPPERCMD_BUFF_SIZE 3000 // Size of the stepper command buffers + + #else + // CoreXY motion needs a larger buffer size. These values are based on our testing. + #define FTM_STEPPER_FS 30000 + #define FTM_STEPPERCMD_BUFF_SIZE 6000 + #endif + + #define FTM_MIN_SHAPE_FREQ 10 // (Hz) Minimum shaping frequency, lower consumes more RAM +#endif // FT_MOTION + +/** + * Input Shaping + * + * Zero Vibration (ZV) Input Shaping for X and/or Y movements. + * + * This option uses a lot of SRAM for the step buffer. The buffer size is + * calculated automatically from SHAPING_FREQ_[XYZ], DEFAULT_AXIS_STEPS_PER_UNIT, + * DEFAULT_MAX_FEEDRATE and ADAPTIVE_STEP_SMOOTHING. The default calculation can + * be overridden by setting SHAPING_MIN_FREQ and/or SHAPING_MAX_FEEDRATE. + * The higher the frequency and the lower the feedrate, the smaller the buffer. + * If the buffer is too small at runtime, input shaping will have reduced + * effectiveness during high speed movements. + * + * Tune with M593 D F + */ +//#define INPUT_SHAPING_X +//#define INPUT_SHAPING_Y +//#define INPUT_SHAPING_Z +#if ANY(INPUT_SHAPING_X, INPUT_SHAPING_Y, INPUT_SHAPING_Z) + #if ENABLED(INPUT_SHAPING_X) + #define SHAPING_FREQ_X 40.0 // (Hz) The default dominant resonant frequency on the X axis. + #define SHAPING_ZETA_X 0.15 // Damping ratio of the X axis (range: 0.0 = no damping to 1.0 = critical damping). + #endif + #if ENABLED(INPUT_SHAPING_Y) + #define SHAPING_FREQ_Y 40.0 // (Hz) The default dominant resonant frequency on the Y axis. + #define SHAPING_ZETA_Y 0.15 // Damping ratio of the Y axis (range: 0.0 = no damping to 1.0 = critical damping). + #endif + #if ENABLED(INPUT_SHAPING_Z) + #define SHAPING_FREQ_Z 40.0 // (Hz) The default dominant resonant frequency on the Z axis. + #define SHAPING_ZETA_Z 0.15 // Damping ratio of the Z axis (range: 0.0 = no damping to 1.0 = critical damping). + #endif + //#define SHAPING_MIN_FREQ 20.0 // (Hz) By default the minimum of the shaping frequencies. Override to affect SRAM usage. + //#define SHAPING_MAX_STEPRATE 10000 // By default the maximum total step rate of the shaped axes. Override to affect SRAM usage. + //#define SHAPING_MENU // Add a menu to the LCD to set shaping parameters. +#endif + +// @section motion + +#define AXIS_RELATIVE_MODES { false, false, false, false } + +// Add a Duplicate option for well-separated conjoined nozzles +//#define MULTI_NOZZLE_DUPLICATION + +// By default stepper drivers require an active-HIGH signal but some high-power drivers require an active-LOW signal to step. +#define STEP_STATE_X HIGH +#define STEP_STATE_Y HIGH +#define STEP_STATE_Z HIGH +#define STEP_STATE_I HIGH +#define STEP_STATE_J HIGH +#define STEP_STATE_K HIGH +#define STEP_STATE_U HIGH +#define STEP_STATE_V HIGH +#define STEP_STATE_W HIGH +#define STEP_STATE_E HIGH + +/** + * Idle Stepper Shutdown + * Enable DISABLE_IDLE_* to shut down axis steppers after an idle period. + * The default timeout duration can be overridden with M18 and M84. Set to 0 for No Timeout. + */ +#define DEFAULT_STEPPER_TIMEOUT_SEC 120 +#define DISABLE_IDLE_X +#define DISABLE_IDLE_Y +#define DISABLE_IDLE_Z // Disable if the nozzle could fall onto your printed part! +//#define DISABLE_IDLE_I +//#define DISABLE_IDLE_J +//#define DISABLE_IDLE_K +//#define DISABLE_IDLE_U +//#define DISABLE_IDLE_V +//#define DISABLE_IDLE_W +#define DISABLE_IDLE_E // Shut down all idle extruders + +// Default Minimum Feedrates for printing and travel moves +#define DEFAULT_MINIMUMFEEDRATE 0.0 // (mm/s) Minimum feedrate. Set with M205 S. +#define DEFAULT_MINTRAVELFEEDRATE 0.0 // (mm/s) Minimum travel feedrate. Set with M205 T. + +// Minimum time that a segment needs to take as the buffer gets emptied +#define DEFAULT_MINSEGMENTTIME 20000 // (µs) Set with M205 B. + +// Slow down the machine if the lookahead buffer is (by default) half full. +// Increase the slowdown divisor for larger buffer sizes. +#define SLOWDOWN +#if ENABLED(SLOWDOWN) + #define SLOWDOWN_DIVISOR 2 +#endif + +/** + * XY Frequency limit + * Reduce resonance by limiting the frequency of small zigzag infill moves. + * See https://hydraraptor.blogspot.com/2010/12/frequency-limit.html + * Use M201 F S to change limits at runtime. + */ +//#define XY_FREQUENCY_LIMIT 10 // (Hz) Maximum frequency of small zigzag infill moves. Set with M201 F. +#ifdef XY_FREQUENCY_LIMIT + #define XY_FREQUENCY_MIN_PERCENT 5 // (%) Minimum FR percentage to apply. Set with M201 S. +#endif + +// +// Backlash Compensation +// Adds extra movement to axes on direction-changes to account for backlash. +// +//#define BACKLASH_COMPENSATION +#if ENABLED(BACKLASH_COMPENSATION) + // Define values for backlash distance and correction. + // If BACKLASH_GCODE is enabled these values are the defaults. + #define BACKLASH_DISTANCE_MM { 0, 0, 0 } // (linear=mm, rotational=°) One value for each linear axis + #define BACKLASH_CORRECTION 0.0 // 0.0 = no correction; 1.0 = full correction + + // Add steps for motor direction changes on CORE kinematics + //#define CORE_BACKLASH + + // Set BACKLASH_SMOOTHING_MM to spread backlash correction over multiple segments + // to reduce print artifacts. (Enabling this is costly in memory and computation!) + //#define BACKLASH_SMOOTHING_MM 3 // (mm) + + // Add runtime configuration and tuning of backlash values (M425) + //#define BACKLASH_GCODE + + #if ENABLED(BACKLASH_GCODE) + // Measure the Z backlash when probing (G29) and set with "M425 Z" + #define MEASURE_BACKLASH_WHEN_PROBING + + #if ENABLED(MEASURE_BACKLASH_WHEN_PROBING) + // When measuring, the probe will move up to BACKLASH_MEASUREMENT_LIMIT + // mm away from point of contact in BACKLASH_MEASUREMENT_RESOLUTION + // increments while checking for the contact to be broken. + #define BACKLASH_MEASUREMENT_LIMIT 0.5 // (mm) + #define BACKLASH_MEASUREMENT_RESOLUTION 0.005 // (mm) + #define BACKLASH_MEASUREMENT_FEEDRATE Z_PROBE_FEEDRATE_SLOW // (mm/min) + #endif + #endif +#endif + +/** + * Automatic backlash, position, and hotend offset calibration + * + * Enable G425 to run automatic calibration using an electrically- + * conductive cube, bolt, or washer mounted on the bed. + * + * G425 uses the probe to touch the top and sides of the calibration object + * on the bed and measures and/or correct positional offsets, axis backlash + * and hotend offsets. + * + * Note: HOTEND_OFFSET and CALIBRATION_OBJECT_CENTER must be set to within + * ±5mm of true values for G425 to succeed. + */ +//#define CALIBRATION_GCODE +#if ENABLED(CALIBRATION_GCODE) + + //#define CALIBRATION_SCRIPT_PRE "M117 Starting Auto-Calibration\nT0\nG28\nG12\nM117 Calibrating..." + //#define CALIBRATION_SCRIPT_POST "M500\nM117 Calibration data saved" + + #define CALIBRATION_FEEDRATE_SLOW 60 // (mm/min) + #define CALIBRATION_FEEDRATE_FAST 1200 // (mm/min) + #define CALIBRATION_FEEDRATE_TRAVEL 3000 // (mm/min) + + // The following parameters refer to the conical section of the nozzle tip. + #define CALIBRATION_NOZZLE_TIP_HEIGHT 1.0 // (mm) + #define CALIBRATION_NOZZLE_OUTER_DIAMETER 2.0 // (mm) + + // Uncomment to enable reporting (required for "G425 V", but consumes flash). + //#define CALIBRATION_REPORTING + + // The true location and dimension the cube/bolt/washer on the bed. + #define CALIBRATION_OBJECT_CENTER { 264.0, -22.0, -2.0 } // (mm) + #define CALIBRATION_OBJECT_DIMENSIONS { 10.0, 10.0, 10.0 } // (mm) + + // Comment out any sides which are unreachable by the probe. For best + // auto-calibration results, all sides must be reachable. + #define CALIBRATION_MEASURE_RIGHT + #define CALIBRATION_MEASURE_FRONT + #define CALIBRATION_MEASURE_LEFT + #define CALIBRATION_MEASURE_BACK + + //#define CALIBRATION_MEASURE_IMIN + //#define CALIBRATION_MEASURE_IMAX + //#define CALIBRATION_MEASURE_JMIN + //#define CALIBRATION_MEASURE_JMAX + //#define CALIBRATION_MEASURE_KMIN + //#define CALIBRATION_MEASURE_KMAX + //#define CALIBRATION_MEASURE_UMIN + //#define CALIBRATION_MEASURE_UMAX + //#define CALIBRATION_MEASURE_VMIN + //#define CALIBRATION_MEASURE_VMAX + //#define CALIBRATION_MEASURE_WMIN + //#define CALIBRATION_MEASURE_WMAX + + // Probing at the exact top center only works if the center is flat. If + // probing on a screw head or hollow washer, probe near the edges. + //#define CALIBRATION_MEASURE_AT_TOP_EDGES + + // Define the pin to read during calibration + #ifndef CALIBRATION_PIN + //#define CALIBRATION_PIN -1 // Define here to override the default pin + #define CALIBRATION_PIN_INVERTING false // Set to true to invert the custom pin + //#define CALIBRATION_PIN_PULLDOWN + #define CALIBRATION_PIN_PULLUP + #endif +#endif + +/** + * Multi-stepping sends steps in bursts to reduce MCU usage for high step-rates. + * This allows higher feedrates than the MCU could otherwise support. + */ +#define MULTISTEPPING_LIMIT 16 // :[1, 2, 4, 8, 16, 32, 64, 128] + +/** + * Adaptive Step Smoothing increases the resolution of multi-axis moves, particularly at step frequencies + * below 1kHz (for AVR) or 10kHz (for ARM), where aliasing between axes in multi-axis moves causes audible + * vibration and surface artifacts. The algorithm adapts to provide the best possible step smoothing at the + * lowest stepping frequencies. + */ +//#define ADAPTIVE_STEP_SMOOTHING + +/** + * Custom Microstepping + * Override as-needed for your setup. Up to 3 MS pins are supported. + */ +//#define MICROSTEP1 LOW,LOW,LOW +//#define MICROSTEP2 HIGH,LOW,LOW +//#define MICROSTEP4 LOW,HIGH,LOW +//#define MICROSTEP8 HIGH,HIGH,LOW +//#define MICROSTEP16 LOW,LOW,HIGH +//#define MICROSTEP32 HIGH,LOW,HIGH + +// Microstep settings (Requires a board with pins named X_MS1, X_MS2, etc.) +#define MICROSTEP_MODES { 16, 16, 16, 16, 16, 16 } // [1,2,4,8,16] + +/** + * @section stepper motor current + * + * Some boards have a means of setting the stepper motor current via firmware. + * + * The power on motor currents are set by: + * PWM_MOTOR_CURRENT - used by MINIRAMBO & ULTIMAIN_2 + * known compatible chips: A4982 + * DIGIPOT_MOTOR_CURRENT - used by BQ_ZUM_MEGA_3D, RAMBO & SCOOVO_X9H + * known compatible chips: AD5206 + * DAC_MOTOR_CURRENT_DEFAULT - used by PRINTRBOARD_REVF & RIGIDBOARD_V2 + * known compatible chips: MCP4728 + * DIGIPOT_I2C_MOTOR_CURRENTS - used by 5DPRINT, AZTEEG_X3_PRO, AZTEEG_X5_MINI_WIFI, MIGHTYBOARD_REVE + * known compatible chips: MCP4451, MCP4018 + * + * Motor currents can also be set by M907 - M910 and by the LCD. + * M907 - applies to all. + * M908 - BQ_ZUM_MEGA_3D, RAMBO, PRINTRBOARD_REVF, RIGIDBOARD_V2 & SCOOVO_X9H + * M909, M910 & LCD - only PRINTRBOARD_REVF & RIGIDBOARD_V2 + */ +//#define PWM_MOTOR_CURRENT { 1300, 1300, 1250 } // Values in milliamps +#define DIGIPOT_MOTOR_CURRENT { 135,135,135,135,135 } // Values 0-255 (RAMBO 135 = ~0.75A, 185 = ~1A) +//#define DAC_MOTOR_CURRENT_DEFAULT { 70, 80, 90, 80 } // Default drive percent - X, Y, Z, E axis + +/** + * I2C-based DIGIPOTs (e.g., Azteeg X3 Pro) + */ +//#define DIGIPOT_MCP4018 // Requires https://github.com/felias-fogg/SlowSoftI2CMaster +//#define DIGIPOT_MCP4451 +#if ANY(DIGIPOT_MCP4018, DIGIPOT_MCP4451) + #define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT:4 AZTEEG_X3_PRO:8 MKS_SBASE:5 MIGHTYBOARD_REVE:5 + + // Actual motor currents in Amps. The number of entries must match DIGIPOT_I2C_NUM_CHANNELS. + // These correspond to the physical drivers, so be mindful if the order is changed. + #define DIGIPOT_I2C_MOTOR_CURRENTS { 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 } // AZTEEG_X3_PRO + + //#define DIGIPOT_USE_RAW_VALUES // Use DIGIPOT_MOTOR_CURRENT raw wiper values (instead of A4988 motor currents) + + /** + * Common slave addresses: + * + * A (A shifted) B (B shifted) IC + * Smoothie 0x2C (0x58) 0x2D (0x5A) MCP4451 + * AZTEEG_X3_PRO 0x2C (0x58) 0x2E (0x5C) MCP4451 + * AZTEEG_X5_MINI 0x2C (0x58) 0x2E (0x5C) MCP4451 + * AZTEEG_X5_MINI_WIFI 0x58 0x5C MCP4451 + * MIGHTYBOARD_REVE 0x2F (0x5E) MCP4018 + */ + //#define DIGIPOT_I2C_ADDRESS_A 0x2C // Unshifted slave address for first DIGIPOT + //#define DIGIPOT_I2C_ADDRESS_B 0x2D // Unshifted slave address for second DIGIPOT +#endif + +//=========================================================================== +//=============================Additional Features=========================== +//=========================================================================== + +// @section lcd + +#if HAS_MANUAL_MOVE_MENU + #define MANUAL_FEEDRATE { 50*60, 50*60, 50*60, 60 } // (mm/min) Feedrates for manual moves along X, Y, Z, E from panel + #define FINE_MANUAL_MOVE 0.025 // (mm) Smallest manual move (< 0.1mm) applying to Z on most machines + #if IS_ULTIPANEL + #define MANUAL_E_MOVES_RELATIVE // Display extruder move distance rather than "position" + #define ULTIPANEL_FEEDMULTIPLY // Encoder sets the feedrate multiplier on the Status Screen + //#define ULTIPANEL_FLOWPERCENT // Encoder sets the flow percentage on the Status Screen + #endif +#endif + +// Change values more rapidly when the encoder is rotated faster +#define ENCODER_RATE_MULTIPLIER +#if ENABLED(ENCODER_RATE_MULTIPLIER) + #define ENCODER_10X_STEPS_PER_SEC 30 // (steps/s) Encoder rate for 10x speed + #define ENCODER_100X_STEPS_PER_SEC 80 // (steps/s) Encoder rate for 100x speed +#endif + +// Play a beep when the feedrate is changed from the Status Screen +//#define BEEP_ON_FEEDRATE_CHANGE +#if ENABLED(BEEP_ON_FEEDRATE_CHANGE) + #define FEEDRATE_CHANGE_BEEP_DURATION 10 + #define FEEDRATE_CHANGE_BEEP_FREQUENCY 440 +#endif + +/** + * Probe Offset Wizard + * Add a Probe Z Offset calibration option to the LCD menu. + * Use this helper to get a perfect 'M851 Z' probe offset. + * When launched this powerful wizard: + * - Measures the bed height at the configured position with the probe. + * - Moves the nozzle to the same position for a "paper" measurement. + * - The difference is used to set the probe Z offset. + */ +#if HAS_BED_PROBE && ANY(HAS_MARLINUI_MENU, HAS_TFT_LVGL_UI) + //#define PROBE_OFFSET_WIZARD + #if ENABLED(PROBE_OFFSET_WIZARD) + /** + * Enable to init the Probe Z-Offset when starting the Wizard. + * Use a height slightly above the estimated nozzle-to-probe Z offset. + * For example, with an offset of -5, consider a starting height of -4. + */ + //#define PROBE_OFFSET_WIZARD_START_Z -4.0 + + // Set a convenient position to do the calibration (probing point and nozzle/bed-distance) + //#define PROBE_OFFSET_WIZARD_XY_POS { X_CENTER, Y_CENTER } + #endif +#endif + +#if HAS_MARLINUI_MENU + + #if HAS_BED_PROBE + + // Show Deploy / Stow Probe options in the Motion menu. + #define PROBE_DEPLOY_STOW_MENU + + // Add calibration in the Probe Offsets menu to compensate for X-axis twist. + //#define X_AXIS_TWIST_COMPENSATION + #if ENABLED(X_AXIS_TWIST_COMPENSATION) + /** + * Enable to init the Probe Z-Offset when starting the Wizard. + * Use a height slightly above the estimated nozzle-to-probe Z offset. + * For example, with an offset of -5, consider a starting height of -4. + */ + #define XATC_START_Z 0.0 + #define XATC_MAX_POINTS 3 // Number of points to probe in the wizard + #define XATC_Y_POSITION Y_CENTER // (mm) Y position to probe + #define XATC_Z_OFFSETS { 0, 0, 0 } // Z offsets for X axis sample points + #endif + + #endif + + // Include a page of printer information in the LCD Main Menu + #define LCD_INFO_MENU + #if ENABLED(LCD_INFO_MENU) + //#define LCD_PRINTER_INFO_IS_BOOTSCREEN // Show bootscreen(s) instead of Printer Info pages + //#define BUILD_INFO_MENU_ITEM // Add a menu item to display the build date and time + #endif + + /** + * MarlinUI "Move Axis" menu distances. Comma-separated list. + * Values are displayed as-defined, so always use plain numbers here. + * Axis moves <= 1/2 the axis length and Extruder moves <= EXTRUDE_MAXLENGTH + * will be shown in the move submenus. + */ + + #define MANUAL_MOVE_DISTANCE_MM 10, 1.0, 0.1 // (mm) + //#define MANUAL_MOVE_DISTANCE_MM 100, 50, 10, 1.0, 0.1 // (mm) + //#define MANUAL_MOVE_DISTANCE_MM 500, 100, 50, 10, 1.0, 0.1 // (mm) + + // Manual move distances for INCH_MODE_SUPPORT + #define MANUAL_MOVE_DISTANCE_IN 0.100, 0.010, 0.001 // (in) + //#define MANUAL_MOVE_DISTANCE_IN 1.000, 0.500, 0.100, 0.010, 0.001 // (in) + //#define MANUAL_MOVE_DISTANCE_IN 5.000, 1.000, 0.500, 0.100, 0.010, 0.001 // (in) + + // Manual move distances for rotational axes + #define MANUAL_MOVE_DISTANCE_DEG 90, 45, 22.5, 5, 1 // (°) + + // BACK menu items keep the highlight at the top + //#define TURBO_BACK_MENU_ITEM + + // BACK menu items show "Back" instead of the previous menu name + //#define GENERIC_BACK_MENU_ITEM + + // Insert a menu for preheating at the top level to allow for quick access + //#define PREHEAT_SHORTCUT_MENU_ITEM + + // Add Configuration > Debug Menu > Endstop Test for endstop/probe/runout testing + //#define LCD_ENDSTOP_TEST + +#endif // HAS_MARLINUI_MENU + +#if HAS_DISPLAY + /** + * *** VENDORS PLEASE READ *** + * + * Marlin allows you to add a custom boot image for Graphical LCDs. + * With this option Marlin will first show your custom screen followed + * by the standard Marlin logo with version number and web URL. + * + * We encourage you to take advantage of this new feature and we also + * respectfully request that you retain the unmodified Marlin boot screen. + */ + #define SHOW_BOOTSCREEN // Show the Marlin bootscreen on startup. ** ENABLE FOR PRODUCTION ** + #if ENABLED(SHOW_BOOTSCREEN) + #define BOOTSCREEN_TIMEOUT 3000 // (ms) Total Duration to display the boot screen(s) + #if ANY(HAS_MARLINUI_U8GLIB, TFT_COLOR_UI) + #define BOOT_MARLIN_LOGO_SMALL // Show a smaller Marlin logo on the Boot Screen (saving lots of flash) + #endif + #if HAS_MARLINUI_U8GLIB + //#define BOOT_MARLIN_LOGO_ANIMATED // Animated Marlin logo. Costs ~3260 (or ~940) bytes of flash. + #endif + #if ANY(HAS_MARLINUI_U8GLIB, TOUCH_UI_FTDI_EVE, HAS_MARLINUI_HD44780) + //#define SHOW_CUSTOM_BOOTSCREEN // Show the bitmap in Marlin/_Bootscreen.h on startup. + #endif + #endif + + #if HAS_MARLINUI_U8GLIB + //#define CUSTOM_STATUS_SCREEN_IMAGE // Show the bitmap in Marlin/_Statusscreen.h on the status screen. + #endif + + //#define SOUND_MENU_ITEM // Add a mute option to the LCD menu + #define SOUND_ON_DEFAULT // Buzzer/speaker default enabled state + + #if ENABLED(U8GLIB_SSD1309) + //#define LCD_DOUBLE_BUFFER // Optimize display updates. Costs ~1K of SRAM. + #endif + + #if HAS_WIRED_LCD + //#define DOUBLE_LCD_FRAMERATE // Not recommended for slow boards. + #endif + + // The timeout to return to the status screen from sub-menus + //#define LCD_TIMEOUT_TO_STATUS 15000 // (ms) + + // Scroll a longer status message into view + //#define STATUS_MESSAGE_SCROLLING + + // Apply a timeout to low-priority status messages + //#define STATUS_MESSAGE_TIMEOUT_SEC 30 // (seconds) + + // On the Info Screen, display XY with one decimal place when possible + //#define LCD_DECIMAL_SMALL_XY + + // Show the E position (filament used) during printing + //#define LCD_SHOW_E_TOTAL + + // Display a negative temperature instead of "err" + //#define SHOW_TEMPERATURE_BELOW_ZERO + + /** + * LED Control Menu + * Add LED Control to the LCD menu + */ + //#define LED_CONTROL_MENU + #if ENABLED(LED_CONTROL_MENU) + #define LED_COLOR_PRESETS // Enable the Preset Color menu option + //#define NEO2_COLOR_PRESETS // Enable a second NeoPixel Preset Color menu option + #if ENABLED(LED_COLOR_PRESETS) + #define LED_USER_PRESET_RED 255 // User defined RED value + #define LED_USER_PRESET_GREEN 128 // User defined GREEN value + #define LED_USER_PRESET_BLUE 0 // User defined BLUE value + #define LED_USER_PRESET_WHITE 255 // User defined WHITE value + #define LED_USER_PRESET_BRIGHTNESS 255 // User defined intensity + //#define LED_USER_PRESET_STARTUP // Have the printer display the user preset color on startup + #endif + #if ENABLED(NEO2_COLOR_PRESETS) + #define NEO2_USER_PRESET_RED 255 // User defined RED value + #define NEO2_USER_PRESET_GREEN 128 // User defined GREEN value + #define NEO2_USER_PRESET_BLUE 0 // User defined BLUE value + #define NEO2_USER_PRESET_WHITE 255 // User defined WHITE value + #define NEO2_USER_PRESET_BRIGHTNESS 255 // User defined intensity + //#define NEO2_USER_PRESET_STARTUP // Have the printer display the user preset color on startup for the second strip + #endif + #endif + +#endif // HAS_DISPLAY + +// Some displays offer Feedrate / Flow editing. +#if ANY(HAS_MARLINUI_MENU, DWIN_CREALITY_LCD, DWIN_LCD_PROUI, MALYAN_LCD, TOUCH_SCREEN, ULTIPANEL_FEEDMULTIPLY) + #define SPEED_EDIT_MIN 10 // (%) Feedrate percentage edit range minimum + #define SPEED_EDIT_MAX 999 // (%) Feedrate percentage edit range maximum +#endif +#if ANY(HAS_MARLINUI_MENU, DWIN_CREALITY_LCD, DWIN_LCD_PROUI, MALYAN_LCD, TOUCH_SCREEN) + #define FLOW_EDIT_MIN 10 // (%) Flow percentage edit range minimum + #define FLOW_EDIT_MAX 999 // (%) Flow percentage edit range maximum +#endif + +// Add 'M73' to set print job progress, overrides Marlin's built-in estimate +//#define SET_PROGRESS_MANUALLY +#if ENABLED(SET_PROGRESS_MANUALLY) + #define SET_PROGRESS_PERCENT // Add 'P' parameter to set percentage done + #define SET_REMAINING_TIME // Add 'R' parameter to set remaining time + //#define SET_INTERACTION_TIME // Add 'C' parameter to set time until next filament change or other user interaction + //#define M73_REPORT // Report M73 values to host + #if ALL(M73_REPORT, HAS_MEDIA) + #define M73_REPORT_SD_ONLY // Report only when printing from SD + #endif +#endif + +// LCD Print Progress options. Multiple times may be displayed in turn. +#if HAS_DISPLAY && ANY(HAS_MEDIA, SET_PROGRESS_MANUALLY) + #define SHOW_PROGRESS_PERCENT // Show print progress percentage (doesn't affect progress bar) + #define SHOW_ELAPSED_TIME // Display elapsed printing time (prefix 'E') + //#define SHOW_REMAINING_TIME // Display estimated time to completion (prefix 'R') + #if ENABLED(SET_INTERACTION_TIME) + #define SHOW_INTERACTION_TIME // Display time until next user interaction ('C' = filament change) + #endif + //#define PRINT_PROGRESS_SHOW_DECIMALS // Show/report progress with decimal digits, not all UIs support this + + #if ANY(HAS_MARLINUI_HD44780, IS_TFTGLCD_PANEL) + //#define LCD_PROGRESS_BAR // Show a progress bar on HD44780 LCDs for SD printing + #if ENABLED(LCD_PROGRESS_BAR) + #define PROGRESS_BAR_BAR_TIME 2000 // (ms) Amount of time to show the bar + #define PROGRESS_BAR_MSG_TIME 3000 // (ms) Amount of time to show the status message + #define PROGRESS_MSG_EXPIRE 0 // (ms) Amount of time to retain the status message (0=forever) + //#define PROGRESS_MSG_ONCE // Show the message for MSG_TIME then clear it + //#define LCD_PROGRESS_BAR_TEST // Add a menu item to test the progress bar + #endif + #endif +#endif + +#if HAS_MEDIA + /** + * SD Card SPI Speed + * May be required to resolve "volume init" errors. + * + * Enable and set to SPI_HALF_SPEED, SPI_QUARTER_SPEED, or SPI_EIGHTH_SPEED + * otherwise full speed will be applied. + * + * :['SPI_HALF_SPEED', 'SPI_QUARTER_SPEED', 'SPI_EIGHTH_SPEED'] + */ + //#define SD_SPI_SPEED SPI_HALF_SPEED + + // The standard SD detect circuit reads LOW when media is inserted and HIGH when empty. + // Enable this option and set to HIGH if your SD cards are incorrectly detected. + #define SD_DETECT_STATE LOW + + //#define SD_IGNORE_AT_STARTUP // Don't mount the SD card when starting up + //#define SDCARD_READONLY // Read-only SD card (to save over 2K of flash) + + //#define GCODE_REPEAT_MARKERS // Enable G-code M808 to set repeat markers and do looping + + #define SD_PROCEDURE_DEPTH 1 // Increase if you need more nested M32 calls + + #define SD_FINISHED_STEPPERRELEASE true // Disable steppers when SD Print is finished + #define SD_FINISHED_RELEASECOMMAND "M84" // Use "M84XYE" to keep Z enabled so your bed stays in place + + // Reverse SD sort to show "more recent" files first, according to the card's FAT. + // Since the FAT gets out of order with usage, SDCARD_SORT_ALPHA is recommended. + #define SDCARD_RATHERRECENTFIRST + + #define SD_MENU_CONFIRM_START // Confirm the selected SD file before printing + + //#define NO_SD_AUTOSTART // Remove auto#.g file support completely to save some Flash, SRAM + //#define MENU_ADDAUTOSTART // Add a menu option to run auto#.g files + + //#define ONE_CLICK_PRINT // Prompt to print the newest file on inserted media + //#define BROWSE_MEDIA_ON_INSERT // Open the file browser when media is inserted + + //#define MEDIA_MENU_AT_TOP // Force the media menu to be listed on the top of the main menu + + #define EVENT_GCODE_SD_ABORT "G28XY" // G-code to run on SD Abort Print (e.g., "G28XY" or "G27") + + #if ENABLED(PRINTER_EVENT_LEDS) + #define PE_LEDS_COMPLETED_TIME (30*60) // (seconds) Time to keep the LED "done" color before restoring normal illumination + #endif + + /** + * Continue after Power-Loss (Creality3D) + * + * Store the current state to the SD Card at the start of each layer + * during SD printing. If the recovery file is found at boot time, present + * an option on the LCD screen to continue the print from the last-known + * point in the file. + */ + //#define POWER_LOSS_RECOVERY + #if ENABLED(POWER_LOSS_RECOVERY) + #define PLR_ENABLED_DEFAULT false // Power-Loss Recovery enabled by default. (Set with 'M413 Sn' & M500) + //#define PLR_BED_THRESHOLD BED_MAXTEMP // (°C) Skip user confirmation at or above this bed temperature (0 to disable) + + //#define POWER_LOSS_PIN 44 // Pin to detect power-loss. Set to -1 to disable default pin on boards without module, or comment to use board default. + //#define POWER_LOSS_STATE HIGH // State of pin indicating power-loss + //#define POWER_LOSS_PULLUP // Set pullup / pulldown as appropriate for your sensor + //#define POWER_LOSS_PULLDOWN + + //#define POWER_LOSS_ZRAISE 2 // (mm) Z axis raise on resume (on power-loss with UPS) + //#define POWER_LOSS_PURGE_LEN 20 // (mm) Length of filament to purge on resume + + // Without a POWER_LOSS_PIN the following option helps reduce wear on the SD card, + // especially with "vase mode" printing. Set too high and vases cannot be continued. + #define POWER_LOSS_MIN_Z_CHANGE 0.05 // (mm) Minimum Z change before saving power-loss data + + //#define BACKUP_POWER_SUPPLY // Backup power / UPS to move the steppers on power-loss + #if ENABLED(BACKUP_POWER_SUPPLY) + //#define POWER_LOSS_RETRACT_LEN 10 // (mm) Length of filament to retract on fail + #endif + + // Enable if Z homing is needed for proper recovery. 99.9% of the time this should be disabled! + //#define POWER_LOSS_RECOVER_ZHOME + #if ENABLED(POWER_LOSS_RECOVER_ZHOME) + //#define POWER_LOSS_ZHOME_POS { 0, 0 } // Safe XY position to home Z while avoiding objects on the bed + #endif + #endif + + /** + * Sort SD file listings in alphabetical order. + * + * With this option enabled, items on SD cards will be sorted + * by name for easier navigation. + * + * By default... + * + * - Use the slowest -but safest- method for sorting. + * - Folders are sorted to the top. + * - The sort key is statically allocated. + * - No added G-code (M34) support. + * - 40 item sorting limit. (Items after the first 40 are unsorted.) + * + * SD sorting uses static allocation (as set by SDSORT_LIMIT), allowing the + * compiler to calculate the worst-case usage and throw an error if the SRAM + * limit is exceeded. + * + * - SDSORT_USES_RAM provides faster sorting via a static directory buffer. + * - SDSORT_USES_STACK does the same, but uses a local stack-based buffer. + * - SDSORT_CACHE_NAMES will retain the sorted file listing in RAM. (Expensive!) + * - SDSORT_DYNAMIC_RAM only uses RAM when the SD menu is visible. (Use with caution!) + */ + //#define SDCARD_SORT_ALPHA + + // SD Card Sorting options + #if ENABLED(SDCARD_SORT_ALPHA) + #define SDSORT_REVERSE false // Default to sorting file names in reverse order. + #define SDSORT_LIMIT 40 // Maximum number of sorted items (10-256). Costs 27 bytes each. + #define SDSORT_FOLDERS -1 // -1=above 0=none 1=below + #define SDSORT_GCODE false // Enable G-code M34 to set sorting behaviors: M34 S<-1|0|1> F<-1|0|1> + #define SDSORT_USES_RAM false // Pre-allocate a static array for faster pre-sorting. + #define SDSORT_USES_STACK false // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.) + #define SDSORT_CACHE_NAMES false // Keep sorted items in RAM longer for speedy performance. Most expensive option. + #define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! + #define SDSORT_CACHE_VFATS 2 // Maximum number of 13-byte VFAT entries to use for sorting. + // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM. + #endif + + // Allow international symbols in long filenames. To display correctly, the + // LCD's font must contain the characters. Check your selected LCD language. + //#define UTF_FILENAME_SUPPORT + + //#define LONG_FILENAME_HOST_SUPPORT // Get the long filename of a file/folder with 'M33 ' and list long filenames with 'M20 L' + //#define LONG_FILENAME_WRITE_SUPPORT // Create / delete files with long filenames via M28, M30, and Binary Transfer Protocol + //#define M20_TIMESTAMP_SUPPORT // Include timestamps by adding the 'T' flag to M20 commands + + #define SCROLL_LONG_FILENAMES // Scroll long filenames in the SD card menu + + //#define SD_ABORT_NO_COOLDOWN // Leave the heaters on after Stop Print (not recommended!) + + /** + * Abort SD printing when any endstop is triggered. + * This feature is enabled with 'M540 S1' or from the LCD menu. + * Endstops must be activated for this option to work. + */ + //#define SD_ABORT_ON_ENDSTOP_HIT + #if ENABLED(SD_ABORT_ON_ENDSTOP_HIT) + //#define SD_ABORT_ON_ENDSTOP_HIT_GCODE "G28XY" // G-code to run on endstop hit (e.g., "G28XY" or "G27") + #endif + + //#define SD_REPRINT_LAST_SELECTED_FILE // On print completion open the LCD Menu and select the same file + + //#define AUTO_REPORT_SD_STATUS // Auto-report media status with 'M27 S' + + /** + * Support for USB thumb drives using an Arduino USB Host Shield or + * equivalent MAX3421E breakout board. The USB thumb drive will appear + * to Marlin as an SD card. + * + * The MAX3421E can be assigned the same pins as the SD card reader, with + * the following pin mapping: + * + * SCLK, MOSI, MISO --> SCLK, MOSI, MISO + * INT --> SD_DETECT_PIN [1] + * SS --> SD_SS_PIN + * + * [1] On AVR an interrupt-capable pin is best for UHS3 compatibility. + */ + //#define USB_FLASH_DRIVE_SUPPORT + #if ENABLED(USB_FLASH_DRIVE_SUPPORT) + /** + * USB Host Shield Library + * + * - UHS2 uses no interrupts and has been production-tested + * on a LulzBot TAZ Pro with a 32-bit Archim board. + * + * - UHS3 is newer code with better USB compatibility. But it + * is less tested and is known to interfere with Servos. + * [1] This requires USB_INTR_PIN to be interrupt-capable. + */ + //#define USE_UHS2_USB + //#define USE_UHS3_USB + + #define DISABLE_DUE_SD_MMC // Disable USB Host access to USB Drive to prevent hangs on block access for DUE platform + + /** + * Native USB Host supported by some boards (USB OTG) + */ + //#define USE_OTG_USB_HOST + + #if DISABLED(USE_OTG_USB_HOST) + #define USB_CS_PIN SD_SS_PIN + #define USB_INTR_PIN SD_DETECT_PIN + #endif + #endif + + /** + * When using a bootloader that supports SD-Firmware-Flashing, + * add a menu item to activate SD-FW-Update on the next reboot. + * + * Requires ATMEGA2560 (Arduino Mega) + * + * Tested with this bootloader: + * https://github.com/FleetProbe/MicroBridge-Arduino-ATMega2560 + */ + //#define SD_FIRMWARE_UPDATE + #if ENABLED(SD_FIRMWARE_UPDATE) + #define SD_FIRMWARE_UPDATE_EEPROM_ADDR 0x1FF + #define SD_FIRMWARE_UPDATE_ACTIVE_VALUE 0xF0 + #define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF + #endif + + /** + * Enable this option if you have more than ~3K of unused flash space. + * Marlin will embed all settings in the firmware binary as compressed data. + * Use 'M503 C' to write the settings out to the SD Card as 'mc.zip'. + * See docs/ConfigEmbedding.md for details on how to use 'mc-apply.py'. + */ + //#define CONFIGURATION_EMBEDDING + + // Add an optimized binary file transfer mode, initiated with 'M28 B1' + //#define BINARY_FILE_TRANSFER + + #if ENABLED(BINARY_FILE_TRANSFER) + // Include extra facilities (e.g., 'M20 F') supporting firmware upload via BINARY_FILE_TRANSFER + //#define CUSTOM_FIRMWARE_UPLOAD + #endif + + // "Over-the-air" Firmware Update with M936 - Required to set EEPROM flag + //#define OTA_FIRMWARE_UPDATE + + /** + * Set this option to one of the following (or the board's defaults apply): + * + * LCD - Use the SD drive in the external LCD controller. + * ONBOARD - Use the SD drive on the control board. + * CUSTOM_CABLE - Use a custom cable to access the SD (as defined in a pins file). + * + * :[ 'LCD', 'ONBOARD', 'CUSTOM_CABLE' ] + */ + //#define SDCARD_CONNECTION LCD + + // Enable if SD detect is rendered useless (e.g., by using an SD extender) + //#define NO_SD_DETECT + + /** + * Multiple volume support - EXPERIMENTAL. + * Adds 'M21 Pm' / 'M21 S' / 'M21 U' to mount SD Card / USB Drive. + */ + //#define MULTI_VOLUME + #if ENABLED(MULTI_VOLUME) + #define VOLUME_SD_ONBOARD + #define VOLUME_USB_FLASH_DRIVE + #define DEFAULT_VOLUME SD_ONBOARD // :[ 'SD_ONBOARD', 'USB_FLASH_DRIVE' ] + #define DEFAULT_SHARED_VOLUME USB_FLASH_DRIVE // :[ 'SD_ONBOARD', 'USB_FLASH_DRIVE' ] + #endif + +#endif // HAS_MEDIA + +/** + * By default an onboard SD card reader may be shared as a USB mass- + * storage device. This option hides the SD card from the host PC. + */ +//#define NO_SD_HOST_DRIVE // Disable SD Card access over USB (for security). + +/** + * Additional options for Graphical Displays + * + * Use the optimizations here to improve printing performance, + * which can be adversely affected by graphical display drawing, + * especially when doing several short moves, and when printing + * on DELTA and SCARA machines. + * + * Some of these options may result in the display lagging behind + * controller events, as there is a trade-off between reliable + * printing performance versus fast display updates. + */ +#if HAS_MARLINUI_U8GLIB + // Save many cycles by drawing a hollow frame or no frame on the Info Screen + //#define XYZ_NO_FRAME + #define XYZ_HOLLOW_FRAME + + // A bigger font is available for edit items. Costs 3120 bytes of flash. + // Western only. Not available for Cyrillic, Kana, Turkish, Greek, or Chinese. + //#define USE_BIG_EDIT_FONT + + // A smaller font may be used on the Info Screen. Costs 2434 bytes of flash. + // Western only. Not available for Cyrillic, Kana, Turkish, Greek, or Chinese. + //#define USE_SMALL_INFOFONT + + /** + * ST7920-based LCDs can emulate a 16 x 4 character display using + * the ST7920 character-generator for very fast screen updates. + * Enable LIGHTWEIGHT_UI to use this special display mode. + * + * Since LIGHTWEIGHT_UI has limited space, the position and status + * message occupy the same line. Set STATUS_EXPIRE_SECONDS to the + * length of time to display the status message before clearing. + * + * Set STATUS_EXPIRE_SECONDS to zero to never clear the status. + * This will prevent position updates from being displayed. + */ + #if IS_U8GLIB_ST7920 + // Enable this option and reduce the value to optimize screen updates. + // The normal delay is 10µs. Use the lowest value that still gives a reliable display. + //#define DOGM_SPI_DELAY_US 5 // (µs) Delay after each SPI transfer + + //#define LIGHTWEIGHT_UI + #if ENABLED(LIGHTWEIGHT_UI) + #define STATUS_EXPIRE_SECONDS 20 + #endif + #endif + + /** + * Status (Info) Screen customization + * These options may affect code size and screen render time. + * Custom status screens can forcibly override these settings. + */ + //#define STATUS_COMBINE_HEATERS // Use combined heater images instead of separate ones + //#define STATUS_HOTEND_NUMBERLESS // Use plain hotend icons instead of numbered ones (with 2+ hotends) + #define STATUS_HOTEND_INVERTED // Show solid nozzle bitmaps when heating (Requires STATUS_HOTEND_ANIM for numbered hotends) + #define STATUS_HOTEND_ANIM // Use a second bitmap to indicate hotend heating + #define STATUS_BED_ANIM // Use a second bitmap to indicate bed heating + #define STATUS_CHAMBER_ANIM // Use a second bitmap to indicate chamber heating + //#define STATUS_CUTTER_ANIM // Use a second bitmap to indicate spindle / laser active + //#define STATUS_COOLER_ANIM // Use a second bitmap to indicate laser cooling + //#define STATUS_FLOWMETER_ANIM // Use multiple bitmaps to indicate coolant flow + //#define STATUS_ALT_BED_BITMAP // Use the alternative bed bitmap + //#define STATUS_ALT_FAN_BITMAP // Use the alternative fan bitmap + //#define STATUS_FAN_FRAMES 3 // :[0,1,2,3,4] Number of fan animation frames + + // Only one STATUS_HEAT_* option can be enabled + //#define STATUS_HEAT_PERCENT // Show heating in a progress bar + //#define STATUS_HEAT_POWER // Show heater output power as a vertical bar + +#endif // HAS_MARLINUI_U8GLIB + +#if HAS_MARLINUI_U8GLIB || IS_DWIN_MARLINUI + #define MENU_HOLLOW_FRAME // Enable to save many cycles by drawing a hollow frame on Menu Screens + //#define OVERLAY_GFX_REVERSE // Swap the CW/CCW indicators in the graphics overlay + + // Frivolous Game Options + //#define MARLIN_BRICKOUT + //#define MARLIN_INVADERS + //#define MARLIN_SNAKE + //#define GAMES_EASTER_EGG // Add extra blank lines above the "Games" sub-menu +#endif + +// +// Additional options for DGUS / DWIN displays +// +#if HAS_DGUS_LCD + #define LCD_BAUDRATE 115200 + + #define DGUS_RX_BUFFER_SIZE 128 + #define DGUS_TX_BUFFER_SIZE 48 + //#define SERIAL_STATS_RX_BUFFER_OVERRUNS // Fix Rx overrun situation (Currently only for AVR) + + #define DGUS_UPDATE_INTERVAL_MS 500 // (ms) Interval between automatic screen updates + + #if DGUS_UI_IS(FYSETC, MKS, HIPRECY) + #define DGUS_PRINT_FILENAME // Display the filename during printing + #define DGUS_PREHEAT_UI // Display a preheat screen during heatup + + #if DGUS_UI_IS(FYSETC, MKS) + //#define DGUS_UI_MOVE_DIS_OPTION // Disabled by default for FYSETC and MKS + #else + #define DGUS_UI_MOVE_DIS_OPTION // Enabled by default for UI_HIPRECY + #endif + + #define DGUS_FILAMENT_LOADUNLOAD + #if ENABLED(DGUS_FILAMENT_LOADUNLOAD) + #define DGUS_FILAMENT_PURGE_LENGTH 10 + #define DGUS_FILAMENT_LOAD_LENGTH_PER_TIME 0.5 // (mm) Adjust in proportion to DGUS_UPDATE_INTERVAL_MS + #endif + + #define DGUS_UI_WAITING // Show a "waiting" screen between some screens + #if ENABLED(DGUS_UI_WAITING) + #define DGUS_UI_WAITING_STATUS 10 + #define DGUS_UI_WAITING_STATUS_PERIOD 8 // Increase to slower waiting status looping + #endif + + #elif DGUS_UI_IS(E3S1PRO) + /** + * The stock Ender-3 S1 Pro/Plus display firmware has rather poor SD file handling. + * + * The autoscroll is mainly useful for status messages, filenames, and the "About" page. + * + * NOTE: The Advanced SD Card option is affected by the stock touchscreen firmware, so + * pages 5 and up will display "4/4". This may get fixed in a screen firmware update. + */ + #define DGUS_SOFTWARE_AUTOSCROLL // Enable long text software auto-scroll + #define DGUS_AUTOSCROLL_START_CYCLES 1 // Refresh cycles without scrolling at the beginning of text strings + #define DGUS_AUTOSCROLL_END_CYCLES 1 // ... at the end of text strings + + #define DGUS_ADVANCED_SDCARD // Allow more than 20 files and navigating directories + #define DGUS_USERCONFIRM // Reuse the SD Card page to show various messages + #endif +#endif // HAS_DGUS_LCD + +// +// Additional options for AnyCubic Chiron TFT displays +// +#if ENABLED(ANYCUBIC_LCD_CHIRON) + // By default the type of panel is automatically detected. + // Enable one of these options if you know the panel type. + //#define CHIRON_TFT_STANDARD + //#define CHIRON_TFT_NEW + + // Enable the longer Anycubic powerup startup tune + //#define AC_DEFAULT_STARTUP_TUNE + + /** + * Display Folders + * By default the file browser lists all G-code files (including those in subfolders) in a flat list. + * Enable this option to display a hierarchical file browser. + * + * NOTES: + * - Without this option it helps to enable SDCARD_SORT_ALPHA so files are sorted before/after folders. + * - When used with the "new" panel, folder names will also have '.gcode' appended to their names. + * This hack is currently required to force the panel to show folders. + */ + #define AC_SD_FOLDER_VIEW +#endif + +// +// Specify additional languages for the UI. Default specified by LCD_LANGUAGE. +// +#if ANY(DOGLCD, TFT_COLOR_UI, TOUCH_UI_FTDI_EVE, IS_DWIN_MARLINUI, ANYCUBIC_LCD_VYPER) + //#define LCD_LANGUAGE_2 fr + //#define LCD_LANGUAGE_3 de + //#define LCD_LANGUAGE_4 es + //#define LCD_LANGUAGE_5 it + #ifdef LCD_LANGUAGE_2 + //#define LCD_LANGUAGE_AUTO_SAVE // Automatically save language to EEPROM on change + #endif +#endif + +// +// Touch UI for the FTDI Embedded Video Engine (EVE) +// +#if ENABLED(TOUCH_UI_FTDI_EVE) + // Display board used + //#define LCD_FTDI_VM800B35A // FTDI 3.5" with FT800 (320x240) + //#define LCD_4DSYSTEMS_4DLCD_FT843 // 4D Systems 4.3" (480x272) + //#define LCD_HAOYU_FT800CB // Haoyu with 4.3" or 5" (480x272) + //#define LCD_HAOYU_FT810CB // Haoyu with 5" (800x480) + //#define LCD_LULZBOT_CLCD_UI // LulzBot Color LCD UI + //#define LCD_FYSETC_TFT81050 // FYSETC with 5" (800x480) + //#define LCD_EVE3_50G // Matrix Orbital 5.0", 800x480, BT815 + //#define LCD_EVE2_50G // Matrix Orbital 5.0", 800x480, FT813 + + // Correct the resolution if not using the stock TFT panel. + //#define TOUCH_UI_320x240 + //#define TOUCH_UI_480x272 + //#define TOUCH_UI_800x480 + + // Mappings for boards with a standard RepRapDiscount Display connector + //#define AO_EXP1_PINMAP // LulzBot CLCD UI EXP1 mapping + //#define AO_EXP2_PINMAP // LulzBot CLCD UI EXP2 mapping + //#define CR10_TFT_PINMAP // Rudolph Riedel's CR10 pin mapping + //#define S6_TFT_PINMAP // FYSETC S6 pin mapping + //#define F6_TFT_PINMAP // FYSETC F6 pin mapping + + //#define OTHER_PIN_LAYOUT // Define pins manually below + #if ENABLED(OTHER_PIN_LAYOUT) + // Pins for CS and MOD_RESET (PD) must be chosen + #define CLCD_MOD_RESET 9 + #define CLCD_SPI_CS 10 + + // If using software SPI, specify pins for SCLK, MOSI, MISO + //#define CLCD_USE_SOFT_SPI + #if ENABLED(CLCD_USE_SOFT_SPI) + #define CLCD_SOFT_SPI_MOSI 11 + #define CLCD_SOFT_SPI_MISO 12 + #define CLCD_SOFT_SPI_SCLK 13 + #endif + #endif + + // Display Orientation. An inverted (i.e. upside-down) display + // is supported on the FT800. The FT810 and beyond also support + // portrait and mirrored orientations. + //#define TOUCH_UI_INVERTED + //#define TOUCH_UI_PORTRAIT + //#define TOUCH_UI_MIRRORED + + // UTF8 processing and rendering. + // Unsupported characters are shown as '?'. + //#define TOUCH_UI_USE_UTF8 + #if ENABLED(TOUCH_UI_USE_UTF8) + // Western accents support. These accented characters use + // combined bitmaps and require relatively little storage. + #define TOUCH_UI_UTF8_WESTERN_CHARSET + #if ENABLED(TOUCH_UI_UTF8_WESTERN_CHARSET) + // Additional character groups. These characters require + // full bitmaps and take up considerable storage: + //#define TOUCH_UI_UTF8_SUPERSCRIPTS // ¹ ² ³ + //#define TOUCH_UI_UTF8_COPYRIGHT // © ® + //#define TOUCH_UI_UTF8_GERMANIC // ß + //#define TOUCH_UI_UTF8_SCANDINAVIAN // Æ Ð Ø Þ æ ð ø þ + //#define TOUCH_UI_UTF8_PUNCTUATION // « » ¿ ¡ + //#define TOUCH_UI_UTF8_CURRENCY // ¢ £ ¤ ¥ + //#define TOUCH_UI_UTF8_ORDINALS // º ª + //#define TOUCH_UI_UTF8_MATHEMATICS // ± × ÷ + //#define TOUCH_UI_UTF8_FRACTIONS // ¼ ½ ¾ + //#define TOUCH_UI_UTF8_SYMBOLS // µ ¶ ¦ § ¬ + #endif + + // Cyrillic character set, costs about 27KiB of flash + //#define TOUCH_UI_UTF8_CYRILLIC_CHARSET + #endif + + // Use a smaller font when labels don't fit buttons + #define TOUCH_UI_FIT_TEXT + + // Use a numeric passcode for "Screen lock" keypad. + // (recommended for smaller displays) + //#define TOUCH_UI_PASSCODE + + // Output extra debug info for Touch UI events + //#define TOUCH_UI_DEBUG + + // Developer menu (accessed by touching "About Printer" copyright text) + //#define TOUCH_UI_DEVELOPER_MENU +#endif // TOUCH_UI_FTDI_EVE + +// +// Classic UI Options +// +#if TFT_SCALED_DOGLCD + //#define TFT_MARLINUI_COLOR 0xFFFF // White + //#define TFT_MARLINBG_COLOR 0x0000 // Black + //#define TFT_DISABLED_COLOR 0x0003 // Almost black + //#define TFT_BTCANCEL_COLOR 0xF800 // Red + //#define TFT_BTARROWS_COLOR 0xDEE6 // 11011 110111 00110 Yellow + //#define TFT_BTOKMENU_COLOR 0x145F // 00010 100010 11111 Cyan +#endif + +/** + * Display Sleep + * Enable this option to save energy and prevent OLED pixel burn-in. + */ +//#define DISPLAY_SLEEP_MINUTES 2 // (minutes) Timeout before turning off the screen + +/** + * LCD Backlight Timeout + * Requires a display with a controllable backlight + */ +//#define LCD_BACKLIGHT_TIMEOUT_MINS 1 // (minutes) Timeout before turning off the backlight + +#if defined(DISPLAY_SLEEP_MINUTES) || defined(LCD_BACKLIGHT_TIMEOUT_MINS) + #define EDITABLE_DISPLAY_TIMEOUT // Edit sleep / backlight timeout with M255 S and a menu item +#endif + +// +// ADC Button Debounce +// +#if HAS_ADC_BUTTONS + #define ADC_BUTTON_DEBOUNCE_DELAY 16 // (count) Increase if buttons bounce or repeat too fast +#endif + +//#define FAST_BUTTON_POLLING // Poll buttons at ~1kHz on 8-bit AVR. Set to 'false' for slow polling on 32-bit. + +// @section safety + +/** + * The watchdog hardware timer will do a reset and disable all outputs + * if the firmware gets too overloaded to read the temperature sensors. + * + * If you find that watchdog reboot causes your AVR board to hang forever, + * enable WATCHDOG_RESET_MANUAL to use a custom timer instead of WDTO. + * NOTE: This method is less reliable as it can only catch hangups while + * interrupts are enabled. + */ +#define USE_WATCHDOG +#if ENABLED(USE_WATCHDOG) + //#define WATCHDOG_RESET_MANUAL +#endif + +// @section lcd + +/** + * Babystepping enables movement of the axes by tiny increments without changing + * the current position values. This feature is used primarily to adjust the Z + * axis in the first layer of a print in real-time. + * + * Warning: Does not respect endstops! + */ +//#define BABYSTEPPING +#if ENABLED(BABYSTEPPING) + //#define EP_BABYSTEPPING // M293/M294 babystepping with EMERGENCY_PARSER support + //#define BABYSTEP_WITHOUT_HOMING + //#define BABYSTEP_ALWAYS_AVAILABLE // Allow babystepping at all times (not just during movement) + //#define BABYSTEP_XY // Also enable X/Y Babystepping. Not supported on DELTA! + //#define BABYSTEP_INVERT_Z // Enable if Z babysteps should go the other way + //#define BABYSTEP_MILLIMETER_UNITS // Specify BABYSTEP_MULTIPLICATOR_(XY|Z) in mm instead of micro-steps + #define BABYSTEP_MULTIPLICATOR_Z 1 // (steps or mm) Steps or millimeter distance for each Z babystep + #define BABYSTEP_MULTIPLICATOR_XY 1 // (steps or mm) Steps or millimeter distance for each XY babystep + + //#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen for Z Babystepping. + #if ENABLED(DOUBLECLICK_FOR_Z_BABYSTEPPING) + #define DOUBLECLICK_MAX_INTERVAL 1250 // (ms) Maximum interval between clicks. + // Note: Extra time may be added to mitigate controller latency. + //#define MOVE_Z_WHEN_IDLE // Jump to the move Z menu on double-click when printer is idle. + #if ENABLED(MOVE_Z_WHEN_IDLE) + #define MOVE_Z_IDLE_MULTIPLICATOR 1 // Multiply 1mm by this factor for the move step size. + #endif + #endif + + //#define BABYSTEP_DISPLAY_TOTAL // Display total babysteps since last G28 + + //#define BABYSTEP_ZPROBE_OFFSET // Combine M851 Z and Babystepping + #if ENABLED(BABYSTEP_ZPROBE_OFFSET) + //#define BABYSTEP_HOTEND_Z_OFFSET // For multiple hotends, babystep relative Z offsets + //#define BABYSTEP_GFX_OVERLAY // Enable graphical overlay on Z-offset editor + #endif +#endif + +// @section extruder + +/** + * Linear Pressure Control v1.5 + * + * Assumption: advance [steps] = k * (delta velocity [steps/s]) + * K=0 means advance disabled. + * + * NOTE: K values for LIN_ADVANCE 1.5 differ from earlier versions! + * + * Set K around 0.22 for 3mm PLA Direct Drive with ~6.5cm between the drive gear and heatbreak. + * Larger K values will be needed for flexible filament and greater distances. + * If this algorithm produces a higher speed offset than the extruder can handle (compared to E jerk) + * print acceleration will be reduced during the affected moves to keep within the limit. + * + * See https://marlinfw.org/docs/features/lin_advance.html for full instructions. + */ +//#define LIN_ADVANCE +#if ENABLED(LIN_ADVANCE) + #if ENABLED(DISTINCT_E_FACTORS) + #define ADVANCE_K { 0.22 } // (mm) Compression length per 1mm/s extruder speed, per extruder + #else + #define ADVANCE_K 0.22 // (mm) Compression length applying to all extruders + #endif + //#define ADVANCE_K_EXTRA // Add a second linear advance constant, configurable with M900 L. + //#define LA_DEBUG // Print debug information to serial during operation. Disable for production use. + //#define EXPERIMENTAL_I2S_LA // Allow I2S_STEPPER_STREAM to be used with LA. Performance degrades as the LA step rate reaches ~20kHz. + + //#define SMOOTH_LIN_ADVANCE // Remove limits on acceleration by gradual increase of nozzle pressure + #if ENABLED(SMOOTH_LIN_ADVANCE) + /** + * ADVANCE_TAU is also the time ahead that the smoother needs to look + * into the planner, so the planner needs to have enough blocks loaded. + * For k=0.04 at 10k acceleration and an "Orbiter 2" extruder it can be as low as 0.0075. + * Adjust by lowering the value until you observe the extruder skipping, then raise slightly. + * Higher k and higher XY acceleration may require larger ADVANCE_TAU to avoid skipping steps. + */ + #if ENABLED(DISTINCT_E_FACTORS) + #define ADVANCE_TAU { 0.02 } // (s) Smoothing time to reduce extruder acceleration, per extruder + #else + #define ADVANCE_TAU 0.02 // (s) Smoothing time to reduce extruder acceleration + #endif + #define SMOOTH_LIN_ADV_HZ 1000 // (Hz) How often to update extruder speed + #define INPUT_SHAPING_E_SYNC // Synchronize the extruder-shaped XY axes (to increase precision) + #endif +#endif + +/** + * Nonlinear Extrusion Control + * + * Control extrusion rate based on instantaneous extruder velocity. Can be used to correct for + * underextrusion at high extruder speeds that are otherwise well-behaved (i.e., not skipping). + * For better results also enable ADAPTIVE_STEP_SMOOTHING. + */ +//#define NONLINEAR_EXTRUSION +#if ENABLED(NONLINEAR_EXTRUSION) + //#define NONLINEAR_EXTRUSION_DEFAULT_ON // Enable if NLE should be ON by default +#endif + +// @section leveling + +/** + * Use Safe Bed Leveling coordinates to move axes to a useful position before bed probing. + * For example, after homing a rotational axis the Z probe might not be perpendicular to the bed. + * Choose values the orient the bed horizontally and the Z-probe vertically. + */ +//#define SAFE_BED_LEVELING_START_X 0.0 +//#define SAFE_BED_LEVELING_START_Y 0.0 +//#define SAFE_BED_LEVELING_START_Z 0.0 +//#define SAFE_BED_LEVELING_START_I 0.0 +//#define SAFE_BED_LEVELING_START_J 0.0 +//#define SAFE_BED_LEVELING_START_K 0.0 +//#define SAFE_BED_LEVELING_START_U 0.0 +//#define SAFE_BED_LEVELING_START_V 0.0 +//#define SAFE_BED_LEVELING_START_W 0.0 + +/** + * Points to probe for all 3-point Leveling procedures. + * Override if the automatically selected points are inadequate. + */ +#if NEEDS_THREE_PROBE_POINTS + //#define PROBE_PT_1 { 15, 180 } // (mm) { x, y } + //#define PROBE_PT_2 { 15, 20 } + //#define PROBE_PT_3 { 170, 20 } +#endif + +/** + * Probing Margins + * + * Override PROBING_MARGIN for each side of the build plate + * Useful to get probe points to exact positions on targets or + * to allow leveling to avoid plate clamps on only specific + * sides of the bed. With NOZZLE_AS_PROBE negative values are + * allowed, to permit probing outside the bed. + * + * If you are replacing the prior *_PROBE_BED_POSITION options, + * LEFT and FRONT values in most cases will map directly over + * RIGHT and REAR would be the inverse such as + * (X/Y_BED_SIZE - RIGHT/BACK_PROBE_BED_POSITION) + * + * This will allow all positions to match at compilation, however + * should the probe position be modified with M851XY then the + * probe points will follow. This prevents any change from causing + * the probe to be unable to reach any points. + */ +#if PROBE_SELECTED && !IS_KINEMATIC + //#define PROBING_MARGIN_LEFT PROBING_MARGIN + //#define PROBING_MARGIN_RIGHT PROBING_MARGIN + //#define PROBING_MARGIN_FRONT PROBING_MARGIN + //#define PROBING_MARGIN_BACK PROBING_MARGIN +#endif + +#if ANY(MESH_BED_LEVELING, AUTO_BED_LEVELING_UBL) + // Override the mesh area if the automatic (max) area is too large + //#define MESH_MIN_X MESH_INSET + //#define MESH_MIN_Y MESH_INSET + //#define MESH_MAX_X X_BED_SIZE - (MESH_INSET) + //#define MESH_MAX_Y Y_BED_SIZE - (MESH_INSET) +#endif + +#if ALL(AUTO_BED_LEVELING_UBL, EEPROM_SETTINGS) + //#define OPTIMIZED_MESH_STORAGE // Store mesh with less precision to save EEPROM space +#endif + +/** + * Repeatedly attempt G29 leveling until it succeeds. + * Stop after G29_MAX_RETRIES attempts. + */ +//#define G29_RETRY_AND_RECOVER +#if ENABLED(G29_RETRY_AND_RECOVER) + #define G29_MAX_RETRIES 3 + #define G29_HALT_ON_FAILURE + /** + * Specify the GCODE commands that will be executed when leveling succeeds, + * between attempts, and after the maximum number of retries have been tried. + */ + #define G29_SUCCESS_COMMANDS "M117 Bed leveling done." + #define G29_RECOVER_COMMANDS "M117 Probe failed. Rewiping.\nG28\nG12 P0 S12 T0" + #define G29_FAILURE_COMMANDS "M117 Bed leveling failed.\nG0 Z10\nM300 P25 S880\nM300 P50 S0\nM300 P25 S880\nM300 P50 S0\nM300 P25 S880\nM300 P50 S0\nG4 S1" + +#endif + +// @section probes + +/** + * Thermal Probe Compensation + * + * Adjust probe measurements to compensate for distortion associated with the temperature + * of the probe, bed, and/or hotend. + * Use G76 to automatically calibrate this feature for probe and bed temperatures. + * (Extruder temperature/offset values must be calibrated manually.) + * Use M871 to set temperature/offset values manually. + * For more details see https://marlinfw.org/docs/features/probe_temp_compensation.html + */ +//#define PTC_PROBE // Compensate based on probe temperature +//#define PTC_BED // Compensate based on bed temperature +//#define PTC_HOTEND // Compensate based on hotend temperature + +#if ANY(PTC_PROBE, PTC_BED, PTC_HOTEND) + /** + * If the probe is outside the defined range, use linear extrapolation with the closest + * point and the point with index PTC_LINEAR_EXTRAPOLATION. e.g., If set to 4 it will use the + * linear extrapolation between data[0] and data[4] for values below PTC_PROBE_START. + */ + //#define PTC_LINEAR_EXTRAPOLATION 4 + + #if ENABLED(PTC_PROBE) + // Probe temperature calibration generates a table of values starting at PTC_PROBE_START + // (e.g., 30), in steps of PTC_PROBE_RES (e.g., 5) with PTC_PROBE_COUNT (e.g., 10) samples. + #define PTC_PROBE_START 30 // (°C) + #define PTC_PROBE_RES 5 // (°C) + #define PTC_PROBE_COUNT 10 + #define PTC_PROBE_ZOFFS { 0 } // (µm) Z adjustments per sample + #endif + + #if ENABLED(PTC_BED) + // Bed temperature calibration builds a similar table. + #define PTC_BED_START 60 // (°C) + #define PTC_BED_RES 5 // (°C) + #define PTC_BED_COUNT 10 + #define PTC_BED_ZOFFS { 0 } // (µm) Z adjustments per sample + #endif + + #if ENABLED(PTC_HOTEND) + // Note: There is no automatic calibration for the hotend. Use M871. + #define PTC_HOTEND_START 180 // (°C) + #define PTC_HOTEND_RES 5 // (°C) + #define PTC_HOTEND_COUNT 20 + #define PTC_HOTEND_ZOFFS { 0 } // (µm) Z adjustments per sample + #endif + + // G76 options + #if ALL(PTC_PROBE, PTC_BED) + // Park position to wait for probe cooldown + #define PTC_PARK_POS { 0, 0, 100 } + + // Probe position to probe and wait for probe to reach target temperature + //#define PTC_PROBE_POS { 12.0f, 7.3f } // Example: MK52 magnetic heatbed + #define PTC_PROBE_POS { 90, 100 } + + // The temperature the probe should be at while taking measurements during + // bed temperature calibration. + #define PTC_PROBE_TEMP 30 // (°C) + + // Height above Z=0.0 to raise the nozzle. Lowering this can help the probe to heat faster. + // Note: The Z=0.0 offset is determined by the probe Z offset (e.g., as set with M851 Z). + #define PTC_PROBE_HEATING_OFFSET 0.5 // (mm) + #endif +#endif // PTC_PROBE || PTC_BED || PTC_HOTEND + +// @section extras + +// +// G60/G61 Position Save and Return +// +//#define SAVED_POSITIONS 1 // Each saved position slot costs 12 bytes + +// +// G2/G3 Arc Support +// +#define ARC_SUPPORT // Requires ~3226 bytes +#if ENABLED(ARC_SUPPORT) + #define MIN_ARC_SEGMENT_MM 0.1 // (mm) Minimum length of each arc segment + #define MAX_ARC_SEGMENT_MM 1.0 // (mm) Maximum length of each arc segment + #define MIN_CIRCLE_SEGMENTS 72 // Minimum number of segments in a complete circle + //#define ARC_SEGMENTS_PER_SEC 50 // Use the feedrate to choose the segment length + #define N_ARC_CORRECTION 25 // Number of interpolated segments between corrections + //#define ARC_P_CIRCLES // Enable the 'P' parameter to specify complete circles + //#define SF_ARC_FIX // Enable only if using SkeinForge with "Arc Point" fillet procedure +#endif + +// G5 Bézier Curve Support with XYZE destination and IJPQ offsets +//#define BEZIER_CURVE_SUPPORT // Requires ~2666 bytes + +#if ANY(ARC_SUPPORT, BEZIER_CURVE_SUPPORT) + //#define CNC_WORKSPACE_PLANES // Allow G2/G3/G5 to operate in XY, ZX, or YZ planes +#endif + +/** + * Direct Stepping + * + * Comparable to the method used by Klipper, G6 direct stepping significantly + * reduces motion calculations, increases top printing speeds, and results in + * less step aliasing by calculating all motions in advance. + * Preparing your G-code: https://github.com/colinrgodsey/step-daemon + */ +//#define DIRECT_STEPPING + +/** + * G38 Probe Target + * + * This option adds G38.2 and G38.3 (probe towards target) + * and optionally G38.4 and G38.5 (probe away from target). + * Set MULTIPLE_PROBING for G38 to probe more than once. + */ +//#define G38_PROBE_TARGET +#if ENABLED(G38_PROBE_TARGET) + //#define G38_PROBE_AWAY // Include G38.4 and G38.5 to probe away from target + #define G38_MINIMUM_MOVE 0.0275 // (mm) Minimum distance that will produce a move. +#endif + +// @section motion + +// Moves (or segments) with fewer steps than this will be joined with the next move +#define MIN_STEPS_PER_SEGMENT 6 + +/** + * Minimum delay before and after setting the stepper DIR (in ns) + * 0 : No delay (Expect at least 10µS since one Stepper ISR must transpire) + * 20 : Minimum for TMC2xxx drivers + * 200 : Minimum for A4988 drivers + * 400 : Minimum for A5984 drivers + * 500 : Minimum for LV8729 drivers (guess, no info in datasheet) + * 650 : Minimum for DRV8825 drivers + * 1500 : Minimum for TB6600 drivers (guess, no info in datasheet) + * 15000 : Minimum for TB6560 drivers (guess, no info in datasheet) + * + * Override the default value based on the driver type set in Configuration.h. + */ +//#define MINIMUM_STEPPER_POST_DIR_DELAY 650 +//#define MINIMUM_STEPPER_PRE_DIR_DELAY 650 + +/** + * Minimum stepper driver pulse width (in ns) + * If undefined, these defaults (from Conditionals-4-adv.h) apply: + * 100 : Minimum for TMC2xxx stepper drivers + * 500 : Minimum for LV8729 + * 1000 : Minimum for A4988 and A5984 stepper drivers + * 2000 : Minimum for DRV8825 stepper drivers + * 3000 : Minimum for TB6600 stepper drivers + * 30000 : Minimum for TB6560 stepper drivers + * + * Override the default value based on the driver type set in Configuration.h. + */ +//#define MINIMUM_STEPPER_PULSE_NS 2000 + +/** + * Maximum stepping rate (in Hz) the stepper driver allows + * If undefined, these defaults (from Conditionals-4-adv.h) apply: + * 5000000 : Maximum for TMC2xxx stepper drivers + * 1000000 : Maximum for LV8729 stepper driver + * 500000 : Maximum for A4988 stepper driver + * 250000 : Maximum for DRV8825 stepper driver + * 150000 : Maximum for TB6600 stepper driver + * 15000 : Maximum for TB6560 stepper driver + * + * Override the default value based on the driver type set in Configuration.h. + */ +//#define MAXIMUM_STEPPER_RATE 250000 + +// @section temperature + +// Control heater 0 and heater 1 in parallel. +//#define HEATERS_PARALLEL + +//=========================================================================== +//================================= Buffers ================================= +//=========================================================================== + +// @section gcode + +// The number of linear moves that can be in the planner at once. +#if ALL(HAS_MEDIA, DIRECT_STEPPING) + #define BLOCK_BUFFER_SIZE 8 +#elif HAS_MEDIA + #define BLOCK_BUFFER_SIZE 16 +#else + #define BLOCK_BUFFER_SIZE 16 +#endif + +// @section serial + +// The ASCII buffer for serial input +#define MAX_CMD_SIZE 96 +#define BUFSIZE 4 + +/** + * Host Transmit Buffer Size + * - Costs 386 bytes of flash and TX_BUFFER_SIZE+3 bytes of SRAM (if not 0). + * - 4 bytes required to buffer a simple "ok". + * - 32 bytes for ADVANCED_OK (M105). + * - 128 bytes for the optimal speed of 'debug-echo:' + * - Other output doesn't need to be that speedy. + * :[0, 2, 4, 8, 16, 32, 64, 128, 256] + */ +#define TX_BUFFER_SIZE 0 + +/** + * Host Receive Buffer Size + * Without XON/XOFF flow control (see SERIAL_XON_XOFF below) 32 bytes should be enough. + * To use flow control, set this buffer size to at least 1024 bytes. + * :[0, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048] + */ +//#define RX_BUFFER_SIZE 1024 + +#if RX_BUFFER_SIZE >= 1024 + // Enable to have the controller send XON/XOFF control characters to + // the host to signal the RX buffer is becoming full. + //#define SERIAL_XON_XOFF +#endif + +#if HAS_MEDIA + // Enable this option to collect and display the maximum + // RX queue usage after transferring a file to SD. + //#define SERIAL_STATS_MAX_RX_QUEUED + + // Enable this option to collect and display the number + // of dropped bytes after a file transfer to SD. + //#define SERIAL_STATS_DROPPED_RX +#endif + +// Monitor RX buffer usage +// Dump an error to the serial port if the serial receive buffer overflows. +// If you see these errors, increase the RX_BUFFER_SIZE value. +// Not supported on all platforms. +//#define RX_BUFFER_MONITOR + +/** + * Emergency Command Parser + * + * Add a low-level parser to intercept certain commands as they + * enter the serial receive buffer, so they cannot be blocked. + * Currently handles M108, M112, M410, M876 + * NOTE: Not yet implemented for all platforms. + */ +//#define EMERGENCY_PARSER + +/** + * Realtime Reporting (requires EMERGENCY_PARSER) + * + * - Report position and state of the machine (like Grbl). + * - Auto-report position during long moves. + * - Useful for CNC/LASER. + * + * Adds support for commands: + * S000 : Report State and Position while moving. + * P000 : Instant Pause / Hold while moving. + * R000 : Resume from Pause / Hold. + * + * - During Hold all Emergency Parser commands are available, as usual. + * - Enable NANODLP_Z_SYNC and NANODLP_ALL_AXIS for move command end-state reports. + */ +//#define REALTIME_REPORTING_COMMANDS +#if ENABLED(REALTIME_REPORTING_COMMANDS) + //#define FULL_REPORT_TO_HOST_FEATURE // Auto-report the machine status like Grbl CNC +#endif + +/** + * Bad Serial-connections can miss a received command by sending an 'ok' + * Therefore some clients abort after 30 seconds in a timeout. + * Some other clients start sending commands while receiving a 'wait'. + * This "wait" is only sent when the buffer is empty. 1 second is a good value here. + */ +//#define NO_TIMEOUTS 1000 // (ms) + +// Some clients will have this feature soon. This could make the NO_TIMEOUTS unnecessary. +//#define ADVANCED_OK + +// Printrun may have trouble receiving long strings all at once. +// This option inserts short delays between lines of serial output. +#define SERIAL_OVERRUN_PROTECTION + +// For serial echo, the number of digits after the decimal point +//#define SERIAL_FLOAT_PRECISION 4 + +/** + * This feature is EXPERIMENTAL so use with caution and test thoroughly. + * Enable this option to receive data on the serial ports via the onboard DMA + * controller for more stable and reliable high-speed serial communication. + * Support is currently limited to some STM32 MCUs and all HC32 MCUs. + * Note: This has no effect on emulated USB serial ports. + */ +//#define SERIAL_DMA + +/** + * Set the number of proportional font spaces required to fill up a typical character space. + * This can help to better align the output of commands like 'G29 O' Mesh Output. + * + * For clients that use a fixed-width font (like OctoPrint), leave this set to 1.0. + * Otherwise, adjust according to your client and font. + */ +#define PROPORTIONAL_FONT_RATIO 1.0 + +// @section extras + +/** + * Extra Fan Speed + * Adds a secondary fan speed for each print-cooling fan. + * 'M106 P T3-255' : Set a secondary speed for + * 'M106 P T2' : Use the set secondary speed + * 'M106 P T1' : Restore the previous fan speed + */ +//#define EXTRA_FAN_SPEED + +// @section gcode + +/** + * Firmware-based and LCD-controlled retract + * + * Add G10 / G11 commands for automatic firmware-based retract / recover. + * Use M207 and M208 to define parameters for retract / recover. + * + * Use M209 to enable or disable auto-retract. + * With auto-retract enabled, all G1 E moves within the set range + * will be converted to firmware-based retract/recover moves. + * + * Be sure to turn off auto-retract during filament change. + * + * Note that M207 / M208 / M209 settings are saved to EEPROM. + */ +//#define FWRETRACT +#if ENABLED(FWRETRACT) + #define FWRETRACT_AUTORETRACT // Override slicer retractions + #if ENABLED(FWRETRACT_AUTORETRACT) + #define MIN_AUTORETRACT 0.1 // (mm) Don't convert E moves under this length + #define MAX_AUTORETRACT 10.0 // (mm) Don't convert E moves over this length + #endif + #define RETRACT_LENGTH 3 // (mm) Default retract length (positive value) + #define RETRACT_LENGTH_SWAP 13 // (mm) Default swap retract length (positive value) + #define RETRACT_FEEDRATE 45 // (mm/s) Default feedrate for retracting + #define RETRACT_ZRAISE 0 // (mm) Default retract Z-raise + #define RETRACT_RECOVER_LENGTH 0 // (mm) Default additional recover length (added to retract length on recover) + #define RETRACT_RECOVER_LENGTH_SWAP 0 // (mm) Default additional swap recover length (added to retract length on recover from toolchange) + #define RETRACT_RECOVER_FEEDRATE 8 // (mm/s) Default feedrate for recovering from retraction + #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // (mm/s) Default feedrate for recovering from swap retraction + #if ENABLED(MIXING_EXTRUDER) + //#define RETRACT_SYNC_MIXING // Retract and restore all mixing steppers simultaneously + #endif +#endif + +// @section tool change + +/** + * Universal tool change settings. + * Applies to all types of extruders except where explicitly noted. + */ +#if HAS_MULTI_EXTRUDER + // Z raise distance for tool-change, as needed for some extruders + #define TOOLCHANGE_ZRAISE 2 // (mm) + //#define TOOLCHANGE_ZRAISE_BEFORE_RETRACT // Apply raise before swap retraction (if enabled) + //#define TOOLCHANGE_NO_RETURN // Never return to previous position on tool-change + #if ENABLED(TOOLCHANGE_NO_RETURN) + //#define EVENT_GCODE_AFTER_TOOLCHANGE "G12X" // Extra G-code to run after tool-change + #endif + + /** + * Extra G-code to run while executing tool-change commands. Can be used to use an additional + * stepper motor (e.g., I axis in Configuration.h) to drive the tool-changer. + */ + //#define EVENT_GCODE_TOOLCHANGE_T0 "G28 A\nG1 A0" // Extra G-code to run while executing tool-change command T0 + //#define EVENT_GCODE_TOOLCHANGE_T1 "G1 A10" // Extra G-code to run while executing tool-change command T1 + //#define EVENT_GCODE_TOOLCHANGE_ALWAYS_RUN // Always execute above G-code sequences. Use with caution! + + /** + * Consider coordinates for EVENT_GCODE_TOOLCHANGE_Tx as relative to T0 + * so that moves in the specified axes are the same for all tools. + */ + //#define TC_GCODE_USE_GLOBAL_X // Use X position relative to Tool 0 + //#define TC_GCODE_USE_GLOBAL_Y // Use Y position relative to Tool 0 + //#define TC_GCODE_USE_GLOBAL_Z // Use Z position relative to Tool 0 + + /** + * Tool Sensors detect when tools have been picked up or dropped. + * Requires the pins TOOL_SENSOR1_PIN, TOOL_SENSOR2_PIN, etc. + */ + //#define TOOL_SENSOR + + /** + * Retract and prime filament on tool-change to reduce + * ooze and stringing and to get cleaner transitions. + */ + //#define TOOLCHANGE_FILAMENT_SWAP + #if ENABLED(TOOLCHANGE_FILAMENT_SWAP) + // Load / Unload + #define TOOLCHANGE_FS_LENGTH 12 // (mm) Load / Unload length + #define TOOLCHANGE_FS_EXTRA_RESUME_LENGTH 0 // (mm) Extra length for better restart. Adjust with LCD or M217 B. + #define TOOLCHANGE_FS_RETRACT_SPEED (50*60) // (mm/min) (Unloading) + #define TOOLCHANGE_FS_UNRETRACT_SPEED (25*60) // (mm/min) (On SINGLENOZZLE or Bowden loading must be slowed down) + + // Longer prime to clean out a SINGLENOZZLE + #define TOOLCHANGE_FS_EXTRA_PRIME 0 // (mm) Extra priming length + #define TOOLCHANGE_FS_PRIME_SPEED (4.6*60) // (mm/min) Extra priming feedrate + #define TOOLCHANGE_FS_WIPE_RETRACT 0 // (mm) Cutting retraction out of park, for less stringing, better wipe, etc. Adjust with LCD or M217 G. + + // Cool after prime to reduce stringing + #define TOOLCHANGE_FS_FAN -1 // Fan index or -1 to skip + #define TOOLCHANGE_FS_FAN_SPEED 255 // 0-255 + #define TOOLCHANGE_FS_FAN_TIME 10 // (seconds) + + // Use TOOLCHANGE_FS_PRIME_SPEED feedrate the first time each extruder is primed + //#define TOOLCHANGE_FS_SLOW_FIRST_PRIME + + /** + * Prime T0 the first time T0 is sent to the printer: + * [ Power-On -> T0 { Activate & Prime T0 } -> T1 { Retract T0, Activate & Prime T1 } ] + * If disabled, no priming on T0 until switching back to T0 from another extruder: + * [ Power-On -> T0 { T0 Activated } -> T1 { Activate & Prime T1 } -> T0 { Retract T1, Activate & Prime T0 } ] + * Enable with M217 V1 before printing to avoid unwanted priming on host connect. + */ + //#define TOOLCHANGE_FS_PRIME_FIRST_USED + + /** + * Tool Change Migration + * This feature provides G-code and LCD options to switch tools mid-print. + * All applicable tool properties are migrated so the print can continue. + * Tools must be closely matching and other restrictions may apply. + * Useful to: + * - Change filament color without interruption + * - Switch spools automatically on filament runout + * - Switch to a different nozzle on an extruder jam + */ + #define TOOLCHANGE_MIGRATION_FEATURE + #if ENABLED(TOOLCHANGE_MIGRATION_FEATURE) + // Override toolchange settings + // By default tool migration uses regular toolchange settings. + // With a prime tower, tool-change swapping/priming occur inside the bed. + // When migrating to a new unprimed tool you can set override values below. + //#define MIGRATION_ZRAISE 0 // (mm) + + // Longer prime to clean out + //#define MIGRATION_FS_EXTRA_PRIME 0 // (mm) Extra priming length + //#define MIGRATION_FS_WIPE_RETRACT 0 // (mm) Retract before cooling for less stringing, better wipe, etc. + + // Cool after prime to reduce stringing + //#define MIGRATION_FS_FAN_SPEED 255 // 0-255 + //#define MIGRATION_FS_FAN_TIME 0 // (seconds) + #endif + #endif + + /** + * Position to park head during tool change. + * Doesn't apply to SWITCHING_TOOLHEAD, DUAL_X_CARRIAGE, or PARKING_EXTRUDER + */ + //#define TOOLCHANGE_PARK + #if ENABLED(TOOLCHANGE_PARK) + #define TOOLCHANGE_PARK_XY { X_MIN_POS + 10, Y_MIN_POS + 10 } + #define TOOLCHANGE_PARK_XY_FEEDRATE 6000 // (mm/min) + //#define TOOLCHANGE_PARK_X_ONLY // X axis only move + //#define TOOLCHANGE_PARK_Y_ONLY // Y axis only move + #if ENABLED(TOOLCHANGE_MIGRATION_FEATURE) + //#define TOOLCHANGE_MIGRATION_DO_PARK // Force park (or no-park) on migration + #endif + #endif +#endif // HAS_MULTI_EXTRUDER + +// @section advanced pause + +/** + * Advanced Pause for Filament Change + * - Adds the G-code M600 Filament Change to initiate a filament change. + * - This feature is required for the default FILAMENT_RUNOUT_SCRIPT. + * + * Requirements: + * - For Filament Change parking enable and configure NOZZLE_PARK_FEATURE. + * - For user interaction enable an LCD display, HOST_PROMPT_SUPPORT, or EMERGENCY_PARSER. + * + * Enable PARK_HEAD_ON_PAUSE to add the G-code M125 Pause and Park. + */ +#define ADVANCED_PAUSE_FEATURE +#if ENABLED(ADVANCED_PAUSE_FEATURE) + #define PAUSE_PARK_RETRACT_FEEDRATE 100 // (mm/s) Initial retract feedrate. + #define PAUSE_PARK_RETRACT_LENGTH 5 // (mm) Initial retract. + // This short retract is done immediately, before parking the nozzle. + #define FILAMENT_CHANGE_UNLOAD_FEEDRATE 10 // (mm/s) Unload filament feedrate. This can be pretty fast. + #define FILAMENT_CHANGE_UNLOAD_ACCEL 25 // (mm/s^2) Lower acceleration may allow a faster feedrate. + #define FILAMENT_CHANGE_UNLOAD_LENGTH 300 // (mm) The length of filament for a complete unload. + // For Bowden, the full length of the tube and nozzle. + // For direct drive, the full length of the nozzle. + // Set to 0 for manual unloading. + #define FILAMENT_CHANGE_SLOW_LOAD_FEEDRATE 6 // (mm/s) Slow move when starting load. + #define FILAMENT_CHANGE_SLOW_LOAD_LENGTH 0 // (mm) Slow length, to allow time to insert material. + // 0 to disable start loading and skip to fast load only + #define FILAMENT_CHANGE_FAST_LOAD_FEEDRATE 10 // (mm/s) Load filament feedrate. This can be pretty fast. + #define FILAMENT_CHANGE_FAST_LOAD_ACCEL 25 // (mm/s^2) Lower acceleration may allow a faster feedrate. + #define FILAMENT_CHANGE_FAST_LOAD_LENGTH 250 // (mm) Load length of filament, from extruder gear to nozzle. + // For Bowden, the full length of the tube and nozzle. + // For direct drive, the full length of the nozzle. + //#define ADVANCED_PAUSE_CONTINUOUS_PURGE // Purge continuously up to the purge length until interrupted. + #define ADVANCED_PAUSE_PURGE_FEEDRATE 3 // (mm/s) Extrude feedrate (after loading). Should be slower than load feedrate. + #define ADVANCED_PAUSE_PURGE_LENGTH 20 // (mm) Length to extrude after loading. + // Set to 0 for manual extrusion. + // Filament can be extruded repeatedly from the Filament Change menu + // until extrusion is consistent, and to purge old filament. + #define ADVANCED_PAUSE_RESUME_PRIME 0 // (mm) Extra distance to prime nozzle after returning from park. + //#define ADVANCED_PAUSE_FANS_PAUSE // Turn off print-cooling fans while the machine is paused. + + // Filament Unload does a Retract, Delay, and Purge first: + #define FILAMENT_UNLOAD_PURGE_RETRACT 13 // (mm) Unload initial retract length. + #define FILAMENT_UNLOAD_PURGE_DELAY 5000 // (ms) Delay for the filament to cool after retract. + #define FILAMENT_UNLOAD_PURGE_LENGTH 8 // (mm) An unretract is done, then this length is purged. + #define FILAMENT_UNLOAD_PURGE_FEEDRATE 25 // (mm/s) feedrate to purge before unload + + #define PAUSE_PARK_NOZZLE_TIMEOUT 45 // (seconds) Time limit before the nozzle is turned off for safety. + #define FILAMENT_CHANGE_ALERT_BEEPS 8 // Number of alert beeps to play when a response is needed. + #define PAUSE_PARK_NO_STEPPER_TIMEOUT // Enable for XYZ steppers to stay powered on during filament change. + //#define FILAMENT_CHANGE_RESUME_ON_INSERT // Automatically continue / load filament when runout sensor is triggered again. + //#define PAUSE_REHEAT_FAST_RESUME // Reduce number of waits by not prompting again post-timeout before continuing. + + #define PARK_HEAD_ON_PAUSE // Park the nozzle during pause and filament change. + #define HOME_BEFORE_FILAMENT_CHANGE // If needed, home before parking for filament change + + #define FILAMENT_LOAD_UNLOAD_GCODES // Add M701/M702 Load/Unload G-codes, plus Load/Unload in the LCD Prepare menu. + //#define FILAMENT_UNLOAD_ALL_EXTRUDERS // Allow M702 to unload all extruders above a minimum target temp (as set by M302) + #define CONFIGURE_FILAMENT_CHANGE // Add M603 G-code and menu items. Requires ~1.3K bytes of flash. +#endif + +// @section tmc_smart + +/** + * Trinamic Smart Drivers + * + * To use TMC2130, TMC2160, TMC2240, TMC2660, TMC5130, TMC5160 stepper drivers in SPI mode: + * - Connect your SPI pins to the Hardware SPI interface on the board. + * Some boards have simple jumper connections! See your board's documentation. + * - Define the required Stepper CS pins in your `pins_MYBOARD.h` file. + * (See the RAMPS pins, for example.) + * - You can also use Software SPI with GPIO pins instead of Hardware SPI. + * + * To use TMC220x stepper drivers with Serial UART: + * - Connect PDN_UART to the #_SERIAL_TX_PIN through a 1K resistor. + * For reading capabilities also connect PDN_UART to #_SERIAL_RX_PIN with no resistor. + * Some boards have simple jumper connections! See your board's documentation. + * - These drivers can also be used with Hardware Serial. + * + * The TMCStepper library is required for other TMC stepper drivers. + * https://github.com/teemuatlut/TMCStepper + * + * @section tmc/config + */ +#if HAS_TRINAMIC_CONFIG + + #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current + + //#define EDITABLE_HOMING_CURRENT // Add a G-code and menu to modify the Homing Current + + /** + * Interpolate microsteps to 256 + * Override for each driver with _INTERPOLATE settings below + */ + #define INTERPOLATE true + + #if HAS_DRIVER(TMC2240) + #define TMC2240_RREF 12000 // (Ω) 12000 .. 60000. (FLY TMC2240 = 12300) + // Max Current. Lower for more internal resolution. Raise to run cooler. + #define TMC2240_CURRENT_RANGE 1 // :{ 0:'RMS=690mA PEAK=1A', 1:'RMS=1410mA PEAK=2A', 2:'RMS=2120mA PEAK=3A', 3:'RMS=2110mA PEAK=3A' } + // Slope Control: Lower is more silent. Higher runs cooler. + #define TMC2240_SLOPE_CONTROL 0 // :{ 0:'100V/µs', 1:'200V/µs', 2:'400V/µs', 3:'800V/µs' } + #endif + + #if AXIS_IS_TMC_CONFIG(X) + #define X_CURRENT 800 // (mA) RMS current. Multiply by 1.414 for peak current. + #define X_CURRENT_HOME X_CURRENT // (mA) RMS current for homing. (Typically lower than *_CURRENT.) + #define X_MICROSTEPS 16 // 0..256 + #define X_RSENSE 0.11 + #define X_CHAIN_POS -1 // -1..0: Not chained. 1: MCU MOSI connected. 2: Next in chain, ... + //#define X_INTERPOLATE true // Enable to override 'INTERPOLATE' for the X axis + //#define X_HOLD_MULTIPLIER 0.5 // Enable to override 'HOLD_MULTIPLIER' for the X axis + #endif + + #if AXIS_IS_TMC_CONFIG(X2) + #define X2_CURRENT X_CURRENT + #define X2_CURRENT_HOME X_CURRENT_HOME + #define X2_MICROSTEPS X_MICROSTEPS + #define X2_RSENSE X_RSENSE + #define X2_CHAIN_POS -1 + //#define X2_INTERPOLATE true + //#define X2_HOLD_MULTIPLIER 0.5 + #endif + + #if AXIS_IS_TMC_CONFIG(Y) + #define Y_CURRENT 800 + #define Y_CURRENT_HOME Y_CURRENT + #define Y_MICROSTEPS 16 + #define Y_RSENSE 0.11 + #define Y_CHAIN_POS -1 + //#define Y_INTERPOLATE true + //#define Y_HOLD_MULTIPLIER 0.5 + #endif + + #if AXIS_IS_TMC_CONFIG(Y2) + #define Y2_CURRENT Y_CURRENT + #define Y2_CURRENT_HOME Y_CURRENT_HOME + #define Y2_MICROSTEPS Y_MICROSTEPS + #define Y2_RSENSE Y_RSENSE + #define Y2_CHAIN_POS -1 + //#define Y2_INTERPOLATE true + //#define Y2_HOLD_MULTIPLIER 0.5 + #endif + + #if AXIS_IS_TMC_CONFIG(Z) + #define Z_CURRENT 800 + #define Z_CURRENT_HOME Z_CURRENT + #define Z_MICROSTEPS 16 + #define Z_RSENSE 0.11 + #define Z_CHAIN_POS -1 + //#define Z_INTERPOLATE true + //#define Z_HOLD_MULTIPLIER 0.5 + #endif + + #if AXIS_IS_TMC_CONFIG(Z2) + #define Z2_CURRENT Z_CURRENT + #define Z2_CURRENT_HOME Z_CURRENT_HOME + #define Z2_MICROSTEPS Z_MICROSTEPS + #define Z2_RSENSE Z_RSENSE + #define Z2_CHAIN_POS -1 + //#define Z2_INTERPOLATE true + //#define Z2_HOLD_MULTIPLIER 0.5 + #endif + + #if AXIS_IS_TMC_CONFIG(Z3) + #define Z3_CURRENT Z_CURRENT + #define Z3_CURRENT_HOME Z_CURRENT_HOME + #define Z3_MICROSTEPS Z_MICROSTEPS + #define Z3_RSENSE Z_RSENSE + #define Z3_CHAIN_POS -1 + //#define Z3_INTERPOLATE true + //#define Z3_HOLD_MULTIPLIER 0.5 + #endif + + #if AXIS_IS_TMC_CONFIG(Z4) + #define Z4_CURRENT Z_CURRENT + #define Z4_CURRENT_HOME Z_CURRENT_HOME + #define Z4_MICROSTEPS Z_MICROSTEPS + #define Z4_RSENSE Z_RSENSE + #define Z4_CHAIN_POS -1 + //#define Z4_INTERPOLATE true + //#define Z4_HOLD_MULTIPLIER 0.5 + #endif + + #if AXIS_IS_TMC_CONFIG(I) + #define I_CURRENT 800 + #define I_CURRENT_HOME I_CURRENT + #define I_MICROSTEPS 16 + #define I_RSENSE 0.11 + #define I_CHAIN_POS -1 + //#define I_INTERPOLATE true + //#define I_HOLD_MULTIPLIER 0.5 + #endif + + #if AXIS_IS_TMC_CONFIG(J) + #define J_CURRENT 800 + #define J_CURRENT_HOME J_CURRENT + #define J_MICROSTEPS 16 + #define J_RSENSE 0.11 + #define J_CHAIN_POS -1 + //#define J_INTERPOLATE true + //#define J_HOLD_MULTIPLIER 0.5 + #endif + + #if AXIS_IS_TMC_CONFIG(K) + #define K_CURRENT 800 + #define K_CURRENT_HOME K_CURRENT + #define K_MICROSTEPS 16 + #define K_RSENSE 0.11 + #define K_CHAIN_POS -1 + //#define K_INTERPOLATE true + //#define K_HOLD_MULTIPLIER 0.5 + #endif + + #if AXIS_IS_TMC_CONFIG(U) + #define U_CURRENT 800 + #define U_CURRENT_HOME U_CURRENT + #define U_MICROSTEPS 8 + #define U_RSENSE 0.11 + #define U_CHAIN_POS -1 + //#define U_INTERPOLATE true + //#define U_HOLD_MULTIPLIER 0.5 + #endif + + #if AXIS_IS_TMC_CONFIG(V) + #define V_CURRENT 800 + #define V_CURRENT_HOME V_CURRENT + #define V_MICROSTEPS 8 + #define V_RSENSE 0.11 + #define V_CHAIN_POS -1 + //#define V_INTERPOLATE true + //#define V_HOLD_MULTIPLIER 0.5 + #endif + + #if AXIS_IS_TMC_CONFIG(W) + #define W_CURRENT 800 + #define W_CURRENT_HOME W_CURRENT + #define W_MICROSTEPS 8 + #define W_RSENSE 0.11 + #define W_CHAIN_POS -1 + //#define W_INTERPOLATE true + //#define W_HOLD_MULTIPLIER 0.5 + #endif + + #if AXIS_IS_TMC_CONFIG(E0) + #define E0_CURRENT 800 + #define E0_MICROSTEPS 16 + #define E0_RSENSE 0.11 + #define E0_CHAIN_POS -1 + //#define E0_INTERPOLATE true + //#define E0_HOLD_MULTIPLIER 0.5 + #endif + + #if AXIS_IS_TMC_CONFIG(E1) + #define E1_CURRENT E0_CURRENT + #define E1_MICROSTEPS E0_MICROSTEPS + #define E1_RSENSE E0_RSENSE + #define E1_CHAIN_POS -1 + //#define E1_INTERPOLATE true + //#define E1_HOLD_MULTIPLIER 0.5 + #endif + + #if AXIS_IS_TMC_CONFIG(E2) + #define E2_CURRENT E0_CURRENT + #define E2_MICROSTEPS E0_MICROSTEPS + #define E2_RSENSE E0_RSENSE + #define E2_CHAIN_POS -1 + //#define E2_INTERPOLATE true + //#define E2_HOLD_MULTIPLIER 0.5 + #endif + + #if AXIS_IS_TMC_CONFIG(E3) + #define E3_CURRENT E0_CURRENT + #define E3_MICROSTEPS E0_MICROSTEPS + #define E3_RSENSE E0_RSENSE + #define E3_CHAIN_POS -1 + //#define E3_INTERPOLATE true + //#define E3_HOLD_MULTIPLIER 0.5 + #endif + + #if AXIS_IS_TMC_CONFIG(E4) + #define E4_CURRENT E0_CURRENT + #define E4_MICROSTEPS E0_MICROSTEPS + #define E4_RSENSE E0_RSENSE + #define E4_CHAIN_POS -1 + //#define E4_INTERPOLATE true + //#define E4_HOLD_MULTIPLIER 0.5 + #endif + + #if AXIS_IS_TMC_CONFIG(E5) + #define E5_CURRENT E0_CURRENT + #define E5_MICROSTEPS E0_MICROSTEPS + #define E5_RSENSE E0_RSENSE + #define E5_CHAIN_POS -1 + //#define E5_INTERPOLATE true + //#define E5_HOLD_MULTIPLIER 0.5 + #endif + + #if AXIS_IS_TMC_CONFIG(E6) + #define E6_CURRENT E0_CURRENT + #define E6_MICROSTEPS E0_MICROSTEPS + #define E6_RSENSE E0_RSENSE + #define E6_CHAIN_POS -1 + //#define E6_INTERPOLATE true + //#define E6_HOLD_MULTIPLIER 0.5 + #endif + + #if AXIS_IS_TMC_CONFIG(E7) + #define E7_CURRENT E0_CURRENT + #define E7_MICROSTEPS E0_MICROSTEPS + #define E7_RSENSE E0_RSENSE + #define E7_CHAIN_POS -1 + //#define E7_INTERPOLATE true + //#define E7_HOLD_MULTIPLIER 0.5 + #endif + + /** + * Use the homing current for all probing. (e.g., Current may be reduced to the + * point where a collision makes the motor skip instead of damaging the bed, + * though this is unlikely to save delicate probes from being damaged. + */ + //#define PROBING_USE_CURRENT_HOME + + // @section tmc/spi + + /** + * Override default SPI pins for TMC2130, TMC2160, TMC2240, TMC2660, TMC5130 and TMC5160 drivers here. + * The default pins can be found in your board's pins file. + */ + //#define X_CS_PIN -1 + //#define Y_CS_PIN -1 + //#define Z_CS_PIN -1 + //#define X2_CS_PIN -1 + //#define Y2_CS_PIN -1 + //#define Z2_CS_PIN -1 + //#define Z3_CS_PIN -1 + //#define Z4_CS_PIN -1 + //#define I_CS_PIN -1 + //#define J_CS_PIN -1 + //#define K_CS_PIN -1 + //#define U_CS_PIN -1 + //#define V_CS_PIN -1 + //#define W_CS_PIN -1 + //#define E0_CS_PIN -1 + //#define E1_CS_PIN -1 + //#define E2_CS_PIN -1 + //#define E3_CS_PIN -1 + //#define E4_CS_PIN -1 + //#define E5_CS_PIN -1 + //#define E6_CS_PIN -1 + //#define E7_CS_PIN -1 + + /** + * Software option for SPI driven drivers (TMC2130, TMC2160, TMC2240, TMC2660, TMC5130 and TMC5160). + * The default SW SPI pins are defined the respective pins files, + * but you can override or define them here. + */ + //#define TMC_USE_SW_SPI + //#define TMC_SPI_MOSI -1 + //#define TMC_SPI_MISO -1 + //#define TMC_SPI_SCK -1 + + // @section tmc/serial + + /** + * Four TMC2209 drivers can use the same HW/SW serial port with hardware configured addresses. + * Set the address using jumpers on pins MS1 and MS2. + * Address | MS1 | MS2 + * 0 | LOW | LOW + * 1 | HIGH | LOW + * 2 | LOW | HIGH + * 3 | HIGH | HIGH + * + * Set *_SERIAL_TX_PIN and *_SERIAL_RX_PIN to match for all drivers + * on the same serial port, either here or in your board's pins file. + */ + //#define X_SLAVE_ADDRESS 0 + //#define Y_SLAVE_ADDRESS 0 + //#define Z_SLAVE_ADDRESS 0 + //#define X2_SLAVE_ADDRESS 0 + //#define Y2_SLAVE_ADDRESS 0 + //#define Z2_SLAVE_ADDRESS 0 + //#define Z3_SLAVE_ADDRESS 0 + //#define Z4_SLAVE_ADDRESS 0 + //#define I_SLAVE_ADDRESS 0 + //#define J_SLAVE_ADDRESS 0 + //#define K_SLAVE_ADDRESS 0 + //#define U_SLAVE_ADDRESS 0 + //#define V_SLAVE_ADDRESS 0 + //#define W_SLAVE_ADDRESS 0 + //#define E0_SLAVE_ADDRESS 0 + //#define E1_SLAVE_ADDRESS 0 + //#define E2_SLAVE_ADDRESS 0 + //#define E3_SLAVE_ADDRESS 0 + //#define E4_SLAVE_ADDRESS 0 + //#define E5_SLAVE_ADDRESS 0 + //#define E6_SLAVE_ADDRESS 0 + //#define E7_SLAVE_ADDRESS 0 + + // @section tmc/smart + + /** + * Software enable + * + * Use for drivers that do not use a dedicated enable pin, but rather handle the same + * function through a communication line such as SPI or UART. + */ + //#define SOFTWARE_DRIVER_ENABLE + + // @section tmc/stealthchop + + /** + * TMC2130, TMC2160, TMC2208, TMC2209, TMC2240, TMC5130 and TMC5160 only + * Use Trinamic's ultra quiet stepping mode. + * When disabled, Marlin will use spreadCycle stepping mode. + */ + #if HAS_STEALTHCHOP + #define STEALTHCHOP_XY + #define STEALTHCHOP_Z + #define STEALTHCHOP_I + #define STEALTHCHOP_J + #define STEALTHCHOP_K + #define STEALTHCHOP_U + #define STEALTHCHOP_V + #define STEALTHCHOP_W + #define STEALTHCHOP_E + #endif + + /** + * Optimize spreadCycle chopper parameters by using predefined parameter sets + * or with the help of an example included in the library. + * Provided parameter sets are + * CHOPPER_DEFAULT_12V + * CHOPPER_DEFAULT_19V + * CHOPPER_DEFAULT_24V + * CHOPPER_DEFAULT_36V + * CHOPPER_09STEP_24V // 0.9 degree steppers (24V) + * CHOPPER_PRUSAMK3_24V // Imported parameters from the official Průša firmware for MK3 (24V) + * CHOPPER_MARLIN_119 // Old defaults from Marlin v1.1.9 + * + * Define your own with: + * { , , hysteresis_start[1..8] } + */ + #define CHOPPER_TIMING CHOPPER_DEFAULT_12V // All axes (override below) + //#define CHOPPER_TIMING_X CHOPPER_TIMING // For X Axes (override below) + //#define CHOPPER_TIMING_X2 CHOPPER_TIMING_X + //#define CHOPPER_TIMING_Y CHOPPER_TIMING // For Y Axes (override below) + //#define CHOPPER_TIMING_Y2 CHOPPER_TIMING_Y + //#define CHOPPER_TIMING_Z CHOPPER_TIMING // For Z Axes (override below) + //#define CHOPPER_TIMING_Z2 CHOPPER_TIMING_Z + //#define CHOPPER_TIMING_Z3 CHOPPER_TIMING_Z + //#define CHOPPER_TIMING_Z4 CHOPPER_TIMING_Z + //#define CHOPPER_TIMING_I CHOPPER_TIMING // For I Axis + //#define CHOPPER_TIMING_J CHOPPER_TIMING // For J Axis + //#define CHOPPER_TIMING_K CHOPPER_TIMING // For K Axis + //#define CHOPPER_TIMING_U CHOPPER_TIMING // For U Axis + //#define CHOPPER_TIMING_V CHOPPER_TIMING // For V Axis + //#define CHOPPER_TIMING_W CHOPPER_TIMING // For W Axis + //#define CHOPPER_TIMING_E CHOPPER_TIMING // For Extruders (override below) + //#define CHOPPER_TIMING_E1 CHOPPER_TIMING_E + //#define CHOPPER_TIMING_E2 CHOPPER_TIMING_E + //#define CHOPPER_TIMING_E3 CHOPPER_TIMING_E + //#define CHOPPER_TIMING_E4 CHOPPER_TIMING_E + //#define CHOPPER_TIMING_E5 CHOPPER_TIMING_E + //#define CHOPPER_TIMING_E6 CHOPPER_TIMING_E + //#define CHOPPER_TIMING_E7 CHOPPER_TIMING_E + + // @section tmc/status + + /** + * Monitor Trinamic drivers + * for error conditions like overtemperature and short to ground. + * To manage over-temp Marlin can decrease the driver current until the error condition clears. + * Other detected conditions can be used to stop the current print. + * Relevant G-codes: + * M906 - Set or get motor current in milliamps using axis codes X, Y, Z, E. Report values if no axis codes given. + * M911 - Report stepper driver overtemperature pre-warn condition. + * M912 - Clear stepper driver overtemperature pre-warn condition flag. + * M122 - Report driver parameters (Requires TMC_DEBUG) + */ + //#define MONITOR_DRIVER_STATUS + + #if ENABLED(MONITOR_DRIVER_STATUS) + #define CURRENT_STEP_DOWN 50 // [mA] + #define REPORT_CURRENT_CHANGE + #define STOP_ON_ERROR + #endif + + // @section tmc/hybrid + + /** + * TMC2130, TMC2160, TMC2208, TMC2209, TMC2240, TMC5130 and TMC5160 only + * The driver will switch to spreadCycle when stepper speed is over HYBRID_THRESHOLD. + * This mode allows for faster movements at the expense of higher noise levels. + * STEALTHCHOP_(XY|Z|E) must be enabled to use HYBRID_THRESHOLD. + * M913 X/Y/Z/E to live tune the setting + */ + #define HYBRID_THRESHOLD + + #define X_HYBRID_THRESHOLD 100 // [mm/s] + #define X2_HYBRID_THRESHOLD 100 + #define Y_HYBRID_THRESHOLD 100 + #define Y2_HYBRID_THRESHOLD 100 + #define Z_HYBRID_THRESHOLD 100 + #define Z2_HYBRID_THRESHOLD 3 + #define Z3_HYBRID_THRESHOLD 3 + #define Z4_HYBRID_THRESHOLD 3 + #define I_HYBRID_THRESHOLD 3 // [linear=mm/s, rotational=°/s] + #define J_HYBRID_THRESHOLD 3 // [linear=mm/s, rotational=°/s] + #define K_HYBRID_THRESHOLD 3 // [linear=mm/s, rotational=°/s] + #define U_HYBRID_THRESHOLD 3 // [mm/s] + #define V_HYBRID_THRESHOLD 3 + #define W_HYBRID_THRESHOLD 3 + #define E0_HYBRID_THRESHOLD 30 + #define E1_HYBRID_THRESHOLD 30 + #define E2_HYBRID_THRESHOLD 30 + #define E3_HYBRID_THRESHOLD 30 + #define E4_HYBRID_THRESHOLD 30 + #define E5_HYBRID_THRESHOLD 30 + #define E6_HYBRID_THRESHOLD 30 + #define E7_HYBRID_THRESHOLD 30 + + /** + * Use StallGuard to home / probe X, Y, Z. + * + * TMC2130, TMC2160, TMC2209, TMC2240, TMC2660, TMC5130, and TMC5160 only + * Connect the stepper driver's DIAG1 pin to the X/Y endstop pin. + * X, Y, and Z homing will always be done in spreadCycle mode. + * + * X/Y/Z_STALL_SENSITIVITY is the default stall threshold. + * Use M914 X Y Z to set the stall threshold at runtime: + * + * Sensitivity TMC2209 Others + * HIGHEST 255 -64 (Too sensitive => False positive) + * LOWEST 0 63 (Too insensitive => No trigger) + * + * It is recommended to set HOMING_BUMP_MM to { 0, 0, 0 }. + * + * SPI_ENDSTOPS *** TMC2130, TMC2240, and TMC5160 Only *** + * Poll the driver through SPI to determine load when homing. + * Removes the need for a wire from DIAG1 to an endstop pin. + * + * IMPROVE_HOMING_RELIABILITY tunes acceleration and jerk when + * homing and adds a guard period for endstop triggering. + * + * Comment *_STALL_SENSITIVITY to disable sensorless homing for that axis. + * @section tmc/stallguard + */ + //#define SENSORLESS_HOMING // StallGuard capable drivers only + + #if ANY(SENSORLESS_HOMING, SENSORLESS_PROBING) + // TMC2209: 0...255. TMC2130: -64...63 + #define X_STALL_SENSITIVITY 8 + #define X2_STALL_SENSITIVITY X_STALL_SENSITIVITY + #define Y_STALL_SENSITIVITY 8 + #define Y2_STALL_SENSITIVITY Y_STALL_SENSITIVITY + //#define Z_STALL_SENSITIVITY 8 + //#define Z2_STALL_SENSITIVITY Z_STALL_SENSITIVITY + //#define Z3_STALL_SENSITIVITY Z_STALL_SENSITIVITY + //#define Z4_STALL_SENSITIVITY Z_STALL_SENSITIVITY + //#define I_STALL_SENSITIVITY 8 + //#define J_STALL_SENSITIVITY 8 + //#define K_STALL_SENSITIVITY 8 + //#define U_STALL_SENSITIVITY 8 + //#define V_STALL_SENSITIVITY 8 + //#define W_STALL_SENSITIVITY 8 + //#define SPI_ENDSTOPS // TMC2130, TMC2240, and TMC5160 + //#define IMPROVE_HOMING_RELIABILITY + //#define SENSORLESS_STALLGUARD_DELAY 0 // (ms) Delay to allow drivers to settle + #endif + + // @section tmc/config + + /** + * TMC Homing stepper phase. + * + * Improve homing repeatability by homing to stepper coil's nearest absolute + * phase position. Trinamic drivers use a stepper phase table with 1024 values + * spanning 4 full steps with 256 positions each (ergo, 1024 positions). + * Full step positions (128, 384, 640, 896) have the highest holding torque. + * + * Values from 0..1023, -1 to disable homing phase for that axis. + */ + //#define TMC_HOME_PHASE { 896, 896, 896 } + + /** + * Step on both rising and falling edge signals (as with a square wave). + */ + #define EDGE_STEPPING + + /** + * Enable M122 debugging command for TMC stepper drivers. + * M122 S0/1 will enable continuous reporting. + */ + //#define TMC_DEBUG + + /** + * You can set your own advanced settings by filling in predefined functions. + * A list of available functions can be found on the library github page + * https://github.com/teemuatlut/TMCStepper + * + * Example: + * #define TMC_ADV() { \ + * stepperX.diag0_otpw(1); \ + * stepperY.intpol(0); \ + * } + */ + #define TMC_ADV() { } + +#endif // HAS_TRINAMIC_CONFIG + +// @section i2cbus + +// +// I2C Master ID for LPC176x LCD and Digital Current control +// Does not apply to other peripherals based on the Wire library. +// +//#define I2C_MASTER_ID 1 // Set a value from 0 to 2 + +/** + * TWI/I2C BUS + * + * This feature is EXPERIMENTAL but may be useful for custom I2C peripherals. + * Enable this to send and receive I2C data from slave devices on the bus. + * + * ; Example #1 + * ; This macro send the string "Marlin" to the slave device with address 0x63 (99) + * ; It uses multiple M260 commands with one B arg + * M260 A99 ; Target slave address + * M260 B77 ; M + * M260 B97 ; a + * M260 B114 ; r + * M260 B108 ; l + * M260 B105 ; i + * M260 B110 ; n + * M260 S1 ; Send the current buffer + * + * ; Example #2 + * ; Request 6 bytes from slave device with address 0x63 (99) + * M261 A99 B5 + * + * ; Example #3 + * ; Example serial output of a M261 request + * echo:i2c-reply: from:99 bytes:5 data:hello + */ + +//#define EXPERIMENTAL_I2CBUS +#if ENABLED(EXPERIMENTAL_I2CBUS) + #define I2C_SLAVE_ADDRESS 0 // Set a value from 8 to 127 to act as a slave +#endif + +// @section photo + +/** + * Photo G-code + * Add the M240 G-code to take a photo. + * The photo can be triggered by a digital pin or a physical movement. + */ +//#define PHOTO_GCODE +#if ENABLED(PHOTO_GCODE) + // A position to move to (and raise Z) before taking the photo + //#define PHOTO_POSITION { X_MAX_POS - 5, Y_MAX_POS, 0 } // { xpos, ypos, zraise } (M240 X Y Z) + //#define PHOTO_DELAY_MS 100 // (ms) Duration to pause before moving back (M240 P) + //#define PHOTO_RETRACT_MM 6.5 // (mm) E retract/recover for the photo move (M240 R S) + + // Canon RC-1 or homebrew digital camera trigger + // Data from: https://www.doc-diy.net/photo/rc-1_hacked/ + //#define PHOTOGRAPH_PIN 23 + + // Canon Hack Development Kit + // https://web.archive.org/web/20200920094805/captain-slow.dk/2014/03/09/3d-printing-timelapses/ + //#define CHDK_PIN 4 + + // Optional second move with delay to trigger the camera shutter + //#define PHOTO_SWITCH_POSITION { X_MAX_POS, Y_MAX_POS } // { xpos, ypos } (M240 I J) + + // Duration to hold the switch or keep CHDK_PIN high + //#define PHOTO_SWITCH_MS 50 // (ms) (M240 D) + + /** + * PHOTO_PULSES_US may need adjustment depending on board and camera model. + * Pin must be running at 48.4kHz. + * Be sure to use a PHOTOGRAPH_PIN which can rise and fall quick enough. + * (e.g., MKS SBase temp sensor pin was too slow, so used P1.23 on J8.) + * + * Example pulse data for Nikon: https://bit.ly/2FKD0Aq + * IR Wiring: https://git.io/JvJf7 + */ + //#define PHOTO_PULSES_US { 2000, 27850, 400, 1580, 400, 3580, 400 } // (µs) Durations for each 48.4kHz oscillation + #ifdef PHOTO_PULSES_US + #define PHOTO_PULSE_DELAY_US 13 // (µs) Approximate duration of each HIGH and LOW pulse in the oscillation + #endif +#endif + +// @section cnc + +/** + * Spindle & Laser control + * + * Add the M3, M4, and M5 commands to turn the spindle/laser on and off, and + * to set spindle speed, spindle direction, and laser power. + * + * SuperPID is a router/spindle speed controller used in the CNC milling community. + * Marlin can be used to turn the spindle on and off. It can also be used to set + * the spindle speed from 5,000 to 30,000 RPM. + * + * You'll need to select a pin for the ON/OFF function and optionally choose a 0-5V + * hardware PWM pin for the speed control and a pin for the rotation direction. + * + * See https://marlinfw.org/docs/configuration/2.0.9/laser_spindle.html for more config details. + */ +//#define SPINDLE_FEATURE +//#define LASER_FEATURE +#if ANY(SPINDLE_FEATURE, LASER_FEATURE) + #define SPINDLE_LASER_ACTIVE_STATE LOW // Set to "HIGH" if SPINDLE_LASER_ENA_PIN is active HIGH + + #define SPINDLE_LASER_USE_PWM // Enable if your controller supports setting the speed/power + #if ENABLED(SPINDLE_LASER_USE_PWM) + #define SPINDLE_LASER_PWM_INVERT false // Set to "true" if the speed/power goes up when you want it to go slower + #define SPINDLE_LASER_FREQUENCY 2500 // (Hz) Spindle/laser frequency (only on supported HALs: AVR, ESP32, and LPC) + // ESP32: If SPINDLE_LASER_PWM_PIN is onboard then <=78125Hz. For I2S expander + // the frequency determines the PWM resolution. 2500Hz = 0-100, 977Hz = 0-255, ... + // (250000 / SPINDLE_LASER_FREQUENCY) = max value. + #endif + + //#define AIR_EVACUATION // Cutter Vacuum / Laser Blower motor control with G-codes M10-M11 + #if ENABLED(AIR_EVACUATION) + #define AIR_EVACUATION_ACTIVE LOW // Set to "HIGH" if the on/off function is active HIGH + //#define AIR_EVACUATION_PIN 42 // Override the default Cutter Vacuum or Laser Blower pin + #endif + + //#define AIR_ASSIST // Air Assist control with G-codes M8-M9 + #if ENABLED(AIR_ASSIST) + #define AIR_ASSIST_ACTIVE LOW // Active state on air assist pin + //#define AIR_ASSIST_PIN 44 // Override the default Air Assist pin + #endif + + //#define SPINDLE_SERVO // A servo converting an angle to spindle power + #ifdef SPINDLE_SERVO + #define SPINDLE_SERVO_NR 0 // Index of servo used for spindle control + #define SPINDLE_SERVO_MIN 10 // Minimum angle for servo spindle + #endif + + /** + * Speed / Power can be set ('M3 S') and displayed in terms of: + * - PWM255 (S0 - S255) + * - PERCENT (S0 - S100) + * - RPM (S0 - S50000) Best for use with a spindle + * - SERVO (S0 - S180) + */ + #define CUTTER_POWER_UNIT PWM255 + + /** + * Relative Cutter Power + * Normally, 'M3 O' sets + * OCR power is relative to the range SPEED_POWER_MIN...SPEED_POWER_MAX. + * so input powers of 0...255 correspond to SPEED_POWER_MIN...SPEED_POWER_MAX + * instead of normal range (0 to SPEED_POWER_MAX). + * Best used with (e.g.) SuperPID router controller: S0 = 5,000 RPM and S255 = 30,000 RPM + */ + //#define CUTTER_POWER_RELATIVE // Set speed proportional to [SPEED_POWER_MIN...SPEED_POWER_MAX] + + #if ENABLED(SPINDLE_FEATURE) + //#define SPINDLE_CHANGE_DIR // Enable if your spindle controller can change spindle direction + #define SPINDLE_CHANGE_DIR_STOP // Enable if the spindle should stop before changing spin direction + #define SPINDLE_INVERT_DIR false // Set to "true" if the spin direction is reversed + + #define SPINDLE_LASER_POWERUP_DELAY 5000 // (ms) Delay to allow the spindle/laser to come up to speed/power + #define SPINDLE_LASER_POWERDOWN_DELAY 5000 // (ms) Delay to allow the spindle to stop + + /** + * M3/M4 Power Equation + * + * Each tool uses different value ranges for speed / power control. + * These parameters are used to convert between tool power units and PWM. + * + * Speed/Power = (PWMDC / 255 * 100 - SPEED_POWER_INTERCEPT) / SPEED_POWER_SLOPE + * PWMDC = (spdpwr - SPEED_POWER_MIN) / (SPEED_POWER_MAX - SPEED_POWER_MIN) / SPEED_POWER_SLOPE + */ + #if ENABLED(SPINDLE_LASER_USE_PWM) + #define SPEED_POWER_INTERCEPT 0 // (%) 0-100 i.e., Minimum power percentage + #define SPEED_POWER_MIN 5000 // (RPM) + #define SPEED_POWER_MAX 30000 // (RPM) SuperPID router controller 0 - 30,000 RPM + #define SPEED_POWER_STARTUP 25000 // (RPM) M3/M4 speed/power default (with no arguments) + + //#define DEFAULT_ACCELERATION_SPINDLE 1000 // (°/s/s) Default spindle acceleration (speed change with time) + #endif + + #else + + #if ENABLED(SPINDLE_LASER_USE_PWM) + #define SPEED_POWER_INTERCEPT 0 // (%) 0-100 i.e., Minimum power percentage + #define SPEED_POWER_MIN 0 // (%) 0-100 + #define SPEED_POWER_MAX 100 // (%) 0-100 + #define SPEED_POWER_STARTUP 80 // (%) M3/M4 speed/power default (with no arguments) + #endif + + // Define the minimum and maximum test pulse time values for a laser test fire function + #define LASER_TEST_PULSE_MIN 1 // (ms) Used with Laser Control Menu + #define LASER_TEST_PULSE_MAX 999 // (ms) Caution: Menu may not show more than 3 characters + + #define SPINDLE_LASER_POWERUP_DELAY 50 // (ms) Delay to allow the spindle/laser to come up to speed/power + #define SPINDLE_LASER_POWERDOWN_DELAY 50 // (ms) Delay to allow the spindle to stop + + /** + * Laser Safety Timeout + * + * The laser should be turned off when there is no movement for a period of time. + * Consider material flammability, cut rate, and G-code order when setting this + * value. Too low and it could turn off during a very slow move; too high and + * the material could ignite. + */ + #define LASER_SAFETY_TIMEOUT_MS 1000 // (ms) + + /** + * Any M3 or G1/2/3/5 command with the 'I' parameter enables continuous inline power mode. + * + * e.g., 'M3 I' enables continuous inline power which is processed by the planner. + * Power is stored in move blocks and applied when blocks are processed by the Stepper ISR. + * + * 'M4 I' sets dynamic mode which uses the current feedrate to calculate a laser power OCR value. + * + * Any move in dynamic mode will use the current feedrate to calculate the laser power. + * Feed rates are set by the F parameter of a move command e.g. G1 X0 Y10 F6000 + * Laser power would be calculated by bit shifting off 8 LSB's. In binary this is div 256. + * The calculation gives us ocr values from 0 to 255, values over F65535 will be set as 255 . + * More refined power control such as compensation for accel/decel will be addressed in future releases. + * + * M5 I clears inline mode and set power to 0, M5 sets the power output to 0 but leaves inline mode on. + */ + + /** + * Enable M3 commands for laser mode inline power planner syncing. + * This feature enables any M3 S-value to be injected into the block buffers while in + * CUTTER_MODE_CONTINUOUS. The option allows M3 laser power to be committed without waiting + * for a planner synchronization + */ + //#define LASER_POWER_SYNC + + /** + * Scale the laser's power in proportion to the movement rate. + * + * - Sets the entry power proportional to the entry speed over the nominal speed. + * - Ramps the power up every N steps to approximate the speed trapezoid. + * - Due to the limited power resolution this is only approximate. + */ + //#define LASER_POWER_TRAP + + // + // Laser I2C Ammeter (High precision INA226 low/high side module) + // + //#define I2C_AMMETER + #if ENABLED(I2C_AMMETER) + #define I2C_AMMETER_IMAX 0.1 // (Amps) Calibration value for the expected current range + #define I2C_AMMETER_SHUNT_RESISTOR 0.1 // (Ohms) Calibration shunt resistor value + #endif + + // + // Laser Coolant Flow Meter + // + //#define LASER_COOLANT_FLOW_METER + #if ENABLED(LASER_COOLANT_FLOW_METER) + #define FLOWMETER_PIN 20 // Requires an external interrupt-enabled pin (e.g., RAMPS 2,3,18,19,20,21) + #define FLOWMETER_PPL 5880 // (pulses/liter) Flow meter pulses-per-liter on the input pin + #define FLOWMETER_INTERVAL 1000 // (ms) Flow rate calculation interval in milliseconds + #define FLOWMETER_SAFETY // Prevent running the laser without the minimum flow rate set below + #if ENABLED(FLOWMETER_SAFETY) + #define FLOWMETER_MIN_LITERS_PER_MINUTE 1.5 // (liters/min) Minimum flow required when enabled + #endif + #endif + + #endif +#endif // SPINDLE_FEATURE || LASER_FEATURE + +/** + * Synchronous Laser Control with M106/M107 + * + * Marlin normally applies M106/M107 fan speeds at a time "soon after" processing + * a planner block. This is too inaccurate for a PWM/TTL laser attached to the fan + * header (as with some add-on laser kits). Enable this option to set fan/laser + * speeds with much more exact timing for improved print fidelity. + * + * NOTE: This option sacrifices some cooling fan speed options. + */ +//#define LASER_SYNCHRONOUS_M106_M107 + +/** + * Coolant Control + * + * Add the M7, M8, and M9 commands to turn mist or flood coolant on and off. + * + * Note: COOLANT_MIST_PIN and/or COOLANT_FLOOD_PIN must also be defined. + */ +//#define COOLANT_CONTROL +#if ENABLED(COOLANT_CONTROL) + #define COOLANT_MIST // Enable if mist coolant is present + #define COOLANT_FLOOD // Enable if flood coolant is present + #define COOLANT_MIST_INVERT false // Set "true" if the on/off function is reversed + #define COOLANT_FLOOD_INVERT false // Set "true" if the on/off function is reversed +#endif + +// @section filament width + +/** + * Filament Width Sensor + * + * Measures the filament width in real-time and adjusts + * flow rate to compensate for any irregularities. + * + * Also allows the measured filament diameter to set the + * extrusion rate, so the slicer only has to specify the + * volume. + * + * Only a single extruder is supported at this time. + * + * 34 RAMPS_14 : Analog input 5 on the AUX2 connector + * 81 PRINTRBOARD : Analog input 2 on the Exp1 connector (version B,C,D,E) + * 301 RAMBO : Analog input 3 + * + * Note: May require analog pins to be defined for other boards. + */ +//#define FILAMENT_WIDTH_SENSOR + +#if ENABLED(FILAMENT_WIDTH_SENSOR) + #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor. :[0,1,2,3,4] + #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber + + #define FILWIDTH_ERROR_MARGIN 1.0 // (mm) If a measurement differs too much from nominal width ignore it + #define MAX_MEASUREMENT_DELAY 20 // (bytes) Buffer size for stored measurements (1 byte per cm). Must be larger than MEASUREMENT_DELAY_CM. + + #define DEFAULT_MEASURED_FILAMENT_DIA DEFAULT_NOMINAL_FILAMENT_DIA // Set measured to nominal initially + + // Display filament width on the LCD status line. Status messages will expire after 5 seconds. + //#define FILAMENT_LCD_DISPLAY +#endif + +// @section power + +/** + * Power Monitor + * Monitor voltage (V) and/or current (A), and -when possible- power (W) + * + * Read and configure with M430 + * + * The current sensor feeds DC voltage (relative to the measured current) to an analog pin + * The voltage sensor feeds DC voltage (relative to the measured voltage) to an analog pin + */ +//#define POWER_MONITOR_CURRENT // Monitor the system current +//#define POWER_MONITOR_VOLTAGE // Monitor the system voltage + +#if ENABLED(POWER_MONITOR_CURRENT) + #define POWER_MONITOR_VOLTS_PER_AMP 0.05000 // Input voltage to the MCU analog pin per amp - DO NOT apply more than ADC_VREF! + #define POWER_MONITOR_CURRENT_OFFSET 0 // Offset (in amps) applied to the calculated current + #define POWER_MONITOR_FIXED_VOLTAGE 13.6 // Voltage for a current sensor with no voltage sensor (for power display) +#endif + +#if ENABLED(POWER_MONITOR_VOLTAGE) + #define POWER_MONITOR_VOLTS_PER_VOLT 0.077933 // Input voltage to the MCU analog pin per volt - DO NOT apply more than ADC_VREF! + #define POWER_MONITOR_VOLTAGE_OFFSET 0 // Offset (in volts) applied to the calculated voltage +#endif + +// @section safety + +/** + * Stepper Driver Anti-SNAFU Protection + * + * If the SAFE_POWER_PIN is defined for your board, Marlin will check + * that stepper drivers are properly plugged in before applying power. + * Disable protection if your stepper drivers don't support the feature. + */ +//#define DISABLE_DRIVER_SAFE_POWER_PROTECT + +// @section cnc + +/** + * CNC Coordinate Systems + * + * Enables G53 and G54-G59.3 commands to select coordinate systems + * and G92.1 to reset the workspace to native machine space. + */ +//#define CNC_COORDINATE_SYSTEMS + +// @section security + +/** + * Expected Printer Check + * Add the M16 G-code to compare a string to the MACHINE_NAME. + * M16 with a non-matching string causes the printer to halt. + */ +//#define EXPECTED_PRINTER_CHECK + +// @section volumetrics + +/** + * Disable all Volumetric extrusion options + */ +//#define NO_VOLUMETRICS + +#if DISABLED(NO_VOLUMETRICS) + /** + * Volumetric extrusion default state + * Activate to make volumetric extrusion the default method, + * with DEFAULT_NOMINAL_FILAMENT_DIA as the default diameter. + * + * M200 D0 to disable, M200 Dn to set a new diameter (and enable volumetric). + * M200 S0/S1 to disable/enable volumetric extrusion. + */ + //#define VOLUMETRIC_DEFAULT_ON + + //#define VOLUMETRIC_EXTRUDER_LIMIT + #if ENABLED(VOLUMETRIC_EXTRUDER_LIMIT) + /** + * Default volumetric extrusion limit in cubic mm per second (mm^3/sec). + * This factory setting applies to all extruders. + * Use 'M200 [T] L' to override and 'M502' to reset. + * A non-zero value activates Volume-based Extrusion Limiting. + */ + #define DEFAULT_VOLUMETRIC_EXTRUDER_LIMIT 0.00 // (mm^3/sec) + #define VOLUMETRIC_EXTRUDER_LIMIT_MAX 20 // (mm^3/sec) + #endif +#endif + +// @section reporting + +/** + * Extra options for the M114 "Current Position" report + */ +//#define M114_DETAIL // Use 'M114 D' for details to check planner calculations +//#define M114_REALTIME // Real current position based on forward kinematics +//#define M114_LEGACY // M114 used to synchronize on every call. Enable if needed. + +/** + * Auto-report fan speed with M123 S + * Requires fans with tachometer pins + */ +//#define AUTO_REPORT_FANS + +//#define REPORT_FAN_CHANGE // Report the new fan speed when changed by M106 (and others) + +/** + * Auto-report temperatures with M155 S + */ +#define AUTO_REPORT_TEMPERATURES +#if ENABLED(AUTO_REPORT_TEMPERATURES) && TEMP_SENSOR_REDUNDANT + //#define AUTO_REPORT_REDUNDANT // Include the "R" sensor in the auto-report +#endif + +/** + * Auto-report position with M154 S + */ +//#define AUTO_REPORT_POSITION +#if ENABLED(AUTO_REPORT_POSITION) + //#define AUTO_REPORT_REAL_POSITION // Auto-report the real position +#endif + +/** + * M115 - Report capabilities. Disable to save ~1150 bytes of flash. + * Some hosts (and serial TFT displays) rely on this feature. + */ +#define CAPABILITIES_REPORT +#if ENABLED(CAPABILITIES_REPORT) + // Include capabilities in M115 output + #define EXTENDED_CAPABILITIES_REPORT + #if ENABLED(EXTENDED_CAPABILITIES_REPORT) + //#define M115_GEOMETRY_REPORT + #endif +#endif + +// @section gcode + +/** + * Spend 28 bytes of SRAM to optimize the G-code parser + */ +#define FASTER_GCODE_PARSER +#if ENABLED(FASTER_GCODE_PARSER) + //#define GCODE_QUOTED_STRINGS // Support for quoted string parameters +#endif + +/** + * Support for MeatPack G-code compression (https://github.com/scottmudge/OctoPrint-MeatPack) + */ +//#define MEATPACK_ON_SERIAL_PORT_1 +//#define MEATPACK_ON_SERIAL_PORT_2 + +//#define GCODE_CASE_INSENSITIVE // Accept G-code sent to the firmware in lowercase + +//#define REPETIER_GCODE_M360 // Add commands originally from Repetier FW + +/** + * Enable M111 debug flags 1=ECHO, 2=INFO, 4=ERRORS (unimplemented). + * Disable to save some flash. Some hosts (Repetier Host) may rely on this feature. + */ +#define DEBUG_FLAGS_GCODE + +/** + * Enable this option for a leaner build of Marlin that removes + * workspace offsets to slightly optimize performance. + * G92 will revert to its behavior from Marlin 1.0. + */ +//#define NO_WORKSPACE_OFFSETS + +/** + * Disable M206 and M428 if you don't need home offsets. + */ +//#define NO_HOME_OFFSETS + +/** + * CNC G-code options + * Support CNC-style G-code dialects used by laser cutters, drawing machine cams, etc. + * Note that G0 feedrates should be used with care for 3D printing (if used at all). + * High feedrates may cause ringing and harm print quality. + */ +//#define PAREN_COMMENTS // Support for parentheses-delimited comments +//#define GCODE_MOTION_MODES // Remember the motion mode (G0 G1 G2 G3 G5 G38.X) and apply for X Y Z E F, etc. + +// Enable and set a (default) feedrate for all G0 moves +//#define G0_FEEDRATE 3000 // (mm/min) +#ifdef G0_FEEDRATE + //#define VARIABLE_G0_FEEDRATE // The G0 feedrate is set by F in G0 motion mode +#endif + +/** + * Startup commands + * + * Execute certain G-code commands immediately after power-on. + */ +//#define STARTUP_COMMANDS "M17 Z" + +/** + * G-code Macros + * + * Add G-codes M810-M819 to define and run G-code macros. + * Macros are not saved to EEPROM. + */ +//#define GCODE_MACROS +#if ENABLED(GCODE_MACROS) + #define GCODE_MACROS_SLOTS 5 // Up to 10 may be used + #define GCODE_MACROS_SLOT_SIZE 50 // Maximum length of a single macro +#endif + +/** + * User-defined menu items to run custom G-code. + * Up to 25 may be defined, but the actual number is LCD-dependent. + */ + +// @section custom main menu + +// Custom Menu: Main Menu +//#define CUSTOM_MENU_MAIN +#if ENABLED(CUSTOM_MENU_MAIN) + //#define CUSTOM_MENU_MAIN_TITLE "Custom Commands" + #define CUSTOM_MENU_MAIN_SCRIPT_DONE "M117 User Script Done" + #define CUSTOM_MENU_MAIN_SCRIPT_AUDIBLE_FEEDBACK + //#define CUSTOM_MENU_MAIN_SCRIPT_RETURN // Return to status screen after a script + #define CUSTOM_MENU_MAIN_ONLY_IDLE // Only show custom menu when the machine is idle + + #define MAIN_MENU_ITEM_1_DESC "Home & UBL Info" + #define MAIN_MENU_ITEM_1_GCODE "G28\nG29 W" + //#define MAIN_MENU_ITEM_1_CONFIRM // Show a confirmation dialog before this action + + #define MAIN_MENU_ITEM_2_DESC "Preheat for " PREHEAT_1_LABEL + #define MAIN_MENU_ITEM_2_GCODE "M140 S" STRINGIFY(PREHEAT_1_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND) + //#define MAIN_MENU_ITEM_2_CONFIRM + + //#define MAIN_MENU_ITEM_3_DESC "Preheat for " PREHEAT_2_LABEL + //#define MAIN_MENU_ITEM_3_GCODE "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_2_TEMP_HOTEND) + //#define MAIN_MENU_ITEM_3_CONFIRM + + //#define MAIN_MENU_ITEM_4_DESC "Heat Bed/Home/Level" + //#define MAIN_MENU_ITEM_4_GCODE "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nG28\nG29" + //#define MAIN_MENU_ITEM_4_CONFIRM + + //#define MAIN_MENU_ITEM_5_DESC "Home & Info" + //#define MAIN_MENU_ITEM_5_GCODE "G28\nM503" + //#define MAIN_MENU_ITEM_5_CONFIRM +#endif + +// @section custom config menu + +// Custom Menu: Configuration Menu +//#define CUSTOM_MENU_CONFIG +#if ENABLED(CUSTOM_MENU_CONFIG) + //#define CUSTOM_MENU_CONFIG_TITLE "Custom Commands" + #define CUSTOM_MENU_CONFIG_SCRIPT_DONE "M117 Wireless Script Done" + #define CUSTOM_MENU_CONFIG_SCRIPT_AUDIBLE_FEEDBACK + //#define CUSTOM_MENU_CONFIG_SCRIPT_RETURN // Return to status screen after a script + #define CUSTOM_MENU_CONFIG_ONLY_IDLE // Only show custom menu when the machine is idle + + #define CONFIG_MENU_ITEM_1_DESC "Wifi ON" + #define CONFIG_MENU_ITEM_1_GCODE "M118 [ESP110] WIFI-STA pwd=12345678" + //#define CONFIG_MENU_ITEM_1_CONFIRM // Show a confirmation dialog before this action + + #define CONFIG_MENU_ITEM_2_DESC "Bluetooth ON" + #define CONFIG_MENU_ITEM_2_GCODE "M118 [ESP110] BT pwd=12345678" + //#define CONFIG_MENU_ITEM_2_CONFIRM + + //#define CONFIG_MENU_ITEM_3_DESC "Radio OFF" + //#define CONFIG_MENU_ITEM_3_GCODE "M118 [ESP110] OFF pwd=12345678" + //#define CONFIG_MENU_ITEM_3_CONFIRM + + //#define CONFIG_MENU_ITEM_4_DESC "Wifi ????" + //#define CONFIG_MENU_ITEM_4_GCODE "M118 ????" + //#define CONFIG_MENU_ITEM_4_CONFIRM + + //#define CONFIG_MENU_ITEM_5_DESC "Wifi ????" + //#define CONFIG_MENU_ITEM_5_GCODE "M118 ????" + //#define CONFIG_MENU_ITEM_5_CONFIRM +#endif + +// @section custom buttons + +/** + * User-defined buttons to run custom G-code. + * Up to 25 may be defined. + */ +//#define CUSTOM_USER_BUTTONS +#if ENABLED(CUSTOM_USER_BUTTONS) + //#define BUTTON1_PIN -1 + #if PIN_EXISTS(BUTTON1) + #define BUTTON1_HIT_STATE LOW // State of the triggered button. NC=LOW. NO=HIGH. + #define BUTTON1_WHEN_PRINTING false // Button allowed to trigger during printing? + #define BUTTON1_GCODE "G28" + #define BUTTON1_DESC "Homing" // Optional string to set the LCD status + #endif + + //#define BUTTON2_PIN -1 + #if PIN_EXISTS(BUTTON2) + #define BUTTON2_HIT_STATE LOW + #define BUTTON2_WHEN_PRINTING false + #define BUTTON2_GCODE "M140 S" STRINGIFY(PREHEAT_1_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND) + #define BUTTON2_DESC "Preheat for " PREHEAT_1_LABEL + #endif + + //#define BUTTON3_PIN -1 + #if PIN_EXISTS(BUTTON3) + #define BUTTON3_HIT_STATE LOW + #define BUTTON3_WHEN_PRINTING false + #define BUTTON3_GCODE "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_2_TEMP_HOTEND) + #define BUTTON3_DESC "Preheat for " PREHEAT_2_LABEL + #endif +#endif + +// @section host + +/** + * Host Action Commands + * + * Define host streamer action commands in compliance with the standard. + * + * See https://reprap.org/wiki/G-code#Action_commands + * Common commands ........ poweroff, pause, paused, resume, resumed, cancel + * G29_RETRY_AND_RECOVER .. probe_rewipe, probe_failed + * + * Some features add reason codes to extend these commands. + * + * Host Prompt Support enables Marlin to use the host for user prompts so + * filament runout and other processes can be managed from the host side. + */ +//#define HOST_ACTION_COMMANDS +#if ENABLED(HOST_ACTION_COMMANDS) + //#define HOST_PAUSE_M76 // Tell the host to pause in response to M76 + //#define HOST_PROMPT_SUPPORT // Initiate host prompts to get user feedback + #if ENABLED(HOST_PROMPT_SUPPORT) + //#define HOST_STATUS_NOTIFICATIONS // Send some status messages to the host as notifications + #endif + //#define HOST_START_MENU_ITEM // Add a menu item that tells the host to start + //#define HOST_SHUTDOWN_MENU_ITEM // Add a menu item that tells the host to shut down +#endif + +// @section extras + +/** + * Cancel Objects + * + * Implement M486 to allow Marlin to skip objects + */ +//#define CANCEL_OBJECTS +#if ENABLED(CANCEL_OBJECTS) + #define CANCEL_OBJECTS_REPORTING // Emit the current object as a status message +#endif + +/** + * I2C position encoders for closed loop control. + * Developed by Chris Barr at Aus3D. + * + * Wiki: https://wiki.aus3d.com.au/Magnetic_Encoder + * Github: https://github.com/Aus3D/MagneticEncoder + * + * Supplier: https://aus3d.com.au/products/magnetic-encoder-module + * Alternative Supplier: https://reliabuild3d.com/ + * + * Reliabuild encoders have been modified to improve reliability. + * @section i2c encoders + */ + +//#define I2C_POSITION_ENCODERS +#if ENABLED(I2C_POSITION_ENCODERS) + + #define I2CPE_ENCODER_CNT 1 // The number of encoders installed; max of 5 + // encoders supported currently. + + #define I2CPE_ENC_1_ADDR I2CPE_PRESET_ADDR_X // I2C address of the encoder. 30-200. + #define I2CPE_ENC_1_AXIS X_AXIS // Axis the encoder module is installed on. _AXIS. + #define I2CPE_ENC_1_TYPE I2CPE_ENC_TYPE_LINEAR // Type of encoder: I2CPE_ENC_TYPE_LINEAR -or- + // I2CPE_ENC_TYPE_ROTARY. + #define I2CPE_ENC_1_TICKS_UNIT 2048 // 1024 for magnetic strips with 2mm poles; 2048 for + // 1mm poles. For linear encoders this is ticks / mm, + // for rotary encoders this is ticks / revolution. + //#define I2CPE_ENC_1_TICKS_REV (16 * 200) // Only needed for rotary encoders; number of stepper + // steps per full revolution (motor steps/rev * microstepping) + //#define I2CPE_ENC_1_INVERT // Invert the direction of axis travel. + #define I2CPE_ENC_1_EC_METHOD I2CPE_ECM_MICROSTEP // Type of error error correction. + #define I2CPE_ENC_1_EC_THRESH 0.10 // Threshold size for error (in mm) above which the + // printer will attempt to correct the error; errors + // smaller than this are ignored to minimize effects of + // measurement noise / latency (filter). + + #define I2CPE_ENC_2_ADDR I2CPE_PRESET_ADDR_Y // Same as above, but for encoder 2. + #define I2CPE_ENC_2_AXIS Y_AXIS + #define I2CPE_ENC_2_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_ENC_2_TICKS_UNIT 2048 + //#define I2CPE_ENC_2_TICKS_REV (16 * 200) + //#define I2CPE_ENC_2_INVERT + #define I2CPE_ENC_2_EC_METHOD I2CPE_ECM_MICROSTEP + #define I2CPE_ENC_2_EC_THRESH 0.10 + + #define I2CPE_ENC_3_ADDR I2CPE_PRESET_ADDR_Z // Encoder 3. Add additional configuration options + #define I2CPE_ENC_3_AXIS Z_AXIS // as above, or use defaults below. + + #define I2CPE_ENC_4_ADDR I2CPE_PRESET_ADDR_E // Encoder 4. + #define I2CPE_ENC_4_AXIS E_AXIS + + #define I2CPE_ENC_5_ADDR 34 // Encoder 5. + #define I2CPE_ENC_5_AXIS E_AXIS + + // Default settings for encoders which are enabled, but without settings configured above. + #define I2CPE_DEF_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_DEF_ENC_TICKS_UNIT 2048 + #define I2CPE_DEF_TICKS_REV (16 * 200) + #define I2CPE_DEF_EC_METHOD I2CPE_ECM_NONE + #define I2CPE_DEF_EC_THRESH 0.1 + + //#define I2CPE_ERR_THRESH_ABORT 100.0 // Threshold size for error (in mm) error on any given + // axis after which the printer will abort. Comment out to + // disable abort behavior. + + #define I2CPE_TIME_TRUSTED 10000 // After an encoder fault, there must be no further fault + // for this amount of time (in ms) before the encoder + // is trusted again. + + /** + * Position is checked every time a new command is executed from the buffer but during long moves, + * this setting determines the minimum update time between checks. A value of 100 works well with + * error rolling average when attempting to correct only for skips and not for vibration. + */ + #define I2CPE_MIN_UPD_TIME_MS 4 // (ms) Minimum time between encoder checks. + + // Use a rolling average to identify persistent errors that indicate skips, as opposed to vibration and noise. + #define I2CPE_ERR_ROLLING_AVERAGE + +#endif // I2C_POSITION_ENCODERS + +/** + * Analog Joystick(s) + * @section joystick + */ +//#define JOYSTICK +#if ENABLED(JOYSTICK) + #define JOY_X_PIN 5 // RAMPS: Suggested pin A5 on AUX2 + #define JOY_Y_PIN 10 // RAMPS: Suggested pin A10 on AUX2 + #define JOY_Z_PIN 12 // RAMPS: Suggested pin A12 on AUX2 + #define JOY_EN_PIN 44 // RAMPS: Suggested pin D44 on AUX2 + + //#define INVERT_JOY_X // Enable if X direction is reversed + //#define INVERT_JOY_Y // Enable if Y direction is reversed + //#define INVERT_JOY_Z // Enable if Z direction is reversed + + // Use M119 with JOYSTICK_DEBUG to find reasonable values after connecting: + #define JOY_X_LIMITS { 5600, 8190-100, 8190+100, 10800 } // min, deadzone start, deadzone end, max + #define JOY_Y_LIMITS { 5600, 8250-100, 8250+100, 11000 } + #define JOY_Z_LIMITS { 4800, 8080-100, 8080+100, 11550 } + //#define JOYSTICK_DEBUG +#endif + +/** + * Mechanical Gantry Calibration + * Modern replacement for the Průša TMC_Z_CALIBRATION. + * Adds capability to work with any adjustable current drivers. + * Implemented as G34 because M915 is deprecated. + * @section calibrate + */ +//#define MECHANICAL_GANTRY_CALIBRATION +#if ENABLED(MECHANICAL_GANTRY_CALIBRATION) + #define GANTRY_CALIBRATION_CURRENT 600 // Default calibration current in ma + #define GANTRY_CALIBRATION_EXTRA_HEIGHT 15 // Extra distance in mm past Z_###_POS to move + #define GANTRY_CALIBRATION_FEEDRATE 500 // Feedrate for correction move + //#define GANTRY_CALIBRATION_TO_MIN // Enable to calibrate Z in the MIN direction + + //#define GANTRY_CALIBRATION_SAFE_POSITION XY_CENTER // Safe position for nozzle + //#define GANTRY_CALIBRATION_XY_PARK_FEEDRATE 3000 // XY Park Feedrate - MMM + //#define GANTRY_CALIBRATION_COMMANDS_PRE "" + #define GANTRY_CALIBRATION_COMMANDS_POST "G28" // G28 highly recommended to ensure an accurate position +#endif + +/** + * Instant freeze / unfreeze functionality + * Potentially useful for rapid stop that allows being resumed. Halts stepper movement. + * Note this does NOT pause spindles, lasers, fans, heaters or any other auxiliary device. + * @section interface + */ +//#define FREEZE_FEATURE +#if ENABLED(FREEZE_FEATURE) + //#define FREEZE_PIN 41 // Override the default (KILL) pin here + #define FREEZE_STATE LOW // State of pin indicating freeze +#endif + +/** + * MAX7219 Debug Matrix + * + * Add support for a low-cost 8x8 LED Matrix based on the Max7219 chip as a realtime status display. + * Requires 3 signal wires. Some useful debug options are included to demonstrate its usage. + * @section debug matrix + */ +//#define MAX7219_DEBUG +#if ENABLED(MAX7219_DEBUG) + #define MAX7219_CLK_PIN 64 + #define MAX7219_DIN_PIN 57 + #define MAX7219_LOAD_PIN 44 + + //#define MAX7219_GCODE // Add the M7219 G-code to control the LED matrix + #define MAX7219_INIT_TEST 2 // Test pattern at startup: 0=none, 1=sweep, 2=spiral + #define MAX7219_NUMBER_UNITS 1 // Number of Max7219 units in chain. + #define MAX7219_ROTATE 0 // Rotate the display clockwise (in multiples of +/- 90°) + // connector at: right=0 bottom=-90 top=90 left=180 + //#define MAX7219_REVERSE_ORDER // The order of the LED matrix units may be reversed + //#define MAX7219_REVERSE_EACH // The LEDs in each matrix unit row may be reversed + //#define MAX7219_SIDE_BY_SIDE // Big chip+matrix boards can be chained side-by-side + + /** + * Sample debug features + * If you add more debug displays, be careful to avoid conflicts! + */ + #define MAX7219_DEBUG_PRINTER_ALIVE // Blink corner LED of 8x8 matrix to show that the firmware is functioning + #define MAX7219_DEBUG_PLANNER_HEAD 2 // Show the planner queue head position on this and the next LED matrix row + #define MAX7219_DEBUG_PLANNER_TAIL 4 // Show the planner queue tail position on this and the next LED matrix row + + #define MAX7219_DEBUG_PLANNER_QUEUE 0 // Show the current planner queue depth on this and the next LED matrix row + // If you experience stuttering, reboots, etc. this option can reveal how + // tweaks made to the configuration are affecting the printer in real-time. + #define MAX7219_DEBUG_PROFILE 6 // Display the fraction of CPU time spent in profiled code on this LED matrix + // row. By default idle() is profiled so this shows how "idle" the processor is. + // See class CodeProfiler. + //#define MAX7219_DEBUG_MULTISTEPPING 6 // Show multi-stepping 1 to 128 on this LED matrix row. + //#define MAX7219_DEBUG_SLOWDOWN 6 // Count (mod 16) how many times SLOWDOWN has reduced print speed. + //#define MAX7219_REINIT_ON_POWERUP // Re-initialize MAX7129 when power supply turns on +#endif + +/** + * NanoDLP Sync support + * + * Support for Synchronized Z moves when used with NanoDLP. G0/G1 axis moves will + * output a "Z_move_comp" string to enable synchronization with DLP projector exposure. + * This feature allows you to use [[WaitForDoneMessage]] instead of M400 commands. + * @section nanodlp + */ +//#define NANODLP_Z_SYNC +#if ENABLED(NANODLP_Z_SYNC) + //#define NANODLP_ALL_AXIS // Send a "Z_move_comp" report for any axis move (not just Z). +#endif + +/** + * Ethernet. Use M552 to enable and set the IP address. + * @section network + */ +#if HAS_ETHERNET + #define MAC_ADDRESS { 0xDE, 0xAD, 0xBE, 0xEF, 0xF0, 0x0D } // A MAC address unique to your network +#endif + +/** + * Native ESP32 board with WiFi or add-on ESP32 WiFi-101 module + */ +//#define WIFISUPPORT // Marlin embedded WiFi management. Not needed for simple WiFi serial port. +//#define ESP3D_WIFISUPPORT // ESP3D Library WiFi management (https://github.com/luc-github/ESP3DLib) + +/** + * Extras for an ESP32-based motherboard with WIFISUPPORT + * These options don't apply to add-on WiFi modules based on ESP32 WiFi101. + */ +#if ANY(WIFISUPPORT, ESP3D_WIFISUPPORT) + //#define WEBSUPPORT // Start a webserver (which may include auto-discovery) using SPIFFS + //#define OTASUPPORT // Support over-the-air firmware updates + //#define WIFI_CUSTOM_COMMAND // Accept feature config commands (e.g., WiFi ESP3D) from the host + + /** + * To set a default WiFi SSID / Password, create a file called Configuration_Secure.h with + * the following defines, customized for your network. This specific file is excluded via + * .gitignore to prevent it from accidentally leaking to the public. + * + * #define WIFI_SSID "WiFi SSID" + * #define WIFI_PWD "WiFi Password" + */ + //#include "Configuration_Secure.h" // External file with WiFi SSID / Password +#endif + +// @section multi-material + +/** + * Průša Multi-Material Unit (MMU) + * Enable in Configuration.h + * + * These devices allow a single stepper driver on the board to drive + * multi-material feeders with any number of stepper motors. + */ +#if HAS_PRUSA_MMU1 + /** + * This option only allows the multiplexer to switch on tool-change. + * Additional options to configure custom E moves are pending. + * + * Override the default DIO selector pins here, if needed. + * Some pins files may provide defaults for these pins. + */ + //#define E_MUX0_PIN 40 // Always Required + //#define E_MUX1_PIN 42 // Needed for 3 to 8 inputs + //#define E_MUX2_PIN 44 // Needed for 5 to 8 inputs + +#elif HAS_PRUSA_MMU2 || HAS_PRUSA_MMU3 + // Common settings for MMU2/MMU2S/MMU3 + // Serial port used for communication with MMU2/MMU2S/MMU3. + #define MMU_SERIAL_PORT 2 + #define MMU_BAUD 115200 + + //#define MMU_RST_PIN 23 // Define this pin to use Hardware Reset for MMU2/MMU2S/MMU3 + + //#define MMU_MENUS // Add an LCD menu for MMU2/MMU2S/MMU3 + + //#define MMU_DEBUG // Write debug info to serial output + + // Options pertaining to MMU2 and MMU2S + #if HAS_PRUSA_MMU2 + // Enable if the MMU2 has 12V stepper motors (MMU2 Firmware 1.0.2 and up) + //#define MMU2_MODE_12V + + // Settings for filament load / unload from the LCD menu. + // This is for Průša MK3-style extruders. Customize for your hardware. + #define MMU2_FILAMENTCHANGE_EJECT_FEED 80.0 + + // G-code to execute when MMU2 F.I.N.D.A. probe detects filament runout + #define MMU2_FILAMENT_RUNOUT_SCRIPT "M600" + + // MMU2 sequences use mm/min. Not compatible with MMU3, which use mm/sec. + #define MMU2_LOAD_TO_NOZZLE_SEQUENCE \ + { 4.4, 871 }, \ + { 10.0, 1393 }, \ + { 4.4, 871 }, \ + { 10.0, 198 } + + #define MMU2_RAMMING_SEQUENCE \ + { 1.0, 1000 }, \ + { 1.0, 1500 }, \ + { 2.0, 2000 }, \ + { 1.5, 3000 }, \ + { 2.5, 4000 }, \ + { -15.0, 5000 }, \ + { -14.0, 1200 }, \ + { -6.0, 600 }, \ + { 10.0, 700 }, \ + { -10.0, 400 }, \ + { -50.0, 2000 } + + #endif // HAS_PRUSA_MMU2 + + /** + * Options pertaining to MMU2S devices + * Requires the MK3S extruder with a sensor at the extruder idler, like the MMU2S. + * See https://help.prusa3d.com/guide/3b-mk3s-mk2-5s-extruder-upgrade_41560#42048, step 11 + */ + #if HAS_PRUSA_MMU2S + #define MMU2_C0_RETRY 5 // Number of retries (total time = timeout*retries) + + /** + * This is called after the filament runout sensor is triggered to check if + * the filament has been loaded properly by moving the filament back and + * forth to see if the filament runout sensor is going to get triggered + * again, which should not occur if the filament is properly loaded. + * + * Thus, the MMU2_CAN_LOAD_SEQUENCE should contain some forward and + * backward moves. The forward moves should be greater than the backward + * moves. + * + * This is useless if your filament runout sensor is way behind the gears. + * In that case use {0, MMU2_CAN_LOAD_FEEDRATE} + * + * Adjust MMU2_CAN_LOAD_SEQUENCE according to your setup. + */ + #define MMU2_CAN_LOAD_FEEDRATE 800 // (mm/min) + #define MMU2_CAN_LOAD_SEQUENCE \ + { 5.0, MMU2_CAN_LOAD_FEEDRATE }, \ + { 15.0, MMU2_CAN_LOAD_FEEDRATE }, \ + { -10.0, MMU2_CAN_LOAD_FEEDRATE } + + #define MMU2_CAN_LOAD_RETRACT 6.0 // (mm) Keep under the distance between Load Sequence values + #define MMU2_CAN_LOAD_DEVIATION 0.8 // (mm) Acceptable deviation + + #define MMU2_CAN_LOAD_INCREMENT 0.2 // (mm) To reuse within MMU2 module + #define MMU2_CAN_LOAD_INCREMENT_SEQUENCE \ + { -MMU2_CAN_LOAD_INCREMENT, MMU2_CAN_LOAD_FEEDRATE } + + // Continue unloading if sensor detects filament after the initial unload move + //#define MMU_IR_UNLOAD_MOVE + + #elif HAS_PRUSA_MMU3 + + // MMU3 settings + + #define MMU3_HAS_CUTTER // Enable cutter related functionality + + #define MMU3_MAX_RETRIES 3 // Number of retries (total time = timeout*retries) + + // As discussed with our PrusaSlicer profile specialist + // - ToolChange shall not try to push filament into the very tip of the nozzle + // to have some space for additional G-code to tune the extruded filament length + // in the profile + // Beware - this value is used to initialize the MMU logic layer - it will be sent to the MMU upon line up (written into its 8bit register 0x0b) + // However - in the G-code we can get a request to set the extra load distance at runtime to something else (M708 A0xb Xsomething). + // The printer intercepts such a call and sets its extra load distance to match the new value as well. + #define MMU3_FILAMENT_SENSOR_E_POSITION 0 // (mm) + #define _MMU3_LOAD_DISTANCE_PAST_GEARS 5 // (mm) + #define MMU3_TOOL_CHANGE_LOAD_LENGTH (MMU3_FILAMENT_SENSOR_E_POSITION + _MMU3_LOAD_DISTANCE_PAST_GEARS) // (mm) + + #define MMU3_LOAD_TO_NOZZLE_FEED_RATE 20.0 // (mm/s) + + #define MMU3_VERIFY_LOAD_TO_NOZZLE_FEED_RATE 50.0 // (mm/s) + #define _MMU3_VERIFY_LOAD_TO_NOZZLE_TWEAK -5.0 // (mm) Amount to adjust the length for verifying load-to-nozzle + + // The first thing the MMU does is initialize its axis. + // Meanwhile the E-motor will unload 20mm of filament in about 1 second. + #define MMU3_RETRY_UNLOAD_TO_FINDA_LENGTH 80.0 // (mm) + #define MMU3_RETRY_UNLOAD_TO_FINDA_FEED_RATE 80.0 // (mm/s) + + // After loading a new filament, the printer will extrude this length of filament + // then retract to the original position. This is used to check if the filament sensor + // reading flickers or filament is jammed. + #define _MMU_EXTRUDER_PTFE_LENGTH 42.3 // (mm) + #define _MMU_EXTRUDER_HEATBREAK_LENGTH 17.7 // (mm) + #define MMU3_CHECK_FILAMENT_PRESENCE_EXTRUSION_LENGTH (MMU3_FILAMENT_SENSOR_E_POSITION + _MMU_EXTRUDER_PTFE_LENGTH + _MMU_EXTRUDER_HEATBREAK_LENGTH + _MMU3_VERIFY_LOAD_TO_NOZZLE_TWEAK) // (mm) + + /** + * SpoolJoin Consumes All Filament -- EXPERIMENTAL + * + * SpoolJoin normally triggers when FINDA sensor untriggers while printing. + * This is the default behaviour and it doesn't consume all the filament + * before triggering a filament change. This leaves some filament in the + * current slot and before switching to the next slot it is unloaded. + * + * Enabling this option will trigger the filament change when both FINDA + * and Filament Runout Sensor triggers during the print and it allows the + * filament in the current slot to be completely consumed before doing the + * filament change. But this can cause problems as a little bit of filament + * will be left between the extruder gears (thinking that the filament + * sensor is triggered through the gears) and the end of the PTFE tube and + * can cause filament load issues. + */ + //#define MMU3_SPOOL_JOIN_CONSUMES_ALL_FILAMENT + + // MMU3 sequences use mm/sec. Not compatible with MMU2 which use mm/min. + #define MMU3_LOAD_TO_NOZZLE_SEQUENCE \ + { _MMU_EXTRUDER_PTFE_LENGTH, MMM_TO_MMS(810) }, /* (13.5 mm/s) Fast load ahead of heatbreak */ \ + { _MMU_EXTRUDER_HEATBREAK_LENGTH, MMM_TO_MMS(198) } /* ( 3.3 mm/s) Slow load after heatbreak */ + + #define MMU3_RAMMING_SEQUENCE \ + { 0.2816, MMM_TO_MMS(1339.0) }, \ + { 0.3051, MMM_TO_MMS(1451.0) }, \ + { 0.3453, MMM_TO_MMS(1642.0) }, \ + { 0.3990, MMM_TO_MMS(1897.0) }, \ + { 0.4761, MMM_TO_MMS(2264.0) }, \ + { 0.5767, MMM_TO_MMS(2742.0) }, \ + { 0.5691, MMM_TO_MMS(3220.0) }, \ + { 0.1081, MMM_TO_MMS(3220.0) }, \ + { 0.7644, MMM_TO_MMS(3635.0) }, \ + { 0.8248, MMM_TO_MMS(3921.0) }, \ + { 0.8483, MMM_TO_MMS(4033.0) }, \ + { -15.0, MMM_TO_MMS(6000.0) }, \ + { -24.5, MMM_TO_MMS(1200.0) }, \ + { -7.0, MMM_TO_MMS( 600.0) }, \ + { -3.5, MMM_TO_MMS( 360.0) }, \ + { 20.0, MMM_TO_MMS( 454.0) }, \ + { -20.0, MMM_TO_MMS( 303.0) }, \ + { -35.0, MMM_TO_MMS(2000.0) } + + #else // MMU2 (not MMU2S) + + /** + * MMU2 Extruder Sensor + * + * Support for a Průša (or other) IR Sensor to detect filament near the extruder + * and make loading more reliable. Suitable for an extruder equipped with a filament + * sensor less than 38mm from the gears. + * + * During loading the extruder will stop when the sensor is triggered, then do a last + * move up to the gears. If no filament is detected, the MMU2 can make some more attempts. + * If all attempts fail, a filament runout will be triggered. + */ + //#define MMU2_EXTRUDER_SENSOR + #if ENABLED(MMU2_EXTRUDER_SENSOR) + #define MMU2_LOADING_ATTEMPTS_NR 5 // Number of times to try loading filament before failure + #endif + + #endif + +#endif // HAS_PRUSA_MMU2 || HAS_PRUSA_MMU3 + +/** + * Advanced Print Counter settings + * @section stats + */ +#if ENABLED(PRINTCOUNTER) + #define SERVICE_WARNING_BUZZES 3 + // Activate up to 3 service interval watchdogs + //#define SERVICE_NAME_1 "Service S" + //#define SERVICE_INTERVAL_1 100 // print hours + //#define SERVICE_NAME_2 "Service L" + //#define SERVICE_INTERVAL_2 200 // print hours + //#define SERVICE_NAME_3 "Service 3" + //#define SERVICE_INTERVAL_3 1 // print hours +#endif + +// @section develop + +// +// M100 Free Memory Watcher to debug memory usage +// +//#define M100_FREE_MEMORY_WATCHER + +// +// M42 - Set pin states +// +//#define DIRECT_PIN_CONTROL + +// +// M43 - display pin status, toggle pins, watch pins, watch endstops & toggle LED, test servo probe +// +#define PINS_DEBUGGING + +// Enable Tests that will run at startup and produce a report +//#define MARLIN_TEST_BUILD + +// Enable Marlin dev mode which adds some special commands +//#define MARLIN_DEV_MODE + +#if ENABLED(MARLIN_DEV_MODE) + /** + * D576 - Buffer Monitoring + * To help diagnose print quality issues stemming from empty command buffers. + */ + //#define BUFFER_MONITORING +#endif + +/** + * Postmortem Debugging captures misbehavior and outputs the CPU status and backtrace to serial. + * When running in the debugger it will break for debugging. This is useful to help understand + * a crash from a remote location. Requires ~400 bytes of SRAM and 5Kb of flash. + */ +//#define POSTMORTEM_DEBUGGING + +/** + * Software Reset options + */ +//#define SOFT_RESET_VIA_SERIAL // 'KILL' and '^X' commands will soft-reset the controller +//#define SOFT_RESET_ON_KILL // Use a digital button to soft-reset the controller after KILL + +// Report uncleaned reset reason from register r2 instead of MCUSR. Supported by Optiboot on AVR. +//#define OPTIBOOT_RESET_REASON + +// Shrink the build for smaller boards by sacrificing some serial feedback +//#define MARLIN_SMALL_BUILD diff --git a/config/examples/delta/Micromake-D1/MKS-Gen-L-V2.1/README.md b/config/examples/delta/Micromake-D1/MKS-Gen-L-V2.1/README.md new file mode 100644 index 0000000000..186b2ed5d2 --- /dev/null +++ b/config/examples/delta/Micromake-D1/MKS-Gen-L-V2.1/README.md @@ -0,0 +1,42 @@ +# Micromake D1 with MKS Gen L V2.1 +## Configuration & wiring guide + +- **Board**: [Makerbase MKS Gen L V2.1](//github.com/makerbase-mks/MKS-GEN_L/wiki/MKS_GEN_L_V2) +- **Display**: RepRapDiscount Smart Controller (LCD 2004, 20×4) +- **Drivers**: TMC2209 @ 1⁄16 µ‑step (UART mode) +- **Features**: Single Extruder, Heated bed, Fixed Z‑probe, Dual Fans + +### 1. About these configurations +- `Configuration.h` & `Configuration_adv.h` already tuned for Micromake D1 geometry. +- English 20×4 LCD presets. +- Safe temperature limits (270°C hot‑end / 120°C bed). +- Smart auto‑fan on MOSFET D. +- EEPROM, SD‑card, auto‑delta‑calibration G33 ready. + +### 2. Pin correspondence (old board → new) + +| Function | [Makeboard Mini 2.1.2](assets/makeboard_mini_2.1.2.webp) | [MKS Gen L V2.1](assets/mks_gen_l_v2.1.webp) | +|--------------------|----------------------|--------------------------| +| X‑STEP / DIR / EN | 54 / 55 / 38 | X.STEP / X.DIR / X.EN | +| Y‑STEP / DIR / EN | 60 / 61 / 56 | Y.STEP / Y.DIR / Y.EN | +| Z‑STEP / DIR / EN | 46 / 48 / 62 | Z.STEP / Z.DIR / Z.EN | +| E0‑STEP / DIR / EN | 26 / 28 / 24 | E0.STEP / E0.DIR / E0.EN | +| X‑MAX | pin 2 (E4) | X+ JST | +| Y‑MAX | pin 15 (J0) | Y+ JST | +| Z‑MAX | pin 19 (D2) | Z+ JST | +| Z‑MIN / Probe | pin 18 (D3) | Z‑ JST | +| Heater‑0 | D10 | HE0 screw | +| Bed Heater | D8 | BED screw | +| Thermistor‑0 / Bed | A13 / A14 | TH0 / THB | +| Fan 0 (model) | D9 | FAN screw | +| Fan 1 (hot‑end) | D7 | MOSFETD | +| VIN | XT‑30 | 2‑pin 12–24V in | + +### 3. After flashing: +```gcode +M502 ; load defaults +M500 ; save +G28 ; home +G33 ; auto‑calibrate +M303 E0 S200 C8 ; PID calibration +``` diff --git a/config/examples/delta/Micromake-D1/MKS-Gen-L-V2.1/assets/makeboard_mini_2.1.2.webp b/config/examples/delta/Micromake-D1/MKS-Gen-L-V2.1/assets/makeboard_mini_2.1.2.webp new file mode 100644 index 0000000000000000000000000000000000000000..70b4bedbebfc0a4681f17c9832f68f1fb3c9b988 GIT binary patch literal 175666 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�D>@=}oM$tQL)R4V;Rm0C#%aRQYs*sKlL$ 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 literal 0 HcmV?d00001 diff --git a/config/examples/delta/Micromake-D1/MKS-Gen-L-V2.1/assets/mks_gen_l_v2.1.webp b/config/examples/delta/Micromake-D1/MKS-Gen-L-V2.1/assets/mks_gen_l_v2.1.webp new file mode 100644 index 0000000000000000000000000000000000000000..fa54a4cdb5a1010de61622cd588b8a262ffc647f GIT binary patch literal 101362 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�D+u8cI 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. + * + */ +#pragma once +#error "Don't build with import-2.1.x configurations!" +#error "Use the 'bugfix...' or 'release...' configurations matching your Marlin version." + +/** + * Configuration.h + * + * Basic settings such as: + * + * - Type of electronics + * - Type of temperature sensor + * - Printer geometry + * - Endstop configuration + * - LCD controller + * - Extra features + * + * Advanced settings can be found in Configuration_adv.h + */ +#define CONFIGURATION_H_VERSION 02010300 + +//=========================================================================== +//============================= Getting Started ============================= +//=========================================================================== + +/** + * Here are some useful links to help get your machine configured and calibrated: + * + * Example Configs: https://github.com/MarlinFirmware/Configurations/branches/all + * + * Průša Calculator: https://blog.prusa3d.com/calculator_3416/ + * + * Calibration Guides: https://reprap.org/wiki/Calibration + * https://reprap.org/wiki/Triffid_Hunter%27s_Calibration_Guide + * https://web.archive.org/web/20220907014303/sites.google.com/site/repraplogphase/calibration-of-your-reprap + * https://youtu.be/wAL9d7FgInk + * https://teachingtechyt.github.io/calibration.html + * + * Calibration Objects: https://www.thingiverse.com/thing:5573 + * https://www.thingiverse.com/thing:1278865 + */ + +// @section info + +// Author info of this build printed to the host during boot and M115 +#define STRING_CONFIG_H_AUTHOR "(none, default config)" // Original author or contributor. +//#define CUSTOM_VERSION_FILE Version.h // Path from the root directory (no quotes) + +// @section machine + +// Choose the name from boards.h that matches your setup +#ifndef MOTHERBOARD + #define MOTHERBOARD BOARD_RAMPS_14_EFB // Micromake 1.3 (RAMPS clone with MKS-Gen style) + #define BOARD_INFO_NAME "Micromake 1.3" +#endif + +// @section serial + +/** + * Select the serial port on the board to use for communication with the host. + * This allows the connection of wireless adapters (for instance) to non-default port pins. + * Serial port -1 is the USB emulated serial port, if available. + * Note: The first serial port (-1 or 0) will always be used by the Arduino bootloader. + * + * :[-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9] + */ +#define SERIAL_PORT 0 + +/** + * Serial Port Baud Rate + * This is the default communication speed for all serial ports. + * Set the baud rate defaults for additional serial ports below. + * + * 250000 works in most cases, but you might try a lower speed if + * you commonly experience drop-outs during host printing. + * You may try up to 1000000 to speed up SD file transfer. + * + * :[2400, 9600, 19200, 38400, 57600, 115200, 250000, 500000, 1000000] + */ +#define BAUDRATE 250000 + +//#define BAUD_RATE_GCODE // Enable G-code M575 to set the baud rate + +/** + * Select a secondary serial port on the board to use for communication with the host. + * Currently Ethernet (-2) is only supported on Teensy 4.1 boards. + * :[-2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9] + */ +//#define SERIAL_PORT_2 -1 +//#define BAUDRATE_2 250000 // :[2400, 9600, 19200, 38400, 57600, 115200, 250000, 500000, 1000000] Enable to override BAUDRATE + +/** + * Select a third serial port on the board to use for communication with the host. + * Currently supported for AVR, DUE, SAMD51, LPC1768/9, STM32/STM32F1/HC32, and Teensy 4.x + * :[-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9] + */ +//#define SERIAL_PORT_3 1 +//#define BAUDRATE_3 250000 // :[2400, 9600, 19200, 38400, 57600, 115200, 250000, 500000, 1000000] Enable to override BAUDRATE + +/** + * Select a serial port to communicate with RS485 protocol + * :[-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9] + */ +//#define RS485_SERIAL_PORT 1 +#ifdef RS485_SERIAL_PORT + //#define M485_PROTOCOL 1 // Check your host for protocol compatibility + //#define RS485_BUS_BUFFER_SIZE 128 +#endif + +// Enable CAN bus support and protocol +//#define CAN_HOST +//#define CAN_TOOLHEAD +#if ANY(CAN_HOST, CAN_TOOLHEAD) + //#define CAN_DEBUG +#endif + +// Enable the Bluetooth serial interface on AT90USB devices +//#define BLUETOOTH + +// Name displayed in the LCD "Ready" message and Info menu +#define CUSTOM_MACHINE_NAME "Blood" +//#define CONFIGURABLE_MACHINE_NAME // Add G-code M550 to set/report the machine name + +// Printer's unique ID, used by some programs to differentiate between machines. +// Choose your own or use a service like https://www.uuidgenerator.net/version4 +//#define MACHINE_UUID "00000000-0000-0000-0000-000000000000" + +// @section stepper drivers + +/** + * Stepper Drivers + * + * These settings allow Marlin to tune stepper driver timing and enable advanced options for + * stepper drivers that support them. You may also override timing options in Configuration_adv.h. + * + * Use TMC2208/TMC2208_STANDALONE for TMC2225 drivers and TMC2209/TMC2209_STANDALONE for TMC2226 drivers. + * + * Options: A4988, A5984, DRV8825, LV8729, TB6560, TB6600, TMC2100, + * TMC2130, TMC2130_STANDALONE, TMC2160, TMC2160_STANDALONE, + * TMC2208, TMC2208_STANDALONE, TMC2209, TMC2209_STANDALONE, + * TMC2240, TMC2660, TMC2660_STANDALONE, + * TMC5130, TMC5130_STANDALONE, TMC5160, TMC5160_STANDALONE + * :['A4988', 'A5984', 'DRV8825', 'LV8729', 'TB6560', 'TB6600', 'TMC2100', 'TMC2130', 'TMC2130_STANDALONE', 'TMC2160', 'TMC2160_STANDALONE', 'TMC2208', 'TMC2208_STANDALONE', 'TMC2209', 'TMC2209_STANDALONE', 'TMC2240', 'TMC2660', 'TMC2660_STANDALONE', 'TMC5130', 'TMC5130_STANDALONE', 'TMC5160', 'TMC5160_STANDALONE'] + */ +#define X_DRIVER_TYPE DRV8825 +#define Y_DRIVER_TYPE DRV8825 +#define Z_DRIVER_TYPE DRV8825 +//#define X2_DRIVER_TYPE A4988 +//#define Y2_DRIVER_TYPE A4988 +//#define Z2_DRIVER_TYPE A4988 +//#define Z3_DRIVER_TYPE A4988 +//#define Z4_DRIVER_TYPE A4988 +//#define I_DRIVER_TYPE A4988 +//#define J_DRIVER_TYPE A4988 +//#define K_DRIVER_TYPE A4988 +//#define U_DRIVER_TYPE A4988 +//#define V_DRIVER_TYPE A4988 +//#define W_DRIVER_TYPE A4988 +#define E0_DRIVER_TYPE DRV8825 +//#define E1_DRIVER_TYPE A4988 +//#define E2_DRIVER_TYPE A4988 +//#define E3_DRIVER_TYPE A4988 +//#define E4_DRIVER_TYPE A4988 +//#define E5_DRIVER_TYPE A4988 +//#define E6_DRIVER_TYPE A4988 +//#define E7_DRIVER_TYPE A4988 + +/** + * Additional Axis Settings + * + * Define AXISn_ROTATES for all axes that rotate or pivot. + * Rotational axis coordinates are expressed in degrees. + * + * AXISn_NAME defines the letter used to refer to the axis in (most) G-code commands. + * By convention the names and roles are typically: + * 'A' : Rotational axis parallel to X + * 'B' : Rotational axis parallel to Y + * 'C' : Rotational axis parallel to Z + * 'U' : Secondary linear axis parallel to X + * 'V' : Secondary linear axis parallel to Y + * 'W' : Secondary linear axis parallel to Z + * + * Regardless of these settings the axes are internally named I, J, K, U, V, W. + */ +#ifdef I_DRIVER_TYPE + #define AXIS4_NAME 'A' // :['A', 'B', 'C', 'U', 'V', 'W'] + #define AXIS4_ROTATES +#endif +#ifdef J_DRIVER_TYPE + #define AXIS5_NAME 'B' // :['B', 'C', 'U', 'V', 'W'] + #define AXIS5_ROTATES +#endif +#ifdef K_DRIVER_TYPE + #define AXIS6_NAME 'C' // :['C', 'U', 'V', 'W'] + #define AXIS6_ROTATES +#endif +#ifdef U_DRIVER_TYPE + #define AXIS7_NAME 'U' // :['U', 'V', 'W'] + //#define AXIS7_ROTATES +#endif +#ifdef V_DRIVER_TYPE + #define AXIS8_NAME 'V' // :['V', 'W'] + //#define AXIS8_ROTATES +#endif +#ifdef W_DRIVER_TYPE + #define AXIS9_NAME 'W' // :['W'] + //#define AXIS9_ROTATES +#endif + +// @section extruder + +// This defines the number of extruders +// :[0, 1, 2, 3, 4, 5, 6, 7, 8] +#define EXTRUDERS 1 + +// Generally expected filament diameter (1.75, 2.85, 3.0, ...). Used for Volumetric, Filament Width Sensor, etc. +#define DEFAULT_NOMINAL_FILAMENT_DIA 1.75 + +// For Cyclops or any "multi-extruder" that shares a single nozzle. +//#define SINGLENOZZLE + +// Save and restore temperature and fan speed on tool-change. +// Set standby for the unselected tool with M104/106/109 T... +#if ENABLED(SINGLENOZZLE) + //#define SINGLENOZZLE_STANDBY_TEMP + //#define SINGLENOZZLE_STANDBY_FAN +#endif + +// A dual extruder that uses a single stepper motor +//#define SWITCHING_EXTRUDER +#if ENABLED(SWITCHING_EXTRUDER) + #define SWITCHING_EXTRUDER_SERVO_NR 0 + #define SWITCHING_EXTRUDER_SERVO_ANGLES { 0, 90 } // Angles for E0, E1[, E2, E3] + #if EXTRUDERS > 3 + #define SWITCHING_EXTRUDER_E23_SERVO_NR 1 + #endif +#endif + +// Switch extruders by bumping the toolhead. Requires EVENT_GCODE_TOOLCHANGE_#. +//#define MECHANICAL_SWITCHING_EXTRUDER + +/** + * A dual-nozzle that uses a servomotor to raise/lower one (or both) of the nozzles. + * Can be combined with SWITCHING_EXTRUDER. + */ +//#define SWITCHING_NOZZLE +#if ENABLED(SWITCHING_NOZZLE) + #define SWITCHING_NOZZLE_SERVO_NR 0 + //#define SWITCHING_NOZZLE_E1_SERVO_NR 1 // If two servos are used, the index of the second + #define SWITCHING_NOZZLE_SERVO_ANGLES { 0, 90 } // A pair of angles for { E0, E1 }. + // For Dual Servo use two pairs: { { lower, raise }, { lower, raise } } + #define SWITCHING_NOZZLE_SERVO_DWELL 2500 // Dwell time to wait for servo to make physical move + #define SWITCHING_NOZZLE_LIFT_TO_PROBE // Lift toolheads out of the way while probing +#endif + +// Switch nozzles by bumping the toolhead. Requires EVENT_GCODE_TOOLCHANGE_#. +//#define MECHANICAL_SWITCHING_NOZZLE + +/** + * Two separate X-carriages with extruders that connect to a moving part + * via a solenoid docking mechanism. Requires SOL1_PIN and SOL2_PIN. + */ +//#define PARKING_EXTRUDER + +/** + * Two separate X-carriages with extruders that connect to a moving part + * via a magnetic docking mechanism using movements and no solenoid + * + * project : https://www.thingiverse.com/thing:3080893 + * movements : https://youtu.be/0xCEiG9VS3k + * https://youtu.be/Bqbcs0CU2FE + */ +//#define MAGNETIC_PARKING_EXTRUDER + +#if ANY(PARKING_EXTRUDER, MAGNETIC_PARKING_EXTRUDER) + + #define PARKING_EXTRUDER_PARKING_X { -78, 184 } // X positions for parking the extruders + #define PARKING_EXTRUDER_GRAB_DISTANCE 1 // (mm) Distance to move beyond the parking point to grab the extruder + + #if ENABLED(PARKING_EXTRUDER) + + #define PARKING_EXTRUDER_SOLENOIDS_INVERT // If enabled, the solenoid is NOT magnetized with applied voltage + #define PARKING_EXTRUDER_SOLENOIDS_PINS_ACTIVE LOW // LOW or HIGH pin signal energizes the coil + #define PARKING_EXTRUDER_SOLENOIDS_DELAY 250 // (ms) Delay for magnetic field. No delay if 0 or not defined. + //#define MANUAL_SOLENOID_CONTROL // Manual control of docking solenoids with M380 S / M381 + + #elif ENABLED(MAGNETIC_PARKING_EXTRUDER) + + #define MPE_FAST_SPEED 9000 // (mm/min) Speed for travel before last distance point + #define MPE_SLOW_SPEED 4500 // (mm/min) Speed for last distance travel to park and couple + #define MPE_TRAVEL_DISTANCE 10 // (mm) Last distance point + #define MPE_COMPENSATION 0 // Offset Compensation -1 , 0 , 1 (multiplier) only for coupling + + #endif + +#endif + +/** + * Switching Toolhead + * + * Support for swappable and dockable toolheads, such as + * the E3D Tool Changer. Toolheads are locked with a servo. + */ +//#define SWITCHING_TOOLHEAD + +/** + * Magnetic Switching Toolhead + * + * Support swappable and dockable toolheads with a magnetic + * docking mechanism using movement and no servo. + */ +//#define MAGNETIC_SWITCHING_TOOLHEAD + +/** + * Electromagnetic Switching Toolhead + * + * Parking for CoreXY / HBot kinematics. + * Toolheads are parked at one edge and held with an electromagnet. + * Supports more than 2 Toolheads. See https://youtu.be/JolbsAKTKf4 + */ +//#define ELECTROMAGNETIC_SWITCHING_TOOLHEAD + +#if ANY(SWITCHING_TOOLHEAD, MAGNETIC_SWITCHING_TOOLHEAD, ELECTROMAGNETIC_SWITCHING_TOOLHEAD) + #define SWITCHING_TOOLHEAD_Y_POS 235 // (mm) Y position of the toolhead dock + #define SWITCHING_TOOLHEAD_Y_SECURITY 10 // (mm) Security distance Y axis + #define SWITCHING_TOOLHEAD_Y_CLEAR 60 // (mm) Minimum distance from dock for unobstructed X axis + #define SWITCHING_TOOLHEAD_X_POS { 215, 0 } // (mm) X positions for parking the extruders + #if ENABLED(SWITCHING_TOOLHEAD) + #define SWITCHING_TOOLHEAD_SERVO_NR 2 // Index of the servo connector + #define SWITCHING_TOOLHEAD_SERVO_ANGLES { 0, 180 } // (degrees) Angles for Lock, Unlock + #elif ENABLED(MAGNETIC_SWITCHING_TOOLHEAD) + #define SWITCHING_TOOLHEAD_Y_RELEASE 5 // (mm) Security distance Y axis + #define SWITCHING_TOOLHEAD_X_SECURITY { 90, 150 } // (mm) Security distance X axis (T0,T1) + //#define PRIME_BEFORE_REMOVE // Prime the nozzle before release from the dock + #if ENABLED(PRIME_BEFORE_REMOVE) + #define SWITCHING_TOOLHEAD_PRIME_MM 20 // (mm) Extruder prime length + #define SWITCHING_TOOLHEAD_RETRACT_MM 10 // (mm) Retract after priming length + #define SWITCHING_TOOLHEAD_PRIME_FEEDRATE 300 // (mm/min) Extruder prime feedrate + #define SWITCHING_TOOLHEAD_RETRACT_FEEDRATE 2400 // (mm/min) Extruder retract feedrate + #endif + #elif ENABLED(ELECTROMAGNETIC_SWITCHING_TOOLHEAD) + #define SWITCHING_TOOLHEAD_Z_HOP 2 // (mm) Z raise for switching + #endif +#endif + +/** + * "Mixing Extruder" + * - Adds G-codes M163 and M164 to set and "commit" the current mix factors. + * - Extends the stepping routines to move multiple steppers in proportion to the mix. + * - Optional support for Repetier Firmware's 'M164 S' supporting virtual tools. + * - This implementation supports up to two mixing extruders. + * - Enable DIRECT_MIXING_IN_G1 for M165 and mixing in G1 (from Pia Taubert's reference implementation). + */ +//#define MIXING_EXTRUDER +#if ENABLED(MIXING_EXTRUDER) + #define MIXING_STEPPERS 2 // Number of steppers in your mixing extruder + #define MIXING_VIRTUAL_TOOLS 16 // Use the Virtual Tool method with M163 and M164 + //#define DIRECT_MIXING_IN_G1 // Allow ABCDHI mix factors in G1 movement commands + //#define GRADIENT_MIX // Support for gradient mixing with M166 and LCD + //#define MIXING_PRESETS // Assign 8 default V-tool presets for 2 or 3 MIXING_STEPPERS + #if ENABLED(GRADIENT_MIX) + //#define GRADIENT_VTOOL // Add M166 T to use a V-tool index as a Gradient alias + #endif +#endif + +// Offset of the extruders (uncomment if using more than one and relying on firmware to position when changing). +// The offset has to be X=0, Y=0 for the extruder 0 hotend (default extruder). +// For the other hotends it is their distance from the extruder 0 hotend. +//#define HOTEND_OFFSET_X { 0.0, 20.00 } // (mm) relative X-offset for each nozzle +//#define HOTEND_OFFSET_Y { 0.0, 5.00 } // (mm) relative Y-offset for each nozzle +//#define HOTEND_OFFSET_Z { 0.0, 0.00 } // (mm) relative Z-offset for each nozzle + +// @section multi-material + +/** + * Multi-Material Unit + * Set to one of these predefined models: + * + * PRUSA_MMU1 : Průša MMU1 (The "multiplexer" version) + * PRUSA_MMU2 : Průša MMU2 + * PRUSA_MMU2S : Průša MMU2S (Requires MK3S extruder with motion sensor, EXTRUDERS = 5) + * PRUSA_MMU3 : Průša MMU3 (Requires MK3S extruder with motion sensor and MMU firmware version 3.x.x, EXTRUDERS = 5) + * EXTENDABLE_EMU_MMU2 : MMU with configurable number of filaments (ERCF, SMuFF or similar with Průša MMU2 compatible firmware) + * EXTENDABLE_EMU_MMU2S : MMUS with configurable number of filaments (ERCF, SMuFF or similar with Průša MMU2 compatible firmware) + * + * Requires NOZZLE_PARK_FEATURE to park print head in case MMU unit fails. + * See additional options in Configuration_adv.h. + * :["PRUSA_MMU1", "PRUSA_MMU2", "PRUSA_MMU2S", "PRUSA_MMU3", "EXTENDABLE_EMU_MMU2", "EXTENDABLE_EMU_MMU2S"] + */ +//#define MMU_MODEL PRUSA_MMU3 + +// @section psu control + +/** + * Power Supply Control + * + * Enable and connect the power supply to the PS_ON_PIN. + * Specify whether the power supply is active HIGH or active LOW. + */ +//#define PSU_CONTROL +//#define PSU_NAME "Power Supply" + +#if ENABLED(PSU_CONTROL) + //#define MKS_PWC // Using the MKS PWC add-on + //#define PS_OFF_CONFIRM // Confirm dialog when power off + //#define PS_OFF_SOUND // Beep 1s when power off + #define PSU_ACTIVE_STATE LOW // Set 'LOW' for ATX, 'HIGH' for X-Box + + //#define PSU_DEFAULT_OFF // Keep power off until enabled directly with M80 + //#define PSU_POWERUP_DELAY 250 // (ms) Delay for the PSU to warm up to full power + //#define LED_POWEROFF_TIMEOUT 10000 // (ms) Turn off LEDs after power-off, with this amount of delay + + //#define PSU_OFF_REDUNDANT // Second pin for redundant power control + //#define PSU_OFF_REDUNDANT_INVERTED // Redundant pin state is the inverse of PSU_ACTIVE_STATE + + //#define PS_ON1_PIN 6 // Redundant pin required to enable power in combination with PS_ON_PIN + + //#define PS_ON_EDM_PIN 8 // External Device Monitoring pins for external power control relay feedback. Fault on mismatch. + //#define PS_ON1_EDM_PIN 9 + #define PS_EDM_RESPONSE 250 // (ms) Time to allow for relay action + + //#define POWER_OFF_TIMER // Enable M81 D to power off after a delay + //#define POWER_OFF_WAIT_FOR_COOLDOWN // Enable M81 S to power off only after cooldown + + //#define PSU_POWERUP_GCODE "M355 S1" // G-code to run after power-on (e.g., case light on) + //#define PSU_POWEROFF_GCODE "M355 S0" // G-code to run before power-off (e.g., case light off) + + //#define AUTO_POWER_CONTROL // Enable automatic control of the PS_ON pin + #if ENABLED(AUTO_POWER_CONTROL) + #define AUTO_POWER_FANS // Turn on PSU for fans + #define AUTO_POWER_E_FANS // Turn on PSU for E Fans + #define AUTO_POWER_CONTROLLERFAN // Turn on PSU for Controller Fan + #define AUTO_POWER_CHAMBER_FAN // Turn on PSU for Chamber Fan + #define AUTO_POWER_COOLER_FAN // Turn on PSU for Cooler Fan + #define AUTO_POWER_SPINDLE_LASER // Turn on PSU for Spindle/Laser + #define POWER_TIMEOUT 30 // (s) Turn off power if the machine is idle for this duration + //#define POWER_OFF_DELAY 60 // (s) Delay of poweroff after M81 command. Useful to let fans run for extra time. + #endif + #if ANY(AUTO_POWER_CONTROL, POWER_OFF_WAIT_FOR_COOLDOWN) + //#define AUTO_POWER_E_TEMP 50 // (°C) PSU on if any extruder is over this temperature + //#define AUTO_POWER_CHAMBER_TEMP 30 // (°C) PSU on if the chamber is over this temperature + //#define AUTO_POWER_COOLER_TEMP 26 // (°C) PSU on if the cooler is over this temperature + #endif +#endif + +//=========================================================================== +//============================= Thermal Settings ============================ +//=========================================================================== +// @section temperature + +/** + * Temperature Sensors: + * + * NORMAL IS 4.7kΩ PULLUP! Hotend sensors can use 1kΩ pullup with correct resistor and table. + * + * ================================================================ + * Analog Thermistors - 4.7kΩ pullup - Normal + * ================================================================ + * 1 : 100kΩ EPCOS - Best choice for EPCOS thermistors + * 331 : 100kΩ Same as #1, but 3.3V scaled for MEGA + * 332 : 100kΩ Same as #1, but 3.3V scaled for DUE + * 2 : 200kΩ ATC Semitec 204GT-2 + * 202 : 200kΩ Copymaster 3D + * 3 : ???Ω Mendel-parts thermistor + * 4 : 10kΩ Generic Thermistor !! DO NOT use for a hotend - it gives bad resolution at high temp. !! + * 5 : 100kΩ ATC Semitec 104GT-2/104NT-4-R025H42G - Used in ParCan, J-Head, and E3D, SliceEngineering 300°C + * 501 : 100kΩ Zonestar - Tronxy X3A + * 502 : 100kΩ Zonestar - used by hot bed in Zonestar Průša P802M + * 503 : 100kΩ Zonestar (Z8XM2) Heated Bed thermistor + * 504 : 100kΩ Zonestar P802QR2 (Part# QWG-104F-B3950) Hotend Thermistor + * 505 : 100kΩ Zonestar P802QR2 (Part# QWG-104F-3950) Bed Thermistor + * 512 : 100kΩ RPW-Ultra hotend + * 6 : 100kΩ EPCOS - Not as accurate as table #1 (created using a fluke thermocouple) + * 7 : 100kΩ Honeywell 135-104LAG-J01 + * 71 : 100kΩ Honeywell 135-104LAF-J01 + * 8 : 100kΩ Vishay 0603 SMD NTCS0603E3104FXT + * 9 : 100kΩ GE Sensing AL03006-58.2K-97-G1 + * 10 : 100kΩ RS PRO 198-961 + * 11 : 100kΩ Keenovo AC silicone mats, most Wanhao i3 machines - beta 3950, 1% + * 12 : 100kΩ Vishay 0603 SMD NTCS0603E3104FXT (#8) - calibrated for Makibox hot bed + * 13 : 100kΩ Hisens up to 300°C - for "Simple ONE" & "All In ONE" hotend - beta 3950, 1% + * 14 : 100kΩ (R25), 4092K (beta25), 4.7kΩ pull-up, bed thermistor as used in Ender-5 S1 + * 15 : 100kΩ Calibrated for JGAurora A5 hotend + * 17 : 100kΩ Dagoma NTC white thermistor + * 18 : 200kΩ ATC Semitec 204GT-2 Dagoma.Fr - MKS_Base_DKU001327 + * 22 : 100kΩ GTM32 Pro vB - hotend - 4.7kΩ pullup to 3.3V and 220Ω to analog input + * 23 : 100kΩ GTM32 Pro vB - bed - 4.7kΩ pullup to 3.3v and 220Ω to analog input + * 30 : 100kΩ Kis3d Silicone heating mat 200W/300W with 6mm precision cast plate (EN AW 5083) NTC100K - beta 3950 + * 60 : 100kΩ Maker's Tool Works Kapton Bed Thermistor - beta 3950 + * 61 : 100kΩ Formbot/Vivedino 350°C Thermistor - beta 3950 + * 66 : 4.7MΩ Dyze Design / Trianglelab T-D500 500°C High Temperature Thermistor + * 67 : 500kΩ SliceEngineering 450°C Thermistor + * 68 : PT100 Smplifier board from Dyze Design + * 70 : 100kΩ bq Hephestos 2 + * 75 : 100kΩ Generic Silicon Heat Pad with NTC100K MGB18-104F39050L32 + * 666 : 200kΩ Einstart S custom thermistor with 10k pullup. + * 2000 : 100kΩ Ultimachine Rambo TDK NTCG104LH104KT1 NTC100K motherboard Thermistor + * + * ================================================================ + * Analog Thermistors - 1kΩ pullup + * Atypical, and requires changing out the 4.7kΩ pullup for 1kΩ. + * (but gives greater accuracy and more stable PID) + * ================================================================ + * 51 : 100kΩ EPCOS (1kΩ pullup) + * 52 : 200kΩ ATC Semitec 204GT-2 (1kΩ pullup) + * 55 : 100kΩ ATC Semitec 104GT-2 - Used in ParCan & J-Head (1kΩ pullup) + * + * ================================================================ + * Analog Thermistors - 10kΩ pullup - Atypical + * ================================================================ + * 99 : 100kΩ Found on some Wanhao i3 machines with a 10kΩ pull-up resistor + * + * ================================================================ + * Analog RTDs (Pt100/Pt1000) + * ================================================================ + * 110 : Pt100 with 1kΩ pullup (atypical) + * 147 : Pt100 with 4.7kΩ pullup + * 1010 : Pt1000 with 1kΩ pullup (atypical) + * 1022 : Pt1000 with 2.2kΩ pullup + * 1047 : Pt1000 with 4.7kΩ pullup (E3D) + * 20 : Pt100 with circuit in the Ultimainboard V2.x with mainboard ADC reference voltage = INA826 amplifier-board supply voltage. + * NOTE: (1) Must use an ADC input with no pullup. (2) Some INA826 amplifiers are unreliable at 3.3V so consider using sensor 147, 110, or 21. + * 21 : Pt100 with circuit in the Ultimainboard V2.x with 3.3v ADC reference voltage (STM32, LPC176x....) and 5V INA826 amplifier board supply. + * NOTE: ADC pins are not 5V tolerant. Not recommended because it's possible to damage the CPU by going over 500°C. + * 201 : Pt100 with circuit in Overlord, similar to Ultimainboard V2.x + * + * ================================================================ + * SPI RTD/Thermocouple Boards + * ================================================================ + * -5 : MAX31865 with Pt100/Pt1000, 2, 3, or 4-wire (only for sensors 0-2 and bed) + * NOTE: You must uncomment/set the MAX31865_*_OHMS_n defines below. + * -3 : MAX31855 with Thermocouple, -200°C to +700°C (only for sensors 0-2 and bed) + * -2 : MAX6675 with Thermocouple, 0°C to +700°C (only for sensors 0-2 and bed) + * + * NOTE: Ensure TEMP_n_CS_PIN is set in your pins file for each TEMP_SENSOR_n using an SPI Thermocouple. By default, + * Hardware SPI on the default serial bus is used. If you have also set TEMP_n_SCK_PIN and TEMP_n_MISO_PIN, + * Software SPI will be used on those ports instead. You can force Hardware SPI on the default bus in the + * Configuration_adv.h file. At this time, separate Hardware SPI buses for sensors are not supported. + * + * ================================================================ + * Analog Thermocouple Boards + * ================================================================ + * -4 : AD8495 with Thermocouple + * -1 : AD595 with Thermocouple + * + * ================================================================ + * SoC internal sensor + * ================================================================ + * 100 : SoC internal sensor + * + * ================================================================ + * Custom/Dummy/Other Thermal Sensors + * ================================================================ + * 0 : not used + * 1000 : Custom - Specify parameters in Configuration_adv.h + * + * !!! Use these for Testing or Development purposes. NEVER for production machine. !!! + * 998 : Dummy Table that ALWAYS reads 25°C or the temperature defined below. + * 999 : Dummy Table that ALWAYS reads 100°C or the temperature defined below. + */ +#define TEMP_SENSOR_0 5 +#define TEMP_SENSOR_1 0 +#define TEMP_SENSOR_2 0 +#define TEMP_SENSOR_3 0 +#define TEMP_SENSOR_4 0 +#define TEMP_SENSOR_5 0 +#define TEMP_SENSOR_6 0 +#define TEMP_SENSOR_7 0 +#define TEMP_SENSOR_BED 1 +#define TEMP_SENSOR_PROBE 0 +#define TEMP_SENSOR_CHAMBER 0 +#define TEMP_SENSOR_COOLER 0 +#define TEMP_SENSOR_BOARD 0 +#define TEMP_SENSOR_SOC 0 +#define TEMP_SENSOR_REDUNDANT 0 + +// Dummy thermistor constant temperature readings, for use with 998 and 999 +#define DUMMY_THERMISTOR_998_VALUE 25 +#define DUMMY_THERMISTOR_999_VALUE 100 + +// Resistor values when using MAX31865 sensors (-5) on TEMP_SENSOR_0 / 1 / 2 / BED +#if TEMP_SENSOR_IS_MAX_TC(0) + #define MAX31865_SENSOR_OHMS_0 100 // (Ω) Typically 100 or 1000 (PT100 or PT1000) + #define MAX31865_CALIBRATION_OHMS_0 430 // (Ω) Typically 430 for Adafruit PT100; 4300 for Adafruit PT1000 +#endif +#if TEMP_SENSOR_IS_MAX_TC(1) + #define MAX31865_SENSOR_OHMS_1 100 + #define MAX31865_CALIBRATION_OHMS_1 430 +#endif +#if TEMP_SENSOR_IS_MAX_TC(2) + #define MAX31865_SENSOR_OHMS_2 100 + #define MAX31865_CALIBRATION_OHMS_2 430 +#endif +#if TEMP_SENSOR_IS_MAX_TC(BED) + #define MAX31865_SENSOR_OHMS_BED 100 + #define MAX31865_CALIBRATION_OHMS_BED 430 +#endif + +#if HAS_E_TEMP_SENSOR + #define TEMP_RESIDENCY_TIME 10 // (seconds) Time to wait for hotend to "settle" in M109 + #define TEMP_WINDOW 1 // (°C) Temperature proximity for the "temperature reached" timer + #define TEMP_HYSTERESIS 3 // (°C) Temperature proximity considered "close enough" to the target +#endif + +#if TEMP_SENSOR_BED + #define TEMP_BED_RESIDENCY_TIME 10 // (seconds) Time to wait for bed to "settle" in M190 + #define TEMP_BED_WINDOW 1 // (°C) Temperature proximity for the "temperature reached" timer + #define TEMP_BED_HYSTERESIS 3 // (°C) Temperature proximity considered "close enough" to the target +#endif + +#if TEMP_SENSOR_CHAMBER + #define TEMP_CHAMBER_RESIDENCY_TIME 10 // (seconds) Time to wait for chamber to "settle" in M191 + #define TEMP_CHAMBER_WINDOW 1 // (°C) Temperature proximity for the "temperature reached" timer + #define TEMP_CHAMBER_HYSTERESIS 3 // (°C) Temperature proximity considered "close enough" to the target +#endif + +/** + * Redundant Temperature Sensor (TEMP_SENSOR_REDUNDANT) + * + * Use a temp sensor as a redundant sensor for another reading. Select an unused temperature sensor, and another + * sensor you'd like it to be redundant for. If the two thermistors differ by TEMP_SENSOR_REDUNDANT_MAX_DIFF (°C), + * the print will be aborted. Whichever sensor is selected will have its normal functions disabled; i.e. selecting + * the Bed sensor (-1) will disable bed heating/monitoring. + * + * For selecting source/target use: COOLER, PROBE, BOARD, CHAMBER, BED, E0, E1, E2, E3, E4, E5, E6, E7 + */ +#if TEMP_SENSOR_REDUNDANT + #define TEMP_SENSOR_REDUNDANT_SOURCE E1 // The sensor that will provide the redundant reading. + #define TEMP_SENSOR_REDUNDANT_TARGET E0 // The sensor that we are providing a redundant reading for. + #define TEMP_SENSOR_REDUNDANT_MAX_DIFF 10 // (°C) Temperature difference that will trigger a print abort. +#endif + +// Below this temperature the heater will be switched off +// because it probably indicates a broken thermistor wire. +#define HEATER_0_MINTEMP 5 +#define HEATER_1_MINTEMP 5 +#define HEATER_2_MINTEMP 5 +#define HEATER_3_MINTEMP 5 +#define HEATER_4_MINTEMP 5 +#define HEATER_5_MINTEMP 5 +#define HEATER_6_MINTEMP 5 +#define HEATER_7_MINTEMP 5 +#define BED_MINTEMP 5 +#define CHAMBER_MINTEMP 5 + +// Above this temperature the heater will be switched off. +// This can protect components from overheating, but NOT from shorts and failures. +// (Use MINTEMP for thermistor short/failure protection.) +#define HEATER_0_MAXTEMP 275 +#define HEATER_1_MAXTEMP 275 +#define HEATER_2_MAXTEMP 275 +#define HEATER_3_MAXTEMP 275 +#define HEATER_4_MAXTEMP 275 +#define HEATER_5_MAXTEMP 275 +#define HEATER_6_MAXTEMP 275 +#define HEATER_7_MAXTEMP 275 +#define BED_MAXTEMP 120 +#define CHAMBER_MAXTEMP 60 + +/** + * Thermal Overshoot + * During heatup (and printing) the temperature can often "overshoot" the target by many degrees + * (especially before PID tuning). Setting the target temperature too close to MAXTEMP guarantees + * a MAXTEMP shutdown! Use these values to forbid temperatures being set too close to MAXTEMP. + */ +#define HOTEND_OVERSHOOT 15 // (°C) Forbid temperatures over MAXTEMP - OVERSHOOT +#define BED_OVERSHOOT 10 // (°C) Forbid temperatures over MAXTEMP - OVERSHOOT +#define COOLER_OVERSHOOT 2 // (°C) Forbid temperatures closer than OVERSHOOT + +//=========================================================================== +//============================= PID Settings ================================ +//=========================================================================== + +// @section hotend temp + +/** + * Temperature Control + * + * (NONE) : Bang-bang heating + * PIDTEMP : PID temperature control (~4.1K) + * MPCTEMP : Predictive Model temperature control. (~1.8K without auto-tune) + */ +#define PIDTEMP // See the PID Tuning Guide at https://reprap.org/wiki/PID_Tuning +//#define MPCTEMP // See https://marlinfw.org/docs/features/model_predictive_control.html + +#define PID_MAX 255 // Limit hotend current while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define PID_K1 0.95 // Smoothing factor within any PID loop + +#if ENABLED(PIDTEMP) + //#define MIN_POWER 0 // Min power to improve PID stability (0..PID_MAX). + // Get the power from the temperature report ('M105' => @:nnn) and try P*2-20 to P*2-10. + //#define PID_DEBUG // Print PID debug data to the serial port. Use 'M303 D' to enable/disable. + //#define PID_PARAMS_PER_HOTEND // Use separate PID parameters for each extruder (useful for mismatched extruders) + // Set/get with G-code: M301 E[extruder number, 0-2] + + #if ENABLED(PID_PARAMS_PER_HOTEND) + // Specify up to one value per hotend here, according to your setup. + // If there are fewer values, the last one applies to the remaining hotends. + #define DEFAULT_Kp_LIST { 22.20, 22.20 } + #define DEFAULT_Ki_LIST { 1.08, 1.08 } + #define DEFAULT_Kd_LIST { 114.00, 114.00 } + #else + #define DEFAULT_Kp 22.20 + #define DEFAULT_Ki 1.08 + #define DEFAULT_Kd 114.00 + #endif +#else + #define BANG_MAX 255 // Limit hotend current while in bang-bang mode; 255=full current +#endif + +/** + * Model Predictive Control for hotend + * + * Use a physical model of the hotend to control temperature. When configured correctly this gives + * better responsiveness and stability than PID and removes the need for PID_EXTRUSION_SCALING + * and PID_FAN_SCALING. Enable MPC_AUTOTUNE and use M306 T to autotune the model. + * @section mpc temp + */ +#if ENABLED(MPCTEMP) + #define MPC_AUTOTUNE // Include a method to do MPC auto-tuning (~6.3K bytes of flash) + #if ENABLED(MPC_AUTOTUNE) + //#define MPC_AUTOTUNE_DEBUG // Enable MPC debug logging (~870 bytes of flash) + #endif + //#define MPC_EDIT_MENU // Add MPC editing to the "Advanced Settings" menu. (~1.3K bytes of flash) + //#define MPC_AUTOTUNE_MENU // Add MPC auto-tuning to the "Advanced Settings" menu. (~350 bytes of flash) + + #define MPC_MAX 255 // (0..255) Current to nozzle while MPC is active. + #define MPC_HEATER_POWER { 40.0f } // (W) Nominal heat cartridge powers. + //#define MPC_PTC // Hotend power changes with temperature (e.g., PTC heat cartridges). + #if ENABLED(MPC_PTC) + #define MPC_HEATER_ALPHA { 0.0028f } // Temperature coefficient of resistance of the heat cartridges. + #define MPC_HEATER_REFTEMP { 20 } // (°C) Reference temperature for MPC_HEATER_POWER and MPC_HEATER_ALPHA. + #endif + + #define MPC_INCLUDE_FAN // Model the fan speed? + + // Measured physical constants from M306 + #define MPC_BLOCK_HEAT_CAPACITY { 16.7f } // (J/K) Heat block heat capacities. + #define MPC_SENSOR_RESPONSIVENESS { 0.22f } // (K/s per ∆K) Rate of change of sensor temperature from heat block. + #define MPC_AMBIENT_XFER_COEFF { 0.068f } // (W/K) Heat transfer coefficients from heat block to room air with fan off. + #if ENABLED(MPC_INCLUDE_FAN) + #define MPC_AMBIENT_XFER_COEFF_FAN255 { 0.097f } // (W/K) Heat transfer coefficients from heat block to room air with fan on full. + #endif + + // For one fan and multiple hotends MPC needs to know how to apply the fan cooling effect. + #if ENABLED(MPC_INCLUDE_FAN) + //#define MPC_FAN_0_ALL_HOTENDS + //#define MPC_FAN_0_ACTIVE_HOTEND + #endif + + // Filament Heat Capacity (joules/kelvin/mm) + // Set at runtime with M306 H + #define FILAMENT_HEAT_CAPACITY_PERMM { 5.6e-3f } // 0.0056 J/K/mm for 1.75mm PLA (0.0149 J/K/mm for 2.85mm PLA). + // 0.0036 J/K/mm for 1.75mm PETG (0.0094 J/K/mm for 2.85mm PETG). + // 0.00515 J/K/mm for 1.75mm ABS (0.0137 J/K/mm for 2.85mm ABS). + // 0.00522 J/K/mm for 1.75mm Nylon (0.0138 J/K/mm for 2.85mm Nylon). + + // Advanced options + #define MPC_SMOOTHING_FACTOR 0.5f // (0.0...1.0) Noisy temperature sensors may need a lower value for stabilization. + #define MPC_MIN_AMBIENT_CHANGE 1.0f // (K/s) Modeled ambient temperature rate of change, when correcting model inaccuracies. + #define MPC_STEADYSTATE 0.5f // (K/s) Temperature change rate for steady state logic to be enforced. + + #define MPC_TUNING_POS { X_CENTER, Y_CENTER, 1.0f } // (mm) M306 Autotuning position, ideally bed center at first layer height. + #define MPC_TUNING_END_Z 10.0f // (mm) M306 Autotuning final Z position. + //#define EVENT_GCODE_AFTER_MPC_TUNE "M84" // G-code to execute after MPC tune finished and Z raised. +#endif + +//=========================================================================== +//====================== PID > Bed Temperature Control ====================== +//=========================================================================== + +// @section bed temp + +/** + * Max Bed Power + * Applies to all forms of bed control (PID, bang-bang, and bang-bang with hysteresis). + * When set to any value below 255, enables a form of PWM to the bed that acts like a divider + * so don't use it unless you are OK with PWM on your bed. (See the comment on enabling PIDTEMPBED) + */ +#define MAX_BED_POWER 255 // limits duty cycle to bed; 255=full current + +/** + * PID Bed Heating + * + * The PID frequency will be the same as the extruder PWM. + * If PID_dT is the default, and correct for the hardware/configuration, that means 7.689Hz, + * which is fine for driving a square wave into a resistive load and does not significantly + * impact FET heating. This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W + * heater. If your configuration is significantly different than this and you don't understand + * the issues involved, don't use bed PID until someone else verifies that your hardware works. + * + * With this option disabled, bang-bang will be used. BED_LIMIT_SWITCHING enables hysteresis. + */ +//#define PIDTEMPBED + +#if ENABLED(PIDTEMPBED) + //#define MIN_BED_POWER 0 // Min power to improve PID stability (0..MAX_BED_POWER). + // Get the power from the temperature report ('M105' => B@:nnn) and try P*2-20 to P*2-10. + //#define PID_BED_DEBUG // Print Bed PID debug data to the serial port. Use 'M303 D' to enable/disable. + + // 120V 250W silicone heater into 4mm borosilicate (MendelMax 1.5+) + // from FOPDT model - kp=.39 Tp=405 Tdead=66, Tc set to 79.2, aggressive factor of .15 (vs .1, 1, 10) + #define DEFAULT_bedKp 10.00 + #define DEFAULT_bedKi 0.023 + #define DEFAULT_bedKd 305.4 + + // FIND YOUR OWN: "M303 E-1 C8 S90" to run autotune on the bed at 90 degreesC for 8 cycles. +#else + //#define BED_LIMIT_SWITCHING // Keep the bed temperature within BED_HYSTERESIS of the target +#endif + +/** + * Peltier Bed - Heating and Cooling + * + * A Peltier device transfers heat from one side to the other in proportion to the amount of + * current flowing through the device and the direction of current flow. So the same device + * can both heat and cool. + * + * When "cooling" in addition to rejecting the heat transferred from the hot side to the cold + * side, the dissipated power (voltage * current) must also be rejected. Be sure to set up a + * fan that can be powered in sync with the Peltier unit. + * + * This feature is only set up to run in bang-bang mode because Peltiers don't handle PWM + * well without filter circuitry. + * + * Since existing 3D printers are made to handle relatively high current for the heated bed, + * we can use the heated bed power pins to control the Peltier power using the same G-codes + * as the heated bed (M140, M190, etc.). + * + * A second GPIO pin is required to control current direction. + * Two configurations are possible: Relay and H-Bridge + * + * (At this time only relay is supported. H-bridge requires 4 MOS switches configured in H-Bridge.) + * + * Power is handled by the bang-bang control loop: 0 or 255. + * Cooling applications are more common than heating, so the pin states are commonly: + * LOW = Heating = Relay Energized + * HIGH = Cooling = Relay in "Normal" state + */ +//#define PELTIER_BED +#if ENABLED(PELTIER_BED) + #define PELTIER_DIR_PIN -1 // Relay control pin for Peltier + #define PELTIER_DIR_HEAT_STATE LOW // The relay pin state that causes the Peltier to heat +#endif + +// Add 'M190 R T' for more gradual M190 R bed cooling. +//#define BED_ANNEALING_GCODE + +//=========================================================================== +//==================== PID > Chamber Temperature Control ==================== +//=========================================================================== + +/** + * PID Chamber Heating + * + * If this option is enabled set PID constants below. + * If this option is disabled, bang-bang will be used and CHAMBER_LIMIT_SWITCHING will enable + * hysteresis. + * + * The PID frequency will be the same as the extruder PWM. + * If PID_dT is the default, and correct for the hardware/configuration, that means 7.689Hz, + * which is fine for driving a square wave into a resistive load and does not significantly + * impact FET heating. This also works fine on a Fotek SSR-10DA Solid State Relay into a 200W + * heater. If your configuration is significantly different than this and you don't understand + * the issues involved, don't use chamber PID until someone else verifies that your hardware works. + * @section chamber temp + */ +//#define PIDTEMPCHAMBER +//#define CHAMBER_LIMIT_SWITCHING + +/** + * Max Chamber Power + * Applies to all forms of chamber control (PID, bang-bang, and bang-bang with hysteresis). + * When set to any value below 255, enables a form of PWM to the chamber heater that acts like a divider + * so don't use it unless you are OK with PWM on your heater. (See the comment on enabling PIDTEMPCHAMBER) + */ +#define MAX_CHAMBER_POWER 255 // limits duty cycle to chamber heater; 255=full current + +#if ENABLED(PIDTEMPCHAMBER) + //#define MIN_CHAMBER_POWER 0 // Min power to improve PID stability. (0..MAX_CHAMBER_POWER) + // Get the power from the temperature report ('M105' => C@:nnn) and try P*2-20 to P*2-10. + //#define PID_CHAMBER_DEBUG // Print Chamber PID debug data to the serial port. Use 'M303 D' to enable/disable. + + // Lasko "MyHeat Personal Heater" (200w) modified with a Fotek SSR-10DA to control only the heating element + // and placed inside the small Creality printer enclosure tent. + #define DEFAULT_chamberKp 37.04 + #define DEFAULT_chamberKi 1.40 + #define DEFAULT_chamberKd 655.17 + // M309 P37.04 I1.04 D655.17 + + // FIND YOUR OWN: "M303 E-2 C8 S50" to run autotune on the chamber at 50 degreesC for 8 cycles. +#endif // PIDTEMPCHAMBER + +// @section pid temp + +#if ANY(PIDTEMP, PIDTEMPBED, PIDTEMPCHAMBER) + //#define PID_OPENLOOP // Puts PID in open loop. M104/M140 sets the output power from 0 to PID_MAX + //#define SLOW_PWM_HEATERS // PWM with very low frequency (roughly 0.125Hz=8s) and minimum state time of approximately 1s useful for heaters driven by a relay + #define PID_FUNCTIONAL_RANGE 20 // If the temperature difference between the target temperature and the actual temperature + // is more than PID_FUNCTIONAL_RANGE then the PID will be shut off and the heater will be set to min/max. + + //#define PID_EDIT_MENU // Add PID editing to the "Advanced Settings" menu. (~700 bytes of flash) + //#define PID_AUTOTUNE_MENU // Add PID auto-tuning to the "Advanced Settings" menu. (~250 bytes of flash) +#endif + +// @section safety + +/** + * Prevent extrusion if the temperature is below EXTRUDE_MINTEMP. + * Add M302 to set the minimum extrusion temperature and/or turn + * cold extrusion prevention on and off. + * + * *** IT IS HIGHLY RECOMMENDED TO LEAVE THIS OPTION ENABLED! *** + */ +#define PREVENT_COLD_EXTRUSION +#define EXTRUDE_MINTEMP 170 + +/** + * Prevent a single extrusion longer than EXTRUDE_MAXLENGTH. + * Note: For Bowden Extruders make this large enough to allow load/unload. + */ +#define PREVENT_LENGTHY_EXTRUDE +#define EXTRUDE_MAXLENGTH 800 // prevent extrusion of very large distances. + +//=========================================================================== +//======================== Thermal Runaway Protection ======================= +//=========================================================================== + +/** + * Thermal Protection provides additional protection to your printer from damage + * and fire. Marlin always includes safe min and max temperature ranges which + * protect against a broken or disconnected thermistor wire. + * + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. + * + * If you get "Thermal Runaway" or "Heating failed" errors the + * details can be tuned in Configuration_adv.h + */ + +#define THERMAL_PROTECTION_HOTENDS // Enable thermal protection for all extruders +#define THERMAL_PROTECTION_BED // Enable thermal protection for the heated bed +#define THERMAL_PROTECTION_CHAMBER // Enable thermal protection for the heated chamber +#define THERMAL_PROTECTION_COOLER // Enable thermal protection for the laser cooling + +//=========================================================================== +//============================= Mechanical Settings ========================= +//=========================================================================== + +// @section kinematics + +// Enable one of the options below for CoreXY, CoreXZ, or CoreYZ kinematics, +// either in the usual order or reversed +//#define COREXY +//#define COREXZ +//#define COREYZ +//#define COREYX +//#define COREZX +//#define COREZY + +// +// MarkForged Kinematics +// See https://reprap.org/forum/read.php?152,504042 +// +//#define MARKFORGED_XY +//#define MARKFORGED_YX +#if ANY(MARKFORGED_XY, MARKFORGED_YX) + //#define MARKFORGED_INVERSE // Enable for an inverted Markforged kinematics belt path +#endif + +// Enable for a belt style printer with endless "Z" motion +//#define BELTPRINTER + +// Articulated robot (arm). Joints are directly mapped to axes with no kinematics. +//#define ARTICULATED_ROBOT_ARM + +// For a hot wire cutter with parallel horizontal axes (X, I) where the heights of the two wire +// ends are controlled by parallel axes (Y, J). Joints are directly mapped to axes (no kinematics). +//#define FOAMCUTTER_XYUV + +// @section polargraph + +// Enable for Polargraph Kinematics +//#define POLARGRAPH +#if ENABLED(POLARGRAPH) + #define POLARGRAPH_MAX_BELT_LEN 1035.0 // (mm) Belt length at full extension. Override with M665 H. + #define DEFAULT_SEGMENTS_PER_SECOND 5 // Move segmentation based on duration + #define PEN_UP_DOWN_MENU // Add "Pen Up" and "Pen Down" to the MarlinUI menu +#endif + +// @section delta + +// Enable for DELTA kinematics and configure below +#define DELTA +#if ENABLED(DELTA) + + // Make delta curves from many straight lines (linear interpolation). + // This is a trade-off between visible corners (not enough segments) + // and processor overload (too many expensive sqrt calls). + #define DEFAULT_SEGMENTS_PER_SECOND 160 + + // After homing move down to a height where XY movement is unconstrained + #define DELTA_HOME_TO_SAFE_ZONE + + // Delta calibration menu + // Add three-point calibration to the MarlinUI menu. + // See http://minow.blogspot.com/index.html#4918805519571907051 + #define DELTA_CALIBRATION_MENU + + // G33 Delta Auto-Calibration. Enable EEPROM_SETTINGS to store results. + #define DELTA_AUTO_CALIBRATION + + #if ENABLED(DELTA_AUTO_CALIBRATION) + // Default number of probe points : n*n (1 -> 7) + #define DELTA_CALIBRATION_DEFAULT_POINTS 4 + #endif + + #if ANY(DELTA_AUTO_CALIBRATION, DELTA_CALIBRATION_MENU) + // Step size for paper-test probing + #define PROBE_MANUALLY_STEP 0.025 // (mm) + #endif + + // Print surface diameter/2 minus unreachable space (avoid collisions with vertical towers). + #define PRINTABLE_RADIUS 85.0 // (mm) + + // Center-to-center distance of the holes in the diagonal push rods. + #define DELTA_DIAGONAL_ROD 216.0 // (mm) + + // Distance between bed and nozzle Z home position + #define DELTA_HEIGHT 325.00 // (mm) Get this value from G33 auto calibrate + + #define DELTA_ENDSTOP_ADJ { -0.05, 0.0, -0.02 } // (mm) Get these values from G33 auto calibrate + + // Horizontal offset from middle of printer to smooth rod center. + #define DELTA_SMOOTH_ROD_OFFSET 157 // 151 mm + + // Horizontal offset of the universal joints on the end effector. + #define DELTA_EFFECTOR_OFFSET 32 // 24 mm + + // Horizontal offset of the universal joints on the carriages. + #define DELTA_CARRIAGE_OFFSET 31 // 22 mm + + // Horizontal distance bridged by diagonal push rods when effector is centered. + #define DELTA_RADIUS (DELTA_SMOOTH_ROD_OFFSET-(DELTA_EFFECTOR_OFFSET)-(DELTA_CARRIAGE_OFFSET)) // (mm) Get this value from G33 auto calibrate + + // Trim adjustments for individual towers + // tower angle corrections for X and Y tower / rotate XYZ so Z tower angle = 0 + // measured in degrees anticlockwise looking from above the printer + #define DELTA_TOWER_ANGLE_TRIM { 0.0, 0.0, 0.0 } // (mm) Get these values from G33 auto calibrate + + // Delta radius and diagonal rod adjustments + //#define DELTA_RADIUS_TRIM_TOWER { 0.0, 0.0, 0.0 } // (mm) + //#define DELTA_DIAGONAL_ROD_TRIM_TOWER { 0.0, 0.0, 0.0 } // (mm) +#endif + +// @section scara + +/** + * MORGAN_SCARA was developed by QHARLEY in South Africa in 2012-2013. + * Implemented and slightly reworked by JCERNY in June, 2014. + * + * Mostly Printed SCARA is an open source design by Tyler Williams. See: + * https://www.thingiverse.com/thing:2487048 + * https://www.thingiverse.com/thing:1241491 + */ +//#define MORGAN_SCARA +//#define MP_SCARA +#if ANY(MORGAN_SCARA, MP_SCARA) + // If movement is choppy try lowering this value + #define DEFAULT_SEGMENTS_PER_SECOND 200 + + // Length of inner and outer support arms. Measure arm lengths precisely. + #define SCARA_LINKAGE_1 150 // (mm) + #define SCARA_LINKAGE_2 150 // (mm) + + // SCARA tower offset (position of Tower relative to bed zero position) + // This needs to be reasonably accurate as it defines the printbed position in the SCARA space. + #define SCARA_OFFSET_X 100 // (mm) + #define SCARA_OFFSET_Y -56 // (mm) + + #if ENABLED(MORGAN_SCARA) + + //#define DEBUG_SCARA_KINEMATICS + #define FEEDRATE_SCALING // Convert XY feedrate from mm/s to degrees/s on the fly + + // Radius around the center where the arm cannot reach + #define MIDDLE_DEAD_ZONE_R 0 // (mm) + + #elif ENABLED(MP_SCARA) + + #define SCARA_OFFSET_THETA1 12 // degrees + #define SCARA_OFFSET_THETA2 131 // degrees + + #endif + +#endif + +// @section tpara + +// Enable for TPARA kinematics and configure below +//#define AXEL_TPARA +#if ENABLED(AXEL_TPARA) + #define DEBUG_TPARA_KINEMATICS + #define DEFAULT_SEGMENTS_PER_SECOND 200 + + // Length of inner and outer support arms. Measure arm lengths precisely. + #define TPARA_LINKAGE_1 120 // (mm) + #define TPARA_LINKAGE_2 120 // (mm) + + // TPARA tower offset (position of Tower relative to bed zero position) + // This needs to be reasonably accurate as it defines the printbed position in the TPARA space. + #define TPARA_OFFSET_X 0 // (mm) + #define TPARA_OFFSET_Y 0 // (mm) + #define TPARA_OFFSET_Z 0 // (mm) + + #define FEEDRATE_SCALING // Convert XY feedrate from mm/s to degrees/s on the fly + + // Radius around the center where the arm cannot reach + #define MIDDLE_DEAD_ZONE_R 0 // (mm) +#endif + +// @section polar + +/** + * POLAR Kinematics + * developed by Kadir ilkimen for PolarBear CNC and babyBear + * https://github.com/kadirilkimen/Polar-Bear-Cnc-Machine + * https://github.com/kadirilkimen/babyBear-3D-printer + * + * A polar machine can have different configurations. + * This kinematics is only compatible with the following configuration: + * X : Independent linear + * Y or B : Polar + * Z : Independent linear + * + * For example, PolarBear has CoreXZ plus Polar Y or B. + * + * Motion problem for Polar axis near center / origin: + * + * 3D printing: + * Movements very close to the center of the polar axis take more time than others. + * This brief delay results in more material deposition due to the pressure in the nozzle. + * + * Current Kinematics and feedrate scaling deals with this by making the movement as fast + * as possible. It works for slow movements but doesn't work well with fast ones. A more + * complicated extrusion compensation must be implemented. + * + * Ideally, it should estimate that a long rotation near the center is ahead and will cause + * unwanted deposition. Therefore it can compensate the extrusion beforehand. + * + * Laser cutting: + * Same thing would be a problem for laser engraving too. As it spends time rotating at the + * center point, more likely it will burn more material than it should. Therefore similar + * compensation would be implemented for laser-cutting operations. + * + * Milling: + * This shouldn't be a problem for cutting/milling operations. + */ +//#define POLAR +#if ENABLED(POLAR) + #define DEFAULT_SEGMENTS_PER_SECOND 180 // If movement is choppy try lowering this value + #define PRINTABLE_RADIUS 82.0f // (mm) Maximum travel of X axis + + // Movements fall inside POLAR_FAST_RADIUS are assigned the highest possible feedrate + // to compensate unwanted deposition related to the near-origin motion problem. + #define POLAR_FAST_RADIUS 3.0f // (mm) + + // Radius which is unreachable by the tool. + // Needed if the tool is not perfectly aligned to the center of the polar axis. + #define POLAR_CENTER_OFFSET 0.0f // (mm) + + #define FEEDRATE_SCALING // Convert XY feedrate from mm/s to degrees/s on the fly +#endif + +//=========================================================================== +//============================== Endstop Settings =========================== +//=========================================================================== + +// @section endstops + +// Enable pullup for all endstops to prevent a floating state +#define ENDSTOPPULLUPS +#if DISABLED(ENDSTOPPULLUPS) + // Disable ENDSTOPPULLUPS to set pullups individually + //#define ENDSTOPPULLUP_XMIN + //#define ENDSTOPPULLUP_YMIN + //#define ENDSTOPPULLUP_ZMIN + //#define ENDSTOPPULLUP_IMIN + //#define ENDSTOPPULLUP_JMIN + //#define ENDSTOPPULLUP_KMIN + //#define ENDSTOPPULLUP_UMIN + //#define ENDSTOPPULLUP_VMIN + //#define ENDSTOPPULLUP_WMIN + //#define ENDSTOPPULLUP_XMAX + //#define ENDSTOPPULLUP_YMAX + //#define ENDSTOPPULLUP_ZMAX + //#define ENDSTOPPULLUP_IMAX + //#define ENDSTOPPULLUP_JMAX + //#define ENDSTOPPULLUP_KMAX + //#define ENDSTOPPULLUP_UMAX + //#define ENDSTOPPULLUP_VMAX + //#define ENDSTOPPULLUP_WMAX + //#define ENDSTOPPULLUP_ZMIN_PROBE +#endif + +// Enable pulldown for all endstops to prevent a floating state +//#define ENDSTOPPULLDOWNS +#if DISABLED(ENDSTOPPULLDOWNS) + // Disable ENDSTOPPULLDOWNS to set pulldowns individually + //#define ENDSTOPPULLDOWN_XMIN + //#define ENDSTOPPULLDOWN_YMIN + //#define ENDSTOPPULLDOWN_ZMIN + //#define ENDSTOPPULLDOWN_IMIN + //#define ENDSTOPPULLDOWN_JMIN + //#define ENDSTOPPULLDOWN_KMIN + //#define ENDSTOPPULLDOWN_UMIN + //#define ENDSTOPPULLDOWN_VMIN + //#define ENDSTOPPULLDOWN_WMIN + //#define ENDSTOPPULLDOWN_XMAX + //#define ENDSTOPPULLDOWN_YMAX + //#define ENDSTOPPULLDOWN_ZMAX + //#define ENDSTOPPULLDOWN_IMAX + //#define ENDSTOPPULLDOWN_JMAX + //#define ENDSTOPPULLDOWN_KMAX + //#define ENDSTOPPULLDOWN_UMAX + //#define ENDSTOPPULLDOWN_VMAX + //#define ENDSTOPPULLDOWN_WMAX + //#define ENDSTOPPULLDOWN_ZMIN_PROBE +#endif + +/** + * Endstop "Hit" State + * Set to the state (HIGH or LOW) that applies to each endstop. + */ +#define X_MIN_ENDSTOP_HIT_STATE HIGH +#define X_MAX_ENDSTOP_HIT_STATE HIGH +#define Y_MIN_ENDSTOP_HIT_STATE HIGH +#define Y_MAX_ENDSTOP_HIT_STATE HIGH +#define Z_MIN_ENDSTOP_HIT_STATE LOW +#define Z_MAX_ENDSTOP_HIT_STATE HIGH +#define I_MIN_ENDSTOP_HIT_STATE HIGH +#define I_MAX_ENDSTOP_HIT_STATE HIGH +#define J_MIN_ENDSTOP_HIT_STATE HIGH +#define J_MAX_ENDSTOP_HIT_STATE HIGH +#define K_MIN_ENDSTOP_HIT_STATE HIGH +#define K_MAX_ENDSTOP_HIT_STATE HIGH +#define U_MIN_ENDSTOP_HIT_STATE HIGH +#define U_MAX_ENDSTOP_HIT_STATE HIGH +#define V_MIN_ENDSTOP_HIT_STATE HIGH +#define V_MAX_ENDSTOP_HIT_STATE HIGH +#define W_MIN_ENDSTOP_HIT_STATE HIGH +#define W_MAX_ENDSTOP_HIT_STATE HIGH +#define Z_MIN_PROBE_ENDSTOP_HIT_STATE LOW + +// Enable this feature if all enabled endstop pins are interrupt-capable. +// This will remove the need to poll the interrupt pins, saving many CPU cycles. +//#define ENDSTOP_INTERRUPTS_FEATURE + +/** + * Endstop Noise Threshold + * + * Enable if your probe or endstops falsely trigger due to noise. + * + * - Higher values may affect repeatability or accuracy of some bed probes. + * - To fix noise install a 100nF ceramic capacitor in parallel with the switch. + * - This feature is not required for common micro-switches mounted on PCBs + * based on the Makerbot design, which already have the 100nF capacitor. + * + * :[2,3,4,5,6,7] + */ +//#define ENDSTOP_NOISE_THRESHOLD 2 + +// Check for stuck or disconnected endstops during homing moves. +//#define DETECT_BROKEN_ENDSTOP + +//============================================================================= +//============================== Movement Settings ============================ +//============================================================================= +// @section motion + +// delta speeds must be the same on xyz +/** + * Default Settings + * + * These settings can be reset by M502 + * + * Note that if EEPROM is enabled, saved values will override these. + */ + +#define NEMA_FULL_STEPS 200 +#define NEMA_MICROSTEPS 16 +#define XYZ_BELT_PITCH 2 +#define XYZ_PULLEY_TEETH 16 +#define XYZ_STEPS (NEMA_FULL_STEPS * NEMA_MICROSTEPS / XYZ_BELT_PITCH / XYZ_PULLEY_TEETH) + +#define E_GEAR_CIRCUMFERENCE 20 +#define E_STEPS NEMA_FULL_STEPS * NEMA_MICROSTEPS / E_GEAR_CIRCUMFERENCE + +/** + * With this option each E stepper can have its own factors for the + * following movement settings. If fewer factors are given than the + * total number of extruders, the last value applies to the rest. + */ +//#define DISTINCT_E_FACTORS + +/** + * Default Axis Steps Per Unit (linear=steps/mm, rotational=steps/°) + * Override with M92 (when enabled below) + * X, Y, Z [, I [, J [, K...]]], E0 [, E1[, E2...]] + */ +#define DEFAULT_AXIS_STEPS_PER_UNIT { XYZ_STEPS, XYZ_STEPS, XYZ_STEPS, E_STEPS } + +/** + * Enable support for M92. Disable to save at least ~530 bytes of flash. + */ +#define EDITABLE_STEPS_PER_UNIT + +/** + * Default Max Feed Rate (linear=mm/s, rotational=°/s) + * Override with M203 + * X, Y, Z [, I [, J [, K...]]], E0 [, E1[, E2...]] + */ +#define DEFAULT_MAX_FEEDRATE { 200, 200, 200, 25 } + +//#define LIMITED_MAX_FR_EDITING // Limit edit via M203 or LCD to DEFAULT_MAX_FEEDRATE * 2 +#if ENABLED(LIMITED_MAX_FR_EDITING) + #define MAX_FEEDRATE_EDIT_VALUES { 600, 600, 10, 50 } // ...or, set your own edit limits +#endif + +/** + * Default Max Acceleration (speed change with time) (linear=mm/(s^2), rotational=°/(s^2)) + * (Maximum start speed for accelerated moves) + * Override with M201 + * X, Y, Z [, I [, J [, K...]]], E0 [, E1[, E2...]] + */ +#define DEFAULT_MAX_ACCELERATION { 3000, 3000, 3000, 10000 } + +//#define LIMITED_MAX_ACCEL_EDITING // Limit edit via M201 or LCD to DEFAULT_MAX_ACCELERATION * 2 +#if ENABLED(LIMITED_MAX_ACCEL_EDITING) + #define MAX_ACCEL_EDIT_VALUES { 6000, 6000, 200, 20000 } // ...or, set your own edit limits +#endif + +/** + * Default Acceleration (speed change with time) (linear=mm/(s^2), rotational=°/(s^2)) + * Override with M204 + * + * M204 P Acceleration + * M204 R Retract Acceleration + * M204 T Travel Acceleration + */ +#define DEFAULT_ACCELERATION 3000 // X, Y, Z and E acceleration for printing moves +#define DEFAULT_RETRACT_ACCELERATION 3000 // E acceleration for retracts +#define DEFAULT_TRAVEL_ACCELERATION 3000 // X, Y, Z acceleration for travel (non printing) moves + +/** + * Default Jerk limits (mm/s) + * Override with M205 X Y Z . . . E + * + * "Jerk" specifies the minimum speed change that requires acceleration. + * When changing speed and direction, if the difference is less than the + * value set here, it may happen instantaneously. + */ +#define CLASSIC_JERK +#if ENABLED(CLASSIC_JERK) + #define DEFAULT_XJERK DEFAULT_ZJERK + #define DEFAULT_YJERK DEFAULT_ZJERK + #define DEFAULT_ZJERK 10.0 + #define DEFAULT_EJERK 5.0 + //#define DEFAULT_IJERK 0.3 + //#define DEFAULT_JJERK 0.3 + //#define DEFAULT_KJERK 0.3 + //#define DEFAULT_UJERK 0.3 + //#define DEFAULT_VJERK 0.3 + //#define DEFAULT_WJERK 0.3 + + //#define TRAVEL_EXTRA_XYJERK 0.0 // Additional jerk allowance for all travel moves + + //#define LIMITED_JERK_EDITING // Limit edit via M205 or LCD to DEFAULT_aJERK * 2 + #if ENABLED(LIMITED_JERK_EDITING) + #define MAX_JERK_EDIT_VALUES { 20, 20, 0.6, 10 } // ...or, set your own edit limits + #endif +#endif + +/** + * Junction Deviation Factor + * + * See: + * https://reprap.org/forum/read.php?1,739819 + * https://blog.kyneticcnc.com/2018/10/computing-junction-deviation-for-marlin.html + */ +#if DISABLED(CLASSIC_JERK) + #define JUNCTION_DEVIATION_MM 0.013 // (mm) Distance from real junction edge + #define JD_HANDLE_SMALL_SEGMENTS // Use curvature estimation instead of just the junction angle + // for small segments (< 1mm) with large junction angles (> 135°). +#endif + +/** + * S-Curve Acceleration + * + * This option eliminates vibration during printing by fitting a Bézier + * curve to move acceleration, producing much smoother direction changes. + * + * See https://github.com/synthetos/TinyG/wiki/Jerk-Controlled-Motion-Explained + */ +//#define S_CURVE_ACCELERATION + +//=========================================================================== +//============================= Z Probe Options ============================= +//=========================================================================== +// @section probes + +// +// See https://marlinfw.org/docs/configuration/probes.html +// + +/** + * Enable this option for a probe connected to the Z-MIN pin. + * The probe replaces the Z-MIN endstop and is used for Z homing. + * (Automatically enables USE_PROBE_FOR_Z_HOMING.) + */ +#define Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + +// Force the use of the probe for Z-axis homing +//#define USE_PROBE_FOR_Z_HOMING + +/** + * Z_MIN_PROBE_PIN + * + * Override this pin only if the probe cannot be connected to + * the default Z_MIN_PROBE_PIN for the selected MOTHERBOARD. + * + * - The simplest option is to use a free endstop connector. + * - Use 5V for powered (usually inductive) sensors. + * + * - For simple switches... + * - Normally-closed (NC) also connect to GND. + * - Normally-open (NO) also connect to 5V. + */ +//#define Z_MIN_PROBE_PIN -1 + +/** + * Probe Type + * + * Allen Key Probes, Servo Probes, Z-Sled Probes, FIX_MOUNTED_PROBE, etc. + * Activate one of these to use Auto Bed Leveling below. + */ + +/** + * The "Manual Probe" provides a means to do "Auto" Bed Leveling without a probe. + * Use G29 repeatedly, adjusting the Z height at each point with movement commands + * or (with LCD_BED_LEVELING) the LCD controller. + */ +//#define PROBE_MANUALLY + +/** + * A Fix-Mounted Probe either doesn't deploy or needs manual deployment. + * (e.g., an inductive probe or a nozzle-based probe-switch.) + */ +//#define FIX_MOUNTED_PROBE + +/** + * Use the nozzle as the probe, as with a conductive + * nozzle system or a piezo-electric smart effector. + */ +#define NOZZLE_AS_PROBE + +/** + * Z Servo Probe, such as an endstop switch on a rotating arm. + */ +//#define Z_PROBE_SERVO_NR 0 +#ifdef Z_PROBE_SERVO_NR + //#define Z_SERVO_ANGLES { 70, 0 } // Z Servo Deploy and Stow angles + //#define Z_SERVO_MEASURE_ANGLE 45 // Use if the servo must move to a "free" position for measuring after deploy + //#define Z_SERVO_INTERMEDIATE_STOW // Stow the probe between points + //#define Z_SERVO_DEACTIVATE_AFTER_STOW // Deactivate the servo when probe is stowed +#endif + +/** + * The BLTouch probe uses a Hall effect sensor and emulates a servo. + */ +//#define BLTOUCH + +/** + * MagLev V4 probe by MDD + * + * This probe is deployed and activated by powering a built-in electromagnet. + */ +//#define MAGLEV4 +#if ENABLED(MAGLEV4) + //#define MAGLEV_TRIGGER_PIN 11 // Set to the connected digital output + #define MAGLEV_TRIGGER_DELAY 15 // Changing this risks overheating the coil +#endif + +/** + * Touch-MI Probe by hotends.fr + * + * This probe is deployed and activated by moving the X-axis to a magnet at the edge of the bed. + * By default, the magnet is assumed to be on the left and activated by a home. If the magnet is + * on the right, enable and set TOUCH_MI_DEPLOY_XPOS to the deploy position. + * + * Also requires: BABYSTEPPING, BABYSTEP_ZPROBE_OFFSET, Z_SAFE_HOMING, + * and a minimum Z_CLEARANCE_FOR_HOMING of 10. + */ +//#define TOUCH_MI_PROBE +#if ENABLED(TOUCH_MI_PROBE) + #define TOUCH_MI_RETRACT_Z 0.5 // Height at which the probe retracts + //#define TOUCH_MI_DEPLOY_XPOS (X_MAX_BED + 2) // For a magnet on the right side of the bed + //#define TOUCH_MI_MANUAL_DEPLOY // For manual deploy (LCD menu) +#endif + +/** + * Bed Distance Sensor + * + * Measures the distance from bed to nozzle with accuracy of 0.01mm. + * For information about this sensor https://github.com/markniu/Bed_Distance_sensor + * Uses I2C port, so it requires I2C library markyue/Panda_SoftMasterI2C. + */ +//#define BD_SENSOR +#if ENABLED(BD_SENSOR) + //#define BD_SENSOR_PROBE_NO_STOP // Probe bed without stopping at each probe point +#endif + +/** + * BIQU MicroProbe + * + * A lightweight, solenoid-driven probe. + * For information about this sensor https://github.com/bigtreetech/MicroProbe + * + * Also requires PROBE_ENABLE_DISABLE + */ +//#define BIQU_MICROPROBE_V1 // Triggers HIGH +//#define BIQU_MICROPROBE_V2 // Triggers LOW + +// A probe that is deployed and stowed with a solenoid pin (SOL1_PIN) +//#define SOLENOID_PROBE + +// A sled-mounted probe like those designed by Charles Bell. +//#define Z_PROBE_SLED +//#define SLED_DOCKING_OFFSET 5 // The extra distance the X axis must travel to pickup the sled. 0 should be fine but you can push it further if you'd like. + +// A probe deployed by moving the x-axis, such as the Wilson II's rack-and-pinion probe designed by Marty Rice. +//#define RACK_AND_PINION_PROBE +#if ENABLED(RACK_AND_PINION_PROBE) + #define Z_PROBE_DEPLOY_X X_MIN_POS + #define Z_PROBE_RETRACT_X X_MAX_POS +#endif + +/** + * Magnetically Mounted Probe + * For probes such as Euclid, Klicky, Klackender, etc. + */ +//#define MAG_MOUNTED_PROBE +#if ENABLED(MAG_MOUNTED_PROBE) + #define PROBE_DEPLOY_FEEDRATE (133*60) // (mm/min) Probe deploy speed + #define PROBE_STOW_FEEDRATE (133*60) // (mm/min) Probe stow speed + + /** + * Magnetically Mounted Probe with a Servo mechanism + * Probe Deploy and Stow both follow the same basic sequence: + * - Rotate the SERVO to its Deployed angle + * - Perform XYZ moves to deploy or stow the PROBE + * - Rotate the SERVO to its Stowed angle + */ + //#define MAG_MOUNTED_PROBE_SERVO_NR 0 // Servo Number for this probe + #ifdef MAG_MOUNTED_PROBE_SERVO_NR + #define MAG_MOUNTED_PROBE_SERVO_ANGLES { 90, 0 } // Servo Angles for Deployed, Stowed + #define MAG_MOUNTED_PRE_DEPLOY { PROBE_DEPLOY_FEEDRATE, { 15, 160, 30 } } // Safe position for servo activation + #define MAG_MOUNTED_PRE_STOW { PROBE_DEPLOY_FEEDRATE, { 15, 160, 30 } } // Safe position for servo deactivation + #endif + + #define MAG_MOUNTED_DEPLOY_1 { PROBE_DEPLOY_FEEDRATE, { 245, 114, 30 } } // Move to side Dock & Attach probe + #define MAG_MOUNTED_DEPLOY_2 { PROBE_DEPLOY_FEEDRATE, { 210, 114, 30 } } // Move probe off dock + #define MAG_MOUNTED_DEPLOY_3 { PROBE_DEPLOY_FEEDRATE, { 0, 0, 0 } } // Extra move if needed + #define MAG_MOUNTED_DEPLOY_4 { PROBE_DEPLOY_FEEDRATE, { 0, 0, 0 } } // Extra move if needed + #define MAG_MOUNTED_DEPLOY_5 { PROBE_DEPLOY_FEEDRATE, { 0, 0, 0 } } // Extra move if needed + #define MAG_MOUNTED_STOW_1 { PROBE_STOW_FEEDRATE, { 245, 114, 20 } } // Move to dock + #define MAG_MOUNTED_STOW_2 { PROBE_STOW_FEEDRATE, { 245, 114, 0 } } // Place probe beside remover + #define MAG_MOUNTED_STOW_3 { PROBE_STOW_FEEDRATE, { 230, 114, 0 } } // Side move to remove probe + #define MAG_MOUNTED_STOW_4 { PROBE_STOW_FEEDRATE, { 210, 114, 20 } } // Side move to remove probe + #define MAG_MOUNTED_STOW_5 { PROBE_STOW_FEEDRATE, { 0, 0, 0 } } // Extra move if needed +#endif + +// Duet Smart Effector (for delta printers) - https://docs.duet3d.com/en/Duet3D_hardware/Accessories/Smart_Effector +// When the pin is defined you can use M672 to set/reset the probe sensitivity. +//#define DUET_SMART_EFFECTOR +#if ENABLED(DUET_SMART_EFFECTOR) + #define SMART_EFFECTOR_MOD_PIN -1 // Connect a GPIO pin to the Smart Effector MOD pin +#endif + +/** + * Use StallGuard2 to probe the bed with the nozzle. + * Requires stallGuard-capable Trinamic stepper drivers. + * CAUTION: This can damage machines with Z lead screws. + * Take extreme care when setting up this feature. + */ +//#define SENSORLESS_PROBING + +/** + * Allen key retractable z-probe as seen on many Kossel delta printers - https://reprap.org/wiki/Kossel#Autolevel_probe + * Deploys by touching z-axis belt. Retracts by pushing the probe down. + */ +//#define Z_PROBE_ALLEN_KEY +#if ENABLED(Z_PROBE_ALLEN_KEY) + // 2 or 3 sets of coordinates for deploying and retracting the spring loaded touch probe on G29, + // if servo actuated touch probe is not defined. Uncomment as appropriate for your printer/probe. + + #define Z_PROBE_ALLEN_KEY_DEPLOY_1 { 30.0, PRINTABLE_RADIUS, 100.0 } + #define Z_PROBE_ALLEN_KEY_DEPLOY_1_FEEDRATE XY_PROBE_FEEDRATE + + #define Z_PROBE_ALLEN_KEY_DEPLOY_2 { 0.0, PRINTABLE_RADIUS, 100.0 } + #define Z_PROBE_ALLEN_KEY_DEPLOY_2_FEEDRATE (XY_PROBE_FEEDRATE)/10 + + #define Z_PROBE_ALLEN_KEY_DEPLOY_3 { 0.0, (PRINTABLE_RADIUS) * 0.75, 100.0 } + #define Z_PROBE_ALLEN_KEY_DEPLOY_3_FEEDRATE XY_PROBE_FEEDRATE + + #define Z_PROBE_ALLEN_KEY_STOW_1 { -64.0, 56.0, 23.0 } // Move the probe into position + #define Z_PROBE_ALLEN_KEY_STOW_1_FEEDRATE XY_PROBE_FEEDRATE + + #define Z_PROBE_ALLEN_KEY_STOW_2 { -64.0, 56.0, 3.0 } // Push it down + #define Z_PROBE_ALLEN_KEY_STOW_2_FEEDRATE (XY_PROBE_FEEDRATE)/10 + + #define Z_PROBE_ALLEN_KEY_STOW_3 { -64.0, 56.0, 50.0 } // Move it up to clear + #define Z_PROBE_ALLEN_KEY_STOW_3_FEEDRATE XY_PROBE_FEEDRATE + + #define Z_PROBE_ALLEN_KEY_STOW_4 { 0.0, 0.0, 50.0 } + #define Z_PROBE_ALLEN_KEY_STOW_4_FEEDRATE XY_PROBE_FEEDRATE + +#endif // Z_PROBE_ALLEN_KEY + +/** + * Nozzle-to-Probe offsets { X, Y, Z } + * + * X and Y offset + * Use a caliper or ruler to measure the distance from the tip of + * the Nozzle to the center-point of the Probe in the X and Y axes. + * + * Z offset + * - For the Z offset use your best known value and adjust at runtime. + * - Common probes trigger below the nozzle and have negative values for Z offset. + * - Probes triggering above the nozzle height are uncommon but do exist. When using + * probes such as this, carefully set Z_CLEARANCE_DEPLOY_PROBE and Z_CLEARANCE_BETWEEN_PROBES + * to avoid collisions during probing. + * + * Tune and Adjust + * - Probe Offsets can be tuned at runtime with 'M851', LCD menus, babystepping, etc. + * - PROBE_OFFSET_WIZARD (Configuration_adv.h) can be used for setting the Z offset. + * + * Assuming the typical work area orientation: + * - Probe to RIGHT of the Nozzle has a Positive X offset + * - Probe to LEFT of the Nozzle has a Negative X offset + * - Probe in BACK of the Nozzle has a Positive Y offset + * - Probe in FRONT of the Nozzle has a Negative Y offset + * + * Some examples: + * #define NOZZLE_TO_PROBE_OFFSET { 10, 10, -1 } // Example "1" + * #define NOZZLE_TO_PROBE_OFFSET {-10, 5, -1 } // Example "2" + * #define NOZZLE_TO_PROBE_OFFSET { 5, -5, -1 } // Example "3" + * #define NOZZLE_TO_PROBE_OFFSET {-15,-10, -1 } // Example "4" + * + * +-- BACK ---+ + * | [+] | + * L | 1 | R <-- Example "1" (right+, back+) + * E | 2 | I <-- Example "2" ( left-, back+) + * F |[-] N [+]| G <-- Nozzle + * T | 3 | H <-- Example "3" (right+, front-) + * | 4 | T <-- Example "4" ( left-, front-) + * | [-] | + * O-- FRONT --+ + */ +#define NOZZLE_TO_PROBE_OFFSET { 0, 0, 0.2 } + +// Enable and set to use a specific tool for probing. Disable to allow any tool. +#define PROBING_TOOL 0 +#ifdef PROBING_TOOL + //#define PROBE_TOOLCHANGE_NO_MOVE // Suppress motion on probe tool-change +#endif + +// Most probes should stay away from the edges of the bed, but +// with NOZZLE_AS_PROBE this can be negative for a wider probing area. +#define PROBING_MARGIN 10 + +// X and Y axis travel speed between probes. +// Leave undefined to use the average of the current XY homing feedrate. +#define XY_PROBE_FEEDRATE (66*60) // (mm/min) + +// Feedrate for the first approach when double-probing (MULTIPLE_PROBING == 2) +#define Z_PROBE_FEEDRATE_FAST (20*60) // (mm/min) + +// Feedrate for the "accurate" probe of each point +#define Z_PROBE_FEEDRATE_SLOW (Z_PROBE_FEEDRATE_FAST / 2) // (mm/min) + +/** + * Probe Activation Switch + * A switch indicating proper deployment, or an optical + * switch triggered when the carriage is near the bed. + */ +//#define PROBE_ACTIVATION_SWITCH +#if ENABLED(PROBE_ACTIVATION_SWITCH) + #define PROBE_ACTIVATION_SWITCH_STATE LOW // State indicating probe is active + //#define PROBE_ACTIVATION_SWITCH_PIN PC6 // Override default pin +#endif + +/** + * Tare Probe (determine zero-point) prior to each probe. + * Useful for a strain gauge or piezo sensor that needs to factor out + * elements such as cables pulling on the carriage. + */ +//#define PROBE_TARE +#if ENABLED(PROBE_TARE) + #define PROBE_TARE_TIME 200 // (ms) Time to hold tare pin + #define PROBE_TARE_DELAY 200 // (ms) Delay after tare before + #define PROBE_TARE_STATE HIGH // State to write pin for tare + //#define PROBE_TARE_PIN PA5 // Override default pin + //#define PROBE_TARE_MENU // Display a menu item to tare the probe + #if ENABLED(PROBE_ACTIVATION_SWITCH) + //#define PROBE_TARE_ONLY_WHILE_INACTIVE // Fail to tare/probe if PROBE_ACTIVATION_SWITCH is active + #endif +#endif + +/** + * Probe Enable / Disable + * The probe only provides a triggered signal when enabled. + */ +//#define PROBE_ENABLE_DISABLE +#if ENABLED(PROBE_ENABLE_DISABLE) + //#define PROBE_ENABLE_PIN -1 // Override the default pin here +#endif + +/** + * Multiple Probing + * + * You may get improved results by probing 2 or more times. + * With EXTRA_PROBING the more atypical reading(s) will be disregarded. + * + * A total of 2 does fast/slow probes with a weighted average. + * A total of 3 or more adds more slow probes, taking the average. + */ +#define MULTIPLE_PROBING 2 +//#define EXTRA_PROBING 1 + +/** + * Z probes require clearance when deploying, stowing, and moving between + * probe points to avoid hitting the bed and other hardware. + * Servo-mounted probes require extra space for the arm to rotate. + * Inductive probes need space to keep from triggering early. + * + * Use these settings to specify the distance (mm) to raise the probe (or + * lower the bed). The values set here apply over and above any (negative) + * probe Z Offset set with NOZZLE_TO_PROBE_OFFSET, M851, or the LCD. + * Only integer values >= 1 are valid here. + * + * Example: 'M851 Z-5' with a CLEARANCE of 4 => 9mm from bed to nozzle. + * But: 'M851 Z+1' with a CLEARANCE of 2 => 2mm from bed to nozzle. + */ +#define Z_CLEARANCE_DEPLOY_PROBE 10 // (mm) Z Clearance for Deploy/Stow +#define Z_CLEARANCE_BETWEEN_PROBES 5 // (mm) Z Clearance between probe points +#define Z_CLEARANCE_MULTI_PROBE 5 // (mm) Z Clearance between multiple probes +#define Z_PROBE_ERROR_TOLERANCE 3 // (mm) Tolerance for early trigger (<= -probe.offset.z + ZPET) +//#define Z_AFTER_PROBING 5 // (mm) Z position after probing is done + +#define Z_PROBE_LOW_POINT -2 // (mm) Farthest distance below the trigger-point to go before stopping + +// For M851 provide ranges for adjusting the X, Y, and Z probe offsets +//#define PROBE_OFFSET_XMIN -50 // (mm) +//#define PROBE_OFFSET_XMAX 50 // (mm) +//#define PROBE_OFFSET_YMIN -50 // (mm) +//#define PROBE_OFFSET_YMAX 50 // (mm) +#define PROBE_OFFSET_ZMIN -20 // (mm) +#define PROBE_OFFSET_ZMAX 20 // (mm) + +// Enable the M48 repeatability test to test probe accuracy +//#define Z_MIN_PROBE_REPEATABILITY_TEST + +// Before deploy/stow pause for user confirmation +//#define PAUSE_BEFORE_DEPLOY_STOW +#if ENABLED(PAUSE_BEFORE_DEPLOY_STOW) + //#define PAUSE_PROBE_DEPLOY_WHEN_TRIGGERED // For Manual Deploy Allenkey Probe +#endif + +/** + * Enable one or more of the following if probing seems unreliable. + * Heaters and/or fans can be disabled during probing to minimize electrical + * noise. A delay can also be added to allow noise and vibration to settle. + * These options are most useful for the BLTouch probe, but may also improve + * readings with inductive probes and piezo sensors. + */ +//#define PROBING_HEATERS_OFF // Turn heaters off when probing +#if ENABLED(PROBING_HEATERS_OFF) + //#define WAIT_FOR_BED_HEATER // Wait for bed to heat back up between probes (to improve accuracy) + //#define WAIT_FOR_HOTEND // Wait for hotend to heat back up between probes (to improve accuracy & prevent cold extrude) +#endif +//#define PROBING_FANS_OFF // Turn fans off when probing +//#define PROBING_ESTEPPERS_OFF // Turn all extruder steppers off when probing +//#define PROBING_STEPPERS_OFF // Turn all steppers off (unless needed to hold position) when probing (including extruders) +//#define DELAY_BEFORE_PROBING 200 // (ms) To prevent vibrations from triggering piezo sensors + +// Require minimum nozzle and/or bed temperature for probing +//#define PREHEAT_BEFORE_PROBING +#if ENABLED(PREHEAT_BEFORE_PROBING) + #define PROBING_NOZZLE_TEMP 120 // (°C) Only applies to E0 at this time + #define PROBING_BED_TEMP 50 +#endif + +// @section stepper drivers + +// For Inverting Stepper Enable Pins (Active Low) use 0, Non Inverting (Active High) use 1 +// :['LOW', 'HIGH'] +#define X_ENABLE_ON LOW +#define Y_ENABLE_ON LOW +#define Z_ENABLE_ON LOW +#define E_ENABLE_ON LOW // For all extruders +//#define I_ENABLE_ON LOW +//#define J_ENABLE_ON LOW +//#define K_ENABLE_ON LOW +//#define U_ENABLE_ON LOW +//#define V_ENABLE_ON LOW +//#define W_ENABLE_ON LOW + +// Disable axis steppers immediately when they're not being stepped. +// WARNING: When motors turn off there is a chance of losing position accuracy! +//#define DISABLE_X +//#define DISABLE_Y +//#define DISABLE_Z +//#define DISABLE_I +//#define DISABLE_J +//#define DISABLE_K +//#define DISABLE_U +//#define DISABLE_V +//#define DISABLE_W + +// Turn off the display blinking that warns about possible accuracy reduction +//#define DISABLE_REDUCED_ACCURACY_WARNING + +// @section extruder + +//#define DISABLE_E // Disable the extruder when not stepping +#define DISABLE_OTHER_EXTRUDERS // Keep only the active extruder enabled + +// @section motion + +// Invert the stepper direction. Change (or reverse the motor connector) if an axis goes the wrong way. +#define INVERT_X_DIR true +#define INVERT_Y_DIR true +#define INVERT_Z_DIR true +//#define INVERT_I_DIR false +//#define INVERT_J_DIR false +//#define INVERT_K_DIR false +//#define INVERT_U_DIR false +//#define INVERT_V_DIR false +//#define INVERT_W_DIR false + +// @section extruder + +// For direct drive extruder v9 set to true, for geared extruder set to false. +#define INVERT_E0_DIR false +#define INVERT_E1_DIR false +#define INVERT_E2_DIR false +#define INVERT_E3_DIR false +#define INVERT_E4_DIR false +#define INVERT_E5_DIR false +#define INVERT_E6_DIR false +#define INVERT_E7_DIR false + +// @section homing + +//#define NO_MOTION_BEFORE_HOMING // Inhibit movement until all axes have been homed. Also enable HOME_AFTER_DEACTIVATE for extra safety. +//#define HOME_AFTER_DEACTIVATE // Require rehoming after steppers are deactivated. Also enable NO_MOTION_BEFORE_HOMING for extra safety. + +/** + * Set Z_IDLE_HEIGHT if the Z-Axis moves on its own when steppers are disabled. + * - Use a low value (i.e., Z_MIN_POS) if the nozzle falls down to the bed. + * - Use a large value (i.e., Z_MAX_POS) if the bed falls down, away from the nozzle. + */ +//#define Z_IDLE_HEIGHT Z_HOME_POS + +//#define Z_CLEARANCE_FOR_HOMING 4 // (mm) Minimal Z height before homing (G28) for Z clearance above the bed, clamps, ... + // You'll need this much clearance above Z_MAX_POS to avoid grinding. + +//#define Z_AFTER_HOMING 10 // (mm) Height to move to after homing (if Z was homed) +//#define XY_AFTER_HOMING { 10, 10 } // (mm) Move to an XY position after homing (and raising Z) + +//#define EVENT_GCODE_AFTER_HOMING "M300 P440 S200" // Commands to run after G28 (and move to XY_AFTER_HOMING) + +// Direction of endstops when homing; 1=MAX, -1=MIN +// :[-1,1] +#define X_HOME_DIR 1 +#define Y_HOME_DIR 1 +#define Z_HOME_DIR 1 +//#define I_HOME_DIR -1 +//#define J_HOME_DIR -1 +//#define K_HOME_DIR -1 +//#define U_HOME_DIR -1 +//#define V_HOME_DIR -1 +//#define W_HOME_DIR -1 + +/** + * Safety Stops + * If an axis has endstops on both ends the one specified above is used for + * homing, while the other can be used for things like SD_ABORT_ON_ENDSTOP_HIT. + */ +//#define X_SAFETY_STOP +//#define Y_SAFETY_STOP +//#define Z_SAFETY_STOP +//#define I_SAFETY_STOP +//#define J_SAFETY_STOP +//#define K_SAFETY_STOP +//#define U_SAFETY_STOP +//#define V_SAFETY_STOP +//#define W_SAFETY_STOP + +// @section geometry + +// The size of the printable area +#define X_BED_SIZE ((PRINTABLE_RADIUS) * 2) +#define Y_BED_SIZE ((PRINTABLE_RADIUS) * 2) + +// Travel limits (linear=mm, rotational=°) after homing, corresponding to endstop positions. +#define X_MIN_POS -(PRINTABLE_RADIUS) +#define Y_MIN_POS -(PRINTABLE_RADIUS) +#define Z_MIN_POS 0 +#define X_MAX_POS PRINTABLE_RADIUS +#define Y_MAX_POS PRINTABLE_RADIUS +#define Z_MAX_POS MANUAL_Z_HOME_POS +//#define I_MIN_POS 0 +//#define I_MAX_POS 50 +//#define J_MIN_POS 0 +//#define J_MAX_POS 50 +//#define K_MIN_POS 0 +//#define K_MAX_POS 50 +//#define U_MIN_POS 0 +//#define U_MAX_POS 50 +//#define V_MIN_POS 0 +//#define V_MAX_POS 50 +//#define W_MIN_POS 0 +//#define W_MAX_POS 50 + +/** + * Software Endstops + * + * - Prevent moves outside the set machine bounds. + * - Individual axes can be disabled, if desired. + * - X and Y only apply to Cartesian robots. + * - Use 'M211' to set software endstops on/off or report current state + */ + +// Min software endstops constrain movement within minimum coordinate bounds +#define MIN_SOFTWARE_ENDSTOPS +#if ENABLED(MIN_SOFTWARE_ENDSTOPS) + #define MIN_SOFTWARE_ENDSTOP_X + #define MIN_SOFTWARE_ENDSTOP_Y + #define MIN_SOFTWARE_ENDSTOP_Z + #define MIN_SOFTWARE_ENDSTOP_I + #define MIN_SOFTWARE_ENDSTOP_J + #define MIN_SOFTWARE_ENDSTOP_K + #define MIN_SOFTWARE_ENDSTOP_U + #define MIN_SOFTWARE_ENDSTOP_V + #define MIN_SOFTWARE_ENDSTOP_W +#endif + +// Max software endstops constrain movement within maximum coordinate bounds +#define MAX_SOFTWARE_ENDSTOPS +#if ENABLED(MAX_SOFTWARE_ENDSTOPS) + #define MAX_SOFTWARE_ENDSTOP_X + #define MAX_SOFTWARE_ENDSTOP_Y + #define MAX_SOFTWARE_ENDSTOP_Z + #define MAX_SOFTWARE_ENDSTOP_I + #define MAX_SOFTWARE_ENDSTOP_J + #define MAX_SOFTWARE_ENDSTOP_K + #define MAX_SOFTWARE_ENDSTOP_U + #define MAX_SOFTWARE_ENDSTOP_V + #define MAX_SOFTWARE_ENDSTOP_W +#endif + +#if ANY(MIN_SOFTWARE_ENDSTOPS, MAX_SOFTWARE_ENDSTOPS) + //#define SOFT_ENDSTOPS_MENU_ITEM // Enable/Disable software endstops from the LCD +#endif + +/** + * @section filament runout sensors + * + * Filament Runout Sensors + * Mechanical or opto endstops are used to check for the presence of filament. + * + * IMPORTANT: Runout will only trigger if Marlin is aware that a print job is running. + * Marlin knows a print job is running when: + * 1. Running a print job from media started with M24. + * 2. The Print Job Timer has been started with M75. + * 3. The heaters were turned on and PRINTJOB_TIMER_AUTOSTART is enabled. + * + * RAMPS-based boards use SERVO3_PIN for the first runout sensor. + * For other boards you may need to define FIL_RUNOUT_PIN, FIL_RUNOUT2_PIN, etc. + */ +//#define FILAMENT_RUNOUT_SENSOR +#if ENABLED(FILAMENT_RUNOUT_SENSOR) + #define FIL_RUNOUT_ENABLED_DEFAULT true // Enable the sensor on startup. Override with M412 followed by M500. + #define NUM_RUNOUT_SENSORS 1 // Number of sensors, up to one per extruder. Define a FIL_RUNOUT#_PIN for each. + + #define FIL_RUNOUT_STATE LOW // Pin state indicating that filament is NOT present. + #define FIL_RUNOUT_PULLUP // Use internal pullup for filament runout pins. + //#define FIL_RUNOUT_PULLDOWN // Use internal pulldown for filament runout pins. + //#define WATCH_ALL_RUNOUT_SENSORS // Execute runout script on any triggering sensor, not only for the active extruder. + // This is automatically enabled for MIXING_EXTRUDERs. + + // Override individually if the runout sensors vary + //#define FIL_RUNOUT1_STATE LOW + //#define FIL_RUNOUT1_PULLUP + //#define FIL_RUNOUT1_PULLDOWN + + //#define FIL_RUNOUT2_STATE LOW + //#define FIL_RUNOUT2_PULLUP + //#define FIL_RUNOUT2_PULLDOWN + + //#define FIL_RUNOUT3_STATE LOW + //#define FIL_RUNOUT3_PULLUP + //#define FIL_RUNOUT3_PULLDOWN + + //#define FIL_RUNOUT4_STATE LOW + //#define FIL_RUNOUT4_PULLUP + //#define FIL_RUNOUT4_PULLDOWN + + //#define FIL_RUNOUT5_STATE LOW + //#define FIL_RUNOUT5_PULLUP + //#define FIL_RUNOUT5_PULLDOWN + + //#define FIL_RUNOUT6_STATE LOW + //#define FIL_RUNOUT6_PULLUP + //#define FIL_RUNOUT6_PULLDOWN + + //#define FIL_RUNOUT7_STATE LOW + //#define FIL_RUNOUT7_PULLUP + //#define FIL_RUNOUT7_PULLDOWN + + //#define FIL_RUNOUT8_STATE LOW + //#define FIL_RUNOUT8_PULLUP + //#define FIL_RUNOUT8_PULLDOWN + + // Commands to execute on filament runout. + // With multiple runout sensors use the %c placeholder for the current tool in commands (e.g., "M600 T%c") + // NOTE: After 'M412 H1' the host handles filament runout and this script does not apply. + #define FILAMENT_RUNOUT_SCRIPT "M600" + + // After a runout is detected, continue printing this length of filament + // before executing the runout script. Useful for a sensor at the end of + // a feed tube. Requires 4 bytes SRAM per sensor, plus 4 bytes overhead. + //#define FILAMENT_RUNOUT_DISTANCE_MM 25 + + #ifdef FILAMENT_RUNOUT_DISTANCE_MM + // Enable this option to use an encoder disc that toggles the runout pin + // as the filament moves. (Be sure to set FILAMENT_RUNOUT_DISTANCE_MM + // large enough to avoid false positives.) + //#define FILAMENT_MOTION_SENSOR + + #if ENABLED(FILAMENT_MOTION_SENSOR) + //#define FILAMENT_SWITCH_AND_MOTION // Define separate pins below to sense motion + #if ENABLED(FILAMENT_SWITCH_AND_MOTION) + + #define FILAMENT_MOTION_DISTANCE_MM 3.0 // (mm) Missing distance required to trigger runout + + #define NUM_MOTION_SENSORS 1 // Number of sensors, up to one per extruder. Define a FIL_MOTION#_PIN for each. + //#define FIL_MOTION1_PIN -1 + + // Override individually if the motion sensors vary + //#define FIL_MOTION1_STATE LOW + //#define FIL_MOTION1_PULLUP + //#define FIL_MOTION1_PULLDOWN + + //#define FIL_MOTION2_STATE LOW + //#define FIL_MOTION2_PULLUP + //#define FIL_MOTION2_PULLDOWN + + //#define FIL_MOTION3_STATE LOW + //#define FIL_MOTION3_PULLUP + //#define FIL_MOTION3_PULLDOWN + + //#define FIL_MOTION4_STATE LOW + //#define FIL_MOTION4_PULLUP + //#define FIL_MOTION4_PULLDOWN + + //#define FIL_MOTION5_STATE LOW + //#define FIL_MOTION5_PULLUP + //#define FIL_MOTION5_PULLDOWN + + //#define FIL_MOTION6_STATE LOW + //#define FIL_MOTION6_PULLUP + //#define FIL_MOTION6_PULLDOWN + + //#define FIL_MOTION7_STATE LOW + //#define FIL_MOTION7_PULLUP + //#define FIL_MOTION7_PULLDOWN + + //#define FIL_MOTION8_STATE LOW + //#define FIL_MOTION8_PULLUP + //#define FIL_MOTION8_PULLDOWN + #endif // FILAMENT_SWITCH_AND_MOTION + #endif // FILAMENT_MOTION_SENSOR + #endif // FILAMENT_RUNOUT_DISTANCE_MM +#endif // FILAMENT_RUNOUT_SENSOR + +//=========================================================================== +//=============================== Bed Leveling ============================== +//=========================================================================== +// @section calibrate + +/** + * Choose one of the options below to enable G29 Bed Leveling. The parameters + * and behavior of G29 will change depending on your selection. + * + * If using a Probe for Z Homing, enable Z_SAFE_HOMING also! + * + * - AUTO_BED_LEVELING_3POINT + * Probe 3 arbitrary points on the bed (that aren't collinear) + * You specify the XY coordinates of all 3 points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_LINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_BILINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a mesh, best for large or uneven beds. + * + * - AUTO_BED_LEVELING_UBL (Unified Bed Leveling) + * A comprehensive bed leveling system combining the features and benefits + * of other systems. UBL also includes integrated Mesh Generation, Mesh + * Validation and Mesh Editing systems. + * + * - MESH_BED_LEVELING + * Probe a grid manually + * The result is a mesh, suitable for large or uneven beds. (See BILINEAR.) + * For machines without a probe, Mesh Bed Leveling provides a method to perform + * leveling in steps so you can manually adjust the Z height at each grid-point. + * With an LCD controller the process is guided step-by-step. + */ +//#define AUTO_BED_LEVELING_3POINT +//#define AUTO_BED_LEVELING_LINEAR +#define AUTO_BED_LEVELING_BILINEAR +//#define AUTO_BED_LEVELING_UBL +//#define MESH_BED_LEVELING + +/** + * Commands to execute at the start of G29 probing, + * after switching to the PROBING_TOOL. + */ +//#define EVENT_GCODE_BEFORE_G29 "M300 P440 S200" + +/** + * Commands to execute at the end of G29 probing. + * Useful to retract or move the Z probe out of the way. + */ +//#define EVENT_GCODE_AFTER_G29 "G1 Z10 F12000\nG1 X15 Y330\nG1 Z0.5\nG1 Z10" + +/** + * Normally G28 leaves leveling disabled on completion. Enable one of + * these options to restore the prior leveling state or to always enable + * leveling immediately after G28. + */ +//#define RESTORE_LEVELING_AFTER_G28 +//#define ENABLE_LEVELING_AFTER_G28 + +/** + * Auto-leveling needs preheating + */ +//#define PREHEAT_BEFORE_LEVELING +#if ENABLED(PREHEAT_BEFORE_LEVELING) + #define LEVELING_NOZZLE_TEMP 120 // (°C) Only applies to E0 at this time + #define LEVELING_BED_TEMP 50 +#endif + +/** + * Enable detailed logging of G28, G29, M48, etc. + * Turn on with the command 'M111 S32'. + * NOTE: Requires a lot of flash! + */ +//#define DEBUG_LEVELING_FEATURE + +#if ANY(MESH_BED_LEVELING, AUTO_BED_LEVELING_UBL, PROBE_MANUALLY) + // Set a height for the start of manual adjustment + #define MANUAL_PROBE_START_Z 0.2 // (mm) Comment out to use the last-measured height +#endif + +#if ANY(MESH_BED_LEVELING, AUTO_BED_LEVELING_BILINEAR, AUTO_BED_LEVELING_UBL) + /** + * Gradually reduce leveling correction until a set height is reached, + * at which point movement will be level to the machine's XY plane. + * The height can be set with M420 Z + */ + #define ENABLE_LEVELING_FADE_HEIGHT + #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) + #define DEFAULT_LEVELING_FADE_HEIGHT 10.0 // (mm) Default fade height. + #endif + + /** + * Add Z offset (M424 Z) that applies to all moves at the planner level. + * This Z offset will be automatically set to the middle value with G29. + */ + //#define GLOBAL_MESH_Z_OFFSET + + /** + * For Cartesian machines, instead of dividing moves on mesh boundaries, + * split up moves into short segments like a Delta. This follows the + * contours of the bed more closely than edge-to-edge straight moves. + */ + #define SEGMENT_LEVELED_MOVES + #define LEVELED_SEGMENT_LENGTH 5.0 // (mm) Length of all segments (except the last one) + + /** + * Enable the G26 Mesh Validation Pattern tool. + */ + //#define G26_MESH_VALIDATION + #if ENABLED(G26_MESH_VALIDATION) + #define MESH_TEST_NOZZLE_SIZE 0.4 // (mm) Diameter of primary nozzle. + #define MESH_TEST_LAYER_HEIGHT 0.2 // (mm) Default layer height for G26. + #define MESH_TEST_HOTEND_TEMP 205 // (°C) Default nozzle temperature for G26. + #define MESH_TEST_BED_TEMP 60 // (°C) Default bed temperature for G26. + #define G26_XY_FEEDRATE 20 // (mm/s) Feedrate for G26 XY moves. + #define G26_XY_FEEDRATE_TRAVEL 100 // (mm/s) Feedrate for G26 XY travel moves. + #define G26_RETRACT_MULTIPLIER 1.0 // G26 Q (retraction) used by default between mesh test elements. + #endif + +#endif + +#if ANY(AUTO_BED_LEVELING_LINEAR, AUTO_BED_LEVELING_BILINEAR) + + // Set the number of grid points per dimension. + #define GRID_MAX_POINTS_X 3 + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + // Probe along the Y axis, advancing X after each column + //#define PROBE_Y_FIRST + + #if ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Beyond the probed grid, continue the implied tilt? + // Default is to maintain the height of the nearest edge. + //#define EXTRAPOLATE_BEYOND_GRID + + // + // Subdivision of the grid by Catmull-Rom method. + // Synthesizes intermediate points to produce a more detailed mesh. + // + //#define ABL_BILINEAR_SUBDIVISION + #if ENABLED(ABL_BILINEAR_SUBDIVISION) + // Number of subdivisions between probe points + #define BILINEAR_SUBDIVISIONS 3 + #endif + + #endif + +#elif ENABLED(AUTO_BED_LEVELING_UBL) + + //=========================================================================== + //========================= Unified Bed Leveling ============================ + //=========================================================================== + + //#define MESH_EDIT_GFX_OVERLAY // Display a graphics overlay while editing the mesh + + #define MESH_INSET 1 // Set Mesh bounds as an inset region of the bed + #define GRID_MAX_POINTS_X 10 // Don't use more than 15 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + //#define UBL_HILBERT_CURVE // Use Hilbert distribution for less travel when probing multiple points + + //#define UBL_TILT_ON_MESH_POINTS // Use nearest mesh points with G29 J for better Z reference + //#define UBL_TILT_ON_MESH_POINTS_3POINT // Use nearest mesh points with G29 J0 (3-point) + + #define UBL_MESH_EDIT_MOVES_Z // Sophisticated users prefer no movement of nozzle + #define UBL_SAVE_ACTIVE_ON_M500 // Save the currently active mesh in the current slot on M500 + + //#define UBL_Z_RAISE_WHEN_OFF_MESH 2.5 // When the nozzle is off the mesh, this value is used + // as the Z-Height correction value. + + //#define UBL_MESH_WIZARD // Run several commands in a row to get a complete mesh + + /** + * Probing not allowed within the position of an obstacle. + */ + //#define AVOID_OBSTACLES + #if ENABLED(AVOID_OBSTACLES) + #define CLIP_W 23 // Bed clip width, should be padded a few mm over its physical size + #define CLIP_H 14 // Bed clip height, should be padded a few mm over its physical size + + // Obstacle Rectangles defined as { X1, Y1, X2, Y2 } + #define OBSTACLE1 { (X_BED_SIZE) / 4 - (CLIP_W) / 2, 0, (X_BED_SIZE) / 4 + (CLIP_W) / 2, CLIP_H } + #define OBSTACLE2 { (X_BED_SIZE) * 3 / 4 - (CLIP_W) / 2, 0, (X_BED_SIZE) * 3 / 4 + (CLIP_W) / 2, CLIP_H } + #define OBSTACLE3 { (X_BED_SIZE) / 4 - (CLIP_W) / 2, (Y_BED_SIZE) - (CLIP_H), (X_BED_SIZE) / 4 + (CLIP_W) / 2, Y_BED_SIZE } + #define OBSTACLE4 { (X_BED_SIZE) * 3 / 4 - (CLIP_W) / 2, (Y_BED_SIZE) - (CLIP_H), (X_BED_SIZE) * 3 / 4 + (CLIP_W) / 2, Y_BED_SIZE } + + // The probed grid must be inset for G29 J. This is okay, since it is + // only used to compute a linear transformation for the mesh itself. + #define G29J_MESH_TILT_MARGIN ((CLIP_H) + 1) + #endif + +#elif ENABLED(MESH_BED_LEVELING) + + //=========================================================================== + //=================================== Mesh ================================== + //=========================================================================== + + #define MESH_INSET 10 // Set Mesh bounds as an inset region of the bed + #define GRID_MAX_POINTS_X 3 + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + //#define MESH_G28_REST_ORIGIN // After homing all axes ('G28' or 'G28 XYZ') rest Z at Z_MIN_POS + +#endif // BED_LEVELING + +/** + * Add a bed leveling sub-menu for ABL or MBL. + * Include a guided procedure if manual probing is enabled. + */ +//#define LCD_BED_LEVELING + +#if ENABLED(LCD_BED_LEVELING) + #define MESH_EDIT_Z_STEP 0.025 // (mm) Step size while manually probing Z axis. + #define LCD_PROBE_Z_RANGE 4 // (mm) Z Range centered on Z_MIN_POS for LCD Z adjustment + //#define MESH_EDIT_MENU // Add a menu to edit mesh points +#endif + +// Add a menu item to move between bed corners for manual bed adjustment +//#define LCD_BED_TRAMMING + +#if ENABLED(LCD_BED_TRAMMING) + #define BED_TRAMMING_INSET_LFRB { 30, 30, 30, 30 } // (mm) Left, Front, Right, Back insets + #define BED_TRAMMING_HEIGHT 0.0 // (mm) Z height of nozzle at tramming points + #define BED_TRAMMING_Z_HOP 4.0 // (mm) Z raise between tramming points + //#define BED_TRAMMING_INCLUDE_CENTER // Move to the center after the last corner + //#define BED_TRAMMING_USE_PROBE + #if ENABLED(BED_TRAMMING_USE_PROBE) + #define BED_TRAMMING_PROBE_TOLERANCE 0.1 // (mm) + #define BED_TRAMMING_VERIFY_RAISED // After adjustment triggers the probe, re-probe to verify + //#define BED_TRAMMING_AUDIO_FEEDBACK + #endif + + /** + * Corner Leveling Order + * + * Set 2 or 4 points. When 2 points are given, the 3rd is the center of the opposite edge. + * + * LF Left-Front RF Right-Front + * LB Left-Back RB Right-Back + * + * Examples: + * + * Default {LF,RB,LB,RF} {LF,RF} {LB,LF} + * LB --------- RB LB --------- RB LB --------- RB LB --------- RB + * | 4 3 | | 3 2 | | <3> | | 1 | + * | | | | | | | <3>| + * | 1 2 | | 1 4 | | 1 2 | | 2 | + * LF --------- RF LF --------- RF LF --------- RF LF --------- RF + */ + #define BED_TRAMMING_LEVELING_ORDER { LF, RF, RB, LB } +#endif + +// @section homing + +// The center of the bed is at (X=0, Y=0) +#define BED_CENTER_AT_0_0 + +// Manually set the home position. Leave these undefined for automatic settings. +// For DELTA this is the top-center of the Cartesian print volume. +//#define MANUAL_X_HOME_POS 0 +//#define MANUAL_Y_HOME_POS 0 +#define MANUAL_Z_HOME_POS DELTA_HEIGHT // Distance between the nozzle to printbed after homing +//#define MANUAL_I_HOME_POS 0 +//#define MANUAL_J_HOME_POS 0 +//#define MANUAL_K_HOME_POS 0 +//#define MANUAL_U_HOME_POS 0 +//#define MANUAL_V_HOME_POS 0 +//#define MANUAL_W_HOME_POS 0 + +/** + * Use "Z Safe Homing" to avoid homing with a Z probe outside the bed area. + * + * - Moves the Z probe (or nozzle) to a defined XY point before Z homing. + * - Allows Z homing only when XY positions are known and trusted. + * - If stepper drivers sleep, XY homing may be required again before Z homing. + */ +//#define Z_SAFE_HOMING + +#if ENABLED(Z_SAFE_HOMING) + #define Z_SAFE_HOMING_X_POINT X_CENTER // (mm) X point for Z homing + #define Z_SAFE_HOMING_Y_POINT Y_CENTER // (mm) Y point for Z homing + //#define Z_SAFE_HOMING_POINT_ABSOLUTE // Ignore home offsets (M206) for Z homing position +#endif + +// Homing speeds (linear=mm/min, rotational=°/min) +#define HOMING_FEEDRATE_MM_M { (50*60), (50*60), (100*60) } + +// Edit homing feedrates with M210 and MarlinUI menu items +//#define EDITABLE_HOMING_FEEDRATE + +// Validate that endstops are triggered on homing moves +#define VALIDATE_HOMING_ENDSTOPS + +// @section calibrate + +/** + * Bed Skew Compensation + * + * This feature corrects for misalignment in the XYZ axes. + * + * Take the following steps to get the bed skew in the XY plane: + * 1. Print a test square (e.g., https://www.thingiverse.com/thing:2563185) + * 2. For XY_DIAG_AC measure the diagonal A to C + * 3. For XY_DIAG_BD measure the diagonal B to D + * 4. For XY_SIDE_AD measure the edge A to D + * + * Marlin automatically computes skew factors from these measurements. + * Skew factors may also be computed and set manually: + * + * - Compute AB : SQRT(2*AC*AC+2*BD*BD-4*AD*AD)/2 + * - XY_SKEW_FACTOR : TAN(PI/2-ACOS((AC*AC-AB*AB-AD*AD)/(2*AB*AD))) + * + * If desired, follow the same procedure for XZ and YZ. + * Use these diagrams for reference: + * + * Y Z Z + * ^ B-------C ^ B-------C ^ B-------C + * | / / | / / | / / + * | / / | / / | / / + * | A-------D | A-------D | A-------D + * +-------------->X +-------------->X +-------------->Y + * XY_SKEW_FACTOR XZ_SKEW_FACTOR YZ_SKEW_FACTOR + */ +//#define SKEW_CORRECTION + +#if ENABLED(SKEW_CORRECTION) + // Input all length measurements here: + #define XY_DIAG_AC 282.8427124746 + #define XY_DIAG_BD 282.8427124746 + #define XY_SIDE_AD 200 + + // Or, set the XY skew factor directly: + //#define XY_SKEW_FACTOR 0.0 + + //#define SKEW_CORRECTION_FOR_Z + #if ENABLED(SKEW_CORRECTION_FOR_Z) + #define XZ_DIAG_AC 282.8427124746 + #define XZ_DIAG_BD 282.8427124746 + #define YZ_DIAG_AC 282.8427124746 + #define YZ_DIAG_BD 282.8427124746 + #define YZ_SIDE_AD 200 + + // Or, set the Z skew factors directly: + //#define XZ_SKEW_FACTOR 0.0 + //#define YZ_SKEW_FACTOR 0.0 + #endif + + // Enable this option for M852 to set skew at runtime + //#define SKEW_CORRECTION_GCODE +#endif + +//============================================================================= +//============================= Additional Features =========================== +//============================================================================= + +// @section eeprom + +/** + * EEPROM + * + * Persistent storage to preserve configurable settings across reboots. + * + * M500 - Store settings to EEPROM. + * M501 - Read settings from EEPROM. (i.e., Throw away unsaved changes) + * M502 - Revert settings to "factory" defaults. (Follow with M500 to init the EEPROM.) + */ +#define EEPROM_SETTINGS // Persistent storage with M500 and M501 +//#define DISABLE_M503 // Saves ~2700 bytes of flash. Disable for release! +#define EEPROM_CHITCHAT // Give feedback on EEPROM commands. Disable to save flash. +#define EEPROM_BOOT_SILENT // Keep M503 quiet and only give errors during first load +#if ENABLED(EEPROM_SETTINGS) + //#define EEPROM_AUTO_INIT // Init EEPROM automatically on any errors. + //#define EEPROM_INIT_NOW // Init EEPROM on first boot after a new build. +#endif + +// @section host + +// +// Host Keepalive +// +// When enabled Marlin will send a busy status message to the host +// every couple of seconds when it can't accept commands. +// +#define HOST_KEEPALIVE_FEATURE // Disable this if your host doesn't like keepalive messages +#define DEFAULT_KEEPALIVE_INTERVAL 2 // Number of seconds between "busy" messages. Set with M113. +#define BUSY_WHILE_HEATING // Some hosts require "busy" messages even during heating + +// @section units + +// +// G20/G21 Inch mode support +// +//#define INCH_MODE_SUPPORT + +// +// M149 Set temperature units support +// +//#define TEMPERATURE_UNITS_SUPPORT + +// @section temperature + +// +// Preheat Constants - Up to 10 are supported without changes +// +#define PREHEAT_1_LABEL "PLA" +#define PREHEAT_1_TEMP_HOTEND 180 +#define PREHEAT_1_TEMP_BED 70 +#define PREHEAT_1_TEMP_CHAMBER 35 +#define PREHEAT_1_FAN_SPEED 0 // Value from 0 to 255 + +#define PREHEAT_2_LABEL "ABS" +#define PREHEAT_2_TEMP_HOTEND 240 +#define PREHEAT_2_TEMP_BED 110 +#define PREHEAT_2_TEMP_CHAMBER 35 +#define PREHEAT_2_FAN_SPEED 0 // Value from 0 to 255 + +/** + * @section nozzle park + * + * Nozzle Park + * + * Park the nozzle at the given XYZ position on idle or G27. + * + * The "P" parameter controls the action applied to the Z axis: + * + * P0 (Default) If Z is below park Z raise the nozzle. + * P1 Raise the nozzle always to Z-park height. + * P2 Raise the nozzle by Z-park amount, limited to Z_MAX_POS. + */ +#define NOZZLE_PARK_FEATURE + +#if ENABLED(NOZZLE_PARK_FEATURE) + // Specify a park position as { X, Y, Z_raise } + #define NOZZLE_PARK_POINT { 0, Y_MIN_POS, 10 } + #define NOZZLE_PARK_MOVE 0 // Park motion: 0 = XY Move, 1 = X Only, 2 = Y Only, 3 = X before Y, 4 = Y before X + #define NOZZLE_PARK_Z_RAISE_MIN 2 // (mm) Always raise Z by at least this distance + #define NOZZLE_PARK_XY_FEEDRATE 100 // (mm/s) X and Y axes feedrate (also used for delta Z axis) + #define NOZZLE_PARK_Z_FEEDRATE 5 // (mm/s) Z axis feedrate (not used for delta printers) +#endif + +/** + * @section nozzle clean + * + * Clean Nozzle Feature + * + * Adds the G12 command to perform a nozzle cleaning process. + * + * Parameters: + * P Pattern + * S Strokes / Repetitions + * T Triangles (P1 only) + * + * Patterns: + * P0 Straight line (default). This process requires a sponge type material + * at a fixed bed location. "S" specifies strokes (i.e. back-forth motions) + * between the start / end points. + * + * P1 Zig-zag pattern between (X0, Y0) and (X1, Y1), "T" specifies the + * number of zig-zag triangles to do. "S" defines the number of strokes. + * Zig-zags are done in whichever is the narrower dimension. + * For example, "G12 P1 S1 T3" will execute: + * + * -- + * | (X0, Y1) | /\ /\ /\ | (X1, Y1) + * | | / \ / \ / \ | + * A | | / \ / \ / \ | + * | | / \ / \ / \ | + * | (X0, Y0) | / \/ \/ \ | (X1, Y0) + * -- +--------------------------------+ + * |________|_________|_________| + * T1 T2 T3 + * + * P2 Circular pattern with middle at NOZZLE_CLEAN_CIRCLE_MIDDLE. + * "R" specifies the radius. "S" specifies the stroke count. + * Before starting, the nozzle moves to NOZZLE_CLEAN_START_POINT. + * + * Caveats: The ending Z should be the same as starting Z. + */ +//#define NOZZLE_CLEAN_FEATURE + +#if ENABLED(NOZZLE_CLEAN_FEATURE) + #define NOZZLE_CLEAN_PATTERN_LINE // Provide 'G12 P0' - a simple linear cleaning pattern + #define NOZZLE_CLEAN_PATTERN_ZIGZAG // Provide 'G12 P1' - a zigzag cleaning pattern + #define NOZZLE_CLEAN_PATTERN_CIRCLE // Provide 'G12 P2' - a circular cleaning pattern + + // Default pattern to use when 'P' is not provided to G12. One of the enabled options above. + #define NOZZLE_CLEAN_DEFAULT_PATTERN 0 + + #define NOZZLE_CLEAN_STROKES 12 // Default number of pattern repetitions + + #if ENABLED(NOZZLE_CLEAN_PATTERN_ZIGZAG) + #define NOZZLE_CLEAN_TRIANGLES 3 // Default number of triangles + #endif + + // Specify positions for each tool as { { X, Y, Z }, { X, Y, Z } } + // Dual hotend system may use { { -20, (Y_BED_SIZE / 2), (Z_MIN_POS + 1) }, { 420, (Y_BED_SIZE / 2), (Z_MIN_POS + 1) }} + #define NOZZLE_CLEAN_START_POINT { { 30, 30, (Z_MIN_POS + 1) } } + #define NOZZLE_CLEAN_END_POINT { { 100, 60, (Z_MIN_POS + 1) } } + + #if ENABLED(NOZZLE_CLEAN_PATTERN_CIRCLE) + #define NOZZLE_CLEAN_CIRCLE_RADIUS 6.5 // (mm) Circular pattern radius + #define NOZZLE_CLEAN_CIRCLE_FN 10 // Circular pattern circle number of segments + #define NOZZLE_CLEAN_CIRCLE_MIDDLE NOZZLE_CLEAN_START_POINT // Middle point of circle + #endif + + // Move the nozzle to the initial position after cleaning + #define NOZZLE_CLEAN_GOBACK + + // For a purge/clean station that's always at the gantry height (thus no Z move) + //#define NOZZLE_CLEAN_NO_Z + + // For a purge/clean station mounted on the X axis + //#define NOZZLE_CLEAN_NO_Y + + // Require a minimum hotend temperature for cleaning + #define NOZZLE_CLEAN_MIN_TEMP 170 + //#define NOZZLE_CLEAN_HEATUP // Heat up the nozzle instead of skipping wipe + + // Explicit wipe G-code script applies to a G12 with no arguments. + //#define WIPE_SEQUENCE_COMMANDS "G1 X-17 Y25 Z10 F4000\nG1 Z1\nM114\nG1 X-17 Y25\nG1 X-17 Y95\nG1 X-17 Y25\nG1 X-17 Y95\nG1 X-17 Y25\nG1 X-17 Y95\nG1 X-17 Y25\nG1 X-17 Y95\nG1 X-17 Y25\nG1 X-17 Y95\nG1 X-17 Y25\nG1 X-17 Y95\nG1 Z15\nM400\nG0 X-10.0 Y-9.0" + +#endif + +// @section host + +/** + * Print Job Timer + * + * Automatically start and stop the print job timer on M104/M109/M140/M190/M141/M191. + * The print job timer will only be stopped if the bed/chamber target temp is + * below BED_MINTEMP/CHAMBER_MINTEMP. + * + * M104 (hotend, no wait) - high temp = none, low temp = stop timer + * M109 (hotend, wait) - high temp = start timer, low temp = stop timer + * M140 (bed, no wait) - high temp = none, low temp = stop timer + * M190 (bed, wait) - high temp = start timer, low temp = none + * M141 (chamber, no wait) - high temp = none, low temp = stop timer + * M191 (chamber, wait) - high temp = start timer, low temp = none + * + * For M104/M109, high temp is anything over EXTRUDE_MINTEMP / 2. + * For M140/M190, high temp is anything over BED_MINTEMP. + * For M141/M191, high temp is anything over CHAMBER_MINTEMP. + * + * The timer can also be controlled with the following commands: + * + * M75 - Start the print job timer + * M76 - Pause the print job timer + * M77 - Stop the print job timer + */ +#define PRINTJOB_TIMER_AUTOSTART + +// @section stats + +/** + * Print Counter + * + * Track statistical data such as: + * + * - Total print jobs + * - Total successful print jobs + * - Total failed print jobs + * - Total time printing + * + * View the current statistics with M78. + */ +#define PRINTCOUNTER +#if ENABLED(PRINTCOUNTER) + #define PRINTCOUNTER_SAVE_INTERVAL 60 // (minutes) EEPROM save interval during print. A value of 0 will save stats at end of print. +#endif + +// @section security + +/** + * Password + * + * Set a numerical password for the printer which can be requested: + * + * - When the printer boots up + * - Upon opening the 'Print from Media' Menu + * - When SD printing is completed or aborted + * + * The following G-codes can be used: + * + * M510 - Lock Printer. Blocks all commands except M511. + * M511 - Unlock Printer. + * M512 - Set, Change and Remove Password. + * + * If you forget the password and get locked out you'll need to re-flash + * the firmware with the feature disabled, reset EEPROM, and (optionally) + * re-flash the firmware again with this feature enabled. + */ +//#define PASSWORD_FEATURE +#if ENABLED(PASSWORD_FEATURE) + #define PASSWORD_LENGTH 4 // (#) Number of digits (1-9). 3 or 4 is recommended + #define PASSWORD_ON_STARTUP + #define PASSWORD_UNLOCK_GCODE // Unlock with the M511 P command. Disable to prevent brute-force attack. + #define PASSWORD_CHANGE_GCODE // Change the password with M512 P S. + //#define PASSWORD_ON_SD_PRINT_MENU // This does not prevent G-codes from running + //#define PASSWORD_AFTER_SD_PRINT_END + //#define PASSWORD_AFTER_SD_PRINT_ABORT + //#include "Configuration_Secure.h" // External file with PASSWORD_DEFAULT_VALUE +#endif + +// @section media + +/** + * SD CARD + * + * SD Card support is disabled by default. If your controller has an SD slot, + * you must uncomment the following option or it won't work. + */ +#define SDSUPPORT + +/** + * SD CARD: ENABLE CRC + * + * Use CRC checks and retries on the SD communication. + */ +#if ENABLED(SDSUPPORT) + //#define SD_CHECK_AND_RETRY +#endif + +// @section interface + +/** + * LCD LANGUAGE + * + * Select the language to display on the LCD. These languages are available: + * + * en, an, bg, ca, cz, da, de, el, el_CY, es, eu, fi, fr, gl, hr, hu, it, + * jp_kana, ko_KR, nl, pl, pt, pt_br, ro, ru, sk, sv, tr, uk, vi, zh_CN, zh_TW + * + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cz':'Czech', 'da':'Danish', 'de':'German', 'el':'Greek (Greece)', 'el_CY':'Greek (Cyprus)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'hu':'Hungarian', 'it':'Italian', 'jp_kana':'Japanese', 'ko_KR':'Korean (South Korea)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt_br':'Portuguese (Brazilian)', 'ro':'Romanian', 'ru':'Russian', 'sk':'Slovak', 'sv':'Swedish', 'tr':'Turkish', 'uk':'Ukrainian', 'vi':'Vietnamese', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Traditional)' } + */ +#define LCD_LANGUAGE en + +/** + * LCD Character Set + * + * Note: This option is NOT applicable to Graphical Displays. + * + * All character-based LCDs provide ASCII plus one of these + * language extensions: + * + * - JAPANESE ... the most common + * - WESTERN ... with more accented characters + * - CYRILLIC ... for the Russian language + * + * To determine the language extension installed on your controller: + * + * - Compile and upload with LCD_LANGUAGE set to 'test' + * - Click the controller to view the LCD menu + * - The LCD will display Japanese, Western, or Cyrillic text + * + * See https://marlinfw.org/docs/development/lcd_language.html + * + * :['JAPANESE', 'WESTERN', 'CYRILLIC'] + */ +#define DISPLAY_CHARSET_HD44780 JAPANESE + +/** + * Info Screen Style (0:Classic, 1:Průša, 2:CNC) + * + * :[0:'Classic', 1:'Průša', 2:'CNC'] + */ +#define LCD_INFO_SCREEN_STYLE 0 + +/** + * LCD Menu Items + * + * Disable all menus and only display the Status Screen, or + * just remove some extraneous menu items to recover space. + */ +//#define NO_LCD_MENUS +//#define SLIM_LCD_MENUS + +// +// ENCODER SETTINGS +// +// This option overrides the default number of encoder pulses needed to +// produce one step. Should be increased for high-resolution encoders. +// +//#define ENCODER_PULSES_PER_STEP 4 + +// +// Use this option to override the number of step signals required to +// move between next/prev menu items. +// +//#define ENCODER_STEPS_PER_MENU_ITEM 1 + +/** + * Encoder Direction Options + * + * Test your encoder's behavior first with both options disabled. + * + * Reversed Value Edit and Menu Nav? Enable REVERSE_ENCODER_DIRECTION. + * Reversed Menu Navigation only? Enable REVERSE_MENU_DIRECTION. + * Reversed Value Editing only? Enable BOTH options. + */ + +// +// This option reverses the encoder direction everywhere. +// +// Set this option if CLOCKWISE causes values to DECREASE +// +//#define REVERSE_ENCODER_DIRECTION + +// +// This option reverses the encoder direction for navigating LCD menus. +// +// If CLOCKWISE normally moves DOWN this makes it go UP. +// If CLOCKWISE normally moves UP this makes it go DOWN. +// +//#define REVERSE_MENU_DIRECTION + +// +// This option reverses the encoder direction for Select Screen. +// +// If CLOCKWISE normally moves LEFT this makes it go RIGHT. +// If CLOCKWISE normally moves RIGHT this makes it go LEFT. +// +//#define REVERSE_SELECT_DIRECTION + +// +// Encoder EMI Noise Filter +// +// This option increases encoder samples to filter out phantom encoder clicks caused by EMI noise. +// +//#define ENCODER_NOISE_FILTER +#if ENABLED(ENCODER_NOISE_FILTER) + #define ENCODER_SAMPLES 10 +#endif + +// +// Individual Axis Homing +// +// Add individual axis homing items (Home X, Home Y, and Home Z) to the LCD menu. +// +//#define INDIVIDUAL_AXIS_HOMING_MENU +//#define INDIVIDUAL_AXIS_HOMING_SUBMENU + +// +// SPEAKER/BUZZER +// +// If you have a speaker that can produce tones, enable it here. +// By default Marlin assumes you have a buzzer with a fixed frequency. +// +//#define SPEAKER + +// +// The duration and frequency for the UI feedback sound. +// Set these to 0 to disable audio feedback in the LCD menus. +// +// Note: Test audio output with the G-Code: +// M300 S P +// +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 2 +//#define LCD_FEEDBACK_FREQUENCY_HZ 5000 + +// +// Tone queue size, used to keep beeps from blocking execution. +// Default is 4, or override here. Costs 4 bytes of SRAM per entry. +// +//#define TONE_QUEUE_LENGTH 4 + +// +// A sequence of tones to play at startup, in pairs of tone (Hz), duration (ms). +// Silence in-between tones. +// +//#define STARTUP_TUNE { 698, 300, 0, 50, 523, 50, 0, 25, 494, 50, 0, 25, 523, 100, 0, 50, 554, 300, 0, 100, 523, 300 } + +//============================================================================= +//======================== LCD / Controller Selection ========================= +//======================== (Character-based LCDs) ========================= +//============================================================================= +// @section lcd + +// +// RepRapDiscount Smart Controller. +// https://reprap.org/wiki/RepRapDiscount_Smart_Controller +// +// Note: Usually sold with a white PCB. +// +#define REPRAP_DISCOUNT_SMART_CONTROLLER + +// +// GT2560 (YHCB2004) LCD Display +// +// Requires Testato, Koepel softwarewire library and +// Andriy Golovnya's LiquidCrystal_AIP31068 library. +// +//#define YHCB2004 + +// +// Original RADDS LCD Display+Encoder+SDCardReader +// https://web.archive.org/web/20200719145306/doku.radds.org/dokumentation/lcd-display/ +// +//#define RADDS_DISPLAY + +// +// ULTIMAKER Controller. +// +//#define ULTIMAKERCONTROLLER + +// +// ULTIPANEL as seen on Thingiverse. +// +//#define ULTIPANEL + +// +// PanelOne from T3P3 (via RAMPS 1.4 AUX2/AUX3) +// https://reprap.org/wiki/PanelOne +// +//#define PANEL_ONE + +// +// GADGETS3D G3D LCD/SD Controller +// https://reprap.org/wiki/RAMPS_1.3/1.4_GADGETS3D_Shield_with_Panel +// +// Note: Usually sold with a blue PCB. +// +//#define G3D_PANEL + +// +// RigidBot Panel V1.0 +// +//#define RIGIDBOT_PANEL + +// +// Makeboard 3D Printer Parts 3D Printer Mini Display 1602 Mini Controller +// https://www.aliexpress.com/item/32765887917.html +// +//#define MAKEBOARD_MINI_2_LINE_DISPLAY_1602 + +/** + * ANET and Tronxy 20x4 Controller + * LCD2004 display with 5 analog buttons. + * + * NOTE: Requires ADC_KEYPAD_PIN to be assigned to an analog pin. + * This LCD is known to be susceptible to electrical interference which + * scrambles the display. Press any button to clear it up. + */ +//#define ZONESTAR_LCD + +// +// Generic 16x2, 16x4, 20x2, or 20x4 character-based LCD. +// +//#define ULTRA_LCD + +//============================================================================= +//======================== LCD / Controller Selection ========================= +//===================== (I2C and Shift-Register LCDs) ===================== +//============================================================================= + +// +// CONTROLLER TYPE: I2C +// +// Note: These controllers require the installation of Arduino's LiquidCrystal_I2C +// library. For more info: https://github.com/kiyoshigawa/LiquidCrystal_I2C +// + +// +// Elefu RA Board Control Panel +// https://web.archive.org/web/20140823033947/www.elefu.com/index.php?route=product/product&product_id=53 +// +//#define RA_CONTROL_PANEL + +// +// Sainsmart (YwRobot) LCD Displays +// +// These require LiquidCrystal_I2C library: +// https://github.com/MarlinFirmware/New-LiquidCrystal +// https://github.com/fmalpartida/New-LiquidCrystal/wiki +// +//#define LCD_SAINSMART_I2C_1602 +//#define LCD_SAINSMART_I2C_2004 + +// +// Generic LCM1602 LCD adapter +// +//#define LCM1602 + +// +// PANELOLU2 LCD with status LEDs, +// separate encoder and click inputs. +// +// Note: This controller requires Arduino's LiquidTWI2 library v1.2.3 or later. +// For more info: https://github.com/lincomatic/LiquidTWI2 +// +// Note: The PANELOLU2 encoder click input can either be directly connected to +// a pin (if BTN_ENC defined to != -1) or read through I2C (when BTN_ENC == -1). +// +//#define LCD_I2C_PANELOLU2 + +// +// Panucatt VIKI LCD with status LEDs, +// integrated click & L/R/U/D buttons, separate encoder inputs. +// +//#define LCD_I2C_VIKI + +// +// CONTROLLER TYPE: Shift register panels +// + +// +// 2-wire Non-latching LCD SR from https://github.com/fmalpartida/New-LiquidCrystal/wiki/schematics#user-content-ShiftRegister_connection +// LCD configuration: https://reprap.org/wiki/SAV_3D_LCD +// +//#define SAV_3DLCD + +// +// 3-wire SR LCD with strobe using 74HC4094 +// https://github.com/mikeshub/SailfishLCD +// Uses the code directly from Sailfish +// +//#define FF_INTERFACEBOARD + +// +// TFT GLCD Panel with Marlin UI +// Panel connected to main board by SPI or I2C interface. +// See https://github.com/Serhiy-K/TFTGLCDAdapter +// +//#define TFTGLCD_PANEL_SPI +//#define TFTGLCD_PANEL_I2C + +//============================================================================= +//======================= LCD / Controller Selection ======================= +//========================= (Graphical LCDs) ======================== +//============================================================================= + +// +// CONTROLLER TYPE: Graphical 128x64 (DOGM) +// +// IMPORTANT: The U8glib library is required for Graphical Display! +// https://github.com/olikraus/U8glib_Arduino +// +// NOTE: If the LCD is unresponsive you may need to reverse the plugs. +// + +// +// RepRapDiscount FULL GRAPHIC Smart Controller +// https://reprap.org/wiki/RepRapDiscount_Full_Graphic_Smart_Controller +// +//#define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER + +// +// K.3D Full Graphic Smart Controller +// +//#define K3D_FULL_GRAPHIC_SMART_CONTROLLER + +// +// ReprapWorld Graphical LCD +// https://reprapworld.com/electronics/3d-printer-modules/autonomous-printing/graphical-lcd-screen-v1-0/ +// +//#define REPRAPWORLD_GRAPHICAL_LCD + +// +// Activate one of these if you have a Panucatt Devices +// Viki 2.0 or mini Viki with Graphic LCD +// https://www.panucatt.com +// +//#define VIKI2 +//#define miniVIKI + +// +// Alfawise Ex8 printer LCD marked as WYH L12864 COG +// +//#define WYH_L12864 + +// +// MakerLab Mini Panel with graphic +// controller and SD support - https://reprap.org/wiki/Mini_panel +// +//#define MINIPANEL + +// +// MaKr3d Makr-Panel with graphic controller and SD support. +// https://reprap.org/wiki/MaKrPanel +// +//#define MAKRPANEL + +// +// Adafruit ST7565 Full Graphic Controller. +// https://github.com/eboston/Adafruit-ST7565-Full-Graphic-Controller/ +// +//#define ELB_FULL_GRAPHIC_CONTROLLER + +// +// BQ LCD Smart Controller shipped by +// default with the BQ Hephestos 2 and Witbox 2. +// +//#define BQ_LCD_SMART_CONTROLLER + +// +// Cartesio UI +// https://web.archive.org/web/20180605050442/mauk.cc/webshop/cartesio-shop/electronics/user-interface +// +//#define CARTESIO_UI + +// +// LCD for Melzi Card with Graphical LCD +// +//#define LCD_FOR_MELZI + +// +// Original Ulticontroller from Ultimaker 2 printer with SSD1309 I2C display and encoder +// https://github.com/Ultimaker/Ultimaker2/tree/master/1249_Ulticontroller_Board_(x1) +// +//#define ULTI_CONTROLLER + +// +// MKS MINI12864 with graphic controller and SD support +// https://reprap.org/wiki/MKS_MINI_12864 +// +//#define MKS_MINI_12864 + +// +// MKS MINI12864 V3 is an alias for FYSETC_MINI_12864_2_1. Type A/B. NeoPixel RGB Backlight. +// +//#define MKS_MINI_12864_V3 + +// +// MKS LCD12864A/B with graphic controller and SD support. Follows MKS_MINI_12864 pinout. +// https://www.aliexpress.com/item/33018110072.html +// +//#define MKS_LCD12864A +//#define MKS_LCD12864B + +// +// FYSETC variant of the MINI12864 graphic controller with SD support +// https://wiki.fysetc.com/docs/Mini12864Panel +// +//#define FYSETC_MINI_12864_X_X // Type C/D/E/F. No tunable RGB Backlight by default +//#define FYSETC_MINI_12864_1_2 // Type C/D/E/F. Simple RGB Backlight (always on) +//#define FYSETC_MINI_12864_2_0 // Type A/B. Discreet RGB Backlight +//#define FYSETC_MINI_12864_2_1 // Type A/B. NeoPixel RGB Backlight +//#define FYSETC_GENERIC_12864_1_1 // Larger display with basic ON/OFF backlight. + +// +// BigTreeTech Mini 12864 V1.0 / V2.0 is an alias for FYSETC_MINI_12864_2_1. Type A/B. NeoPixel RGB Backlight. +// https://github.com/bigtreetech/MINI-12864 +// +//#define BTT_MINI_12864 + +// +// BEEZ MINI 12864 is an alias for FYSETC_MINI_12864_2_1. Type A/B. NeoPixel RGB Backlight. +// +//#define BEEZ_MINI_12864 + +// +// Factory display for Creality CR-10 / CR-7 / Ender-3 +// https://marlinfw.org/docs/hardware/controllers.html#cr10_stockdisplay +// +// Connect to EXP1 on RAMPS and compatible boards. +// +//#define CR10_STOCKDISPLAY + +// +// Ender-2 OEM display, a variant of the MKS_MINI_12864 +// +//#define ENDER2_STOCKDISPLAY + +// +// ANET and Tronxy 128×64 Full Graphics Controller as used on Anet A6 +// +//#define ANET_FULL_GRAPHICS_LCD + +// +// GUCOCO CTC 128×64 Full Graphics Controller as used on GUCOCO CTC A10S +// +//#define CTC_A10S_A13 + +// +// AZSMZ 12864 LCD with SD +// https://www.aliexpress.com/item/32837222770.html +// +//#define AZSMZ_12864 + +// +// Silvergate GLCD controller +// https://github.com/android444/Silvergate +// +//#define SILVER_GATE_GLCD_CONTROLLER + +// +// eMotion Tech LCD with SD +// https://www.reprap-france.com/produit/1234568748-ecran-graphique-128-x-64-points-2-1 +// +//#define EMOTION_TECH_LCD + +//============================================================================= +//============================== OLED Displays ============================== +//============================================================================= + +// +// SSD1306 OLED full graphics generic display +// +//#define U8GLIB_SSD1306 + +// +// SAV OLEd LCD module support using either SSD1306 or SH1106 based LCD modules +// +//#define SAV_3DGLCD +#if ENABLED(SAV_3DGLCD) + #define U8GLIB_SSD1306 + //#define U8GLIB_SH1106 +#endif + +// +// TinyBoy2 128x64 OLED / Encoder Panel +// +//#define OLED_PANEL_TINYBOY2 + +// +// MKS OLED 1.3" 128×64 Full Graphics Controller +// https://reprap.org/wiki/MKS_12864OLED +// +// Tiny, but very sharp OLED display +// +//#define MKS_12864OLED // Uses the SH1106 controller +//#define MKS_12864OLED_SSD1306 // Uses the SSD1306 controller + +// +// Zonestar OLED 128×64 Full Graphics Controller +// +//#define ZONESTAR_12864LCD // Graphical (DOGM) with ST7920 controller +//#define ZONESTAR_12864OLED // 1.3" OLED with SH1106 controller +//#define ZONESTAR_12864OLED_SSD1306 // 0.96" OLED with SSD1306 controller + +// +// Einstart S OLED SSD1306 +// +//#define U8GLIB_SH1106_EINSTART + +// +// Overlord OLED display/controller with i2c buzzer and LEDs +// +//#define OVERLORD_OLED + +// +// FYSETC OLED 2.42" 128×64 Full Graphics Controller with WS2812 RGB +// Where to find : https://www.aliexpress.com/item/4000345255731.html +//#define FYSETC_242_OLED_12864 // Uses the SSD1309 controller + +// +// K.3D SSD1309 OLED 2.42" 128×64 Full Graphics Controller +// +//#define K3D_242_OLED_CONTROLLER // Software SPI + +//============================================================================= +//========================== Extensible UI Displays =========================== +//============================================================================= + +/** + * DGUS Touch Display with DWIN OS. (Choose one.) + * + * ORIGIN (Marlin DWIN_SET) + * - Download https://github.com/coldtobi/Marlin_DGUS_Resources + * - Copy the downloaded DWIN_SET folder to the SD card. + * - Product: https://www.aliexpress.com/item/32993409517.html + * + * FYSETC (Supplier default) + * - Download https://github.com/FYSETC/FYSTLCD-2.0 + * - Copy the downloaded SCREEN folder to the SD card. + * - Product: https://www.aliexpress.com/item/32961471929.html + * + * HIPRECY (Supplier default) + * - Download https://github.com/HiPrecy/Touch-Lcd-LEO + * - Copy the downloaded DWIN_SET folder to the SD card. + * + * MKS (MKS-H43) (Supplier default) + * - Download https://github.com/makerbase-mks/MKS-H43 + * - Copy the downloaded DWIN_SET folder to the SD card. + * - Product: https://www.aliexpress.com/item/1005002008179262.html + * + * RELOADED (T5UID1) + * - Download https://github.com/Neo2003/DGUS-reloaded/releases + * - Copy the downloaded DWIN_SET folder to the SD card. + * + * IA_CREALITY (T5UID1) + * - Download https://github.com/InsanityAutomation/Marlin/raw/CrealityDwin_2.0/TM3D_Combined480272_Landscape_V7.7z + * - Copy the downloaded DWIN_SET folder to the SD card. + * + * E3S1PRO (T5L) + * - Download https://github.com/CrealityOfficial/Ender-3S1/archive/3S1_Plus_Screen.zip + * - Copy the downloaded DWIN_SET folder to the SD card. + * + * CREALITY_TOUCH + * - CR-6 OEM touch screen. A DWIN display with touch. + * + * Flash display with DGUS Displays for Marlin: + * - Format the SD card to FAT32 with an allocation size of 4kb. + * - Download files as specified for your type of display. + * - Plug the microSD card into the back of the display. + * - Boot the display and wait for the update to complete. + * + * :[ 'ORIGIN', 'FYSETC', 'HYPRECY', 'MKS', 'RELOADED', 'IA_CREALITY', 'E3S1PRO', 'CREALITY_TOUCH' ] + */ +//#define DGUS_LCD_UI ORIGIN +#if DGUS_UI_IS(MKS) + #define USE_MKS_GREEN_UI +#elif DGUS_UI_IS(IA_CREALITY) + //#define LCD_SCREEN_ROTATE 90 // Portrait Mode or 800x480 displays + //#define IA_CREALITY_BOOT_DELAY 1500 // (ms) +#endif + +// +// LCD for Malyan M200/M300 printers +// +//#define MALYAN_LCD + +// +// Touch UI for FTDI EVE (FT800/FT810) displays +// See Configuration_adv.h for all configuration options. +// +//#define TOUCH_UI_FTDI_EVE + +// +// Touch-screen LCD for Anycubic Chiron +// +//#define ANYCUBIC_LCD_CHIRON + +// +// Touch-screen LCD for Anycubic i3 Mega +// +//#define ANYCUBIC_LCD_I3MEGA +#if ENABLED(ANYCUBIC_LCD_I3MEGA) + //#define ANYCUBIC_LCD_GCODE_EXT // Add ".gcode" to menu entries for DGUS clone compatibility +#endif + +// +// Touch-screen LCD for Anycubic Vyper +// +//#define ANYCUBIC_LCD_VYPER + +// +// Sovol SV-06 Resistive Touch Screen +// +//#define SOVOL_SV06_RTS + +// +// 320x240 Nextion 2.8" serial TFT Resistive Touch Screen NX3224T028 +// +//#define NEXTION_TFT + +// +// PanelDue touch controller by Escher3D +// http://escher3d.com/pages/order/products/product2.php +// +//#define PANELDUE + +// +// Third-party or vendor-customized controller interfaces. +// Sources should be installed in 'src/lcd/extui'. +// +//#define EXTENSIBLE_UI + +#if ENABLED(EXTENSIBLE_UI) + //#define EXTUI_LOCAL_BEEPER // Enables use of local Beeper pin with external display +#endif + +//============================================================================= +//=============================== Graphical TFTs ============================== +//============================================================================= + +/** + * Specific TFT Model Presets. Enable one of the following options + * or enable TFT_GENERIC and set sub-options. + */ + +// +// 480x320, 3.5", SPI Display with Rotary Encoder from MKS +// Usually paired with MKS Robin Nano V2 & V3 +// https://github.com/makerbase-mks/MKS-TFT-Hardware/tree/master/MKS%20TS35 +// +//#define MKS_TS35_V2_0 + +// +// 320x240, 2.4", FSMC Display From MKS +// Usually paired with MKS Robin Nano V1.2 +// +//#define MKS_ROBIN_TFT24 + +// +// 320x240, 2.8", FSMC Display From MKS +// Usually paired with MKS Robin Nano V1.2 +// +//#define MKS_ROBIN_TFT28 + +// +// 320x240, 3.2", FSMC Display From MKS +// Usually paired with MKS Robin Nano V1.2 +// +//#define MKS_ROBIN_TFT32 + +// +// 480x320, 3.5", FSMC Display From MKS +// Usually paired with MKS Robin Nano V1.2 +// +//#define MKS_ROBIN_TFT35 + +// +// 480x272, 4.3", FSMC Display From MKS +// +//#define MKS_ROBIN_TFT43 + +// +// 320x240, 3.2", FSMC Display From MKS +// Usually paired with MKS Robin +// +//#define MKS_ROBIN_TFT_V1_1R + +// +// 480x320, 3.5", FSMC Stock Display from Tronxy +// +//#define TFT_TRONXY_X5SA + +// +// 480x320, 3.5", FSMC Stock Display from AnyCubic +// +//#define ANYCUBIC_TFT35 + +// +// 320x240, 2.8", FSMC Stock Display from Longer/Alfawise +// +//#define LONGER_LK_TFT28 + +// +// 320x240, 2.8", FSMC Stock Display from ET4 +// +//#define ANET_ET4_TFT28 + +// +// 480x320, 3.5", FSMC Stock Display from ET5 +// +//#define ANET_ET5_TFT35 + +// +// 1024x600, 7", RGB Stock Display with Rotary Encoder from BIQU BX +// https://github.com/bigtreetech/BIQU-BX/tree/master/Hardware +// +//#define BIQU_BX_TFT70 + +// +// 480x320, 3.5", SPI Stock Display with Rotary Encoder from BIQU B1 SE Series +// https://github.com/bigtreetech/TFT35-SPI/tree/master/v1 +// +//#define BTT_TFT35_SPI_V1_0 + +// +// Generic TFT with detailed options +// +//#define TFT_GENERIC +#if ENABLED(TFT_GENERIC) + // :[ 'AUTO', 'ST7735', 'ST7789', 'ST7796', 'R61505', 'ILI9328', 'ILI9341', 'ILI9488' ] + #define TFT_DRIVER AUTO + + // Interface. Enable one of the following options: + //#define TFT_INTERFACE_FSMC + //#define TFT_INTERFACE_SPI + + // TFT Resolution. Enable one of the following options: + //#define TFT_RES_320x240 + //#define TFT_RES_480x272 + //#define TFT_RES_480x320 + //#define TFT_RES_1024x600 +#endif + +/** + * TFT UI - User Interface Selection. Enable one of the following options: + * + * TFT_CLASSIC_UI - Emulated DOGM - 128x64 Upscaled + * TFT_COLOR_UI - Marlin Default Menus, Touch Friendly, using full TFT capabilities + * TFT_LVGL_UI - A Modern UI using LVGL + * + * For LVGL_UI also copy the 'assets' folder from the build directory to the + * root of your SD card, together with the compiled firmware. + */ +//#define TFT_CLASSIC_UI +//#define TFT_COLOR_UI +//#define TFT_LVGL_UI + +#if ENABLED(TFT_COLOR_UI) + /** + * TFT Font for Color UI. Choose one of the following: + * + * NOTOSANS - Default font with anti-aliasing. Supports Latin Extended and non-Latin characters. + * UNIFONT - Lightweight font, no anti-aliasing. Supports Latin Extended and non-Latin characters. + * HELVETICA - Lightweight font, no anti-aliasing. Supports Basic Latin (0x0020-0x007F) and Latin-1 Supplement (0x0080-0x00FF) characters only. + * :['NOTOSANS', 'UNIFONT', 'HELVETICA'] + */ + #define TFT_FONT NOTOSANS + + /** + * TFT Theme for Color UI. Choose one of the following or add a new one to 'Marlin/src/lcd/tft/themes' directory + * + * BLUE_MARLIN - Default theme with 'midnight blue' background + * BLACK_MARLIN - Theme with 'black' background + * ANET_BLACK - Theme used for Anet ET4/5 + * :['BLUE_MARLIN', 'BLACK_MARLIN', 'ANET_BLACK'] + */ + #define TFT_THEME BLACK_MARLIN + + //#define TFT_SHARED_IO // I/O is shared between TFT display and other devices. Disable async data transfer. + + #define COMPACT_MARLIN_BOOT_LOGO // Use compressed data to save Flash space +#endif + +#if ENABLED(TFT_LVGL_UI) + //#define MKS_WIFI_MODULE // MKS WiFi module +#endif + +/** + * TFT Rotation. Set to one of the following values: + * + * TFT_ROTATE_90, TFT_ROTATE_90_MIRROR_X, TFT_ROTATE_90_MIRROR_Y, + * TFT_ROTATE_180, TFT_ROTATE_180_MIRROR_X, TFT_ROTATE_180_MIRROR_Y, + * TFT_ROTATE_270, TFT_ROTATE_270_MIRROR_X, TFT_ROTATE_270_MIRROR_Y, + * TFT_MIRROR_X, TFT_MIRROR_Y, TFT_NO_ROTATION + * + * :{ 'TFT_NO_ROTATION':'None', 'TFT_ROTATE_90':'90°', 'TFT_ROTATE_90_MIRROR_X':'90° (Mirror X)', 'TFT_ROTATE_90_MIRROR_Y':'90° (Mirror Y)', 'TFT_ROTATE_180':'180°', 'TFT_ROTATE_180_MIRROR_X':'180° (Mirror X)', 'TFT_ROTATE_180_MIRROR_Y':'180° (Mirror Y)', 'TFT_ROTATE_270':'270°', 'TFT_ROTATE_270_MIRROR_X':'270° (Mirror X)', 'TFT_ROTATE_270_MIRROR_Y':'270° (Mirror Y)', 'TFT_MIRROR_X':'Mirror X', 'TFT_MIRROR_Y':'Mirror Y' } + */ +//#define TFT_ROTATION TFT_NO_ROTATION + +//============================================================================= +//============================ Other Controllers ============================ +//============================================================================= + +// +// Ender-3 v2 OEM display. A DWIN display with Rotary Encoder. +// +//#define DWIN_CREALITY_LCD // Creality UI +//#define DWIN_LCD_PROUI // Pro UI by MRiscoC +//#define DWIN_CREALITY_LCD_JYERSUI // Jyers UI by Jacob Myers +//#define DWIN_MARLINUI_PORTRAIT // MarlinUI (portrait orientation) +//#define DWIN_MARLINUI_LANDSCAPE // MarlinUI (landscape orientation) + +#if ENABLED(DWIN_CREALITY_LCD) + //#define USE_STRING_HEADINGS // Use string headings for Creality UI instead of images + //#define USE_STRING_TITLES // Use string titles for Creality UI instead of images +#endif + +// +// Touch Screen Settings +// +//#define TOUCH_SCREEN +#if ENABLED(TOUCH_SCREEN) + #define BUTTON_DELAY_EDIT 50 // (ms) Button repeat delay for edit screens + #define BUTTON_DELAY_MENU 250 // (ms) Button repeat delay for menus + + #if ANY(TFT_CLASSIC_UI, TFT_COLOR_UI) + //#define NO_BACK_MENU_ITEM // Don't display a top menu item to go back to the parent menu + #endif + + #define TOUCH_SCREEN_CALIBRATION + + //#define TOUCH_CALIBRATION_X 12316 + //#define TOUCH_CALIBRATION_Y -8981 + //#define TOUCH_OFFSET_X -43 + //#define TOUCH_OFFSET_Y 257 + //#define TOUCH_ORIENTATION TOUCH_LANDSCAPE + + #if ALL(TOUCH_SCREEN_CALIBRATION, EEPROM_SETTINGS) + #define TOUCH_CALIBRATION_AUTO_SAVE // Auto save successful calibration values to EEPROM + #endif + + #if ENABLED(TFT_COLOR_UI) + //#define SINGLE_TOUCH_NAVIGATION + #endif +#endif + +// +// RepRapWorld REPRAPWORLD_KEYPAD v1.1 +// https://reprapworld.com/products/electronics/ramps/keypad_v1_0_fully_assembled/ +// +//#define REPRAPWORLD_KEYPAD +#if ENABLED(REPRAPWORLD_KEYPAD) + //#define REPRAPWORLD_KEYPAD_MOVE_STEP 10.0 // (mm) Distance to move per key-press +#endif + +// +// EasyThreeD ET-4000+ with button input and status LED +// +//#define EASYTHREED_UI + +//============================================================================= +//=============================== Extra Features ============================== +//============================================================================= + +// @section fans + +// Set number of user-controlled fans. Disable to use all board-defined fans. +// :[1,2,3,4,5,6,7,8] +//#define NUM_M106_FANS 1 + +/** + * Use software PWM to drive the fan, as for the heaters. This uses a very low frequency + * which is not as annoying as with the hardware PWM. On the other hand, if this frequency + * is too low, you should also increment SOFT_PWM_SCALE. + */ +//#define FAN_SOFT_PWM + +/** + * Incrementing this by 1 will double the software PWM frequency, affecting heaters, and + * the fan if FAN_SOFT_PWM is enabled. However, control resolution will be halved for each + * increment; at zero value, there are 128 effective control positions. + * :[0,1,2,3,4,5,6,7] + */ +#define SOFT_PWM_SCALE 0 + +/** + * If SOFT_PWM_SCALE is set to a value higher than 0, dithering can be used to mitigate the + * associated resolution loss. If enabled, some of the PWM cycles are stretched so on average + * the desired duty cycle is attained. + */ +//#define SOFT_PWM_DITHER + +// @section extras + +// Support for the BariCUDA Paste Extruder +//#define BARICUDA + +// @section lights + +/** + * Temperature status LEDs that display the hotend and bed temperature. + * If all hotends, bed temperature, and target temperature are under 54C + * the BLUE led is on. Otherwise the RED led is on. (1C hysteresis) + */ +//#define TEMP_STAT_LEDS + +// Support for BlinkM/CyzRgb +//#define BLINKM + +// Support for PCA9632 PWM LED driver +//#define PCA9632 + +// Support for PCA9533 PWM LED driver +//#define PCA9533 + +/** + * RGB LED / LED Strip Control + * + * Enable support for an RGB LED connected to 5V digital pins, or + * an RGB Strip connected to MOSFETs controlled by digital pins. + * + * Adds the M150 command to set the LED (or LED strip) color. + * If pins are PWM capable (e.g., 4, 5, 6, 11) then a range of + * luminance values can be set from 0 to 255. + * For NeoPixel LED an overall brightness parameter is also available. + * + * === CAUTION === + * LED Strips require a MOSFET Chip between PWM lines and LEDs, + * as the Arduino cannot handle the current the LEDs will require. + * Failure to follow this precaution can destroy your Arduino! + * + * NOTE: A separate 5V power supply is required! The NeoPixel LED needs + * more current than the Arduino 5V linear regulator can produce. + * + * Requires PWM frequency between 50 <> 100Hz (Check HAL or variant) + * Use FAST_PWM_FAN, if possible, to reduce fan noise. + */ + +// LED Type. Enable only one of the following two options: +//#define RGB_LED +//#define RGBW_LED + +#if ANY(RGB_LED, RGBW_LED) + //#define RGB_LED_R_PIN 34 + //#define RGB_LED_G_PIN 43 + //#define RGB_LED_B_PIN 35 + //#define RGB_LED_W_PIN -1 +#endif + +#if ANY(RGB_LED, RGBW_LED, PCA9632) + //#define RGB_STARTUP_TEST // For PWM pins, fade between all colors + #if ENABLED(RGB_STARTUP_TEST) + #define RGB_STARTUP_TEST_INNER_MS 10 // (ms) Reduce or increase fading speed + #endif +#endif + +// Support for Adafruit NeoPixel LED driver +//#define NEOPIXEL_LED +#if ENABLED(NEOPIXEL_LED) + #define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW, NEO_RGBW, NEO_GRB, NEO_RBG, etc. + // See https://github.com/adafruit/Adafruit_NeoPixel/blob/master/Adafruit_NeoPixel.h + //#define NEOPIXEL_PIN 4 // LED driving pin + //#define NEOPIXEL2_TYPE NEOPIXEL_TYPE + //#define NEOPIXEL2_PIN 5 + #define NEOPIXEL_PIXELS 30 // Number of LEDs in the strip. (Longest strip when NEOPIXEL2_SEPARATE is disabled.) + #define NEOPIXEL_IS_SEQUENTIAL // Sequential display for temperature change - LED by LED. Disable to change all LEDs at once. + #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness (0-255) + //#define NEOPIXEL_STARTUP_TEST // Cycle through colors at startup + + // Support for second Adafruit NeoPixel LED driver controlled with M150 S1 ... + //#define NEOPIXEL2_SEPARATE + #if ENABLED(NEOPIXEL2_SEPARATE) + #define NEOPIXEL2_PIXELS 15 // Number of LEDs in the second strip + #define NEOPIXEL2_BRIGHTNESS 127 // Initial brightness (0-255) + #define NEOPIXEL2_STARTUP_TEST // Cycle through colors at startup + #define NEOPIXEL_M150_DEFAULT -1 // Default strip for M150 without 'S'. Use -1 to set all by default. + #else + //#define NEOPIXEL2_INSERIES // Default behavior is NeoPixel 2 in parallel + #endif + + // Use some of the NeoPixel LEDs for static (background) lighting + //#define NEOPIXEL_BKGD_INDEX_FIRST 0 // Index of the first background LED + //#define NEOPIXEL_BKGD_INDEX_LAST 5 // Index of the last background LED + //#define NEOPIXEL_BKGD_COLOR { 255, 255, 255, 0 } // R, G, B, W + //#define NEOPIXEL_BKGD_TIMEOUT_COLOR { 25, 25, 25, 0 } // R, G, B, W + //#define NEOPIXEL_BKGD_ALWAYS_ON // Keep the backlight on when other NeoPixels are off +#endif + +/** + * Printer Event LEDs + * + * During printing, the LEDs will reflect the printer status: + * + * - Gradually change from blue to violet as the heated bed gets to target temp + * - Gradually change from violet to red as the hotend gets to temperature + * - Change to white to illuminate work surface + * - Change to green once print has finished + * - Turn off after the print has finished and the user has pushed a button + */ +#if ANY(BLINKM, RGB_LED, RGBW_LED, PCA9632, PCA9533, NEOPIXEL_LED) + #define PRINTER_EVENT_LEDS +#endif + +// @section servos + +/** + * Number of servos + * + * For some servo-related options NUM_SERVOS will be set automatically. + * Set this manually if there are extra servos needing manual control. + * Set to 0 to turn off servo support. + */ +//#define NUM_SERVOS 3 // Note: Servo index starts with 0 for M280-M282 commands + +// (ms) Delay before the next move will start, to give the servo time to reach its target angle. +// 300ms is a good value but you can try less delay. +// If the servo can't reach the requested position, increase it. +#define SERVO_DELAY { 300 } + +// Only power servos during movement, otherwise leave off to prevent jitter +//#define DEACTIVATE_SERVOS_AFTER_MOVE + +// Edit servo angles with M281 and save to EEPROM with M500 +//#define EDITABLE_SERVO_ANGLES + +// Disable servo with M282 to reduce power consumption, noise, and heat when not in use +//#define SERVO_DETACH_GCODE diff --git a/config/examples/delta/Micromake-D1/RAMPS-1.4/Configuration_adv.h b/config/examples/delta/Micromake-D1/RAMPS-1.4/Configuration_adv.h new file mode 100644 index 0000000000..5530e5abb5 --- /dev/null +++ b/config/examples/delta/Micromake-D1/RAMPS-1.4/Configuration_adv.h @@ -0,0 +1,4751 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2025 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/** + * Configuration_adv.h + * + * Advanced settings. + * Only change these if you know exactly what you're doing. + * Some of these settings can damage your printer if improperly set! + * + * Basic settings can be found in Configuration.h + */ +#define CONFIGURATION_ADV_H_VERSION 02010300 + +// @section develop + +/** + * Configuration Export + * + * Export the configuration as part of the build. (See signature.py) + * Output files are saved with the build (e.g., .pio/build/mega2560). + * + * See `build_all_examples --ini` as an example of config.ini archiving. + * + * 1 = marlin_config.json - Dictionary containing the configuration. + * This file is also generated for CONFIGURATION_EMBEDDING. + * 2 = config.ini - File format for PlatformIO preprocessing. + * 3 = schema.json - The entire configuration schema. (13 = pattern groups) + * 4 = schema.yml - The entire configuration schema. + * 5 = Config.h - Minimal configuration by popular demand. + */ +//#define CONFIG_EXPORT 105 // :[1:'JSON', 2:'config.ini', 3:'schema.json', 4:'schema.yml', 5:'Config.h'] + +//=========================================================================== +//============================= Thermal Settings ============================ +//=========================================================================== +// @section temperature + +/** + * Thermocouple sensors are quite sensitive to noise. Any noise induced in + * the sensor wires, such as by stepper motor wires run in parallel to them, + * may result in the thermocouple sensor reporting spurious errors. This + * value is the number of errors which can occur in a row before the error + * is reported. This allows us to ignore intermittent error conditions while + * still detecting an actual failure, which should result in a continuous + * stream of errors from the sensor. + * + * Set this value to 0 to fail on the first error to occur. + */ +#define THERMOCOUPLE_MAX_ERRORS 15 + +// +// Custom Thermistor 1000 parameters +// +#if TEMP_SENSOR_0 == 1000 + #define HOTEND0_PULLUP_RESISTOR_OHMS 4700 // Pullup resistor + #define HOTEND0_RESISTANCE_25C_OHMS 100000 // Resistance at 25C + #define HOTEND0_BETA 3950 // Beta value + #define HOTEND0_SH_C_COEFF 0 // Steinhart-Hart C coefficient +#endif + +#if TEMP_SENSOR_1 == 1000 + #define HOTEND1_PULLUP_RESISTOR_OHMS 4700 // Pullup resistor + #define HOTEND1_RESISTANCE_25C_OHMS 100000 // Resistance at 25C + #define HOTEND1_BETA 3950 // Beta value + #define HOTEND1_SH_C_COEFF 0 // Steinhart-Hart C coefficient +#endif + +#if TEMP_SENSOR_2 == 1000 + #define HOTEND2_PULLUP_RESISTOR_OHMS 4700 // Pullup resistor + #define HOTEND2_RESISTANCE_25C_OHMS 100000 // Resistance at 25C + #define HOTEND2_BETA 3950 // Beta value + #define HOTEND2_SH_C_COEFF 0 // Steinhart-Hart C coefficient +#endif + +#if TEMP_SENSOR_3 == 1000 + #define HOTEND3_PULLUP_RESISTOR_OHMS 4700 // Pullup resistor + #define HOTEND3_RESISTANCE_25C_OHMS 100000 // Resistance at 25C + #define HOTEND3_BETA 3950 // Beta value + #define HOTEND3_SH_C_COEFF 0 // Steinhart-Hart C coefficient +#endif + +#if TEMP_SENSOR_4 == 1000 + #define HOTEND4_PULLUP_RESISTOR_OHMS 4700 // Pullup resistor + #define HOTEND4_RESISTANCE_25C_OHMS 100000 // Resistance at 25C + #define HOTEND4_BETA 3950 // Beta value + #define HOTEND4_SH_C_COEFF 0 // Steinhart-Hart C coefficient +#endif + +#if TEMP_SENSOR_5 == 1000 + #define HOTEND5_PULLUP_RESISTOR_OHMS 4700 // Pullup resistor + #define HOTEND5_RESISTANCE_25C_OHMS 100000 // Resistance at 25C + #define HOTEND5_BETA 3950 // Beta value + #define HOTEND5_SH_C_COEFF 0 // Steinhart-Hart C coefficient +#endif + +#if TEMP_SENSOR_6 == 1000 + #define HOTEND6_PULLUP_RESISTOR_OHMS 4700 // Pullup resistor + #define HOTEND6_RESISTANCE_25C_OHMS 100000 // Resistance at 25C + #define HOTEND6_BETA 3950 // Beta value + #define HOTEND6_SH_C_COEFF 0 // Steinhart-Hart C coefficient +#endif + +#if TEMP_SENSOR_7 == 1000 + #define HOTEND7_PULLUP_RESISTOR_OHMS 4700 // Pullup resistor + #define HOTEND7_RESISTANCE_25C_OHMS 100000 // Resistance at 25C + #define HOTEND7_BETA 3950 // Beta value + #define HOTEND7_SH_C_COEFF 0 // Steinhart-Hart C coefficient +#endif + +#if TEMP_SENSOR_BED == 1000 + #define BED_PULLUP_RESISTOR_OHMS 4700 // Pullup resistor + #define BED_RESISTANCE_25C_OHMS 100000 // Resistance at 25C + #define BED_BETA 3950 // Beta value + #define BED_SH_C_COEFF 0 // Steinhart-Hart C coefficient +#endif + +#if TEMP_SENSOR_CHAMBER == 1000 + #define CHAMBER_PULLUP_RESISTOR_OHMS 4700 // Pullup resistor + #define CHAMBER_RESISTANCE_25C_OHMS 100000 // Resistance at 25C + #define CHAMBER_BETA 3950 // Beta value + #define CHAMBER_SH_C_COEFF 0 // Steinhart-Hart C coefficient +#endif + +#if TEMP_SENSOR_COOLER == 1000 + #define COOLER_PULLUP_RESISTOR_OHMS 4700 // Pullup resistor + #define COOLER_RESISTANCE_25C_OHMS 100000 // Resistance at 25C + #define COOLER_BETA 3950 // Beta value + #define COOLER_SH_C_COEFF 0 // Steinhart-Hart C coefficient +#endif + +#if TEMP_SENSOR_PROBE == 1000 + #define PROBE_PULLUP_RESISTOR_OHMS 4700 // Pullup resistor + #define PROBE_RESISTANCE_25C_OHMS 100000 // Resistance at 25C + #define PROBE_BETA 3950 // Beta value + #define PROBE_SH_C_COEFF 0 // Steinhart-Hart C coefficient +#endif + +#if TEMP_SENSOR_BOARD == 1000 + #define BOARD_PULLUP_RESISTOR_OHMS 4700 // Pullup resistor + #define BOARD_RESISTANCE_25C_OHMS 100000 // Resistance at 25C + #define BOARD_BETA 3950 // Beta value + #define BOARD_SH_C_COEFF 0 // Steinhart-Hart C coefficient +#endif + +#if TEMP_SENSOR_REDUNDANT == 1000 + #define REDUNDANT_PULLUP_RESISTOR_OHMS 4700 // Pullup resistor + #define REDUNDANT_RESISTANCE_25C_OHMS 100000 // Resistance at 25C + #define REDUNDANT_BETA 3950 // Beta value + #define REDUNDANT_SH_C_COEFF 0 // Steinhart-Hart C coefficient +#endif + +/** + * Thermocouple Options — for MAX6675 (-2), MAX31855 (-3), and MAX31865 (-5). + */ +//#define TEMP_SENSOR_FORCE_HW_SPI // Ignore SCK/MOSI/MISO pins; use CS and the default SPI bus. +//#define MAX31865_SENSOR_WIRES_0 2 // (2-4) Number of wires for the probe connected to a MAX31865 board. +//#define MAX31865_SENSOR_WIRES_1 2 +//#define MAX31865_SENSOR_WIRES_2 2 +//#define MAX31865_SENSOR_WIRES_BED 2 + +//#define MAX31865_50HZ_FILTER // Use a 50Hz filter instead of the default 60Hz. +//#define MAX31865_USE_READ_ERROR_DETECTION // Treat value spikes (20°C delta in under 1s) as read errors. + +//#define MAX31865_USE_AUTO_MODE // Read faster and more often than 1-shot; bias voltage always on; slight effect on RTD temperature. +//#define MAX31865_MIN_SAMPLING_TIME_MSEC 100 // (ms) 1-shot: minimum read interval. Reduces bias voltage effects by leaving sensor unpowered for longer intervals. +//#define MAX31865_IGNORE_INITIAL_FAULTY_READS 10 // Ignore some read faults (keeping the temperature reading) to work around a possible issue (#23439). + +//#define MAX31865_WIRE_OHMS_0 0.95f // For 2-wire, set the wire resistances for more accurate readings. +//#define MAX31865_WIRE_OHMS_1 0.0f +//#define MAX31865_WIRE_OHMS_2 0.0f +//#define MAX31865_WIRE_OHMS_BED 0.0f + +/** + * Hephestos 2 24V heated bed upgrade kit. + * https://www.en3dstudios.com/product/bq-hephestos-2-heated-bed-kit/ + */ +//#define HEPHESTOS2_HEATED_BED_KIT +#if ENABLED(HEPHESTOS2_HEATED_BED_KIT) + #define HEATER_BED_INVERTING true +#endif + +// +// Heated Bed Bang-Bang options +// +#if DISABLED(PIDTEMPBED) + #define BED_CHECK_INTERVAL 5000 // (ms) Interval between checks in bang-bang control + #if ANY(BED_LIMIT_SWITCHING, PELTIER_BED) + #define BED_HYSTERESIS 2 // (°C) Only set the relevant heater state when ABS(T-target) > BED_HYSTERESIS + #endif +#endif + +// +// Heated Chamber options +// + +#if TEMP_SENSOR_CHAMBER + //#define HEATER_CHAMBER_PIN P2_04 // Required heater on/off pin (example: SKR 1.4 Turbo HE1 plug) + //#define HEATER_CHAMBER_INVERTING false + //#define FAN1_PIN -1 // Remove the fan signal on pin P2_04 (example: SKR 1.4 Turbo HE1 plug) + + #if DISABLED(PIDTEMPCHAMBER) + #define CHAMBER_CHECK_INTERVAL 5000 // (ms) Interval between checks in bang-bang control + #if ENABLED(CHAMBER_LIMIT_SWITCHING) + #define CHAMBER_HYSTERESIS 2 // (°C) Only set the relevant heater state when ABS(T-target) > CHAMBER_HYSTERESIS + #endif + #endif + + //#define CHAMBER_FAN // Enable a fan on the chamber + #if ENABLED(CHAMBER_FAN) + //#define CHAMBER_FAN_INDEX 2 // Index of a fan to repurpose as the chamber fan. (Default: first unused fan) + #define CHAMBER_FAN_MODE 2 // Fan control mode: 0=Static; 1=Linear increase when temp is higher than target; 2=V-shaped curve; 3=similar to 1 but fan is always on. + #if CHAMBER_FAN_MODE == 0 + #define CHAMBER_FAN_BASE 255 // Chamber fan PWM (0-255) + #elif CHAMBER_FAN_MODE == 1 + #define CHAMBER_FAN_BASE 128 // Base chamber fan PWM (0-255); turns on when chamber temperature is above the target + #define CHAMBER_FAN_FACTOR 25 // PWM increase per °C above target + #elif CHAMBER_FAN_MODE == 2 + #define CHAMBER_FAN_BASE 128 // Minimum chamber fan PWM (0-255) + #define CHAMBER_FAN_FACTOR 25 // PWM increase per °C difference from target + #elif CHAMBER_FAN_MODE == 3 + #define CHAMBER_FAN_BASE 128 // Base chamber fan PWM (0-255) + #define CHAMBER_FAN_FACTOR 25 // PWM increase per °C above target + #endif + #endif + + //#define CHAMBER_VENT // Enable a servo-controlled vent on the chamber + #if ENABLED(CHAMBER_VENT) + #define CHAMBER_VENT_SERVO_NR 1 // Index of the vent servo + #define HIGH_EXCESS_HEAT_LIMIT 5 // How much above target temp to consider there is excess heat in the chamber + #define LOW_EXCESS_HEAT_LIMIT 3 + #define MIN_COOLING_SLOPE_TIME_CHAMBER_VENT 20 + #define MIN_COOLING_SLOPE_DEG_CHAMBER_VENT 1.5 + #endif +#endif + +// +// Laser Cooler options +// +#if TEMP_SENSOR_COOLER + #define COOLER_MINTEMP 8 // (°C) + #define COOLER_MAXTEMP 26 // (°C) + #define COOLER_DEFAULT_TEMP 16 // (°C) + #define TEMP_COOLER_HYSTERESIS 1 // (°C) Temperature proximity considered "close enough" to the target + #define COOLER_PIN 8 // Laser cooler on/off pin used to control power to the cooling element (e.g., TEC, External chiller via relay) + #define COOLER_INVERTING false + #define TEMP_COOLER_PIN 15 // Laser/Cooler temperature sensor pin. ADC is required. + #define COOLER_FAN // Enable a fan on the cooler, Fan# 0,1,2,3 etc. + #define COOLER_FAN_INDEX 0 // FAN number 0, 1, 2 etc. e.g. + #if ENABLED(COOLER_FAN) + #define COOLER_FAN_BASE 100 // Base Cooler fan PWM (0-255); turns on when Cooler temperature is above the target + #define COOLER_FAN_FACTOR 25 // PWM increase per °C above target + #endif +#endif + +// +// Motherboard Sensor options +// +#if TEMP_SENSOR_BOARD + #define THERMAL_PROTECTION_BOARD // Halt the printer if the board sensor leaves the temp range below. + #define BOARD_MINTEMP 8 // (°C) + #define BOARD_MAXTEMP 70 // (°C) + //#define TEMP_BOARD_PIN -1 // Board temp sensor pin override. +#endif + +// +// SoC Sensor options +// +#if TEMP_SENSOR_SOC + #define THERMAL_PROTECTION_SOC // Halt the printer if the SoC sensor leaves the temp range below. + #define SOC_MAXTEMP 85 // (°C) +#endif + +/** + * Thermal Protection provides additional protection to your printer from damage + * and fire. Marlin always includes safe min and max temperature ranges which + * protect against a broken or disconnected thermistor wire. + * + * The issue: If a thermistor falls out, it will report the much lower + * temperature of the air in the room, and the the firmware will keep + * the heater on. + * + * The solution: Once the temperature reaches the target, start observing. + * If the temperature stays too far below the target (hysteresis) for too + * long (period), the firmware will halt the machine as a safety precaution. + * + * If you get false positives for "Thermal Runaway", increase + * THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD + */ +#if ALL(HAS_HOTEND, THERMAL_PROTECTION_HOTENDS) + #define THERMAL_PROTECTION_PERIOD 40 // (seconds) + #define THERMAL_PROTECTION_HYSTERESIS 4 // (°C) + + //#define ADAPTIVE_FAN_SLOWING // Slow down the part-cooling fan if the temperature drops + #if ENABLED(ADAPTIVE_FAN_SLOWING) + //#define REPORT_ADAPTIVE_FAN_SLOWING // Report fan slowing activity to the console + #if ANY(MPCTEMP, PIDTEMP) + //#define TEMP_TUNING_MAINTAIN_FAN // Don't slow down the fan speed during M303 or M306 T + #endif + #endif + + /** + * Whenever an M104, M109, or M303 increases the target temperature, the + * firmware will wait for the WATCH_TEMP_PERIOD to expire. If the temperature + * hasn't increased by WATCH_TEMP_INCREASE degrees, the machine is halted and + * requires a hard reset. This test restarts with any M104/M109/M303, but only + * if the current temperature is far enough below the target for a reliable + * test. + * + * If you get false positives for "Heating failed", increase WATCH_TEMP_PERIOD + * and/or decrease WATCH_TEMP_INCREASE. WATCH_TEMP_INCREASE should not be set + * below 2. + */ + #define WATCH_TEMP_PERIOD 40 // (seconds) + #define WATCH_TEMP_INCREASE 2 // (°C) +#endif + +/** + * Thermal Protection parameters for the bed are just as above for hotends. + */ +#if TEMP_SENSOR_BED && ENABLED(THERMAL_PROTECTION_BED) + #define THERMAL_PROTECTION_BED_PERIOD 20 // (seconds) + #define THERMAL_PROTECTION_BED_HYSTERESIS 2 // (°C) + + /** + * As described above, except for the bed (M140/M190/M303). + */ + #define WATCH_BED_TEMP_PERIOD 60 // (seconds) + #define WATCH_BED_TEMP_INCREASE 2 // (°C) +#endif + +/** + * Thermal Protection parameters for the heated chamber. + */ +#if TEMP_SENSOR_CHAMBER && ENABLED(THERMAL_PROTECTION_CHAMBER) + #define THERMAL_PROTECTION_CHAMBER_PERIOD 20 // (seconds) + #define THERMAL_PROTECTION_CHAMBER_HYSTERESIS 2 // (°C) + + /** + * Heated chamber watch settings (M141/M191). + */ + #define WATCH_CHAMBER_TEMP_PERIOD 60 // (seconds) + #define WATCH_CHAMBER_TEMP_INCREASE 2 // (°C) +#endif + +/** + * Thermal Protection parameters for the laser cooler. + */ +#if TEMP_SENSOR_COOLER && ENABLED(THERMAL_PROTECTION_COOLER) + #define THERMAL_PROTECTION_COOLER_PERIOD 10 // (seconds) + #define THERMAL_PROTECTION_COOLER_HYSTERESIS 3 // (°C) + + /** + * Laser cooling watch settings (M143/M193). + */ + #define WATCH_COOLER_TEMP_PERIOD 60 // (seconds) + #define WATCH_COOLER_TEMP_INCREASE 3 // (°C) +#endif + +#if ANY(THERMAL_PROTECTION_HOTENDS, THERMAL_PROTECTION_BED, THERMAL_PROTECTION_CHAMBER, THERMAL_PROTECTION_COOLER) + /** + * Thermal Protection Variance Monitor - EXPERIMENTAL + * Kill the machine on a stuck temperature sensor. + * + * This feature may cause some thermally-stable systems to halt. Be sure to test it thoroughly under + * a variety of conditions. Disable if you get false positives. + * + * This feature ensures that temperature sensors are updating regularly. If sensors die or get "stuck", + * or if Marlin stops reading them, temperatures will remain constant while heaters may still be powered! + * This feature only monitors temperature changes so it should catch any issue, hardware or software. + * + * By default it uses the THERMAL_PROTECTION_*_PERIOD constants (above) for the time window, within which + * at least one temperature change must occur, to indicate that sensor polling is working. If any monitored + * heater's temperature remains totally constant (without even a fractional change) during this period, a + * thermal malfunction error occurs and the printer is halted. + * + * A very stable heater might produce a false positive and halt the printer. In this case, try increasing + * the corresponding THERMAL_PROTECTION_*_PERIOD constant a bit. Keep in mind that uncontrolled heating + * shouldn't be allowed to persist for more than a minute or two. + * + * Be careful to distinguish false positives from real sensor issues before disabling this feature. If the + * heater's temperature appears even slightly higher than expected after restarting, you may have a real + * thermal malfunction. Check the temperature graph in your host for any unusual bumps. + */ + //#define THERMAL_PROTECTION_VARIANCE_MONITOR + #if ENABLED(THERMAL_PROTECTION_VARIANCE_MONITOR) + // Variance detection window to override the THERMAL_PROTECTION...PERIOD settings above. + // Keep in mind that some heaters heat up faster than others. + //#define THERMAL_PROTECTION_VARIANCE_MONITOR_PERIOD 30 // (s) Override all watch periods + #endif +#endif + +#if ENABLED(PIDTEMP) + // Add an additional term to the heater power, proportional to the extrusion speed. + // A well-chosen Kc value should add just enough power to melt the increased material volume. + //#define PID_EXTRUSION_SCALING + #if ENABLED(PID_EXTRUSION_SCALING) + #define DEFAULT_Kc (100) // heating power = Kc * e_speed + #define LPQ_MAX_LEN 50 + #endif + + /** + * Add an additional term to the heater power, proportional to the fan speed. + * A well-chosen Kf value should add just enough power to compensate for power-loss from the cooling fan. + * You can either just add a constant compensation with the DEFAULT_Kf value + * or follow the instruction below to get speed-dependent compensation. + * + * Constant compensation (use only with fan speeds of 0% and 100%) + * --------------------------------------------------------------------- + * A good starting point for the Kf-value comes from the calculation: + * kf = (power_fan * eff_fan) / power_heater * 255 + * where eff_fan is between 0.0 and 1.0, based on fan-efficiency and airflow to the nozzle / heater. + * + * Example: + * Heater: 40W, Fan: 0.1A * 24V = 2.4W, eff_fan = 0.8 + * Kf = (2.4W * 0.8) / 40W * 255 = 12.24 + * + * Fan-speed dependent compensation + * -------------------------------- + * 1. To find a good Kf value, set the hotend temperature, wait for it to settle, and enable the fan (100%). + * Make sure PID_FAN_SCALING_LIN_FACTOR is 0 and PID_FAN_SCALING_ALTERNATIVE_DEFINITION is not enabled. + * If you see the temperature drop repeat the test, increasing the Kf value slowly, until the temperature + * drop goes away. If the temperature overshoots after enabling the fan, the Kf value is too big. + * 2. Note the Kf-value for fan-speed at 100% + * 3. Determine a good value for PID_FAN_SCALING_MIN_SPEED, which is around the speed, where the fan starts moving. + * 4. Repeat step 1. and 2. for this fan speed. + * 5. Enable PID_FAN_SCALING_ALTERNATIVE_DEFINITION and enter the two identified Kf-values in + * PID_FAN_SCALING_AT_FULL_SPEED and PID_FAN_SCALING_AT_MIN_SPEED. Enter the minimum speed in PID_FAN_SCALING_MIN_SPEED + */ + //#define PID_FAN_SCALING + #if ENABLED(PID_FAN_SCALING) + //#define PID_FAN_SCALING_ALTERNATIVE_DEFINITION + #if ENABLED(PID_FAN_SCALING_ALTERNATIVE_DEFINITION) + // The alternative definition is used for an easier configuration. + // Just figure out Kf at full speed (255) and PID_FAN_SCALING_MIN_SPEED. + // DEFAULT_Kf and PID_FAN_SCALING_LIN_FACTOR are calculated accordingly. + + #define PID_FAN_SCALING_AT_FULL_SPEED 13.0 //=PID_FAN_SCALING_LIN_FACTOR*255+DEFAULT_Kf + #define PID_FAN_SCALING_AT_MIN_SPEED 6.0 //=PID_FAN_SCALING_LIN_FACTOR*PID_FAN_SCALING_MIN_SPEED+DEFAULT_Kf + #define PID_FAN_SCALING_MIN_SPEED 10.0 // Minimum fan speed at which to enable PID_FAN_SCALING + + #define DEFAULT_Kf (255.0*PID_FAN_SCALING_AT_MIN_SPEED-PID_FAN_SCALING_AT_FULL_SPEED*PID_FAN_SCALING_MIN_SPEED)/(255.0-PID_FAN_SCALING_MIN_SPEED) + #define PID_FAN_SCALING_LIN_FACTOR (PID_FAN_SCALING_AT_FULL_SPEED-DEFAULT_Kf)/255.0 + + #else + #define PID_FAN_SCALING_LIN_FACTOR (0) // Power-loss due to cooling = Kf * (fan_speed) + #define DEFAULT_Kf 10 // A constant value added to the PID-tuner + #define PID_FAN_SCALING_MIN_SPEED 10 // Minimum fan speed at which to enable PID_FAN_SCALING + #endif + #endif +#endif + +/** + * Automatic Temperature Mode + * + * Dynamically adjust the hotend target temperature based on planned E moves. + * + * (Contrast with PID_EXTRUSION_SCALING, which tracks E movement and adjusts PID + * behavior using an additional kC value.) + * + * Autotemp is calculated by (mintemp + factor * mm_per_sec), capped to maxtemp. + * + * Enable Autotemp Mode with M104/M109 F S B. + * Disable by sending M104/M109 with no F parameter (or F0 with AUTOTEMP_PROPORTIONAL). + */ +#define AUTOTEMP +#if ENABLED(AUTOTEMP) + #define AUTOTEMP_OLDWEIGHT 0.98 // Factor used to weight previous readings (0.0 < value < 1.0) + #define AUTOTEMP_MIN 210 + #define AUTOTEMP_MAX 250 + #define AUTOTEMP_FACTOR 0.1f + // Turn on AUTOTEMP on M104/M109 by default using proportions set here + //#define AUTOTEMP_PROPORTIONAL + #if ENABLED(AUTOTEMP_PROPORTIONAL) + #define AUTOTEMP_MIN_P 0 // (°C) Added to the target temperature + #define AUTOTEMP_MAX_P 5 // (°C) Added to the target temperature + #define AUTOTEMP_FACTOR_P 1 // Apply this F parameter by default (overridden by M104/M109 F) + #endif +#endif + +// Show Temperature ADC value +// Enable for M105 to include ADC values read from temperature sensors. +//#define SHOW_TEMP_ADC_VALUES + +/** + * High Temperature Thermistor Support + * + * Thermistors able to support high temperature tend to have a hard time getting + * good readings at room and lower temperatures. This means TEMP_SENSOR_X_RAW_LO_TEMP + * will probably be caught when the heating element first turns on during the + * preheating process, which will trigger a MINTEMP error as a safety measure + * and force stop everything. + * To circumvent this limitation, we allow for a preheat time (during which, + * MINTEMP error won't be triggered) and add a min_temp buffer to handle + * aberrant readings. + * + * If you want to enable this feature for your hotend thermistor(s) + * uncomment and set values > 0 in the constants below + */ + +// The number of consecutive low temperature errors that can occur +// before a MINTEMP error is triggered. (Shouldn't be more than 10.) +//#define MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED 0 + +/** + * The number of milliseconds a hotend will preheat before starting to check + * the temperature. This value should NOT be set to the time it takes the + * hot end to reach the target temperature, but the time it takes to reach + * the minimum temperature your thermistor can read. The lower the better/safer. + * This shouldn't need to be more than 30 seconds (30000) + */ +//#define PREHEAT_TIME_HOTEND_MS 0 +//#define PREHEAT_TIME_BED_MS 0 + +// @section extruder + +/** + * Extruder runout prevention. + * If the machine is idle and the temperature over MINTEMP + * then extrude some filament every couple of SECONDS. + */ +//#define EXTRUDER_RUNOUT_PREVENT +#if ENABLED(EXTRUDER_RUNOUT_PREVENT) + #define EXTRUDER_RUNOUT_MINTEMP 190 + #define EXTRUDER_RUNOUT_SECONDS 30 + #define EXTRUDER_RUNOUT_SPEED 1500 // (mm/min) + #define EXTRUDER_RUNOUT_EXTRUDE 5 // (mm) +#endif + +/** + * Hotend Idle Timeout + * Prevent filament in the nozzle from charring and causing a critical jam. + */ +//#define HOTEND_IDLE_TIMEOUT +#if ENABLED(HOTEND_IDLE_TIMEOUT) + #define HOTEND_IDLE_TIMEOUT_SEC (5*60) // (seconds) Time without extruder movement to trigger protection + #define HOTEND_IDLE_MIN_TRIGGER 180 // (°C) Minimum temperature to enable hotend protection + #define HOTEND_IDLE_NOZZLE_TARGET 0 // (°C) Safe temperature for the nozzle after timeout + #define HOTEND_IDLE_BED_TARGET 0 // (°C) Safe temperature for the bed after timeout +#endif + +// @section temperature + +// Calibration for AD595 / AD8495 sensor to adjust temperature measurements. +// The final temperature is calculated as (measuredTemp * GAIN) + OFFSET. +#define TEMP_SENSOR_AD595_OFFSET 0.0 +#define TEMP_SENSOR_AD595_GAIN 1.0 +#define TEMP_SENSOR_AD8495_OFFSET 0.0 +#define TEMP_SENSOR_AD8495_GAIN 1.0 + +// @section fans + +/** + * Controller Fan + * To cool down the stepper drivers and MOSFETs. + * + * The fan turns on automatically whenever any driver is enabled and turns + * off (or reduces to idle speed) shortly after drivers are turned off. + */ +//#define USE_CONTROLLER_FAN +#if ENABLED(USE_CONTROLLER_FAN) + //#define CONTROLLER_FAN_PIN -1 // Set a custom pin for the controller fan + //#define CONTROLLER_FAN2_PIN -1 // Set a custom pin for second controller fan + //#define CONTROLLER_FAN_USE_Z_ONLY // With this option only the Z axis is considered + //#define CONTROLLER_FAN_IGNORE_Z // Ignore Z stepper. Useful when stepper timeout is disabled. + #define CONTROLLERFAN_SPEED_MIN 0 // (0-255) Minimum speed. (If set below this value the fan is turned off.) + #define CONTROLLERFAN_SPEED_ACTIVE 255 // (0-255) Active speed, used when any motor is enabled + #define CONTROLLERFAN_SPEED_IDLE 0 // (0-255) Idle speed, used when motors are disabled + #define CONTROLLERFAN_IDLE_TIME 60 // (seconds) Extra time to keep the fan running after disabling motors + + // Use TEMP_SENSOR_BOARD as a trigger for enabling the controller fan + //#define CONTROLLER_FAN_MIN_BOARD_TEMP 40 // (°C) Turn on the fan if the board reaches this temperature + + // Use TEMP_SENSOR_SOC as a trigger for enabling the controller fan + //#define CONTROLLER_FAN_MIN_SOC_TEMP 40 // (°C) Turn on the fan if the SoC reaches this temperature + + #define CONTROLLER_FAN_BED_HEATING // Turn on the fan when heating the bed + + //#define CONTROLLER_FAN_EDITABLE // Enable M710 configurable settings + #if ENABLED(CONTROLLER_FAN_EDITABLE) + #define CONTROLLER_FAN_MENU // Enable the Controller Fan submenu + #endif +#endif + +/** + * Fan Kickstart + * When part cooling or controller fans first start, run at a speed that + * gets it spinning reliably for a short time before setting the requested speed. + * (Does not work on Sanguinololu with FAN_SOFT_PWM.) + */ +//#define FAN_KICKSTART_TIME 100 // (ms) +//#define FAN_KICKSTART_POWER 180 // 64-255 +//#define FAN_KICKSTART_LINEAR // Set kickstart time linearly based on the speed, e.g., for 20% (51) it will be FAN_KICKSTART_TIME * 0.2. + // Useful for quick speed up to low speed. Kickstart power must be set to 255. + +// Some coolers may require a non-zero "off" state. +//#define FAN_OFF_PWM 1 + +/** + * PWM Fan Scaling + * + * Define the min/max speeds for PWM fans (as set with M106). + * + * With these options the M106 0-255 value range is scaled to a subset + * to ensure that the fan has enough power to spin, or to run lower + * current fans with higher current. (e.g., 5V/12V fans with 12V/24V) + * Value 0 always turns off the fan. + * + * Define one or both of these to override the default 0-255 range. + */ +//#define FAN_MIN_PWM 50 +//#define FAN_MAX_PWM 128 + +/** + * Fan Fast PWM + * + * Combinations of PWM Modes, prescale values and TOP resolutions are used internally + * to produce a frequency as close as possible to the desired frequency. + * + * FAST_PWM_FAN_FREQUENCY + * Set this to your desired frequency. + * For AVR, if left undefined this defaults to F = F_CPU/(2*255*1) + * i.e., F = 31.4kHz on 16MHz micro-controllers or F = 39.2kHz on 20MHz micro-controllers. + * For non AVR, if left undefined this defaults to F = 1Khz. + * This F value is only to protect the hardware from an absence of configuration + * and not to complete it when users are not aware that the frequency must be specifically set to support the target board. + * + * NOTE: Setting very low frequencies (< 10 Hz) may result in unexpected timer behavior. + * Setting very high frequencies can damage your hardware. + * + * USE_OCR2A_AS_TOP [undefined by default] + * Boards that use TIMER2 for PWM have limitations resulting in only a few possible frequencies on TIMER2: + * 16MHz MCUs: [62.5kHz, 31.4kHz (default), 7.8kHz, 3.92kHz, 1.95kHz, 977Hz, 488Hz, 244Hz, 60Hz, 122Hz, 30Hz] + * 20MHz MCUs: [78.1kHz, 39.2kHz (default), 9.77kHz, 4.9kHz, 2.44kHz, 1.22kHz, 610Hz, 305Hz, 153Hz, 76Hz, 38Hz] + * A greater range can be achieved by enabling USE_OCR2A_AS_TOP. But note that this option blocks the use of + * PWM on pin OC2A. Only use this option if you don't need PWM on 0C2A. (Check your schematic.) + * USE_OCR2A_AS_TOP sacrifices duty cycle control resolution to achieve this broader range of frequencies. + */ +//#define FAST_PWM_FAN // Increase the fan PWM frequency. Removes the PWM noise but increases heating in the FET/Arduino +#if ENABLED(FAST_PWM_FAN) + //#define FAST_PWM_FAN_FREQUENCY 31400 // Define here to override the defaults below + //#define USE_OCR2A_AS_TOP + #ifndef FAST_PWM_FAN_FREQUENCY + #ifdef __AVR__ + #define FAST_PWM_FAN_FREQUENCY ((F_CPU) / (2 * 255 * 1)) + #else + #define FAST_PWM_FAN_FREQUENCY 1000U + #endif + #endif +#endif + +/** + * Assign more PWM fans for part cooling, synchronized with Fan 0 + */ +//#define REDUNDANT_PART_COOLING_FAN 1 // Index of the first fan to synchronize with Fan 0 +#ifdef REDUNDANT_PART_COOLING_FAN + //#define NUM_REDUNDANT_FANS 1 // Number of sequential fans to synchronize with Fan 0 +#endif + +/** + * Extruder cooling fans + * + * Extruder auto fans automatically turn on when their extruders' + * temperatures go above EXTRUDER_AUTO_FAN_TEMPERATURE. + * + * Your board's pins file specifies the recommended pins. Override those here + * or set to -1 to disable completely. + * + * Multiple extruders can be assigned to the same pin in which case + * the fan will turn on when any selected extruder is above the threshold. + */ +#define E0_AUTO_FAN_PIN -1 +#define E1_AUTO_FAN_PIN -1 +#define E2_AUTO_FAN_PIN -1 +#define E3_AUTO_FAN_PIN -1 +#define E4_AUTO_FAN_PIN -1 +#define E5_AUTO_FAN_PIN -1 +#define E6_AUTO_FAN_PIN -1 +#define E7_AUTO_FAN_PIN -1 +#define CHAMBER_AUTO_FAN_PIN -1 +#define COOLER_AUTO_FAN_PIN -1 + +#define EXTRUDER_AUTO_FAN_TEMPERATURE 50 +#define EXTRUDER_AUTO_FAN_SPEED 255 // 255 == full speed +#define CHAMBER_AUTO_FAN_TEMPERATURE 30 +#define CHAMBER_AUTO_FAN_SPEED 255 +#define COOLER_AUTO_FAN_TEMPERATURE 18 +#define COOLER_AUTO_FAN_SPEED 255 + +/** + * Hotend Cooling Fans tachometers + * + * Define one or more tachometer pins to enable fan speed + * monitoring, and reporting of fan speeds with M123. + * + * NOTE: Only works with fans up to 7000 RPM. + */ +//#define FOURWIRES_FANS // Needed with AUTO_FAN when 4-wire PWM fans are installed +//#define E0_FAN_TACHO_PIN -1 +//#define E0_FAN_TACHO_PULLUP +//#define E0_FAN_TACHO_PULLDOWN +//#define E1_FAN_TACHO_PIN -1 +//#define E1_FAN_TACHO_PULLUP +//#define E1_FAN_TACHO_PULLDOWN +//#define E2_FAN_TACHO_PIN -1 +//#define E2_FAN_TACHO_PULLUP +//#define E2_FAN_TACHO_PULLDOWN +//#define E3_FAN_TACHO_PIN -1 +//#define E3_FAN_TACHO_PULLUP +//#define E3_FAN_TACHO_PULLDOWN +//#define E4_FAN_TACHO_PIN -1 +//#define E4_FAN_TACHO_PULLUP +//#define E4_FAN_TACHO_PULLDOWN +//#define E5_FAN_TACHO_PIN -1 +//#define E5_FAN_TACHO_PULLUP +//#define E5_FAN_TACHO_PULLDOWN +//#define E6_FAN_TACHO_PIN -1 +//#define E6_FAN_TACHO_PULLUP +//#define E6_FAN_TACHO_PULLDOWN +//#define E7_FAN_TACHO_PIN -1 +//#define E7_FAN_TACHO_PULLUP +//#define E7_FAN_TACHO_PULLDOWN + +/** + * Part-Cooling Fan Multiplexer + * + * This feature allows you to digitally multiplex the fan output. + * The multiplexer is automatically switched at tool-change. + * Set FANMUX[012]_PINs below for up to 2, 4, or 8 multiplexed fans. + */ +#define FANMUX0_PIN -1 +#define FANMUX1_PIN -1 +#define FANMUX2_PIN -1 + +/** + * @section caselight + * M355 Case Light on-off / brightness + */ +//#define CASE_LIGHT_ENABLE +#if ENABLED(CASE_LIGHT_ENABLE) + //#define CASE_LIGHT_PIN 4 // Override the default pin if needed + #define INVERT_CASE_LIGHT false // Set true if Case Light is ON when pin is LOW + #define CASE_LIGHT_DEFAULT_ON true // Set default power-up state on + #define CASE_LIGHT_DEFAULT_BRIGHTNESS 105 // Set default power-up brightness (0-255, requires PWM pin) + //#define CASE_LIGHT_NO_BRIGHTNESS // Disable brightness control. Enable for non-PWM lighting. + //#define CASE_LIGHT_MAX_PWM 128 // Limit PWM duty cycle (0-255) + //#define CASE_LIGHT_MENU // Add Case Light options to the LCD menu + #if ENABLED(NEOPIXEL_LED) + //#define CASE_LIGHT_USE_NEOPIXEL // Use NeoPixel LED as case light + #endif + #if ANY(RGB_LED, RGBW_LED) + //#define CASE_LIGHT_USE_RGB_LED // Use RGB / RGBW LED as case light + #endif + #if ANY(CASE_LIGHT_USE_NEOPIXEL, CASE_LIGHT_USE_RGB_LED) + #define CASE_LIGHT_DEFAULT_COLOR { 255, 255, 255, 255 } // { Red, Green, Blue, White } + #endif +#endif + +// @section endstops + +// If you want endstops to stay on (by default) even when not homing +// enable this option. Override at any time with M120, M121. +//#define ENDSTOPS_ALWAYS_ON_DEFAULT + +// @section extras + +//#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats. + +// Employ an external closed loop controller. Override pins here if needed. +//#define EXTERNAL_CLOSED_LOOP_CONTROLLER +#if ENABLED(EXTERNAL_CLOSED_LOOP_CONTROLLER) + //#define CLOSED_LOOP_ENABLE_PIN -1 + //#define CLOSED_LOOP_MOVE_COMPLETE_PIN -1 +#endif + +// @section idex + +/** + * Dual X Carriage + * + * This setup has two X carriages that can move independently, each with its own hotend. + * The carriages can be used to print an object with two colors or materials, or in + * "duplication mode" it can print two identical or X-mirrored objects simultaneously. + * The inactive carriage is parked automatically to prevent oozing. + * X1 is the left carriage, X2 the right. They park and home at opposite ends of the X axis. + * By default the X2 stepper is assigned to the first unused E plug on the board. + * + * The following Dual X Carriage modes can be selected with M605 S: + * + * 0 : (FULL_CONTROL) The slicer has full control over both X-carriages and can achieve optimal travel + * results as long as it supports dual X-carriages. (M605 S0) + * + * 1 : (AUTO_PARK) The firmware automatically parks and unparks the X-carriages on tool-change so + * that additional slicer support is not required. (M605 S1) + * + * 2 : (DUPLICATION) The firmware moves the second X-carriage and extruder in synchronization with + * the first X-carriage and extruder, to print 2 copies of the same object at the same time. + * Set the constant X-offset and temperature differential with M605 S2 X[offs] R[deg] and + * follow with M605 S2 to initiate duplicated movement. + * + * 3 : (MIRRORED) Formbot/Vivedino-inspired mirrored mode in which the second extruder duplicates + * the movement of the first except the second extruder is reversed in the X axis. + * Set the initial X offset and temperature differential with M605 S2 X[offs] R[deg] and + * follow with M605 S3 to initiate mirrored movement. + */ +//#define DUAL_X_CARRIAGE +#if ENABLED(DUAL_X_CARRIAGE) + #define X1_MIN_POS X_MIN_POS // Set to X_MIN_POS + #define X1_MAX_POS X_BED_SIZE // A max coordinate so the X1 carriage can't hit the parked X2 carriage + #define X2_MIN_POS 80 // A min coordinate so the X2 carriage can't hit the parked X1 carriage + #define X2_MAX_POS 353 // The max position of the X2 carriage, typically also the home position + #define X2_HOME_POS X2_MAX_POS // Default X2 home position. Set to X2_MAX_POS. + // NOTE: For Dual X Carriage use M218 T1 Xn to override the X2_HOME_POS. + // This allows recalibration of endstops distance without a rebuild. + // Remember to set the second extruder's X-offset to 0 in your slicer. + + // This is the default power-up mode which can be changed later using M605 S. + #define DEFAULT_DUAL_X_CARRIAGE_MODE DXC_AUTO_PARK_MODE + + // Default x offset in duplication mode (typically set to half print bed width) + #define DEFAULT_DUPLICATION_X_OFFSET 100 + + // Default action to execute following M605 mode change commands. Typically G28X to apply new mode. + //#define EVENT_GCODE_IDEX_AFTER_MODECHANGE "G28X" +#endif + +// @section multi stepper + +/** + * Multi-Stepper / Multi-Endstop + * + * When X2_DRIVER_TYPE is defined, this indicates that the X and X2 motors work in tandem. + * The following explanations for X also apply to Y and Z multi-stepper setups. + * Endstop offsets may be changed by 'M666 X Y Z' and stored to EEPROM. + * + * - Enable INVERT_X2_VS_X_DIR if the X2 motor requires an opposite DIR signal from X. + * + * - Enable X_DUAL_ENDSTOPS if the second motor has its own endstop, with adjustable offset. + * + * - Extra endstops are included in the output of 'M119'. + * + * - Set X_DUAL_ENDSTOP_ADJUSTMENT to the known error in the X2 endstop. + * Applied to the X2 motor on 'G28' / 'G28 X'. + * Get the offset by homing X and measuring the error. + * Also set with 'M666 X' and stored to EEPROM with 'M500'. + * + * - Define the extra endstop pins here to override defaults. No auto-assignment. + */ +#if HAS_X2_STEPPER && DISABLED(DUAL_X_CARRIAGE) + //#define INVERT_X2_VS_X_DIR // X2 direction signal is the opposite of X + //#define X_DUAL_ENDSTOPS // X2 has its own endstop + #if ENABLED(X_DUAL_ENDSTOPS) + //#define X2_STOP_PIN X_MAX_PIN // X2 endstop pin override + #define X2_ENDSTOP_ADJUSTMENT 0 // X2 offset relative to X endstop + #endif +#endif + +#if HAS_Y2_STEPPER + //#define INVERT_Y2_VS_Y_DIR // Y2 direction signal is the opposite of Y + //#define Y_DUAL_ENDSTOPS // Y2 has its own endstop + #if ENABLED(Y_DUAL_ENDSTOPS) + //#define Y2_STOP_PIN Y_MAX_PIN // Y2 endstop pin override + #define Y2_ENDSTOP_ADJUSTMENT 0 // Y2 offset relative to Y endstop + #endif +#endif + +// +// Multi-Z steppers +// +#ifdef Z2_DRIVER_TYPE + //#define INVERT_Z2_VS_Z_DIR // Z2 direction signal is the opposite of Z + + //#define Z_MULTI_ENDSTOPS // Other Z axes have their own endstops + #if ENABLED(Z_MULTI_ENDSTOPS) + //#define Z2_STOP_PIN X_MAX_PIN // Z2 endstop pin override + #define Z2_ENDSTOP_ADJUSTMENT 0 // Z2 offset relative to Z endstop + #endif + #ifdef Z3_DRIVER_TYPE + //#define INVERT_Z3_VS_Z_DIR // Z3 direction signal is the opposite of Z + #if ENABLED(Z_MULTI_ENDSTOPS) + //#define Z3_STOP_PIN Y_MAX_PIN // Z3 endstop pin override + #define Z3_ENDSTOP_ADJUSTMENT 0 // Z3 offset relative to Z endstop + #endif + #endif + #ifdef Z4_DRIVER_TYPE + //#define INVERT_Z4_VS_Z_DIR // Z4 direction signal is the opposite of Z + #if ENABLED(Z_MULTI_ENDSTOPS) + //#define Z4_STOP_PIN Z_MAX_PIN // Z4 endstop pin override + #define Z4_ENDSTOP_ADJUSTMENT 0 // Z4 offset relative to Z endstop + #endif + #endif +#endif + +// Drive the E axis with two synchronized steppers +//#define E_DUAL_STEPPER_DRIVERS +#if ENABLED(E_DUAL_STEPPER_DRIVERS) + //#define INVERT_E1_VS_E0_DIR // E direction signals are opposites +#endif + +// @section extruder + +// Activate a solenoid on the active extruder with M380. Disable all with M381. +// Define SOL0_PIN, SOL1_PIN, etc., for each extruder that has a solenoid. +//#define EXT_SOLENOID + +// @section homing + +/** + * Homing Procedure + * Homing (G28) does an indefinite move towards the endstops to establish + * the position of the toolhead relative to the workspace. + */ + +//#define SENSORLESS_BACKOFF_MM { 2, 2, 0 } // (linear=mm, rotational=°) Backoff from endstops before sensorless homing + +#define HOMING_BUMP_MM { 5, 5, 5 } // (linear=mm, rotational=°) Backoff from endstops after first bump +#define HOMING_BUMP_DIVISOR { 4, 4, 4 } // Re-Bump Speed Divisor (Divides the Homing Feedrate) + +//#define HOMING_BACKOFF_POST_MM { 2, 2, 2 } // (linear=mm, rotational=°) Backoff from endstops after homing +//#define XY_COUNTERPART_BACKOFF_MM 0 // (mm) Backoff X after homing Y, and vice-versa + +//#define QUICK_HOME // If G28 contains XY do a diagonal move first +//#define HOME_Y_BEFORE_X // If G28 contains XY home Y before X +//#define HOME_Z_FIRST // Home Z first. Requires a real endstop (not a probe). +//#define CODEPENDENT_XY_HOMING // If X/Y can't home without homing Y/X first + +// @section bltouch + +#if ENABLED(BLTOUCH) + /** + * Either: Use the defaults (recommended) or: For special purposes, use the following DEFINES + * Do not activate settings that the probe might not understand. Clones might misunderstand + * advanced commands. + * + * Note: If the probe is not deploying, do a "Reset" and "Self-Test" and then check the + * wiring of the BROWN, RED and ORANGE wires. + * + * Note: If the trigger signal of your probe is not being recognized, it has been very often + * because the BLACK and WHITE wires needed to be swapped. They are not "interchangeable" + * like they would be with a real switch. So please check the wiring first. + * + * Settings for all BLTouch and clone probes: + */ + + // Safety: The probe needs time to recognize the command. + // Minimum command delay (ms). Enable and increase if needed. + //#define BLTOUCH_DELAY 500 + + /** + * Settings for BLTOUCH Classic 1.2, 1.3 or BLTouch Smart 1.0, 2.0, 2.2, 3.0, 3.1, and most clones: + */ + + // Feature: Switch into SW mode after a deploy. It makes the output pulse longer. Can be useful + // in special cases, like noisy or filtered input configurations. + //#define BLTOUCH_FORCE_SW_MODE + + /** + * Settings for BLTouch Smart 3.0 and 3.1 + * Summary: + * - Voltage modes: 5V and OD (open drain - "logic voltage free") output modes + * - High-Speed mode + * - Disable LCD voltage options + */ + + /** + * Danger: Don't activate 5V mode unless attached to a 5V-tolerant controller! + * V3.0 or 3.1: Set default mode to 5V mode at Marlin startup. + * If disabled, OD mode is the hard-coded default on 3.0 + * On startup, Marlin will compare its EEPROM to this value. If the selected mode + * differs, a mode set EEPROM write will be completed at initialization. + * Use the option below to force an EEPROM write to a V3.1 probe regardless. + */ + //#define BLTOUCH_SET_5V_MODE + + // Safety: Enable voltage mode settings in the LCD menu. + //#define BLTOUCH_LCD_VOLTAGE_MENU + + /** + * Safety: Activate if connecting a probe with an unknown voltage mode. + * V3.0: Set a probe into mode selected above at Marlin startup. Required for 5V mode on 3.0 + * V3.1: Force a probe with unknown mode into selected mode at Marlin startup ( = Probe EEPROM write ) + * To preserve the life of the probe, use this once then turn it off and re-flash. + */ + //#define BLTOUCH_FORCE_MODE_SET + + /** + * Enable "HIGH SPEED" option for probing. + * Danger: Disable if your probe sometimes fails. Only suitable for stable well-adjusted systems. + * This feature was designed for Deltabots with very fast Z moves; however, higher speed Cartesians + * might be able to use it. If the machine can't raise Z fast enough the BLTouch may go into ALARM. + * + * Set the default state here, change with 'M401 S' or UI, use M500 to save, M502 to reset. + */ + //#define BLTOUCH_HS_MODE true + + #ifdef BLTOUCH_HS_MODE + // The probe Z offset (M851 Z) is the height at which the probe triggers. + // This must be large enough to keep the probe pin off the bed and prevent + // it from snagging on the bed clips. + #define BLTOUCH_HS_EXTRA_CLEARANCE 7 // Extra Z Clearance + #endif + +#endif // BLTOUCH + +// @section calibrate + +/** + * Z Steppers Auto-Alignment + * Add the G34 command to align multiple Z steppers using a bed probe. + */ +//#define Z_STEPPER_AUTO_ALIGN +#if ENABLED(Z_STEPPER_AUTO_ALIGN) + /** + * Define probe X and Y positions for Z1, Z2 [, Z3 [, Z4]] + * These positions are machine-relative and do not shift with the M206 home offset! + * If not defined, probe limits will be used. + * Override with 'M422 S X Y'. + */ + //#define Z_STEPPER_ALIGN_XY { { 10, 190 }, { 100, 10 }, { 190, 190 } } + + /** + * Orientation for the automatically-calculated probe positions. + * Override Z stepper align points with 'M422 S X Y' + * + * 2 Steppers: (0) (1) + * | | 2 | + * | 1 2 | | + * | | 1 | + * + * 3 Steppers: (0) (1) (2) (3) + * | 3 | 1 | 2 1 | 2 | + * | | 3 | | 3 | + * | 1 2 | 2 | 3 | 1 | + * + * 4 Steppers: (0) (1) (2) (3) + * | 4 3 | 1 4 | 2 1 | 3 2 | + * | | | | | + * | 1 2 | 2 3 | 3 4 | 4 1 | + */ + #ifndef Z_STEPPER_ALIGN_XY + //#define Z_STEPPERS_ORIENTATION 0 + #endif + + /** + * Z Stepper positions for more rapid convergence in bed alignment. + * Requires 3 or 4 Z steppers. + * + * Define Stepper XY positions for Z1, Z2, Z3... corresponding to the screw + * positions in the bed carriage, with one position per Z stepper in stepper + * driver order. + */ + //#define Z_STEPPER_ALIGN_STEPPER_XY { { 210.7, 102.5 }, { 152.6, 220.0 }, { 94.5, 102.5 } } + + #ifndef Z_STEPPER_ALIGN_STEPPER_XY + // Amplification factor. Used to scale the correction step up or down in case + // the stepper (spindle) position is farther out than the test point. + #define Z_STEPPER_ALIGN_AMP 1.0 // Use a value > 1.0 NOTE: This may cause instability! + #endif + + // On a 300mm bed a 5% grade would give a misalignment of ~1.5cm + #define G34_MAX_GRADE 5 // (%) Maximum incline that G34 will handle + #define Z_STEPPER_ALIGN_ITERATIONS 5 // Number of iterations to apply during alignment + #define Z_STEPPER_ALIGN_ACC 0.02 // Stop iterating early if the accuracy is better than this + + #define RESTORE_LEVELING_AFTER_G34 // Restore leveling after G34 is done? + + // After G34, re-home Z (G28 Z) or just calculate it from the last probe heights? + // Re-homing might be more precise in reproducing the actual 'G28 Z' homing height, especially on an uneven bed. + #define HOME_AFTER_G34 + + /** + * Commands to execute at the start of G34 probing, + * after switching to the PROBING_TOOL. + */ + //#define EVENT_GCODE_BEFORE_G34 "M300 P440 S200" + + /** + * Commands to execute at the end of G34 probing. + * Useful to retract or move the Z probe out of the way. + */ + //#define EVENT_GCODE_AFTER_G34 "G1 Z10 F12000\nG1 X15 Y330\nG1 Z0.5\nG1 Z10" + +#endif // Z_STEPPER_AUTO_ALIGN + +/** + * Assisted Tramming + * + * Add the G35 command to measure bed corners and help adjust screws. Requires a bed probe. + */ +//#define ASSISTED_TRAMMING +#if ENABLED(ASSISTED_TRAMMING) + + // Define from 3 to 9 points to probe. + #define TRAMMING_POINT_XY { { 20, 20 }, { 180, 20 }, { 180, 180 }, { 20, 180 } } + + // Define position names for probe points. + #define TRAMMING_POINT_NAME_1 "Front-Left" + #define TRAMMING_POINT_NAME_2 "Front-Right" + #define TRAMMING_POINT_NAME_3 "Back-Right" + #define TRAMMING_POINT_NAME_4 "Back-Left" + + #define RESTORE_LEVELING_AFTER_G35 // Enable to restore leveling setup after operation + //#define REPORT_TRAMMING_MM // Report Z deviation (mm) for each point relative to the first + + //#define ASSISTED_TRAMMING_WIZARD // Add a Tramming Wizard to the LCD menu + + //#define ASSISTED_TRAMMING_WAIT_POSITION { X_CENTER, Y_CENTER, 30 } // Move the nozzle out of the way for adjustment + + /** + * Screw Thread. Use one of the following defines: + * + * M3_CW = M3 Clockwise, M3_CCW = M3 Counter-Clockwise + * M4_CW = M4 Clockwise, M4_CCW = M4 Counter-Clockwise + * M5_CW = M5 Clockwise, M5_CCW = M5 Counter-Clockwise + * + * :{'M3_CW':'M3 Clockwise','M3_CCW':'M3 Counter-Clockwise','M4_CW':'M4 Clockwise','M4_CCW':'M4 Counter-Clockwise','M5_CW':'M5 Clockwise','M5_CCW':'M5 Counter-Clockwise'} + */ + #define TRAMMING_SCREW_THREAD M3_CW + +#endif + +// @section motion control + +/** + * Fixed-time-based Motion Control -- BETA FEATURE + * Enable/disable and set parameters with G-code M493 and M494. + * See ft_types.h for named values used by FTM options. + */ +//#define FT_MOTION +#if ENABLED(FT_MOTION) + //#define FTM_IS_DEFAULT_MOTION // Use FT Motion as the factory default? + //#define FT_MOTION_MENU // Provide a MarlinUI menu to set M493 and M494 parameters + //#define FTM_HOME_AND_PROBE // Use FT Motion for homing / probing. Disable if FT Motion breaks these functions. + + #define FTM_DEFAULT_DYNFREQ_MODE dynFreqMode_DISABLED // Default mode of dynamic frequency calculation. (DISABLED, Z_BASED, MASS_BASED) + + #define FTM_LINEAR_ADV_DEFAULT_ENA false // Default linear advance enable (true) or disable (false) + #define FTM_LINEAR_ADV_DEFAULT_K 0.0f // Default linear advance gain. (Acceleration-based scaling factor.) + + #define FTM_DEFAULT_SHAPER_X ftMotionShaper_NONE // Default shaper mode on X axis (NONE, ZV, ZVD, ZVDD, ZVDDD, EI, 2HEI, 3HEI, MZV) + #define FTM_SHAPING_DEFAULT_FREQ_X 37.0f // (Hz) Default peak frequency used by input shapers + #define FTM_SHAPING_ZETA_X 0.1f // Zeta used by input shapers for X axis + #define FTM_SHAPING_V_TOL_X 0.05f // Vibration tolerance used by EI input shapers for X axis + + #define FTM_DEFAULT_SHAPER_Y ftMotionShaper_NONE // Default shaper mode on Y axis + #define FTM_SHAPING_DEFAULT_FREQ_Y 37.0f // (Hz) Default peak frequency used by input shapers + #define FTM_SHAPING_ZETA_Y 0.1f // Zeta used by input shapers for Y axis + #define FTM_SHAPING_V_TOL_Y 0.05f // Vibration tolerance used by EI input shapers for Y axis + + //#define FTM_SHAPER_Z // Include Z shaping support + #define FTM_DEFAULT_SHAPER_Z ftMotionShaper_NONE // Default shaper mode on Z axis + #define FTM_SHAPING_DEFAULT_FREQ_Z 21.0f // (Hz) Default peak frequency used by input shapers + #define FTM_SHAPING_ZETA_Z 0.03f // Zeta used by input shapers for Z axis + #define FTM_SHAPING_V_TOL_Z 0.05f // Vibration tolerance used by EI input shapers for Z axis + + //#define FTM_SHAPER_E // Include E shaping support + // Required to synchronise extruder with XYZ (better quality) + #define FTM_DEFAULT_SHAPER_E ftMotionShaper_NONE // Default shaper mode on Extruder axis + #define FTM_SHAPING_DEFAULT_FREQ_E 21.0f // (Hz) Default peak frequency used by input shapers + #define FTM_SHAPING_ZETA_E 0.03f // Zeta used by input shapers for E axis + #define FTM_SHAPING_V_TOL_E 0.05f // Vibration tolerance used by EI input shapers for E axis + + //#define FTM_SMOOTHING // Smoothing can reduce artifacts and make steppers quieter + // on sharp corners, but too much will round corners. + #if ENABLED(FTM_SMOOTHING) + #define FTM_MAX_SMOOTHING_TIME 0.10f // Maximum smoothing time (seconds), higher consumes more RAM. + // Increase smoothing time to reduce jerky motion, ghosting and noises. + #define FTM_SMOOTHING_TIME_X 0.00f // (s) Smoothing time for X axis. Zero means disabled. + #define FTM_SMOOTHING_TIME_Y 0.00f // (s) Smoothing time for Y axis + #define FTM_SMOOTHING_TIME_Z 0.00f // (s) Smoothing time for Z axis + #define FTM_SMOOTHING_TIME_E 0.02f // (s) Smoothing time for E axis. Prevents noise/skipping from LA by + // smoothing acceleration peaks, which may also smooth curved surfaces. + #endif + + #define FTM_TRAJECTORY_TYPE TRAPEZOIDAL // Block acceleration profile (TRAPEZOIDAL, POLY5, POLY6) + // TRAPEZOIDAL: Continuous Velocity. Max acceleration is respected. + // POLY5: Like POLY6 with 1.5x but cpu cheaper. + // POLY6: Continuous Acceleration (aka S_CURVE). + // POLY trajectories not only reduce resonances without rounding corners, but also + // reduce extruder strain due to linear advance. + + #define FTM_POLY6_ACCELERATION_OVERSHOOT 1.875f // Max acceleration overshoot factor for POLY6 (1.25 to 1.875) + + /** + * Advanced configuration + */ + #define FTM_UNIFIED_BWS // DON'T DISABLE unless you use Ulendo FBS (not implemented) + #if ENABLED(FTM_UNIFIED_BWS) + #define FTM_BW_SIZE 100 // Unified Window and Batch size with a ratio of 2 + #else + #define FTM_WINDOW_SIZE 200 // Custom Window size for trajectory generation needed by Ulendo FBS + #define FTM_BATCH_SIZE 100 // Custom Batch size for trajectory generation needed by Ulendo FBS + #endif + + #define FTM_FS 1000 // (Hz) Frequency for trajectory generation. (Reciprocal of FTM_TS) + + #if DISABLED(COREXY) + #define FTM_STEPPER_FS 20000 // (Hz) Frequency for stepper I/O update + + // Use this to adjust the time required to consume the command buffer. + // Try increasing this value if stepper motion is choppy. + #define FTM_STEPPERCMD_BUFF_SIZE 3000 // Size of the stepper command buffers + + #else + // CoreXY motion needs a larger buffer size. These values are based on our testing. + #define FTM_STEPPER_FS 30000 + #define FTM_STEPPERCMD_BUFF_SIZE 6000 + #endif + + #define FTM_MIN_SHAPE_FREQ 10 // (Hz) Minimum shaping frequency, lower consumes more RAM +#endif // FT_MOTION + +/** + * Input Shaping + * + * Zero Vibration (ZV) Input Shaping for X and/or Y movements. + * + * This option uses a lot of SRAM for the step buffer. The buffer size is + * calculated automatically from SHAPING_FREQ_[XYZ], DEFAULT_AXIS_STEPS_PER_UNIT, + * DEFAULT_MAX_FEEDRATE and ADAPTIVE_STEP_SMOOTHING. The default calculation can + * be overridden by setting SHAPING_MIN_FREQ and/or SHAPING_MAX_FEEDRATE. + * The higher the frequency and the lower the feedrate, the smaller the buffer. + * If the buffer is too small at runtime, input shaping will have reduced + * effectiveness during high speed movements. + * + * Tune with M593 D F + */ +//#define INPUT_SHAPING_X +//#define INPUT_SHAPING_Y +//#define INPUT_SHAPING_Z +#if ANY(INPUT_SHAPING_X, INPUT_SHAPING_Y, INPUT_SHAPING_Z) + #if ENABLED(INPUT_SHAPING_X) + #define SHAPING_FREQ_X 40.0 // (Hz) The default dominant resonant frequency on the X axis. + #define SHAPING_ZETA_X 0.15 // Damping ratio of the X axis (range: 0.0 = no damping to 1.0 = critical damping). + #endif + #if ENABLED(INPUT_SHAPING_Y) + #define SHAPING_FREQ_Y 40.0 // (Hz) The default dominant resonant frequency on the Y axis. + #define SHAPING_ZETA_Y 0.15 // Damping ratio of the Y axis (range: 0.0 = no damping to 1.0 = critical damping). + #endif + #if ENABLED(INPUT_SHAPING_Z) + #define SHAPING_FREQ_Z 40.0 // (Hz) The default dominant resonant frequency on the Z axis. + #define SHAPING_ZETA_Z 0.15 // Damping ratio of the Z axis (range: 0.0 = no damping to 1.0 = critical damping). + #endif + //#define SHAPING_MIN_FREQ 20.0 // (Hz) By default the minimum of the shaping frequencies. Override to affect SRAM usage. + //#define SHAPING_MAX_STEPRATE 10000 // By default the maximum total step rate of the shaped axes. Override to affect SRAM usage. + //#define SHAPING_MENU // Add a menu to the LCD to set shaping parameters. +#endif + +// @section motion + +#define AXIS_RELATIVE_MODES { false, false, false, false } + +// Add a Duplicate option for well-separated conjoined nozzles +//#define MULTI_NOZZLE_DUPLICATION + +// By default stepper drivers require an active-HIGH signal but some high-power drivers require an active-LOW signal to step. +#define STEP_STATE_X HIGH +#define STEP_STATE_Y HIGH +#define STEP_STATE_Z HIGH +#define STEP_STATE_I HIGH +#define STEP_STATE_J HIGH +#define STEP_STATE_K HIGH +#define STEP_STATE_U HIGH +#define STEP_STATE_V HIGH +#define STEP_STATE_W HIGH +#define STEP_STATE_E HIGH + +/** + * Idle Stepper Shutdown + * Enable DISABLE_IDLE_* to shut down axis steppers after an idle period. + * The default timeout duration can be overridden with M18 and M84. Set to 0 for No Timeout. + */ +#define DEFAULT_STEPPER_TIMEOUT_SEC 300 +#define DISABLE_IDLE_X +#define DISABLE_IDLE_Y +#define DISABLE_IDLE_Z // Disable if the nozzle could fall onto your printed part! +//#define DISABLE_IDLE_I +//#define DISABLE_IDLE_J +//#define DISABLE_IDLE_K +//#define DISABLE_IDLE_U +//#define DISABLE_IDLE_V +//#define DISABLE_IDLE_W +#define DISABLE_IDLE_E // Shut down all idle extruders + +// Default Minimum Feedrates for printing and travel moves +#define DEFAULT_MINIMUMFEEDRATE 0.0 // (mm/s) Minimum feedrate. Set with M205 S. +#define DEFAULT_MINTRAVELFEEDRATE 0.0 // (mm/s) Minimum travel feedrate. Set with M205 T. + +// Minimum time that a segment needs to take as the buffer gets emptied +#define DEFAULT_MINSEGMENTTIME 20000 // (µs) Set with M205 B. + +// Slow down the machine if the lookahead buffer is (by default) half full. +// Increase the slowdown divisor for larger buffer sizes. +#define SLOWDOWN +#if ENABLED(SLOWDOWN) + #define SLOWDOWN_DIVISOR 2 +#endif + +/** + * XY Frequency limit + * Reduce resonance by limiting the frequency of small zigzag infill moves. + * See https://hydraraptor.blogspot.com/2010/12/frequency-limit.html + * Use M201 F S to change limits at runtime. + */ +//#define XY_FREQUENCY_LIMIT 10 // (Hz) Maximum frequency of small zigzag infill moves. Set with M201 F. +#ifdef XY_FREQUENCY_LIMIT + #define XY_FREQUENCY_MIN_PERCENT 5 // (%) Minimum FR percentage to apply. Set with M201 S. +#endif + +// +// Backlash Compensation +// Adds extra movement to axes on direction-changes to account for backlash. +// +//#define BACKLASH_COMPENSATION +#if ENABLED(BACKLASH_COMPENSATION) + // Define values for backlash distance and correction. + // If BACKLASH_GCODE is enabled these values are the defaults. + #define BACKLASH_DISTANCE_MM { 0, 0, 0 } // (linear=mm, rotational=°) One value for each linear axis + #define BACKLASH_CORRECTION 0.0 // 0.0 = no correction; 1.0 = full correction + + // Add steps for motor direction changes on CORE kinematics + //#define CORE_BACKLASH + + // Set BACKLASH_SMOOTHING_MM to spread backlash correction over multiple segments + // to reduce print artifacts. (Enabling this is costly in memory and computation!) + //#define BACKLASH_SMOOTHING_MM 3 // (mm) + + // Add runtime configuration and tuning of backlash values (M425) + //#define BACKLASH_GCODE + + #if ENABLED(BACKLASH_GCODE) + // Measure the Z backlash when probing (G29) and set with "M425 Z" + #define MEASURE_BACKLASH_WHEN_PROBING + + #if ENABLED(MEASURE_BACKLASH_WHEN_PROBING) + // When measuring, the probe will move up to BACKLASH_MEASUREMENT_LIMIT + // mm away from point of contact in BACKLASH_MEASUREMENT_RESOLUTION + // increments while checking for the contact to be broken. + #define BACKLASH_MEASUREMENT_LIMIT 0.5 // (mm) + #define BACKLASH_MEASUREMENT_RESOLUTION 0.005 // (mm) + #define BACKLASH_MEASUREMENT_FEEDRATE Z_PROBE_FEEDRATE_SLOW // (mm/min) + #endif + #endif +#endif + +/** + * Automatic backlash, position, and hotend offset calibration + * + * Enable G425 to run automatic calibration using an electrically- + * conductive cube, bolt, or washer mounted on the bed. + * + * G425 uses the probe to touch the top and sides of the calibration object + * on the bed and measures and/or correct positional offsets, axis backlash + * and hotend offsets. + * + * Note: HOTEND_OFFSET and CALIBRATION_OBJECT_CENTER must be set to within + * ±5mm of true values for G425 to succeed. + */ +//#define CALIBRATION_GCODE +#if ENABLED(CALIBRATION_GCODE) + + //#define CALIBRATION_SCRIPT_PRE "M117 Starting Auto-Calibration\nT0\nG28\nG12\nM117 Calibrating..." + //#define CALIBRATION_SCRIPT_POST "M500\nM117 Calibration data saved" + + #define CALIBRATION_FEEDRATE_SLOW 60 // (mm/min) + #define CALIBRATION_FEEDRATE_FAST 1200 // (mm/min) + #define CALIBRATION_FEEDRATE_TRAVEL 3000 // (mm/min) + + // The following parameters refer to the conical section of the nozzle tip. + #define CALIBRATION_NOZZLE_TIP_HEIGHT 1.0 // (mm) + #define CALIBRATION_NOZZLE_OUTER_DIAMETER 2.0 // (mm) + + // Uncomment to enable reporting (required for "G425 V", but consumes flash). + //#define CALIBRATION_REPORTING + + // The true location and dimension the cube/bolt/washer on the bed. + #define CALIBRATION_OBJECT_CENTER { 264.0, -22.0, -2.0 } // (mm) + #define CALIBRATION_OBJECT_DIMENSIONS { 10.0, 10.0, 10.0 } // (mm) + + // Comment out any sides which are unreachable by the probe. For best + // auto-calibration results, all sides must be reachable. + #define CALIBRATION_MEASURE_RIGHT + #define CALIBRATION_MEASURE_FRONT + #define CALIBRATION_MEASURE_LEFT + #define CALIBRATION_MEASURE_BACK + + //#define CALIBRATION_MEASURE_IMIN + //#define CALIBRATION_MEASURE_IMAX + //#define CALIBRATION_MEASURE_JMIN + //#define CALIBRATION_MEASURE_JMAX + //#define CALIBRATION_MEASURE_KMIN + //#define CALIBRATION_MEASURE_KMAX + //#define CALIBRATION_MEASURE_UMIN + //#define CALIBRATION_MEASURE_UMAX + //#define CALIBRATION_MEASURE_VMIN + //#define CALIBRATION_MEASURE_VMAX + //#define CALIBRATION_MEASURE_WMIN + //#define CALIBRATION_MEASURE_WMAX + + // Probing at the exact top center only works if the center is flat. If + // probing on a screw head or hollow washer, probe near the edges. + //#define CALIBRATION_MEASURE_AT_TOP_EDGES + + // Define the pin to read during calibration + #ifndef CALIBRATION_PIN + //#define CALIBRATION_PIN -1 // Define here to override the default pin + #define CALIBRATION_PIN_INVERTING false // Set to true to invert the custom pin + //#define CALIBRATION_PIN_PULLDOWN + #define CALIBRATION_PIN_PULLUP + #endif +#endif + +/** + * Multi-stepping sends steps in bursts to reduce MCU usage for high step-rates. + * This allows higher feedrates than the MCU could otherwise support. + */ +#define MULTISTEPPING_LIMIT 16 // :[1, 2, 4, 8, 16, 32, 64, 128] + +/** + * Adaptive Step Smoothing increases the resolution of multi-axis moves, particularly at step frequencies + * below 1kHz (for AVR) or 10kHz (for ARM), where aliasing between axes in multi-axis moves causes audible + * vibration and surface artifacts. The algorithm adapts to provide the best possible step smoothing at the + * lowest stepping frequencies. + */ +//#define ADAPTIVE_STEP_SMOOTHING + +/** + * Custom Microstepping + * Override as-needed for your setup. Up to 3 MS pins are supported. + */ +//#define MICROSTEP1 LOW,LOW,LOW +//#define MICROSTEP2 HIGH,LOW,LOW +//#define MICROSTEP4 LOW,HIGH,LOW +//#define MICROSTEP8 HIGH,HIGH,LOW +//#define MICROSTEP16 LOW,LOW,HIGH +//#define MICROSTEP32 HIGH,LOW,HIGH + +// Microstep settings (Requires a board with pins named X_MS1, X_MS2, etc.) +#define MICROSTEP_MODES { 16, 16, 16, 16, 16, 16 } // [1,2,4,8,16] + +/** + * @section stepper motor current + * + * Some boards have a means of setting the stepper motor current via firmware. + * + * The power on motor currents are set by: + * PWM_MOTOR_CURRENT - used by MINIRAMBO & ULTIMAIN_2 + * known compatible chips: A4982 + * DIGIPOT_MOTOR_CURRENT - used by BQ_ZUM_MEGA_3D, RAMBO & SCOOVO_X9H + * known compatible chips: AD5206 + * DAC_MOTOR_CURRENT_DEFAULT - used by PRINTRBOARD_REVF & RIGIDBOARD_V2 + * known compatible chips: MCP4728 + * DIGIPOT_I2C_MOTOR_CURRENTS - used by 5DPRINT, AZTEEG_X3_PRO, AZTEEG_X5_MINI_WIFI, MIGHTYBOARD_REVE + * known compatible chips: MCP4451, MCP4018 + * + * Motor currents can also be set by M907 - M910 and by the LCD. + * M907 - applies to all. + * M908 - BQ_ZUM_MEGA_3D, RAMBO, PRINTRBOARD_REVF, RIGIDBOARD_V2 & SCOOVO_X9H + * M909, M910 & LCD - only PRINTRBOARD_REVF & RIGIDBOARD_V2 + */ +//#define PWM_MOTOR_CURRENT { 1300, 1300, 1250 } // Values in milliamps +//#define DIGIPOT_MOTOR_CURRENT { 135,135,135,135,135 } // Values 0-255 (RAMBO 135 = ~0.75A, 185 = ~1A) +//#define DAC_MOTOR_CURRENT_DEFAULT { 70, 80, 90, 80 } // Default drive percent - X, Y, Z, E axis + +/** + * I2C-based DIGIPOTs (e.g., Azteeg X3 Pro) + */ +//#define DIGIPOT_MCP4018 // Requires https://github.com/felias-fogg/SlowSoftI2CMaster +//#define DIGIPOT_MCP4451 +#if ANY(DIGIPOT_MCP4018, DIGIPOT_MCP4451) + #define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT:4 AZTEEG_X3_PRO:8 MKS_SBASE:5 MIGHTYBOARD_REVE:5 + + // Actual motor currents in Amps. The number of entries must match DIGIPOT_I2C_NUM_CHANNELS. + // These correspond to the physical drivers, so be mindful if the order is changed. + #define DIGIPOT_I2C_MOTOR_CURRENTS { 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 } // AZTEEG_X3_PRO + + //#define DIGIPOT_USE_RAW_VALUES // Use DIGIPOT_MOTOR_CURRENT raw wiper values (instead of A4988 motor currents) + + /** + * Common slave addresses: + * + * A (A shifted) B (B shifted) IC + * Smoothie 0x2C (0x58) 0x2D (0x5A) MCP4451 + * AZTEEG_X3_PRO 0x2C (0x58) 0x2E (0x5C) MCP4451 + * AZTEEG_X5_MINI 0x2C (0x58) 0x2E (0x5C) MCP4451 + * AZTEEG_X5_MINI_WIFI 0x58 0x5C MCP4451 + * MIGHTYBOARD_REVE 0x2F (0x5E) MCP4018 + */ + //#define DIGIPOT_I2C_ADDRESS_A 0x2C // Unshifted slave address for first DIGIPOT + //#define DIGIPOT_I2C_ADDRESS_B 0x2D // Unshifted slave address for second DIGIPOT +#endif + +//=========================================================================== +//=============================Additional Features=========================== +//=========================================================================== + +// @section lcd + +#if HAS_MANUAL_MOVE_MENU + #define MANUAL_FEEDRATE { 50*60, 50*60, 50*60, 60 } // (mm/min) Feedrates for manual moves along X, Y, Z, E from panel + #define FINE_MANUAL_MOVE 0.025 // (mm) Smallest manual move (< 0.1mm) applying to Z on most machines + #if IS_ULTIPANEL + #define MANUAL_E_MOVES_RELATIVE // Display extruder move distance rather than "position" + #define ULTIPANEL_FEEDMULTIPLY // Encoder sets the feedrate multiplier on the Status Screen + //#define ULTIPANEL_FLOWPERCENT // Encoder sets the flow percentage on the Status Screen + #endif +#endif + +// Change values more rapidly when the encoder is rotated faster +#define ENCODER_RATE_MULTIPLIER +#if ENABLED(ENCODER_RATE_MULTIPLIER) + #define ENCODER_10X_STEPS_PER_SEC 30 // (steps/s) Encoder rate for 10x speed + #define ENCODER_100X_STEPS_PER_SEC 80 // (steps/s) Encoder rate for 100x speed +#endif + +// Play a beep when the feedrate is changed from the Status Screen +//#define BEEP_ON_FEEDRATE_CHANGE +#if ENABLED(BEEP_ON_FEEDRATE_CHANGE) + #define FEEDRATE_CHANGE_BEEP_DURATION 10 + #define FEEDRATE_CHANGE_BEEP_FREQUENCY 440 +#endif + +/** + * Probe Offset Wizard + * Add a Probe Z Offset calibration option to the LCD menu. + * Use this helper to get a perfect 'M851 Z' probe offset. + * When launched this powerful wizard: + * - Measures the bed height at the configured position with the probe. + * - Moves the nozzle to the same position for a "paper" measurement. + * - The difference is used to set the probe Z offset. + */ +#if HAS_BED_PROBE && ANY(HAS_MARLINUI_MENU, HAS_TFT_LVGL_UI) + //#define PROBE_OFFSET_WIZARD + #if ENABLED(PROBE_OFFSET_WIZARD) + /** + * Enable to init the Probe Z-Offset when starting the Wizard. + * Use a height slightly above the estimated nozzle-to-probe Z offset. + * For example, with an offset of -5, consider a starting height of -4. + */ + //#define PROBE_OFFSET_WIZARD_START_Z -4.0 + + // Set a convenient position to do the calibration (probing point and nozzle/bed-distance) + //#define PROBE_OFFSET_WIZARD_XY_POS { X_CENTER, Y_CENTER } + #endif +#endif + +#if HAS_MARLINUI_MENU + + #if HAS_BED_PROBE + + // Show Deploy / Stow Probe options in the Motion menu. + #define PROBE_DEPLOY_STOW_MENU + + // Add calibration in the Probe Offsets menu to compensate for X-axis twist. + //#define X_AXIS_TWIST_COMPENSATION + #if ENABLED(X_AXIS_TWIST_COMPENSATION) + /** + * Enable to init the Probe Z-Offset when starting the Wizard. + * Use a height slightly above the estimated nozzle-to-probe Z offset. + * For example, with an offset of -5, consider a starting height of -4. + */ + #define XATC_START_Z 0.0 + #define XATC_MAX_POINTS 3 // Number of points to probe in the wizard + #define XATC_Y_POSITION Y_CENTER // (mm) Y position to probe + #define XATC_Z_OFFSETS { 0, 0, 0 } // Z offsets for X axis sample points + #endif + + #endif + + // Include a page of printer information in the LCD Main Menu + //#define LCD_INFO_MENU + #if ENABLED(LCD_INFO_MENU) + //#define LCD_PRINTER_INFO_IS_BOOTSCREEN // Show bootscreen(s) instead of Printer Info pages + //#define BUILD_INFO_MENU_ITEM // Add a menu item to display the build date and time + #endif + + /** + * MarlinUI "Move Axis" menu distances. Comma-separated list. + * Values are displayed as-defined, so always use plain numbers here. + * Axis moves <= 1/2 the axis length and Extruder moves <= EXTRUDE_MAXLENGTH + * will be shown in the move submenus. + */ + + #define MANUAL_MOVE_DISTANCE_MM 10, 1.0, 0.1 // (mm) + //#define MANUAL_MOVE_DISTANCE_MM 100, 50, 10, 1.0, 0.1 // (mm) + //#define MANUAL_MOVE_DISTANCE_MM 500, 100, 50, 10, 1.0, 0.1 // (mm) + + // Manual move distances for INCH_MODE_SUPPORT + #define MANUAL_MOVE_DISTANCE_IN 0.100, 0.010, 0.001 // (in) + //#define MANUAL_MOVE_DISTANCE_IN 1.000, 0.500, 0.100, 0.010, 0.001 // (in) + //#define MANUAL_MOVE_DISTANCE_IN 5.000, 1.000, 0.500, 0.100, 0.010, 0.001 // (in) + + // Manual move distances for rotational axes + #define MANUAL_MOVE_DISTANCE_DEG 90, 45, 22.5, 5, 1 // (°) + + // BACK menu items keep the highlight at the top + //#define TURBO_BACK_MENU_ITEM + + // BACK menu items show "Back" instead of the previous menu name + //#define GENERIC_BACK_MENU_ITEM + + // Insert a menu for preheating at the top level to allow for quick access + //#define PREHEAT_SHORTCUT_MENU_ITEM + + // Add Configuration > Debug Menu > Endstop Test for endstop/probe/runout testing + //#define LCD_ENDSTOP_TEST + +#endif // HAS_MARLINUI_MENU + +#if HAS_DISPLAY + /** + * *** VENDORS PLEASE READ *** + * + * Marlin allows you to add a custom boot image for Graphical LCDs. + * With this option Marlin will first show your custom screen followed + * by the standard Marlin logo with version number and web URL. + * + * We encourage you to take advantage of this new feature and we also + * respectfully request that you retain the unmodified Marlin boot screen. + */ + #define SHOW_BOOTSCREEN // Show the Marlin bootscreen on startup. ** ENABLE FOR PRODUCTION ** + #if ENABLED(SHOW_BOOTSCREEN) + #define BOOTSCREEN_TIMEOUT 3000 // (ms) Total Duration to display the boot screen(s) + #if ANY(HAS_MARLINUI_U8GLIB, TFT_COLOR_UI) + #define BOOT_MARLIN_LOGO_SMALL // Show a smaller Marlin logo on the Boot Screen (saving lots of flash) + #endif + #if HAS_MARLINUI_U8GLIB + //#define BOOT_MARLIN_LOGO_ANIMATED // Animated Marlin logo. Costs ~3260 (or ~940) bytes of flash. + #endif + #if ANY(HAS_MARLINUI_U8GLIB, TOUCH_UI_FTDI_EVE, HAS_MARLINUI_HD44780) + //#define SHOW_CUSTOM_BOOTSCREEN // Show the bitmap in Marlin/_Bootscreen.h on startup. + #endif + #endif + + #if HAS_MARLINUI_U8GLIB + //#define CUSTOM_STATUS_SCREEN_IMAGE // Show the bitmap in Marlin/_Statusscreen.h on the status screen. + #endif + + //#define SOUND_MENU_ITEM // Add a mute option to the LCD menu + #define SOUND_ON_DEFAULT // Buzzer/speaker default enabled state + + #if ENABLED(U8GLIB_SSD1309) + //#define LCD_DOUBLE_BUFFER // Optimize display updates. Costs ~1K of SRAM. + #endif + + #if HAS_WIRED_LCD + //#define DOUBLE_LCD_FRAMERATE // Not recommended for slow boards. + #endif + + // The timeout to return to the status screen from sub-menus + //#define LCD_TIMEOUT_TO_STATUS 15000 // (ms) + + // Scroll a longer status message into view + //#define STATUS_MESSAGE_SCROLLING + + // Apply a timeout to low-priority status messages + //#define STATUS_MESSAGE_TIMEOUT_SEC 30 // (seconds) + + // On the Info Screen, display XY with one decimal place when possible + //#define LCD_DECIMAL_SMALL_XY + + // Show the E position (filament used) during printing + //#define LCD_SHOW_E_TOTAL + + // Display a negative temperature instead of "err" + //#define SHOW_TEMPERATURE_BELOW_ZERO + + /** + * LED Control Menu + * Add LED Control to the LCD menu + */ + //#define LED_CONTROL_MENU + #if ENABLED(LED_CONTROL_MENU) + #define LED_COLOR_PRESETS // Enable the Preset Color menu option + //#define NEO2_COLOR_PRESETS // Enable a second NeoPixel Preset Color menu option + #if ENABLED(LED_COLOR_PRESETS) + #define LED_USER_PRESET_RED 255 // User defined RED value + #define LED_USER_PRESET_GREEN 128 // User defined GREEN value + #define LED_USER_PRESET_BLUE 0 // User defined BLUE value + #define LED_USER_PRESET_WHITE 255 // User defined WHITE value + #define LED_USER_PRESET_BRIGHTNESS 255 // User defined intensity + //#define LED_USER_PRESET_STARTUP // Have the printer display the user preset color on startup + #endif + #if ENABLED(NEO2_COLOR_PRESETS) + #define NEO2_USER_PRESET_RED 255 // User defined RED value + #define NEO2_USER_PRESET_GREEN 128 // User defined GREEN value + #define NEO2_USER_PRESET_BLUE 0 // User defined BLUE value + #define NEO2_USER_PRESET_WHITE 255 // User defined WHITE value + #define NEO2_USER_PRESET_BRIGHTNESS 255 // User defined intensity + //#define NEO2_USER_PRESET_STARTUP // Have the printer display the user preset color on startup for the second strip + #endif + #endif + +#endif // HAS_DISPLAY + +// Some displays offer Feedrate / Flow editing. +#if ANY(HAS_MARLINUI_MENU, DWIN_CREALITY_LCD, DWIN_LCD_PROUI, MALYAN_LCD, TOUCH_SCREEN, ULTIPANEL_FEEDMULTIPLY) + #define SPEED_EDIT_MIN 10 // (%) Feedrate percentage edit range minimum + #define SPEED_EDIT_MAX 999 // (%) Feedrate percentage edit range maximum +#endif +#if ANY(HAS_MARLINUI_MENU, DWIN_CREALITY_LCD, DWIN_LCD_PROUI, MALYAN_LCD, TOUCH_SCREEN) + #define FLOW_EDIT_MIN 10 // (%) Flow percentage edit range minimum + #define FLOW_EDIT_MAX 999 // (%) Flow percentage edit range maximum +#endif + +// Add 'M73' to set print job progress, overrides Marlin's built-in estimate +//#define SET_PROGRESS_MANUALLY +#if ENABLED(SET_PROGRESS_MANUALLY) + #define SET_PROGRESS_PERCENT // Add 'P' parameter to set percentage done + #define SET_REMAINING_TIME // Add 'R' parameter to set remaining time + //#define SET_INTERACTION_TIME // Add 'C' parameter to set time until next filament change or other user interaction + //#define M73_REPORT // Report M73 values to host + #if ALL(M73_REPORT, HAS_MEDIA) + #define M73_REPORT_SD_ONLY // Report only when printing from SD + #endif +#endif + +// LCD Print Progress options. Multiple times may be displayed in turn. +#if HAS_DISPLAY && ANY(HAS_MEDIA, SET_PROGRESS_MANUALLY) + #define SHOW_PROGRESS_PERCENT // Show print progress percentage (doesn't affect progress bar) + #define SHOW_ELAPSED_TIME // Display elapsed printing time (prefix 'E') + //#define SHOW_REMAINING_TIME // Display estimated time to completion (prefix 'R') + #if ENABLED(SET_INTERACTION_TIME) + #define SHOW_INTERACTION_TIME // Display time until next user interaction ('C' = filament change) + #endif + //#define PRINT_PROGRESS_SHOW_DECIMALS // Show/report progress with decimal digits, not all UIs support this + + #if ANY(HAS_MARLINUI_HD44780, IS_TFTGLCD_PANEL) + //#define LCD_PROGRESS_BAR // Show a progress bar on HD44780 LCDs for SD printing + #if ENABLED(LCD_PROGRESS_BAR) + #define PROGRESS_BAR_BAR_TIME 2000 // (ms) Amount of time to show the bar + #define PROGRESS_BAR_MSG_TIME 3000 // (ms) Amount of time to show the status message + #define PROGRESS_MSG_EXPIRE 0 // (ms) Amount of time to retain the status message (0=forever) + //#define PROGRESS_MSG_ONCE // Show the message for MSG_TIME then clear it + //#define LCD_PROGRESS_BAR_TEST // Add a menu item to test the progress bar + #endif + #endif +#endif + +#if HAS_MEDIA + /** + * SD Card SPI Speed + * May be required to resolve "volume init" errors. + * + * Enable and set to SPI_HALF_SPEED, SPI_QUARTER_SPEED, or SPI_EIGHTH_SPEED + * otherwise full speed will be applied. + * + * :['SPI_HALF_SPEED', 'SPI_QUARTER_SPEED', 'SPI_EIGHTH_SPEED'] + */ + //#define SD_SPI_SPEED SPI_HALF_SPEED + + // The standard SD detect circuit reads LOW when media is inserted and HIGH when empty. + // Enable this option and set to HIGH if your SD cards are incorrectly detected. + //#define SD_DETECT_STATE HIGH + + //#define SD_IGNORE_AT_STARTUP // Don't mount the SD card when starting up + //#define SDCARD_READONLY // Read-only SD card (to save over 2K of flash) + + //#define GCODE_REPEAT_MARKERS // Enable G-code M808 to set repeat markers and do looping + + #define SD_PROCEDURE_DEPTH 1 // Increase if you need more nested M32 calls + + #define SD_FINISHED_STEPPERRELEASE true // Disable steppers when SD Print is finished + #define SD_FINISHED_RELEASECOMMAND "M84" // Use "M84XYE" to keep Z enabled so your bed stays in place + + // Reverse SD sort to show "more recent" files first, according to the card's FAT. + // Since the FAT gets out of order with usage, SDCARD_SORT_ALPHA is recommended. + #define SDCARD_RATHERRECENTFIRST + + #define SD_MENU_CONFIRM_START // Confirm the selected SD file before printing + + //#define NO_SD_AUTOSTART // Remove auto#.g file support completely to save some Flash, SRAM + //#define MENU_ADDAUTOSTART // Add a menu option to run auto#.g files + + //#define ONE_CLICK_PRINT // Prompt to print the newest file on inserted media + //#define BROWSE_MEDIA_ON_INSERT // Open the file browser when media is inserted + + //#define MEDIA_MENU_AT_TOP // Force the media menu to be listed on the top of the main menu + + #define EVENT_GCODE_SD_ABORT "G28XY" // G-code to run on SD Abort Print (e.g., "G28XY" or "G27") + + #if ENABLED(PRINTER_EVENT_LEDS) + #define PE_LEDS_COMPLETED_TIME (30*60) // (seconds) Time to keep the LED "done" color before restoring normal illumination + #endif + + /** + * Continue after Power-Loss (Creality3D) + * + * Store the current state to the SD Card at the start of each layer + * during SD printing. If the recovery file is found at boot time, present + * an option on the LCD screen to continue the print from the last-known + * point in the file. + */ + //#define POWER_LOSS_RECOVERY + #if ENABLED(POWER_LOSS_RECOVERY) + #define PLR_ENABLED_DEFAULT false // Power-Loss Recovery enabled by default. (Set with 'M413 Sn' & M500) + //#define PLR_BED_THRESHOLD BED_MAXTEMP // (°C) Skip user confirmation at or above this bed temperature (0 to disable) + + //#define POWER_LOSS_PIN 44 // Pin to detect power-loss. Set to -1 to disable default pin on boards without module, or comment to use board default. + //#define POWER_LOSS_STATE HIGH // State of pin indicating power-loss + //#define POWER_LOSS_PULLUP // Set pullup / pulldown as appropriate for your sensor + //#define POWER_LOSS_PULLDOWN + + //#define POWER_LOSS_ZRAISE 2 // (mm) Z axis raise on resume (on power-loss with UPS) + //#define POWER_LOSS_PURGE_LEN 20 // (mm) Length of filament to purge on resume + + // Without a POWER_LOSS_PIN the following option helps reduce wear on the SD card, + // especially with "vase mode" printing. Set too high and vases cannot be continued. + #define POWER_LOSS_MIN_Z_CHANGE 0.05 // (mm) Minimum Z change before saving power-loss data + + //#define BACKUP_POWER_SUPPLY // Backup power / UPS to move the steppers on power-loss + #if ENABLED(BACKUP_POWER_SUPPLY) + //#define POWER_LOSS_RETRACT_LEN 10 // (mm) Length of filament to retract on fail + #endif + + // Enable if Z homing is needed for proper recovery. 99.9% of the time this should be disabled! + //#define POWER_LOSS_RECOVER_ZHOME + #if ENABLED(POWER_LOSS_RECOVER_ZHOME) + //#define POWER_LOSS_ZHOME_POS { 0, 0 } // Safe XY position to home Z while avoiding objects on the bed + #endif + #endif + + /** + * Sort SD file listings in alphabetical order. + * + * With this option enabled, items on SD cards will be sorted + * by name for easier navigation. + * + * By default... + * + * - Use the slowest -but safest- method for sorting. + * - Folders are sorted to the top. + * - The sort key is statically allocated. + * - No added G-code (M34) support. + * - 40 item sorting limit. (Items after the first 40 are unsorted.) + * + * SD sorting uses static allocation (as set by SDSORT_LIMIT), allowing the + * compiler to calculate the worst-case usage and throw an error if the SRAM + * limit is exceeded. + * + * - SDSORT_USES_RAM provides faster sorting via a static directory buffer. + * - SDSORT_USES_STACK does the same, but uses a local stack-based buffer. + * - SDSORT_CACHE_NAMES will retain the sorted file listing in RAM. (Expensive!) + * - SDSORT_DYNAMIC_RAM only uses RAM when the SD menu is visible. (Use with caution!) + */ + //#define SDCARD_SORT_ALPHA + + // SD Card Sorting options + #if ENABLED(SDCARD_SORT_ALPHA) + #define SDSORT_REVERSE false // Default to sorting file names in reverse order. + #define SDSORT_LIMIT 40 // Maximum number of sorted items (10-256). Costs 27 bytes each. + #define SDSORT_FOLDERS -1 // -1=above 0=none 1=below + #define SDSORT_GCODE false // Enable G-code M34 to set sorting behaviors: M34 S<-1|0|1> F<-1|0|1> + #define SDSORT_USES_RAM false // Pre-allocate a static array for faster pre-sorting. + #define SDSORT_USES_STACK false // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.) + #define SDSORT_CACHE_NAMES false // Keep sorted items in RAM longer for speedy performance. Most expensive option. + #define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! + #define SDSORT_CACHE_VFATS 2 // Maximum number of 13-byte VFAT entries to use for sorting. + // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM. + #endif + + // Allow international symbols in long filenames. To display correctly, the + // LCD's font must contain the characters. Check your selected LCD language. + //#define UTF_FILENAME_SUPPORT + + //#define LONG_FILENAME_HOST_SUPPORT // Get the long filename of a file/folder with 'M33 ' and list long filenames with 'M20 L' + //#define LONG_FILENAME_WRITE_SUPPORT // Create / delete files with long filenames via M28, M30, and Binary Transfer Protocol + //#define M20_TIMESTAMP_SUPPORT // Include timestamps by adding the 'T' flag to M20 commands + + //#define SCROLL_LONG_FILENAMES // Scroll long filenames in the SD card menu + + //#define SD_ABORT_NO_COOLDOWN // Leave the heaters on after Stop Print (not recommended!) + + /** + * Abort SD printing when any endstop is triggered. + * This feature is enabled with 'M540 S1' or from the LCD menu. + * Endstops must be activated for this option to work. + */ + //#define SD_ABORT_ON_ENDSTOP_HIT + #if ENABLED(SD_ABORT_ON_ENDSTOP_HIT) + //#define SD_ABORT_ON_ENDSTOP_HIT_GCODE "G28XY" // G-code to run on endstop hit (e.g., "G28XY" or "G27") + #endif + + //#define SD_REPRINT_LAST_SELECTED_FILE // On print completion open the LCD Menu and select the same file + + //#define AUTO_REPORT_SD_STATUS // Auto-report media status with 'M27 S' + + /** + * Support for USB thumb drives using an Arduino USB Host Shield or + * equivalent MAX3421E breakout board. The USB thumb drive will appear + * to Marlin as an SD card. + * + * The MAX3421E can be assigned the same pins as the SD card reader, with + * the following pin mapping: + * + * SCLK, MOSI, MISO --> SCLK, MOSI, MISO + * INT --> SD_DETECT_PIN [1] + * SS --> SD_SS_PIN + * + * [1] On AVR an interrupt-capable pin is best for UHS3 compatibility. + */ + //#define USB_FLASH_DRIVE_SUPPORT + #if ENABLED(USB_FLASH_DRIVE_SUPPORT) + /** + * USB Host Shield Library + * + * - UHS2 uses no interrupts and has been production-tested + * on a LulzBot TAZ Pro with a 32-bit Archim board. + * + * - UHS3 is newer code with better USB compatibility. But it + * is less tested and is known to interfere with Servos. + * [1] This requires USB_INTR_PIN to be interrupt-capable. + */ + //#define USE_UHS2_USB + //#define USE_UHS3_USB + + #define DISABLE_DUE_SD_MMC // Disable USB Host access to USB Drive to prevent hangs on block access for DUE platform + + /** + * Native USB Host supported by some boards (USB OTG) + */ + //#define USE_OTG_USB_HOST + + #if DISABLED(USE_OTG_USB_HOST) + #define USB_CS_PIN SD_SS_PIN + #define USB_INTR_PIN SD_DETECT_PIN + #endif + #endif + + /** + * When using a bootloader that supports SD-Firmware-Flashing, + * add a menu item to activate SD-FW-Update on the next reboot. + * + * Requires ATMEGA2560 (Arduino Mega) + * + * Tested with this bootloader: + * https://github.com/FleetProbe/MicroBridge-Arduino-ATMega2560 + */ + //#define SD_FIRMWARE_UPDATE + #if ENABLED(SD_FIRMWARE_UPDATE) + #define SD_FIRMWARE_UPDATE_EEPROM_ADDR 0x1FF + #define SD_FIRMWARE_UPDATE_ACTIVE_VALUE 0xF0 + #define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF + #endif + + /** + * Enable this option if you have more than ~3K of unused flash space. + * Marlin will embed all settings in the firmware binary as compressed data. + * Use 'M503 C' to write the settings out to the SD Card as 'mc.zip'. + * See docs/ConfigEmbedding.md for details on how to use 'mc-apply.py'. + */ + //#define CONFIGURATION_EMBEDDING + + // Add an optimized binary file transfer mode, initiated with 'M28 B1' + //#define BINARY_FILE_TRANSFER + + #if ENABLED(BINARY_FILE_TRANSFER) + // Include extra facilities (e.g., 'M20 F') supporting firmware upload via BINARY_FILE_TRANSFER + //#define CUSTOM_FIRMWARE_UPLOAD + #endif + + // "Over-the-air" Firmware Update with M936 - Required to set EEPROM flag + //#define OTA_FIRMWARE_UPDATE + + /** + * Set this option to one of the following (or the board's defaults apply): + * + * LCD - Use the SD drive in the external LCD controller. + * ONBOARD - Use the SD drive on the control board. + * CUSTOM_CABLE - Use a custom cable to access the SD (as defined in a pins file). + * + * :[ 'LCD', 'ONBOARD', 'CUSTOM_CABLE' ] + */ + //#define SDCARD_CONNECTION LCD + + // Enable if SD detect is rendered useless (e.g., by using an SD extender) + //#define NO_SD_DETECT + + /** + * Multiple volume support - EXPERIMENTAL. + * Adds 'M21 Pm' / 'M21 S' / 'M21 U' to mount SD Card / USB Drive. + */ + //#define MULTI_VOLUME + #if ENABLED(MULTI_VOLUME) + #define VOLUME_SD_ONBOARD + #define VOLUME_USB_FLASH_DRIVE + #define DEFAULT_VOLUME SD_ONBOARD // :[ 'SD_ONBOARD', 'USB_FLASH_DRIVE' ] + #define DEFAULT_SHARED_VOLUME USB_FLASH_DRIVE // :[ 'SD_ONBOARD', 'USB_FLASH_DRIVE' ] + #endif + +#endif // HAS_MEDIA + +/** + * By default an onboard SD card reader may be shared as a USB mass- + * storage device. This option hides the SD card from the host PC. + */ +//#define NO_SD_HOST_DRIVE // Disable SD Card access over USB (for security). + +/** + * Additional options for Graphical Displays + * + * Use the optimizations here to improve printing performance, + * which can be adversely affected by graphical display drawing, + * especially when doing several short moves, and when printing + * on DELTA and SCARA machines. + * + * Some of these options may result in the display lagging behind + * controller events, as there is a trade-off between reliable + * printing performance versus fast display updates. + */ +#if HAS_MARLINUI_U8GLIB + // Save many cycles by drawing a hollow frame or no frame on the Info Screen + //#define XYZ_NO_FRAME + #define XYZ_HOLLOW_FRAME + + // A bigger font is available for edit items. Costs 3120 bytes of flash. + // Western only. Not available for Cyrillic, Kana, Turkish, Greek, or Chinese. + //#define USE_BIG_EDIT_FONT + + // A smaller font may be used on the Info Screen. Costs 2434 bytes of flash. + // Western only. Not available for Cyrillic, Kana, Turkish, Greek, or Chinese. + //#define USE_SMALL_INFOFONT + + /** + * ST7920-based LCDs can emulate a 16 x 4 character display using + * the ST7920 character-generator for very fast screen updates. + * Enable LIGHTWEIGHT_UI to use this special display mode. + * + * Since LIGHTWEIGHT_UI has limited space, the position and status + * message occupy the same line. Set STATUS_EXPIRE_SECONDS to the + * length of time to display the status message before clearing. + * + * Set STATUS_EXPIRE_SECONDS to zero to never clear the status. + * This will prevent position updates from being displayed. + */ + #if IS_U8GLIB_ST7920 + // Enable this option and reduce the value to optimize screen updates. + // The normal delay is 10µs. Use the lowest value that still gives a reliable display. + //#define DOGM_SPI_DELAY_US 5 // (µs) Delay after each SPI transfer + + //#define LIGHTWEIGHT_UI + #if ENABLED(LIGHTWEIGHT_UI) + #define STATUS_EXPIRE_SECONDS 20 + #endif + #endif + + /** + * Status (Info) Screen customization + * These options may affect code size and screen render time. + * Custom status screens can forcibly override these settings. + */ + //#define STATUS_COMBINE_HEATERS // Use combined heater images instead of separate ones + //#define STATUS_HOTEND_NUMBERLESS // Use plain hotend icons instead of numbered ones (with 2+ hotends) + #define STATUS_HOTEND_INVERTED // Show solid nozzle bitmaps when heating (Requires STATUS_HOTEND_ANIM for numbered hotends) + #define STATUS_HOTEND_ANIM // Use a second bitmap to indicate hotend heating + #define STATUS_BED_ANIM // Use a second bitmap to indicate bed heating + #define STATUS_CHAMBER_ANIM // Use a second bitmap to indicate chamber heating + //#define STATUS_CUTTER_ANIM // Use a second bitmap to indicate spindle / laser active + //#define STATUS_COOLER_ANIM // Use a second bitmap to indicate laser cooling + //#define STATUS_FLOWMETER_ANIM // Use multiple bitmaps to indicate coolant flow + //#define STATUS_ALT_BED_BITMAP // Use the alternative bed bitmap + //#define STATUS_ALT_FAN_BITMAP // Use the alternative fan bitmap + //#define STATUS_FAN_FRAMES 3 // :[0,1,2,3,4] Number of fan animation frames + + // Only one STATUS_HEAT_* option can be enabled + //#define STATUS_HEAT_PERCENT // Show heating in a progress bar + //#define STATUS_HEAT_POWER // Show heater output power as a vertical bar + +#endif // HAS_MARLINUI_U8GLIB + +#if HAS_MARLINUI_U8GLIB || IS_DWIN_MARLINUI + #define MENU_HOLLOW_FRAME // Enable to save many cycles by drawing a hollow frame on Menu Screens + //#define OVERLAY_GFX_REVERSE // Swap the CW/CCW indicators in the graphics overlay + + // Frivolous Game Options + //#define MARLIN_BRICKOUT + //#define MARLIN_INVADERS + //#define MARLIN_SNAKE + //#define GAMES_EASTER_EGG // Add extra blank lines above the "Games" sub-menu +#endif + +// +// Additional options for DGUS / DWIN displays +// +#if HAS_DGUS_LCD + #define LCD_BAUDRATE 115200 + + #define DGUS_RX_BUFFER_SIZE 128 + #define DGUS_TX_BUFFER_SIZE 48 + //#define SERIAL_STATS_RX_BUFFER_OVERRUNS // Fix Rx overrun situation (Currently only for AVR) + + #define DGUS_UPDATE_INTERVAL_MS 500 // (ms) Interval between automatic screen updates + + #if DGUS_UI_IS(FYSETC, MKS, HIPRECY) + #define DGUS_PRINT_FILENAME // Display the filename during printing + #define DGUS_PREHEAT_UI // Display a preheat screen during heatup + + #if DGUS_UI_IS(FYSETC, MKS) + //#define DGUS_UI_MOVE_DIS_OPTION // Disabled by default for FYSETC and MKS + #else + #define DGUS_UI_MOVE_DIS_OPTION // Enabled by default for UI_HIPRECY + #endif + + #define DGUS_FILAMENT_LOADUNLOAD + #if ENABLED(DGUS_FILAMENT_LOADUNLOAD) + #define DGUS_FILAMENT_PURGE_LENGTH 10 + #define DGUS_FILAMENT_LOAD_LENGTH_PER_TIME 0.5 // (mm) Adjust in proportion to DGUS_UPDATE_INTERVAL_MS + #endif + + #define DGUS_UI_WAITING // Show a "waiting" screen between some screens + #if ENABLED(DGUS_UI_WAITING) + #define DGUS_UI_WAITING_STATUS 10 + #define DGUS_UI_WAITING_STATUS_PERIOD 8 // Increase to slower waiting status looping + #endif + + #elif DGUS_UI_IS(E3S1PRO) + /** + * The stock Ender-3 S1 Pro/Plus display firmware has rather poor SD file handling. + * + * The autoscroll is mainly useful for status messages, filenames, and the "About" page. + * + * NOTE: The Advanced SD Card option is affected by the stock touchscreen firmware, so + * pages 5 and up will display "4/4". This may get fixed in a screen firmware update. + */ + #define DGUS_SOFTWARE_AUTOSCROLL // Enable long text software auto-scroll + #define DGUS_AUTOSCROLL_START_CYCLES 1 // Refresh cycles without scrolling at the beginning of text strings + #define DGUS_AUTOSCROLL_END_CYCLES 1 // ... at the end of text strings + + #define DGUS_ADVANCED_SDCARD // Allow more than 20 files and navigating directories + #define DGUS_USERCONFIRM // Reuse the SD Card page to show various messages + #endif +#endif // HAS_DGUS_LCD + +// +// Additional options for AnyCubic Chiron TFT displays +// +#if ENABLED(ANYCUBIC_LCD_CHIRON) + // By default the type of panel is automatically detected. + // Enable one of these options if you know the panel type. + //#define CHIRON_TFT_STANDARD + //#define CHIRON_TFT_NEW + + // Enable the longer Anycubic powerup startup tune + //#define AC_DEFAULT_STARTUP_TUNE + + /** + * Display Folders + * By default the file browser lists all G-code files (including those in subfolders) in a flat list. + * Enable this option to display a hierarchical file browser. + * + * NOTES: + * - Without this option it helps to enable SDCARD_SORT_ALPHA so files are sorted before/after folders. + * - When used with the "new" panel, folder names will also have '.gcode' appended to their names. + * This hack is currently required to force the panel to show folders. + */ + #define AC_SD_FOLDER_VIEW +#endif + +// +// Specify additional languages for the UI. Default specified by LCD_LANGUAGE. +// +#if ANY(DOGLCD, TFT_COLOR_UI, TOUCH_UI_FTDI_EVE, IS_DWIN_MARLINUI, ANYCUBIC_LCD_VYPER) + //#define LCD_LANGUAGE_2 fr + //#define LCD_LANGUAGE_3 de + //#define LCD_LANGUAGE_4 es + //#define LCD_LANGUAGE_5 it + #ifdef LCD_LANGUAGE_2 + //#define LCD_LANGUAGE_AUTO_SAVE // Automatically save language to EEPROM on change + #endif +#endif + +// +// Touch UI for the FTDI Embedded Video Engine (EVE) +// +#if ENABLED(TOUCH_UI_FTDI_EVE) + // Display board used + //#define LCD_FTDI_VM800B35A // FTDI 3.5" with FT800 (320x240) + //#define LCD_4DSYSTEMS_4DLCD_FT843 // 4D Systems 4.3" (480x272) + //#define LCD_HAOYU_FT800CB // Haoyu with 4.3" or 5" (480x272) + //#define LCD_HAOYU_FT810CB // Haoyu with 5" (800x480) + //#define LCD_LULZBOT_CLCD_UI // LulzBot Color LCD UI + //#define LCD_FYSETC_TFT81050 // FYSETC with 5" (800x480) + //#define LCD_EVE3_50G // Matrix Orbital 5.0", 800x480, BT815 + //#define LCD_EVE2_50G // Matrix Orbital 5.0", 800x480, FT813 + + // Correct the resolution if not using the stock TFT panel. + //#define TOUCH_UI_320x240 + //#define TOUCH_UI_480x272 + //#define TOUCH_UI_800x480 + + // Mappings for boards with a standard RepRapDiscount Display connector + //#define AO_EXP1_PINMAP // LulzBot CLCD UI EXP1 mapping + //#define AO_EXP2_PINMAP // LulzBot CLCD UI EXP2 mapping + //#define CR10_TFT_PINMAP // Rudolph Riedel's CR10 pin mapping + //#define S6_TFT_PINMAP // FYSETC S6 pin mapping + //#define F6_TFT_PINMAP // FYSETC F6 pin mapping + + //#define OTHER_PIN_LAYOUT // Define pins manually below + #if ENABLED(OTHER_PIN_LAYOUT) + // Pins for CS and MOD_RESET (PD) must be chosen + #define CLCD_MOD_RESET 9 + #define CLCD_SPI_CS 10 + + // If using software SPI, specify pins for SCLK, MOSI, MISO + //#define CLCD_USE_SOFT_SPI + #if ENABLED(CLCD_USE_SOFT_SPI) + #define CLCD_SOFT_SPI_MOSI 11 + #define CLCD_SOFT_SPI_MISO 12 + #define CLCD_SOFT_SPI_SCLK 13 + #endif + #endif + + // Display Orientation. An inverted (i.e. upside-down) display + // is supported on the FT800. The FT810 and beyond also support + // portrait and mirrored orientations. + //#define TOUCH_UI_INVERTED + //#define TOUCH_UI_PORTRAIT + //#define TOUCH_UI_MIRRORED + + // UTF8 processing and rendering. + // Unsupported characters are shown as '?'. + //#define TOUCH_UI_USE_UTF8 + #if ENABLED(TOUCH_UI_USE_UTF8) + // Western accents support. These accented characters use + // combined bitmaps and require relatively little storage. + #define TOUCH_UI_UTF8_WESTERN_CHARSET + #if ENABLED(TOUCH_UI_UTF8_WESTERN_CHARSET) + // Additional character groups. These characters require + // full bitmaps and take up considerable storage: + //#define TOUCH_UI_UTF8_SUPERSCRIPTS // ¹ ² ³ + //#define TOUCH_UI_UTF8_COPYRIGHT // © ® + //#define TOUCH_UI_UTF8_GERMANIC // ß + //#define TOUCH_UI_UTF8_SCANDINAVIAN // Æ Ð Ø Þ æ ð ø þ + //#define TOUCH_UI_UTF8_PUNCTUATION // « » ¿ ¡ + //#define TOUCH_UI_UTF8_CURRENCY // ¢ £ ¤ ¥ + //#define TOUCH_UI_UTF8_ORDINALS // º ª + //#define TOUCH_UI_UTF8_MATHEMATICS // ± × ÷ + //#define TOUCH_UI_UTF8_FRACTIONS // ¼ ½ ¾ + //#define TOUCH_UI_UTF8_SYMBOLS // µ ¶ ¦ § ¬ + #endif + + // Cyrillic character set, costs about 27KiB of flash + //#define TOUCH_UI_UTF8_CYRILLIC_CHARSET + #endif + + // Use a smaller font when labels don't fit buttons + #define TOUCH_UI_FIT_TEXT + + // Use a numeric passcode for "Screen lock" keypad. + // (recommended for smaller displays) + //#define TOUCH_UI_PASSCODE + + // Output extra debug info for Touch UI events + //#define TOUCH_UI_DEBUG + + // Developer menu (accessed by touching "About Printer" copyright text) + //#define TOUCH_UI_DEVELOPER_MENU +#endif // TOUCH_UI_FTDI_EVE + +// +// Classic UI Options +// +#if TFT_SCALED_DOGLCD + //#define TFT_MARLINUI_COLOR 0xFFFF // White + //#define TFT_MARLINBG_COLOR 0x0000 // Black + //#define TFT_DISABLED_COLOR 0x0003 // Almost black + //#define TFT_BTCANCEL_COLOR 0xF800 // Red + //#define TFT_BTARROWS_COLOR 0xDEE6 // 11011 110111 00110 Yellow + //#define TFT_BTOKMENU_COLOR 0x145F // 00010 100010 11111 Cyan +#endif + +/** + * Display Sleep + * Enable this option to save energy and prevent OLED pixel burn-in. + */ +//#define DISPLAY_SLEEP_MINUTES 2 // (minutes) Timeout before turning off the screen + +/** + * LCD Backlight Timeout + * Requires a display with a controllable backlight + */ +//#define LCD_BACKLIGHT_TIMEOUT_MINS 1 // (minutes) Timeout before turning off the backlight + +#if defined(DISPLAY_SLEEP_MINUTES) || defined(LCD_BACKLIGHT_TIMEOUT_MINS) + #define EDITABLE_DISPLAY_TIMEOUT // Edit sleep / backlight timeout with M255 S and a menu item +#endif + +// +// ADC Button Debounce +// +#if HAS_ADC_BUTTONS + #define ADC_BUTTON_DEBOUNCE_DELAY 16 // (count) Increase if buttons bounce or repeat too fast +#endif + +//#define FAST_BUTTON_POLLING // Poll buttons at ~1kHz on 8-bit AVR. Set to 'false' for slow polling on 32-bit. + +// @section safety + +/** + * The watchdog hardware timer will do a reset and disable all outputs + * if the firmware gets too overloaded to read the temperature sensors. + * + * If you find that watchdog reboot causes your AVR board to hang forever, + * enable WATCHDOG_RESET_MANUAL to use a custom timer instead of WDTO. + * NOTE: This method is less reliable as it can only catch hangups while + * interrupts are enabled. + */ +#define USE_WATCHDOG +#if ENABLED(USE_WATCHDOG) + //#define WATCHDOG_RESET_MANUAL +#endif + +// @section lcd + +/** + * Babystepping enables movement of the axes by tiny increments without changing + * the current position values. This feature is used primarily to adjust the Z + * axis in the first layer of a print in real-time. + * + * Warning: Does not respect endstops! + */ +//#define BABYSTEPPING +#if ENABLED(BABYSTEPPING) + //#define EP_BABYSTEPPING // M293/M294 babystepping with EMERGENCY_PARSER support + //#define BABYSTEP_WITHOUT_HOMING + //#define BABYSTEP_ALWAYS_AVAILABLE // Allow babystepping at all times (not just during movement) + //#define BABYSTEP_XY // Also enable X/Y Babystepping. Not supported on DELTA! + //#define BABYSTEP_INVERT_Z // Enable if Z babysteps should go the other way + //#define BABYSTEP_MILLIMETER_UNITS // Specify BABYSTEP_MULTIPLICATOR_(XY|Z) in mm instead of micro-steps + #define BABYSTEP_MULTIPLICATOR_Z 1 // (steps or mm) Steps or millimeter distance for each Z babystep + #define BABYSTEP_MULTIPLICATOR_XY 1 // (steps or mm) Steps or millimeter distance for each XY babystep + + //#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen for Z Babystepping. + #if ENABLED(DOUBLECLICK_FOR_Z_BABYSTEPPING) + #define DOUBLECLICK_MAX_INTERVAL 1250 // (ms) Maximum interval between clicks. + // Note: Extra time may be added to mitigate controller latency. + //#define MOVE_Z_WHEN_IDLE // Jump to the move Z menu on double-click when printer is idle. + #if ENABLED(MOVE_Z_WHEN_IDLE) + #define MOVE_Z_IDLE_MULTIPLICATOR 1 // Multiply 1mm by this factor for the move step size. + #endif + #endif + + //#define BABYSTEP_DISPLAY_TOTAL // Display total babysteps since last G28 + + //#define BABYSTEP_ZPROBE_OFFSET // Combine M851 Z and Babystepping + #if ENABLED(BABYSTEP_ZPROBE_OFFSET) + //#define BABYSTEP_HOTEND_Z_OFFSET // For multiple hotends, babystep relative Z offsets + //#define BABYSTEP_GFX_OVERLAY // Enable graphical overlay on Z-offset editor + #endif +#endif + +// @section extruder + +/** + * Linear Pressure Control v1.5 + * + * Assumption: advance [steps] = k * (delta velocity [steps/s]) + * K=0 means advance disabled. + * + * NOTE: K values for LIN_ADVANCE 1.5 differ from earlier versions! + * + * Set K around 0.22 for 3mm PLA Direct Drive with ~6.5cm between the drive gear and heatbreak. + * Larger K values will be needed for flexible filament and greater distances. + * If this algorithm produces a higher speed offset than the extruder can handle (compared to E jerk) + * print acceleration will be reduced during the affected moves to keep within the limit. + * + * See https://marlinfw.org/docs/features/lin_advance.html for full instructions. + */ +//#define LIN_ADVANCE +#if ENABLED(LIN_ADVANCE) + #if ENABLED(DISTINCT_E_FACTORS) + #define ADVANCE_K { 0.22 } // (mm) Compression length per 1mm/s extruder speed, per extruder + #else + #define ADVANCE_K 0.22 // (mm) Compression length applying to all extruders + #endif + //#define ADVANCE_K_EXTRA // Add a second linear advance constant, configurable with M900 L. + //#define LA_DEBUG // Print debug information to serial during operation. Disable for production use. + //#define EXPERIMENTAL_I2S_LA // Allow I2S_STEPPER_STREAM to be used with LA. Performance degrades as the LA step rate reaches ~20kHz. + + //#define SMOOTH_LIN_ADVANCE // Remove limits on acceleration by gradual increase of nozzle pressure + #if ENABLED(SMOOTH_LIN_ADVANCE) + /** + * ADVANCE_TAU is also the time ahead that the smoother needs to look + * into the planner, so the planner needs to have enough blocks loaded. + * For k=0.04 at 10k acceleration and an "Orbiter 2" extruder it can be as low as 0.0075. + * Adjust by lowering the value until you observe the extruder skipping, then raise slightly. + * Higher k and higher XY acceleration may require larger ADVANCE_TAU to avoid skipping steps. + */ + #if ENABLED(DISTINCT_E_FACTORS) + #define ADVANCE_TAU { 0.02 } // (s) Smoothing time to reduce extruder acceleration, per extruder + #else + #define ADVANCE_TAU 0.02 // (s) Smoothing time to reduce extruder acceleration + #endif + #define SMOOTH_LIN_ADV_HZ 1000 // (Hz) How often to update extruder speed + #define INPUT_SHAPING_E_SYNC // Synchronize the extruder-shaped XY axes (to increase precision) + #endif +#endif + +/** + * Nonlinear Extrusion Control + * + * Control extrusion rate based on instantaneous extruder velocity. Can be used to correct for + * underextrusion at high extruder speeds that are otherwise well-behaved (i.e., not skipping). + * For better results also enable ADAPTIVE_STEP_SMOOTHING. + */ +//#define NONLINEAR_EXTRUSION +#if ENABLED(NONLINEAR_EXTRUSION) + //#define NONLINEAR_EXTRUSION_DEFAULT_ON // Enable if NLE should be ON by default +#endif + +// @section leveling + +/** + * Use Safe Bed Leveling coordinates to move axes to a useful position before bed probing. + * For example, after homing a rotational axis the Z probe might not be perpendicular to the bed. + * Choose values the orient the bed horizontally and the Z-probe vertically. + */ +//#define SAFE_BED_LEVELING_START_X 0.0 +//#define SAFE_BED_LEVELING_START_Y 0.0 +//#define SAFE_BED_LEVELING_START_Z 0.0 +//#define SAFE_BED_LEVELING_START_I 0.0 +//#define SAFE_BED_LEVELING_START_J 0.0 +//#define SAFE_BED_LEVELING_START_K 0.0 +//#define SAFE_BED_LEVELING_START_U 0.0 +//#define SAFE_BED_LEVELING_START_V 0.0 +//#define SAFE_BED_LEVELING_START_W 0.0 + +/** + * Points to probe for all 3-point Leveling procedures. + * Override if the automatically selected points are inadequate. + */ +#if NEEDS_THREE_PROBE_POINTS + //#define PROBE_PT_1 { 15, 180 } // (mm) { x, y } + //#define PROBE_PT_2 { 15, 20 } + //#define PROBE_PT_3 { 170, 20 } +#endif + +/** + * Probing Margins + * + * Override PROBING_MARGIN for each side of the build plate + * Useful to get probe points to exact positions on targets or + * to allow leveling to avoid plate clamps on only specific + * sides of the bed. With NOZZLE_AS_PROBE negative values are + * allowed, to permit probing outside the bed. + * + * If you are replacing the prior *_PROBE_BED_POSITION options, + * LEFT and FRONT values in most cases will map directly over + * RIGHT and REAR would be the inverse such as + * (X/Y_BED_SIZE - RIGHT/BACK_PROBE_BED_POSITION) + * + * This will allow all positions to match at compilation, however + * should the probe position be modified with M851XY then the + * probe points will follow. This prevents any change from causing + * the probe to be unable to reach any points. + */ +#if PROBE_SELECTED && !IS_KINEMATIC + //#define PROBING_MARGIN_LEFT PROBING_MARGIN + //#define PROBING_MARGIN_RIGHT PROBING_MARGIN + //#define PROBING_MARGIN_FRONT PROBING_MARGIN + //#define PROBING_MARGIN_BACK PROBING_MARGIN +#endif + +#if ANY(MESH_BED_LEVELING, AUTO_BED_LEVELING_UBL) + // Override the mesh area if the automatic (max) area is too large + //#define MESH_MIN_X MESH_INSET + //#define MESH_MIN_Y MESH_INSET + //#define MESH_MAX_X X_BED_SIZE - (MESH_INSET) + //#define MESH_MAX_Y Y_BED_SIZE - (MESH_INSET) +#endif + +#if ALL(AUTO_BED_LEVELING_UBL, EEPROM_SETTINGS) + //#define OPTIMIZED_MESH_STORAGE // Store mesh with less precision to save EEPROM space +#endif + +/** + * Repeatedly attempt G29 leveling until it succeeds. + * Stop after G29_MAX_RETRIES attempts. + */ +//#define G29_RETRY_AND_RECOVER +#if ENABLED(G29_RETRY_AND_RECOVER) + #define G29_MAX_RETRIES 3 + #define G29_HALT_ON_FAILURE + /** + * Specify the GCODE commands that will be executed when leveling succeeds, + * between attempts, and after the maximum number of retries have been tried. + */ + #define G29_SUCCESS_COMMANDS "M117 Bed leveling done." + #define G29_RECOVER_COMMANDS "M117 Probe failed. Rewiping.\nG28\nG12 P0 S12 T0" + #define G29_FAILURE_COMMANDS "M117 Bed leveling failed.\nG0 Z10\nM300 P25 S880\nM300 P50 S0\nM300 P25 S880\nM300 P50 S0\nM300 P25 S880\nM300 P50 S0\nG4 S1" + +#endif + +// @section probes + +/** + * Thermal Probe Compensation + * + * Adjust probe measurements to compensate for distortion associated with the temperature + * of the probe, bed, and/or hotend. + * Use G76 to automatically calibrate this feature for probe and bed temperatures. + * (Extruder temperature/offset values must be calibrated manually.) + * Use M871 to set temperature/offset values manually. + * For more details see https://marlinfw.org/docs/features/probe_temp_compensation.html + */ +//#define PTC_PROBE // Compensate based on probe temperature +//#define PTC_BED // Compensate based on bed temperature +//#define PTC_HOTEND // Compensate based on hotend temperature + +#if ANY(PTC_PROBE, PTC_BED, PTC_HOTEND) + /** + * If the probe is outside the defined range, use linear extrapolation with the closest + * point and the point with index PTC_LINEAR_EXTRAPOLATION. e.g., If set to 4 it will use the + * linear extrapolation between data[0] and data[4] for values below PTC_PROBE_START. + */ + //#define PTC_LINEAR_EXTRAPOLATION 4 + + #if ENABLED(PTC_PROBE) + // Probe temperature calibration generates a table of values starting at PTC_PROBE_START + // (e.g., 30), in steps of PTC_PROBE_RES (e.g., 5) with PTC_PROBE_COUNT (e.g., 10) samples. + #define PTC_PROBE_START 30 // (°C) + #define PTC_PROBE_RES 5 // (°C) + #define PTC_PROBE_COUNT 10 + #define PTC_PROBE_ZOFFS { 0 } // (µm) Z adjustments per sample + #endif + + #if ENABLED(PTC_BED) + // Bed temperature calibration builds a similar table. + #define PTC_BED_START 60 // (°C) + #define PTC_BED_RES 5 // (°C) + #define PTC_BED_COUNT 10 + #define PTC_BED_ZOFFS { 0 } // (µm) Z adjustments per sample + #endif + + #if ENABLED(PTC_HOTEND) + // Note: There is no automatic calibration for the hotend. Use M871. + #define PTC_HOTEND_START 180 // (°C) + #define PTC_HOTEND_RES 5 // (°C) + #define PTC_HOTEND_COUNT 20 + #define PTC_HOTEND_ZOFFS { 0 } // (µm) Z adjustments per sample + #endif + + // G76 options + #if ALL(PTC_PROBE, PTC_BED) + // Park position to wait for probe cooldown + #define PTC_PARK_POS { 0, 0, 100 } + + // Probe position to probe and wait for probe to reach target temperature + //#define PTC_PROBE_POS { 12.0f, 7.3f } // Example: MK52 magnetic heatbed + #define PTC_PROBE_POS { 90, 100 } + + // The temperature the probe should be at while taking measurements during + // bed temperature calibration. + #define PTC_PROBE_TEMP 30 // (°C) + + // Height above Z=0.0 to raise the nozzle. Lowering this can help the probe to heat faster. + // Note: The Z=0.0 offset is determined by the probe Z offset (e.g., as set with M851 Z). + #define PTC_PROBE_HEATING_OFFSET 0.5 // (mm) + #endif +#endif // PTC_PROBE || PTC_BED || PTC_HOTEND + +// @section extras + +// +// G60/G61 Position Save and Return +// +//#define SAVED_POSITIONS 1 // Each saved position slot costs 12 bytes + +// +// G2/G3 Arc Support +// +#define ARC_SUPPORT // Requires ~3226 bytes +#if ENABLED(ARC_SUPPORT) + #define MIN_ARC_SEGMENT_MM 0.1 // (mm) Minimum length of each arc segment + #define MAX_ARC_SEGMENT_MM 1.0 // (mm) Maximum length of each arc segment + #define MIN_CIRCLE_SEGMENTS 72 // Minimum number of segments in a complete circle + //#define ARC_SEGMENTS_PER_SEC 50 // Use the feedrate to choose the segment length + #define N_ARC_CORRECTION 25 // Number of interpolated segments between corrections + //#define ARC_P_CIRCLES // Enable the 'P' parameter to specify complete circles + //#define SF_ARC_FIX // Enable only if using SkeinForge with "Arc Point" fillet procedure +#endif + +// G5 Bézier Curve Support with XYZE destination and IJPQ offsets +//#define BEZIER_CURVE_SUPPORT // Requires ~2666 bytes + +#if ANY(ARC_SUPPORT, BEZIER_CURVE_SUPPORT) + //#define CNC_WORKSPACE_PLANES // Allow G2/G3/G5 to operate in XY, ZX, or YZ planes +#endif + +/** + * Direct Stepping + * + * Comparable to the method used by Klipper, G6 direct stepping significantly + * reduces motion calculations, increases top printing speeds, and results in + * less step aliasing by calculating all motions in advance. + * Preparing your G-code: https://github.com/colinrgodsey/step-daemon + */ +//#define DIRECT_STEPPING + +/** + * G38 Probe Target + * + * This option adds G38.2 and G38.3 (probe towards target) + * and optionally G38.4 and G38.5 (probe away from target). + * Set MULTIPLE_PROBING for G38 to probe more than once. + */ +//#define G38_PROBE_TARGET +#if ENABLED(G38_PROBE_TARGET) + //#define G38_PROBE_AWAY // Include G38.4 and G38.5 to probe away from target + #define G38_MINIMUM_MOVE 0.0275 // (mm) Minimum distance that will produce a move. +#endif + +// @section motion + +// Moves (or segments) with fewer steps than this will be joined with the next move +#define MIN_STEPS_PER_SEGMENT 6 + +/** + * Minimum delay before and after setting the stepper DIR (in ns) + * 0 : No delay (Expect at least 10µS since one Stepper ISR must transpire) + * 20 : Minimum for TMC2xxx drivers + * 200 : Minimum for A4988 drivers + * 400 : Minimum for A5984 drivers + * 500 : Minimum for LV8729 drivers (guess, no info in datasheet) + * 650 : Minimum for DRV8825 drivers + * 1500 : Minimum for TB6600 drivers (guess, no info in datasheet) + * 15000 : Minimum for TB6560 drivers (guess, no info in datasheet) + * + * Override the default value based on the driver type set in Configuration.h. + */ +//#define MINIMUM_STEPPER_POST_DIR_DELAY 650 +//#define MINIMUM_STEPPER_PRE_DIR_DELAY 650 + +/** + * Minimum stepper driver pulse width (in ns) + * If undefined, these defaults (from Conditionals-4-adv.h) apply: + * 100 : Minimum for TMC2xxx stepper drivers + * 500 : Minimum for LV8729 + * 1000 : Minimum for A4988 and A5984 stepper drivers + * 2000 : Minimum for DRV8825 stepper drivers + * 3000 : Minimum for TB6600 stepper drivers + * 30000 : Minimum for TB6560 stepper drivers + * + * Override the default value based on the driver type set in Configuration.h. + */ +//#define MINIMUM_STEPPER_PULSE_NS 2000 + +/** + * Maximum stepping rate (in Hz) the stepper driver allows + * If undefined, these defaults (from Conditionals-4-adv.h) apply: + * 5000000 : Maximum for TMC2xxx stepper drivers + * 1000000 : Maximum for LV8729 stepper driver + * 500000 : Maximum for A4988 stepper driver + * 250000 : Maximum for DRV8825 stepper driver + * 150000 : Maximum for TB6600 stepper driver + * 15000 : Maximum for TB6560 stepper driver + * + * Override the default value based on the driver type set in Configuration.h. + */ +//#define MAXIMUM_STEPPER_RATE 250000 + +// @section temperature + +// Control heater 0 and heater 1 in parallel. +//#define HEATERS_PARALLEL + +//=========================================================================== +//================================= Buffers ================================= +//=========================================================================== + +// @section gcode + +// The number of linear moves that can be in the planner at once. +#if ALL(HAS_MEDIA, DIRECT_STEPPING) + #define BLOCK_BUFFER_SIZE 8 +#elif HAS_MEDIA + #define BLOCK_BUFFER_SIZE 16 +#else + #define BLOCK_BUFFER_SIZE 16 +#endif + +// @section serial + +// The ASCII buffer for serial input +#define MAX_CMD_SIZE 96 +#define BUFSIZE 4 + +/** + * Host Transmit Buffer Size + * - Costs 386 bytes of flash and TX_BUFFER_SIZE+3 bytes of SRAM (if not 0). + * - 4 bytes required to buffer a simple "ok". + * - 32 bytes for ADVANCED_OK (M105). + * - 128 bytes for the optimal speed of 'debug-echo:' + * - Other output doesn't need to be that speedy. + * :[0, 2, 4, 8, 16, 32, 64, 128, 256] + */ +#define TX_BUFFER_SIZE 0 + +/** + * Host Receive Buffer Size + * Without XON/XOFF flow control (see SERIAL_XON_XOFF below) 32 bytes should be enough. + * To use flow control, set this buffer size to at least 1024 bytes. + * :[0, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048] + */ +//#define RX_BUFFER_SIZE 1024 + +#if RX_BUFFER_SIZE >= 1024 + // Enable to have the controller send XON/XOFF control characters to + // the host to signal the RX buffer is becoming full. + //#define SERIAL_XON_XOFF +#endif + +#if HAS_MEDIA + // Enable this option to collect and display the maximum + // RX queue usage after transferring a file to SD. + //#define SERIAL_STATS_MAX_RX_QUEUED + + // Enable this option to collect and display the number + // of dropped bytes after a file transfer to SD. + //#define SERIAL_STATS_DROPPED_RX +#endif + +// Monitor RX buffer usage +// Dump an error to the serial port if the serial receive buffer overflows. +// If you see these errors, increase the RX_BUFFER_SIZE value. +// Not supported on all platforms. +//#define RX_BUFFER_MONITOR + +/** + * Emergency Command Parser + * + * Add a low-level parser to intercept certain commands as they + * enter the serial receive buffer, so they cannot be blocked. + * Currently handles M108, M112, M410, M876 + * NOTE: Not yet implemented for all platforms. + */ +//#define EMERGENCY_PARSER + +/** + * Realtime Reporting (requires EMERGENCY_PARSER) + * + * - Report position and state of the machine (like Grbl). + * - Auto-report position during long moves. + * - Useful for CNC/LASER. + * + * Adds support for commands: + * S000 : Report State and Position while moving. + * P000 : Instant Pause / Hold while moving. + * R000 : Resume from Pause / Hold. + * + * - During Hold all Emergency Parser commands are available, as usual. + * - Enable NANODLP_Z_SYNC and NANODLP_ALL_AXIS for move command end-state reports. + */ +//#define REALTIME_REPORTING_COMMANDS +#if ENABLED(REALTIME_REPORTING_COMMANDS) + //#define FULL_REPORT_TO_HOST_FEATURE // Auto-report the machine status like Grbl CNC +#endif + +/** + * Bad Serial-connections can miss a received command by sending an 'ok' + * Therefore some clients abort after 30 seconds in a timeout. + * Some other clients start sending commands while receiving a 'wait'. + * This "wait" is only sent when the buffer is empty. 1 second is a good value here. + */ +//#define NO_TIMEOUTS 1000 // (ms) + +// Some clients will have this feature soon. This could make the NO_TIMEOUTS unnecessary. +//#define ADVANCED_OK + +// Printrun may have trouble receiving long strings all at once. +// This option inserts short delays between lines of serial output. +#define SERIAL_OVERRUN_PROTECTION + +// For serial echo, the number of digits after the decimal point +//#define SERIAL_FLOAT_PRECISION 4 + +/** + * This feature is EXPERIMENTAL so use with caution and test thoroughly. + * Enable this option to receive data on the serial ports via the onboard DMA + * controller for more stable and reliable high-speed serial communication. + * Support is currently limited to some STM32 MCUs and all HC32 MCUs. + * Note: This has no effect on emulated USB serial ports. + */ +//#define SERIAL_DMA + +/** + * Set the number of proportional font spaces required to fill up a typical character space. + * This can help to better align the output of commands like 'G29 O' Mesh Output. + * + * For clients that use a fixed-width font (like OctoPrint), leave this set to 1.0. + * Otherwise, adjust according to your client and font. + */ +#define PROPORTIONAL_FONT_RATIO 1.0 + +// @section extras + +/** + * Extra Fan Speed + * Adds a secondary fan speed for each print-cooling fan. + * 'M106 P T3-255' : Set a secondary speed for + * 'M106 P T2' : Use the set secondary speed + * 'M106 P T1' : Restore the previous fan speed + */ +//#define EXTRA_FAN_SPEED + +// @section gcode + +/** + * Firmware-based and LCD-controlled retract + * + * Add G10 / G11 commands for automatic firmware-based retract / recover. + * Use M207 and M208 to define parameters for retract / recover. + * + * Use M209 to enable or disable auto-retract. + * With auto-retract enabled, all G1 E moves within the set range + * will be converted to firmware-based retract/recover moves. + * + * Be sure to turn off auto-retract during filament change. + * + * Note that M207 / M208 / M209 settings are saved to EEPROM. + */ +//#define FWRETRACT +#if ENABLED(FWRETRACT) + #define FWRETRACT_AUTORETRACT // Override slicer retractions + #if ENABLED(FWRETRACT_AUTORETRACT) + #define MIN_AUTORETRACT 0.1 // (mm) Don't convert E moves under this length + #define MAX_AUTORETRACT 10.0 // (mm) Don't convert E moves over this length + #endif + #define RETRACT_LENGTH 3 // (mm) Default retract length (positive value) + #define RETRACT_LENGTH_SWAP 13 // (mm) Default swap retract length (positive value) + #define RETRACT_FEEDRATE 45 // (mm/s) Default feedrate for retracting + #define RETRACT_ZRAISE 0 // (mm) Default retract Z-raise + #define RETRACT_RECOVER_LENGTH 0 // (mm) Default additional recover length (added to retract length on recover) + #define RETRACT_RECOVER_LENGTH_SWAP 0 // (mm) Default additional swap recover length (added to retract length on recover from toolchange) + #define RETRACT_RECOVER_FEEDRATE 8 // (mm/s) Default feedrate for recovering from retraction + #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // (mm/s) Default feedrate for recovering from swap retraction + #if ENABLED(MIXING_EXTRUDER) + //#define RETRACT_SYNC_MIXING // Retract and restore all mixing steppers simultaneously + #endif +#endif + +// @section tool change + +/** + * Universal tool change settings. + * Applies to all types of extruders except where explicitly noted. + */ +#if HAS_MULTI_EXTRUDER + // Z raise distance for tool-change, as needed for some extruders + #define TOOLCHANGE_ZRAISE 2 // (mm) + //#define TOOLCHANGE_ZRAISE_BEFORE_RETRACT // Apply raise before swap retraction (if enabled) + //#define TOOLCHANGE_NO_RETURN // Never return to previous position on tool-change + #if ENABLED(TOOLCHANGE_NO_RETURN) + //#define EVENT_GCODE_AFTER_TOOLCHANGE "G12X" // Extra G-code to run after tool-change + #endif + + /** + * Extra G-code to run while executing tool-change commands. Can be used to use an additional + * stepper motor (e.g., I axis in Configuration.h) to drive the tool-changer. + */ + //#define EVENT_GCODE_TOOLCHANGE_T0 "G28 A\nG1 A0" // Extra G-code to run while executing tool-change command T0 + //#define EVENT_GCODE_TOOLCHANGE_T1 "G1 A10" // Extra G-code to run while executing tool-change command T1 + //#define EVENT_GCODE_TOOLCHANGE_ALWAYS_RUN // Always execute above G-code sequences. Use with caution! + + /** + * Consider coordinates for EVENT_GCODE_TOOLCHANGE_Tx as relative to T0 + * so that moves in the specified axes are the same for all tools. + */ + //#define TC_GCODE_USE_GLOBAL_X // Use X position relative to Tool 0 + //#define TC_GCODE_USE_GLOBAL_Y // Use Y position relative to Tool 0 + //#define TC_GCODE_USE_GLOBAL_Z // Use Z position relative to Tool 0 + + /** + * Tool Sensors detect when tools have been picked up or dropped. + * Requires the pins TOOL_SENSOR1_PIN, TOOL_SENSOR2_PIN, etc. + */ + //#define TOOL_SENSOR + + /** + * Retract and prime filament on tool-change to reduce + * ooze and stringing and to get cleaner transitions. + */ + //#define TOOLCHANGE_FILAMENT_SWAP + #if ENABLED(TOOLCHANGE_FILAMENT_SWAP) + // Load / Unload + #define TOOLCHANGE_FS_LENGTH 12 // (mm) Load / Unload length + #define TOOLCHANGE_FS_EXTRA_RESUME_LENGTH 0 // (mm) Extra length for better restart. Adjust with LCD or M217 B. + #define TOOLCHANGE_FS_RETRACT_SPEED (50*60) // (mm/min) (Unloading) + #define TOOLCHANGE_FS_UNRETRACT_SPEED (25*60) // (mm/min) (On SINGLENOZZLE or Bowden loading must be slowed down) + + // Longer prime to clean out a SINGLENOZZLE + #define TOOLCHANGE_FS_EXTRA_PRIME 0 // (mm) Extra priming length + #define TOOLCHANGE_FS_PRIME_SPEED (4.6*60) // (mm/min) Extra priming feedrate + #define TOOLCHANGE_FS_WIPE_RETRACT 0 // (mm) Cutting retraction out of park, for less stringing, better wipe, etc. Adjust with LCD or M217 G. + + // Cool after prime to reduce stringing + #define TOOLCHANGE_FS_FAN -1 // Fan index or -1 to skip + #define TOOLCHANGE_FS_FAN_SPEED 255 // 0-255 + #define TOOLCHANGE_FS_FAN_TIME 10 // (seconds) + + // Use TOOLCHANGE_FS_PRIME_SPEED feedrate the first time each extruder is primed + //#define TOOLCHANGE_FS_SLOW_FIRST_PRIME + + /** + * Prime T0 the first time T0 is sent to the printer: + * [ Power-On -> T0 { Activate & Prime T0 } -> T1 { Retract T0, Activate & Prime T1 } ] + * If disabled, no priming on T0 until switching back to T0 from another extruder: + * [ Power-On -> T0 { T0 Activated } -> T1 { Activate & Prime T1 } -> T0 { Retract T1, Activate & Prime T0 } ] + * Enable with M217 V1 before printing to avoid unwanted priming on host connect. + */ + //#define TOOLCHANGE_FS_PRIME_FIRST_USED + + /** + * Tool Change Migration + * This feature provides G-code and LCD options to switch tools mid-print. + * All applicable tool properties are migrated so the print can continue. + * Tools must be closely matching and other restrictions may apply. + * Useful to: + * - Change filament color without interruption + * - Switch spools automatically on filament runout + * - Switch to a different nozzle on an extruder jam + */ + #define TOOLCHANGE_MIGRATION_FEATURE + #if ENABLED(TOOLCHANGE_MIGRATION_FEATURE) + // Override toolchange settings + // By default tool migration uses regular toolchange settings. + // With a prime tower, tool-change swapping/priming occur inside the bed. + // When migrating to a new unprimed tool you can set override values below. + //#define MIGRATION_ZRAISE 0 // (mm) + + // Longer prime to clean out + //#define MIGRATION_FS_EXTRA_PRIME 0 // (mm) Extra priming length + //#define MIGRATION_FS_WIPE_RETRACT 0 // (mm) Retract before cooling for less stringing, better wipe, etc. + + // Cool after prime to reduce stringing + //#define MIGRATION_FS_FAN_SPEED 255 // 0-255 + //#define MIGRATION_FS_FAN_TIME 0 // (seconds) + #endif + #endif + + /** + * Position to park head during tool change. + * Doesn't apply to SWITCHING_TOOLHEAD, DUAL_X_CARRIAGE, or PARKING_EXTRUDER + */ + //#define TOOLCHANGE_PARK + #if ENABLED(TOOLCHANGE_PARK) + #define TOOLCHANGE_PARK_XY { X_MIN_POS + 10, Y_MIN_POS + 10 } + #define TOOLCHANGE_PARK_XY_FEEDRATE 6000 // (mm/min) + //#define TOOLCHANGE_PARK_X_ONLY // X axis only move + //#define TOOLCHANGE_PARK_Y_ONLY // Y axis only move + #if ENABLED(TOOLCHANGE_MIGRATION_FEATURE) + //#define TOOLCHANGE_MIGRATION_DO_PARK // Force park (or no-park) on migration + #endif + #endif +#endif // HAS_MULTI_EXTRUDER + +// @section advanced pause + +/** + * Advanced Pause for Filament Change + * - Adds the G-code M600 Filament Change to initiate a filament change. + * - This feature is required for the default FILAMENT_RUNOUT_SCRIPT. + * + * Requirements: + * - For Filament Change parking enable and configure NOZZLE_PARK_FEATURE. + * - For user interaction enable an LCD display, HOST_PROMPT_SUPPORT, or EMERGENCY_PARSER. + * + * Enable PARK_HEAD_ON_PAUSE to add the G-code M125 Pause and Park. + */ +#define ADVANCED_PAUSE_FEATURE +#if ENABLED(ADVANCED_PAUSE_FEATURE) + #define PAUSE_PARK_RETRACT_FEEDRATE 100 // (mm/s) Initial retract feedrate. + #define PAUSE_PARK_RETRACT_LENGTH 5 // (mm) Initial retract. + // This short retract is done immediately, before parking the nozzle. + #define FILAMENT_CHANGE_UNLOAD_FEEDRATE 10 // (mm/s) Unload filament feedrate. This can be pretty fast. + #define FILAMENT_CHANGE_UNLOAD_ACCEL 25 // (mm/s^2) Lower acceleration may allow a faster feedrate. + #define FILAMENT_CHANGE_UNLOAD_LENGTH 800 // (mm) The length of filament for a complete unload. + // For Bowden, the full length of the tube and nozzle. + // For direct drive, the full length of the nozzle. + // Set to 0 for manual unloading. + #define FILAMENT_CHANGE_SLOW_LOAD_FEEDRATE 6 // (mm/s) Slow move when starting load. + #define FILAMENT_CHANGE_SLOW_LOAD_LENGTH 0 // (mm) Slow length, to allow time to insert material. + // 0 to disable start loading and skip to fast load only + #define FILAMENT_CHANGE_FAST_LOAD_FEEDRATE 10 // (mm/s) Load filament feedrate. This can be pretty fast. + #define FILAMENT_CHANGE_FAST_LOAD_ACCEL 25 // (mm/s^2) Lower acceleration may allow a faster feedrate. + #define FILAMENT_CHANGE_FAST_LOAD_LENGTH 780 // (mm) Load length of filament, from extruder gear to nozzle. + // For Bowden, the full length of the tube and nozzle. + // For direct drive, the full length of the nozzle. + //#define ADVANCED_PAUSE_CONTINUOUS_PURGE // Purge continuously up to the purge length until interrupted. + #define ADVANCED_PAUSE_PURGE_FEEDRATE 3 // (mm/s) Extrude feedrate (after loading). Should be slower than load feedrate. + #define ADVANCED_PAUSE_PURGE_LENGTH 20 // (mm) Length to extrude after loading. + // Set to 0 for manual extrusion. + // Filament can be extruded repeatedly from the Filament Change menu + // until extrusion is consistent, and to purge old filament. + #define ADVANCED_PAUSE_RESUME_PRIME 0 // (mm) Extra distance to prime nozzle after returning from park. + //#define ADVANCED_PAUSE_FANS_PAUSE // Turn off print-cooling fans while the machine is paused. + + // Filament Unload does a Retract, Delay, and Purge first: + #define FILAMENT_UNLOAD_PURGE_RETRACT 13 // (mm) Unload initial retract length. + #define FILAMENT_UNLOAD_PURGE_DELAY 5000 // (ms) Delay for the filament to cool after retract. + #define FILAMENT_UNLOAD_PURGE_LENGTH 8 // (mm) An unretract is done, then this length is purged. + #define FILAMENT_UNLOAD_PURGE_FEEDRATE 25 // (mm/s) feedrate to purge before unload + + #define PAUSE_PARK_NOZZLE_TIMEOUT 45 // (seconds) Time limit before the nozzle is turned off for safety. + #define FILAMENT_CHANGE_ALERT_BEEPS 8 // Number of alert beeps to play when a response is needed. + #define PAUSE_PARK_NO_STEPPER_TIMEOUT // Enable for XYZ steppers to stay powered on during filament change. + //#define FILAMENT_CHANGE_RESUME_ON_INSERT // Automatically continue / load filament when runout sensor is triggered again. + //#define PAUSE_REHEAT_FAST_RESUME // Reduce number of waits by not prompting again post-timeout before continuing. + + //#define PARK_HEAD_ON_PAUSE // Park the nozzle during pause and filament change. + //#define HOME_BEFORE_FILAMENT_CHANGE // If needed, home before parking for filament change + + //#define FILAMENT_LOAD_UNLOAD_GCODES // Add M701/M702 Load/Unload G-codes, plus Load/Unload in the LCD Prepare menu. + //#define FILAMENT_UNLOAD_ALL_EXTRUDERS // Allow M702 to unload all extruders above a minimum target temp (as set by M302) + #define CONFIGURE_FILAMENT_CHANGE // Add M603 G-code and menu items. Requires ~1.3K bytes of flash. +#endif + +// @section tmc_smart + +/** + * Trinamic Smart Drivers + * + * To use TMC2130, TMC2160, TMC2240, TMC2660, TMC5130, TMC5160 stepper drivers in SPI mode: + * - Connect your SPI pins to the Hardware SPI interface on the board. + * Some boards have simple jumper connections! See your board's documentation. + * - Define the required Stepper CS pins in your `pins_MYBOARD.h` file. + * (See the RAMPS pins, for example.) + * - You can also use Software SPI with GPIO pins instead of Hardware SPI. + * + * To use TMC220x stepper drivers with Serial UART: + * - Connect PDN_UART to the #_SERIAL_TX_PIN through a 1K resistor. + * For reading capabilities also connect PDN_UART to #_SERIAL_RX_PIN with no resistor. + * Some boards have simple jumper connections! See your board's documentation. + * - These drivers can also be used with Hardware Serial. + * + * The TMCStepper library is required for other TMC stepper drivers. + * https://github.com/teemuatlut/TMCStepper + * + * @section tmc/config + */ +#if HAS_TRINAMIC_CONFIG + + #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current + + //#define EDITABLE_HOMING_CURRENT // Add a G-code and menu to modify the Homing Current + + /** + * Interpolate microsteps to 256 + * Override for each driver with _INTERPOLATE settings below + */ + #define INTERPOLATE true + + #if HAS_DRIVER(TMC2240) + #define TMC2240_RREF 12000 // (Ω) 12000 .. 60000. (FLY TMC2240 = 12300) + // Max Current. Lower for more internal resolution. Raise to run cooler. + #define TMC2240_CURRENT_RANGE 1 // :{ 0:'RMS=690mA PEAK=1A', 1:'RMS=1410mA PEAK=2A', 2:'RMS=2120mA PEAK=3A', 3:'RMS=2110mA PEAK=3A' } + // Slope Control: Lower is more silent. Higher runs cooler. + #define TMC2240_SLOPE_CONTROL 0 // :{ 0:'100V/µs', 1:'200V/µs', 2:'400V/µs', 3:'800V/µs' } + #endif + + #if AXIS_IS_TMC_CONFIG(X) + #define X_CURRENT 800 // (mA) RMS current. Multiply by 1.414 for peak current. + #define X_CURRENT_HOME X_CURRENT // (mA) RMS current for homing. (Typically lower than *_CURRENT.) + #define X_MICROSTEPS 16 // 0..256 + #define X_RSENSE 0.11 + #define X_CHAIN_POS -1 // -1..0: Not chained. 1: MCU MOSI connected. 2: Next in chain, ... + //#define X_INTERPOLATE true // Enable to override 'INTERPOLATE' for the X axis + //#define X_HOLD_MULTIPLIER 0.5 // Enable to override 'HOLD_MULTIPLIER' for the X axis + #endif + + #if AXIS_IS_TMC_CONFIG(X2) + #define X2_CURRENT X_CURRENT + #define X2_CURRENT_HOME X_CURRENT_HOME + #define X2_MICROSTEPS X_MICROSTEPS + #define X2_RSENSE X_RSENSE + #define X2_CHAIN_POS -1 + //#define X2_INTERPOLATE true + //#define X2_HOLD_MULTIPLIER 0.5 + #endif + + #if AXIS_IS_TMC_CONFIG(Y) + #define Y_CURRENT 800 + #define Y_CURRENT_HOME Y_CURRENT + #define Y_MICROSTEPS 16 + #define Y_RSENSE 0.11 + #define Y_CHAIN_POS -1 + //#define Y_INTERPOLATE true + //#define Y_HOLD_MULTIPLIER 0.5 + #endif + + #if AXIS_IS_TMC_CONFIG(Y2) + #define Y2_CURRENT Y_CURRENT + #define Y2_CURRENT_HOME Y_CURRENT_HOME + #define Y2_MICROSTEPS Y_MICROSTEPS + #define Y2_RSENSE Y_RSENSE + #define Y2_CHAIN_POS -1 + //#define Y2_INTERPOLATE true + //#define Y2_HOLD_MULTIPLIER 0.5 + #endif + + #if AXIS_IS_TMC_CONFIG(Z) + #define Z_CURRENT 800 + #define Z_CURRENT_HOME Z_CURRENT + #define Z_MICROSTEPS 16 + #define Z_RSENSE 0.11 + #define Z_CHAIN_POS -1 + //#define Z_INTERPOLATE true + //#define Z_HOLD_MULTIPLIER 0.5 + #endif + + #if AXIS_IS_TMC_CONFIG(Z2) + #define Z2_CURRENT Z_CURRENT + #define Z2_CURRENT_HOME Z_CURRENT_HOME + #define Z2_MICROSTEPS Z_MICROSTEPS + #define Z2_RSENSE Z_RSENSE + #define Z2_CHAIN_POS -1 + //#define Z2_INTERPOLATE true + //#define Z2_HOLD_MULTIPLIER 0.5 + #endif + + #if AXIS_IS_TMC_CONFIG(Z3) + #define Z3_CURRENT Z_CURRENT + #define Z3_CURRENT_HOME Z_CURRENT_HOME + #define Z3_MICROSTEPS Z_MICROSTEPS + #define Z3_RSENSE Z_RSENSE + #define Z3_CHAIN_POS -1 + //#define Z3_INTERPOLATE true + //#define Z3_HOLD_MULTIPLIER 0.5 + #endif + + #if AXIS_IS_TMC_CONFIG(Z4) + #define Z4_CURRENT Z_CURRENT + #define Z4_CURRENT_HOME Z_CURRENT_HOME + #define Z4_MICROSTEPS Z_MICROSTEPS + #define Z4_RSENSE Z_RSENSE + #define Z4_CHAIN_POS -1 + //#define Z4_INTERPOLATE true + //#define Z4_HOLD_MULTIPLIER 0.5 + #endif + + #if AXIS_IS_TMC_CONFIG(I) + #define I_CURRENT 800 + #define I_CURRENT_HOME I_CURRENT + #define I_MICROSTEPS 16 + #define I_RSENSE 0.11 + #define I_CHAIN_POS -1 + //#define I_INTERPOLATE true + //#define I_HOLD_MULTIPLIER 0.5 + #endif + + #if AXIS_IS_TMC_CONFIG(J) + #define J_CURRENT 800 + #define J_CURRENT_HOME J_CURRENT + #define J_MICROSTEPS 16 + #define J_RSENSE 0.11 + #define J_CHAIN_POS -1 + //#define J_INTERPOLATE true + //#define J_HOLD_MULTIPLIER 0.5 + #endif + + #if AXIS_IS_TMC_CONFIG(K) + #define K_CURRENT 800 + #define K_CURRENT_HOME K_CURRENT + #define K_MICROSTEPS 16 + #define K_RSENSE 0.11 + #define K_CHAIN_POS -1 + //#define K_INTERPOLATE true + //#define K_HOLD_MULTIPLIER 0.5 + #endif + + #if AXIS_IS_TMC_CONFIG(U) + #define U_CURRENT 800 + #define U_CURRENT_HOME U_CURRENT + #define U_MICROSTEPS 8 + #define U_RSENSE 0.11 + #define U_CHAIN_POS -1 + //#define U_INTERPOLATE true + //#define U_HOLD_MULTIPLIER 0.5 + #endif + + #if AXIS_IS_TMC_CONFIG(V) + #define V_CURRENT 800 + #define V_CURRENT_HOME V_CURRENT + #define V_MICROSTEPS 8 + #define V_RSENSE 0.11 + #define V_CHAIN_POS -1 + //#define V_INTERPOLATE true + //#define V_HOLD_MULTIPLIER 0.5 + #endif + + #if AXIS_IS_TMC_CONFIG(W) + #define W_CURRENT 800 + #define W_CURRENT_HOME W_CURRENT + #define W_MICROSTEPS 8 + #define W_RSENSE 0.11 + #define W_CHAIN_POS -1 + //#define W_INTERPOLATE true + //#define W_HOLD_MULTIPLIER 0.5 + #endif + + #if AXIS_IS_TMC_CONFIG(E0) + #define E0_CURRENT 800 + #define E0_MICROSTEPS 16 + #define E0_RSENSE 0.11 + #define E0_CHAIN_POS -1 + //#define E0_INTERPOLATE true + //#define E0_HOLD_MULTIPLIER 0.5 + #endif + + #if AXIS_IS_TMC_CONFIG(E1) + #define E1_CURRENT E0_CURRENT + #define E1_MICROSTEPS E0_MICROSTEPS + #define E1_RSENSE E0_RSENSE + #define E1_CHAIN_POS -1 + //#define E1_INTERPOLATE true + //#define E1_HOLD_MULTIPLIER 0.5 + #endif + + #if AXIS_IS_TMC_CONFIG(E2) + #define E2_CURRENT E0_CURRENT + #define E2_MICROSTEPS E0_MICROSTEPS + #define E2_RSENSE E0_RSENSE + #define E2_CHAIN_POS -1 + //#define E2_INTERPOLATE true + //#define E2_HOLD_MULTIPLIER 0.5 + #endif + + #if AXIS_IS_TMC_CONFIG(E3) + #define E3_CURRENT E0_CURRENT + #define E3_MICROSTEPS E0_MICROSTEPS + #define E3_RSENSE E0_RSENSE + #define E3_CHAIN_POS -1 + //#define E3_INTERPOLATE true + //#define E3_HOLD_MULTIPLIER 0.5 + #endif + + #if AXIS_IS_TMC_CONFIG(E4) + #define E4_CURRENT E0_CURRENT + #define E4_MICROSTEPS E0_MICROSTEPS + #define E4_RSENSE E0_RSENSE + #define E4_CHAIN_POS -1 + //#define E4_INTERPOLATE true + //#define E4_HOLD_MULTIPLIER 0.5 + #endif + + #if AXIS_IS_TMC_CONFIG(E5) + #define E5_CURRENT E0_CURRENT + #define E5_MICROSTEPS E0_MICROSTEPS + #define E5_RSENSE E0_RSENSE + #define E5_CHAIN_POS -1 + //#define E5_INTERPOLATE true + //#define E5_HOLD_MULTIPLIER 0.5 + #endif + + #if AXIS_IS_TMC_CONFIG(E6) + #define E6_CURRENT E0_CURRENT + #define E6_MICROSTEPS E0_MICROSTEPS + #define E6_RSENSE E0_RSENSE + #define E6_CHAIN_POS -1 + //#define E6_INTERPOLATE true + //#define E6_HOLD_MULTIPLIER 0.5 + #endif + + #if AXIS_IS_TMC_CONFIG(E7) + #define E7_CURRENT E0_CURRENT + #define E7_MICROSTEPS E0_MICROSTEPS + #define E7_RSENSE E0_RSENSE + #define E7_CHAIN_POS -1 + //#define E7_INTERPOLATE true + //#define E7_HOLD_MULTIPLIER 0.5 + #endif + + /** + * Use the homing current for all probing. (e.g., Current may be reduced to the + * point where a collision makes the motor skip instead of damaging the bed, + * though this is unlikely to save delicate probes from being damaged. + */ + //#define PROBING_USE_CURRENT_HOME + + // @section tmc/spi + + /** + * Override default SPI pins for TMC2130, TMC2160, TMC2240, TMC2660, TMC5130 and TMC5160 drivers here. + * The default pins can be found in your board's pins file. + */ + //#define X_CS_PIN -1 + //#define Y_CS_PIN -1 + //#define Z_CS_PIN -1 + //#define X2_CS_PIN -1 + //#define Y2_CS_PIN -1 + //#define Z2_CS_PIN -1 + //#define Z3_CS_PIN -1 + //#define Z4_CS_PIN -1 + //#define I_CS_PIN -1 + //#define J_CS_PIN -1 + //#define K_CS_PIN -1 + //#define U_CS_PIN -1 + //#define V_CS_PIN -1 + //#define W_CS_PIN -1 + //#define E0_CS_PIN -1 + //#define E1_CS_PIN -1 + //#define E2_CS_PIN -1 + //#define E3_CS_PIN -1 + //#define E4_CS_PIN -1 + //#define E5_CS_PIN -1 + //#define E6_CS_PIN -1 + //#define E7_CS_PIN -1 + + /** + * Software option for SPI driven drivers (TMC2130, TMC2160, TMC2240, TMC2660, TMC5130 and TMC5160). + * The default SW SPI pins are defined the respective pins files, + * but you can override or define them here. + */ + //#define TMC_USE_SW_SPI + //#define TMC_SPI_MOSI -1 + //#define TMC_SPI_MISO -1 + //#define TMC_SPI_SCK -1 + + // @section tmc/serial + + /** + * Four TMC2209 drivers can use the same HW/SW serial port with hardware configured addresses. + * Set the address using jumpers on pins MS1 and MS2. + * Address | MS1 | MS2 + * 0 | LOW | LOW + * 1 | HIGH | LOW + * 2 | LOW | HIGH + * 3 | HIGH | HIGH + * + * Set *_SERIAL_TX_PIN and *_SERIAL_RX_PIN to match for all drivers + * on the same serial port, either here or in your board's pins file. + */ + //#define X_SLAVE_ADDRESS 0 + //#define Y_SLAVE_ADDRESS 0 + //#define Z_SLAVE_ADDRESS 0 + //#define X2_SLAVE_ADDRESS 0 + //#define Y2_SLAVE_ADDRESS 0 + //#define Z2_SLAVE_ADDRESS 0 + //#define Z3_SLAVE_ADDRESS 0 + //#define Z4_SLAVE_ADDRESS 0 + //#define I_SLAVE_ADDRESS 0 + //#define J_SLAVE_ADDRESS 0 + //#define K_SLAVE_ADDRESS 0 + //#define U_SLAVE_ADDRESS 0 + //#define V_SLAVE_ADDRESS 0 + //#define W_SLAVE_ADDRESS 0 + //#define E0_SLAVE_ADDRESS 0 + //#define E1_SLAVE_ADDRESS 0 + //#define E2_SLAVE_ADDRESS 0 + //#define E3_SLAVE_ADDRESS 0 + //#define E4_SLAVE_ADDRESS 0 + //#define E5_SLAVE_ADDRESS 0 + //#define E6_SLAVE_ADDRESS 0 + //#define E7_SLAVE_ADDRESS 0 + + // @section tmc/smart + + /** + * Software enable + * + * Use for drivers that do not use a dedicated enable pin, but rather handle the same + * function through a communication line such as SPI or UART. + */ + //#define SOFTWARE_DRIVER_ENABLE + + // @section tmc/stealthchop + + /** + * TMC2130, TMC2160, TMC2208, TMC2209, TMC2240, TMC5130 and TMC5160 only + * Use Trinamic's ultra quiet stepping mode. + * When disabled, Marlin will use spreadCycle stepping mode. + */ + #if HAS_STEALTHCHOP + #define STEALTHCHOP_XY + #define STEALTHCHOP_Z + #define STEALTHCHOP_I + #define STEALTHCHOP_J + #define STEALTHCHOP_K + #define STEALTHCHOP_U + #define STEALTHCHOP_V + #define STEALTHCHOP_W + #define STEALTHCHOP_E + #endif + + /** + * Optimize spreadCycle chopper parameters by using predefined parameter sets + * or with the help of an example included in the library. + * Provided parameter sets are + * CHOPPER_DEFAULT_12V + * CHOPPER_DEFAULT_19V + * CHOPPER_DEFAULT_24V + * CHOPPER_DEFAULT_36V + * CHOPPER_09STEP_24V // 0.9 degree steppers (24V) + * CHOPPER_PRUSAMK3_24V // Imported parameters from the official Průša firmware for MK3 (24V) + * CHOPPER_MARLIN_119 // Old defaults from Marlin v1.1.9 + * + * Define your own with: + * { , , hysteresis_start[1..8] } + */ + #define CHOPPER_TIMING CHOPPER_DEFAULT_12V // All axes (override below) + //#define CHOPPER_TIMING_X CHOPPER_TIMING // For X Axes (override below) + //#define CHOPPER_TIMING_X2 CHOPPER_TIMING_X + //#define CHOPPER_TIMING_Y CHOPPER_TIMING // For Y Axes (override below) + //#define CHOPPER_TIMING_Y2 CHOPPER_TIMING_Y + //#define CHOPPER_TIMING_Z CHOPPER_TIMING // For Z Axes (override below) + //#define CHOPPER_TIMING_Z2 CHOPPER_TIMING_Z + //#define CHOPPER_TIMING_Z3 CHOPPER_TIMING_Z + //#define CHOPPER_TIMING_Z4 CHOPPER_TIMING_Z + //#define CHOPPER_TIMING_I CHOPPER_TIMING // For I Axis + //#define CHOPPER_TIMING_J CHOPPER_TIMING // For J Axis + //#define CHOPPER_TIMING_K CHOPPER_TIMING // For K Axis + //#define CHOPPER_TIMING_U CHOPPER_TIMING // For U Axis + //#define CHOPPER_TIMING_V CHOPPER_TIMING // For V Axis + //#define CHOPPER_TIMING_W CHOPPER_TIMING // For W Axis + //#define CHOPPER_TIMING_E CHOPPER_TIMING // For Extruders (override below) + //#define CHOPPER_TIMING_E1 CHOPPER_TIMING_E + //#define CHOPPER_TIMING_E2 CHOPPER_TIMING_E + //#define CHOPPER_TIMING_E3 CHOPPER_TIMING_E + //#define CHOPPER_TIMING_E4 CHOPPER_TIMING_E + //#define CHOPPER_TIMING_E5 CHOPPER_TIMING_E + //#define CHOPPER_TIMING_E6 CHOPPER_TIMING_E + //#define CHOPPER_TIMING_E7 CHOPPER_TIMING_E + + // @section tmc/status + + /** + * Monitor Trinamic drivers + * for error conditions like overtemperature and short to ground. + * To manage over-temp Marlin can decrease the driver current until the error condition clears. + * Other detected conditions can be used to stop the current print. + * Relevant G-codes: + * M906 - Set or get motor current in milliamps using axis codes X, Y, Z, E. Report values if no axis codes given. + * M911 - Report stepper driver overtemperature pre-warn condition. + * M912 - Clear stepper driver overtemperature pre-warn condition flag. + * M122 - Report driver parameters (Requires TMC_DEBUG) + */ + //#define MONITOR_DRIVER_STATUS + + #if ENABLED(MONITOR_DRIVER_STATUS) + #define CURRENT_STEP_DOWN 50 // [mA] + #define REPORT_CURRENT_CHANGE + #define STOP_ON_ERROR + #endif + + // @section tmc/hybrid + + /** + * TMC2130, TMC2160, TMC2208, TMC2209, TMC2240, TMC5130 and TMC5160 only + * The driver will switch to spreadCycle when stepper speed is over HYBRID_THRESHOLD. + * This mode allows for faster movements at the expense of higher noise levels. + * STEALTHCHOP_(XY|Z|E) must be enabled to use HYBRID_THRESHOLD. + * M913 X/Y/Z/E to live tune the setting + */ + //#define HYBRID_THRESHOLD + + #define X_HYBRID_THRESHOLD 100 // [mm/s] + #define X2_HYBRID_THRESHOLD 100 + #define Y_HYBRID_THRESHOLD 100 + #define Y2_HYBRID_THRESHOLD 100 + #define Z_HYBRID_THRESHOLD 3 + #define Z2_HYBRID_THRESHOLD 3 + #define Z3_HYBRID_THRESHOLD 3 + #define Z4_HYBRID_THRESHOLD 3 + #define I_HYBRID_THRESHOLD 3 // [linear=mm/s, rotational=°/s] + #define J_HYBRID_THRESHOLD 3 // [linear=mm/s, rotational=°/s] + #define K_HYBRID_THRESHOLD 3 // [linear=mm/s, rotational=°/s] + #define U_HYBRID_THRESHOLD 3 // [mm/s] + #define V_HYBRID_THRESHOLD 3 + #define W_HYBRID_THRESHOLD 3 + #define E0_HYBRID_THRESHOLD 30 + #define E1_HYBRID_THRESHOLD 30 + #define E2_HYBRID_THRESHOLD 30 + #define E3_HYBRID_THRESHOLD 30 + #define E4_HYBRID_THRESHOLD 30 + #define E5_HYBRID_THRESHOLD 30 + #define E6_HYBRID_THRESHOLD 30 + #define E7_HYBRID_THRESHOLD 30 + + /** + * Use StallGuard to home / probe X, Y, Z. + * + * TMC2130, TMC2160, TMC2209, TMC2240, TMC2660, TMC5130, and TMC5160 only + * Connect the stepper driver's DIAG1 pin to the X/Y endstop pin. + * X, Y, and Z homing will always be done in spreadCycle mode. + * + * X/Y/Z_STALL_SENSITIVITY is the default stall threshold. + * Use M914 X Y Z to set the stall threshold at runtime: + * + * Sensitivity TMC2209 Others + * HIGHEST 255 -64 (Too sensitive => False positive) + * LOWEST 0 63 (Too insensitive => No trigger) + * + * It is recommended to set HOMING_BUMP_MM to { 0, 0, 0 }. + * + * SPI_ENDSTOPS *** TMC2130, TMC2240, and TMC5160 Only *** + * Poll the driver through SPI to determine load when homing. + * Removes the need for a wire from DIAG1 to an endstop pin. + * + * IMPROVE_HOMING_RELIABILITY tunes acceleration and jerk when + * homing and adds a guard period for endstop triggering. + * + * Comment *_STALL_SENSITIVITY to disable sensorless homing for that axis. + * @section tmc/stallguard + */ + //#define SENSORLESS_HOMING // StallGuard capable drivers only + + #if ANY(SENSORLESS_HOMING, SENSORLESS_PROBING) + // TMC2209: 0...255. TMC2130: -64...63 + #define X_STALL_SENSITIVITY 8 + #define X2_STALL_SENSITIVITY X_STALL_SENSITIVITY + #define Y_STALL_SENSITIVITY 8 + #define Y2_STALL_SENSITIVITY Y_STALL_SENSITIVITY + //#define Z_STALL_SENSITIVITY 8 + //#define Z2_STALL_SENSITIVITY Z_STALL_SENSITIVITY + //#define Z3_STALL_SENSITIVITY Z_STALL_SENSITIVITY + //#define Z4_STALL_SENSITIVITY Z_STALL_SENSITIVITY + //#define I_STALL_SENSITIVITY 8 + //#define J_STALL_SENSITIVITY 8 + //#define K_STALL_SENSITIVITY 8 + //#define U_STALL_SENSITIVITY 8 + //#define V_STALL_SENSITIVITY 8 + //#define W_STALL_SENSITIVITY 8 + //#define SPI_ENDSTOPS // TMC2130, TMC2240, and TMC5160 + //#define IMPROVE_HOMING_RELIABILITY + //#define SENSORLESS_STALLGUARD_DELAY 0 // (ms) Delay to allow drivers to settle + #endif + + // @section tmc/config + + /** + * TMC Homing stepper phase. + * + * Improve homing repeatability by homing to stepper coil's nearest absolute + * phase position. Trinamic drivers use a stepper phase table with 1024 values + * spanning 4 full steps with 256 positions each (ergo, 1024 positions). + * Full step positions (128, 384, 640, 896) have the highest holding torque. + * + * Values from 0..1023, -1 to disable homing phase for that axis. + */ + //#define TMC_HOME_PHASE { 896, 896, 896 } + + /** + * Step on both rising and falling edge signals (as with a square wave). + */ + #define EDGE_STEPPING + + /** + * Enable M122 debugging command for TMC stepper drivers. + * M122 S0/1 will enable continuous reporting. + */ + //#define TMC_DEBUG + + /** + * You can set your own advanced settings by filling in predefined functions. + * A list of available functions can be found on the library github page + * https://github.com/teemuatlut/TMCStepper + * + * Example: + * #define TMC_ADV() { \ + * stepperX.diag0_otpw(1); \ + * stepperY.intpol(0); \ + * } + */ + #define TMC_ADV() { } + +#endif // HAS_TRINAMIC_CONFIG + +// @section i2cbus + +// +// I2C Master ID for LPC176x LCD and Digital Current control +// Does not apply to other peripherals based on the Wire library. +// +//#define I2C_MASTER_ID 1 // Set a value from 0 to 2 + +/** + * TWI/I2C BUS + * + * This feature is EXPERIMENTAL but may be useful for custom I2C peripherals. + * Enable this to send and receive I2C data from slave devices on the bus. + * + * ; Example #1 + * ; This macro send the string "Marlin" to the slave device with address 0x63 (99) + * ; It uses multiple M260 commands with one B arg + * M260 A99 ; Target slave address + * M260 B77 ; M + * M260 B97 ; a + * M260 B114 ; r + * M260 B108 ; l + * M260 B105 ; i + * M260 B110 ; n + * M260 S1 ; Send the current buffer + * + * ; Example #2 + * ; Request 6 bytes from slave device with address 0x63 (99) + * M261 A99 B5 + * + * ; Example #3 + * ; Example serial output of a M261 request + * echo:i2c-reply: from:99 bytes:5 data:hello + */ + +//#define EXPERIMENTAL_I2CBUS +#if ENABLED(EXPERIMENTAL_I2CBUS) + #define I2C_SLAVE_ADDRESS 0 // Set a value from 8 to 127 to act as a slave +#endif + +// @section photo + +/** + * Photo G-code + * Add the M240 G-code to take a photo. + * The photo can be triggered by a digital pin or a physical movement. + */ +//#define PHOTO_GCODE +#if ENABLED(PHOTO_GCODE) + // A position to move to (and raise Z) before taking the photo + //#define PHOTO_POSITION { X_MAX_POS - 5, Y_MAX_POS, 0 } // { xpos, ypos, zraise } (M240 X Y Z) + //#define PHOTO_DELAY_MS 100 // (ms) Duration to pause before moving back (M240 P) + //#define PHOTO_RETRACT_MM 6.5 // (mm) E retract/recover for the photo move (M240 R S) + + // Canon RC-1 or homebrew digital camera trigger + // Data from: https://www.doc-diy.net/photo/rc-1_hacked/ + //#define PHOTOGRAPH_PIN 23 + + // Canon Hack Development Kit + // https://web.archive.org/web/20200920094805/captain-slow.dk/2014/03/09/3d-printing-timelapses/ + //#define CHDK_PIN 4 + + // Optional second move with delay to trigger the camera shutter + //#define PHOTO_SWITCH_POSITION { X_MAX_POS, Y_MAX_POS } // { xpos, ypos } (M240 I J) + + // Duration to hold the switch or keep CHDK_PIN high + //#define PHOTO_SWITCH_MS 50 // (ms) (M240 D) + + /** + * PHOTO_PULSES_US may need adjustment depending on board and camera model. + * Pin must be running at 48.4kHz. + * Be sure to use a PHOTOGRAPH_PIN which can rise and fall quick enough. + * (e.g., MKS SBase temp sensor pin was too slow, so used P1.23 on J8.) + * + * Example pulse data for Nikon: https://bit.ly/2FKD0Aq + * IR Wiring: https://git.io/JvJf7 + */ + //#define PHOTO_PULSES_US { 2000, 27850, 400, 1580, 400, 3580, 400 } // (µs) Durations for each 48.4kHz oscillation + #ifdef PHOTO_PULSES_US + #define PHOTO_PULSE_DELAY_US 13 // (µs) Approximate duration of each HIGH and LOW pulse in the oscillation + #endif +#endif + +// @section cnc + +/** + * Spindle & Laser control + * + * Add the M3, M4, and M5 commands to turn the spindle/laser on and off, and + * to set spindle speed, spindle direction, and laser power. + * + * SuperPID is a router/spindle speed controller used in the CNC milling community. + * Marlin can be used to turn the spindle on and off. It can also be used to set + * the spindle speed from 5,000 to 30,000 RPM. + * + * You'll need to select a pin for the ON/OFF function and optionally choose a 0-5V + * hardware PWM pin for the speed control and a pin for the rotation direction. + * + * See https://marlinfw.org/docs/configuration/2.0.9/laser_spindle.html for more config details. + */ +//#define SPINDLE_FEATURE +//#define LASER_FEATURE +#if ANY(SPINDLE_FEATURE, LASER_FEATURE) + #define SPINDLE_LASER_ACTIVE_STATE LOW // Set to "HIGH" if SPINDLE_LASER_ENA_PIN is active HIGH + + #define SPINDLE_LASER_USE_PWM // Enable if your controller supports setting the speed/power + #if ENABLED(SPINDLE_LASER_USE_PWM) + #define SPINDLE_LASER_PWM_INVERT false // Set to "true" if the speed/power goes up when you want it to go slower + #define SPINDLE_LASER_FREQUENCY 2500 // (Hz) Spindle/laser frequency (only on supported HALs: AVR, ESP32, and LPC) + // ESP32: If SPINDLE_LASER_PWM_PIN is onboard then <=78125Hz. For I2S expander + // the frequency determines the PWM resolution. 2500Hz = 0-100, 977Hz = 0-255, ... + // (250000 / SPINDLE_LASER_FREQUENCY) = max value. + #endif + + //#define AIR_EVACUATION // Cutter Vacuum / Laser Blower motor control with G-codes M10-M11 + #if ENABLED(AIR_EVACUATION) + #define AIR_EVACUATION_ACTIVE LOW // Set to "HIGH" if the on/off function is active HIGH + //#define AIR_EVACUATION_PIN 42 // Override the default Cutter Vacuum or Laser Blower pin + #endif + + //#define AIR_ASSIST // Air Assist control with G-codes M8-M9 + #if ENABLED(AIR_ASSIST) + #define AIR_ASSIST_ACTIVE LOW // Active state on air assist pin + //#define AIR_ASSIST_PIN 44 // Override the default Air Assist pin + #endif + + //#define SPINDLE_SERVO // A servo converting an angle to spindle power + #ifdef SPINDLE_SERVO + #define SPINDLE_SERVO_NR 0 // Index of servo used for spindle control + #define SPINDLE_SERVO_MIN 10 // Minimum angle for servo spindle + #endif + + /** + * Speed / Power can be set ('M3 S') and displayed in terms of: + * - PWM255 (S0 - S255) + * - PERCENT (S0 - S100) + * - RPM (S0 - S50000) Best for use with a spindle + * - SERVO (S0 - S180) + */ + #define CUTTER_POWER_UNIT PWM255 + + /** + * Relative Cutter Power + * Normally, 'M3 O' sets + * OCR power is relative to the range SPEED_POWER_MIN...SPEED_POWER_MAX. + * so input powers of 0...255 correspond to SPEED_POWER_MIN...SPEED_POWER_MAX + * instead of normal range (0 to SPEED_POWER_MAX). + * Best used with (e.g.) SuperPID router controller: S0 = 5,000 RPM and S255 = 30,000 RPM + */ + //#define CUTTER_POWER_RELATIVE // Set speed proportional to [SPEED_POWER_MIN...SPEED_POWER_MAX] + + #if ENABLED(SPINDLE_FEATURE) + //#define SPINDLE_CHANGE_DIR // Enable if your spindle controller can change spindle direction + #define SPINDLE_CHANGE_DIR_STOP // Enable if the spindle should stop before changing spin direction + #define SPINDLE_INVERT_DIR false // Set to "true" if the spin direction is reversed + + #define SPINDLE_LASER_POWERUP_DELAY 5000 // (ms) Delay to allow the spindle/laser to come up to speed/power + #define SPINDLE_LASER_POWERDOWN_DELAY 5000 // (ms) Delay to allow the spindle to stop + + /** + * M3/M4 Power Equation + * + * Each tool uses different value ranges for speed / power control. + * These parameters are used to convert between tool power units and PWM. + * + * Speed/Power = (PWMDC / 255 * 100 - SPEED_POWER_INTERCEPT) / SPEED_POWER_SLOPE + * PWMDC = (spdpwr - SPEED_POWER_MIN) / (SPEED_POWER_MAX - SPEED_POWER_MIN) / SPEED_POWER_SLOPE + */ + #if ENABLED(SPINDLE_LASER_USE_PWM) + #define SPEED_POWER_INTERCEPT 0 // (%) 0-100 i.e., Minimum power percentage + #define SPEED_POWER_MIN 5000 // (RPM) + #define SPEED_POWER_MAX 30000 // (RPM) SuperPID router controller 0 - 30,000 RPM + #define SPEED_POWER_STARTUP 25000 // (RPM) M3/M4 speed/power default (with no arguments) + + //#define DEFAULT_ACCELERATION_SPINDLE 1000 // (°/s/s) Default spindle acceleration (speed change with time) + #endif + + #else + + #if ENABLED(SPINDLE_LASER_USE_PWM) + #define SPEED_POWER_INTERCEPT 0 // (%) 0-100 i.e., Minimum power percentage + #define SPEED_POWER_MIN 0 // (%) 0-100 + #define SPEED_POWER_MAX 100 // (%) 0-100 + #define SPEED_POWER_STARTUP 80 // (%) M3/M4 speed/power default (with no arguments) + #endif + + // Define the minimum and maximum test pulse time values for a laser test fire function + #define LASER_TEST_PULSE_MIN 1 // (ms) Used with Laser Control Menu + #define LASER_TEST_PULSE_MAX 999 // (ms) Caution: Menu may not show more than 3 characters + + #define SPINDLE_LASER_POWERUP_DELAY 50 // (ms) Delay to allow the spindle/laser to come up to speed/power + #define SPINDLE_LASER_POWERDOWN_DELAY 50 // (ms) Delay to allow the spindle to stop + + /** + * Laser Safety Timeout + * + * The laser should be turned off when there is no movement for a period of time. + * Consider material flammability, cut rate, and G-code order when setting this + * value. Too low and it could turn off during a very slow move; too high and + * the material could ignite. + */ + #define LASER_SAFETY_TIMEOUT_MS 1000 // (ms) + + /** + * Any M3 or G1/2/3/5 command with the 'I' parameter enables continuous inline power mode. + * + * e.g., 'M3 I' enables continuous inline power which is processed by the planner. + * Power is stored in move blocks and applied when blocks are processed by the Stepper ISR. + * + * 'M4 I' sets dynamic mode which uses the current feedrate to calculate a laser power OCR value. + * + * Any move in dynamic mode will use the current feedrate to calculate the laser power. + * Feed rates are set by the F parameter of a move command e.g. G1 X0 Y10 F6000 + * Laser power would be calculated by bit shifting off 8 LSB's. In binary this is div 256. + * The calculation gives us ocr values from 0 to 255, values over F65535 will be set as 255 . + * More refined power control such as compensation for accel/decel will be addressed in future releases. + * + * M5 I clears inline mode and set power to 0, M5 sets the power output to 0 but leaves inline mode on. + */ + + /** + * Enable M3 commands for laser mode inline power planner syncing. + * This feature enables any M3 S-value to be injected into the block buffers while in + * CUTTER_MODE_CONTINUOUS. The option allows M3 laser power to be committed without waiting + * for a planner synchronization + */ + //#define LASER_POWER_SYNC + + /** + * Scale the laser's power in proportion to the movement rate. + * + * - Sets the entry power proportional to the entry speed over the nominal speed. + * - Ramps the power up every N steps to approximate the speed trapezoid. + * - Due to the limited power resolution this is only approximate. + */ + //#define LASER_POWER_TRAP + + // + // Laser I2C Ammeter (High precision INA226 low/high side module) + // + //#define I2C_AMMETER + #if ENABLED(I2C_AMMETER) + #define I2C_AMMETER_IMAX 0.1 // (Amps) Calibration value for the expected current range + #define I2C_AMMETER_SHUNT_RESISTOR 0.1 // (Ohms) Calibration shunt resistor value + #endif + + // + // Laser Coolant Flow Meter + // + //#define LASER_COOLANT_FLOW_METER + #if ENABLED(LASER_COOLANT_FLOW_METER) + #define FLOWMETER_PIN 20 // Requires an external interrupt-enabled pin (e.g., RAMPS 2,3,18,19,20,21) + #define FLOWMETER_PPL 5880 // (pulses/liter) Flow meter pulses-per-liter on the input pin + #define FLOWMETER_INTERVAL 1000 // (ms) Flow rate calculation interval in milliseconds + #define FLOWMETER_SAFETY // Prevent running the laser without the minimum flow rate set below + #if ENABLED(FLOWMETER_SAFETY) + #define FLOWMETER_MIN_LITERS_PER_MINUTE 1.5 // (liters/min) Minimum flow required when enabled + #endif + #endif + + #endif +#endif // SPINDLE_FEATURE || LASER_FEATURE + +/** + * Synchronous Laser Control with M106/M107 + * + * Marlin normally applies M106/M107 fan speeds at a time "soon after" processing + * a planner block. This is too inaccurate for a PWM/TTL laser attached to the fan + * header (as with some add-on laser kits). Enable this option to set fan/laser + * speeds with much more exact timing for improved print fidelity. + * + * NOTE: This option sacrifices some cooling fan speed options. + */ +//#define LASER_SYNCHRONOUS_M106_M107 + +/** + * Coolant Control + * + * Add the M7, M8, and M9 commands to turn mist or flood coolant on and off. + * + * Note: COOLANT_MIST_PIN and/or COOLANT_FLOOD_PIN must also be defined. + */ +//#define COOLANT_CONTROL +#if ENABLED(COOLANT_CONTROL) + #define COOLANT_MIST // Enable if mist coolant is present + #define COOLANT_FLOOD // Enable if flood coolant is present + #define COOLANT_MIST_INVERT false // Set "true" if the on/off function is reversed + #define COOLANT_FLOOD_INVERT false // Set "true" if the on/off function is reversed +#endif + +// @section filament width + +/** + * Filament Width Sensor + * + * Measures the filament width in real-time and adjusts + * flow rate to compensate for any irregularities. + * + * Also allows the measured filament diameter to set the + * extrusion rate, so the slicer only has to specify the + * volume. + * + * Only a single extruder is supported at this time. + * + * 34 RAMPS_14 : Analog input 5 on the AUX2 connector + * 81 PRINTRBOARD : Analog input 2 on the Exp1 connector (version B,C,D,E) + * 301 RAMBO : Analog input 3 + * + * Note: May require analog pins to be defined for other boards. + */ +//#define FILAMENT_WIDTH_SENSOR + +#if ENABLED(FILAMENT_WIDTH_SENSOR) + #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor. :[0,1,2,3,4] + #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber + + #define FILWIDTH_ERROR_MARGIN 1.0 // (mm) If a measurement differs too much from nominal width ignore it + #define MAX_MEASUREMENT_DELAY 20 // (bytes) Buffer size for stored measurements (1 byte per cm). Must be larger than MEASUREMENT_DELAY_CM. + + #define DEFAULT_MEASURED_FILAMENT_DIA DEFAULT_NOMINAL_FILAMENT_DIA // Set measured to nominal initially + + // Display filament width on the LCD status line. Status messages will expire after 5 seconds. + //#define FILAMENT_LCD_DISPLAY +#endif + +// @section power + +/** + * Power Monitor + * Monitor voltage (V) and/or current (A), and -when possible- power (W) + * + * Read and configure with M430 + * + * The current sensor feeds DC voltage (relative to the measured current) to an analog pin + * The voltage sensor feeds DC voltage (relative to the measured voltage) to an analog pin + */ +//#define POWER_MONITOR_CURRENT // Monitor the system current +//#define POWER_MONITOR_VOLTAGE // Monitor the system voltage + +#if ENABLED(POWER_MONITOR_CURRENT) + #define POWER_MONITOR_VOLTS_PER_AMP 0.05000 // Input voltage to the MCU analog pin per amp - DO NOT apply more than ADC_VREF! + #define POWER_MONITOR_CURRENT_OFFSET 0 // Offset (in amps) applied to the calculated current + #define POWER_MONITOR_FIXED_VOLTAGE 13.6 // Voltage for a current sensor with no voltage sensor (for power display) +#endif + +#if ENABLED(POWER_MONITOR_VOLTAGE) + #define POWER_MONITOR_VOLTS_PER_VOLT 0.077933 // Input voltage to the MCU analog pin per volt - DO NOT apply more than ADC_VREF! + #define POWER_MONITOR_VOLTAGE_OFFSET 0 // Offset (in volts) applied to the calculated voltage +#endif + +// @section safety + +/** + * Stepper Driver Anti-SNAFU Protection + * + * If the SAFE_POWER_PIN is defined for your board, Marlin will check + * that stepper drivers are properly plugged in before applying power. + * Disable protection if your stepper drivers don't support the feature. + */ +//#define DISABLE_DRIVER_SAFE_POWER_PROTECT + +// @section cnc + +/** + * CNC Coordinate Systems + * + * Enables G53 and G54-G59.3 commands to select coordinate systems + * and G92.1 to reset the workspace to native machine space. + */ +//#define CNC_COORDINATE_SYSTEMS + +// @section security + +/** + * Expected Printer Check + * Add the M16 G-code to compare a string to the MACHINE_NAME. + * M16 with a non-matching string causes the printer to halt. + */ +//#define EXPECTED_PRINTER_CHECK + +// @section volumetrics + +/** + * Disable all Volumetric extrusion options + */ +//#define NO_VOLUMETRICS + +#if DISABLED(NO_VOLUMETRICS) + /** + * Volumetric extrusion default state + * Activate to make volumetric extrusion the default method, + * with DEFAULT_NOMINAL_FILAMENT_DIA as the default diameter. + * + * M200 D0 to disable, M200 Dn to set a new diameter (and enable volumetric). + * M200 S0/S1 to disable/enable volumetric extrusion. + */ + //#define VOLUMETRIC_DEFAULT_ON + + //#define VOLUMETRIC_EXTRUDER_LIMIT + #if ENABLED(VOLUMETRIC_EXTRUDER_LIMIT) + /** + * Default volumetric extrusion limit in cubic mm per second (mm^3/sec). + * This factory setting applies to all extruders. + * Use 'M200 [T] L' to override and 'M502' to reset. + * A non-zero value activates Volume-based Extrusion Limiting. + */ + #define DEFAULT_VOLUMETRIC_EXTRUDER_LIMIT 0.00 // (mm^3/sec) + #define VOLUMETRIC_EXTRUDER_LIMIT_MAX 20 // (mm^3/sec) + #endif +#endif + +// @section reporting + +/** + * Extra options for the M114 "Current Position" report + */ +//#define M114_DETAIL // Use 'M114 D' for details to check planner calculations +//#define M114_REALTIME // Real current position based on forward kinematics +//#define M114_LEGACY // M114 used to synchronize on every call. Enable if needed. + +/** + * Auto-report fan speed with M123 S + * Requires fans with tachometer pins + */ +//#define AUTO_REPORT_FANS + +//#define REPORT_FAN_CHANGE // Report the new fan speed when changed by M106 (and others) + +/** + * Auto-report temperatures with M155 S + */ +#define AUTO_REPORT_TEMPERATURES +#if ENABLED(AUTO_REPORT_TEMPERATURES) && TEMP_SENSOR_REDUNDANT + //#define AUTO_REPORT_REDUNDANT // Include the "R" sensor in the auto-report +#endif + +/** + * Auto-report position with M154 S + */ +//#define AUTO_REPORT_POSITION +#if ENABLED(AUTO_REPORT_POSITION) + //#define AUTO_REPORT_REAL_POSITION // Auto-report the real position +#endif + +/** + * M115 - Report capabilities. Disable to save ~1150 bytes of flash. + * Some hosts (and serial TFT displays) rely on this feature. + */ +#define CAPABILITIES_REPORT +#if ENABLED(CAPABILITIES_REPORT) + // Include capabilities in M115 output + #define EXTENDED_CAPABILITIES_REPORT + #if ENABLED(EXTENDED_CAPABILITIES_REPORT) + //#define M115_GEOMETRY_REPORT + #endif +#endif + +// @section gcode + +/** + * Spend 28 bytes of SRAM to optimize the G-code parser + */ +#define FASTER_GCODE_PARSER +#if ENABLED(FASTER_GCODE_PARSER) + //#define GCODE_QUOTED_STRINGS // Support for quoted string parameters +#endif + +/** + * Support for MeatPack G-code compression (https://github.com/scottmudge/OctoPrint-MeatPack) + */ +//#define MEATPACK_ON_SERIAL_PORT_1 +//#define MEATPACK_ON_SERIAL_PORT_2 + +//#define GCODE_CASE_INSENSITIVE // Accept G-code sent to the firmware in lowercase + +//#define REPETIER_GCODE_M360 // Add commands originally from Repetier FW + +/** + * Enable M111 debug flags 1=ECHO, 2=INFO, 4=ERRORS (unimplemented). + * Disable to save some flash. Some hosts (Repetier Host) may rely on this feature. + */ +#define DEBUG_FLAGS_GCODE + +/** + * Enable this option for a leaner build of Marlin that removes + * workspace offsets to slightly optimize performance. + * G92 will revert to its behavior from Marlin 1.0. + */ +//#define NO_WORKSPACE_OFFSETS + +/** + * Disable M206 and M428 if you don't need home offsets. + */ +//#define NO_HOME_OFFSETS + +/** + * CNC G-code options + * Support CNC-style G-code dialects used by laser cutters, drawing machine cams, etc. + * Note that G0 feedrates should be used with care for 3D printing (if used at all). + * High feedrates may cause ringing and harm print quality. + */ +//#define PAREN_COMMENTS // Support for parentheses-delimited comments +//#define GCODE_MOTION_MODES // Remember the motion mode (G0 G1 G2 G3 G5 G38.X) and apply for X Y Z E F, etc. + +// Enable and set a (default) feedrate for all G0 moves +//#define G0_FEEDRATE 3000 // (mm/min) +#ifdef G0_FEEDRATE + //#define VARIABLE_G0_FEEDRATE // The G0 feedrate is set by F in G0 motion mode +#endif + +/** + * Startup commands + * + * Execute certain G-code commands immediately after power-on. + */ +//#define STARTUP_COMMANDS "M17 Z" + +/** + * G-code Macros + * + * Add G-codes M810-M819 to define and run G-code macros. + * Macros are not saved to EEPROM. + */ +//#define GCODE_MACROS +#if ENABLED(GCODE_MACROS) + #define GCODE_MACROS_SLOTS 5 // Up to 10 may be used + #define GCODE_MACROS_SLOT_SIZE 50 // Maximum length of a single macro +#endif + +/** + * User-defined menu items to run custom G-code. + * Up to 25 may be defined, but the actual number is LCD-dependent. + */ + +// @section custom main menu + +// Custom Menu: Main Menu +//#define CUSTOM_MENU_MAIN +#if ENABLED(CUSTOM_MENU_MAIN) + //#define CUSTOM_MENU_MAIN_TITLE "Custom Commands" + #define CUSTOM_MENU_MAIN_SCRIPT_DONE "M117 User Script Done" + #define CUSTOM_MENU_MAIN_SCRIPT_AUDIBLE_FEEDBACK + //#define CUSTOM_MENU_MAIN_SCRIPT_RETURN // Return to status screen after a script + #define CUSTOM_MENU_MAIN_ONLY_IDLE // Only show custom menu when the machine is idle + + #define MAIN_MENU_ITEM_1_DESC "Home & UBL Info" + #define MAIN_MENU_ITEM_1_GCODE "G28\nG29 W" + //#define MAIN_MENU_ITEM_1_CONFIRM // Show a confirmation dialog before this action + + #define MAIN_MENU_ITEM_2_DESC "Preheat for " PREHEAT_1_LABEL + #define MAIN_MENU_ITEM_2_GCODE "M140 S" STRINGIFY(PREHEAT_1_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND) + //#define MAIN_MENU_ITEM_2_CONFIRM + + //#define MAIN_MENU_ITEM_3_DESC "Preheat for " PREHEAT_2_LABEL + //#define MAIN_MENU_ITEM_3_GCODE "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_2_TEMP_HOTEND) + //#define MAIN_MENU_ITEM_3_CONFIRM + + //#define MAIN_MENU_ITEM_4_DESC "Heat Bed/Home/Level" + //#define MAIN_MENU_ITEM_4_GCODE "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nG28\nG29" + //#define MAIN_MENU_ITEM_4_CONFIRM + + //#define MAIN_MENU_ITEM_5_DESC "Home & Info" + //#define MAIN_MENU_ITEM_5_GCODE "G28\nM503" + //#define MAIN_MENU_ITEM_5_CONFIRM +#endif + +// @section custom config menu + +// Custom Menu: Configuration Menu +//#define CUSTOM_MENU_CONFIG +#if ENABLED(CUSTOM_MENU_CONFIG) + //#define CUSTOM_MENU_CONFIG_TITLE "Custom Commands" + #define CUSTOM_MENU_CONFIG_SCRIPT_DONE "M117 Wireless Script Done" + #define CUSTOM_MENU_CONFIG_SCRIPT_AUDIBLE_FEEDBACK + //#define CUSTOM_MENU_CONFIG_SCRIPT_RETURN // Return to status screen after a script + #define CUSTOM_MENU_CONFIG_ONLY_IDLE // Only show custom menu when the machine is idle + + #define CONFIG_MENU_ITEM_1_DESC "Wifi ON" + #define CONFIG_MENU_ITEM_1_GCODE "M118 [ESP110] WIFI-STA pwd=12345678" + //#define CONFIG_MENU_ITEM_1_CONFIRM // Show a confirmation dialog before this action + + #define CONFIG_MENU_ITEM_2_DESC "Bluetooth ON" + #define CONFIG_MENU_ITEM_2_GCODE "M118 [ESP110] BT pwd=12345678" + //#define CONFIG_MENU_ITEM_2_CONFIRM + + //#define CONFIG_MENU_ITEM_3_DESC "Radio OFF" + //#define CONFIG_MENU_ITEM_3_GCODE "M118 [ESP110] OFF pwd=12345678" + //#define CONFIG_MENU_ITEM_3_CONFIRM + + //#define CONFIG_MENU_ITEM_4_DESC "Wifi ????" + //#define CONFIG_MENU_ITEM_4_GCODE "M118 ????" + //#define CONFIG_MENU_ITEM_4_CONFIRM + + //#define CONFIG_MENU_ITEM_5_DESC "Wifi ????" + //#define CONFIG_MENU_ITEM_5_GCODE "M118 ????" + //#define CONFIG_MENU_ITEM_5_CONFIRM +#endif + +// @section custom buttons + +/** + * User-defined buttons to run custom G-code. + * Up to 25 may be defined. + */ +//#define CUSTOM_USER_BUTTONS +#if ENABLED(CUSTOM_USER_BUTTONS) + //#define BUTTON1_PIN -1 + #if PIN_EXISTS(BUTTON1) + #define BUTTON1_HIT_STATE LOW // State of the triggered button. NC=LOW. NO=HIGH. + #define BUTTON1_WHEN_PRINTING false // Button allowed to trigger during printing? + #define BUTTON1_GCODE "G28" + #define BUTTON1_DESC "Homing" // Optional string to set the LCD status + #endif + + //#define BUTTON2_PIN -1 + #if PIN_EXISTS(BUTTON2) + #define BUTTON2_HIT_STATE LOW + #define BUTTON2_WHEN_PRINTING false + #define BUTTON2_GCODE "M140 S" STRINGIFY(PREHEAT_1_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND) + #define BUTTON2_DESC "Preheat for " PREHEAT_1_LABEL + #endif + + //#define BUTTON3_PIN -1 + #if PIN_EXISTS(BUTTON3) + #define BUTTON3_HIT_STATE LOW + #define BUTTON3_WHEN_PRINTING false + #define BUTTON3_GCODE "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_2_TEMP_HOTEND) + #define BUTTON3_DESC "Preheat for " PREHEAT_2_LABEL + #endif +#endif + +// @section host + +/** + * Host Action Commands + * + * Define host streamer action commands in compliance with the standard. + * + * See https://reprap.org/wiki/G-code#Action_commands + * Common commands ........ poweroff, pause, paused, resume, resumed, cancel + * G29_RETRY_AND_RECOVER .. probe_rewipe, probe_failed + * + * Some features add reason codes to extend these commands. + * + * Host Prompt Support enables Marlin to use the host for user prompts so + * filament runout and other processes can be managed from the host side. + */ +//#define HOST_ACTION_COMMANDS +#if ENABLED(HOST_ACTION_COMMANDS) + //#define HOST_PAUSE_M76 // Tell the host to pause in response to M76 + //#define HOST_PROMPT_SUPPORT // Initiate host prompts to get user feedback + #if ENABLED(HOST_PROMPT_SUPPORT) + //#define HOST_STATUS_NOTIFICATIONS // Send some status messages to the host as notifications + #endif + //#define HOST_START_MENU_ITEM // Add a menu item that tells the host to start + //#define HOST_SHUTDOWN_MENU_ITEM // Add a menu item that tells the host to shut down +#endif + +// @section extras + +/** + * Cancel Objects + * + * Implement M486 to allow Marlin to skip objects + */ +//#define CANCEL_OBJECTS +#if ENABLED(CANCEL_OBJECTS) + #define CANCEL_OBJECTS_REPORTING // Emit the current object as a status message +#endif + +/** + * I2C position encoders for closed loop control. + * Developed by Chris Barr at Aus3D. + * + * Wiki: https://wiki.aus3d.com.au/Magnetic_Encoder + * Github: https://github.com/Aus3D/MagneticEncoder + * + * Supplier: https://aus3d.com.au/products/magnetic-encoder-module + * Alternative Supplier: https://reliabuild3d.com/ + * + * Reliabuild encoders have been modified to improve reliability. + * @section i2c encoders + */ + +//#define I2C_POSITION_ENCODERS +#if ENABLED(I2C_POSITION_ENCODERS) + + #define I2CPE_ENCODER_CNT 1 // The number of encoders installed; max of 5 + // encoders supported currently. + + #define I2CPE_ENC_1_ADDR I2CPE_PRESET_ADDR_X // I2C address of the encoder. 30-200. + #define I2CPE_ENC_1_AXIS X_AXIS // Axis the encoder module is installed on. _AXIS. + #define I2CPE_ENC_1_TYPE I2CPE_ENC_TYPE_LINEAR // Type of encoder: I2CPE_ENC_TYPE_LINEAR -or- + // I2CPE_ENC_TYPE_ROTARY. + #define I2CPE_ENC_1_TICKS_UNIT 2048 // 1024 for magnetic strips with 2mm poles; 2048 for + // 1mm poles. For linear encoders this is ticks / mm, + // for rotary encoders this is ticks / revolution. + //#define I2CPE_ENC_1_TICKS_REV (16 * 200) // Only needed for rotary encoders; number of stepper + // steps per full revolution (motor steps/rev * microstepping) + //#define I2CPE_ENC_1_INVERT // Invert the direction of axis travel. + #define I2CPE_ENC_1_EC_METHOD I2CPE_ECM_MICROSTEP // Type of error error correction. + #define I2CPE_ENC_1_EC_THRESH 0.10 // Threshold size for error (in mm) above which the + // printer will attempt to correct the error; errors + // smaller than this are ignored to minimize effects of + // measurement noise / latency (filter). + + #define I2CPE_ENC_2_ADDR I2CPE_PRESET_ADDR_Y // Same as above, but for encoder 2. + #define I2CPE_ENC_2_AXIS Y_AXIS + #define I2CPE_ENC_2_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_ENC_2_TICKS_UNIT 2048 + //#define I2CPE_ENC_2_TICKS_REV (16 * 200) + //#define I2CPE_ENC_2_INVERT + #define I2CPE_ENC_2_EC_METHOD I2CPE_ECM_MICROSTEP + #define I2CPE_ENC_2_EC_THRESH 0.10 + + #define I2CPE_ENC_3_ADDR I2CPE_PRESET_ADDR_Z // Encoder 3. Add additional configuration options + #define I2CPE_ENC_3_AXIS Z_AXIS // as above, or use defaults below. + + #define I2CPE_ENC_4_ADDR I2CPE_PRESET_ADDR_E // Encoder 4. + #define I2CPE_ENC_4_AXIS E_AXIS + + #define I2CPE_ENC_5_ADDR 34 // Encoder 5. + #define I2CPE_ENC_5_AXIS E_AXIS + + // Default settings for encoders which are enabled, but without settings configured above. + #define I2CPE_DEF_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_DEF_ENC_TICKS_UNIT 2048 + #define I2CPE_DEF_TICKS_REV (16 * 200) + #define I2CPE_DEF_EC_METHOD I2CPE_ECM_NONE + #define I2CPE_DEF_EC_THRESH 0.1 + + //#define I2CPE_ERR_THRESH_ABORT 100.0 // Threshold size for error (in mm) error on any given + // axis after which the printer will abort. Comment out to + // disable abort behavior. + + #define I2CPE_TIME_TRUSTED 10000 // After an encoder fault, there must be no further fault + // for this amount of time (in ms) before the encoder + // is trusted again. + + /** + * Position is checked every time a new command is executed from the buffer but during long moves, + * this setting determines the minimum update time between checks. A value of 100 works well with + * error rolling average when attempting to correct only for skips and not for vibration. + */ + #define I2CPE_MIN_UPD_TIME_MS 4 // (ms) Minimum time between encoder checks. + + // Use a rolling average to identify persistent errors that indicate skips, as opposed to vibration and noise. + #define I2CPE_ERR_ROLLING_AVERAGE + +#endif // I2C_POSITION_ENCODERS + +/** + * Analog Joystick(s) + * @section joystick + */ +//#define JOYSTICK +#if ENABLED(JOYSTICK) + #define JOY_X_PIN 5 // RAMPS: Suggested pin A5 on AUX2 + #define JOY_Y_PIN 10 // RAMPS: Suggested pin A10 on AUX2 + #define JOY_Z_PIN 12 // RAMPS: Suggested pin A12 on AUX2 + #define JOY_EN_PIN 44 // RAMPS: Suggested pin D44 on AUX2 + + //#define INVERT_JOY_X // Enable if X direction is reversed + //#define INVERT_JOY_Y // Enable if Y direction is reversed + //#define INVERT_JOY_Z // Enable if Z direction is reversed + + // Use M119 with JOYSTICK_DEBUG to find reasonable values after connecting: + #define JOY_X_LIMITS { 5600, 8190-100, 8190+100, 10800 } // min, deadzone start, deadzone end, max + #define JOY_Y_LIMITS { 5600, 8250-100, 8250+100, 11000 } + #define JOY_Z_LIMITS { 4800, 8080-100, 8080+100, 11550 } + //#define JOYSTICK_DEBUG +#endif + +/** + * Mechanical Gantry Calibration + * Modern replacement for the Průša TMC_Z_CALIBRATION. + * Adds capability to work with any adjustable current drivers. + * Implemented as G34 because M915 is deprecated. + * @section calibrate + */ +//#define MECHANICAL_GANTRY_CALIBRATION +#if ENABLED(MECHANICAL_GANTRY_CALIBRATION) + #define GANTRY_CALIBRATION_CURRENT 600 // Default calibration current in ma + #define GANTRY_CALIBRATION_EXTRA_HEIGHT 15 // Extra distance in mm past Z_###_POS to move + #define GANTRY_CALIBRATION_FEEDRATE 500 // Feedrate for correction move + //#define GANTRY_CALIBRATION_TO_MIN // Enable to calibrate Z in the MIN direction + + //#define GANTRY_CALIBRATION_SAFE_POSITION XY_CENTER // Safe position for nozzle + //#define GANTRY_CALIBRATION_XY_PARK_FEEDRATE 3000 // XY Park Feedrate - MMM + //#define GANTRY_CALIBRATION_COMMANDS_PRE "" + #define GANTRY_CALIBRATION_COMMANDS_POST "G28" // G28 highly recommended to ensure an accurate position +#endif + +/** + * Instant freeze / unfreeze functionality + * Potentially useful for rapid stop that allows being resumed. Halts stepper movement. + * Note this does NOT pause spindles, lasers, fans, heaters or any other auxiliary device. + * @section interface + */ +//#define FREEZE_FEATURE +#if ENABLED(FREEZE_FEATURE) + //#define FREEZE_PIN 41 // Override the default (KILL) pin here + #define FREEZE_STATE LOW // State of pin indicating freeze +#endif + +/** + * MAX7219 Debug Matrix + * + * Add support for a low-cost 8x8 LED Matrix based on the Max7219 chip as a realtime status display. + * Requires 3 signal wires. Some useful debug options are included to demonstrate its usage. + * @section debug matrix + */ +//#define MAX7219_DEBUG +#if ENABLED(MAX7219_DEBUG) + #define MAX7219_CLK_PIN 64 + #define MAX7219_DIN_PIN 57 + #define MAX7219_LOAD_PIN 44 + + //#define MAX7219_GCODE // Add the M7219 G-code to control the LED matrix + #define MAX7219_INIT_TEST 2 // Test pattern at startup: 0=none, 1=sweep, 2=spiral + #define MAX7219_NUMBER_UNITS 1 // Number of Max7219 units in chain. + #define MAX7219_ROTATE 0 // Rotate the display clockwise (in multiples of +/- 90°) + // connector at: right=0 bottom=-90 top=90 left=180 + //#define MAX7219_REVERSE_ORDER // The order of the LED matrix units may be reversed + //#define MAX7219_REVERSE_EACH // The LEDs in each matrix unit row may be reversed + //#define MAX7219_SIDE_BY_SIDE // Big chip+matrix boards can be chained side-by-side + + /** + * Sample debug features + * If you add more debug displays, be careful to avoid conflicts! + */ + #define MAX7219_DEBUG_PRINTER_ALIVE // Blink corner LED of 8x8 matrix to show that the firmware is functioning + #define MAX7219_DEBUG_PLANNER_HEAD 2 // Show the planner queue head position on this and the next LED matrix row + #define MAX7219_DEBUG_PLANNER_TAIL 4 // Show the planner queue tail position on this and the next LED matrix row + + #define MAX7219_DEBUG_PLANNER_QUEUE 0 // Show the current planner queue depth on this and the next LED matrix row + // If you experience stuttering, reboots, etc. this option can reveal how + // tweaks made to the configuration are affecting the printer in real-time. + #define MAX7219_DEBUG_PROFILE 6 // Display the fraction of CPU time spent in profiled code on this LED matrix + // row. By default idle() is profiled so this shows how "idle" the processor is. + // See class CodeProfiler. + //#define MAX7219_DEBUG_MULTISTEPPING 6 // Show multi-stepping 1 to 128 on this LED matrix row. + //#define MAX7219_DEBUG_SLOWDOWN 6 // Count (mod 16) how many times SLOWDOWN has reduced print speed. + //#define MAX7219_REINIT_ON_POWERUP // Re-initialize MAX7129 when power supply turns on +#endif + +/** + * NanoDLP Sync support + * + * Support for Synchronized Z moves when used with NanoDLP. G0/G1 axis moves will + * output a "Z_move_comp" string to enable synchronization with DLP projector exposure. + * This feature allows you to use [[WaitForDoneMessage]] instead of M400 commands. + * @section nanodlp + */ +//#define NANODLP_Z_SYNC +#if ENABLED(NANODLP_Z_SYNC) + //#define NANODLP_ALL_AXIS // Send a "Z_move_comp" report for any axis move (not just Z). +#endif + +/** + * Ethernet. Use M552 to enable and set the IP address. + * @section network + */ +#if HAS_ETHERNET + #define MAC_ADDRESS { 0xDE, 0xAD, 0xBE, 0xEF, 0xF0, 0x0D } // A MAC address unique to your network +#endif + +/** + * Native ESP32 board with WiFi or add-on ESP32 WiFi-101 module + */ +//#define WIFISUPPORT // Marlin embedded WiFi management. Not needed for simple WiFi serial port. +//#define ESP3D_WIFISUPPORT // ESP3D Library WiFi management (https://github.com/luc-github/ESP3DLib) + +/** + * Extras for an ESP32-based motherboard with WIFISUPPORT + * These options don't apply to add-on WiFi modules based on ESP32 WiFi101. + */ +#if ANY(WIFISUPPORT, ESP3D_WIFISUPPORT) + //#define WEBSUPPORT // Start a webserver (which may include auto-discovery) using SPIFFS + //#define OTASUPPORT // Support over-the-air firmware updates + //#define WIFI_CUSTOM_COMMAND // Accept feature config commands (e.g., WiFi ESP3D) from the host + + /** + * To set a default WiFi SSID / Password, create a file called Configuration_Secure.h with + * the following defines, customized for your network. This specific file is excluded via + * .gitignore to prevent it from accidentally leaking to the public. + * + * #define WIFI_SSID "WiFi SSID" + * #define WIFI_PWD "WiFi Password" + */ + //#include "Configuration_Secure.h" // External file with WiFi SSID / Password +#endif + +// @section multi-material + +/** + * Průša Multi-Material Unit (MMU) + * Enable in Configuration.h + * + * These devices allow a single stepper driver on the board to drive + * multi-material feeders with any number of stepper motors. + */ +#if HAS_PRUSA_MMU1 + /** + * This option only allows the multiplexer to switch on tool-change. + * Additional options to configure custom E moves are pending. + * + * Override the default DIO selector pins here, if needed. + * Some pins files may provide defaults for these pins. + */ + //#define E_MUX0_PIN 40 // Always Required + //#define E_MUX1_PIN 42 // Needed for 3 to 8 inputs + //#define E_MUX2_PIN 44 // Needed for 5 to 8 inputs + +#elif HAS_PRUSA_MMU2 || HAS_PRUSA_MMU3 + // Common settings for MMU2/MMU2S/MMU3 + // Serial port used for communication with MMU2/MMU2S/MMU3. + #define MMU_SERIAL_PORT 2 + #define MMU_BAUD 115200 + + //#define MMU_RST_PIN 23 // Define this pin to use Hardware Reset for MMU2/MMU2S/MMU3 + + //#define MMU_MENUS // Add an LCD menu for MMU2/MMU2S/MMU3 + + //#define MMU_DEBUG // Write debug info to serial output + + // Options pertaining to MMU2 and MMU2S + #if HAS_PRUSA_MMU2 + // Enable if the MMU2 has 12V stepper motors (MMU2 Firmware 1.0.2 and up) + //#define MMU2_MODE_12V + + // Settings for filament load / unload from the LCD menu. + // This is for Průša MK3-style extruders. Customize for your hardware. + #define MMU2_FILAMENTCHANGE_EJECT_FEED 80.0 + + // G-code to execute when MMU2 F.I.N.D.A. probe detects filament runout + #define MMU2_FILAMENT_RUNOUT_SCRIPT "M600" + + // MMU2 sequences use mm/min. Not compatible with MMU3, which use mm/sec. + #define MMU2_LOAD_TO_NOZZLE_SEQUENCE \ + { 4.4, 871 }, \ + { 10.0, 1393 }, \ + { 4.4, 871 }, \ + { 10.0, 198 } + + #define MMU2_RAMMING_SEQUENCE \ + { 1.0, 1000 }, \ + { 1.0, 1500 }, \ + { 2.0, 2000 }, \ + { 1.5, 3000 }, \ + { 2.5, 4000 }, \ + { -15.0, 5000 }, \ + { -14.0, 1200 }, \ + { -6.0, 600 }, \ + { 10.0, 700 }, \ + { -10.0, 400 }, \ + { -50.0, 2000 } + + #endif // HAS_PRUSA_MMU2 + + /** + * Options pertaining to MMU2S devices + * Requires the MK3S extruder with a sensor at the extruder idler, like the MMU2S. + * See https://help.prusa3d.com/guide/3b-mk3s-mk2-5s-extruder-upgrade_41560#42048, step 11 + */ + #if HAS_PRUSA_MMU2S + #define MMU2_C0_RETRY 5 // Number of retries (total time = timeout*retries) + + /** + * This is called after the filament runout sensor is triggered to check if + * the filament has been loaded properly by moving the filament back and + * forth to see if the filament runout sensor is going to get triggered + * again, which should not occur if the filament is properly loaded. + * + * Thus, the MMU2_CAN_LOAD_SEQUENCE should contain some forward and + * backward moves. The forward moves should be greater than the backward + * moves. + * + * This is useless if your filament runout sensor is way behind the gears. + * In that case use {0, MMU2_CAN_LOAD_FEEDRATE} + * + * Adjust MMU2_CAN_LOAD_SEQUENCE according to your setup. + */ + #define MMU2_CAN_LOAD_FEEDRATE 800 // (mm/min) + #define MMU2_CAN_LOAD_SEQUENCE \ + { 5.0, MMU2_CAN_LOAD_FEEDRATE }, \ + { 15.0, MMU2_CAN_LOAD_FEEDRATE }, \ + { -10.0, MMU2_CAN_LOAD_FEEDRATE } + + #define MMU2_CAN_LOAD_RETRACT 6.0 // (mm) Keep under the distance between Load Sequence values + #define MMU2_CAN_LOAD_DEVIATION 0.8 // (mm) Acceptable deviation + + #define MMU2_CAN_LOAD_INCREMENT 0.2 // (mm) To reuse within MMU2 module + #define MMU2_CAN_LOAD_INCREMENT_SEQUENCE \ + { -MMU2_CAN_LOAD_INCREMENT, MMU2_CAN_LOAD_FEEDRATE } + + // Continue unloading if sensor detects filament after the initial unload move + //#define MMU_IR_UNLOAD_MOVE + + #elif HAS_PRUSA_MMU3 + + // MMU3 settings + + #define MMU3_HAS_CUTTER // Enable cutter related functionality + + #define MMU3_MAX_RETRIES 3 // Number of retries (total time = timeout*retries) + + // As discussed with our PrusaSlicer profile specialist + // - ToolChange shall not try to push filament into the very tip of the nozzle + // to have some space for additional G-code to tune the extruded filament length + // in the profile + // Beware - this value is used to initialize the MMU logic layer - it will be sent to the MMU upon line up (written into its 8bit register 0x0b) + // However - in the G-code we can get a request to set the extra load distance at runtime to something else (M708 A0xb Xsomething). + // The printer intercepts such a call and sets its extra load distance to match the new value as well. + #define MMU3_FILAMENT_SENSOR_E_POSITION 0 // (mm) + #define _MMU3_LOAD_DISTANCE_PAST_GEARS 5 // (mm) + #define MMU3_TOOL_CHANGE_LOAD_LENGTH (MMU3_FILAMENT_SENSOR_E_POSITION + _MMU3_LOAD_DISTANCE_PAST_GEARS) // (mm) + + #define MMU3_LOAD_TO_NOZZLE_FEED_RATE 20.0 // (mm/s) + + #define MMU3_VERIFY_LOAD_TO_NOZZLE_FEED_RATE 50.0 // (mm/s) + #define _MMU3_VERIFY_LOAD_TO_NOZZLE_TWEAK -5.0 // (mm) Amount to adjust the length for verifying load-to-nozzle + + // The first thing the MMU does is initialize its axis. + // Meanwhile the E-motor will unload 20mm of filament in about 1 second. + #define MMU3_RETRY_UNLOAD_TO_FINDA_LENGTH 80.0 // (mm) + #define MMU3_RETRY_UNLOAD_TO_FINDA_FEED_RATE 80.0 // (mm/s) + + // After loading a new filament, the printer will extrude this length of filament + // then retract to the original position. This is used to check if the filament sensor + // reading flickers or filament is jammed. + #define _MMU_EXTRUDER_PTFE_LENGTH 42.3 // (mm) + #define _MMU_EXTRUDER_HEATBREAK_LENGTH 17.7 // (mm) + #define MMU3_CHECK_FILAMENT_PRESENCE_EXTRUSION_LENGTH (MMU3_FILAMENT_SENSOR_E_POSITION + _MMU_EXTRUDER_PTFE_LENGTH + _MMU_EXTRUDER_HEATBREAK_LENGTH + _MMU3_VERIFY_LOAD_TO_NOZZLE_TWEAK) // (mm) + + /** + * SpoolJoin Consumes All Filament -- EXPERIMENTAL + * + * SpoolJoin normally triggers when FINDA sensor untriggers while printing. + * This is the default behaviour and it doesn't consume all the filament + * before triggering a filament change. This leaves some filament in the + * current slot and before switching to the next slot it is unloaded. + * + * Enabling this option will trigger the filament change when both FINDA + * and Filament Runout Sensor triggers during the print and it allows the + * filament in the current slot to be completely consumed before doing the + * filament change. But this can cause problems as a little bit of filament + * will be left between the extruder gears (thinking that the filament + * sensor is triggered through the gears) and the end of the PTFE tube and + * can cause filament load issues. + */ + //#define MMU3_SPOOL_JOIN_CONSUMES_ALL_FILAMENT + + // MMU3 sequences use mm/sec. Not compatible with MMU2 which use mm/min. + #define MMU3_LOAD_TO_NOZZLE_SEQUENCE \ + { _MMU_EXTRUDER_PTFE_LENGTH, MMM_TO_MMS(810) }, /* (13.5 mm/s) Fast load ahead of heatbreak */ \ + { _MMU_EXTRUDER_HEATBREAK_LENGTH, MMM_TO_MMS(198) } /* ( 3.3 mm/s) Slow load after heatbreak */ + + #define MMU3_RAMMING_SEQUENCE \ + { 0.2816, MMM_TO_MMS(1339.0) }, \ + { 0.3051, MMM_TO_MMS(1451.0) }, \ + { 0.3453, MMM_TO_MMS(1642.0) }, \ + { 0.3990, MMM_TO_MMS(1897.0) }, \ + { 0.4761, MMM_TO_MMS(2264.0) }, \ + { 0.5767, MMM_TO_MMS(2742.0) }, \ + { 0.5691, MMM_TO_MMS(3220.0) }, \ + { 0.1081, MMM_TO_MMS(3220.0) }, \ + { 0.7644, MMM_TO_MMS(3635.0) }, \ + { 0.8248, MMM_TO_MMS(3921.0) }, \ + { 0.8483, MMM_TO_MMS(4033.0) }, \ + { -15.0, MMM_TO_MMS(6000.0) }, \ + { -24.5, MMM_TO_MMS(1200.0) }, \ + { -7.0, MMM_TO_MMS( 600.0) }, \ + { -3.5, MMM_TO_MMS( 360.0) }, \ + { 20.0, MMM_TO_MMS( 454.0) }, \ + { -20.0, MMM_TO_MMS( 303.0) }, \ + { -35.0, MMM_TO_MMS(2000.0) } + + #else // MMU2 (not MMU2S) + + /** + * MMU2 Extruder Sensor + * + * Support for a Průša (or other) IR Sensor to detect filament near the extruder + * and make loading more reliable. Suitable for an extruder equipped with a filament + * sensor less than 38mm from the gears. + * + * During loading the extruder will stop when the sensor is triggered, then do a last + * move up to the gears. If no filament is detected, the MMU2 can make some more attempts. + * If all attempts fail, a filament runout will be triggered. + */ + //#define MMU2_EXTRUDER_SENSOR + #if ENABLED(MMU2_EXTRUDER_SENSOR) + #define MMU2_LOADING_ATTEMPTS_NR 5 // Number of times to try loading filament before failure + #endif + + #endif + +#endif // HAS_PRUSA_MMU2 || HAS_PRUSA_MMU3 + +/** + * Advanced Print Counter settings + * @section stats + */ +#if ENABLED(PRINTCOUNTER) + #define SERVICE_WARNING_BUZZES 3 + // Activate up to 3 service interval watchdogs + //#define SERVICE_NAME_1 "Service S" + //#define SERVICE_INTERVAL_1 100 // print hours + //#define SERVICE_NAME_2 "Service L" + //#define SERVICE_INTERVAL_2 200 // print hours + //#define SERVICE_NAME_3 "Service 3" + //#define SERVICE_INTERVAL_3 1 // print hours +#endif + +// @section develop + +// +// M100 Free Memory Watcher to debug memory usage +// +//#define M100_FREE_MEMORY_WATCHER + +// +// M42 - Set pin states +// +//#define DIRECT_PIN_CONTROL + +// +// M43 - display pin status, toggle pins, watch pins, watch endstops & toggle LED, test servo probe +// +//#define PINS_DEBUGGING + +// Enable Tests that will run at startup and produce a report +//#define MARLIN_TEST_BUILD + +// Enable Marlin dev mode which adds some special commands +//#define MARLIN_DEV_MODE + +#if ENABLED(MARLIN_DEV_MODE) + /** + * D576 - Buffer Monitoring + * To help diagnose print quality issues stemming from empty command buffers. + */ + //#define BUFFER_MONITORING +#endif + +/** + * Postmortem Debugging captures misbehavior and outputs the CPU status and backtrace to serial. + * When running in the debugger it will break for debugging. This is useful to help understand + * a crash from a remote location. Requires ~400 bytes of SRAM and 5Kb of flash. + */ +//#define POSTMORTEM_DEBUGGING + +/** + * Software Reset options + */ +//#define SOFT_RESET_VIA_SERIAL // 'KILL' and '^X' commands will soft-reset the controller +//#define SOFT_RESET_ON_KILL // Use a digital button to soft-reset the controller after KILL + +// Report uncleaned reset reason from register r2 instead of MCUSR. Supported by Optiboot on AVR. +//#define OPTIBOOT_RESET_REASON + +// Shrink the build for smaller boards by sacrificing some serial feedback +//#define MARLIN_SMALL_BUILD