From 0643276ae43177953e40be1ae5587f1b2218499c Mon Sep 17 00:00:00 2001 From: ellensp <530024+ellensp@users.noreply.github.com> Date: Sat, 22 Nov 2025 08:44:43 +1300 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Ender-3=20Max=20Neo=20with=20BTT=20?= =?UTF-8?q?SKR=20MINI=20E3=20v3.0=20(#1165)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/default/Configuration_adv.h | 27 +- .../Configuration.h | 3801 +++++++++++++ .../Configuration_adv.h | 4780 +++++++++++++++++ .../BigTreeTech SKR Mini E3 3.0/README.md | 38 + .../images/DIAG jumpers.png | Bin 0 -> 132342 bytes .../{ => CrealityV422}/Configuration.h | 0 .../{ => CrealityV422}/Configuration_adv.h | 0 7 files changed, 8643 insertions(+), 3 deletions(-) create mode 100644 config/examples/Creality/Ender-3 Max Neo/BigTreeTech SKR Mini E3 3.0/Configuration.h create mode 100644 config/examples/Creality/Ender-3 Max Neo/BigTreeTech SKR Mini E3 3.0/Configuration_adv.h create mode 100644 config/examples/Creality/Ender-3 Max Neo/BigTreeTech SKR Mini E3 3.0/README.md create mode 100644 config/examples/Creality/Ender-3 Max Neo/BigTreeTech SKR Mini E3 3.0/images/DIAG jumpers.png rename config/examples/Creality/Ender-3 Max Neo/{ => CrealityV422}/Configuration.h (100%) rename config/examples/Creality/Ender-3 Max Neo/{ => CrealityV422}/Configuration_adv.h (100%) diff --git a/config/default/Configuration_adv.h b/config/default/Configuration_adv.h index c5ed503b4c..dc640896a8 100644 --- a/config/default/Configuration_adv.h +++ b/config/default/Configuration_adv.h @@ -2345,8 +2345,12 @@ //#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_GLOBAL_Z // Combine M424 Z and Babystepping + + #if ANY(BABYSTEP_ZPROBE_OFFSET, BABYSTEP_GLOBAL_Z) + #if ENABLED(BABYSTEP_ZPROBE_OFFSET) + //#define BABYSTEP_HOTEND_Z_OFFSET // For multiple hotends, babystep relative Z offsets + #endif //#define BABYSTEP_GFX_OVERLAY // Enable graphical overlay on Z-offset editor #endif #endif @@ -3942,6 +3946,14 @@ */ //#define CNC_COORDINATE_SYSTEMS +/** + * CNC Drilling Cycle - UNDER DEVELOPMENT + * + * Enables G81 to perform a drilling cycle. + * Currently only supports a single cycle, no G-code chaining. + */ +//#define CNC_DRILLING_CYCLE + // @section security /** @@ -4038,6 +4050,15 @@ //#define GCODE_QUOTED_STRINGS // Support for quoted string parameters #endif +/** + * Variables + * + * Define a variable from 100-115 with G-code like '#101=19.6'. + * A variable can then be used in a G-code expression like 'G0 X[#101+3]'. + * See https://gcodetutor.com/cnc-macro-programming/cnc-variables.html + */ +//#define GCODE_VARIABLES + /** * Support for MeatPack G-code compression (https://github.com/scottmudge/OctoPrint-MeatPack) */ @@ -4197,7 +4218,7 @@ #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 - //#define BUTTON1_IMMEDIATE // Skip the queue and run the G-code immediately. Rarely needed. + //#define BUTTON1_IMMEDIATE // Skip the queue and execute immediately. Rarely needed. #endif //#define BUTTON2_PIN -1 diff --git a/config/examples/Creality/Ender-3 Max Neo/BigTreeTech SKR Mini E3 3.0/Configuration.h b/config/examples/Creality/Ender-3 Max Neo/BigTreeTech SKR Mini E3 3.0/Configuration.h new file mode 100644 index 0000000000..c770cef750 --- /dev/null +++ b/config/examples/Creality/Ender-3 Max Neo/BigTreeTech SKR Mini E3 3.0/Configuration.h @@ -0,0 +1,3801 @@ +/** + * 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 + */ + +#define NO_AUTO_ASSIGN_WARNING +#define NO_CONTROLLER_CUSTOM_WIRING_WARNING +#define DIAG_JUMPERS_REMOVED + +// @section info + +// Author info of this build printed to the host during boot and M115 +#define STRING_CONFIG_H_AUTHOR "(anonymous)" // 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_BTT_SKR_MINI_E3_V3_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 -1 + +/** + * 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 "Ender-3 Max Neo 4.2.2" +//#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 + +/** + * Differential Extruder + * + * The X and E steppers work together to create a differential drive system. + * Simple : E steps = X + E ; X steps = X (E drives a loop, X stays the same) + * Balanced: E steps = X + E/2 ; X steps = X - E/2 (Dual loop system) + */ +//#define DIFFERENTIAL_EXTRUDER +#if ENABLED(DIFFERENTIAL_EXTRUDER) + //#define BALANCED_DIFFERENTIAL_EXTRUDER +#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 0 +#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 0 +#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 12.72 + #define DEFAULT_Ki 0.79 + #define DEFAULT_Kd 51.23 + #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 198.96 + #define DEFAULT_bedKi 38.80 + #define DEFAULT_bedKd 680.25 + + // 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 180 + +/** + * 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 1000 + +//=========================================================================== +//======================== 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 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 200 + + // 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.05 // (mm) + #endif + + // Print surface diameter/2 minus unreachable space (avoid collisions with vertical towers). + #define PRINTABLE_RADIUS 140.0 // (mm) + + // Center-to-center distance of the holes in the diagonal push rods. + #define DELTA_DIAGONAL_ROD 250.0 // (mm) + + // Distance between bed and nozzle Z home position + #define DELTA_HEIGHT 250.00 // (mm) Get this value from G33 auto calibrate + + #define DELTA_ENDSTOP_ADJ { 0.0, 0.0, 0.0 } // (mm) Get these values from G33 auto calibrate + + // Horizontal distance bridged by diagonal push rods when effector is centered. + #define DELTA_RADIUS 124.0 // (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 // DELTA + +// @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) + + // Height of the Shoulder axis (pivot) relative to the tower floor + #define TPARA_SHOULDER_AXIS_HEIGHT 135.0 // (mm) + + // The position of the last linkage relative to the robot arm origin + // (intersection of the base axis and floor) when at the home position + #define TPARA_ARM_X_HOME_POS 28.75 // (mm) Measured from shoulder axis to tool holder axis in home position + #define TPARA_ARM_Y_HOME_POS 0 // (mm) + #define TPARA_ARM_Z_HOME_POS 250.00 // (mm) Measured from tool holder axis to the floor + + // TPARA Workspace offset relative to the tower (position of workspace origin relative to robot Tower origin ) + // This needs to be reasonably accurate as it defines the printbed position in the TPARA space. + #define TPARA_OFFSET_X 127.0 // (mm) to coincide with minimum radius MIDDLE_DEAD_ZONE_R, and W(0,0,0) is reachable + #define TPARA_OFFSET_Y 0.0 // (mm) + #define TPARA_OFFSET_Z 0.0 // (mm) + + // TPARA tool connection point offset, relative to the tool moving frame origin which is in the last linkage axis, + // (TCP: tool center/connection point) of the robot, + // the plane of measured offset must be alligned with home position plane + #define TPARA_TCP_OFFSET_X 27.0 // (mm) Tool flange: 27 (distance from pivot to bolt holes), extruder tool: 50.0, + #define TPARA_TCP_OFFSET_Y 0.0 // (mm) + #define TPARA_TCP_OFFSET_Z -65.0 // (mm) Tool flange (bottom): -6 (caution as Z 0 posiion will crash second linkage to the floor, -35 is safe for testing with no tool), extruder tool (depends on extruder): -65.0 + + #define FEEDRATE_SCALING // Convert XY feedrate from mm/s to degrees/s on the fly + + // Radius around the center where the arm cannot reach + // For now use a hardcoded uniform limit, although it should be calculated, or fix a limit for each axis angle + #define MIDDLE_DEAD_ZONE_R 100 // (mm) + + // Max angle between L1 and L2 + #define TPARA_MAX_L1L2_ANGLE 140.0f // (degrees) +#endif // AXEL_TPARA + +// @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 HIGH +#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 HIGH + +// 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. + */ + +/** + * 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 { 80.08, 80.17, 400, 101.30 } + +/** + * 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 { 180, 180, 5, 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 { 500, 500, 50, 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 500 // X, Y, Z and E acceleration for printing moves +#define DEFAULT_RETRACT_ACCELERATION 800 // E acceleration for retracts +#define DEFAULT_TRAVEL_ACCELERATION 1000 // 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 5.0 + #define DEFAULT_YJERK 5.0 + #define DEFAULT_ZJERK 0.3 + #define DEFAULT_EJERK 10.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 +#if ENABLED(S_CURVE_ACCELERATION) + // Define to use 4th instead of 6th order motion curve + //#define S_CURVE_FACTOR 0.25 // Initial and final acceleration factor, ideally 0.1 to 0.4. + // Shouldn't generally require tuning. +#endif + +//=========================================================================== +//============================= 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 { -36, -12, 0 } + +// 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 + +//#define PROBE_WAKEUP_TIME_MS 30 // (ms) Time for the probe to wake up + +// 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 (133*60) // (mm/min) + +// Feedrate for the first approach when double-probing (MULTIPLE_PROBING == 2) +#define Z_PROBE_FEEDRATE_FAST (4*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 false +#define INVERT_Y_DIR false +#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 300 +#define Y_BED_SIZE 300 + +// Travel limits (linear=mm, rotational=°) after homing, corresponding to endstop positions. +#define X_MIN_POS -24 +#define Y_MIN_POS -4 +#define Z_MIN_POS 0 +#define X_MAX_POS X_BED_SIZE +#define Y_MAX_POS Y_BED_SIZE +#define Z_MAX_POS 320 +//#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 5 + #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 0 +//#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), (4*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 200 +#define PREHEAT_1_TEMP_BED 60 +#define PREHEAT_1_TEMP_CHAMBER 35 +#define PREHEAT_1_FAN_SPEED 255 // Value from 0 to 255 + +#define PREHEAT_2_LABEL "ABS" +#define PREHEAT_2_TEMP_HOTEND 240 +#define PREHEAT_2_TEMP_BED 100 +#define PREHEAT_2_TEMP_CHAMBER 35 +#define PREHEAT_2_FAN_SPEED 255 // 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 { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 } + #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/Creality/Ender-3 Max Neo/BigTreeTech SKR Mini E3 3.0/Configuration_adv.h b/config/examples/Creality/Ender-3 Max Neo/BigTreeTech SKR Mini E3 3.0/Configuration_adv.h new file mode 100644 index 0000000000..1c90985c28 --- /dev/null +++ b/config/examples/Creality/Ender-3 Max Neo/BigTreeTech SKR Mini E3 3.0/Configuration_adv.h @@ -0,0 +1,4780 @@ +/** + * 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 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 60 // (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 100 // (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, 2 } // (linear=mm, rotational=°) Backoff from endstops after first bump +#define HOMING_BUMP_DIVISOR { 2, 2, 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 M4_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_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 synchronize 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_RESONANCE_TEST // Sine sweep motion for resonance study + + //#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 // (s) Maximum smoothing time. Higher values consume 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 uses less CPU. + // 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_BUFFER_SIZE 128 // Window size for trajectory generation, must be a power of 2 (e.g 64, 128, 256, ...) + // The total buffered time in seconds is (FTM_BUFFER_SIZE/FTM_FS) + #define FTM_FS 1000 // (Hz) Frequency for trajectory generation. + #define FTM_STEPPER_FS 2'000'000 // (Hz) Time resolution of stepper I/O update. Shouldn't affect CPU much (slower board testing needed) + #define FTM_MIN_SHAPE_FREQ 20 // (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, 4*60, 2*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, HAS_GRAPHICAL_TFT) + #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 true // 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 true // 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 true // Keep sorted items in RAM longer for speedy performance. Most expensive option. + #define SDSORT_DYNAMIC_RAM true // 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. + #define SDSORT_QUICK true // Use Quick Sort as a sorting algorithm. Otherwise use Bubble Sort. + #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 ONBOARD + + // 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 + #define BABYSTEP_GLOBAL_Z // Combine M424 Z and Babystepping + + #if ANY(BABYSTEP_ZPROBE_OFFSET, BABYSTEP_GLOBAL_Z) + #if ENABLED(BABYSTEP_ZPROBE_OFFSET) + //#define BABYSTEP_HOTEND_Z_OFFSET // For multiple hotends, babystep relative Z offsets + #endif + //#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 ANY(LIN_ADVANCE, FT_MOTION) + #if ENABLED(DISTINCT_E_FACTORS) + #define ADVANCE_K { 0.22 } // (mm) Compression length per 1mm/s extruder speed, per extruder. Override with 'M900 T K'. + #else + #define ADVANCE_K 0.22 // (mm) Compression length for all extruders. Override with 'M900 K'. + #endif + //#define ADVANCE_K_EXTRA // Add a second linear advance constant, configurable with 'M900 L'. +#endif + +#if ENABLED(LIN_ADVANCE) + //#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 60 // (mm/s) Initial retract feedrate. + #define PAUSE_PARK_RETRACT_LENGTH 2 // (mm) Initial retract. + // This short retract is done immediately, before parking the nozzle. + #define FILAMENT_CHANGE_UNLOAD_FEEDRATE 200 // (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 100 // (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 75 // (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 410 // (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 25 // (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 10 // 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 580 // (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 580 + #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 580 + #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 650 + #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_24V // 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 + +/** + * CNC Drilling Cycle - UNDER DEVELOPMENT + * + * Enables G81 to perform a drilling cycle. + * Currently only supports a single cycle, no G-code chaining. + */ +//#define CNC_DRILLING_CYCLE + +// @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 + +/** + * Variables + * + * Define a variable from 100-115 with G-code like '#101=19.6'. + * A variable can then be used in a G-code expression like 'G0 X[#101+3]'. + * See https://gcodetutor.com/cnc-macro-programming/cnc-variables.html + */ +//#define GCODE_VARIABLES + +/** + * 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 + * and M820 to report the current set of macros. + * Macros are not saved to EEPROM unless enabled below. + */ +//#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 + #if ENABLED(EEPROM_SETTINGS) + //#define GCODE_MACROS_IN_EEPROM // Include macros in EEPROM + #endif +#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_1_IMMEDIATE // Skip the queue and execute immediately. Rarely needed. + + #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_2_IMMEDIATE + + //#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_3_IMMEDIATE + + //#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_4_IMMEDIATE + + //#define MAIN_MENU_ITEM_5_DESC "Home & Info" + //#define MAIN_MENU_ITEM_5_GCODE "G28\nM503" + //#define MAIN_MENU_ITEM_5_CONFIRM + //#define MAIN_MENU_ITEM_5_IMMEDIATE +#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_1_IMMEDIATE // Skip the queue and execute immediately. Rarely needed. + + #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_2_IMMEDIATE + + //#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_3_IMMEDIATE + + //#define CONFIG_MENU_ITEM_4_DESC "Wifi ????" + //#define CONFIG_MENU_ITEM_4_GCODE "M118 ????" + //#define CONFIG_MENU_ITEM_4_CONFIRM + //#define CONFIG_MENU_ITEM_4_IMMEDIATE + + //#define CONFIG_MENU_ITEM_5_DESC "Wifi ????" + //#define CONFIG_MENU_ITEM_5_GCODE "M118 ????" + //#define CONFIG_MENU_ITEM_5_CONFIRM + //#define CONFIG_MENU_ITEM_5_IMMEDIATE +#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 + //#define BUTTON1_IMMEDIATE // Skip the queue and execute immediately. Rarely needed. + #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 + //#define BUTTON2_IMMEDIATE + #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 + //#define BUTTON3_IMMEDIATE + #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 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 + +// +// M265 - I2C Scanner +// +//#define I2C_SCANNER + +// 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/Creality/Ender-3 Max Neo/BigTreeTech SKR Mini E3 3.0/README.md b/config/examples/Creality/Ender-3 Max Neo/BigTreeTech SKR Mini E3 3.0/README.md new file mode 100644 index 0000000000..d97f8b08e6 --- /dev/null +++ b/config/examples/Creality/Ender-3 Max Neo/BigTreeTech SKR Mini E3 3.0/README.md @@ -0,0 +1,38 @@ +# Ender-3 Max Neo with BigTreeTech SKR Mini E3 V3.0 Configuration + +## DIAG Jumpers + +> [!WARNING] +> **Critical Configuration Notes**
The motherboard’s DIAG jumpers must be removed when using end‑stops. + +Remove the jumpers outlined in this image: +![DIAG Jumpers]() + +## LCD Wiring Modification + +> [!WARNING] +> The `DWIN_CREALITY_LCD` requires wiring modification!
See `pins_BTT_SKR_MINI_E3_V3_0.h` for details. Requires a custom cable. + +### Physical Layout +``` +Board and display pin layouts + ------ ------ + ENT | 1 2 | BEEP 5V | 1 2 | GND + TX1 | 3 4 | A | 3 4 | B + RX1 5 6 | BEEP | 5 6 ENT + B | 7 8 | A TX | 7 8 | RX + GND | 9 10 | 5V | 9 10 | + ------ ------ + Motherboard EXP1 Screen connector +``` + +### Pin Connections +| Motherboard | Screen | +|-------------|--------| +| TX1 | RX | +| RX1 | TX | +| BEEP | BEEP | +| A | A | +| B | B | +| 5V | 5V | +| GND | GND | diff --git a/config/examples/Creality/Ender-3 Max Neo/BigTreeTech SKR Mini E3 3.0/images/DIAG jumpers.png b/config/examples/Creality/Ender-3 Max Neo/BigTreeTech SKR Mini E3 3.0/images/DIAG jumpers.png new file mode 100644 index 0000000000000000000000000000000000000000..255b3789089b2baa5a8a24abc92a8e3b092204bf GIT binary patch literal 132342 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 literal 0 HcmV?d00001 diff --git a/config/examples/Creality/Ender-3 Max Neo/Configuration.h b/config/examples/Creality/Ender-3 Max Neo/CrealityV422/Configuration.h similarity index 100% rename from config/examples/Creality/Ender-3 Max Neo/Configuration.h rename to config/examples/Creality/Ender-3 Max Neo/CrealityV422/Configuration.h diff --git a/config/examples/Creality/Ender-3 Max Neo/Configuration_adv.h b/config/examples/Creality/Ender-3 Max Neo/CrealityV422/Configuration_adv.h similarity index 100% rename from config/examples/Creality/Ender-3 Max Neo/Configuration_adv.h rename to config/examples/Creality/Ender-3 Max Neo/CrealityV422/Configuration_adv.h