From bcf54a4a9ff5aa6b7d1ff0e6b331dbba3b0fbf80 Mon Sep 17 00:00:00 2001 From: ellensp <530024+ellensp@users.noreply.github.com> Date: Tue, 18 Nov 2025 15:34:53 +1300 Subject: [PATCH] add Endeer 3 Max neo with BTT SKR min e3v3 --- .../Configuration.h | 3800 +++++++++++++ .../Configuration_adv.h | 0 .../README images/DIAG jumpers.png | Bin 0 -> 137085 bytes .../BigTreeTech SKR Mini E3 3.0/README.md | 41 + .../{ => CrealityV422}/Configuration.h | 0 .../CrealityV422/Configuration_adv.h | 4767 +++++++++++++++++ 6 files changed, 8608 insertions(+) create mode 100644 config/examples/Creality/Ender-3 Max Neo/BigTreeTech SKR Mini E3 3.0/Configuration.h rename config/examples/Creality/Ender-3 Max Neo/{ => BigTreeTech SKR Mini E3 3.0}/Configuration_adv.h (100%) create mode 100644 config/examples/Creality/Ender-3 Max Neo/BigTreeTech SKR Mini E3 3.0/README images/DIAG jumpers.png create mode 100644 config/examples/Creality/Ender-3 Max Neo/BigTreeTech SKR Mini E3 3.0/README.md rename config/examples/Creality/Ender-3 Max Neo/{ => CrealityV422}/Configuration.h (100%) create mode 100644 config/examples/Creality/Ender-3 Max Neo/CrealityV422/Configuration_adv.h 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..f1571898c4 --- /dev/null +++ b/config/examples/Creality/Ender-3 Max Neo/BigTreeTech SKR Mini E3 3.0/Configuration.h @@ -0,0 +1,3800 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2023 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once +#error "Don't build with import-2.1.x configurations!" +#error "Use the 'bugfix...' or 'release...' configurations matching your Marlin version." + +/** + * Configuration.h + * + * Basic settings such as: + * + * - Type of electronics + * - Type of temperature sensor + * - Printer geometry + * - Endstop configuration + * - LCD controller + * - Extra features + * + * Advanced settings can be found in Configuration_adv.h + */ +#define CONFIGURATION_H_VERSION 02010300 + +//=========================================================================== +//============================= Getting Started ============================= +//=========================================================================== + +/** + * Here are some useful links to help get your machine configured and calibrated: + * + * Example Configs: https://github.com/MarlinFirmware/Configurations/branches/all + * + * Průša Calculator: https://blog.prusa3d.com/calculator_3416/ + * + * Calibration Guides: https://reprap.org/wiki/Calibration + * https://reprap.org/wiki/Triffid_Hunter%27s_Calibration_Guide + * https://web.archive.org/web/20220907014303/sites.google.com/site/repraplogphase/calibration-of-your-reprap + * https://youtu.be/wAL9d7FgInk + * https://teachingtechyt.github.io/calibration.html + * + * Calibration Objects: https://www.thingiverse.com/thing:5573 + * https://www.thingiverse.com/thing:1278865 + */ + +// @section info + +// Author info of this build printed to the host during boot and M115 +#define STRING_CONFIG_H_AUTHOR "(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 + #define NO_AUTO_ASSIGN_WARNING + #define NO_CONTROLLER_CUSTOM_WIRING_WARNING + #define DIAG_JUMPERS_REMOVED +#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/Configuration_adv.h b/config/examples/Creality/Ender-3 Max Neo/BigTreeTech SKR Mini E3 3.0/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/BigTreeTech SKR Mini E3 3.0/Configuration_adv.h diff --git a/config/examples/Creality/Ender-3 Max Neo/BigTreeTech SKR Mini E3 3.0/README images/DIAG jumpers.png b/config/examples/Creality/Ender-3 Max Neo/BigTreeTech SKR Mini E3 3.0/README images/DIAG jumpers.png new file mode 100644 index 0000000000000000000000000000000000000000..56efbe54d85de559166cc8de6ce99404024c6bd9 GIT binary patch literal 137085 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 z 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
  • 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 **⚠️ WARNING: Critical Configuration Notes** + +## DIAG Jumpers + +> **Warning** +> Motherboard DIAG jumpers must be removed when using endstops. + +Remove these jumpers: +![DIAG Jumpers](README images/DIAG jumpers.png) + +## DWIN_CREALITY_LCD Wiring Modification + +> **WARNING!** +> DWIN_CREALITY_LCD requires wiring modification! See `pins_BTT_SKR_MINI_E3_V3_0.h` for details (replicated below). Requires a custom cable. + +``` + ------ ------ + 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 +``` +As layed out on the physical boards + + +Connect the following pins: + +| 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/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/CrealityV422/Configuration_adv.h b/config/examples/Creality/Ender-3 Max Neo/CrealityV422/Configuration_adv.h new file mode 100644 index 0000000000..004333a557 --- /dev/null +++ b/config/examples/Creality/Ender-3 Max Neo/CrealityV422/Configuration_adv.h @@ -0,0 +1,4767 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2023 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_2_DESC "Preheat for " PREHEAT_1_LABEL + #define MAIN_MENU_ITEM_2_GCODE "M140 S" STRINGIFY(PREHEAT_1_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND) + //#define MAIN_MENU_ITEM_2_CONFIRM + + //#define MAIN_MENU_ITEM_3_DESC "Preheat for " PREHEAT_2_LABEL + //#define MAIN_MENU_ITEM_3_GCODE "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_2_TEMP_HOTEND) + //#define MAIN_MENU_ITEM_3_CONFIRM + + //#define MAIN_MENU_ITEM_4_DESC "Heat Bed/Home/Level" + //#define MAIN_MENU_ITEM_4_GCODE "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nG28\nG29" + //#define MAIN_MENU_ITEM_4_CONFIRM + + //#define MAIN_MENU_ITEM_5_DESC "Home & Info" + //#define MAIN_MENU_ITEM_5_GCODE "G28\nM503" + //#define MAIN_MENU_ITEM_5_CONFIRM +#endif + +// @section custom config menu + +// Custom Menu: Configuration Menu +//#define CUSTOM_MENU_CONFIG +#if ENABLED(CUSTOM_MENU_CONFIG) + //#define CUSTOM_MENU_CONFIG_TITLE "Custom Commands" + #define CUSTOM_MENU_CONFIG_SCRIPT_DONE "M117 Wireless Script Done" + #define CUSTOM_MENU_CONFIG_SCRIPT_AUDIBLE_FEEDBACK + //#define CUSTOM_MENU_CONFIG_SCRIPT_RETURN // Return to status screen after a script + #define CUSTOM_MENU_CONFIG_ONLY_IDLE // Only show custom menu when the machine is idle + + #define CONFIG_MENU_ITEM_1_DESC "Wifi ON" + #define CONFIG_MENU_ITEM_1_GCODE "M118 [ESP110] WIFI-STA pwd=12345678" + //#define CONFIG_MENU_ITEM_1_CONFIRM // Show a confirmation dialog before this action + + #define CONFIG_MENU_ITEM_2_DESC "Bluetooth ON" + #define CONFIG_MENU_ITEM_2_GCODE "M118 [ESP110] BT pwd=12345678" + //#define CONFIG_MENU_ITEM_2_CONFIRM + + //#define CONFIG_MENU_ITEM_3_DESC "Radio OFF" + //#define CONFIG_MENU_ITEM_3_GCODE "M118 [ESP110] OFF pwd=12345678" + //#define CONFIG_MENU_ITEM_3_CONFIRM + + //#define CONFIG_MENU_ITEM_4_DESC "Wifi ????" + //#define CONFIG_MENU_ITEM_4_GCODE "M118 ????" + //#define CONFIG_MENU_ITEM_4_CONFIRM + + //#define CONFIG_MENU_ITEM_5_DESC "Wifi ????" + //#define CONFIG_MENU_ITEM_5_GCODE "M118 ????" + //#define CONFIG_MENU_ITEM_5_CONFIRM +#endif + +// @section custom buttons + +/** + * User-defined buttons to run custom G-code. + * Up to 25 may be defined. + */ +//#define CUSTOM_USER_BUTTONS +#if ENABLED(CUSTOM_USER_BUTTONS) + //#define BUTTON1_PIN -1 + #if PIN_EXISTS(BUTTON1) + #define BUTTON1_HIT_STATE LOW // State of the triggered button. NC=LOW. NO=HIGH. + #define BUTTON1_WHEN_PRINTING false // Button allowed to trigger during printing? + #define BUTTON1_GCODE "G28" + #define BUTTON1_DESC "Homing" // Optional string to set the LCD status + #endif + + //#define BUTTON2_PIN -1 + #if PIN_EXISTS(BUTTON2) + #define BUTTON2_HIT_STATE LOW + #define BUTTON2_WHEN_PRINTING false + #define BUTTON2_GCODE "M140 S" STRINGIFY(PREHEAT_1_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND) + #define BUTTON2_DESC "Preheat for " PREHEAT_1_LABEL + #endif + + //#define BUTTON3_PIN -1 + #if PIN_EXISTS(BUTTON3) + #define BUTTON3_HIT_STATE LOW + #define BUTTON3_WHEN_PRINTING false + #define BUTTON3_GCODE "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_2_TEMP_HOTEND) + #define BUTTON3_DESC "Preheat for " PREHEAT_2_LABEL + #endif +#endif + +// @section host + +/** + * Host Action Commands + * + * Define host streamer action commands in compliance with the standard. + * + * See https://reprap.org/wiki/G-code#Action_commands + * Common commands ........ poweroff, pause, paused, resume, resumed, cancel + * G29_RETRY_AND_RECOVER .. probe_rewipe, probe_failed + * + * Some features add reason codes to extend these commands. + * + * Host Prompt Support enables Marlin to use the host for user prompts so + * filament runout and other processes can be managed from the host side. + */ +#define HOST_ACTION_COMMANDS +#if ENABLED(HOST_ACTION_COMMANDS) + //#define HOST_PAUSE_M76 // Tell the host to pause in response to M76 + #define HOST_PROMPT_SUPPORT // Initiate host prompts to get user feedback + #if ENABLED(HOST_PROMPT_SUPPORT) + //#define HOST_STATUS_NOTIFICATIONS // Send some status messages to the host as notifications + #endif + //#define HOST_START_MENU_ITEM // Add a menu item that tells the host to start + //#define HOST_SHUTDOWN_MENU_ITEM // Add a menu item that tells the host to shut down +#endif + +// @section extras + +/** + * Cancel Objects + * + * Implement M486 to allow Marlin to skip objects + */ +//#define CANCEL_OBJECTS +#if ENABLED(CANCEL_OBJECTS) + #define CANCEL_OBJECTS_REPORTING // Emit the current object as a status message +#endif + +/** + * I2C position encoders for closed loop control. + * Developed by Chris Barr at Aus3D. + * + * Wiki: https://wiki.aus3d.com.au/Magnetic_Encoder + * Github: https://github.com/Aus3D/MagneticEncoder + * + * Supplier: https://aus3d.com.au/products/magnetic-encoder-module + * Alternative Supplier: https://reliabuild3d.com/ + * + * Reliabuild encoders have been modified to improve reliability. + * @section i2c encoders + */ + +//#define I2C_POSITION_ENCODERS +#if ENABLED(I2C_POSITION_ENCODERS) + + #define I2CPE_ENCODER_CNT 1 // The number of encoders installed; max of 5 + // encoders supported currently. + + #define I2CPE_ENC_1_ADDR I2CPE_PRESET_ADDR_X // I2C address of the encoder. 30-200. + #define I2CPE_ENC_1_AXIS X_AXIS // Axis the encoder module is installed on. _AXIS. + #define I2CPE_ENC_1_TYPE I2CPE_ENC_TYPE_LINEAR // Type of encoder: I2CPE_ENC_TYPE_LINEAR -or- + // I2CPE_ENC_TYPE_ROTARY. + #define I2CPE_ENC_1_TICKS_UNIT 2048 // 1024 for magnetic strips with 2mm poles; 2048 for + // 1mm poles. For linear encoders this is ticks / mm, + // for rotary encoders this is ticks / revolution. + //#define I2CPE_ENC_1_TICKS_REV (16 * 200) // Only needed for rotary encoders; number of stepper + // steps per full revolution (motor steps/rev * microstepping) + //#define I2CPE_ENC_1_INVERT // Invert the direction of axis travel. + #define I2CPE_ENC_1_EC_METHOD I2CPE_ECM_MICROSTEP // Type of error 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